示例#1
0
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;
  }
}
示例#2
0
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;
}
示例#3
0
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;
}