Doxygen Source Code Documentation
gifsicle.h File Reference
#include "gif.h"
#include "clp.h"
Go to the source code of this file.
Define Documentation
|
Definition at line 202 of file gifsicle.h. Referenced by do_colormap_change(), and main(). |
|
Definition at line 201 of file gifsicle.h. Referenced by do_colormap_change(), initialize_def_frame(), and main(). |
|
Definition at line 158 of file gifsicle.h. Referenced by find_background(), and merge_colormap_if_possible(). |
|
Definition at line 203 of file gifsicle.h. Referenced by do_colormap_change(), and main(). |
|
Definition at line 143 of file gifsicle.h. Referenced by main(). |
|
Definition at line 142 of file gifsicle.h. Referenced by main(). |
|
Definition at line 144 of file gifsicle.h. Referenced by fatal_error(), and main(). |
|
Definition at line 255 of file gifsicle.h. Referenced by blank_frameset(), merger_flatten(), output_frames(), output_information(), set_frame_change(), and show_frame(). |
|
Definition at line 15 of file gifsicle.h. |
Typedef Documentation
|
Definition at line 208 of file gifsicle.h. |
|
Definition at line 177 of file gifsicle.h. Referenced by append_color_transform(), and delete_color_transforms(). |
|
Definition at line 210 of file gifsicle.h. Referenced by colormap_stream(), and do_set_colormap(). |
|
Definition at line 84 of file gifsicle.h. |
|
Definition at line 20 of file gifsicle.h. |
|
Definition at line 19 of file gifsicle.h. |
|
|
|
Definition at line 18 of file gifsicle.h. |
Function Documentation
|
Definition at line 929 of file support.c. References blank_frameset(), Gt_Frameset::cap, clear_def_frame_once_options(), Gt_Frameset::count, Gt_Frameset::f, Gif_ReArray, Gt_Frame::image, Gif_Stream::refcount, Gif_Image::refcount, and Gt_Frame::stream. Referenced by input_stream(), and show_frame().
00930 { 00931 if (number < 0) { 00932 while (fset->count >= fset->cap) { 00933 fset->cap *= 2; 00934 Gif_ReArray(fset->f, Gt_Frame, fset->cap); 00935 } 00936 number = fset->count++; 00937 } else { 00938 assert(number < fset->count); 00939 blank_frameset(fset, number, number, 0); 00940 } 00941 00942 /* Mark the stream and the image both */ 00943 gfs->refcount++; 00944 gfi->refcount++; 00945 fset->f[number] = def_frame; 00946 fset->f[number].stream = gfs; 00947 fset->f[number].image = gfi; 00948 00949 clear_def_frame_once_options(); 00950 00951 return &fset->f[number]; 00952 } |
|
Definition at line 104 of file xform.c. References append_color_transform(), color_change_transformer(), Gt_ColorTransform::data, Gt_ColorTransform::func, Gif_New, Gt_ColorChange::new_color, Gt_ColorChange::next, Gt_ColorTransform::next, and Gt_ColorChange::old_color.
00106 { 00107 Gt_ColorTransform *xform; 00108 Gt_ColorChange *change = Gif_New(Gt_ColorChange); 00109 change->old_color = old_color; 00110 change->new_color = new_color; 00111 change->next = 0; 00112 00113 for (xform = list; xform && xform->next; xform = xform->next) 00114 ; 00115 if (!xform || xform->func != &color_change_transformer) 00116 return append_color_transform(list, &color_change_transformer, change); 00117 else { 00118 Gt_ColorChange *prev = (Gt_ColorChange *)(xform->data); 00119 while (prev->next) prev = prev->next; 00120 prev->next = change; 00121 return list; 00122 } 00123 } |
|
Definition at line 25 of file xform.c. References color_transform_func, Gt_ColorTransform::data, Gt_ColorTransform::func, Gif_New, and Gt_ColorTransform::next. Referenced by append_color_change().
00027 { 00028 Gt_ColorTransform *trav; 00029 Gt_ColorTransform *xform = Gif_New(Gt_ColorTransform); 00030 xform->next = 0; 00031 xform->func = func; 00032 xform->data = data; 00033 00034 for (trav = list; trav && trav->next; trav = trav->next) 00035 ; 00036 if (trav) { 00037 trav->next = xform; 00038 return list; 00039 } else 00040 return xform; 00041 } |
|
Definition at line 61 of file xform.c. References Gt_ColorTransform::data, Gt_ColorTransform::func, Gif_Stream::global, i, Gif_Stream::images, Gt_ColorTransform::next, and Gif_Stream::nimages. Referenced by input_stream(), and merge_and_write_frames().
00062 { 00063 int i; 00064 Gt_ColorTransform *xform; 00065 for (xform = list; xform; xform = xform->next) { 00066 if (gfs->global) 00067 xform->func(gfs->global, xform->data); 00068 for (i = 0; i < gfs->nimages; i++) 00069 if (gfs->images[i]->local) 00070 xform->func(gfs->images[i]->local, xform->data); 00071 } 00072 } |
|
END MERGE LOOP * Definition at line 1405 of file support.c. References Gt_Frameset::count, Gt_Frameset::f, FRAME, Gif_Delete, Gif_DeleteArray, Gif_DeleteComment(), Gif_DeleteStream(), and i. Referenced by add_frame(), clear_frameset(), and main().
01406 { 01407 int i; 01408 if (delete_object) f1 = 0, f2 = -1; 01409 if (f2 < 0) f2 = fset->count - 1; 01410 for (i = f1; i <= f2; i++) { 01411 /* We may have deleted stream and image earlier to save on memory; see 01412 above in merge_frame_interval(); but if we didn't, do it now. */ 01413 if (FRAME(fset, i).image && FRAME(fset, i).image->refcount > 1) 01414 FRAME(fset, i).image->refcount--; 01415 Gif_DeleteStream(FRAME(fset, i).stream); 01416 Gif_DeleteComment(FRAME(fset, i).comment); 01417 if (FRAME(fset, i).nest) 01418 blank_frameset(FRAME(fset, i).nest, 0, 0, 1); 01419 } 01420 if (delete_object) { 01421 Gif_DeleteArray(fset->f); 01422 Gif_Delete(fset); 01423 } 01424 } |
|
Definition at line 906 of file support.c. Referenced by add_frame().
00907 { 00908 /* Get rid of next-frame-only options. 00909 00910 This causes problems with frame selection. In the command `gifsicle 00911 -nblah f.gif', the name should be applied to frame 0 of f.gif. This will 00912 happen automatically when f.gif is read, since all of its frames will be 00913 added when it is input. After frame 0, the name in def_frame will be 00914 cleared. 00915 00916 Now, `gifsicle -nblah f.gif #1' should apply the name to frame 1 of 00917 f.gif. But once f.gif is input, its frames are added, and the name 00918 component of def_frame is cleared!! So when #1 comes around it's gone! 00919 00920 We handle this in gifsicle.c using the _change fields. */ 00921 00922 def_frame.name = 0; 00923 def_frame.comment = 0; 00924 def_frame.extensions = 0; 00925 } |
|
Definition at line 1428 of file support.c. References blank_frameset(), and Gt_Frameset::count. Referenced by output_frames(), and show_frame().
01429 { 01430 blank_frameset(fset, f1, -1, 0); 01431 fset->count = f1; 01432 } |
|
Definition at line 95 of file support.c. References verbose_endline().
00096 { 00097 verbose_endline(); 00098 fputs(message, stderr); 00099 } |
|
Definition at line 82 of file xform.c. References Gif_Colormap::col, GIF_COLOREQ, Gif_Color::haspixel, i, Gif_Colormap::ncol, Gt_ColorChange::new_color, Gt_ColorChange::next, Gt_ColorChange::old_color, and Gif_Color::pixel. Referenced by append_color_change().
00083 { 00084 int i, have; 00085 Gt_ColorChange *first_change = (Gt_ColorChange *)thunk; 00086 Gt_ColorChange *change; 00087 00088 /* change colors named by color */ 00089 for (i = 0; i < gfcm->ncol; i++) 00090 for (change = first_change; change; change = change->next) { 00091 if (!change->old_color.haspixel) 00092 have = GIF_COLOREQ(&gfcm->col[i], &change->old_color); 00093 else 00094 have = change->old_color.pixel == i; 00095 00096 if (have) { 00097 gfcm->col[i] = change->new_color; 00098 break; /* ignore remaining color changes */ 00099 } 00100 } 00101 } |
|
Definition at line 517 of file quantize.c. References colormap_diversity().
00518 { 00519 return colormap_diversity(hist, nhist, adapt_size, 1); 00520 } |
|
Definition at line 523 of file quantize.c. References colormap_diversity().
00524 { 00525 return colormap_diversity(hist, nhist, adapt_size, 0); 00526 } |
|
Definition at line 712 of file quantize.c. References Gif_Color::blue, Gif_Colormap::col, DITHER_SCALE, DITHER_SCALE_M1, Gif_DeleteArray, Gif_NewArray, Gif_Color::green, hash_color(), Gif_Image::height, i, Gif_Image::img, Gif_Image::left, max, min, N_RANDOM_VALUES, RANDOM, Gif_Color::red, Gif_Image::transparent, u_int32_t, and Gif_Image::width.
00715 { 00716 static int32_t *random_values = 0; 00717 00718 int width = gfi->width; 00719 int dither_direction = 0; 00720 int transparent = gfi->transparent; 00721 int i, j; 00722 int32_t *r_err, *g_err, *b_err, *r_err1, *g_err1, *b_err1; 00723 Gif_Color *col = old_cm->col; 00724 Gif_Color *new_col = new_cm->col; 00725 00726 /* This code was written with reference to ppmquant by Jef Poskanzer, part 00727 of the pbmplus package. */ 00728 00729 /* Initialize Floyd-Steinberg error vectors to small random values, so we 00730 don't get artifacts on the top row */ 00731 r_err = Gif_NewArray(int32_t, width + 2); 00732 g_err = Gif_NewArray(int32_t, width + 2); 00733 b_err = Gif_NewArray(int32_t, width + 2); 00734 r_err1 = Gif_NewArray(int32_t, width + 2); 00735 g_err1 = Gif_NewArray(int32_t, width + 2); 00736 b_err1 = Gif_NewArray(int32_t, width + 2); 00737 /* Use the same random values on each call in an attempt to minimize 00738 "jumping dithering" effects on animations */ 00739 if (!random_values) { 00740 random_values = Gif_NewArray(int32_t, N_RANDOM_VALUES); 00741 for (i = 0; i < N_RANDOM_VALUES; i++) 00742 random_values[i] = RANDOM() % (DITHER_SCALE_M1 * 2) - DITHER_SCALE_M1; 00743 } 00744 for (i = 0; i < gfi->width + 2; i++) { 00745 int j = (i + gfi->left) * 3; 00746 r_err[i] = random_values[ (j + 0) % N_RANDOM_VALUES ]; 00747 g_err[i] = random_values[ (j + 1) % N_RANDOM_VALUES ]; 00748 b_err[i] = random_values[ (j + 2) % N_RANDOM_VALUES ]; 00749 } 00750 /* *_err1 initialized below */ 00751 00752 /* Do the image! */ 00753 for (j = 0; j < gfi->height; j++) { 00754 int d0, d1, d2, d3; /* used for error diffusion */ 00755 byte *data, *new_data; 00756 int x; 00757 00758 if (dither_direction) { 00759 x = width - 1; 00760 d0 = 0, d1 = 2, d2 = 1, d3 = 0; 00761 } else { 00762 x = 0; 00763 d0 = 2, d1 = 0, d2 = 1, d3 = 2; 00764 } 00765 data = &gfi->img[j][x]; 00766 new_data = all_new_data + j * width + x; 00767 00768 for (i = 0; i < width + 2; i++) 00769 r_err1[i] = g_err1[i] = b_err1[i] = 0; 00770 00771 /* Do a single row */ 00772 while (x >= 0 && x < width) { 00773 int e, use_r, use_g, use_b; 00774 00775 /* the transparent color never gets adjusted */ 00776 if (*data == transparent) 00777 goto next; 00778 00779 /* use Floyd-Steinberg errors to adjust actual color */ 00780 use_r = col[*data].red + r_err[x+1] / DITHER_SCALE; 00781 use_g = col[*data].green + g_err[x+1] / DITHER_SCALE; 00782 use_b = col[*data].blue + b_err[x+1] / DITHER_SCALE; 00783 use_r = max(use_r, 0); use_r = min(use_r, 255); 00784 use_g = max(use_g, 0); use_g = min(use_g, 255); 00785 use_b = max(use_b, 0); use_b = min(use_b, 255); 00786 00787 *new_data = hash_color(use_r, use_g, use_b, hash, new_cm); 00788 histogram[*new_data]++; 00789 00790 /* calculate and propagate the error between desired and selected color. 00791 Assume that, with a large scale (1024), we don't need to worry about 00792 image artifacts caused by error accumulation (the fact that the 00793 error terms might not sum to the error). */ 00794 e = (use_r - new_col[*new_data].red) * DITHER_SCALE; 00795 if (e) { 00796 r_err [x+d0] += (e * 7) / 16; 00797 r_err1[x+d1] += (e * 3) / 16; 00798 r_err1[x+d2] += (e * 5) / 16; 00799 r_err1[x+d3] += e / 16; 00800 } 00801 00802 e = (use_g - new_col[*new_data].green) * DITHER_SCALE; 00803 if (e) { 00804 g_err [x+d0] += (e * 7) / 16; 00805 g_err1[x+d1] += (e * 3) / 16; 00806 g_err1[x+d2] += (e * 5) / 16; 00807 g_err1[x+d3] += e / 16; 00808 } 00809 00810 e = (use_b - new_col[*new_data].blue) * DITHER_SCALE; 00811 if (e) { 00812 b_err [x+d0] += (e * 7) / 16; 00813 b_err1[x+d1] += (e * 3) / 16; 00814 b_err1[x+d2] += (e * 5) / 16; 00815 b_err1[x+d3] += e / 16; 00816 } 00817 00818 next: 00819 if (dither_direction) 00820 x--, data--, new_data--; 00821 else 00822 x++, data++, new_data++; 00823 } 00824 /* Did a single row */ 00825 00826 /* change dithering directions */ 00827 { 00828 int32_t *temp; 00829 temp = r_err; r_err = r_err1; r_err1 = temp; 00830 temp = g_err; g_err = g_err1; g_err1 = temp; 00831 temp = b_err; b_err = b_err1; b_err1 = temp; 00832 dither_direction = !dither_direction; 00833 } 00834 } 00835 00836 /* delete temporary storage */ 00837 Gif_DeleteArray(r_err); 00838 Gif_DeleteArray(g_err); 00839 Gif_DeleteArray(b_err); 00840 Gif_DeleteArray(r_err1); 00841 Gif_DeleteArray(g_err1); 00842 Gif_DeleteArray(b_err1); 00843 } |
|
Definition at line 675 of file quantize.c. References Gif_Colormap::col, hash_color(), Gif_Image::height, i, Gif_Image::img, ncol, Gif_Colormap::ncol, Gif_Image::transparent, u_int32_t, and Gif_Image::width.
00678 { 00679 int ncol = old_cm->ncol; 00680 Gif_Color *col = old_cm->col; 00681 int map[256]; 00682 int i, j; 00683 int transparent = gfi->transparent; 00684 00685 /* find closest colors in new colormap */ 00686 for (i = 0; i < ncol; i++) 00687 if (col[i].haspixel) 00688 map[i] = col[i].pixel; 00689 else { 00690 map[i] = col[i].pixel = 00691 hash_color(col[i].red, col[i].green, col[i].blue, hash, new_cm); 00692 col[i].haspixel = 1; 00693 } 00694 00695 /* map image */ 00696 for (j = 0; j < gfi->height; j++) { 00697 byte *data = gfi->img[j]; 00698 for (i = 0; i < gfi->width; i++, data++, new_data++) 00699 if (*data != transparent) { 00700 *new_data = map[*data]; 00701 histogram[*new_data]++; 00702 } 00703 } 00704 } |
|
Definition at line 236 of file quantize.c. References assert_hist_transparency(), Gif_Color::blue, blue_sort_compare(), Gif_Colormap::col, adaptive_slot::count, fatal_error(), adaptive_slot::first, Gif_DeleteArray, Gif_NewArray, Gif_NewFullColormap(), Gif_Color::green, green_sort_compare(), Gif_Color::haspixel, i, max, min, Gif_Colormap::ncol, adaptive_slot::pixel, Gif_Color::pixel, pixel_sort_compare(), Gif_Color::red, red_sort_compare(), u_int32_t, and warning().
00237 { 00238 adaptive_slot *slots = Gif_NewArray(adaptive_slot, adapt_size); 00239 Gif_Colormap *gfcm = Gif_NewFullColormap(adapt_size, 256); 00240 Gif_Color *adapt = gfcm->col; 00241 int nadapt; 00242 int i, j; 00243 00244 /* This code was written with reference to ppmquant by Jef Poskanzer, part 00245 of the pbmplus package. */ 00246 00247 if (adapt_size < 2 || adapt_size > 256) 00248 fatal_error("adaptive palette size must be between 2 and 256"); 00249 if (adapt_size >= nhist) { 00250 warning("trivial adaptive palette (only %d colors in source)", nhist); 00251 adapt_size = nhist; 00252 } 00253 00254 /* 0. remove any transparent color from consideration; reduce adaptive 00255 palette size to accommodate transparency if it looks like that'll be 00256 necessary */ 00257 assert_hist_transparency(hist, nhist); 00258 if (adapt_size > 2 && adapt_size < nhist && hist[0].haspixel == 255 00259 && nhist <= 265) 00260 adapt_size--; 00261 if (hist[0].haspixel == 255) { 00262 hist[0] = hist[nhist - 1]; 00263 nhist--; 00264 } 00265 00266 /* 1. set up the first slot, containing all pixels. */ 00267 { 00268 u_int32_t total = 0; 00269 for (i = 0; i < nhist; i++) 00270 total += hist[i].pixel; 00271 slots[0].first = 0; 00272 slots[0].count = nhist; 00273 slots[0].pixel = total; 00274 qsort(hist, nhist, sizeof(Gif_Color), pixel_sort_compare); 00275 } 00276 00277 /* 2. split slots until we have enough. */ 00278 for (nadapt = 1; nadapt < adapt_size; nadapt++) { 00279 adaptive_slot *split = 0; 00280 Gif_Color minc, maxc, *slice; 00281 00282 /* 2.1. pick the slot to split. */ 00283 { 00284 u_int32_t split_pixel = 0; 00285 for (i = 0; i < nadapt; i++) 00286 if (slots[i].count >= 2 && slots[i].pixel > split_pixel) { 00287 split = &slots[i]; 00288 split_pixel = slots[i].pixel; 00289 } 00290 if (!split) 00291 break; 00292 } 00293 slice = &hist[split->first]; 00294 00295 /* 2.2. find its extent. */ 00296 { 00297 Gif_Color *trav = slice; 00298 minc = maxc = *trav; 00299 for (i = 1, trav++; i < split->count; i++, trav++) { 00300 minc.red = min(minc.red, trav->red); 00301 maxc.red = max(maxc.red, trav->red); 00302 minc.green = min(minc.green, trav->green); 00303 maxc.green = max(maxc.green, trav->green); 00304 minc.blue = min(minc.blue, trav->blue); 00305 maxc.blue = max(maxc.blue, trav->blue); 00306 } 00307 } 00308 00309 /* 2.3. decide how to split it. use the luminance method. also sort the 00310 colors. */ 00311 { 00312 double red_diff = 0.299 * (maxc.red - minc.red); 00313 double green_diff = 0.587 * (maxc.green - minc.green); 00314 double blue_diff = 0.114 * (maxc.blue - minc.blue); 00315 if (red_diff >= green_diff && red_diff >= blue_diff) 00316 qsort(slice, split->count, sizeof(Gif_Color), red_sort_compare); 00317 else if (green_diff >= blue_diff) 00318 qsort(slice, split->count, sizeof(Gif_Color), green_sort_compare); 00319 else 00320 qsort(slice, split->count, sizeof(Gif_Color), blue_sort_compare); 00321 } 00322 00323 /* 2.4. decide where to split the slot and split it there. */ 00324 { 00325 u_int32_t half_pixels = split->pixel / 2; 00326 u_int32_t pixel_accum = slice[0].pixel; 00327 u_int32_t diff1, diff2; 00328 for (i = 1; i < split->count - 1 && pixel_accum < half_pixels; i++) 00329 pixel_accum += slice[i].pixel; 00330 00331 /* We know the area before the split has more pixels than the area 00332 after, possibly by a large margin (bad news). If it would shrink the 00333 margin, change the split. */ 00334 diff1 = 2*pixel_accum - split->pixel; 00335 diff2 = split->pixel - 2*(pixel_accum - slice[i-1].pixel); 00336 if (diff2 < diff1 && i > 1) { 00337 i--; 00338 pixel_accum -= slice[i].pixel; 00339 } 00340 00341 slots[nadapt].first = split->first + i; 00342 slots[nadapt].count = split->count - i; 00343 slots[nadapt].pixel = split->pixel - pixel_accum; 00344 split->count = i; 00345 split->pixel = pixel_accum; 00346 } 00347 } 00348 00349 /* 3. make the new palette by choosing one color from each slot. */ 00350 for (i = 0; i < nadapt; i++) { 00351 double red_total = 0, green_total = 0, blue_total = 0; 00352 Gif_Color *slice = &hist[ slots[i].first ]; 00353 for (j = 0; j < slots[i].count; j++) { 00354 red_total += slice[j].red * slice[j].pixel; 00355 green_total += slice[j].green * slice[j].pixel; 00356 blue_total += slice[j].blue * slice[j].pixel; 00357 } 00358 adapt[i].red = (byte)(red_total / slots[i].pixel); 00359 adapt[i].green = (byte)(green_total / slots[i].pixel); 00360 adapt[i].blue = (byte)(blue_total / slots[i].pixel); 00361 adapt[i].haspixel = 0; 00362 } 00363 00364 Gif_DeleteArray(slots); 00365 gfcm->ncol = nadapt; 00366 return gfcm; 00367 } |
|
Definition at line 911 of file quantize.c. References Gif_Stream::background, Gif_Color::blue, c, Gif_Colormap::capacity, Gif_Colormap::col, colormap_image_func, free_all_color_hash_items(), Gif_CopyColormap(), Gif_DeleteArray, Gif_DeleteArrayFunc, Gif_DeleteColormap(), Gif_NewArray, Gif_ReleaseUncompressedImage(), Gif_SetUncompressedImage(), Gif_Stream::global, Gif_Color::green, hash_color(), Gif_Color::haspixel, Gif_Image::height, Gif_Image::image_data, Gif_Stream::images, Gif_Image::local, Gif_Colormap::ncol, new_color_hash(), Gif_Stream::nimages, Gif_Color::pixel, popularity_sort_compare(), Gif_Color::red, Gif_Image::transparent, try_assign_transparency(), u_int32_t, unmark_colors(), and Gif_Image::width. Referenced by do_set_colormap().
00913 { 00914 color_hash_item **hash = new_color_hash(); 00915 int background_transparent = gfs->images[0]->transparent >= 0; 00916 Gif_Color *new_col = new_cm->col; 00917 int new_ncol = new_cm->ncol; 00918 int imagei, j; 00919 int compress_new_cm = 1; 00920 00921 /* make sure colormap has enough space */ 00922 if (new_cm->capacity < 256) { 00923 Gif_Color *x = Gif_NewArray(Gif_Color, 256); 00924 memcpy(x, new_col, sizeof(Gif_Color) * new_ncol); 00925 Gif_DeleteArray(new_col); 00926 new_cm->col = new_col = x; 00927 new_cm->capacity = 256; 00928 } 00929 assert(new_cm->capacity >= 256); 00930 00931 /* new_col[j].pixel == number of pixels with color j in the new image. */ 00932 for (j = 0; j < 256; j++) 00933 new_col[j].pixel = 0; 00934 00935 for (imagei = 0; imagei < gfs->nimages; imagei++) { 00936 Gif_Image *gfi = gfs->images[imagei]; 00937 Gif_Colormap *gfcm = gfi->local ? gfi->local : gfs->global; 00938 00939 if (gfcm) { 00940 /* If there was an old colormap, change the image data */ 00941 byte *new_data = Gif_NewArray(byte, gfi->width * gfi->height); 00942 u_int32_t histogram[256]; 00943 unmark_colors(new_cm); 00944 unmark_colors(gfcm); 00945 00946 do { 00947 for (j = 0; j < 256; j++) histogram[j] = 0; 00948 image_changer(gfi, new_data, gfcm, new_cm, hash, histogram); 00949 } while (try_assign_transparency(gfi, gfcm, new_data, new_cm, &new_ncol, 00950 histogram)); 00951 00952 Gif_ReleaseUncompressedImage(gfi); 00953 Gif_SetUncompressedImage(gfi, new_data, Gif_DeleteArrayFunc, 0); 00954 00955 /* update count of used colors */ 00956 for (j = 0; j < 256; j++) 00957 new_col[j].pixel += histogram[j]; 00958 if (gfi->transparent >= 0) 00959 /* we don't have data on the number of used colors for transparency 00960 so fudge it. */ 00961 new_col[gfi->transparent].pixel += gfi->width * gfi->height / 8; 00962 00963 } else { 00964 /* Can't compress new_cm afterwards if we didn't actively change colors 00965 over */ 00966 compress_new_cm = 0; 00967 } 00968 00969 if (gfi->local) { 00970 Gif_DeleteColormap(gfi->local); 00971 gfi->local = 0; 00972 } 00973 } 00974 00975 /* Set new_cm->ncol from new_ncol. We didn't update new_cm->ncol before so 00976 the closest-color algorithms wouldn't see any new transparent colors. 00977 That way added transparent colors were only used for transparency. */ 00978 new_cm->ncol = new_ncol; 00979 00980 /* change the background. I hate the background by now */ 00981 if (background_transparent) 00982 gfs->background = gfs->images[0]->transparent; 00983 else if (gfs->global && gfs->background < gfs->global->ncol) { 00984 Gif_Color *c = &gfs->global->col[ gfs->background ]; 00985 gfs->background = hash_color(c->red, c->green, c->blue, hash, new_cm); 00986 new_col[gfs->background].pixel++; 00987 } 00988 00989 Gif_DeleteColormap(gfs->global); 00990 00991 /* We may have used only a subset of the colors in new_cm. We try to store 00992 only that subset, just as if we'd piped the output of `gifsicle 00993 --use-colormap=X' through `gifsicle' another time. */ 00994 gfs->global = Gif_CopyColormap(new_cm); 00995 if (compress_new_cm) { 00996 /* only bother to recompress if we'll get anything out of it */ 00997 compress_new_cm = 0; 00998 for (j = 0; j < new_cm->ncol - 1; j++) 00999 if (new_col[j].pixel == 0 || new_col[j].pixel < new_col[j+1].pixel) { 01000 compress_new_cm = 1; 01001 break; 01002 } 01003 } 01004 01005 if (compress_new_cm) { 01006 int map[256]; 01007 01008 /* Gif_CopyColormap copies the `pixel' values as well */ 01009 new_col = gfs->global->col; 01010 for (j = 0; j < new_cm->ncol; j++) 01011 new_col[j].haspixel = j; 01012 01013 /* sort based on popularity */ 01014 qsort(new_col, new_cm->ncol, sizeof(Gif_Color), popularity_sort_compare); 01015 01016 /* set up the map and reduce the number of colors */ 01017 for (j = 0; j < new_cm->ncol; j++) 01018 map[ new_col[j].haspixel ] = j; 01019 for (j = 0; j < new_cm->ncol; j++) 01020 if (!new_col[j].pixel) { 01021 gfs->global->ncol = j; 01022 break; 01023 } 01024 01025 /* map the image data, transparencies, and background */ 01026 gfs->background = map[gfs->background]; 01027 for (imagei = 0; imagei < gfs->nimages; imagei++) { 01028 Gif_Image *gfi = gfs->images[imagei]; 01029 u_int32_t size; 01030 byte *data = gfi->image_data; 01031 for (size = gfi->width * gfi->height; size > 0; size--, data++) 01032 *data = map[*data]; 01033 if (gfi->transparent >= 0) 01034 gfi->transparent = map[gfi->transparent]; 01035 } 01036 } 01037 01038 /* free storage */ 01039 free_all_color_hash_items(); 01040 Gif_DeleteArray(hash); 01041 } |
|
Definition at line 192 of file xform.c. References error(), Gif_DeleteArray, Gif_NewArray, Gt_Crop::h, Gif_Image::height, Gif_Image::img, Gif_Image::left, Gt_Crop::left_off, Gt_Crop::ready, Gt_Crop::right_off, Gt_Crop::spec_h, Gt_Crop::spec_w, Gt_Crop::spec_x, Gt_Crop::spec_y, Gif_Image::top, Gt_Crop::w, Gt_Crop::whole_stream, Gif_Image::width, Gt_Crop::x, and Gt_Crop::y. Referenced by merge_frame_interval().
00193 { 00194 int x, y, w, h, j; 00195 byte **img; 00196 00197 if (!crop->ready) { 00198 crop->x = crop->spec_x + gfi->left; 00199 crop->y = crop->spec_y + gfi->top; 00200 crop->w = crop->spec_w <= 0 ? gfi->width + crop->spec_w : crop->spec_w; 00201 crop->h = crop->spec_h <= 0 ? gfi->height + crop->spec_h : crop->spec_h; 00202 if (crop->x < 0 || crop->y < 0 || crop->w <= 0 || crop->h <= 0 00203 || crop->x + crop->w > gfi->width 00204 || crop->y + crop->h > gfi->height) { 00205 error("cropping dimensions don't fit image"); 00206 crop->ready = 2; 00207 } else 00208 crop->ready = 1; 00209 } 00210 if (crop->ready == 2) 00211 return 1; 00212 00213 x = crop->x - gfi->left; 00214 y = crop->y - gfi->top; 00215 w = crop->w; 00216 h = crop->h; 00217 00218 /* Check that the rectangle actually intersects with the image. */ 00219 if (x < 0) w += x, x = 0; 00220 if (y < 0) h += y, y = 0; 00221 if (x + w > gfi->width) w = gfi->width - x; 00222 if (y + h > gfi->height) h = gfi->height - y; 00223 00224 if (w > 0 && h > 0) { 00225 img = Gif_NewArray(byte *, h + 1); 00226 for (j = 0; j < h; j++) 00227 img[j] = gfi->img[y + j] + x; 00228 img[h] = 0; 00229 00230 /* Change position of image appropriately */ 00231 if (crop->whole_stream) { 00232 /* If cropping the whole stream, then this is the first frame. Position 00233 it at (0,0). */ 00234 crop->left_off = x + gfi->left; 00235 crop->right_off = y + gfi->top; 00236 gfi->left = 0; 00237 gfi->top = 0; 00238 crop->whole_stream = 0; 00239 } else { 00240 gfi->left += x - crop->left_off; 00241 gfi->top += y - crop->right_off; 00242 } 00243 00244 } else { 00245 /* Empty image */ 00246 w = h = 0; 00247 img = 0; 00248 } 00249 00250 Gif_DeleteArray(gfi->img); 00251 gfi->img = img; 00252 gfi->width = w; 00253 gfi->height = h; 00254 return gfi->img != 0; 00255 } |
|
Definition at line 44 of file xform.c. References color_transform_func, Gt_ColorTransform::func, Gif_Delete, and Gt_ColorTransform::next.
00045 { 00046 Gt_ColorTransform *prev = 0, *trav = list; 00047 while (trav) { 00048 Gt_ColorTransform *next = trav->next; 00049 if (trav->func == func) { 00050 if (prev) prev->next = next; 00051 else list = next; 00052 Gif_Delete(trav); 00053 } else 00054 prev = trav; 00055 trav = next; 00056 } 00057 return list; 00058 } |
|
Definition at line 205 of file gifview.c. Referenced by parse_geometry().
00206 { 00207 va_list val; 00208 va_start(val, message); 00209 fprintf(stderr, "%s: ", program_name); 00210 vfprintf(stderr, message, val); 00211 fputc('\n', stderr); 00212 } |
|
Definition at line 446 of file support.c. References Gif_Delete, Gif_NewArray, l, and name. Referenced by output_frames().
00447 { 00448 static char *s; 00449 int l = strlen(filename); 00450 l += name ? strlen(name) : 10; 00451 00452 Gif_Delete(s); 00453 s = Gif_NewArray(char, l + 3); 00454 if (name) 00455 sprintf(s, "%s.%s", filename, name); 00456 else if (max_nimages <= 1000) 00457 sprintf(s, "%s.%03d", filename, number); 00458 else { 00459 int digits; 00460 unsigned j; 00461 unsigned max = (max_nimages < 0 ? 0 : max_nimages); 00462 for (digits = 4, j = 10000; max > j; digits++) 00463 j *= 10; 00464 sprintf(s, "%s.%0*d", filename, digits, number); 00465 } 00466 00467 return s; 00468 } |
|
Definition at line 194 of file gifview.c. References EXIT_USER_ERR, and verror(). Referenced by colormap_diversity(), colormap_median_cut(), do_colormap_change(), get_used_colors(), handle_extension(), main(), merge_image(), pipe_color_transformer(), scale_image(), set_frame_change(), and set_mode().
00195 { 00196 va_list val; 00197 va_start(val, message); 00198 fprintf(stderr, "%s: ", program_name); 00199 vfprintf(stderr, message, val); 00200 fputc('\n', stderr); 00201 exit(1); 00202 } |
|
Definition at line 81 of file gifsicledir/merge.c. References c, color, GIF_COLOREQ, and nc. Referenced by merge_colormap_if_possible().
00082 { 00083 int index; 00084 for (index = 0; index < nc; index++) 00085 if (GIF_COLOREQ(&c[index], color)) 00086 return index; 00087 return -1; 00088 } |
|
Definition at line 263 of file xform.c. References Gif_DeleteArray, Gif_NewArray, Gif_Image::height, Gif_Image::img, Gif_Image::left, Gif_Image::top, and Gif_Image::width. Referenced by handle_flip_and_screen().
00264 { 00265 int x, y; 00266 int width = gfi->width; 00267 int height = gfi->height; 00268 byte **img = gfi->img; 00269 00270 /* horizontal flips */ 00271 if (!is_vert) { 00272 byte *buffer = Gif_NewArray(byte, width); 00273 byte *trav; 00274 for (y = 0; y < height; y++) { 00275 memcpy(buffer, img[y], width); 00276 trav = img[y] + width - 1; 00277 for (x = 0; x < width; x++) 00278 *trav-- = buffer[x]; 00279 } 00280 gfi->left = screen_width - (gfi->left + width); 00281 Gif_DeleteArray(buffer); 00282 } 00283 00284 /* vertical flips */ 00285 if (is_vert) { 00286 byte **buffer = Gif_NewArray(byte *, height); 00287 memcpy(buffer, img, height * sizeof(byte *)); 00288 for (y = 0; y < height; y++) 00289 img[y] = buffer[height - y - 1]; 00290 gfi->top = screen_height - (gfi->top + height); 00291 Gif_DeleteArray(buffer); 00292 } 00293 } |
|
Definition at line 100 of file quantize.c. References add_histogram_color(), Gif_Stream::background, Gif_Histogram::c, Gif_Histogram::cap, Gif_Colormap::col, delete_histogram(), Gif_Image::disposal, GIF_DISPOSAL_BACKGROUND, Gif_NewArray, Gif_Stream::global, Gif_Color::haspixel, Gif_Image::height, i, Gif_Stream::images, Gif_Image::img, init_histogram(), Gif_Image::local, Gif_Histogram::n, ncol, Gif_Colormap::ncol, Gif_Stream::nimages, Gif_Color::pixel, Gif_Image::transparent, u_int32_t, unmark_colors(), and Gif_Image::width. Referenced by do_colormap_change().
00101 { 00102 Gif_Histogram hist; 00103 Gif_Color *linear; 00104 Gif_Color transparent_color; 00105 unsigned long ntransparent = 0; 00106 unsigned long nbackground = 0; 00107 int x, y, i; 00108 00109 unmark_colors(gfs->global); 00110 for (i = 0; i < gfs->nimages; i++) 00111 unmark_colors(gfs->images[i]->local); 00112 00113 init_histogram(&hist, 0); 00114 00115 /* Count pixels. Be careful about values which are outside the range of the 00116 colormap. */ 00117 for (i = 0; i < gfs->nimages; i++) { 00118 Gif_Image *gfi = gfs->images[i]; 00119 Gif_Colormap *gfcm = gfi->local ? gfi->local : gfs->global; 00120 u_int32_t count[256]; 00121 Gif_Color *col; 00122 int ncol; 00123 int transparent = gfi->transparent; 00124 if (!gfcm) continue; 00125 00126 /* sweep over the image data, counting pixels */ 00127 for (x = 0; x < 256; x++) 00128 count[x] = 0; 00129 for (y = 0; y < gfi->height; y++) { 00130 byte *data = gfi->img[y]; 00131 for (x = 0; x < gfi->width; x++, data++) 00132 count[*data]++; 00133 } 00134 00135 /* add counted colors to global histogram */ 00136 col = gfcm->col; 00137 ncol = gfcm->ncol; 00138 for (x = 0; x < ncol; x++) 00139 if (count[x] && x != transparent) { 00140 if (col[x].haspixel) 00141 hist.c[ col[x].pixel ].pixel += count[x]; 00142 else 00143 add_histogram_color(&col[x], &hist, count[x]); 00144 } 00145 if (transparent >= 0) { 00146 if (ntransparent == 0) transparent_color = col[transparent]; 00147 ntransparent += count[transparent]; 00148 } 00149 00150 /* if this image has background disposal, count its size towards the 00151 background's pixel count */ 00152 if (gfi->disposal == GIF_DISPOSAL_BACKGROUND) 00153 nbackground += gfi->width * gfi->height; 00154 } 00155 00156 /* account for background by adding it to `ntransparent' or the histogram */ 00157 if (gfs->images[0]->transparent < 0 && gfs->global 00158 && gfs->background < gfs->global->ncol) 00159 add_histogram_color(&gfs->global->col[gfs->background], &hist, nbackground); 00160 else 00161 ntransparent += nbackground; 00162 00163 /* now, make the linear histogram from the hashed histogram */ 00164 linear = Gif_NewArray(Gif_Color, hist.n + 1); 00165 i = 0; 00166 00167 /* Put all transparent pixels in histogram slot 0. Transparent pixels are 00168 marked by haspixel == 255. */ 00169 if (ntransparent) { 00170 linear[0] = transparent_color; 00171 linear[0].haspixel = 255; 00172 linear[0].pixel = ntransparent; 00173 i++; 00174 } 00175 00176 /* put hash histogram colors into linear histogram */ 00177 for (x = 0; x < hist.cap; x++) 00178 if (hist.c[x].haspixel) 00179 linear[i++] = hist.c[x]; 00180 00181 delete_histogram(&hist); 00182 *nhist_store = i; 00183 return linear; 00184 } |
|
Definition at line 397 of file support.c. References colormap_info(), Gif_Image::comment, comment_info(), Gif_Image::compressed, Gif_Image::compressed_len, Gif_Image::delay, Gif_Image::disposal, disposal_names, Gif_ImageNumber(), Gif_Image::height, Gif_Image::identifier, Gif_Image::interlace, Gif_Image::left, Gif_Image::local, Gif_Colormap::ncol, Gif_Image::top, Gif_Image::transparent, verbose_endline(), and Gif_Image::width. Referenced by output_information().
00398 { 00399 int num; 00400 if (!gfs || !gfi) return; 00401 num = Gif_ImageNumber(gfs, gfi); 00402 00403 verbose_endline(); 00404 fprintf(where, " + image #%d ", num); 00405 if (gfi->identifier) 00406 fprintf(where, "#%s ", gfi->identifier); 00407 00408 fprintf(where, "%dx%d", gfi->width, gfi->height); 00409 if (gfi->left || gfi->top) 00410 fprintf(where, " at %d,%d", gfi->left, gfi->top); 00411 00412 if (gfi->interlace) 00413 fprintf(where, " interlaced"); 00414 00415 if (gfi->transparent >= 0) 00416 fprintf(where, " transparent %d", gfi->transparent); 00417 00418 #if defined(PRINT_SIZE) 00419 if (gfi->compressed) 00420 fprintf(where, " compressed size %u min_code_size %d", gfi->compressed_len, *gfi->compressed); 00421 #endif 00422 00423 fprintf(where, "\n"); 00424 00425 if (gfi->comment) 00426 comment_info(where, gfi->comment, " comment "); 00427 00428 if (gfi->local) { 00429 fprintf(where, " local color table [%d]\n", gfi->local->ncol); 00430 if (colormaps) colormap_info(where, gfi->local, " |"); 00431 } 00432 00433 if (gfi->disposal || gfi->delay) { 00434 fprintf(where, " "); 00435 if (gfi->disposal) 00436 fprintf(where, " disposal %s", disposal_names[gfi->disposal]); 00437 if (gfi->delay) 00438 fprintf(where, " delay %d.%02ds", 00439 gfi->delay / 100, gfi->delay % 100); 00440 fprintf(where, "\n"); 00441 } 00442 } |
|
Definition at line 588 of file gifsicle.c. References BATCHING, DELETING, EXPLODING, frame_change_done(), Gif_DeleteStream(), mode, output_frames(), and verbose_close(). Referenced by main().
00589 { 00590 if (!input) return; 00591 00592 if (verbosing) verbose_close('>'); 00593 /*if (infoing) { 00594 int i; 00595 if (input->userflags == 97) 00596 stream_info(infoing, input, input_name, 00597 colormap_infoing, extension_infoing); 00598 for (i = first_input_frame; i < frames->count; i++) 00599 if (FRAME(frames, i).stream == input && FRAME(frames, i).use) 00600 image_info(infoing, input, FRAME(frames, i).image, colormap_infoing); 00601 }*/ 00602 00603 Gif_DeleteStream(input); 00604 input = 0; 00605 00606 if (mode == DELETING) 00607 frame_change_done(); 00608 if (mode == BATCHING || mode == EXPLODING) 00609 output_frames(); 00610 } |
|
Definition at line 461 of file gifsicle.c. References add_frame(), apply_color_transforms(), BATCHING, BLANK_MODE, CH_COMMENT, CH_EXTENSION, CH_NAME, CHANGED, combine_output_options(), Gt_Frame::comment, Gt_Frameset::count, error(), Gif_Stream::errors, EXPLODING, Gt_Frame::extensions, files_given, first_input_frame, frames_done, Gif_DeleteStream(), Gif_FullReadFile(), Gif_ImageCount, GIF_READ_COMPRESSED, gif_read_flags, Gif_Unoptimize(), gifread_error(), gifread_error_count, i, Gif_Stream::images, Gt_Frame::input_filename, input_name, MERGING, mode, Gt_Frame::name, name, next_frame, next_input, Gif_Stream::nimages, Gt_OutputData::output_name, Gt_Frame::position_is_offset, Gif_Stream::refcount, set_mode(), strerror(), ungetc(), verbose_close(), verbose_open(), warncontext(), and warning(). Referenced by main(), and parse_frame_spec().
00462 { 00463 FILE *f; 00464 Gif_Stream *gfs; 00465 int i; 00466 int saved_next_frame = next_frame; 00467 Gt_Frame old_def_frame; 00468 00469 input = 0; 00470 input_name = name; 00471 frames_done = 0; 00472 next_frame = 0; 00473 next_input = 0; 00474 if (next_output) combine_output_options(); 00475 files_given++; 00476 00477 if (name == 0 || strcmp(name, "-") == 0) { 00478 #if defined(_MSDOS) || defined(_WIN32) 00479 _setmode(_fileno(stdin), _O_BINARY); 00480 #elif defined(__EMX__) 00481 _fsetmode(stdin, "b"); 00482 #endif 00483 f = stdin; 00484 name = "<stdin>"; 00485 } else 00486 f = fopen(name, "rb"); 00487 if (!f) { 00488 error("%s: %s", name, strerror(errno)); 00489 return; 00490 } 00491 00492 /* special error message for empty files */ 00493 i = getc(f); 00494 if (i == EOF) { 00495 error("%s: empty file", name); 00496 return; 00497 } 00498 ungetc(i, f); 00499 00500 if (verbosing) verbose_open('<', name); 00501 gifread_error_count = 0; 00502 gfs = Gif_FullReadFile(f, gif_read_flags | GIF_READ_COMPRESSED, 00503 gifread_error, (void *)name); 00504 fclose(f); 00505 gifread_error(0, -1, (void *)name); /* print out last error message */ 00506 00507 if (!gfs || (Gif_ImageCount(gfs) == 0 && gfs->errors > 0)) { 00508 error("%s: not a GIF", name); 00509 Gif_DeleteStream(gfs); 00510 if (verbosing) verbose_close('>'); 00511 return; 00512 } 00513 00514 input = gfs; 00515 00516 /* Processing when we've got a new input frame */ 00517 if (mode == BLANK_MODE) 00518 set_mode(MERGING); 00519 00520 if (active_output_data.output_name == 0) { 00521 /* Don't override explicit output names. 00522 This code works 'cause output_name is reset to 0 after each output. */ 00523 if (mode == BATCHING) 00524 active_output_data.output_name = input_name; 00525 else if (mode == EXPLODING) { 00526 /* Explode into current directory. */ 00527 char *explode_name = (input_name ? input_name : "#stdin#"); 00528 char *slash = strrchr(explode_name, PATHNAME_SEPARATOR); 00529 if (slash) 00530 active_output_data.output_name = slash + 1; 00531 else 00532 active_output_data.output_name = explode_name; 00533 } 00534 } 00535 00536 /* This code rather sucks. Here's the problem: Since we consider options 00537 strictly sequentially, one at a time, we can't tell the difference 00538 between these: 00539 00540 --name=X g.gif h.gif // name on g.gif #0 00541 --name=X g.gif #2 h.gif // name on g.gif #2 00542 g.gif --name=X #2 h.gif // name on g.gif #2 00543 g.gif --name=X h.gif // name on h.gif #0 !!! 00544 00545 Here's the solution. Mark when we CHANGE an option. After processing 00546 an input GIF, mark all the options as `unchanged' -- but leave the 00547 VALUES as is. Then when we read the next frame, CLEAR the unchanged 00548 options. So it's like so: (* means changed, . means not.) 00549 00550 [-.] --name=X [X*] g.gif [X.] #2 [-.] h.gif == name on g.gif #2 00551 [-.] g.gif [-.] --name=X [X*] #2 [-.] h.gif == name on g.gif #2 00552 [-.] --name=X [X*] g.gif [X.|-.] h.gif == name on g.gif #0 00553 [-.] g.gif [-.] --name=X [X*] h.gif == name on h.gif #0 */ 00554 00555 /* Clear old options from the last input stream */ 00556 if (!CHANGED(saved_next_frame, CH_NAME)) 00557 def_frame.name = 0; 00558 if (!CHANGED(saved_next_frame, CH_COMMENT)) 00559 def_frame.comment = 0; 00560 if (!CHANGED(saved_next_frame, CH_EXTENSION)) 00561 def_frame.extensions = 0; 00562 def_frame.input_filename = input_name; 00563 00564 old_def_frame = def_frame; 00565 first_input_frame = frames->count; 00566 if (gfs->nimages > 1) 00567 def_frame.position_is_offset = 1; 00568 for (i = 0; i < gfs->nimages; i++) 00569 add_frame(frames, -1, gfs, gfs->images[i]); 00570 def_frame = old_def_frame; 00571 00572 if (unoptimizing) 00573 if (!Gif_Unoptimize(gfs)) { 00574 static int context = 0; 00575 warning("`%s' is too complex to unoptimize", name); 00576 if (!context) { 00577 warncontext("(The reason was local color tables or complex transparency."); 00578 warncontext("Try running the GIF through `gifsicle --colors=255' first.)"); 00579 } 00580 context = 1; 00581 } 00582 00583 apply_color_transforms(input_transforms, gfs); 00584 gfs->refcount++; 00585 } |
|
Definition at line 103 of file gifsicledir/merge.c. References Gif_Colormap::col, COLORMAP_ENSURE_SLOT_255, ensure_slot_255(), find_color_index(), GIF_COLOREQ, Gif_Color::haspixel, i, Gif_Colormap::ncol, Gif_Color::pixel, Gif_Colormap::userflags, warncontext(), and warning(). Referenced by merge_image().
00104 { 00105 Gif_Color *srccol = src->col; 00106 Gif_Color *destcol = dest->col; 00107 int ndestcol = dest->ncol; 00108 int dest_userflags = dest->userflags; 00109 int i, x; 00110 int trivial_map = 1; 00111 00112 for (i = 0; i < src->ncol; i++) { 00113 if (srccol[i].haspixel == 1) { 00114 /* Store an image color cell's mapping to the global colormap in its 00115 `pixel' slot. This is useful caching: oftentimes many input frames 00116 will share a colormap */ 00117 int mapto = srccol[i].pixel < 256 ? srccol[i].pixel : -1; 00118 00119 if (mapto == -1) 00120 mapto = find_color_index(destcol, ndestcol, &srccol[i]); 00121 00122 if (mapto == -1 && ndestcol == 255 00123 && (dest_userflags & COLORMAP_ENSURE_SLOT_255) != 0) { 00124 ndestcol = ensure_slot_255(dest, ndestcol); 00125 dest_userflags &= ~COLORMAP_ENSURE_SLOT_255; 00126 /* slot 255 might have been equal to `srccol[i]'! */ 00127 if (ndestcol == 256 && GIF_COLOREQ(&destcol[255], &srccol[i])) 00128 mapto = 255; 00129 } 00130 00131 if (mapto == -1 && ndestcol < 256) { 00132 /* add the color */ 00133 mapto = ndestcol; 00134 destcol[mapto] = srccol[i]; 00135 ndestcol++; 00136 } 00137 00138 if (mapto == -1) 00139 /* check for a pure-transparent color */ 00140 for (x = 0; x < ndestcol; x++) 00141 if (destcol[x].haspixel == 2) { 00142 mapto = x; 00143 destcol[mapto] = srccol[i]; 00144 break; 00145 } 00146 00147 if (mapto == -1) 00148 /* give up and require a local colormap */ 00149 goto local_colormap_required; 00150 00151 assert(mapto >= 0 && mapto < ndestcol); 00152 assert(GIF_COLOREQ(&destcol[mapto], &srccol[i])); 00153 00154 srccol[i].pixel = mapto; 00155 destcol[mapto].haspixel = 1; 00156 if (mapto != i) 00157 trivial_map = 0; 00158 00159 } else if (srccol[i].haspixel == 2) 00160 /* a dedicated transparent color; if trivial_map & at end of colormap 00161 insert it with haspixel == 2. (strictly not necessary; we do it to 00162 try to keep the map trivial.) */ 00163 if (trivial_map && i == ndestcol) { 00164 destcol[ndestcol] = srccol[i]; 00165 ndestcol++; 00166 } 00167 } 00168 00169 /* success! save new number of colors */ 00170 dest->ncol = ndestcol; 00171 dest->userflags = dest_userflags; 00172 return 1; 00173 00174 /* failure: a local colormap is required */ 00175 local_colormap_required: 00176 if (warn_local_colormaps == 1) { 00177 static int context = 0; 00178 warning("so many colors that local colormaps were required"); 00179 if (!context) 00180 warncontext("(You may want to try `--colors 256'.)"); 00181 warn_local_colormaps = 2; 00182 context = 1; 00183 } 00184 00185 /* 9.Dec.1998 - This must have been a longstanding bug! We MUST clear 00186 the cached mappings of any pixels in the source colormap we 00187 assigned this time through, since we are throwing those colors 00188 away. We assigned it this time through if the cached mapping is >= 00189 dest->ncol. */ 00190 for (x = 0; x < i; x++) 00191 if (srccol[x].haspixel == 1 && srccol[x].pixel >= dest->ncol) 00192 srccol[x].pixel = 256; 00193 00194 return 0; 00195 } |
|
Definition at line 222 of file gifsicledir/merge.c. References Gif_Comment::count, Gif_AddComment(), i, Gif_Comment::len, and Gif_Comment::str. Referenced by fix_total_crop(), merge_frame_interval(), merge_image(), and merge_stream().
|
|
Definition at line 1203 of file support.c. References Gt_OutputData::background, Gif_Stream::background, Gif_Colormap::col, Gif_Image::comment, Gt_Frame::comment, copy_extension(), Gt_Frameset::count, Gt_Frame::crop, crop_image(), Gt_Frame::delay, Gif_Image::delay, Gt_Frame::disposal, Gif_Image::disposal, error(), Gif_Stream::extensions, Gt_Frame::extensions, find_background(), find_color_or_error(), fix_total_crop(), Gt_Frame::flip_horizontal, Gt_Frame::flip_vertical, Gif_AddExtension(), Gif_CalculateScreenSize(), Gif_CopyImage(), Gif_CopyString(), Gif_DeleteArray, Gif_DeleteComment(), Gif_DeleteImage(), Gif_DeleteStream(), Gif_FullCompressImage(), Gif_NewComment(), Gif_NewFullColormap(), Gif_NewStream(), Gif_ReleaseCompressedImage(), Gif_ReleaseUncompressedImage(), Gif_UncompressImage, global, Gif_Stream::global, handle_flip_and_screen(), handle_screen(), Gif_Color::haspixel, i, Gif_Image::identifier, Gt_Frame::image, Gif_Stream::images, Gif_Image::interlace, Gt_Frame::interlacing, Gt_Frame::left, Gif_Image::left, Gt_OutputData::loopcount, Gif_Stream::loopcount, merge_comments(), merge_image(), merge_stream(), merger_flatten(), Gt_Frame::name, Gif_Colormap::ncol, Gif_Extension::next, nmerger, Gt_Frame::no_comments, Gt_Frame::no_extensions, Gt_Frame::no_name, Gif_Extension::position, Gt_Frame::position_is_offset, Gif_Image::refcount, Gt_Frame::rotation, Gif_Stream::screen_height, Gt_OutputData::screen_height, Gif_Stream::screen_width, Gt_OutputData::screen_width, Gt_Frame::stream, Gt_Frame::top, Gif_Image::top, Gif_Image::transparent, Gt_Frame::transparent, unmark_colors_2(), Gif_Stream::userflags, and Gt_Crop::whole_stream. Referenced by merge_and_write_frames().
01205 { 01206 Gif_Stream *dest = Gif_NewStream(); 01207 Gif_Colormap *global = Gif_NewFullColormap(256, 256); 01208 Gif_Color dest_background; 01209 int i; 01210 01211 global->ncol = 0; 01212 dest->global = global; 01213 /* 11/23/98 A new stream's screen size is 0x0; we'll use the max of the 01214 merged-together streams' screen sizes by default (in merge_stream()) */ 01215 01216 if (f2 < 0) f2 = fset->count - 1; 01217 nmerger = 0; 01218 merger_flatten(fset, f1, f2); 01219 if (nmerger == 0) { 01220 error("empty output GIF not written"); 01221 return 0; 01222 } 01223 01224 /* merge stream-specific info and clear colormaps */ 01225 for (i = 0; i < nmerger; i++) 01226 merger[i]->stream->userflags = 1; 01227 for (i = 0; i < nmerger; i++) { 01228 if (merger[i]->stream->userflags) { 01229 Gif_Stream *src = merger[i]->stream; 01230 Gif_CalculateScreenSize(src, 0); 01231 /* merge_stream() unmarks the global colormap */ 01232 merge_stream(dest, src, merger[i]->no_comments); 01233 src->userflags = 0; 01234 } 01235 if (merger[i]->image->local) 01236 unmark_colors_2(merger[i]->image->local); 01237 } 01238 01239 /* decide on the background. use the one from output_data */ 01240 dest_background = output_data->background; 01241 find_background(global, &dest_background); 01242 01243 /* check for cropping the whole stream */ 01244 for (i = 0; i < nmerger; i++) 01245 if (merger[i]->crop) 01246 merger[i]->crop->whole_stream = 0; 01247 if (merger[0]->crop) { 01248 merger[0]->crop->whole_stream = 1; 01249 for (i = 1; i < nmerger; i++) 01250 if (merger[i]->crop != merger[0]->crop) 01251 merger[0]->crop->whole_stream = 0; 01252 } 01253 01254 /* copy stream-wide information from output_data */ 01255 if (output_data->loopcount > -2) 01256 dest->loopcount = output_data->loopcount; 01257 dest->screen_width = dest->screen_height = 0; 01258 01259 /** ACTUALLY MERGE FRAMES INTO THE NEW STREAM **/ 01260 for (i = 0; i < nmerger; i++) { 01261 Gt_Frame *fr = merger[i]; 01262 Gif_Image *srci; 01263 Gif_Image *desti; 01264 int old_transparent; 01265 01266 /* First, check for extensions */ 01267 { 01268 int j; 01269 Gif_Extension *gfex = fr->stream->extensions; 01270 for (j = 0; fr->stream->images[j] != fr->image; j++) ; 01271 while (gfex && gfex->position < j) 01272 gfex = gfex->next; 01273 while (!fr->no_extensions && gfex && gfex->position == j) { 01274 Gif_AddExtension(dest, copy_extension(gfex), i); 01275 gfex = gfex->next; 01276 } 01277 gfex = fr->extensions; 01278 while (gfex) { 01279 Gif_Extension *next = gfex->next; 01280 Gif_AddExtension(dest, gfex, i); 01281 gfex = next; 01282 } 01283 } 01284 01285 /* Make a copy of the image and crop it if we're cropping */ 01286 if (fr->crop) { 01287 srci = Gif_CopyImage(fr->image); 01288 Gif_UncompressImage(srci); 01289 if (!crop_image(srci, fr->crop)) { 01290 /* We cropped the image out of existence! Be careful not to make 0x0 01291 frames. */ 01292 fix_total_crop(dest, srci, i); 01293 goto merge_frame_done; 01294 } 01295 } else { 01296 srci = fr->image; 01297 Gif_UncompressImage(srci); 01298 } 01299 01300 /* It was pretty stupid to remove this code, which I did between 1.2b6 and 01301 1.2 */ 01302 old_transparent = srci->transparent; 01303 if (fr->transparent.haspixel == 255) 01304 srci->transparent = -1; 01305 else if (fr->transparent.haspixel) 01306 srci->transparent = 01307 find_color_or_error(&fr->transparent, fr->stream, srci, "transparent"); 01308 01309 desti = merge_image(dest, fr->stream, srci); 01310 01311 srci->transparent = old_transparent; /* restore real transparent value */ 01312 01313 /* Flipping and rotating, and also setting the screen size */ 01314 if (fr->flip_horizontal || fr->flip_vertical || fr->rotation) 01315 handle_flip_and_screen(dest, desti, fr, i == 0); 01316 else 01317 handle_screen(dest, fr->stream->screen_width, fr->stream->screen_height); 01318 01319 /* Names and comments */ 01320 if (fr->name || fr->no_name) { 01321 Gif_DeleteArray(desti->identifier); 01322 desti->identifier = Gif_CopyString(fr->name); 01323 } 01324 if (fr->no_comments && desti->comment) { 01325 Gif_DeleteComment(desti->comment); 01326 desti->comment = 0; 01327 } 01328 if (fr->comment) { 01329 if (!desti->comment) desti->comment = Gif_NewComment(); 01330 merge_comments(desti->comment, fr->comment); 01331 /* delete the comment early to help with memory; set field to 0 so we 01332 don't re-free it later */ 01333 Gif_DeleteComment(fr->comment); 01334 fr->comment = 0; 01335 } 01336 01337 if (fr->interlacing >= 0) 01338 desti->interlace = fr->interlacing; 01339 if (fr->left >= 0) 01340 desti->left = fr->left + (fr->position_is_offset ? desti->left : 0); 01341 if (fr->top >= 0) 01342 desti->top = fr->top + (fr->position_is_offset ? desti->top : 0); 01343 01344 if (fr->delay >= 0) 01345 desti->delay = fr->delay; 01346 if (fr->disposal >= 0) 01347 desti->disposal = fr->disposal; 01348 01349 /* compress immediately if possible to save on memory */ 01350 if (compress_immediately) { 01351 Gif_FullCompressImage(dest, desti, gif_write_flags); 01352 Gif_ReleaseUncompressedImage(desti); 01353 } 01354 01355 merge_frame_done: 01356 /* Destroy the copied, cropped image if necessary */ 01357 if (fr->crop) 01358 Gif_DeleteImage(srci); 01359 01360 /* if we can, delete the image's data right now to save memory */ 01361 srci = fr->image; 01362 assert(srci->refcount > 1); 01363 if (--srci->refcount == 1) { 01364 /* only 1 reference ==> the reference is from the input stream itself */ 01365 Gif_ReleaseUncompressedImage(srci); 01366 Gif_ReleaseCompressedImage(srci); 01367 fr->image = 0; 01368 } 01369 01370 /* 5/26/98 Destroy the stream now to help with memory. Assumes that 01371 all frames are added with add_frame() which properly increments the 01372 stream's refcount. Set field to 0 so we don't redelete */ 01373 Gif_DeleteStream(fr->stream); 01374 fr->stream = 0; 01375 } 01376 /** END MERGE LOOP **/ 01377 01378 /* Cropping the whole output? Clear the logical screen */ 01379 if (merger[0]->crop && merger[0]->crop == merger[nmerger-1]->crop) 01380 dest->screen_width = dest->screen_height = 0; 01381 /* Set the logical screen from the user's preferences */ 01382 if (output_data->screen_width >= 0) 01383 dest->screen_width = output_data->screen_width; 01384 if (output_data->screen_height >= 0) 01385 dest->screen_height = output_data->screen_height; 01386 01387 /* Find the background color in the colormap, or add it if we can */ 01388 { 01389 int bg = find_color_or_error(&dest_background, dest, 0, 0); 01390 if (bg < 0 && dest->images[0]->transparent >= 0) 01391 dest->background = dest->images[0]->transparent; 01392 else if (bg < 0 && global->ncol < 256) { 01393 dest->background = global->ncol; 01394 global->col[ global->ncol ] = dest_background; 01395 global->ncol++; 01396 } else 01397 dest->background = bg; 01398 } 01399 01400 return dest; 01401 } |
|
Definition at line 231 of file gifsicledir/merge.c. References c, Gif_Colormap::col, Gif_Image::comment, Gif_Image::delay, Gif_Image::disposal, fatal_error(), Gif_AddImage(), Gif_CopyString(), Gif_CreateUncompressedImage(), Gif_NewComment(), Gif_NewFullColormap(), Gif_NewImage(), Gif_Stream::global, Gif_Color::haspixel, Gif_Image::height, i, Gif_Image::identifier, Gif_Image::img, Gif_Image::interlace, Gif_Image::left, Gif_Image::local, mark_used_colors(), merge_colormap_if_possible(), merge_comments(), Gif_Colormap::ncol, ncol, Gif_Image::top, Gif_Image::transparent, and Gif_Image::width. Referenced by merge_frame_interval().
00232 { 00233 Gif_Colormap *imagecm; 00234 Gif_Color *imagecol; 00235 int islocal; 00236 int i; 00237 Gif_Colormap *localcm = 0; 00238 Gif_Colormap *destcm = dest->global; 00239 00240 byte map[256]; /* map[input pixel value] == output pixval */ 00241 int trivial_map = 1; /* does the map take input pixval --> the same 00242 pixel value for all colors in the image? */ 00243 byte used[256]; /* used[output pixval K] == 1 iff K was used 00244 in the image */ 00245 00246 Gif_Image *desti; 00247 00248 /* mark colors that were actually used in this image */ 00249 islocal = srci->local != 0; 00250 imagecm = islocal ? srci->local : src->global; 00251 if (!imagecm) 00252 fatal_error("no global or local colormap for source image"); 00253 00254 mark_used_colors(srci, imagecm); 00255 imagecol = imagecm->col; /* may be changed by mark_used_colors */ 00256 00257 /* map[old_pixel_value] == new_pixel_value */ 00258 for (i = 0; i < 256; i++) 00259 map[i] = used[i] = 0; 00260 00261 /* Merge the colormap */ 00262 if (merge_colormap_if_possible(dest->global, imagecm)) { 00263 /* Create `map' and `used' for global colormap. */ 00264 for (i = 0; i < imagecm->ncol; i++) 00265 if (imagecol[i].haspixel == 1) { 00266 map[i] = imagecol[i].pixel; 00267 if (map[i] != i) trivial_map = 0; 00268 used[map[i]] = 1; 00269 } 00270 00271 } else { 00272 /* Need a local colormap. */ 00273 int ncol = 0; 00274 destcm = localcm = Gif_NewFullColormap(0, 256); 00275 for (i = 0; i < imagecm->ncol; i++) 00276 if (imagecol[i].haspixel) { 00277 map[i] = ncol; 00278 if (ncol != i) trivial_map = 0; 00279 /* 19.Aug.1999- BUGFIX! color is only used if it was opaque */ 00280 if (imagecol[i].haspixel == 1) 00281 used[ncol] = 1; 00282 localcm->col[ ncol++ ] = imagecol[i]; 00283 } 00284 localcm->ncol = ncol; 00285 } 00286 00287 /* Decide on a transparent index */ 00288 if (srci->transparent >= 0) { 00289 int found_transparent = -1; 00290 00291 /* try to keep the map trivial -- prefer same transparent index */ 00292 if (trivial_map && !used[srci->transparent]) 00293 found_transparent = srci->transparent; 00294 else 00295 for (i = destcm->ncol - 1; i >= 0; i--) 00296 if (!used[i]) 00297 found_transparent = i; 00298 00299 /* 1.Aug.1999 - Allow for the case that the transparent index is bigger 00300 than the number of colors we've created thus far. */ 00301 if (found_transparent < 0 || found_transparent >= destcm->ncol) { 00302 Gif_Color *c; 00303 found_transparent = destcm->ncol; 00304 /* 1.Aug.1999 - Don't update destcm->ncol -- we want the output colormap 00305 to be as small as possible. */ 00306 c = &destcm->col[found_transparent]; 00307 if (srci->transparent < imagecm->ncol) 00308 *c = imagecol[srci->transparent]; 00309 else 00310 c->haspixel = 2; 00311 assert(c->haspixel == 2 && found_transparent < 256); 00312 } 00313 00314 map[srci->transparent] = found_transparent; 00315 if (srci->transparent != found_transparent) trivial_map = 0; 00316 } 00317 00318 assert(destcm->ncol <= 256); 00319 /* Make the new image. */ 00320 desti = Gif_NewImage(); 00321 00322 desti->identifier = Gif_CopyString(srci->identifier); 00323 if (srci->transparent > -1) 00324 desti->transparent = map[srci->transparent]; 00325 desti->delay = srci->delay; 00326 desti->disposal = srci->disposal; 00327 desti->left = srci->left; 00328 desti->top = srci->top; 00329 desti->interlace = srci->interlace; 00330 00331 desti->width = srci->width; 00332 desti->height = srci->height; 00333 desti->local = localcm; 00334 00335 if (srci->comment) { 00336 desti->comment = Gif_NewComment(); 00337 merge_comments(desti->comment, srci->comment); 00338 } 00339 00340 Gif_CreateUncompressedImage(desti); 00341 00342 { 00343 int i, j; 00344 00345 if (trivial_map) 00346 for (j = 0; j < desti->height; j++) 00347 memcpy(desti->img[j], srci->img[j], desti->width); 00348 00349 else 00350 for (j = 0; j < desti->height; j++) { 00351 byte *srcdata = srci->img[j]; 00352 byte *destdata = desti->img[j]; 00353 for (i = 0; i < desti->width; i++, srcdata++, destdata++) 00354 *destdata = map[*srcdata]; 00355 } 00356 } 00357 00358 Gif_AddImage(dest, desti); 00359 return desti; 00360 } |
|
Definition at line 199 of file gifsicledir/merge.c. References Gif_Stream::comment, Gif_NewComment(), Gif_Stream::global, i, Gif_Stream::images, Gif_Stream::loopcount, merge_comments(), Gif_Stream::nimages, and unmark_colors_2(). Referenced by merge_frame_interval().
00200 { 00201 int i; 00202 assert(dest->global); 00203 00204 /* unmark colors in global and local colormaps -- 12/9 */ 00205 if (src->global) 00206 unmark_colors_2(src->global); 00207 for (i = 0; i < src->nimages; i++) 00208 if (src->images[i]->local) 00209 unmark_colors_2(src->images[i]->local); 00210 00211 if (dest->loopcount < 0) 00212 dest->loopcount = src->loopcount; 00213 00214 if (src->comment && !no_comments) { 00215 if (!dest->comment) dest->comment = Gif_NewComment(); 00216 merge_comments(dest->comment, src->comment); 00217 } 00218 } |
|
Definition at line 894 of file support.c. References Gt_Frameset::cap, Gt_Frameset::count, Gt_Frameset::f, Gif_New, and Gif_NewArray. Referenced by main(), and set_frame_change().
00895 { 00896 Gt_Frameset *fs = Gif_New(Gt_Frameset); 00897 if (initial_cap < 0) initial_cap = 0; 00898 fs->cap = initial_cap; 00899 fs->count = 0; 00900 fs->f = Gif_NewArray(Gt_Frame, initial_cap); 00901 return fs; 00902 } |
|
Definition at line 1264 of file optimize.c. References create_new_image_data(), create_out_global_map(), create_subimages(), finalize_optimizer(), and initialize_optimizer(). Referenced by merge_and_write_frames().
01265 { 01266 if (!initialize_optimizer(gfs, optimize_level)) 01267 return; 01268 01269 create_subimages(gfs, optimize_level); 01270 create_out_global_map(gfs); 01271 create_new_image_data(gfs, optimize_level); 01272 01273 finalize_optimizer(gfs); 01274 } |
|
Definition at line 830 of file gifsicle.c. References active_next_output, BATCHING, clear_frameset(), Gt_Frameset::count, Gt_Frame::crop, Gt_Frame::explode_by_name, explode_filename(), EXPLODING, FRAME, Gif_ImageNumber(), i, Gif_Image::identifier, Gt_Frame::image, infoing, INSERTING, merge_and_write_frames(), MERGING, Gt_Frame::name, Gif_Stream::nimages, output_information(), Gt_OutputData::output_name, Gt_Crop::ready, and Gt_Frame::stream. Referenced by input_done(), and main().
00831 { 00832 /* Use the current output name, not the stored output name. 00833 This supports `gifsicle a.gif -o xxx'. 00834 It's not like any other option, but seems right: it fits the natural 00835 order -- input, then output. */ 00836 int i; 00837 char *outfile = active_output_data.output_name; 00838 active_output_data.output_name = 0; 00839 00840 /* Output information only now. */ 00841 if (infoing) 00842 output_information(outfile); 00843 00844 if (infoing != 1 && frames->count > 0) 00845 switch (mode) { 00846 00847 case MERGING: 00848 case BATCHING: 00849 merge_and_write_frames(outfile, 0, -1); 00850 break; 00851 00852 case EXPLODING: { 00853 /* Use the current output name for consistency, even though that means 00854 we can't explode different frames to different names. Not a big deal 00855 anyway; they can always repeat the gif on the cmd line. */ 00856 int max_nimages = 0; 00857 for (i = 0; i < frames->count; i++) { 00858 Gt_Frame *fr = &FRAME(frames, i); 00859 if (fr->stream->nimages > max_nimages) 00860 max_nimages = fr->stream->nimages; 00861 } 00862 00863 if (!outfile) /* Watch out! */ 00864 outfile = "-"; 00865 00866 for (i = 0; i < frames->count; i++) { 00867 Gt_Frame *fr = &FRAME(frames, i); 00868 int imagenumber = Gif_ImageNumber(fr->stream, fr->image); 00869 char *explodename; 00870 00871 char *imagename = 0; 00872 if (fr->explode_by_name) 00873 imagename = fr->name ? fr->name : fr->image->identifier; 00874 00875 explodename = explode_filename(outfile, imagenumber, imagename, 00876 max_nimages); 00877 merge_and_write_frames(explodename, i, i); 00878 } 00879 break; 00880 } 00881 00882 case INSERTING: 00883 /* do nothing */ 00884 break; 00885 00886 } 00887 00888 active_next_output = 0; 00889 clear_frameset(frames, 0); 00890 00891 /* cropping: clear the `crop->ready' information, which depended on the last 00892 input image. */ 00893 if (def_frame.crop) 00894 def_frame.crop->ready = 0; 00895 } |
|
Definition at line 698 of file support.c. References arg, Gif_Color::blue, Clp_OptionError(), error(), Gif_Color::green, Gif_Color::haspixel, parse_hex_color_channel(), Gif_Color::pixel, and Gif_Color::red. Referenced by parse_two_colors().
00699 { 00700 const char *input_arg = arg; 00701 char *str; 00702 int red, green, blue; 00703 00704 if (*arg == '#') { 00705 int len = strlen(++arg); 00706 if (!len || len % 3 != 0 || strspn(arg, "0123456789ABCDEFabcdef") != len) { 00707 if (complain) 00708 Clp_OptionError(clp, "invalid color `%s' (want `#RGB' or `#RRGGBB')", 00709 input_arg); 00710 return 0; 00711 } 00712 00713 len /= 3; 00714 red = parse_hex_color_channel(&arg[ 0 * len ], len); 00715 green = parse_hex_color_channel(&arg[ 1 * len ], len); 00716 blue = parse_hex_color_channel(&arg[ 2 * len ], len); 00717 goto gotrgb; 00718 00719 } else if (!isdigit(*arg)) 00720 goto error; 00721 00722 red = strtol(arg, &str, 10); 00723 if (*str == 0) { 00724 if (red < 0 || red > 255) 00725 goto error; 00726 parsed_color.haspixel = 1; 00727 parsed_color.pixel = red; 00728 return 1; 00729 00730 } else if (*str != ',' && *str != '/') 00731 goto error; 00732 00733 if (*++str == 0) goto error; 00734 green = strtol(str, &str, 10); 00735 if (*str != ',' && *str != '/') goto error; 00736 00737 if (*++str == 0) goto error; 00738 blue = strtol(str, &str, 10); 00739 if (*str != 0) goto error; 00740 00741 gotrgb: 00742 if (red < 0 || green < 0 || blue < 0 00743 || red > 255 || green > 255 || blue > 255) 00744 goto error; 00745 parsed_color.red = red; 00746 parsed_color.green = green; 00747 parsed_color.blue = blue; 00748 parsed_color.haspixel = 0; 00749 return 1; 00750 00751 error: 00752 if (complain) 00753 return Clp_OptionError(clp, "invalid color `%s'", input_arg); 00754 else 00755 return 0; 00756 } |
|
Definition at line 569 of file support.c. References arg, Clp_OptionError(), dimensions_x, and dimensions_y. Referenced by parse_rectangle().
00570 { 00571 char *val; 00572 00573 if (*arg == '_' && arg[1] == 'x') { 00574 dimensions_x = 0; 00575 val = (char *)(arg + 1); 00576 } else 00577 dimensions_x = strtol(arg, &val, 10); 00578 if (*val == 'x') { 00579 if (val[1] == '_' && val[2] == 0) { 00580 dimensions_y = 0; 00581 val = val + 2; 00582 } else 00583 dimensions_y = strtol(val + 1, &val, 10); 00584 if (*val == 0) 00585 return 1; 00586 } 00587 00588 if (complain) 00589 return Clp_OptionError(clp, "invalid dimensions `%s' (want WxH)", arg); 00590 else 00591 return 0; 00592 } |
|
Definition at line 488 of file support.c. References arg, c, Clp_OptionError(), frame_spec_1, frame_spec_2, frame_spec_name, Gif_GetNamedImage(), Gif_ImageCount, Gif_ImageNumber(), and input_stream(). Referenced by frame_argument().
00489 { 00490 char *c; 00491 00492 frame_spec_1 = 0; 00493 frame_spec_2 = -1; 00494 frame_spec_name = 0; 00495 00496 if (!input && !input_name) 00497 input_stream(0); 00498 if (!input) 00499 return 0; 00500 00501 if (arg[0] != '#') { 00502 if (complain) 00503 return Clp_OptionError(clp, "frame specifications must start with #"); 00504 else 00505 return 0; 00506 } 00507 arg++; 00508 c = (char *)arg; 00509 00510 /* Get a number range (#x, #x-y, or #x-). First, read x. */ 00511 if (isdigit(c[0])) 00512 frame_spec_1 = frame_spec_2 = strtol(c, &c, 10); 00513 else if (c[0] == '-' && isdigit(c[1])) { 00514 frame_spec_1 = frame_spec_2 = Gif_ImageCount(input) + strtol(c, &c, 10); 00515 if (frame_spec_1 < 0) 00516 return complain ? Clp_OptionError(clp, "there are only %d frames", 00517 Gif_ImageCount(input)) : 0; 00518 } 00519 00520 /* Then, if the next character is a dash, read y. Be careful to prevent 00521 #- from being interpreted as a frame range. */ 00522 if (c[0] == '-' && (frame_spec_2 > 0 || c[1] != 0)) { 00523 c++; 00524 if (isdigit(c[0])) 00525 frame_spec_2 = strtol(c, &c, 10); 00526 else if (c[0] == '-' && isdigit(c[1])) 00527 frame_spec_2 = Gif_ImageCount(input) + strtol(c, &c, 10); 00528 else 00529 frame_spec_2 = Gif_ImageCount(input) - 1; 00530 } 00531 00532 /* It really was a number range (and not a frame name) 00533 only if c is now at the end of the argument. */ 00534 if (c[0] != 0) { 00535 Gif_Image *gfi = Gif_GetNamedImage(input, arg); 00536 if (gfi) { 00537 frame_spec_name = (char *)arg; 00538 frame_spec_1 = frame_spec_2 = Gif_ImageNumber(input, gfi); 00539 return 1; 00540 } else if (complain < 0) /* -1 is special value meaning `don't complain 00541 about frame NAMES, but do complain about 00542 frame numbers.' */ 00543 return -97; /* Return -97 on bad frame name. */ 00544 else if (complain) 00545 return Clp_OptionError(clp, "no frame named `#%s'", arg); 00546 else 00547 return 0; 00548 00549 } else { 00550 if (frame_spec_1 >= 0 && frame_spec_1 <= frame_spec_2 00551 && frame_spec_2 < Gif_ImageCount(input)) 00552 return 1; 00553 else if (!complain) 00554 return 0; 00555 00556 if (frame_spec_1 == frame_spec_2) 00557 return Clp_OptionError(clp, "no frame number #%d", frame_spec_1); 00558 else if (frame_spec_1 < 0) 00559 return Clp_OptionError(clp, "frame numbers can't be negative"); 00560 else if (frame_spec_1 > frame_spec_2) 00561 return Clp_OptionError(clp, "empty frame range"); 00562 else 00563 return Clp_OptionError(clp, "there are only %d frames", 00564 Gif_ImageCount(input)); 00565 } 00566 } |
|
Definition at line 595 of file support.c. References arg, Clp_OptionError(), position_x, and position_y. Referenced by parse_rectangle().
00596 { 00597 char *val; 00598 00599 position_x = strtol(arg, &val, 10); 00600 if (*val == ',') { 00601 position_y = strtol(val + 1, &val, 10); 00602 if (*val == 0) 00603 return 1; 00604 } 00605 00606 if (complain) 00607 return Clp_OptionError(clp, "invalid position `%s' (want `X,Y')", arg); 00608 else 00609 return 0; 00610 } |
|
Definition at line 634 of file support.c. References arg, Clp_OptionError(), dimensions_x, dimensions_y, parse_dimensions(), parse_position(), position_x, and position_y.
00635 { 00636 const char *input_arg = arg; 00637 char *val; 00638 00639 int x = position_x = strtol(arg, &val, 10); 00640 if (*val == ',') { 00641 int y = position_y = strtol(val + 1, &val, 10); 00642 if (*val == '-' && parse_position(clp, val + 1, 0, 0)) { 00643 if (x >= 0 && y >= 0 && x < position_x && y < position_y) { 00644 dimensions_x = position_x - x; 00645 dimensions_y = position_y - y; 00646 position_x = x; 00647 position_y = y; 00648 return 1; 00649 } 00650 } else if (*val == '+' && parse_dimensions(clp, val + 1, 0, 0)) 00651 return 1; 00652 } else if (*val == 'x') { 00653 dimensions_x = position_x; 00654 dimensions_y = strtol(val + 1, &val, 10); 00655 if (*val == 0) { 00656 position_x = position_y = 0; 00657 return 1; 00658 } 00659 } 00660 00661 if (complain) 00662 return Clp_OptionError(clp, "invalid rectangle `%s' (want `X1,Y1-X2,Y2' or `X1,Y1+WxH'", input_arg); 00663 else 00664 return 0; 00665 } |
|
Definition at line 613 of file support.c. References arg, Clp_OptionError(), parsed_scale_factor_x, parsed_scale_factor_y, and strtod().
00614 { 00615 char *val; 00616 00617 parsed_scale_factor_x = strtod(arg, &val); 00618 if (*val == 'x') { 00619 parsed_scale_factor_y = strtod(val + 1, &val); 00620 if (*val == 0) 00621 return 1; 00622 } else if (*val == 0) { 00623 parsed_scale_factor_y = parsed_scale_factor_x; 00624 return 1; 00625 } 00626 00627 if (complain) 00628 return Clp_OptionError(clp, "invalid scale factor `%s' (want XxY)", arg); 00629 else 00630 return 0; 00631 } |
|
Definition at line 759 of file support.c. References arg, Clp_OptionError(), Clp_Shift(), and parse_color().
00760 { 00761 Gif_Color old_color; 00762 if (parse_color(clp, arg, complain, thunk) <= 0) 00763 return 0; 00764 old_color = parsed_color; 00765 00766 arg = Clp_Shift(clp, 0); 00767 if (!arg && complain) 00768 return Clp_OptionError(clp, "`%O' takes two color arguments"); 00769 else if (!arg) 00770 return 0; 00771 00772 if (parse_color(clp, arg, complain, thunk) <= 0) 00773 return 0; 00774 00775 parsed_color2 = parsed_color; 00776 parsed_color = old_color; 00777 return 1; 00778 } |
|
Definition at line 127 of file xform.c. References Gif_Colormap::col, error(), fatal_error(), Gif_DeleteArray, Gif_DeleteColormap(), Gif_NewArray, i, nc, Gif_Colormap::ncol, pclose, popen, read_colormap_file(), strerror(), and warning().
00128 { 00129 int i, status; 00130 FILE *f; 00131 Gif_Color *col = gfcm->col; 00132 Gif_Colormap *new_cm = 0; 00133 char *command = (char *)thunk; 00134 char *tmp_file = tmpnam(0); 00135 char *new_command; 00136 00137 if (!tmp_file) 00138 fatal_error("can't create temporary file!"); 00139 00140 new_command = Gif_NewArray(char, strlen(command) + strlen(tmp_file) + 4); 00141 sprintf(new_command, "%s >%s", command, tmp_file); 00142 f = popen(new_command, "w"); 00143 if (!f) 00144 fatal_error("can't run color transformation command: %s", strerror(errno)); 00145 Gif_DeleteArray(new_command); 00146 00147 for (i = 0; i < gfcm->ncol; i++) 00148 fprintf(f, "%d %d %d\n", col[i].red, col[i].green, col[i].blue); 00149 00150 errno = 0; 00151 status = pclose(f); 00152 if (status < 0) { 00153 error("color transformation error: %s", strerror(errno)); 00154 goto done; 00155 } else if (status > 0) { 00156 error("color transformation command failed"); 00157 goto done; 00158 } 00159 00160 f = fopen(tmp_file, "r"); 00161 if (!f || feof(f)) { 00162 error("color transformation command generated no output", command); 00163 if (f) fclose(f); 00164 goto done; 00165 } 00166 new_cm = read_colormap_file("<color transformation>", f); 00167 fclose(f); 00168 00169 if (new_cm) { 00170 int nc = new_cm->ncol; 00171 if (nc < gfcm->ncol) { 00172 nc = gfcm->ncol; 00173 warning("too few colors in color transformation results"); 00174 } else if (nc > gfcm->ncol) 00175 warning("too many colors in color transformation results"); 00176 for (i = 0; i < nc; i++) 00177 col[i] = new_cm->col[i]; 00178 } 00179 00180 done: 00181 remove(tmp_file); 00182 Gif_DeleteColormap(new_cm); 00183 } |
|
Definition at line 841 of file support.c. References c, error(), Gif_Stream::errors, Gif_CopyColormap(), Gif_DeleteStream(), Gif_ReadFile, Gif_Stream::global, name, read_text_colormap(), strerror(), ungetc(), verbose_close(), verbose_open(), and warning(). Referenced by pipe_color_transformer(), and set_new_fixed_colormap().
00842 { 00843 Gif_Colormap *cm = 0; 00844 int c; 00845 int my_file = 0; 00846 00847 if (name && strcmp(name, "-") == 0) 00848 name = 0; 00849 if (!f) { 00850 my_file = 1; 00851 if (!name) 00852 f = stdin; 00853 else 00854 f = fopen(name, "rb"); 00855 if (!f) { 00856 error("%s: %s", name, strerror(errno)); 00857 return 0; 00858 } 00859 } 00860 00861 name = name ? name : "<stdin>"; 00862 if (verbosing) verbose_open('<', name); 00863 00864 c = getc(f); 00865 ungetc(c, f); 00866 if (c == 'G') { 00867 Gif_Stream *gfs = Gif_ReadFile(f); 00868 if (!gfs) 00869 error("`%s' doesn't seem to contain a GIF", name); 00870 else if (!gfs->global) 00871 error("can't use `%s' as a palette (no global color table)", name); 00872 else { 00873 if (gfs->errors) 00874 warning("there were errors reading `%s'", name); 00875 cm = Gif_CopyColormap(gfs->global); 00876 } 00877 00878 Gif_DeleteStream(gfs); 00879 } else 00880 cm = read_text_colormap(f, name); 00881 00882 if (my_file) fclose(f); 00883 if (verbosing) verbose_close('>'); 00884 return cm; 00885 } |
|
Definition at line 423 of file xform.c. References Gif_CalculateScreenSize(), i, Gif_Stream::images, Gif_Stream::nimages, scale_image(), Gif_Stream::screen_height, and Gif_Stream::screen_width. Referenced by merge_and_write_frames().
00424 { 00425 double xfactor, yfactor; 00426 int i; 00427 00428 if (new_width <= 0) 00429 new_width = (int)(((double)gfs->screen_width / gfs->screen_height) * new_height); 00430 if (new_height <= 0) 00431 new_height = (int)(((double)gfs->screen_height / gfs->screen_width) * new_width); 00432 00433 Gif_CalculateScreenSize(gfs, 0); 00434 xfactor = (double)new_width / gfs->screen_width; 00435 yfactor = (double)new_height / gfs->screen_height; 00436 for (i = 0; i < gfs->nimages; i++) 00437 scale_image(gfs, gfs->images[i], xfactor, yfactor); 00438 00439 gfs->screen_width = new_width; 00440 gfs->screen_height = new_height; 00441 } |
|
Definition at line 296 of file xform.c. References Gif_DeleteArrayFunc, Gif_NewArray, Gif_ReleaseUncompressedImage(), Gif_SetUncompressedImage(), Gif_Image::height, Gif_Image::img, Gif_Image::left, Gif_Image::top, and Gif_Image::width. Referenced by handle_flip_and_screen().
00297 { 00298 int x, y; 00299 int width = gfi->width; 00300 int height = gfi->height; 00301 byte **img = gfi->img; 00302 byte *new_data = Gif_NewArray(byte, width * height); 00303 byte *trav = new_data; 00304 00305 /* this function can only rotate by 90 or 270 degrees */ 00306 assert(rotation == 1 || rotation == 3); 00307 00308 if (rotation == 1) { 00309 for (x = 0; x < width; x++) 00310 for (y = height - 1; y >= 0; y--) 00311 *trav++ = img[y][x]; 00312 x = gfi->left; 00313 gfi->left = screen_height - (gfi->top + height); 00314 gfi->top = x; 00315 00316 } else { 00317 for (x = width - 1; x >= 0; x--) 00318 for (y = 0; y < height; y++) 00319 *trav++ = img[y][x]; 00320 y = gfi->top; 00321 gfi->top = screen_width - (gfi->left + width); 00322 gfi->left = y; 00323 } 00324 00325 Gif_ReleaseUncompressedImage(gfi); 00326 gfi->width = height; 00327 gfi->height = width; 00328 Gif_SetUncompressedImage(gfi, new_data, Gif_DeleteArrayFunc, 0); 00329 } |
|
Definition at line 341 of file xform.c. References fatal_error(), Gif_DeleteArrayFunc, Gif_NewArray, Gif_ReleaseCompressedImage(), Gif_ReleaseUncompressedImage(), Gif_SetUncompressedImage(), Gif_Image::height, i, Gif_Image::img, Gif_Image::left, SCALE, SCALE_FACTOR, Gif_Image::top, UNSCALE, and Gif_Image::width. Referenced by resize_stream().
00342 { 00343 byte *new_data; 00344 int new_left, new_top, new_right, new_bottom, new_width, new_height; 00345 00346 int i, j, new_x, new_y; 00347 int scaled_xstep, scaled_ystep, scaled_new_x, scaled_new_y; 00348 00349 /* Fri 9 Jan 1999: Fix problem with resizing animated GIFs: we scaled from 00350 left edge of the *subimage* to right edge of the subimage, causing 00351 consistency problems when several subimages overlap. Solution: always use 00352 scale factors relating to the *whole image* (the screen size). */ 00353 00354 /* use fixed-point arithmetic */ 00355 scaled_xstep = (int)(SCALE_FACTOR * xfactor + 0.5); 00356 scaled_ystep = (int)(SCALE_FACTOR * yfactor + 0.5); 00357 00358 /* calculate new width and height based on the four edges (left, right, top, 00359 bottom). This is better than simply multiplying the width and height by 00360 the scale factors because it avoids roundoff inconsistencies between 00361 frames on animated GIFs. Don't allow 0-width or 0-height images; GIF 00362 doesn't support them well. */ 00363 new_left = UNSCALE(scaled_xstep * gfi->left); 00364 new_top = UNSCALE(scaled_ystep * gfi->top); 00365 new_right = UNSCALE(scaled_xstep * (gfi->left + gfi->width)); 00366 new_bottom = UNSCALE(scaled_ystep * (gfi->top + gfi->height)); 00367 00368 new_width = new_right - new_left; 00369 new_height = new_bottom - new_top; 00370 00371 if (new_width <= 0) new_width = 1, new_right = new_left + 1; 00372 if (new_height <= 0) new_height = 1, new_bottom = new_top + 1; 00373 if (new_width > UNSCALE(INT_MAX) || new_height > UNSCALE(INT_MAX)) 00374 fatal_error("new image size is too big for me to handle"); 00375 00376 assert(gfi->img); 00377 new_data = Gif_NewArray(byte, new_width * new_height); 00378 00379 new_y = new_top; 00380 scaled_new_y = scaled_ystep * gfi->top; 00381 00382 for (j = 0; j < gfi->height; j++) { 00383 byte *in_line = gfi->img[j]; 00384 byte *out_data; 00385 int x_delta, y_delta, yinc; 00386 00387 scaled_new_y += scaled_ystep; 00388 /* account for images which should've had 0 height but don't */ 00389 if (j == gfi->height - 1) scaled_new_y = SCALE(new_bottom); 00390 00391 if (scaled_new_y < SCALE(new_y + 1)) continue; 00392 y_delta = UNSCALE(scaled_new_y - SCALE(new_y)); 00393 00394 new_x = new_left; 00395 scaled_new_x = scaled_xstep * gfi->left; 00396 out_data = &new_data[(new_y - new_top) * new_width + (new_x - new_left)]; 00397 00398 for (i = 0; i < gfi->width; i++) { 00399 scaled_new_x += scaled_xstep; 00400 /* account for images which should've had 0 width but don't */ 00401 if (i == gfi->width - 1) scaled_new_x = SCALE(new_right); 00402 00403 x_delta = UNSCALE(scaled_new_x - SCALE(new_x)); 00404 00405 for (; x_delta > 0; new_x++, x_delta--, out_data++) 00406 for (yinc = 0; yinc < y_delta; yinc++) 00407 out_data[yinc * new_width] = in_line[i]; 00408 } 00409 00410 new_y += y_delta; 00411 } 00412 00413 Gif_ReleaseUncompressedImage(gfi); 00414 Gif_ReleaseCompressedImage(gfi); 00415 gfi->width = new_width; 00416 gfi->height = new_height; 00417 gfi->left = UNSCALE(scaled_xstep * gfi->left); 00418 gfi->top = UNSCALE(scaled_ystep * gfi->top); 00419 Gif_SetUncompressedImage(gfi, new_data, Gif_DeleteArrayFunc, 0); 00420 } |
|
Definition at line 225 of file gifview.c. References program_name.
00226 { 00227 fprintf(stderr, "Usage: %s [--display DISPLAY] [OPTION]... [FILE | FRAME]...\n\ 00228 Try `%s --help' for more information.\n", 00229 program_name, program_name); 00230 } |
|
Definition at line 356 of file support.c. References Gif_Stream::background, colormap_info(), Gif_Stream::comment, comment_info(), extension_info(), Gif_Stream::extensions, Gif_Stream::global, Gif_Stream::loopcount, Gif_Colormap::ncol, Gif_Extension::next, Gif_Stream::nimages, Gif_Stream::screen_height, Gif_Stream::screen_width, and verbose_endline(). Referenced by output_information().
00358 { 00359 Gif_Extension *gfex; 00360 int n; 00361 00362 if (!gfs) return; 00363 00364 verbose_endline(); 00365 fprintf(where, "* %s %d image%s\n", (filename ? filename : "<stdin>"), 00366 gfs->nimages, gfs->nimages == 1 ? "" : "s"); 00367 fprintf(where, " logical screen %dx%d\n", 00368 gfs->screen_width, gfs->screen_height); 00369 00370 if (gfs->global) { 00371 fprintf(where, " global color table [%d]\n", gfs->global->ncol); 00372 if (colormaps) colormap_info(where, gfs->global, " |"); 00373 fprintf(where, " background %d\n", gfs->background); 00374 } 00375 00376 if (gfs->comment) 00377 comment_info(where, gfs->comment, " end comment "); 00378 00379 if (gfs->loopcount == 0) 00380 fprintf(where, " loop forever\n"); 00381 else if (gfs->loopcount > 0) 00382 fprintf(where, " loop count %u\n", (unsigned)gfs->loopcount); 00383 00384 for (n = 0, gfex = gfs->extensions; gfex; gfex = gfex->next, n++) 00385 if (extensions) 00386 extension_info(where, gfs, gfex, n); 00387 if (n && !extensions) 00388 fprintf(where, " extensions %d\n", n); 00389 } |
|
Definition at line 22 of file gifsicledir/merge.c. References Gif_Colormap::col, i, and Gif_Colormap::ncol. Referenced by colormap_stream(), and histogram().
|
|
Definition at line 31 of file gifsicledir/merge.c. References Gif_Colormap::col, i, and Gif_Colormap::ncol. Referenced by merge_frame_interval(), and merge_stream().
|
|
Definition at line 233 of file gifview.c.
00234 { 00235 printf("\ 00236 `Gifview' is a lightweight GIF viewer for X. It can display animated GIFs as\n\ 00237 slideshows, one frame at a time, or as animations.\n\ 00238 \n\ 00239 Usage: %s [--display DISPLAY] [OPTION]... [FILE | FRAME]...\n\ 00240 \n\ 00241 Options are:\n\ 00242 -a, --animate Animate multiframe GIFs.\n\ 00243 -U, --unoptimize Unoptimize displayed GIFs.\n\ 00244 -d, --display DISPLAY Set display to DISPLAY.\n\ 00245 --name NAME Set application resource name to NAME.\n\ 00246 -g, --geometry GEOMETRY Set window geometry.\n\ 00247 -w, --window WINDOW Show GIF in existing WINDOW.\n\ 00248 -i, --install-colormap Use a private colormap.\n\ 00249 --bg, --background COLOR Use COLOR for transparent pixels.\n\ 00250 +e, --no-interactive Ignore buttons and keystrokes.\n\ 00251 --help Print this message and exit.\n\ 00252 --version Print version number and exit.\n\ 00253 \n\ 00254 Frame selections: #num, #num1-num2, #num1-, #name\n\ 00255 \n\ 00256 Keystrokes:\n\ 00257 [Space] Go to next frame. [B] Go to previous frame.\n\ 00258 [R]/[<] Go to first frame. [>] Go to last frame.\n\ 00259 [ESC] Stop animation. [S]/[A] Toggle animation.\n\ 00260 [U] Toggle unoptimization. [Backspace]/[W] Delete window.\n\ 00261 [Q] Quit.\n\ 00262 \n\ 00263 Left mouse button goes to next frame, right mouse button deletes window.\n\ 00264 \n\ 00265 Report bugs to <eddietwo@lcs.mit.edu>.\n", program_name); 00266 } |
|
Definition at line 222 of file support.c. References close(), and verbose_pos. Referenced by input_done(), input_stream(), merge_and_write_frames(), and read_colormap_file().
00223 { 00224 fputc(close, stderr); 00225 verbose_pos++; 00226 } |
|
Definition at line 230 of file support.c. References verbose_pos. Referenced by clp_error_handler(), image_info(), main(), stream_info(), and verror().
00231 { 00232 if (verbose_pos) { 00233 fputc('\n', stderr); 00234 fflush(stderr); 00235 verbose_pos = 0; 00236 } 00237 } |
|
Definition at line 204 of file support.c. References l, name, and verbose_pos. Referenced by input_stream(), merge_and_write_frames(), and read_colormap_file().
00205 { 00206 int l = strlen(name); 00207 if (verbose_pos && verbose_pos + 3 + l > 79) { 00208 fputc('\n', stderr); 00209 verbose_pos = 0; 00210 } 00211 if (verbose_pos) { 00212 fputc(' ', stderr); 00213 verbose_pos++; 00214 } 00215 fputc(open, stderr); 00216 fputs(name, stderr); 00217 verbose_pos += 1 + l; 00218 } |
|
Definition at line 86 of file support.c. References verror(). Referenced by do_colormap_change(), find_background(), input_stream(), merge_colormap_if_possible(), print_useless_options(), and redundant_option_warning().
00087 { 00088 va_list val; 00089 va_start(val, message); 00090 verror(0, message, val); 00091 va_end(val); 00092 } |
|
Definition at line 215 of file gifview.c. References verror(). Referenced by colormap_diversity(), colormap_median_cut(), find_background(), input_stream(), merge_colormap_if_possible(), new_viewer(), parse_geometry(), pipe_color_transformer(), print_useless_options(), read_colormap_file(), and redundant_option_warning().
00216 { 00217 va_list val; 00218 va_start(val, message); 00219 fprintf(stderr, "%s: warning: ", program_name); 00220 vfprintf(stderr, message, val); 00221 fputc('\n', stderr); 00222 } |
Variable Documentation
|
Definition at line 254 of file gifsicle.h. |
|
Definition at line 227 of file gifsicle.h. Referenced by parse_dimensions(), and parse_rectangle(). |
|
Definition at line 228 of file gifsicle.h. Referenced by parse_dimensions(), and parse_rectangle(). |
|
Definition at line 125 of file gifsicle.h. Referenced by verror(). |
|
Definition at line 224 of file gifsicle.h. Referenced by parse_frame_spec(). |
|
Definition at line 225 of file gifsicle.h. Referenced by parse_frame_spec(). |
|
Definition at line 226 of file gifsicle.h. Referenced by parse_frame_spec(). |
|
Definition at line 127 of file gifsicle.h. Referenced by input_stream(), and main(). |
|
Definition at line 128 of file gifsicle.h. Referenced by main(), and write_stream(). |
|
Definition at line 244 of file gifsicle.h. |
|
Definition at line 245 of file gifsicle.h. Referenced by input_stream(). |
|
Definition at line 126 of file gifsicle.h. |
|
Definition at line 231 of file gifsicle.h. |
|
Definition at line 232 of file gifsicle.h. |
|
Definition at line 233 of file gifsicle.h. Referenced by parse_scale_factor(). |
|
Definition at line 234 of file gifsicle.h. Referenced by parse_scale_factor(). |
|
Definition at line 229 of file gifsicle.h. Referenced by parse_position(), and parse_rectangle(). |
|
Definition at line 230 of file gifsicle.h. Referenced by parse_position(), and parse_rectangle(). |
|
Definition at line 123 of file gifsicle.h. Referenced by short_usage(), usage(), and verror(). |
|
Definition at line 124 of file gifsicle.h. Referenced by main(). |
|
Definition at line 164 of file gifsicle.h. Referenced by merge_and_write_frames(). |