void colormap_combine(Gif_Colormap *dst, Gif_Colormap *src) { Gif_Color *src_col, *dst_col; int i, j; /* expand dst->col if necessary. This might change dst->col */ if (dst->ncol + src->ncol >= dst->capacity) { dst->capacity *= 2; Gif_ReArray(dst->col, Gif_Color, dst->capacity); } src_col = src->col; dst_col = dst->col; for (i = 0; i < src->ncol; i++, src_col++) { for (j = 1; j < dst->ncol; j++) { if (GIF_COLOREQ(src_col, &dst_col[j])) goto found; } dst_col[j] = *src_col; dst_col[j].pixel = 0; dst->ncol++; found: src_col->pixel = j; } }
int find_color_index(Gif_Color *c, int nc, Gif_Color *color) { int index; for (index = 0; index < nc; index++) if (GIF_COLOREQ(&c[index], color)) return index; return -1; }
int merge_colormap_if_possible(Gif_Colormap *dest, Gif_Colormap *src) { Gif_Color *srccol; Gif_Color *destcol = dest->col; int ndestcol = dest->ncol; int dest_userflags = dest->userflags; int i, x; int trivial_map = 1; if (!src) return 1; srccol = src->col; for (i = 0; i < src->ncol; i++) { if (srccol[i].haspixel & 1) { /* Store an image color cell's mapping to the global colormap in its 'pixel' slot. This is useful caching: oftentimes many input frames will share a colormap */ int mapto = (srccol[i].pixel < 256 ? (int)srccol[i].pixel : -1); if (mapto == -1) mapto = find_color_index(destcol, ndestcol, &srccol[i]); if (mapto == -1 && ndestcol < 256) { /* add the color */ mapto = ndestcol; destcol[mapto] = srccol[i]; ndestcol++; } if (mapto == -1) /* check for a pure-transparent color */ for (x = 0; x < ndestcol; x++) if (destcol[x].haspixel == 2) { mapto = x; destcol[mapto] = srccol[i]; break; } if (mapto == -1) /* give up and require a local colormap */ goto local_colormap_required; assert(mapto >= 0 && mapto < ndestcol); assert(GIF_COLOREQ(&destcol[mapto], &srccol[i])); srccol[i].pixel = mapto; destcol[mapto].haspixel = 1; if (mapto != i) trivial_map = 0; } else if (srccol[i].haspixel & 2) { /* a dedicated transparent color; if trivial_map & at end of colormap insert it with haspixel == 2. (strictly not necessary; we do it to try to keep the map trivial.) */ if (trivial_map && i == ndestcol) { destcol[ndestcol] = srccol[i]; ndestcol++; } } } /* success! save new number of colors */ dest->ncol = ndestcol; dest->userflags = dest_userflags; return 1; /* failure: a local colormap is required */ local_colormap_required: if (warn_local_colormaps == 1) { static int context = 0; if (!context) { warning(1, "too many colors, using local colormaps\n" " (You may want to try %<--colors 256%>.)"); context = 1; } else warning(1, "too many colors, using local colormaps"); warn_local_colormaps = 2; } /* 9.Dec.1998 - This must have been a longstanding bug! We MUST clear the cached mappings of any pixels in the source colormap we assigned this time through, since we are throwing those colors away. We assigned it this time through if the cached mapping is >= dest->ncol. */ for (x = 0; x < i; x++) if ((srccol[x].haspixel & 1) && srccol[x].pixel >= (uint32_t)dest->ncol) srccol[x].pixel = 256; return 0; }