int giftest_write(void) { struct gif *gif; struct palette *pal; struct color colors[4] = { { 0, 0, 0, 0xff }, { 64, 64, 64, 0xff }, { 128, 128, 128, 0xff }, { 192, 192, 192, 0xff } }; uint32_t x,y,i; uint8_t data; gif = gif_new("test.gif", GIF_WRITE); pal = gif_palette_make(4, colors); gif_screen_put(gif, GIFTEST_WIDTH, GIFTEST_HEIGHT, 2, 0, pal); gif_image_put(gif, 0, 0, GIFTEST_WIDTH, GIFTEST_HEIGHT, 0, pal); i=0; for(y = 0; y < GIFTEST_HEIGHT; y++) for(x = 0; x < GIFTEST_WIDTH; x++) { /* data = i & 0x03;*/ data = (y*x*2 + x*x*8) / 80; data &= 0x03; gif_data_put(gif, &data, 1); i++; } gif_close(gif); gif_save(gif); return 0; }
void * gif_encode(Image *image, int single, int *size) { int width = image->columns; int height = image->rows; int total = width * height; GifByteType red[total]; GifByteType green[total]; GifByteType blue[total]; // Quantize the images using IM/GM first, to reduce // their number of colors to 256. int count = GetImageListLength(image); QuantizeInfo info; GetQuantizeInfo(&info); info.dither = 0; info.number_colors = NCOLORS; QuantizeImage(&info, image); if (count > 1) { #ifdef _MAGICK_USES_IM RemapImages(&info, image->next, image); #else MapImages(image->next, image, 0); #endif } if (!acquire_image_pixels(image, red, green, blue)) { return NULL; } size_t frame_size = sizeof(Frame) + total; Frame *frames = malloc(frame_size * count); ColorMapObject *palette = GifMakeMapObject(NCOLORS, NULL); int palette_size = NCOLORS; // Quantize again using giflib, since it yields a palette which produces // better compression, reducing the file size by 20%. Note that this second // quantization is very fast, because the image already has 256 colors, so // its effect on performance is negligible. if (GifQuantizeBuffer(width, height, &palette_size, red, green, blue, frames->data, palette->Colors) == GIF_ERROR) { GifFreeMapObject(palette); free(frames); return NULL; } frames->width = width; frames->height = height; frames->duration = image->delay; GifColorType *colors = palette->Colors; Image *cur = image->next; PixelCache *cache = pixel_cache_new(); unsigned char *p = (unsigned char*)frames; int ii; for (ii = 1; ii < count; ii++, cur = cur->next) { p += frame_size; Frame *frame = (Frame*)p; frame->width = width; frame->height = height; frame->duration = cur->delay; GifPixelType *data = frame->data; if (!aprox_image_pixels(cur, colors, palette_size, cache, data)) { GifFreeMapObject(palette); free(frames); pixel_cache_free(cache); return NULL; } } pixel_cache_free(cache); void *ret = gif_save(image, palette, frames, count, frame_size, size); GifFreeMapObject(palette); free(frames); return ret; }