_imageFile::~_imageFile() { if( !this->buffer ) return; _mimeType type = this->getRealMime(); if( type == _mime::image_ico ) delete[] this->bufferedData; if( type == _mime::image_gif ) { // Delete buffer of file content delete[] bufferedGif->gif_data; // Finalize gif gif_finalise( this->bufferedGif ); // Delet gif decoder delete this->bufferedGif; // Delete the buffered image if( this->bufferedGifBitmap ) delete this->bufferedGifBitmap; } else delete this->bufferedImage; }
static void nsgif_destroy(struct content *c) { nsgif_content *gif = (nsgif_content *) c; /* Free all the associated memory buffers */ guit->browser->schedule(-1, nsgif_animate, c); gif_finalise(gif->gif); free(gif->gif); }
/* gifReadImage: Reads an image from a memory buffer. Returns: non-zero if successful. */ int gifReadImage(int w, int h, int d, char* bits, char *data, int nBytes) { gif_bitmap_callback_vt bitmap_callbacks = { bitmap_create, bitmap_destroy, bitmap_get_buffer, bitmap_set_opaque, bitmap_test_opaque, bitmap_modified }; gif_animation gif; gif_result code; formWidth = w; formHeight = h; formBits = bits; /* create our gif animation */ gif_create(&gif, &bitmap_callbacks); /* begin decoding */ do { code = gif_initialise(&gif, nBytes, data); if (code != GIF_OK && code != GIF_WORKING) { DBG("gif_initialise failure"); return 0; } } while (code != GIF_OK); if(gif.width != w || gif.height != h || gif.frame_count != 1 || d != 32) { DBG("image format mismatch"); return 0; } code = gif_decode_frame(&gif, 0); if (code != GIF_OK) { DBG("gif_decode_frame error"); return 0; } /* clean up */ gif_finalise(&gif); return 1; }
void gs_image_file_free(gs_image_file_t *image) { if (!image) return; if (image->loaded) { if (image->is_animated_gif) { gif_finalise(&image->gif); bfree(image->animation_frame_cache); bfree(image->animation_frame_data); } gs_texture_destroy(image->texture); } bfree(image->texture_data); bfree(image->gif_data); memset(image, 0, sizeof(*image)); }
static bool init_animated_gif(gs_image_file_t *image, const char *path) { bool is_animated_gif = true; gif_result result; uint64_t max_size; size_t size; FILE *file; image->bitmap_callbacks.bitmap_create = bi_def_bitmap_create; image->bitmap_callbacks.bitmap_destroy = bi_def_bitmap_destroy; image->bitmap_callbacks.bitmap_get_buffer = bi_def_bitmap_get_buffer; image->bitmap_callbacks.bitmap_modified = bi_def_bitmap_modified; image->bitmap_callbacks.bitmap_set_opaque = bi_def_bitmap_set_opaque; image->bitmap_callbacks.bitmap_test_opaque = bi_def_bitmap_test_opaque; gif_create(&image->gif, &image->bitmap_callbacks); file = os_fopen(path, "rb"); if (!file) { blog(LOG_WARNING, "Failed to open file '%s'", path); goto fail; } fseek(file, 0, SEEK_END); size = (size_t)os_ftelli64(file); fseek(file, 0, SEEK_SET); image->gif_data = bmalloc(size); fread(image->gif_data, 1, size, file); do { result = gif_initialise(&image->gif, size, image->gif_data); if (result < 0) { blog(LOG_WARNING, "Failed to initialize gif '%s', " "possible file corruption", path); goto fail; } } while (result != GIF_OK); if (image->gif.width > 4096 || image->gif.height > 4096) { blog(LOG_WARNING, "Bad texture dimensions (%dx%d) in '%s'", image->gif.width, image->gif.height, path); goto fail; } max_size = (uint64_t)image->gif.width * (uint64_t)image->gif.height * (uint64_t)image->gif.frame_count * 4LLU; if ((uint64_t)get_full_decoded_gif_size(image) != max_size) { blog(LOG_WARNING, "Gif '%s' overflowed maximum pointer size", path); goto fail; } image->is_animated_gif = (image->gif.frame_count > 1 && result >= 0); if (image->is_animated_gif) { gif_decode_frame(&image->gif, 0); image->animation_frame_cache = bzalloc( image->gif.frame_count * sizeof(uint8_t*)); image->animation_frame_data = bzalloc( get_full_decoded_gif_size(image)); for (unsigned int i = 0; i < image->gif.frame_count; i++) { if (gif_decode_frame(&image->gif, i) != GIF_OK) blog(LOG_WARNING, "Couldn't decode frame %u " "of '%s'", i, path); } gif_decode_frame(&image->gif, 0); image->cx = (uint32_t)image->gif.width; image->cy = (uint32_t)image->gif.height; image->format = GS_RGBA; } else { gif_finalise(&image->gif); bfree(image->gif_data); image->gif_data = NULL; is_animated_gif = false; goto not_animated; } image->loaded = true; fail: if (!image->loaded) gs_image_file_free(image); not_animated: if (file) fclose(file); return is_animated_gif; }
int main(int argc, char *argv[]) { gif_bitmap_callback_vt bitmap_callbacks = { bitmap_create, bitmap_destroy, bitmap_get_buffer, bitmap_set_opaque, bitmap_test_opaque, bitmap_modified }; gif_animation gif; size_t size; gif_result code; unsigned int i; if (argc != 2) { fprintf(stderr, "Usage: %s image.gif\n", argv[0]); return 1; } /* create our gif animation */ gif_create(&gif, &bitmap_callbacks); /* load file into memory */ unsigned char *data = load_file(argv[1], &size); /* begin decoding */ do { code = gif_initialise(&gif, size, data); if (code != GIF_OK && code != GIF_WORKING) { warning("gif_initialise", code); exit(1); } } while (code != GIF_OK); printf("P3\n"); printf("# %s\n", argv[1]); printf("# width %u \n", gif.width); printf("# height %u \n", gif.height); printf("# frame_count %u \n", gif.frame_count); printf("# frame_count_partial %u \n", gif.frame_count_partial); printf("# loop_count %u \n", gif.loop_count); printf("%u %u 256\n", gif.width, gif.height * gif.frame_count); /* decode the frames */ for (i = 0; i != gif.frame_count; i++) { unsigned int row, col; unsigned char *image; code = gif_decode_frame(&gif, i); if (code != GIF_OK) warning("gif_decode_frame", code); printf("# frame %u:\n", i); image = (unsigned char *) gif.frame_image; for (row = 0; row != gif.height; row++) { for (col = 0; col != gif.width; col++) { size_t z = (row * gif.width + col) * 4; printf("%u %u %u ", (unsigned char) image[z], (unsigned char) image[z + 1], (unsigned char) image[z + 2]); } printf("\n"); } } /* clean up */ gif_finalise(&gif); free(data); return 0; }