Esempio n. 1
0
static int
read_image(Gif_Reader *grr, Gif_Context *gfc, Gif_Image *gfi, int read_flags)
/* returns 0 on memory error */
{
    uint8_t packed;

    gfi->left = gifgetunsigned(grr);
    gfi->top = gifgetunsigned(grr);
    gfi->width = gifgetunsigned(grr);
    gfi->height = gifgetunsigned(grr);
    packed = gifgetbyte(grr);
    GIF_DEBUG(("<%ux%u>", gfi->width, gfi->height));

    if (packed & 0x80) { /* have a local color table */
        int ncol = 1 << ((packed & 0x07) + 1);
        gfi->local = read_color_table(ncol, grr);
        if (!gfi->local) return 0;
        gfi->local->refcount = 1;
    }

    gfi->interlace = (packed & 0x40) != 0;

    /* Keep the compressed data if asked */
    if (read_flags & GIF_READ_COMPRESSED) {
        if (!read_compressed_image(gfi, grr, read_flags))
            return 0;
        if (read_flags & GIF_READ_UNCOMPRESSED) {
            Gif_Reader new_grr;
            make_data_reader(&new_grr, gfi->compressed, gfi->compressed_len);
            if (!uncompress_image(gfc, gfi, &new_grr))
                return 0;
        }

    } else if (read_flags & GIF_READ_UNCOMPRESSED) {
        if (!uncompress_image(gfc, gfi, grr))
            return 0;

    } else {
        /* skip over the image */
        uint8_t buffer[GIF_MAX_BLOCK];
        int i = gifgetbyte(grr);
        while (i > 0) {
            gifgetblock(buffer, i, grr);
            i = gifgetbyte(grr);
        }
    }

    return 1;
}
Esempio n. 2
0
int
Gif_FullUncompressImage(Gif_Image *gfi, Gif_ReadErrorHandler h, void *hthunk)
{
    Gif_Context gfc;
    Gif_Stream fake_gfs;
    Gif_Reader grr;
    int ok = 0;

    /* return right away if image is already uncompressed. this might screw over
       people who expect re-uncompressing to restore the compressed version. */
    if (gfi->img)
        return 2;
    if (gfi->image_data)
        /* we have uncompressed data, but not an 'img' array;
           this shouldn't happen */
        return 0;

    fake_gfs.errors = 0;
    gfc.stream = &fake_gfs;
    gfc.prefix = Gif_NewArray(Gif_Code, GIF_MAX_CODE);
    gfc.suffix = Gif_NewArray(uint8_t, GIF_MAX_CODE);
    gfc.length = Gif_NewArray(uint16_t, GIF_MAX_CODE);
    gfc.handler = h;
    gfc.handler_thunk = hthunk;

    if (gfi && gfc.prefix && gfc.suffix && gfc.length && gfi->compressed) {
        make_data_reader(&grr, gfi->compressed, gfi->compressed_len);
        ok = uncompress_image(&gfc, gfi, &grr);
    }

    Gif_DeleteArray(gfc.prefix);
    Gif_DeleteArray(gfc.suffix);
    Gif_DeleteArray(gfc.length);
    return ok && !fake_gfs.errors;
}
Esempio n. 3
0
static int
read_image(Gif_Reader *grr, Gif_Context *gfc, Gif_Image *gfi, int read_flags)
     /* returns 0 on memory error */
{
  uint8_t packed;

  gfi->left = gifgetunsigned(grr);
  gfi->top = gifgetunsigned(grr);
  gfi->width = gifgetunsigned(grr);
  gfi->height = gifgetunsigned(grr);
  /* Mainline GIF processors (Firefox, etc.) process missing width (height)
     as screen_width (screen_height). */
  if (gfi->width == 0)
      gfi->width = gfc->stream->screen_width;
  if (gfi->height == 0)
      gfi->height = gfc->stream->screen_height;
  /* If still zero, error. */
  if (gfi->width == 0 || gfi->height == 0) {
      gif_read_error(gfc, 1, "image has zero width and/or height");
      Gif_MakeImageEmpty(gfi);
      read_flags = 0;
  }
  /* If position out of range, error. */
  if ((unsigned) gfi->left + (unsigned) gfi->width > 0xFFFF
      || (unsigned) gfi->top + (unsigned) gfi->height > 0xFFFF) {
      gif_read_error(gfc, 1, "image position and/or dimensions out of range");
      Gif_MakeImageEmpty(gfi);
      read_flags = 0;
  }
  GIF_DEBUG(("<%ux%u>", gfi->width, gfi->height));

  packed = gifgetbyte(grr);
  if (packed & 0x80) { /* have a local color table */
    int ncol = 1 << ((packed & 0x07) + 1);
    gfi->local = read_color_table(ncol, grr);
    if (!gfi->local) return 0;
    gfi->local->refcount = 1;
  }

  gfi->interlace = (packed & 0x40) != 0;

  /* Keep the compressed data if asked */
  if (read_flags & GIF_READ_COMPRESSED) {
    if (!read_compressed_image(gfi, grr, read_flags))
      return 0;
    if (read_flags & GIF_READ_UNCOMPRESSED) {
      Gif_Reader new_grr;
      make_data_reader(&new_grr, gfi->compressed, gfi->compressed_len);
      if (!uncompress_image(gfc, gfi, &new_grr))
	return 0;
    }

  } else if (read_flags & GIF_READ_UNCOMPRESSED) {
    if (!uncompress_image(gfc, gfi, grr))
      return 0;

  } else {
    /* skip over the image */
    uint8_t buffer[GIF_MAX_BLOCK];
    int i = gifgetbyte(grr);
    while (i > 0) {
      gifgetblock(buffer, i, grr);
      i = gifgetbyte(grr);
    }
  }

  return 1;
}