Doxygen Source Code Documentation
gifsicle.c File Reference
#include "config.h"
#include "gifsicle.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <errno.h>
Go to the source code of this file.
Defines | |
#define | BLANK_MODE 0 |
#define | MERGING 1 |
#define | BATCHING 2 |
#define | EXPLODING 3 |
#define | DELETING 4 |
#define | INSERTING 5 |
#define | CHANGED(next, flag) (((next) & 1<<(flag)) != 0) |
#define | UNCHECKED_MARK_CH(where, what) next_##where |= 1<<what; |
#define | MARK_CH(where, what) |
#define | CH_INTERLACE 0 |
#define | CH_DISPOSAL 1 |
#define | CH_DELAY 2 |
#define | CH_TRANSPARENT 3 |
#define | CH_COMMENT 4 |
#define | CH_NAME 5 |
#define | CH_POSITION 6 |
#define | CH_CROP 7 |
#define | CH_EXTENSION 8 |
#define | CH_FLIP 9 |
#define | CH_ROTATE 10 |
#define | CH_UNOPTIMIZE 0 |
#define | CH_CHANGE_COLOR 1 |
#define | CH_LOOPCOUNT 0 |
#define | CH_LOGICAL_SCREEN 1 |
#define | CH_OPTIMIZE 2 |
#define | CH_OUTPUT 3 |
#define | CH_COLORMAP 4 |
#define | CH_DITHER 5 |
#define | CH_USE_COLORMAP 6 |
#define | CH_COLORMAP_METHOD 7 |
#define | CH_BACKGROUND 8 |
#define | CH_COLOR_TRANSFORM 9 |
#define | CH_RESIZE 10 |
#define | SAME_INTERLACE_OPT 300 |
#define | INFO_OPT 301 |
#define | DISPOSAL_OPT 302 |
#define | SAME_LOOPCOUNT_OPT 303 |
#define | SAME_DISPOSAL_OPT 304 |
#define | SAME_DELAY_OPT 305 |
#define | SAME_TRANSPARENT_OPT 308 |
#define | LOGICAL_SCREEN_OPT 309 |
#define | COMMENT_OPT 310 |
#define | UNOPTIMIZE_OPT 311 |
#define | CAREFUL_OPT 312 |
#define | OPTIMIZE_OPT 313 |
#define | SAME_LOGICAL_SCREEN_OPT 314 |
#define | DELETE_OPT 315 |
#define | REPLACE_OPT 316 |
#define | INSERT_OPT 317 |
#define | ALTER_DONE_OPT 318 |
#define | APPEND_OPT 319 |
#define | COLOR_INFO_OPT 320 |
#define | VERBOSE_OPT 321 |
#define | NO_COMMENTS_OPT 322 |
#define | SAME_COMMENTS_OPT 323 |
#define | NAME_OPT 324 |
#define | SAME_NAME_OPT 325 |
#define | NO_NAME_OPT 326 |
#define | POSITION_OPT 327 |
#define | SAME_POSITION_OPT 328 |
#define | VERSION_OPT 329 |
#define | HELP_OPT 330 |
#define | OUTPUT_OPT 331 |
#define | CROP_OPT 332 |
#define | SAME_CROP_OPT 333 |
#define | CHANGE_COLOR_OPT 334 |
#define | COLORMAP_OPT 335 |
#define | COLORMAP_ALGORITHM_OPT 336 |
#define | DITHER_OPT 337 |
#define | USE_COLORMAP_OPT 338 |
#define | NO_EXTENSIONS_OPT 339 |
#define | SAME_EXTENSIONS_OPT 340 |
#define | EXTENSION_INFO_OPT 341 |
#define | BACKGROUND_OPT 342 |
#define | SAME_BACKGROUND_OPT 343 |
#define | FLIP_HORIZ_OPT 344 |
#define | FLIP_VERT_OPT 345 |
#define | NO_FLIP_OPT 346 |
#define | ROTATE_90_OPT 347 |
#define | ROTATE_180_OPT 348 |
#define | ROTATE_270_OPT 349 |
#define | NO_ROTATE_OPT 350 |
#define | APP_EXTENSION_OPT 351 |
#define | EXTENSION_OPT 352 |
#define | COLOR_TRANSFORM_OPT 353 |
#define | RESIZE_OPT 354 |
#define | SCALE_OPT 355 |
#define | NO_WARNINGS_OPT 356 |
#define | WARNINGS_OPT 357 |
#define | RESIZE_WIDTH_OPT 358 |
#define | RESIZE_HEIGHT_OPT 359 |
#define | LOOP_TYPE (Clp_MaxDefaultType + 1) |
#define | DISPOSAL_TYPE (Clp_MaxDefaultType + 2) |
#define | DIMENSIONS_TYPE (Clp_MaxDefaultType + 3) |
#define | FRAME_SPEC_TYPE (Clp_MaxDefaultType + 4) |
#define | COLOR_TYPE (Clp_MaxDefaultType + 5) |
#define | POSITION_TYPE (Clp_MaxDefaultType + 6) |
#define | RECTANGLE_TYPE (Clp_MaxDefaultType + 7) |
#define | TWO_COLORS_TYPE (Clp_MaxDefaultType + 8) |
#define | COLORMAP_ALG_TYPE (Clp_MaxDefaultType + 9) |
#define | SCALE_FACTOR_TYPE (Clp_MaxDefaultType + 10) |
#define | COMBINE_ONE_OUTPUT_OPTION(value, field) |
Functions | |
void | combine_output_options (void) |
void | initialize_def_frame (void) |
void | redundant_option_warning (const char *) |
void | set_mode (int newmode) |
void | set_frame_change (int kind) |
void | frame_change_done (void) |
void | show_frame (int imagenumber, int usename) |
void | gifread_error (const char *message, int which_image, void *thunk) |
void | input_stream (char *name) |
void | input_done (void) |
void | set_new_fixed_colormap (char *name) |
void | do_set_colormap (Gif_Stream *gfs, Gif_Colormap *gfcm) |
void | do_colormap_change (Gif_Stream *gfs) |
void | write_stream (char *output_name, Gif_Stream *gfs) |
void | merge_and_write_frames (char *outfile, int f1, int f2) |
void | output_information (const char *outfile) |
void | output_frames (void) |
int | frame_argument (Clp_Parser *clp, char *arg) |
int | handle_extension (Clp_Parser *clp, int is_app) |
void | print_useless_options (const char *type_name, int value, const char *names[]) |
int | main (int argc, char **argv) |
Variables | |
Gt_Frame | def_frame |
Gt_Frameset * | frames = 0 |
int | first_input_frame = 0 |
Gt_Frameset * | nested_frames = 0 |
Gif_Stream * | input = 0 |
char * | input_name = 0 |
int | unoptimizing = 0 |
int | gif_read_flags = 0 |
int | gif_write_flags = 0 |
int | frames_done = 0 |
int | files_given = 0 |
int | warn_local_colormaps = 1 |
Gt_ColorTransform * | input_transforms |
Gt_ColorTransform * | output_transforms |
int | mode = BLANK_MODE |
int | nested_mode = 0 |
int | infoing = 0 |
int | verbosing = 0 |
int | next_frame = 0 |
const char * | frame_option_types [] |
int | next_input = 0 |
const char * | input_option_types [] |
Gt_OutputData | def_output_data |
Gt_OutputData | active_output_data |
int | next_output = 0 |
int | active_next_output = 0 |
int | any_output_successful = 0 |
const char * | output_option_types [] |
Clp_Option | options [] |
int | gifread_error_count |
Define Documentation
|
Definition at line 136 of file gifsicle.c. Referenced by main(). |
|
Definition at line 169 of file gifsicle.c. Referenced by main(). |
|
Definition at line 137 of file gifsicle.c. Referenced by main(), and set_frame_change(). |
|
Definition at line 160 of file gifsicle.c. Referenced by main(). |
|
Definition at line 50 of file gifsicle.c. Referenced by input_done(), input_stream(), main(), output_frames(), and show_frame(). |
|
Definition at line 48 of file gifsicle.c. Referenced by input_stream(), set_frame_change(), and set_mode(). |
|
Definition at line 130 of file gifsicle.c. Referenced by main(). |
|
Definition at line 110 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 91 of file gifsicle.c. Referenced by main(). |
|
Definition at line 111 of file gifsicle.c. Referenced by main(). |
|
Definition at line 106 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 109 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 75 of file gifsicle.c. Referenced by input_stream(), and main(). |
|
Definition at line 78 of file gifsicle.c. Referenced by main(). |
|
Definition at line 73 of file gifsicle.c. Referenced by main(). |
|
Definition at line 72 of file gifsicle.c. Referenced by main(). |
|
Definition at line 107 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 79 of file gifsicle.c. Referenced by handle_extension(), and input_stream(). |
|
Definition at line 80 of file gifsicle.c. Referenced by main(). |
|
Definition at line 71 of file gifsicle.c. Referenced by main(). |
|
Definition at line 103 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 102 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 76 of file gifsicle.c. Referenced by input_stream(), and main(). |
|
Definition at line 104 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 105 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 77 of file gifsicle.c. Referenced by main(). |
|
Definition at line 112 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 81 of file gifsicle.c. Referenced by main(). |
|
Definition at line 74 of file gifsicle.c. Referenced by main(). |
|
Definition at line 90 of file gifsicle.c. Referenced by main(). |
|
Definition at line 108 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 152 of file gifsicle.c. Referenced by main(). |
|
Definition at line 61 of file gifsicle.c. Referenced by combine_output_options(), input_stream(), and print_useless_options(). |
|
Definition at line 138 of file gifsicle.c. Referenced by main(). |
|
Definition at line 171 of file gifsicle.c. Referenced by main(). |
|
Definition at line 183 of file gifsicle.c. Referenced by main(). |
|
Definition at line 187 of file gifsicle.c. Referenced by main(). |
|
Definition at line 154 of file gifsicle.c. Referenced by main(). |
|
Definition at line 153 of file gifsicle.c. Referenced by main(). |
|
Value: |
|
Definition at line 128 of file gifsicle.c. Referenced by main(). |
|
Definition at line 150 of file gifsicle.c. Referenced by main(). |
|
Definition at line 133 of file gifsicle.c. Referenced by main(), and set_frame_change(). |
|
Definition at line 52 of file gifsicle.c. Referenced by input_done(), set_frame_change(), and show_frame(). |
|
Definition at line 181 of file gifsicle.c. Referenced by main(). |
|
Definition at line 122 of file gifsicle.c. Referenced by main(). |
|
Definition at line 180 of file gifsicle.c. Referenced by main(). |
|
Definition at line 155 of file gifsicle.c. Referenced by main(). |
|
Definition at line 51 of file gifsicle.c. Referenced by input_done(), input_stream(), main(), output_frames(), and show_frame(). |
|
Definition at line 159 of file gifsicle.c. Referenced by main(). |
|
Definition at line 170 of file gifsicle.c. Referenced by main(). |
|
Definition at line 162 of file gifsicle.c. Referenced by main(). |
|
Definition at line 163 of file gifsicle.c. Referenced by main(). |
|
Definition at line 182 of file gifsicle.c. Referenced by main(). |
|
Definition at line 148 of file gifsicle.c. Referenced by main(). |
|
Definition at line 121 of file gifsicle.c. Referenced by main(). |
|
Definition at line 135 of file gifsicle.c. Referenced by main(), and set_frame_change(). |
|
Definition at line 53 of file gifsicle.c. Referenced by output_frames(), set_frame_change(), and show_frame(). |
|
Definition at line 127 of file gifsicle.c. Referenced by main(). |
|
Definition at line 179 of file gifsicle.c. Referenced by main(). |
|
Value: if (CHANGED(next_##where, what)) \ redundant_option_warning(where##_option_types[what]); \ UNCHECKED_MARK_CH(where, what) Definition at line 64 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
|
Definition at line 142 of file gifsicle.c. Referenced by main(). |
|
Definition at line 140 of file gifsicle.c. Referenced by main(). |
|
Definition at line 157 of file gifsicle.c. Referenced by main(). |
|
Definition at line 164 of file gifsicle.c. Referenced by main(). |
|
Definition at line 144 of file gifsicle.c. Referenced by main(). |
|
Definition at line 168 of file gifsicle.c. Referenced by main(). |
|
Definition at line 174 of file gifsicle.c. Referenced by main(). |
|
Definition at line 131 of file gifsicle.c. Referenced by main(). |
|
Definition at line 149 of file gifsicle.c. Referenced by main(). |
|
Definition at line 145 of file gifsicle.c. Referenced by main(). |
|
Definition at line 184 of file gifsicle.c. Referenced by main(). |
|
Definition at line 185 of file gifsicle.c. Referenced by main(). |
|
Definition at line 134 of file gifsicle.c. Referenced by main(), and set_frame_change(). |
|
Definition at line 177 of file gifsicle.c. Referenced by main(). |
|
Definition at line 172 of file gifsicle.c. Referenced by main(). |
|
Definition at line 176 of file gifsicle.c. Referenced by main(). |
|
Definition at line 166 of file gifsicle.c. Referenced by main(). |
|
Definition at line 167 of file gifsicle.c. Referenced by main(). |
|
Definition at line 165 of file gifsicle.c. Referenced by main(). |
|
Definition at line 161 of file gifsicle.c. Referenced by main(). |
|
Definition at line 141 of file gifsicle.c. Referenced by main(). |
|
Definition at line 151 of file gifsicle.c. Referenced by main(). |
|
Definition at line 125 of file gifsicle.c. Referenced by main(). |
|
Definition at line 124 of file gifsicle.c. Referenced by main(). |
|
Definition at line 158 of file gifsicle.c. Referenced by main(). |
|
Definition at line 120 of file gifsicle.c. Referenced by main(). |
|
Definition at line 132 of file gifsicle.c. Referenced by main(). |
|
Definition at line 123 of file gifsicle.c. Referenced by main(). |
|
Definition at line 143 of file gifsicle.c. Referenced by main(). |
|
Definition at line 146 of file gifsicle.c. Referenced by main(). |
|
Definition at line 126 of file gifsicle.c. Referenced by main(). |
|
Definition at line 188 of file gifsicle.c. Referenced by main(). |
|
Definition at line 173 of file gifsicle.c. Referenced by main(). |
|
Definition at line 186 of file gifsicle.c. Referenced by main(). |
|
Definition at line 62 of file gifsicle.c. Referenced by handle_extension(), and main(). |
|
Definition at line 129 of file gifsicle.c. Referenced by main(). |
|
Definition at line 156 of file gifsicle.c. Referenced by main(). |
|
Definition at line 139 of file gifsicle.c. Referenced by main(). |
|
Definition at line 147 of file gifsicle.c. Referenced by main(). |
|
Definition at line 175 of file gifsicle.c. Referenced by main(). |
Function Documentation
|
|
Definition at line 661 of file gifsicle.c. References Gt_OutputData::colormap_algorithm, COLORMAP_BLEND_DIVERSITY, COLORMAP_DIVERSITY, Gt_OutputData::colormap_fixed, COLORMAP_MEDIAN_CUT, Gt_OutputData::colormap_size, do_set_colormap(), fatal_error(), Gif_DeleteArray, Gif_DeleteColormap(), histogram(), i, Gif_Stream::images, Gif_Stream::nimages, and warncontext(). Referenced by merge_and_write_frames().
00662 { 00663 if (active_output_data.colormap_fixed) 00664 do_set_colormap(gfs, active_output_data.colormap_fixed); 00665 00666 if (active_output_data.colormap_size > 0) { 00667 int nhist; 00668 Gif_Color *hist; 00669 Gif_Colormap *(*adapt_func)(Gif_Color *, int, int); 00670 Gif_Colormap *new_cm; 00671 00672 /* set up the histogram */ 00673 { 00674 int i, any_locals = 0; 00675 for (i = 0; i < gfs->nimages; i++) 00676 if (gfs->images[i]->local) 00677 any_locals = 1; 00678 hist = histogram(gfs, &nhist); 00679 if (nhist <= active_output_data.colormap_size && !any_locals) { 00680 warncontext("trivial adaptive palette (only %d colors in source)", nhist); 00681 return; 00682 } 00683 } 00684 00685 switch (active_output_data.colormap_algorithm) { 00686 00687 case COLORMAP_DIVERSITY: 00688 adapt_func = &colormap_flat_diversity; 00689 break; 00690 00691 case COLORMAP_BLEND_DIVERSITY: 00692 adapt_func = &colormap_blend_diversity; 00693 break; 00694 00695 case COLORMAP_MEDIAN_CUT: 00696 adapt_func = &colormap_median_cut; 00697 break; 00698 00699 default: 00700 fatal_error("can't happen"); 00701 00702 } 00703 00704 new_cm = (*adapt_func)(hist, nhist, active_output_data.colormap_size); 00705 do_set_colormap(gfs, new_cm); 00706 00707 Gif_DeleteArray(hist); 00708 Gif_DeleteColormap(new_cm); 00709 } 00710 } |
|
Definition at line 650 of file gifsicle.c. References Gt_OutputData::colormap_dither, colormap_image_func, and colormap_stream(). Referenced by do_colormap_change().
00651 { 00652 colormap_image_func image_func; 00653 if (active_output_data.colormap_dither) 00654 image_func = colormap_image_floyd_steinberg; 00655 else 00656 image_func = colormap_image_posterize; 00657 colormap_stream(gfs, gfcm, image_func); 00658 } |
|
Definition at line 903 of file gifsicle.c. References arg, combine_output_options(), i, parse_frame_spec(), and show_frame().
00904 { 00905 /* Returns 0 iff you should try a file named `arg'. */ 00906 int val = parse_frame_spec(clp, arg, -1, 0); 00907 if (val == -97) 00908 return 0; 00909 else if (val > 0) { 00910 int i; 00911 for (i = frame_spec_1; i <= frame_spec_2; i++) 00912 show_frame(i, frame_spec_name != 0); 00913 if (next_output) combine_output_options(); 00914 return 1; 00915 } else 00916 return 1; 00917 } |
|
Definition at line 360 of file gifsicle.c. References mode, and nested_mode. Referenced by input_done(), and main().
00361 { 00362 if (nested_mode) 00363 mode = nested_mode; 00364 if (nested_frames) 00365 frames = nested_frames; 00366 nested_mode = 0; 00367 nested_frames = 0; 00368 } |
|
Definition at line 414 of file gifsicle.c. References error(), and gifread_error_count. Referenced by input_stream(), and main().
00415 { 00416 static int last_which_image = 0; 00417 static char last_message[256]; 00418 static int different_error_count = 0; 00419 static int same_error_count = 0; 00420 const char *filename = (const char *)thunk; 00421 00422 if (gifread_error_count == 0) { 00423 last_which_image = -1; 00424 last_message[0] = 0; 00425 different_error_count = 0; 00426 } 00427 00428 gifread_error_count++; 00429 if (last_message[0] && different_error_count <= 10 00430 && (last_which_image != which_image || message == 0 00431 || strcmp(message, last_message) != 0)) { 00432 if (same_error_count == 1) 00433 error(" %s", last_message); 00434 else if (same_error_count > 0) 00435 error(" %s (%d times)", last_message, same_error_count); 00436 same_error_count = 0; 00437 last_message[0] = 0; 00438 } 00439 00440 if (last_message[0] == 0) 00441 different_error_count++; 00442 00443 same_error_count++; 00444 if (message) 00445 strcpy(last_message, message); 00446 else 00447 last_message[0] = 0; 00448 if (last_which_image != which_image && different_error_count <= 10 00449 && message) { 00450 error("Error while reading `%s' frame #%d:", filename, which_image); 00451 last_which_image = which_image; 00452 } 00453 00454 if (different_error_count == 11 && message) { 00455 error("(more errors while reading `%s')", filename); 00456 different_error_count++; 00457 } 00458 } |
|
Definition at line 920 of file gifsicle.c. References Clp_Parser::arg, CH_EXTENSION, Clp_OptionError(), Clp_Shift(), Gif_Extension::data, Gt_Frame::extensions, fatal_error(), Gif_NewExtension(), l, Gif_Extension::length, Gif_Extension::next, and UNCHECKED_MARK_CH. Referenced by main().
00921 { 00922 Gif_Extension *gfex; 00923 char *extension_type = clp->arg; 00924 char *extension_body = Clp_Shift(clp, 1); 00925 if (!extension_body) { 00926 Clp_OptionError(clp, "%O requires two arguments"); 00927 return 0; 00928 } 00929 00930 UNCHECKED_MARK_CH(frame, CH_EXTENSION); 00931 if (is_app) 00932 gfex = Gif_NewExtension(255, extension_type); 00933 else if (!isdigit(extension_type[0]) && extension_type[1] == 0) 00934 gfex = Gif_NewExtension(extension_type[0], 0); 00935 else { 00936 long l = strtol(extension_type, &extension_type, 0); 00937 if (*extension_type != 0 || l < 0 || l >= 256) 00938 fatal_error("bad extension type: must be a number between 0 and 255"); 00939 gfex = Gif_NewExtension(l, 0); 00940 } 00941 00942 gfex->data = (byte *)extension_body; 00943 gfex->length = strlen(extension_body); 00944 gfex->next = def_frame.extensions; 00945 def_frame.extensions = gfex; 00946 00947 return 1; 00948 } |
|
|
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, name, Gt_Frame::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 1090 of file gifsicle.c. References active_next_output, ALTER_DONE_OPT, APP_EXTENSION_OPT, APPEND_OPT, Clp_Parser::arg, argc, Gt_OutputData::background, BACKGROUND_OPT, BATCHING, blank_frameset(), CAREFUL_OPT, CH_BACKGROUND, CH_CHANGE_COLOR, CH_COLOR_TRANSFORM, CH_COLORMAP, CH_COLORMAP_METHOD, CH_COMMENT, CH_CROP, CH_DELAY, CH_DISPOSAL, CH_DITHER, CH_FLIP, CH_INTERLACE, CH_LOGICAL_SCREEN, CH_LOOPCOUNT, CH_NAME, CH_OPTIMIZE, CH_OUTPUT, CH_POSITION, CH_RESIZE, CH_ROTATE, CH_TRANSPARENT, CH_UNOPTIMIZE, CH_USE_COLORMAP, CHANGE_COLOR_OPT, Clp_AddType(), Clp_AllowNumbers, Clp_BadOption, Clp_DisallowOptions, Clp_Done, Clp_NewParser(), Clp_Next(), Clp_NotOption, Clp_OptionError(), Clp_ProgramName(), Clp_SetErrorHandler(), Clp_SetOptionChar(), Clp_ShortNegated, COLOR_INFO_OPT, COLOR_TRANSFORM_OPT, COLOR_TYPE, COLORMAP_ALG_TYPE, Gt_OutputData::colormap_algorithm, COLORMAP_ALGORITHM_OPT, COLORMAP_BLEND_DIVERSITY, Gt_OutputData::colormap_dither, COLORMAP_DIVERSITY, Gt_OutputData::colormap_fixed, Gt_Frame::colormap_info, COLORMAP_MEDIAN_CUT, COLORMAP_OPT, Gt_OutputData::colormap_size, combine_output_options(), Gt_Frame::comment, COMMENT_OPT, Gt_Frame::crop, CROP_OPT, Gt_Frame::delay, DELETE_OPT, DIMENSIONS_TYPE, Gt_Frame::disposal, DISPOSAL_OPT, DISPOSAL_TYPE, DITHER_OPT, dmalloc_report(), dmalloc_verbose(), error(), EXIT_ERR, EXIT_OK, EXIT_USER_ERR, Gt_Frame::explode_by_name, EXPLODING, EXTENSION_INFO_OPT, EXTENSION_OPT, Gt_Frame::extensions_info, files_given, FLIP_HORIZ_OPT, Gt_Frame::flip_horizontal, FLIP_VERT_OPT, Gt_Frame::flip_vertical, frame_argument(), frame_change_done(), frame_option_types, FRAME_SPEC_TYPE, Gif_AddComment(), Gif_DeleteColormap(), Gif_DeleteComment(), GIF_DISPOSAL_ASIS, GIF_DISPOSAL_BACKGROUND, GIF_DISPOSAL_NONE, Gif_New, Gif_NewComment(), gif_read_flags, GIF_WRITE_CAREFUL_MIN_CODE_SIZE, gif_write_flags, handle_extension(), Gif_Color::haspixel, Clp_Parser::have_arg, HELP_OPT, i, INFO_OPT, infoing, initialize_def_frame(), input_done(), input_option_types, input_stream(), INSERT_OPT, Gt_Frame::interlacing, Gt_Frame::left, LOGICAL_SCREEN_OPT, LOOP_TYPE, Gt_OutputData::loopcount, MARK_CH, MERGING, mode, Gt_Frame::name, NAME_OPT, Clp_Parser::negated, new_frameset(), next_frame, next_input, next_output, Gt_Frame::no_comments, NO_COMMENTS_OPT, Gt_Frame::no_extensions, NO_EXTENSIONS_OPT, NO_FLIP_OPT, Gt_Frame::no_name, NO_NAME_OPT, NO_ROTATE_OPT, NO_WARNINGS_OPT, OPTIMIZE_OPT, Gt_OutputData::optimizing, output_frames(), Gt_OutputData::output_name, OUTPUT_OPT, output_option_types, Gif_Color::pixel, POSITION_OPT, POSITION_TYPE, print_useless_options(), Gt_Crop::ready, RECTANGLE_TYPE, REPLACE_OPT, Gt_OutputData::resize_height, RESIZE_HEIGHT_OPT, RESIZE_OPT, Gt_OutputData::resize_width, RESIZE_WIDTH_OPT, ROTATE_180_OPT, ROTATE_270_OPT, ROTATE_90_OPT, Gt_Frame::rotation, SAME_BACKGROUND_OPT, SAME_COMMENTS_OPT, SAME_CROP_OPT, SAME_DELAY_OPT, SAME_DISPOSAL_OPT, SAME_EXTENSIONS_OPT, SAME_INTERLACE_OPT, SAME_LOGICAL_SCREEN_OPT, SAME_LOOPCOUNT_OPT, SAME_NAME_OPT, SAME_POSITION_OPT, SAME_TRANSPARENT_OPT, SCALE_FACTOR_TYPE, SCALE_OPT, Gt_OutputData::scale_x, Gt_OutputData::scale_y, Gt_OutputData::scaling, Gt_OutputData::screen_height, Gt_OutputData::screen_width, set_frame_change(), set_mode(), set_new_fixed_colormap(), short_usage(), Gt_Crop::spec_h, Gt_Crop::spec_w, Gt_Crop::spec_x, Gt_Crop::spec_y, Gt_Frame::top, Gt_Frame::transparent, TWO_COLORS_TYPE, u_int16_t, UNCHECKED_MARK_CH, UNOPTIMIZE_OPT, unoptimizing, usage(), USE_COLORMAP_OPT, Clp_Parser::val, verbose_endline(), VERBOSE_OPT, verbosing, VERSION_OPT, WARNINGS_OPT, and Gt_Crop::whole_stream.
01091 { 01092 Clp_Parser *clp = 01093 Clp_NewParser(argc, argv, sizeof(options) / sizeof(options[0]), options); 01094 01095 Clp_AddStringListType 01096 (clp, LOOP_TYPE, Clp_AllowNumbers, 01097 "infinite", 0, "forever", 0, 01098 0); 01099 Clp_AddStringListType 01100 (clp, DISPOSAL_TYPE, Clp_AllowNumbers, 01101 "none", GIF_DISPOSAL_NONE, 01102 "asis", GIF_DISPOSAL_ASIS, 01103 "background", GIF_DISPOSAL_BACKGROUND, 01104 "bg", GIF_DISPOSAL_BACKGROUND, 01105 "previous", GIF_DISPOSAL_ASIS, 01106 0); 01107 Clp_AddStringListType 01108 (clp, COLORMAP_ALG_TYPE, 0, 01109 "diversity", COLORMAP_DIVERSITY, 01110 "blend-diversity", COLORMAP_BLEND_DIVERSITY, 01111 "median-cut", COLORMAP_MEDIAN_CUT, 01112 0); 01113 Clp_AddType(clp, DIMENSIONS_TYPE, 0, parse_dimensions, 0); 01114 Clp_AddType(clp, POSITION_TYPE, 0, parse_position, 0); 01115 Clp_AddType(clp, SCALE_FACTOR_TYPE, 0, parse_scale_factor, 0); 01116 Clp_AddType(clp, FRAME_SPEC_TYPE, 0, parse_frame_spec, 0); 01117 Clp_AddType(clp, COLOR_TYPE, Clp_DisallowOptions, parse_color, 0); 01118 Clp_AddType(clp, RECTANGLE_TYPE, 0, parse_rectangle, 0); 01119 Clp_AddType(clp, TWO_COLORS_TYPE, Clp_DisallowOptions, parse_two_colors, 0); 01120 Clp_SetOptionChar(clp, '+', Clp_ShortNegated); 01121 Clp_SetErrorHandler(clp, clp_error_handler); 01122 01123 program_name = Clp_ProgramName(clp); 01124 01125 frames = new_frameset(16); 01126 initialize_def_frame(); 01127 01128 #ifdef DMALLOC 01129 dmalloc_verbose("fudge"); 01130 #endif 01131 01132 /* Yep, I'm an idiot. 01133 GIF dimensions are unsigned 16-bit integers. I assume that these 01134 numbers will fit in an `int'. This assertion tests that assumption. 01135 Really I should go through & change everything over, but it doesn't 01136 seem worth my time. */ 01137 { 01138 u_int16_t m = 0xFFFFU; 01139 int i = m; 01140 assert(i > 0 && "configuration/lameness failure! bug the author!"); 01141 } 01142 01143 while (1) { 01144 int opt = Clp_Next(clp); 01145 switch (opt) { 01146 01147 /* MODE OPTIONS */ 01148 01149 case 'b': 01150 set_mode(BATCHING); 01151 break; 01152 01153 case 'm': 01154 set_mode(MERGING); 01155 break; 01156 01157 case 'e': 01158 set_mode(EXPLODING); 01159 def_frame.explode_by_name = 0; 01160 break; 01161 01162 case 'E': 01163 set_mode(EXPLODING); 01164 def_frame.explode_by_name = 1; 01165 break; 01166 01167 /* INFORMATION OPTIONS */ 01168 01169 case INFO_OPT: 01170 if (clp->negated) 01171 infoing = 0; 01172 else 01173 /* switch between infoing == 1 (suppress regular output) and 2 (don't 01174 suppress) */ 01175 infoing = (infoing == 1 ? 2 : 1); 01176 break; 01177 01178 case COLOR_INFO_OPT: 01179 if (clp->negated) 01180 def_frame.colormap_info = 0; 01181 else { 01182 def_frame.colormap_info = 1; 01183 if (!infoing) infoing = 1; 01184 } 01185 break; 01186 01187 case EXTENSION_INFO_OPT: 01188 if (clp->negated) 01189 def_frame.extensions_info = 0; 01190 else { 01191 def_frame.extensions_info = 1; 01192 if (!infoing) infoing = 1; 01193 } 01194 break; 01195 01196 case VERBOSE_OPT: 01197 verbosing = clp->negated ? 0 : 1; 01198 break; 01199 01200 /* FRAME CHANGE OPTIONS */ 01201 01202 case DELETE_OPT: 01203 case REPLACE_OPT: 01204 case INSERT_OPT: 01205 case APPEND_OPT: 01206 frame_change_done(); 01207 set_frame_change(opt); 01208 break; 01209 01210 case ALTER_DONE_OPT: 01211 frame_change_done(); 01212 break; 01213 01214 /* IMAGE OPTIONS */ 01215 01216 case NAME_OPT: 01217 if (clp->negated) goto no_names; 01218 MARK_CH(frame, CH_NAME); 01219 def_frame.name = clp->arg; 01220 break; 01221 01222 no_names: 01223 case NO_NAME_OPT: 01224 MARK_CH(frame, CH_NAME); 01225 def_frame.no_name = 1; 01226 def_frame.name = 0; 01227 break; 01228 01229 case SAME_NAME_OPT: 01230 def_frame.no_name = 0; 01231 def_frame.name = 0; 01232 break; 01233 01234 case COMMENT_OPT: 01235 if (clp->negated) goto no_comments; 01236 MARK_CH(frame, CH_COMMENT); 01237 if (!def_frame.comment) def_frame.comment = Gif_NewComment(); 01238 Gif_AddComment(def_frame.comment, clp->arg, -1); 01239 break; 01240 01241 no_comments: 01242 case NO_COMMENTS_OPT: 01243 Gif_DeleteComment(def_frame.comment); 01244 def_frame.comment = 0; 01245 def_frame.no_comments = 1; 01246 break; 01247 01248 case SAME_COMMENTS_OPT: 01249 def_frame.no_comments = 0; 01250 break; 01251 01252 case 'i': 01253 MARK_CH(frame, CH_INTERLACE); 01254 def_frame.interlacing = clp->negated ? 0 : 1; 01255 break; 01256 01257 case SAME_INTERLACE_OPT: 01258 def_frame.interlacing = -1; 01259 break; 01260 01261 case POSITION_OPT: 01262 MARK_CH(frame, CH_POSITION); 01263 def_frame.left = clp->negated ? 0 : position_x; 01264 def_frame.top = clp->negated ? 0 : position_y; 01265 break; 01266 01267 case SAME_POSITION_OPT: 01268 def_frame.left = -1; 01269 def_frame.top = -1; 01270 break; 01271 01272 case 't': 01273 MARK_CH(frame, CH_TRANSPARENT); 01274 if (clp->negated) 01275 def_frame.transparent.haspixel = 255; 01276 else { 01277 def_frame.transparent = parsed_color; 01278 def_frame.transparent.haspixel = parsed_color.haspixel ? 2 : 1; 01279 } 01280 break; 01281 01282 case SAME_TRANSPARENT_OPT: 01283 def_frame.transparent.haspixel = 0; 01284 break; 01285 01286 case BACKGROUND_OPT: 01287 MARK_CH(output, CH_BACKGROUND); 01288 if (clp->negated) { 01289 def_output_data.background.haspixel = 2; 01290 def_output_data.background.pixel = 0; 01291 } else { 01292 def_output_data.background = parsed_color; 01293 def_output_data.background.haspixel = parsed_color.haspixel ? 2 : 1; 01294 } 01295 break; 01296 01297 case SAME_BACKGROUND_OPT: 01298 MARK_CH(output, CH_BACKGROUND); 01299 def_output_data.background.haspixel = 0; 01300 break; 01301 01302 case LOGICAL_SCREEN_OPT: 01303 MARK_CH(output, CH_LOGICAL_SCREEN); 01304 if (clp->negated) 01305 def_output_data.screen_width = def_output_data.screen_height = 0; 01306 else { 01307 def_output_data.screen_width = dimensions_x; 01308 def_output_data.screen_height = dimensions_y; 01309 } 01310 break; 01311 01312 case SAME_LOGICAL_SCREEN_OPT: 01313 MARK_CH(output, CH_LOGICAL_SCREEN); 01314 def_output_data.screen_width = def_output_data.screen_height = -1; 01315 break; 01316 01317 case CROP_OPT: 01318 if (clp->negated) goto no_crop; 01319 MARK_CH(frame, CH_CROP); 01320 { 01321 Gt_Crop *crop = Gif_New(Gt_Crop); 01322 /* Memory leak on crops, but this just is NOT a problem. */ 01323 crop->ready = 0; 01324 crop->whole_stream = 0; 01325 crop->spec_x = position_x; 01326 crop->spec_y = position_y; 01327 crop->spec_w = dimensions_x; 01328 crop->spec_h = dimensions_y; 01329 def_frame.crop = crop; 01330 } 01331 break; 01332 01333 no_crop: 01334 case SAME_CROP_OPT: 01335 def_frame.crop = 0; 01336 break; 01337 01338 /* extensions options */ 01339 01340 case NO_EXTENSIONS_OPT: 01341 def_frame.no_extensions = 1; 01342 break; 01343 01344 case SAME_EXTENSIONS_OPT: 01345 def_frame.no_extensions = 0; 01346 break; 01347 01348 case EXTENSION_OPT: 01349 if (!handle_extension(clp, 0)) 01350 goto bad_option; 01351 break; 01352 01353 case APP_EXTENSION_OPT: 01354 if (!handle_extension(clp, 1)) 01355 goto bad_option; 01356 break; 01357 01358 /* IMAGE DATA OPTIONS */ 01359 01360 case FLIP_HORIZ_OPT: 01361 MARK_CH(frame, CH_FLIP); 01362 def_frame.flip_horizontal = !clp->negated; 01363 break; 01364 01365 case FLIP_VERT_OPT: 01366 MARK_CH(frame, CH_FLIP); 01367 def_frame.flip_vertical = !clp->negated; 01368 break; 01369 01370 case NO_FLIP_OPT: 01371 def_frame.flip_horizontal = def_frame.flip_vertical = 0; 01372 break; 01373 01374 case NO_ROTATE_OPT: 01375 def_frame.rotation = 0; 01376 break; 01377 01378 case ROTATE_90_OPT: 01379 MARK_CH(frame, CH_ROTATE); 01380 def_frame.rotation = 1; 01381 break; 01382 01383 case ROTATE_180_OPT: 01384 MARK_CH(frame, CH_ROTATE); 01385 def_frame.rotation = 2; 01386 break; 01387 01388 case ROTATE_270_OPT: 01389 MARK_CH(frame, CH_ROTATE); 01390 def_frame.rotation = 3; 01391 break; 01392 01393 /* ANIMATION OPTIONS */ 01394 01395 case 'd': 01396 MARK_CH(frame, CH_DELAY); 01397 def_frame.delay = clp->negated ? 0 : clp->val.i; 01398 break; 01399 01400 case SAME_DELAY_OPT: 01401 def_frame.delay = -1; 01402 break; 01403 01404 case DISPOSAL_OPT: 01405 MARK_CH(frame, CH_DISPOSAL); 01406 if (clp->negated) 01407 def_frame.disposal = GIF_DISPOSAL_NONE; 01408 else if (clp->val.i < 0 || clp->val.i > 7) 01409 error("disposal must be between 0 and 7"); 01410 else 01411 def_frame.disposal = clp->val.i; 01412 break; 01413 01414 case SAME_DISPOSAL_OPT: 01415 def_frame.disposal = -1; 01416 break; 01417 01418 case 'l': 01419 MARK_CH(output, CH_LOOPCOUNT); 01420 if (clp->negated) 01421 def_output_data.loopcount = -1; 01422 else 01423 def_output_data.loopcount = (clp->have_arg ? clp->val.i : 0); 01424 break; 01425 01426 case SAME_LOOPCOUNT_OPT: 01427 MARK_CH(output, CH_LOOPCOUNT); 01428 def_output_data.loopcount = -2; 01429 break; 01430 01431 case OPTIMIZE_OPT: 01432 MARK_CH(output, CH_OPTIMIZE); 01433 if (clp->negated) 01434 def_output_data.optimizing = 0; 01435 else 01436 def_output_data.optimizing = (clp->have_arg ? clp->val.i : 1); 01437 break; 01438 01439 case UNOPTIMIZE_OPT: 01440 UNCHECKED_MARK_CH(input, CH_UNOPTIMIZE); 01441 unoptimizing = clp->negated ? 0 : 1; 01442 break; 01443 01444 /* WHOLE-GIF OPTIONS */ 01445 01446 case CAREFUL_OPT: { 01447 if (clp->negated) 01448 gif_read_flags = gif_write_flags = 0; 01449 else { 01450 gif_read_flags = 0; 01451 gif_write_flags = GIF_WRITE_CAREFUL_MIN_CODE_SIZE; 01452 } 01453 break; 01454 } 01455 01456 case CHANGE_COLOR_OPT: { 01457 next_input |= CH_CHANGE_COLOR; 01458 if (clp->negated) 01459 input_transforms = delete_color_transforms 01460 (input_transforms, &color_change_transformer); 01461 else if (parsed_color2.haspixel) 01462 error("COLOR2 must be in RGB format in `--change-color COLOR1 COLOR2'"); 01463 else 01464 input_transforms = append_color_change 01465 (input_transforms, parsed_color, parsed_color2); 01466 break; 01467 } 01468 01469 case COLOR_TRANSFORM_OPT: 01470 next_output |= CH_COLOR_TRANSFORM; 01471 if (clp->negated) 01472 output_transforms = delete_color_transforms 01473 (output_transforms, &pipe_color_transformer); 01474 else 01475 output_transforms = append_color_transform 01476 (output_transforms, &pipe_color_transformer, clp->arg); 01477 break; 01478 01479 case COLORMAP_OPT: 01480 MARK_CH(output, CH_COLORMAP); 01481 if (clp->negated) 01482 def_output_data.colormap_size = 0; 01483 else { 01484 def_output_data.colormap_size = clp->val.i; 01485 if (def_output_data.colormap_size < 2 01486 || def_output_data.colormap_size > 256) { 01487 Clp_OptionError(clp, "argument to `%O' must be between 2 and 256"); 01488 def_output_data.colormap_size = 0; 01489 } 01490 } 01491 break; 01492 01493 case USE_COLORMAP_OPT: 01494 MARK_CH(output, CH_USE_COLORMAP); 01495 Gif_DeleteColormap(def_output_data.colormap_fixed); 01496 if (clp->negated) 01497 def_output_data.colormap_fixed = 0; 01498 else 01499 set_new_fixed_colormap(clp->arg); 01500 break; 01501 01502 case COLORMAP_ALGORITHM_OPT: 01503 MARK_CH(output, CH_COLORMAP_METHOD); 01504 def_output_data.colormap_algorithm = clp->val.i; 01505 break; 01506 01507 case DITHER_OPT: 01508 MARK_CH(output, CH_DITHER); 01509 def_output_data.colormap_dither = !clp->negated; 01510 break; 01511 01512 case RESIZE_OPT: 01513 MARK_CH(output, CH_RESIZE); 01514 if (clp->negated) 01515 def_output_data.scaling = 0; 01516 else if (dimensions_x <= 0 && dimensions_y <= 0) { 01517 error("one of W and H must be positive in `--resize WxH'"); 01518 def_output_data.scaling = 0; 01519 } else { 01520 def_output_data.scaling = 1; /* use resize dimensions */ 01521 def_output_data.resize_width = dimensions_x; 01522 def_output_data.resize_height = dimensions_y; 01523 } 01524 break; 01525 01526 case RESIZE_WIDTH_OPT: 01527 MARK_CH(output, CH_RESIZE); 01528 if (clp->negated) 01529 def_output_data.scaling = 0; 01530 else if (clp->val.u == 0) { 01531 error("`--resize-width' argument must be positive"); 01532 def_output_data.scaling = 0; 01533 } else { 01534 def_output_data.scaling = 1; /* use resize dimensions */ 01535 def_output_data.resize_width = clp->val.u; 01536 def_output_data.resize_height = 0; 01537 } 01538 break; 01539 01540 case RESIZE_HEIGHT_OPT: 01541 MARK_CH(output, CH_RESIZE); 01542 if (clp->negated) 01543 def_output_data.scaling = 0; 01544 else if (clp->val.u == 0) { 01545 error("`--resize-height' argument must be positive"); 01546 def_output_data.scaling = 0; 01547 } else { 01548 def_output_data.scaling = 1; /* use resize dimensions */ 01549 def_output_data.resize_width = 0; 01550 def_output_data.resize_height = clp->val.u; 01551 } 01552 break; 01553 01554 case SCALE_OPT: 01555 MARK_CH(output, CH_RESIZE); 01556 if (clp->negated) 01557 def_output_data.scaling = 0; 01558 else if (parsed_scale_factor_x <= 0 || parsed_scale_factor_y <= 0) { 01559 error("`--scale' X and Y factors must be positive"); 01560 def_output_data.scaling = 0; 01561 } else { 01562 def_output_data.scaling = 2; /* use scale factor */ 01563 def_output_data.scale_x = parsed_scale_factor_x; 01564 def_output_data.scale_y = parsed_scale_factor_y; 01565 } 01566 break; 01567 01568 /* RANDOM OPTIONS */ 01569 01570 case NO_WARNINGS_OPT: 01571 no_warnings = !clp->negated; 01572 break; 01573 01574 case WARNINGS_OPT: 01575 no_warnings = clp->negated; 01576 break; 01577 01578 case VERSION_OPT: 01579 #ifdef GIF_UNGIF 01580 printf("LCDF Gifsicle %s (ungif)\n", VERSION); 01581 #else 01582 printf("LCDF Gifsicle %s\n", VERSION); 01583 #endif 01584 printf("Copyright (C) 1997-2001 Eddie Kohler\n\ 01585 This is free software; see the source for copying conditions.\n\ 01586 There is NO warranty, not even for merchantability or fitness for a\n\ 01587 particular purpose.\n"); 01588 exit(EXIT_OK); 01589 break; 01590 01591 case HELP_OPT: 01592 usage(); 01593 exit(EXIT_OK); 01594 break; 01595 01596 case OUTPUT_OPT: 01597 MARK_CH(output, CH_OUTPUT); 01598 if (strcmp(clp->arg, "-") == 0) 01599 def_output_data.output_name = 0; 01600 else 01601 def_output_data.output_name = clp->arg; 01602 break; 01603 01604 /* NONOPTIONS */ 01605 01606 case Clp_NotOption: 01607 if (clp->arg[0] != '#' || !frame_argument(clp, clp->arg)) { 01608 input_done(); 01609 input_stream(clp->arg); 01610 } 01611 break; 01612 01613 case Clp_Done: 01614 goto done; 01615 01616 bad_option: 01617 case Clp_BadOption: 01618 short_usage(); 01619 exit(EXIT_USER_ERR); 01620 break; 01621 01622 default: 01623 break; 01624 01625 } 01626 } 01627 01628 done: 01629 01630 if (next_output) 01631 combine_output_options(); 01632 if (!files_given) 01633 input_stream(0); 01634 01635 frame_change_done(); 01636 input_done(); 01637 if (mode == MERGING) 01638 output_frames(); 01639 01640 verbose_endline(); 01641 print_useless_options("frame", next_frame, frame_option_types); 01642 print_useless_options("input", next_input, input_option_types); 01643 if (any_output_successful) 01644 print_useless_options("output", active_next_output, output_option_types); 01645 blank_frameset(frames, 0, 0, 1); 01646 #ifdef DMALLOC 01647 dmalloc_report(); 01648 #endif 01649 return (error_count ? EXIT_ERR : EXIT_OK); 01650 } |
|
|
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 789 of file gifsicle.c. References Gt_Frame::colormap_info, Gt_Frameset::count, error(), Gt_Frame::extensions_info, FRAME, i, Gt_Frame::image, image_info(), infoing, Gt_Frame::input_filename, Gt_Frame::stream, stream_info(), strerror(), and Gif_Stream::userflags. Referenced by output_frames().
00790 { 00791 FILE *f; 00792 int i, j; 00793 Gt_Frame *fr; 00794 Gif_Stream *gfs; 00795 00796 if (infoing == 2) 00797 f = stderr; 00798 else if (outfile == 0) 00799 f = stdout; 00800 else { 00801 f = fopen(outfile, "w"); 00802 if (!f) { 00803 error("%s: %s", outfile, strerror(errno)); 00804 return; 00805 } 00806 } 00807 00808 for (i = 0; i < frames->count; i++) 00809 FRAME(frames, i).stream->userflags = 97; 00810 00811 for (i = 0; i < frames->count; i++) 00812 if (FRAME(frames, i).stream->userflags == 97) { 00813 fr = &FRAME(frames, i); 00814 gfs = fr->stream; 00815 gfs->userflags = 0; 00816 stream_info(f, gfs, fr->input_filename, fr->colormap_info, 00817 fr->extensions_info); 00818 for (j = i; j < frames->count; j++) 00819 if (FRAME(frames, j).stream == gfs) { 00820 fr = &FRAME(frames, j); 00821 image_info(f, gfs, fr->image, fr->colormap_info); 00822 } 00823 } 00824 00825 if (f != stderr && f != stdout) 00826 fclose(f); 00827 } |
|
Definition at line 1070 of file gifsicle.c. References CHANGED, i, warncontext(), and warning(). Referenced by main().
01071 { 01072 int explanation_printed = 0; 01073 int i; 01074 if (!value) return; 01075 for (i = 0; i < 32; i++) 01076 if (CHANGED(value, i)) { 01077 warning("useless %s-related %s option", names[i], type_name); 01078 if (!explanation_printed) 01079 warncontext("(It didn't affect any %s.)", type_name); 01080 explanation_printed = 1; 01081 } 01082 } |
|
Definition at line 1057 of file gifsicle.c. References warncontext(), and warning().
01058 { 01059 static int context = 0; 01060 warning("redundant %s option", option_type); 01061 if (!context) { 01062 warncontext("(The %s option was overridden by another %s option", 01063 option_type, option_type); 01064 warncontext("before it had any effect.)"); 01065 } 01066 context = 1; 01067 } |
|
Definition at line 312 of file gifsicle.c. References APPEND_OPT, BLANK_MODE, DELETE_OPT, DELETING, fatal_error(), FRAME, frames_done, i, INSERT_OPT, INSERTING, MERGING, mode, nested_mode, new_frameset(), REPLACE_OPT, and set_mode(). Referenced by main().
00313 { 00314 int i; 00315 Gt_Frameset *fset; 00316 00317 if (mode == BLANK_MODE) 00318 set_mode(MERGING); 00319 if (mode < DELETING && frames_done) { 00320 fatal_error("frame selection and frame changes don't mix"); 00321 return; 00322 } 00323 assert(!nested_mode); 00324 nested_mode = mode; 00325 00326 switch (kind) { 00327 00328 case DELETE_OPT: 00329 mode = DELETING; 00330 break; 00331 00332 case REPLACE_OPT: 00333 for (i = frame_spec_1; i < frame_spec_2; i++) 00334 FRAME(frames, i).use = 0; 00335 /* We want to use the last frame's delay, but nothing else about it. */ 00336 FRAME(frames, i).use = -1; 00337 /* FALLTHRU */ 00338 00339 case INSERT_OPT: 00340 /* Define a nested frameset (or use an existing one). */ 00341 fset = FRAME(frames, frame_spec_2).nest; 00342 if (!fset) fset = new_frameset(8); 00343 FRAME(frames, frame_spec_2).nest = fset; 00344 00345 /* Later: Merge frames at the end of the nested frameset. */ 00346 mode = INSERTING; 00347 nested_frames = frames; 00348 frames = fset; 00349 break; 00350 00351 case APPEND_OPT: 00352 /* Just merge frames at the end of this frameset. */ 00353 mode = INSERTING; 00354 break; 00355 00356 } 00357 } |
|
Definition at line 300 of file gifsicle.c. References BLANK_MODE, fatal_error(), and mode. Referenced by input_stream(), main(), and set_frame_change().
00301 { 00302 if (mode == BLANK_MODE) 00303 mode = newmode; 00304 else if (mode == newmode) 00305 ; 00306 else 00307 fatal_error("too late to change modes"); 00308 } |
|
Definition at line 618 of file gifsicle.c. References Gif_Color::blue, Gif_Colormap::col, Gt_OutputData::colormap_fixed, Gif_NewFullColormap(), Gif_Color::green, i, name, read_colormap_file(), and Gif_Color::red. Referenced by main().
00619 { 00620 int i; 00621 if (name && strcmp(name, "web") == 0) { 00622 Gif_Colormap *cm = Gif_NewFullColormap(216, 256); 00623 Gif_Color *col = cm->col; 00624 for (i = 0; i < 216; i++) { 00625 col[i].red = (i / 36) * 0x33; 00626 col[i].green = ((i / 6) % 6) * 0x33; 00627 col[i].blue = (i % 6) * 0x33; 00628 } 00629 def_output_data.colormap_fixed = cm; 00630 00631 } else if (name && (strcmp(name, "gray") == 0 00632 || strcmp(name, "grey") == 0)) { 00633 Gif_Colormap *cm = Gif_NewFullColormap(256, 256); 00634 Gif_Color *col = cm->col; 00635 for (i = 0; i < 256; i++) 00636 col[i].red = col[i].green = col[i].blue = i; 00637 def_output_data.colormap_fixed = cm; 00638 00639 } else if (name && strcmp(name, "bw") == 0) { 00640 Gif_Colormap *cm = Gif_NewFullColormap(2, 256); 00641 cm->col[0].red = cm->col[0].green = cm->col[0].blue = 0; 00642 cm->col[1].red = cm->col[1].green = cm->col[1].blue = 255; 00643 def_output_data.colormap_fixed = cm; 00644 00645 } else 00646 def_output_data.colormap_fixed = read_colormap_file(name, 0); 00647 } |
|
Definition at line 372 of file gifsicle.c. References add_frame(), BATCHING, clear_frameset(), DELETING, Gt_Frame::explode_by_name, EXPLODING, first_input_frame, FRAME, frames_done, Gif_GetImage(), INSERTING, MERGING, next_frame, and Gt_Frame::use. Referenced by frame_argument().
00373 { 00374 Gif_Image *gfi; 00375 Gt_Frame *frame; 00376 00377 if (!input) return; 00378 gfi = Gif_GetImage(input, imagenumber); 00379 if (!gfi) return; 00380 00381 switch (mode) { 00382 00383 case MERGING: 00384 case INSERTING: 00385 case EXPLODING: 00386 if (!frames_done) clear_frameset(frames, first_input_frame); 00387 frame = add_frame(frames, -1, input, gfi); 00388 if (usename) frame->explode_by_name = 1; 00389 break; 00390 00391 case BATCHING: 00392 add_frame(frames, first_input_frame + imagenumber, input, gfi); 00393 break; 00394 00395 case DELETING: 00396 frame = &FRAME(frames, first_input_frame + imagenumber); 00397 frame->use = 0; 00398 break; 00399 00400 } 00401 00402 next_frame = 0; 00403 frames_done = 1; 00404 } |
|
Definition at line 718 of file gifsicle.c. References any_output_successful, error(), Gif_FullWriteFile(), gif_write_flags, isatty(), and strerror(). Referenced by merge_and_write_frames().
00719 { 00720 FILE *f; 00721 00722 if (output_name) 00723 f = fopen(output_name, "wb"); 00724 else { 00725 #ifndef OUTPUT_GIF_TO_TERMINAL 00726 extern int isatty(int); 00727 if (isatty(fileno(stdout))) { 00728 error("not writing to <stdout>: it's a terminal"); 00729 return; 00730 } 00731 #endif 00732 #if defined(_MSDOS) || defined(_WIN32) 00733 _setmode(_fileno(stdout), _O_BINARY); 00734 #elif defined(__EMX__) 00735 _fsetmode(stdout, "b"); 00736 #endif 00737 f = stdout; 00738 output_name = "<stdout>"; 00739 } 00740 00741 if (f) { 00742 Gif_FullWriteFile(gfs, gif_write_flags, f); 00743 fclose(f); 00744 any_output_successful = 1; 00745 } else 00746 error("%s: %s", output_name, strerror(errno)); 00747 } |
Variable Documentation
|
Definition at line 100 of file gifsicle.c. Referenced by combine_output_options(), main(), and output_frames(). |
|
Definition at line 98 of file gifsicle.c. |
|
Definition at line 101 of file gifsicle.c. Referenced by write_stream(). |
|
Definition at line 27 of file gifsicle.c. |
|
Definition at line 97 of file gifsicle.c. |
|
Definition at line 41 of file gifsicle.c. Referenced by input_stream(), and main(). |
|
Definition at line 30 of file gifsicle.c. Referenced by input_stream(), and show_frame(). |
|
Initial value: { "interlace", "disposal", "delay", "transparency", "comment", "name", "position", "crop", "extension", "flip", "rotation" } Definition at line 82 of file gifsicle.c. Referenced by main(). |
|
Definition at line 29 of file gifsicle.c. |
|
Definition at line 40 of file gifsicle.c. Referenced by input_stream(), set_frame_change(), and show_frame(). |
|
Definition at line 37 of file gifsicle.c. Referenced by input_stream(), and main(). |
|
Definition at line 38 of file gifsicle.c. Referenced by main(), and write_stream(). |
|
Definition at line 411 of file gifsicle.c. Referenced by gifread_error(), and input_stream(). |
|
Definition at line 57 of file gifsicle.c. Referenced by main(), output_frames(), and output_information(). |
|
Definition at line 33 of file gifsicle.c. |
|
Definition at line 34 of file gifsicle.c. Referenced by input_stream(). |
|
Initial value: { "unoptimization", "color change" } Definition at line 92 of file gifsicle.c. Referenced by main(). |
|
Definition at line 45 of file gifsicle.c. |
|
Definition at line 54 of file gifsicle.c. Referenced by frame_change_done(), input_done(), input_stream(), main(), set_frame_change(), and set_mode(). |
|
Definition at line 31 of file gifsicle.c. |
|
Definition at line 55 of file gifsicle.c. Referenced by frame_change_done(), merge_and_write_frames(), and set_frame_change(). |
|
Definition at line 70 of file gifsicle.c. Referenced by input_stream(), main(), and show_frame(). |
|
Definition at line 89 of file gifsicle.c. Referenced by input_stream(), and main(). |
|
Definition at line 99 of file gifsicle.c. Referenced by combine_output_options(), and main(). |
|
Definition at line 190 of file gifsicle.c. |
|
Initial value: { "loopcount", "logical screen", "optimization", "output file", "colormap size", "dither", "colormap", "colormap method", "background", "color transformation", "resize" } Definition at line 113 of file gifsicle.c. Referenced by main(). |
|
Definition at line 46 of file gifsicle.c. |
|
Definition at line 35 of file gifsicle.c. Referenced by main(). |
|
Definition at line 58 of file gifsicle.c. Referenced by main(). |
|
Definition at line 43 of file gifsicle.c. Referenced by merge_and_write_frames(). |