コード例 #1
0
ファイル: gifunopt.c プロジェクト: c0ns0le/nikkhokkho
int
Gif_FullUnoptimize(Gif_Stream *gfs, int flags)
{
    int ok = 1;
    int i;
    unsigned pos, size;
    uint16_t *screen;
    uint16_t background;
    Gif_Image *gfi;

    if (gfs->nimages < 1) return 1;
    for (i = 0; i < gfs->nimages; i++)
        if (gfs->images[i]->local)
            return 0;
    if (!gfs->global)
        return 0;

    Gif_CalculateScreenSize(gfs, 0);
    size = gfs->screen_width * gfs->screen_height;

    screen = Gif_NewArray(uint16_t, size);
    gfi = gfs->images[0];
    if (gfi->transparent < 0
            && gfs->global && gfs->background < gfs->global->ncol)
        background = gfs->background;
    else
        background = TRANSPARENT;
    for (pos = 0; pos != size; ++pos)
        screen[pos] = background;

    for (i = 0; i < gfs->nimages; i++)
        if (!unoptimize_image(gfs, gfs->images[i], screen))
            ok = 0;

    if (ok) {
        if (flags & GIF_UNOPTIMIZE_SIMPLEST_DISPOSAL) {
            /* set disposal based on use of transparency.
               If (every transparent pixel in frame i is also transparent in frame
               i - 1), then frame i - 1 gets disposal ASIS; otherwise, disposal
               BACKGROUND. */
            for (i = 0; i < gfs->nimages; ++i)
                if (i == gfs->nimages - 1
                        || no_more_transparency(gfs->images[i+1], gfs->images[i]))
                    gfs->images[i]->disposal = GIF_DISPOSAL_NONE;
                else
                    gfs->images[i]->disposal = GIF_DISPOSAL_BACKGROUND;
        } else
            for (i = 0; i < gfs->nimages; ++i)
                gfs->images[i]->disposal = GIF_DISPOSAL_BACKGROUND;
    }

    Gif_DeleteArray(screen);
    return ok;
}
コード例 #2
0
ファイル: gifdiff.c プロジェクト: alexzhuustc/gifsicle
int
compare(Gif_Stream *s1, Gif_Stream *s2)
{
  Gif_Colormap *newcm;
  int imageno1, imageno2, background1, background2;
  char buf1[256], buf2[256], fbuf[256];

  was_different = 0;

  /* Compare image counts and screen sizes. If either of these differs, quit
     early. */
  Gif_CalculateScreenSize(s1, 0);
  Gif_CalculateScreenSize(s2, 0);

  if (s1->nimages != s2->nimages
      && (s1->nimages == 0 || s2->nimages == 0)) {
    different("frame counts differ: <#%d >#%d", s1->nimages, s2->nimages);
    return DIFFERENT;
  }

  if (s1->screen_width != s2->screen_width
      || s1->screen_height != s2->screen_height) {
    different("screen sizes differ: <%dx%d >%dx%d", s1->screen_width,
	      s1->screen_height, s2->screen_width, s2->screen_height);
    return DIFFERENT;
  }

  if (s1->screen_width == 0 || s1->screen_height == 0
      || s2->screen_width == 0 || s2->screen_height == 0) {
    /* paranoia -- don't think this can happen */
    different("zero screen sizes");
    return DIFFERENT;
  }

  /* Create arrays for the image data */
  screen_width = s1->screen_width;
  screen_height = s1->screen_height;

  gdata[0] = Gif_NewArray(uint16_t, screen_width * screen_height);
  gdata[1] = Gif_NewArray(uint16_t, screen_width * screen_height);
  glast[0] = Gif_NewArray(uint16_t, screen_width * screen_height);
  glast[1] = Gif_NewArray(uint16_t, screen_width * screen_height);
  scratch = Gif_NewArray(uint16_t, screen_width * screen_height);
  line = Gif_NewArray(uint16_t, screen_width);

  /* Merge all distinct colors from the two images into one colormap, setting
     the 'pixel' slots in the images' colormaps to the corresponding values
     in the merged colormap. Don't forget transparency */
  newcm = Gif_NewFullColormap(1, 256);
  combine_colormaps(s1->global, newcm);
  combine_colormaps(s2->global, newcm);
  for (imageno1 = 0; imageno1 < s1->nimages; ++imageno1)
    combine_colormaps(s1->images[imageno1]->local, newcm);
  for (imageno2 = 0; imageno2 < s2->nimages; ++imageno2)
    combine_colormaps(s2->images[imageno2]->local, newcm);

  /* Choose the background values and clear the image data arrays */
  if (s1->images[0]->transparent >= 0 || !s1->global)
    background1 = TRANSP;
  else
    background1 = s1->global->col[ s1->background ].pixel;

  if (s2->images[0]->transparent >= 0 || !s2->global)
    background2 = TRANSP;
  else
    background2 = s2->global->col[ s2->background ].pixel;

  fill_area(gdata[0], 0, 0, screen_width, screen_height, background1);
  fill_area(gdata[1], 0, 0, screen_width, screen_height, background2);

  /* Loopcounts differ? */
  if (s1->loopcount != s2->loopcount) {
    name_loopcount(s1->loopcount, buf1);
    name_loopcount(s2->loopcount, buf2);
    different("loop counts differ: <%s >%s", buf1, buf2);
  }

  /* Loop over frames, comparing image data and delays */
  apply_image(0, s1, 0, background1);
  apply_image(1, s2, 0, background2);
  imageno1 = imageno2 = 0;
  while (imageno1 != s1->nimages && imageno2 != s2->nimages) {
    int fi1 = imageno1, fi2 = imageno2,
      delay1 = s1->images[fi1]->delay, delay2 = s2->images[fi2]->delay;

    /* get message right */
    if (imageno1 == imageno2)
      sprintf(fbuf, "#%d", imageno1);
    else
      sprintf(fbuf, "<#%d >#%d", imageno1, imageno2);

    /* compare pixels */
    if (memcmp(gdata[0], gdata[1],
	       screen_width * screen_height * sizeof(uint16_t)) != 0) {
      unsigned d, c = screen_width * screen_height;
      uint16_t *d1 = gdata[0], *d2 = gdata[1];
      for (d = 0; d < c; d++, d1++, d2++)
	if (*d1 != *d2) {
	  name_color(*d1, newcm, buf1);
	  name_color(*d2, newcm, buf2);
	  different("frame %s pixels differ: %d,%d <%s >%s",
		    fbuf, d % screen_width, d / screen_width, buf1, buf2);
	  break;
	}
    }

    /* move to next images, skipping redundancy */
    for (++imageno1;
	 imageno1 < s1->nimages && !apply_image(0, s1, imageno1, background1);
	 ++imageno1)
      delay1 += s1->images[imageno1]->delay;
    for (++imageno2;
	 imageno2 < s2->nimages && !apply_image(1, s2, imageno2, background2);
	 ++imageno2)
      delay2 += s2->images[imageno2]->delay;

    if (!ignore_redundancy) {
      fi1 = (imageno1 - fi1) - (imageno2 - fi2);
      for (; fi1 > 0; --fi1)
	different("extra redundant frame: <#%d", imageno1 - fi1);
      for (; fi1 < 0; ++fi1)
	different("extra redundant frame: >#%d", imageno2 + fi1);
    }

    if (delay1 != delay2) {
      name_delay(delay1, buf1);
      name_delay(delay2, buf2);
      different("frame %s delays differ: <%s >%s", fbuf, buf1, buf2);
    }
  }

  if (imageno1 != s1->nimages || imageno2 != s2->nimages)
    different("frame counts differ: <#%d >#%d", s1->nimages, s2->nimages);

  /* That's it! */
  Gif_DeleteColormap(newcm);
  Gif_DeleteArray(gdata[0]);
  Gif_DeleteArray(gdata[1]);
  Gif_DeleteArray(glast[0]);
  Gif_DeleteArray(glast[1]);
  Gif_DeleteArray(scratch);
  Gif_DeleteArray(line);

  return was_different ? DIFFERENT : SAME;
}
コード例 #3
0
ファイル: optimize.c プロジェクト: alberthdev/CEmu
static int
initialize_optimizer(Gif_Stream *gfs)
{
  int i;

  if (gfs->nimages < 1)
    return 0;

  /* combine colormaps */
  all_colormap = Gif_NewFullColormap(1, 384);
  all_colormap->col[0].gfc_red = 255;
  all_colormap->col[0].gfc_green = 255;
  all_colormap->col[0].gfc_blue = 255;

  in_global_map = gfs->global;
  if (!in_global_map) {
    Gif_Color *col;
    in_global_map = Gif_NewFullColormap(256, 256);
    col = in_global_map->col;
    for (i = 0; i < 256; i++, col++)
      col->gfc_red = col->gfc_green = col->gfc_blue = i;
  }

  {
    int any_globals = 0;
    int first_transparent = -1;

    kchist_init(&all_colormap_hist);
    for (i = 0; i < gfs->nimages; i++) {
      Gif_Image *gfi = gfs->images[i];
      if (gfi->local)
        all_colormap_add(gfi->local);
      else
        any_globals = 1;
      if (gfi->transparent >= 0 && first_transparent < 0)
        first_transparent = i;
    }
    if (any_globals)
      all_colormap_add(in_global_map);
    kchist_cleanup(&all_colormap_hist);

    /* try and maintain transparency's pixel value */
    if (first_transparent >= 0) {
      Gif_Image *gfi = gfs->images[first_transparent];
      Gif_Colormap *gfcm = gfi->local ? gfi->local : gfs->global;
      all_colormap->col[TRANSP] = gfcm->col[gfi->transparent];
    }
  }

  /* find screen_width and screen_height, and clip all images to screen */
  Gif_CalculateScreenSize(gfs, 0);
  screen_width = gfs->screen_width;
  screen_height = gfs->screen_height;
  for (i = 0; i < gfs->nimages; i++)
    Gif_ClipImage(gfs->images[i], 0, 0, screen_width, screen_height);

  /* choose background */
  if (gfs->images[0]->transparent < 0
      && gfs->global && gfs->background < in_global_map->ncol)
    background = in_global_map->col[gfs->background].pixel;
  else
    background = TRANSP;

  return 1;
}
コード例 #4
0
static int
initialize_optimizer(Gif_Stream *gfs)
{
  int i;
  unsigned screen_size;

  if (gfs->nimages < 1)
    return 0;

  /* combine colormaps */
  all_colormap = Gif_NewFullColormap(1, 384);
  all_colormap->col[0].gfc_red = 255;
  all_colormap->col[0].gfc_green = 255;
  all_colormap->col[0].gfc_blue = 255;

  in_global_map = gfs->global;
  if (!in_global_map) {
    Gif_Color *col;
    in_global_map = Gif_NewFullColormap(256, 256);
    col = in_global_map->col;
    for (i = 0; i < 256; i++, col++)
      col->gfc_red = col->gfc_green = col->gfc_blue = i;
  }

  {
    int any_globals = 0;
    int first_transparent = -1;
    for (i = 0; i < gfs->nimages; i++) {
      Gif_Image *gfi = gfs->images[i];
      if (gfi->local)
	colormap_combine(all_colormap, gfi->local);
      else
	any_globals = 1;
      if (gfi->transparent >= 0 && first_transparent < 0)
	first_transparent = i;
    }
    if (any_globals)
      colormap_combine(all_colormap, in_global_map);

    /* try and maintain transparency's pixel value */
    if (first_transparent >= 0) {
      Gif_Image *gfi = gfs->images[first_transparent];
      Gif_Colormap *gfcm = gfi->local ? gfi->local : gfs->global;
      all_colormap->col[TRANSP] = gfcm->col[gfi->transparent];
    }
  }

  /* find screen_width and screen_height, and clip all images to screen */
  Gif_CalculateScreenSize(gfs, 0);
  screen_width = gfs->screen_width;
  screen_height = gfs->screen_height;
  for (i = 0; i < gfs->nimages; i++)
    Gif_ClipImage(gfs->images[i], 0, 0, screen_width, screen_height);

  /* create data arrays */
  screen_size = (unsigned) screen_width * (unsigned) screen_height;
  last_data = Gif_NewArray(uint16_t, screen_size);
  this_data = Gif_NewArray(uint16_t, screen_size);

  /* set up colormaps */
  gif_color_count = 2;
  while (gif_color_count < gfs->global->ncol && gif_color_count < 256)
    gif_color_count *= 2;

  /* choose background */
  if (gfs->images[0]->transparent < 0
      && gfs->background < in_global_map->ncol)
    background = in_global_map->col[gfs->background].pixel;
  else
    background = TRANSP;

  return 1;
}