Пример #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
static int
create_image_data(Gif_Stream *gfs, Gif_Image *gfi, uint16_t *screen,
                  uint8_t *new_data, int *used_transparent)
{
    int have[257];
    int transparent = -1;
    unsigned pos, size = gfs->screen_width * gfs->screen_height;
    uint16_t *move;
    int i;

    /* mark colors used opaquely in the image */
    assert(TRANSPARENT == 256);
    for (i = 0; i < 257; i++)
        have[i] = 0;
    for (pos = 0, move = screen; pos != size; ++pos, move++)
        have[*move] = 1;

    /* the new transparent color is a color unused in either */
    if (have[TRANSPARENT]) {
        for (i = 0; i < 256 && transparent < 0; i++)
            if (!have[i])
                transparent = i;
        if (transparent < 0)
            goto error;
        if (transparent >= gfs->global->ncol) {
            Gif_ReArray(gfs->global->col, Gif_Color, 256);
            if (!gfs->global->col) goto error;
            gfs->global->ncol = transparent + 1;
        }
    }

    /* map the wide image onto the new data */
    *used_transparent = 0;
    for (pos = 0, move = screen; pos != size; ++pos, move++, new_data++)
        if (*move == TRANSPARENT) {
            *new_data = transparent;
            *used_transparent = 1;
        } else
            *new_data = *move;

    gfi->transparent = transparent;
    return 1;

error:
    return 0;
}
Пример #3
0
static void all_colormap_add(const Gif_Colormap* src) {
    int i;

    /* expand dst->col if necessary. This might change dst->col */
    if (all_colormap->ncol + src->ncol >= all_colormap->capacity) {
        all_colormap->capacity *= 2;
        Gif_ReArray(all_colormap->col, Gif_Color, all_colormap->capacity);
    }

    for (i = 0; i < src->ncol; ++i) {
        kchistitem* khi = kchist_add(&all_colormap_hist,
                                     kc_makegfcng(&src->col[i]), 0);
        if (!khi->count) {
            all_colormap->col[all_colormap->ncol] = src->col[i];
            all_colormap->col[all_colormap->ncol].pixel = 0;
            khi->count = all_colormap->ncol;
            ++all_colormap->ncol;
        }
        src->col[i].pixel = khi->count;
    }
}
Пример #4
0
static int
read_compressed_image(Gif_Image *gfi, Gif_Reader *grr, int read_flags)
{
  if (grr->is_record) {
    const uint8_t *first = grr->v;
    uint32_t pos;

    /* scan over image */
    pos = 1;			/* skip min code size */
    while (pos < grr->w) {
      int amt = grr->v[pos];
      pos += amt + 1;
      if (amt == 0) break;
    }
    if (pos > grr->w) pos = grr->w;

    gfi->compressed_len = pos;
    if (read_flags & GIF_READ_CONST_RECORD) {
      gfi->compressed = (uint8_t *)first;
      gfi->free_compressed = 0;
    } else {
      gfi->compressed = Gif_NewArray(uint8_t, gfi->compressed_len);
      gfi->free_compressed = Gif_Free;
      if (!gfi->compressed) return 0;
      memcpy(gfi->compressed, first, gfi->compressed_len);
    }

    /* move reader over that image */
    grr->v += pos;
    grr->w -= pos;

  } else {
    /* non-record; have to read it block by block. */
    uint32_t comp_cap = 1024;
    uint32_t comp_len;
    uint8_t *comp = Gif_NewArray(uint8_t, comp_cap);
    int i;
    if (!comp) return 0;

    /* min code size */
    i = gifgetbyte(grr);
    comp[0] = i;
    comp_len = 1;

    i = gifgetbyte(grr);
    while (i > 0) {
      /* add 2 before check so we don't have to check after loop when appending
	 0 block */
      if (comp_len + i + 2 > comp_cap) {
	comp_cap *= 2;
	Gif_ReArray(comp, uint8_t, comp_cap);
	if (!comp) return 0;
      }
      comp[comp_len] = i;
      gifgetblock(comp + comp_len + 1, i, grr);
      comp_len += i + 1;
      i = gifgetbyte(grr);
    }
    comp[comp_len++] = 0;

    gfi->compressed = comp;
    gfi->compressed_len = comp_len;
    gfi->free_compressed = Gif_Free;
  }

  return 1;
}