static int initialize_optimizer(Gif_Stream *gfs) { int i; if (gfs->nimages < 1) return 0; /* combine colormaps */ all_colormap = Gif_NewFullColormap(1, 384); all_colormap->col[0].gfc_red = 255; all_colormap->col[0].gfc_green = 255; all_colormap->col[0].gfc_blue = 255; in_global_map = gfs->global; if (!in_global_map) { Gif_Color *col; in_global_map = Gif_NewFullColormap(256, 256); col = in_global_map->col; for (i = 0; i < 256; i++, col++) col->gfc_red = col->gfc_green = col->gfc_blue = i; } { int any_globals = 0; int first_transparent = -1; kchist_init(&all_colormap_hist); for (i = 0; i < gfs->nimages; i++) { Gif_Image *gfi = gfs->images[i]; if (gfi->local) all_colormap_add(gfi->local); else any_globals = 1; if (gfi->transparent >= 0 && first_transparent < 0) first_transparent = i; } if (any_globals) all_colormap_add(in_global_map); kchist_cleanup(&all_colormap_hist); /* try and maintain transparency's pixel value */ if (first_transparent >= 0) { Gif_Image *gfi = gfs->images[first_transparent]; Gif_Colormap *gfcm = gfi->local ? gfi->local : gfs->global; all_colormap->col[TRANSP] = gfcm->col[gfi->transparent]; } } /* find screen_width and screen_height, and clip all images to screen */ Gif_CalculateScreenSize(gfs, 0); screen_width = gfs->screen_width; screen_height = gfs->screen_height; for (i = 0; i < gfs->nimages; i++) Gif_ClipImage(gfs->images[i], 0, 0, screen_width, screen_height); /* choose background */ if (gfs->images[0]->transparent < 0 && gfs->global && gfs->background < in_global_map->ncol) background = in_global_map->col[gfs->background].pixel; else background = TRANSP; return 1; }
static int apply_image(int is_second, Gif_Stream *gfs, int imageno, uint16_t background) { int i, x, y, any_change; Gif_Image *gfi = gfs->images[imageno]; Gif_Image *pgfi = imageno ? gfs->images[imageno - 1] : 0; int width = gfi->width; uint16_t map[256]; uint16_t *data = gdata[is_second]; uint16_t *last = glast[is_second]; Gif_Colormap *gfcm = gfi->local ? gfi->local : gfs->global; /* set up colormap */ for (i = 0; i < 256; i++) map[i] = 1; if (gfs) for (i = 0; i < gfcm->ncol; i++) map[i] = gfcm->col[i].pixel; if (gfi->transparent >= 0 && gfi->transparent < 256) map[gfi->transparent] = TRANSP; /* if this image's disposal is 'previous', save the post-disposal version in 'scratch' */ if (gfi->disposal == GIF_DISPOSAL_PREVIOUS) { copy_area(scratch, data, gfi->left, gfi->top, gfi->width, gfi->height); if (pgfi && pgfi->disposal == GIF_DISPOSAL_PREVIOUS) copy_area(scratch, last, pgfi->left, pgfi->top, pgfi->width, pgfi->height); else if (pgfi && pgfi->disposal == GIF_DISPOSAL_BACKGROUND) fill_area(scratch, pgfi->left, pgfi->top, pgfi->width, pgfi->height, background); } /* uncompress and clip */ Gif_UncompressImage(gfs, gfi); Gif_ClipImage(gfi, 0, 0, screen_width, screen_height); any_change = imageno == 0; { int lf = 0, tp = 0, rt = 0, bt = 0; expand_bounds(&lf, &tp, &rt, &bt, gfi); if (pgfi && pgfi->disposal == GIF_DISPOSAL_PREVIOUS) expand_bounds(&lf, &tp, &rt, &bt, pgfi); else if (pgfi && pgfi->disposal == GIF_DISPOSAL_BACKGROUND) { expand_bounds(&lf, &tp, &rt, &bt, pgfi); fill_area(last, pgfi->left, pgfi->top, pgfi->width, pgfi->height, background); } else pgfi = 0; for (y = tp; y < bt; ++y) { uint16_t *outd = data + screen_width * y + lf; if (!any_change) memcpy(line, outd, (rt - lf) * sizeof(uint16_t)); if (pgfi && y >= pgfi->top && y < pgfi->top + pgfi->height) memcpy(outd + pgfi->left - lf, last + screen_width * y + pgfi->left, pgfi->width * sizeof(uint16_t)); if (y >= gfi->top && y < gfi->top + gfi->height) { uint16_t *xoutd = outd + gfi->left - lf; const uint8_t *ind = gfi->img[y - gfi->top]; for (x = 0; x < width; ++x, ++ind, ++xoutd) if (map[*ind] != TRANSP) *xoutd = map[*ind]; } if (!any_change && memcmp(line, outd, (rt - lf) * sizeof(uint16_t)) != 0) any_change = 1; } } Gif_ReleaseUncompressedImage(gfi); Gif_ReleaseCompressedImage(gfi); /* switch 'glast' with 'scratch' if necessary */ if (gfi->disposal == GIF_DISPOSAL_PREVIOUS) { uint16_t *x = scratch; scratch = glast[is_second]; glast[is_second] = x; } return any_change; }
static int initialize_optimizer(Gif_Stream *gfs) { int i; unsigned screen_size; if (gfs->nimages < 1) return 0; /* combine colormaps */ all_colormap = Gif_NewFullColormap(1, 384); all_colormap->col[0].gfc_red = 255; all_colormap->col[0].gfc_green = 255; all_colormap->col[0].gfc_blue = 255; in_global_map = gfs->global; if (!in_global_map) { Gif_Color *col; in_global_map = Gif_NewFullColormap(256, 256); col = in_global_map->col; for (i = 0; i < 256; i++, col++) col->gfc_red = col->gfc_green = col->gfc_blue = i; } { int any_globals = 0; int first_transparent = -1; for (i = 0; i < gfs->nimages; i++) { Gif_Image *gfi = gfs->images[i]; if (gfi->local) colormap_combine(all_colormap, gfi->local); else any_globals = 1; if (gfi->transparent >= 0 && first_transparent < 0) first_transparent = i; } if (any_globals) colormap_combine(all_colormap, in_global_map); /* try and maintain transparency's pixel value */ if (first_transparent >= 0) { Gif_Image *gfi = gfs->images[first_transparent]; Gif_Colormap *gfcm = gfi->local ? gfi->local : gfs->global; all_colormap->col[TRANSP] = gfcm->col[gfi->transparent]; } } /* find screen_width and screen_height, and clip all images to screen */ Gif_CalculateScreenSize(gfs, 0); screen_width = gfs->screen_width; screen_height = gfs->screen_height; for (i = 0; i < gfs->nimages; i++) Gif_ClipImage(gfs->images[i], 0, 0, screen_width, screen_height); /* create data arrays */ screen_size = (unsigned) screen_width * (unsigned) screen_height; last_data = Gif_NewArray(uint16_t, screen_size); this_data = Gif_NewArray(uint16_t, screen_size); /* set up colormaps */ gif_color_count = 2; while (gif_color_count < gfs->global->ncol && gif_color_count < 256) gif_color_count *= 2; /* choose background */ if (gfs->images[0]->transparent < 0 && gfs->background < in_global_map->ncol) background = in_global_map->col[gfs->background].pixel; else background = TRANSP; return 1; }