Androidはlibnsgifクラスライブラリを使用してgif画像を解く
ダウンロードアドレス:http://www.netsurf-browser.org/projects/libnsgif/
Android Androidプロジェクト住所:https://github.com/hzy3774/AndroidNSGif
これはnetsurfブラウザのコンポーネントで、単独で使用でき、gifを解析するのにメモリが少なく、簡単です.
Windowsの下でopenglでレンダリングし、MinGWでコンパイルした、コード:
実行効果:
アンドロイドプラットフォームはjniによって呼び出されます.
Androidプロジェクトの住所:https://github.com/hzy3774/AndroidNSGifその他の参考添付ファイル.
Android Androidプロジェクト住所:https://github.com/hzy3774/AndroidNSGif
これはnetsurfブラウザのコンポーネントで、単独で使用でき、gifを解析するのにメモリが少なく、簡単です.
Windowsの下でopenglでレンダリングし、MinGWでコンパイルした、コード:
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <GL/freeglut.h>
#include "nsgif/libnsgif.h"
unsigned char *load_file(const char *path, size_t *data_size);
void warning(const char *context, int code);
void *bitmap_create(int width, int height);
void bitmap_set_opaque(void *bitmap, bool opaque);
bool bitmap_test_opaque(void *bitmap);
unsigned char *bitmap_get_buffer(void *bitmap);
void bitmap_destroy(void *bitmap);
void bitmap_modified(void *bitmap);
gif_animation gif;
unsigned char *data;
int index = 0;
void close(){
/* clean up */
gif_finalise(&gif);
free(data);
}
int decodeGif(const char* fname)
{
gif_bitmap_callback_vt bitmap_callbacks = {
bitmap_create,
bitmap_destroy,
bitmap_get_buffer,
bitmap_set_opaque,
bitmap_test_opaque,
bitmap_modified
};
size_t size;
gif_result code;
/* create our gif animation */
gif_create(&gif, &bitmap_callbacks);
/* load file into memory */
data = load_file(fname, &size);
/* begin decoding */
do {
code = gif_initialise(&gif, size, data);
if (code != GIF_OK && code != GIF_WORKING) {
warning("gif_initialise", code);
return -1;
}
} while (code != GIF_OK);
printf("# width %u
", gif.width);
printf("# height %u
", gif.height);
printf("# frame_count %u
", gif.frame_count);
printf("# frame_count_partial %u
", gif.frame_count_partial);
printf("# loop_count %u
", gif.loop_count);
printf("%u %u 256
", gif.width, gif.height * gif.frame_count);
return 0;
}
unsigned char* getFrame(int i){
unsigned char *image;
gif_result code;
code = gif_decode_frame(&gif, i);
if (code != GIF_OK)
warning("gif_decode_frame", code);
image = (unsigned char *) gif.frame_image;
return image;
}
unsigned char *load_file(const char *path, size_t *data_size)
{
FILE *fd;
struct stat sb;
unsigned char *buffer;
size_t size;
size_t n;
fd = fopen(path, "rb");
if (!fd) {
perror(path);
exit(EXIT_FAILURE);
}
if (stat(path, &sb)) {
perror(path);
exit(EXIT_FAILURE);
}
size = sb.st_size;
buffer = malloc(size);
if (!buffer) {
fprintf(stderr, "Unable to allocate %lld bytes
",
(long long) size);
exit(EXIT_FAILURE);
}
n = fread(buffer, 1, size, fd);
if (n != size) {
perror(path);
exit(EXIT_FAILURE);
}
fclose(fd);
*data_size = size;
return buffer;
}
void warning(const char *context, gif_result code)
{
fprintf(stderr, "%s failed: ", context);
switch (code)
{
case GIF_INSUFFICIENT_FRAME_DATA:
fprintf(stderr, "GIF_INSUFFICIENT_FRAME_DATA");
break;
case GIF_FRAME_DATA_ERROR:
fprintf(stderr, "GIF_FRAME_DATA_ERROR");
break;
case GIF_INSUFFICIENT_DATA:
fprintf(stderr, "GIF_INSUFFICIENT_DATA");
break;
case GIF_DATA_ERROR:
fprintf(stderr, "GIF_DATA_ERROR");
break;
case GIF_INSUFFICIENT_MEMORY:
fprintf(stderr, "GIF_INSUFFICIENT_MEMORY");
break;
default:
fprintf(stderr, "unknown code %i", code);
break;
}
fprintf(stderr, "
");
}
void *bitmap_create(int width, int height)
{
return calloc(width * height, 4);
}
void bitmap_set_opaque(void *bitmap, bool opaque)
{
(void) opaque; /* unused */
assert(bitmap);
}
bool bitmap_test_opaque(void *bitmap)
{
assert(bitmap);
return false;
}
unsigned char *bitmap_get_buffer(void *bitmap)
{
assert(bitmap);
return bitmap;
}
void bitmap_destroy(void *bitmap)
{
assert(bitmap);
free(bitmap);
}
void bitmap_modified(void *bitmap)
{
assert(bitmap);
return;
}
void myDisplay(void)
{
// glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(gif.width, gif.height, GL_RGBA, GL_UNSIGNED_BYTE, gif.frame_image);
glutSwapBuffers();
}
void myTimer(int i){
int delay;
index++;
if(index == gif.frame_count){
index = 0;
}
delay = gif.frames[index].frame_delay * 10;
getFrame(index);
glutPostRedisplay();
printf("Frame index[%d], delay[%d]
", index, delay);
glutTimerFunc(delay, myTimer, 1);
}
int main(int argc, char *argv[])
{
decodeGif("test.gif");
glutInit(&argc, argv) ;
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(300, 200);
glutInitWindowSize(gif.width, gif.height);
glutCreateWindow("Gif Show");
getFrame(index);
glutTimerFunc(gif.frames[index].frame_delay * 10, &myTimer, 1);
glRasterPos2f(-1, 1); //
glPixelZoom(1, -1); //y
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}
実行効果:
アンドロイドプラットフォームはjniによって呼び出されます.
Androidプロジェクトの住所:https://github.com/hzy3774/AndroidNSGifその他の参考添付ファイル.