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(). |