Beispiel #1
0
static int
uncompress_image(Gif_Context *gfc, Gif_Image *gfi, Gif_Reader *grr)
{
    if (!Gif_CreateUncompressedImage(gfi)) return 0;
    gfc->width = gfi->width;
    gfc->height = gfi->height;
    gfc->image = gfi->image_data;
    gfc->maximage = gfi->image_data + gfi->width * gfi->height;
    read_image_data(gfc, grr);
    return 1;
}
Beispiel #2
0
Gif_Image *
merge_image(Gif_Stream *dest, Gif_Stream *src, Gif_Image *srci,
            Gt_Frame* srcfr, int same_compressed_ok)
{
  Gif_Colormap *imagecm;
  int i;
  Gif_Colormap *localcm = 0;
  Gif_Colormap *destcm = dest->global;

  uint8_t map[256];             /* map[input pixel value] == output pixval */
  int trivial_map;              /* does the map take input pixval --> the same
                                   pixel value for all colors in the image? */
  uint8_t inused[256];          /* inused[input pival] == 1 iff used */
  uint8_t used[256];            /* used[output pixval K] == 1 iff K was used
                                   in the image */

  Gif_Image *desti;

  /* mark colors that were actually used in this image */
  imagecm = srci->local ? srci->local : src->global;
  merge_image_input_colors(inused, srci);
  for (i = imagecm ? imagecm->ncol : 0; i != 256; ++i)
      if (inused[i]) {
          lwarning(srcfr->input_filename, "some colors undefined by colormap");
          break;
      }

  /* map[old_pixel_value] == new_pixel_value */
  for (i = 0; i < 256; i++)
      map[i] = used[i] = 0;

  /* Merge the colormap */
  if (merge_colormap_if_possible(dest->global, imagecm)) {
      /* Create 'map' and 'used' for global colormap. */
      for (i = 0; i != 256; ++i)
          if (inused[i]) {
              if (imagecm && i < imagecm->ncol)
                  map[i] = imagecm->col[i].pixel;
              else
                  map[i] = 0;
          }

  } else {
      /* Need a local colormap. */
      destcm = localcm = Gif_NewFullColormap(0, 256);
      for (i = 0; i != 256; ++i)
          if (inused[i]) {
              map[i] = localcm->ncol;
              localcm->col[localcm->ncol] = imagecm->col[i];
              ++localcm->ncol;
          }
  }

  trivial_map = 1;
  for (i = 0; i != 256; ++i)
      if (inused[i]) {
          used[map[i]] = 1;
          trivial_map = trivial_map && map[i] == i;
      }

  /* Decide on a transparent index */
  if (srci->transparent >= 0) {
    int found_transparent = -1;

    /* try to keep the map trivial -- prefer same transparent index */
    if (trivial_map && !used[srci->transparent])
      found_transparent = srci->transparent;
    else
      for (i = destcm->ncol - 1; i >= 0; i--)
        if (!used[i])
          found_transparent = i;

    /* 1.Aug.1999 - Allow for the case that the transparent index is bigger
       than the number of colors we've created thus far. */
    if (found_transparent < 0 || found_transparent >= destcm->ncol) {
      Gif_Color *c;
      found_transparent = destcm->ncol;
      /* 1.Aug.1999 - Don't update destcm->ncol -- we want the output colormap
         to be as small as possible. */
      c = &destcm->col[found_transparent];
      if (imagecm && srci->transparent < imagecm->ncol)
        *c = imagecm->col[srci->transparent];
      c->haspixel = 2;
      assert(c->haspixel == 2 && found_transparent < 256);
    }

    map[srci->transparent] = found_transparent;
    if (srci->transparent != found_transparent) trivial_map = 0;
  }

  assert(destcm->ncol <= 256);
  /* Make the new image. */
  desti = Gif_NewImage();

  desti->identifier = Gif_CopyString(srci->identifier);
  if (srci->transparent > -1)
    desti->transparent = map[srci->transparent];
  desti->delay = srci->delay;
  desti->disposal = srci->disposal;
  desti->left = srci->left;
  desti->top = srci->top;
  desti->interlace = srci->interlace;

  desti->width = srci->width;
  desti->height = srci->height;
  desti->local = localcm;

  if (trivial_map && same_compressed_ok && srci->compressed) {
    desti->compressed_len = srci->compressed_len;
    desti->compressed = Gif_NewArray(uint8_t, srci->compressed_len);
    desti->free_compressed = Gif_Free;
    memcpy(desti->compressed, srci->compressed, srci->compressed_len);
  } else {
    int i, j;
    Gif_CreateUncompressedImage(desti, desti->interlace);

    if (trivial_map)
      for (j = 0; j < desti->height; j++)
        memcpy(desti->img[j], srci->img[j], desti->width);

    else
      for (j = 0; j < desti->height; j++) {
        uint8_t *srcdata = srci->img[j];
        uint8_t *destdata = desti->img[j];
        for (i = 0; i < desti->width; i++, srcdata++, destdata++)
          *destdata = map[*srcdata];
      }
  }

  /* comments and extensions */
  if (srci->comment) {
    desti->comment = Gif_NewComment();
    merge_comments(desti->comment, srci->comment);
  }
  if (srci->extension_list && !srcfr->no_extensions) {
      Gif_Extension* gfex;
      for (gfex = srci->extension_list; gfex; gfex = gfex->next)
          if (gfex->kind != 255 || !srcfr->no_app_extensions)
              Gif_AddExtension(dest, desti, Gif_CopyExtension(gfex));
  }
  while (srcfr->extensions) {
      Gif_Extension* next = srcfr->extensions->next;
      Gif_AddExtension(dest, desti, srcfr->extensions);
      srcfr->extensions = next;
  }

  Gif_AddImage(dest, desti);
  return desti;
}