Doxygen Source Code Documentation
support.c File Reference
#include "config.h"#include "gifsicle.h"#include <stdio.h>#include <stdarg.h>#include <string.h>#include <ctype.h>#include <assert.h>#include <errno.h>Go to the source code of this file.
Defines | |
| #define | COLORMAP_COLS 4 |
Functions | |
| void | verror (int seriousness, char *message, va_list val) |
| void | fatal_error (char *message,...) |
| void | error (char *message,...) |
| void | warning (char *message,...) |
| void | warncontext (char *message,...) |
| void | clp_error_handler (char *message) |
| void | short_usage (void) |
| void | usage (void) |
| void | verbose_open (char open, const char *name) |
| void | verbose_close (char close) |
| void | verbose_endline (void) |
| void | safe_puts (const char *s, u_int32_t len, FILE *f) |
| void | comment_info (FILE *where, Gif_Comment *gfcom, char *prefix) |
| void | colormap_info (FILE *where, Gif_Colormap *gfcm, char *prefix) |
| void | extension_info (FILE *where, Gif_Stream *gfs, Gif_Extension *gfex, int count) |
| void | stream_info (FILE *where, Gif_Stream *gfs, const char *filename, int colormaps, int extensions) |
| void | image_info (FILE *where, Gif_Stream *gfs, Gif_Image *gfi, int colormaps) |
| char * | explode_filename (char *filename, int number, char *name, int max_nimages) |
| int | parse_frame_spec (Clp_Parser *clp, const char *arg, int complain, void *thunk) |
| int | parse_dimensions (Clp_Parser *clp, const char *arg, int complain, void *thunk) |
| int | parse_position (Clp_Parser *clp, const char *arg, int complain, void *thunk) |
| int | parse_scale_factor (Clp_Parser *clp, const char *arg, int complain, void *thunk) |
| int | parse_rectangle (Clp_Parser *clp, const char *arg, int complain, void *thunk) |
| int | xvalue (char c) |
| int | parse_hex_color_channel (const char *s, int ndigits) |
| int | parse_color (Clp_Parser *clp, const char *arg, int complain, void *thunk) |
| int | parse_two_colors (Clp_Parser *clp, const char *arg, int complain, void *thunk) |
| Gif_Colormap * | read_text_colormap (FILE *f, char *name) |
| Gif_Colormap * | read_colormap_file (char *name, FILE *f) |
| Gt_Frameset * | new_frameset (int initial_cap) |
| void | clear_def_frame_once_options (void) |
| Gt_Frame * | add_frame (Gt_Frameset *fset, int number, Gif_Stream *gfs, Gif_Image *gfi) |
| Gif_Extension * | copy_extension (Gif_Extension *src) |
| void | merger_add (Gt_Frame *fp) |
| void | merger_flatten (Gt_Frameset *fset, int f1, int f2) |
| void | find_background (Gif_Colormap *dest_global, Gif_Color *background) |
| int | find_color_or_error (Gif_Color *color, Gif_Stream *gfs, Gif_Image *gfi, char *color_context) |
| void | fix_total_crop (Gif_Stream *dest, Gif_Image *srci, int merger_index) |
| void | handle_screen (Gif_Stream *dest, u_int16_t width, u_int16_t height) |
| void | handle_flip_and_screen (Gif_Stream *dest, Gif_Image *desti, Gt_Frame *fr, int first_image) |
| Gif_Stream * | merge_frame_interval (Gt_Frameset *fset, int f1, int f2, Gt_OutputData *output_data, int compress_immediately) |
| void | blank_frameset (Gt_Frameset *fset, int f1, int f2, int delete_object) |
| void | clear_frameset (Gt_Frameset *fset, int f1) |
Variables | |
| const char * | program_name = "gifsicle" |
| int | verbose_pos = 0 |
| int | error_count = 0 |
| int | no_warnings = 0 |
| char * | disposal_names [] |
| int | frame_spec_1 |
| int | frame_spec_2 |
| char * | frame_spec_name |
| int | dimensions_x |
| int | dimensions_y |
| int | position_x |
| int | position_y |
| Gif_Color | parsed_color |
| Gif_Color | parsed_color2 |
| double | parsed_scale_factor_x |
| double | parsed_scale_factor_y |
| Gt_Frame ** | merger = 0 |
| int | nmerger = 0 |
| int | mergercap = 0 |
Define Documentation
|
|
Definition at line 284 of file support.c. Referenced by colormap_info(). |
Function Documentation
|
||||||||||||||||||||
|
Definition at line 929 of file support.c. References blank_frameset(), Gt_Frameset::cap, clear_def_frame_once_options(), Gt_Frameset::count, Gt_Frameset::f, Gif_ReArray, Gt_Frame::image, Gif_Image::refcount, Gif_Stream::refcount, and Gt_Frame::stream. Referenced by input_stream(), and show_frame().
00930 {
00931 if (number < 0) {
00932 while (fset->count >= fset->cap) {
00933 fset->cap *= 2;
00934 Gif_ReArray(fset->f, Gt_Frame, fset->cap);
00935 }
00936 number = fset->count++;
00937 } else {
00938 assert(number < fset->count);
00939 blank_frameset(fset, number, number, 0);
00940 }
00941
00942 /* Mark the stream and the image both */
00943 gfs->refcount++;
00944 gfi->refcount++;
00945 fset->f[number] = def_frame;
00946 fset->f[number].stream = gfs;
00947 fset->f[number].image = gfi;
00948
00949 clear_def_frame_once_options();
00950
00951 return &fset->f[number];
00952 }
|
|
||||||||||||||||||||
|
END MERGE LOOP * Definition at line 1405 of file support.c. References Gt_Frameset::count, Gt_Frameset::f, FRAME, Gif_Delete, Gif_DeleteArray, Gif_DeleteComment(), Gif_DeleteStream(), and i. Referenced by add_frame(), clear_frameset(), and main().
01406 {
01407 int i;
01408 if (delete_object) f1 = 0, f2 = -1;
01409 if (f2 < 0) f2 = fset->count - 1;
01410 for (i = f1; i <= f2; i++) {
01411 /* We may have deleted stream and image earlier to save on memory; see
01412 above in merge_frame_interval(); but if we didn't, do it now. */
01413 if (FRAME(fset, i).image && FRAME(fset, i).image->refcount > 1)
01414 FRAME(fset, i).image->refcount--;
01415 Gif_DeleteStream(FRAME(fset, i).stream);
01416 Gif_DeleteComment(FRAME(fset, i).comment);
01417 if (FRAME(fset, i).nest)
01418 blank_frameset(FRAME(fset, i).nest, 0, 0, 1);
01419 }
01420 if (delete_object) {
01421 Gif_DeleteArray(fset->f);
01422 Gif_Delete(fset);
01423 }
01424 }
|
|
|
Definition at line 906 of file support.c. Referenced by add_frame().
00907 {
00908 /* Get rid of next-frame-only options.
00909
00910 This causes problems with frame selection. In the command `gifsicle
00911 -nblah f.gif', the name should be applied to frame 0 of f.gif. This will
00912 happen automatically when f.gif is read, since all of its frames will be
00913 added when it is input. After frame 0, the name in def_frame will be
00914 cleared.
00915
00916 Now, `gifsicle -nblah f.gif #1' should apply the name to frame 1 of
00917 f.gif. But once f.gif is input, its frames are added, and the name
00918 component of def_frame is cleared!! So when #1 comes around it's gone!
00919
00920 We handle this in gifsicle.c using the _change fields. */
00921
00922 def_frame.name = 0;
00923 def_frame.comment = 0;
00924 def_frame.extensions = 0;
00925 }
|
|
||||||||||||
|
Definition at line 1428 of file support.c. References blank_frameset(), and Gt_Frameset::count. Referenced by output_frames(), and show_frame().
01429 {
01430 blank_frameset(fset, f1, -1, 0);
01431 fset->count = f1;
01432 }
|
|
|
Definition at line 95 of file support.c. References verbose_endline().
00096 {
00097 verbose_endline();
00098 fputs(message, stderr);
00099 }
|
|
||||||||||||||||
|
Definition at line 287 of file support.c. References Gif_Color::blue, Gif_Colormap::col, COLORMAP_COLS, Gif_Color::green, i, Gif_Colormap::ncol, and Gif_Color::red. Referenced by image_info(), and stream_info().
00288 {
00289 int i, j;
00290 int nrows = ((gfcm->ncol - 1) / COLORMAP_COLS) + 1;
00291
00292 for (j = 0; j < nrows; j++) {
00293 int which = j;
00294 fputs(prefix, where);
00295 for (i = 0; i < COLORMAP_COLS && which < gfcm->ncol; i++, which += nrows) {
00296 if (i) fputs(" ", where);
00297 fprintf(where, " %3d: #%02X%02X%02X", which, gfcm->col[which].red,
00298 gfcm->col[which].green, gfcm->col[which].blue);
00299 }
00300 fputc('\n', where);
00301 }
00302 }
|
|
||||||||||||||||
|
Definition at line 273 of file support.c. References Gif_Comment::count, i, Gif_Comment::len, safe_puts(), and Gif_Comment::str. Referenced by image_info(), and stream_info().
|
|
|
Definition at line 956 of file support.c. References Gif_Extension::application, Gif_Extension::data, Gif_Extension::free_data, Gif_DeleteArrayFunc, Gif_DeleteExtension(), Gif_NewArray, Gif_NewExtension(), Gif_Extension::kind, and Gif_Extension::length. Referenced by merge_frame_interval().
00957 {
00958 Gif_Extension *dest = Gif_NewExtension(src->kind, src->application);
00959 if (!dest) return 0;
00960 dest->data = Gif_NewArray(byte, src->length);
00961 dest->length = src->length;
00962 dest->free_data = Gif_DeleteArrayFunc;
00963 if (!dest->data) {
00964 Gif_DeleteExtension(dest);
00965 return 0;
00966 }
00967 memcpy(dest->data, src->data, src->length);
00968 return dest;
00969 }
|
|
||||||||||||
|
Definition at line 68 of file support.c. References verror(). Referenced by parse_color().
00069 {
00070 va_list val;
00071 va_start(val, message);
00072 verror(2, message, val);
00073 va_end(val);
00074 }
|
|
||||||||||||||||||||
|
Definition at line 446 of file support.c. References Gif_Delete, Gif_NewArray, l, and name. Referenced by output_frames().
00447 {
00448 static char *s;
00449 int l = strlen(filename);
00450 l += name ? strlen(name) : 10;
00451
00452 Gif_Delete(s);
00453 s = Gif_NewArray(char, l + 3);
00454 if (name)
00455 sprintf(s, "%s.%s", filename, name);
00456 else if (max_nimages <= 1000)
00457 sprintf(s, "%s.%03d", filename, number);
00458 else {
00459 int digits;
00460 unsigned j;
00461 unsigned max = (max_nimages < 0 ? 0 : max_nimages);
00462 for (digits = 4, j = 10000; max > j; digits++)
00463 j *= 10;
00464 sprintf(s, "%s.%0*d", filename, digits, number);
00465 }
00466
00467 return s;
00468 }
|
|
||||||||||||||||||||
|
Definition at line 306 of file support.c. References Gif_Extension::application, Gif_Extension::data, i, Gif_Extension::kind, Gif_Extension::length, Gif_Stream::nimages, Gif_Extension::position, safe_puts(), and u_int32_t. Referenced by stream_info().
00307 {
00308 byte *data = gfex->data;
00309 u_int32_t pos = 0;
00310 u_int32_t len = gfex->length;
00311
00312 fprintf(where, " extension %d: ", count);
00313 if (gfex->kind == 255) {
00314 fprintf(where, "app `");
00315 safe_puts(gfex->application, strlen(gfex->application), where);
00316 fprintf(where, "'");
00317 } else {
00318 if (gfex->kind >= 32 && gfex->kind < 127)
00319 fprintf(where, "`%c' (0x%02X)", gfex->kind, gfex->kind);
00320 else
00321 fprintf(where, "0x%02X", gfex->kind);
00322 }
00323 if (gfex->position >= gfs->nimages)
00324 fprintf(where, " at end\n");
00325 else
00326 fprintf(where, " before #%d\n", gfex->position);
00327
00328 /* Now, hexl the data. */
00329 while (len > 0) {
00330 u_int32_t row = 16;
00331 u_int32_t i;
00332 if (row > len) row = len;
00333 fprintf(where, " %08x: ", pos);
00334
00335 for (i = 0; i < row; i += 2) {
00336 if (i + 1 >= row)
00337 fprintf(where, "%02x ", data[i]);
00338 else
00339 fprintf(where, "%02x%02x ", data[i], data[i+1]);
00340 }
00341 for (; i < 16; i += 2)
00342 fputs(" ", where);
00343
00344 putc(' ', where);
00345 for (i = 0; i < row; i++, data++)
00346 putc((*data >= ' ' && *data < 127 ? *data : '.'), where);
00347 putc('\n', where);
00348
00349 pos += row;
00350 len -= row;
00351 }
00352 }
|
|
||||||||||||
|
Definition at line 58 of file support.c. References EXIT_USER_ERR, and verror(). Referenced by colormap_diversity(), colormap_median_cut(), do_colormap_change(), get_used_colors(), handle_extension(), main(), merge_image(), pipe_color_transformer(), scale_image(), set_frame_change(), and set_mode().
00059 {
00060 va_list val;
00061 va_start(val, message);
00062 verror(3, message, val);
00063 va_end(val);
00064 exit(EXIT_USER_ERR);
00065 }
|
|
||||||||||||
|
Definition at line 1021 of file support.c. References Gif_Stream::background, Gif_Color::blue, Gif_Colormap::col, COLORMAP_ENSURE_SLOT_255, error(), GIF_COLOREQ, GIF_DISPOSAL_BACKGROUND, Gif_Stream::global, Gif_Color::green, Gif_Color::haspixel, i, Gt_Frame::image, Gif_Stream::images, Gif_Colormap::ncol, nmerger, Gif_Color::pixel, Gif_Color::red, Gt_Frame::stream, Gif_Image::transparent, Gt_Frame::transparent, Gif_Colormap::userflags, warncontext(), and warning(). Referenced by merge_frame_interval().
01022 {
01023 int i;
01024 /* This code is SUCH a PAIN in the PATOOTIE!! */
01025
01026 /* 0. report warnings if the user wants an impossible background setting */
01027 if (background->haspixel) {
01028 int first_img_transp = 0;
01029 if (merger[0]->transparent.haspixel < 255)
01030 first_img_transp = (merger[0]->image->transparent >= 0
01031 || merger[0]->transparent.haspixel);
01032 if (first_img_transp) {
01033 static int context = 0;
01034 warning("irrelevant background color");
01035 if (!context) {
01036 warncontext("(The background will appear transparent because");
01037 warncontext("the first image contains transparency.)");
01038 context = 1;
01039 }
01040 }
01041 }
01042
01043 /* 1. user set the background to a color index
01044 -> find the associated color */
01045 if (background->haspixel == 2) {
01046 Gif_Stream *gfs = merger[0]->stream;
01047 if (gfs->global && background->pixel < gfs->global->ncol) {
01048 *background = gfs->global->col[ background->pixel ];
01049 background->haspixel = 1;
01050 } else {
01051 error("background color index `%d' out of range", background->pixel);
01052 background->haspixel = 0;
01053 }
01054 }
01055
01056 /* 2. search the existing streams and images for background colors
01057 (prefer colors from images with disposal == BACKGROUND)
01058 -> choose the color. warn if two such images have conflicting colors */
01059 if (background->haspixel == 0) {
01060 int relevance = 0;
01061 int saved_bg_transparent = 0;
01062 for (i = 0; i < nmerger; i++) {
01063 Gif_Stream *gfs = merger[i]->stream;
01064 int bg_disposal = merger[i]->image->disposal == GIF_DISPOSAL_BACKGROUND;
01065 int bg_transparent = gfs->images[0]->transparent >= 0;
01066 int bg_exists = gfs->global && gfs->background < gfs->global->ncol;
01067
01068 if ((!bg_exists && !bg_transparent) || (bg_disposal + 1 < relevance))
01069 continue;
01070 else if (bg_disposal + 1 > relevance) {
01071 if (bg_exists)
01072 *background = gfs->global->col[gfs->background];
01073 else
01074 background->red = background->green = background->blue = 0;
01075 saved_bg_transparent = bg_transparent;
01076 relevance = bg_disposal + 1;
01077 continue;
01078 }
01079
01080 /* check for conflicting background requirements */
01081 if (bg_transparent != saved_bg_transparent
01082 || (!saved_bg_transparent &&
01083 !GIF_COLOREQ(background, &gfs->global->col[gfs->background]))) {
01084 static int context = 0;
01085 warning("input images have conflicting background colors");
01086 if (!context) {
01087 warncontext("(This means some animation frames may appear incorrect.)");
01088 context = 1;
01089 }
01090 break;
01091 }
01092 }
01093 background->haspixel = relevance != 0;
01094 }
01095
01096 /* 3. we found a background color
01097 -> force the merging process to keep it in the global colormap with
01098 COLORMAP_ENSURE_SLOT_255. See merge.c function ensure_slot_255 */
01099 if (background->haspixel) {
01100 dest_global->userflags |= COLORMAP_ENSURE_SLOT_255;
01101 dest_global->col[255] = *background;
01102 }
01103 }
|
|
||||||||||||||||||||
|
Definition at line 1107 of file support.c. References color, error(), Gif_FindColor(), Gif_Stream::global, Gif_Color::haspixel, Gif_Image::local, Gif_Colormap::ncol, and Gif_Color::pixel. Referenced by merge_frame_interval().
01109 {
01110 Gif_Colormap *gfcm = gfs->global;
01111 int index;
01112 if (gfi && gfi->local) gfcm = gfi->local;
01113
01114 if (color->haspixel == 2) { /* have pixel value, not color */
01115 if (color->pixel < gfcm->ncol)
01116 return color->pixel;
01117 else {
01118 if (color_context) error("%s color out of range", color_context);
01119 return -1;
01120 }
01121 }
01122
01123 index = Gif_FindColor(gfcm, color);
01124 if (index < 0 && color_context)
01125 error("%s color not in colormap", color_context);
01126 return index;
01127 }
|
|
||||||||||||||||
|
Definition at line 1131 of file support.c. References Gt_Frame::comment, Gif_Image::comment, Gif_Image::delay, Gt_Frame::delay, Gif_DeleteComment(), Gif_NewComment(), Gif_Stream::images, merge_comments(), Gif_Stream::nimages, nmerger, and Gt_Frame::no_comments. Referenced by merge_frame_interval().
01132 {
01133 /* Salvage any relevant information from a frame that's been completely
01134 cropped away. This ends up being comments and delay. */
01135 Gt_Frame *fr = merger[merger_index];
01136 Gt_Frame *next_fr = 0;
01137 Gif_Image *prev_image = 0;
01138 if (dest->nimages > 0) prev_image = dest->images[dest->nimages - 1];
01139 if (merger_index < nmerger - 1) next_fr = merger[merger_index + 1];
01140
01141 /* Don't save identifiers since the frame that was to be identified, is
01142 gone. Save comments though. */
01143 if (!fr->no_comments && srci->comment && next_fr) {
01144 if (!next_fr->comment) next_fr->comment = Gif_NewComment();
01145 merge_comments(next_fr->comment, srci->comment);
01146 }
01147 if (fr->comment && next_fr) {
01148 if (!next_fr->comment) next_fr->comment = Gif_NewComment();
01149 merge_comments(next_fr->comment, fr->comment);
01150 Gif_DeleteComment(fr->comment);
01151 fr->comment = 0;
01152 }
01153
01154 /* Save delay by adding it to the previous frame's delay. */
01155 if (fr->delay < 0)
01156 fr->delay = srci->delay;
01157 prev_image->delay += fr->delay;
01158 }
|
|
||||||||||||||||||||
|
Definition at line 1173 of file support.c. References first_image, Gt_Frame::flip_horizontal, flip_image(), Gt_Frame::flip_vertical, handle_screen(), rotate_image(), Gt_Frame::rotation, Gif_Stream::screen_height, Gif_Stream::screen_width, Gt_Frame::stream, and u_int16_t. Referenced by merge_frame_interval().
01175 {
01176 Gif_Stream *gfs = fr->stream;
01177
01178 u_int16_t screen_width = gfs->screen_width;
01179 u_int16_t screen_height = gfs->screen_height;
01180
01181 if (fr->flip_horizontal)
01182 flip_image(desti, screen_width, screen_height, 0);
01183 if (fr->flip_vertical)
01184 flip_image(desti, screen_width, screen_height, 1);
01185
01186 if (fr->rotation == 1)
01187 rotate_image(desti, screen_width, screen_height, 1);
01188 else if (fr->rotation == 2) {
01189 flip_image(desti, screen_width, screen_height, 0);
01190 flip_image(desti, screen_width, screen_height, 1);
01191 } else if (fr->rotation == 3)
01192 rotate_image(desti, screen_width, screen_height, 3);
01193
01194 /* handle screen size, which might have height & width exchanged */
01195 if (fr->rotation == 1 || fr->rotation == 3)
01196 handle_screen(dest, screen_height, screen_width);
01197 else
01198 handle_screen(dest, screen_width, screen_height);
01199 }
|
|
||||||||||||||||
|
Definition at line 1162 of file support.c. References Gif_Stream::screen_height, Gif_Stream::screen_width, and u_int16_t. Referenced by handle_flip_and_screen(), and merge_frame_interval().
01163 {
01164 /* Set the screen width & height, if the current input width and height are
01165 larger */
01166 if (dest->screen_width < width)
01167 dest->screen_width = width;
01168 if (dest->screen_height < height)
01169 dest->screen_height = height;
01170 }
|
|
||||||||||||||||||||
|
Definition at line 397 of file support.c. References colormap_info(), Gif_Image::comment, comment_info(), Gif_Image::compressed, Gif_Image::compressed_len, Gif_Image::delay, Gif_Image::disposal, disposal_names, Gif_ImageNumber(), Gif_Image::height, Gif_Image::identifier, Gif_Image::interlace, Gif_Image::left, Gif_Image::local, Gif_Colormap::ncol, Gif_Image::top, Gif_Image::transparent, verbose_endline(), and Gif_Image::width. Referenced by output_information().
00398 {
00399 int num;
00400 if (!gfs || !gfi) return;
00401 num = Gif_ImageNumber(gfs, gfi);
00402
00403 verbose_endline();
00404 fprintf(where, " + image #%d ", num);
00405 if (gfi->identifier)
00406 fprintf(where, "#%s ", gfi->identifier);
00407
00408 fprintf(where, "%dx%d", gfi->width, gfi->height);
00409 if (gfi->left || gfi->top)
00410 fprintf(where, " at %d,%d", gfi->left, gfi->top);
00411
00412 if (gfi->interlace)
00413 fprintf(where, " interlaced");
00414
00415 if (gfi->transparent >= 0)
00416 fprintf(where, " transparent %d", gfi->transparent);
00417
00418 #if defined(PRINT_SIZE)
00419 if (gfi->compressed)
00420 fprintf(where, " compressed size %u min_code_size %d", gfi->compressed_len, *gfi->compressed);
00421 #endif
00422
00423 fprintf(where, "\n");
00424
00425 if (gfi->comment)
00426 comment_info(where, gfi->comment, " comment ");
00427
00428 if (gfi->local) {
00429 fprintf(where, " local color table [%d]\n", gfi->local->ncol);
00430 if (colormaps) colormap_info(where, gfi->local, " |");
00431 }
00432
00433 if (gfi->disposal || gfi->delay) {
00434 fprintf(where, " ");
00435 if (gfi->disposal)
00436 fprintf(where, " disposal %s", disposal_names[gfi->disposal]);
00437 if (gfi->delay)
00438 fprintf(where, " delay %d.%02ds",
00439 gfi->delay / 100, gfi->delay % 100);
00440 fprintf(where, "\n");
00441 }
00442 }
|
|
||||||||||||||||||||||||
|
Definition at line 1203 of file support.c. References Gif_Stream::background, Gt_OutputData::background, Gif_Colormap::col, Gt_Frame::comment, Gif_Image::comment, copy_extension(), Gt_Frameset::count, Gt_Frame::crop, crop_image(), Gif_Image::delay, Gt_Frame::delay, Gif_Image::disposal, Gt_Frame::disposal, error(), Gt_Frame::extensions, Gif_Stream::extensions, find_background(), find_color_or_error(), fix_total_crop(), Gt_Frame::flip_horizontal, Gt_Frame::flip_vertical, Gif_AddExtension(), Gif_CalculateScreenSize(), Gif_CopyImage(), Gif_CopyString(), Gif_DeleteArray, Gif_DeleteComment(), Gif_DeleteImage(), Gif_DeleteStream(), Gif_FullCompressImage(), Gif_NewComment(), Gif_NewFullColormap(), Gif_NewStream(), Gif_ReleaseCompressedImage(), Gif_ReleaseUncompressedImage(), Gif_UncompressImage, Gif_Stream::global, global, handle_flip_and_screen(), handle_screen(), Gif_Color::haspixel, i, Gif_Image::identifier, Gt_Frame::image, Gif_Stream::images, Gif_Image::interlace, Gt_Frame::interlacing, Gif_Image::left, Gt_Frame::left, Gif_Stream::loopcount, Gt_OutputData::loopcount, merge_comments(), merge_image(), merge_stream(), merger_flatten(), Gt_Frame::name, Gif_Colormap::ncol, Gif_Extension::next, nmerger, Gt_Frame::no_comments, Gt_Frame::no_extensions, Gt_Frame::no_name, Gif_Extension::position, Gt_Frame::position_is_offset, Gif_Image::refcount, Gt_Frame::rotation, Gt_OutputData::screen_height, Gif_Stream::screen_height, Gt_OutputData::screen_width, Gif_Stream::screen_width, Gt_Frame::stream, Gif_Image::top, Gt_Frame::top, Gt_Frame::transparent, Gif_Image::transparent, unmark_colors_2(), Gif_Stream::userflags, and Gt_Crop::whole_stream. Referenced by merge_and_write_frames().
01205 {
01206 Gif_Stream *dest = Gif_NewStream();
01207 Gif_Colormap *global = Gif_NewFullColormap(256, 256);
01208 Gif_Color dest_background;
01209 int i;
01210
01211 global->ncol = 0;
01212 dest->global = global;
01213 /* 11/23/98 A new stream's screen size is 0x0; we'll use the max of the
01214 merged-together streams' screen sizes by default (in merge_stream()) */
01215
01216 if (f2 < 0) f2 = fset->count - 1;
01217 nmerger = 0;
01218 merger_flatten(fset, f1, f2);
01219 if (nmerger == 0) {
01220 error("empty output GIF not written");
01221 return 0;
01222 }
01223
01224 /* merge stream-specific info and clear colormaps */
01225 for (i = 0; i < nmerger; i++)
01226 merger[i]->stream->userflags = 1;
01227 for (i = 0; i < nmerger; i++) {
01228 if (merger[i]->stream->userflags) {
01229 Gif_Stream *src = merger[i]->stream;
01230 Gif_CalculateScreenSize(src, 0);
01231 /* merge_stream() unmarks the global colormap */
01232 merge_stream(dest, src, merger[i]->no_comments);
01233 src->userflags = 0;
01234 }
01235 if (merger[i]->image->local)
01236 unmark_colors_2(merger[i]->image->local);
01237 }
01238
01239 /* decide on the background. use the one from output_data */
01240 dest_background = output_data->background;
01241 find_background(global, &dest_background);
01242
01243 /* check for cropping the whole stream */
01244 for (i = 0; i < nmerger; i++)
01245 if (merger[i]->crop)
01246 merger[i]->crop->whole_stream = 0;
01247 if (merger[0]->crop) {
01248 merger[0]->crop->whole_stream = 1;
01249 for (i = 1; i < nmerger; i++)
01250 if (merger[i]->crop != merger[0]->crop)
01251 merger[0]->crop->whole_stream = 0;
01252 }
01253
01254 /* copy stream-wide information from output_data */
01255 if (output_data->loopcount > -2)
01256 dest->loopcount = output_data->loopcount;
01257 dest->screen_width = dest->screen_height = 0;
01258
01259 /** ACTUALLY MERGE FRAMES INTO THE NEW STREAM **/
01260 for (i = 0; i < nmerger; i++) {
01261 Gt_Frame *fr = merger[i];
01262 Gif_Image *srci;
01263 Gif_Image *desti;
01264 int old_transparent;
01265
01266 /* First, check for extensions */
01267 {
01268 int j;
01269 Gif_Extension *gfex = fr->stream->extensions;
01270 for (j = 0; fr->stream->images[j] != fr->image; j++) ;
01271 while (gfex && gfex->position < j)
01272 gfex = gfex->next;
01273 while (!fr->no_extensions && gfex && gfex->position == j) {
01274 Gif_AddExtension(dest, copy_extension(gfex), i);
01275 gfex = gfex->next;
01276 }
01277 gfex = fr->extensions;
01278 while (gfex) {
01279 Gif_Extension *next = gfex->next;
01280 Gif_AddExtension(dest, gfex, i);
01281 gfex = next;
01282 }
01283 }
01284
01285 /* Make a copy of the image and crop it if we're cropping */
01286 if (fr->crop) {
01287 srci = Gif_CopyImage(fr->image);
01288 Gif_UncompressImage(srci);
01289 if (!crop_image(srci, fr->crop)) {
01290 /* We cropped the image out of existence! Be careful not to make 0x0
01291 frames. */
01292 fix_total_crop(dest, srci, i);
01293 goto merge_frame_done;
01294 }
01295 } else {
01296 srci = fr->image;
01297 Gif_UncompressImage(srci);
01298 }
01299
01300 /* It was pretty stupid to remove this code, which I did between 1.2b6 and
01301 1.2 */
01302 old_transparent = srci->transparent;
01303 if (fr->transparent.haspixel == 255)
01304 srci->transparent = -1;
01305 else if (fr->transparent.haspixel)
01306 srci->transparent =
01307 find_color_or_error(&fr->transparent, fr->stream, srci, "transparent");
01308
01309 desti = merge_image(dest, fr->stream, srci);
01310
01311 srci->transparent = old_transparent; /* restore real transparent value */
01312
01313 /* Flipping and rotating, and also setting the screen size */
01314 if (fr->flip_horizontal || fr->flip_vertical || fr->rotation)
01315 handle_flip_and_screen(dest, desti, fr, i == 0);
01316 else
01317 handle_screen(dest, fr->stream->screen_width, fr->stream->screen_height);
01318
01319 /* Names and comments */
01320 if (fr->name || fr->no_name) {
01321 Gif_DeleteArray(desti->identifier);
01322 desti->identifier = Gif_CopyString(fr->name);
01323 }
01324 if (fr->no_comments && desti->comment) {
01325 Gif_DeleteComment(desti->comment);
01326 desti->comment = 0;
01327 }
01328 if (fr->comment) {
01329 if (!desti->comment) desti->comment = Gif_NewComment();
01330 merge_comments(desti->comment, fr->comment);
01331 /* delete the comment early to help with memory; set field to 0 so we
01332 don't re-free it later */
01333 Gif_DeleteComment(fr->comment);
01334 fr->comment = 0;
01335 }
01336
01337 if (fr->interlacing >= 0)
01338 desti->interlace = fr->interlacing;
01339 if (fr->left >= 0)
01340 desti->left = fr->left + (fr->position_is_offset ? desti->left : 0);
01341 if (fr->top >= 0)
01342 desti->top = fr->top + (fr->position_is_offset ? desti->top : 0);
01343
01344 if (fr->delay >= 0)
01345 desti->delay = fr->delay;
01346 if (fr->disposal >= 0)
01347 desti->disposal = fr->disposal;
01348
01349 /* compress immediately if possible to save on memory */
01350 if (compress_immediately) {
01351 Gif_FullCompressImage(dest, desti, gif_write_flags);
01352 Gif_ReleaseUncompressedImage(desti);
01353 }
01354
01355 merge_frame_done:
01356 /* Destroy the copied, cropped image if necessary */
01357 if (fr->crop)
01358 Gif_DeleteImage(srci);
01359
01360 /* if we can, delete the image's data right now to save memory */
01361 srci = fr->image;
01362 assert(srci->refcount > 1);
01363 if (--srci->refcount == 1) {
01364 /* only 1 reference ==> the reference is from the input stream itself */
01365 Gif_ReleaseUncompressedImage(srci);
01366 Gif_ReleaseCompressedImage(srci);
01367 fr->image = 0;
01368 }
01369
01370 /* 5/26/98 Destroy the stream now to help with memory. Assumes that
01371 all frames are added with add_frame() which properly increments the
01372 stream's refcount. Set field to 0 so we don't redelete */
01373 Gif_DeleteStream(fr->stream);
01374 fr->stream = 0;
01375 }
01376 /** END MERGE LOOP **/
01377
01378 /* Cropping the whole output? Clear the logical screen */
01379 if (merger[0]->crop && merger[0]->crop == merger[nmerger-1]->crop)
01380 dest->screen_width = dest->screen_height = 0;
01381 /* Set the logical screen from the user's preferences */
01382 if (output_data->screen_width >= 0)
01383 dest->screen_width = output_data->screen_width;
01384 if (output_data->screen_height >= 0)
01385 dest->screen_height = output_data->screen_height;
01386
01387 /* Find the background color in the colormap, or add it if we can */
01388 {
01389 int bg = find_color_or_error(&dest_background, dest, 0, 0);
01390 if (bg < 0 && dest->images[0]->transparent >= 0)
01391 dest->background = dest->images[0]->transparent;
01392 else if (bg < 0 && global->ncol < 256) {
01393 dest->background = global->ncol;
01394 global->col[ global->ncol ] = dest_background;
01395 global->ncol++;
01396 } else
01397 dest->background = bg;
01398 }
01399
01400 return dest;
01401 }
|
|
|
Definition at line 977 of file support.c. References Gif_NewArray, Gif_ReArray, mergercap, and nmerger. Referenced by merger_flatten().
|
|
||||||||||||||||
|
Definition at line 992 of file support.c. References Gt_Frameset::count, FRAME, Gif_CopyString(), i, and merger_add(). Referenced by merge_frame_interval().
00993 {
00994 int i;
00995 assert(f1 >= 0 && f2 < fset->count);
00996 for (i = f1; i <= f2; i++) {
00997 Gt_Frameset *nest = FRAME(fset, i).nest;
00998
00999 if (nest && nest->count > 0) {
01000 if (FRAME(fset, i).use < 0 && nest->count == 1) {
01001 /* use < 0 means use the frame's delay, disposal and name (if not
01002 explicitly overridden), but not the frame itself. */
01003 if (FRAME(nest, 0).delay < 0)
01004 FRAME(nest, 0).delay = FRAME(fset, i).image->delay;
01005 if (FRAME(nest, 0).disposal < 0)
01006 FRAME(nest, 0).disposal = FRAME(fset, i).image->disposal;
01007 if (FRAME(nest, 0).name == 0 && FRAME(nest, 0).no_name == 0)
01008 FRAME(nest, 0).name =
01009 Gif_CopyString(FRAME(fset, i).image->identifier);
01010 }
01011 merger_flatten(nest, 0, nest->count - 1);
01012 }
01013
01014 if (FRAME(fset, i).use > 0)
01015 merger_add(&FRAME(fset, i));
01016 }
01017 }
|
|
|
Definition at line 894 of file support.c. References Gt_Frameset::cap, Gt_Frameset::count, Gt_Frameset::f, Gif_New, and Gif_NewArray. Referenced by main(), and set_frame_change().
00895 {
00896 Gt_Frameset *fs = Gif_New(Gt_Frameset);
00897 if (initial_cap < 0) initial_cap = 0;
00898 fs->cap = initial_cap;
00899 fs->count = 0;
00900 fs->f = Gif_NewArray(Gt_Frame, initial_cap);
00901 return fs;
00902 }
|
|
||||||||||||||||||||
|
Definition at line 698 of file support.c. References arg, Gif_Color::blue, Clp_OptionError(), error(), Gif_Color::green, Gif_Color::haspixel, parse_hex_color_channel(), Gif_Color::pixel, and Gif_Color::red. Referenced by parse_two_colors().
00699 {
00700 const char *input_arg = arg;
00701 char *str;
00702 int red, green, blue;
00703
00704 if (*arg == '#') {
00705 int len = strlen(++arg);
00706 if (!len || len % 3 != 0 || strspn(arg, "0123456789ABCDEFabcdef") != len) {
00707 if (complain)
00708 Clp_OptionError(clp, "invalid color `%s' (want `#RGB' or `#RRGGBB')",
00709 input_arg);
00710 return 0;
00711 }
00712
00713 len /= 3;
00714 red = parse_hex_color_channel(&arg[ 0 * len ], len);
00715 green = parse_hex_color_channel(&arg[ 1 * len ], len);
00716 blue = parse_hex_color_channel(&arg[ 2 * len ], len);
00717 goto gotrgb;
00718
00719 } else if (!isdigit(*arg))
00720 goto error;
00721
00722 red = strtol(arg, &str, 10);
00723 if (*str == 0) {
00724 if (red < 0 || red > 255)
00725 goto error;
00726 parsed_color.haspixel = 1;
00727 parsed_color.pixel = red;
00728 return 1;
00729
00730 } else if (*str != ',' && *str != '/')
00731 goto error;
00732
00733 if (*++str == 0) goto error;
00734 green = strtol(str, &str, 10);
00735 if (*str != ',' && *str != '/') goto error;
00736
00737 if (*++str == 0) goto error;
00738 blue = strtol(str, &str, 10);
00739 if (*str != 0) goto error;
00740
00741 gotrgb:
00742 if (red < 0 || green < 0 || blue < 0
00743 || red > 255 || green > 255 || blue > 255)
00744 goto error;
00745 parsed_color.red = red;
00746 parsed_color.green = green;
00747 parsed_color.blue = blue;
00748 parsed_color.haspixel = 0;
00749 return 1;
00750
00751 error:
00752 if (complain)
00753 return Clp_OptionError(clp, "invalid color `%s'", input_arg);
00754 else
00755 return 0;
00756 }
|
|
||||||||||||||||||||
|
Definition at line 569 of file support.c. References arg, Clp_OptionError(), dimensions_x, and dimensions_y. Referenced by parse_rectangle().
00570 {
00571 char *val;
00572
00573 if (*arg == '_' && arg[1] == 'x') {
00574 dimensions_x = 0;
00575 val = (char *)(arg + 1);
00576 } else
00577 dimensions_x = strtol(arg, &val, 10);
00578 if (*val == 'x') {
00579 if (val[1] == '_' && val[2] == 0) {
00580 dimensions_y = 0;
00581 val = val + 2;
00582 } else
00583 dimensions_y = strtol(val + 1, &val, 10);
00584 if (*val == 0)
00585 return 1;
00586 }
00587
00588 if (complain)
00589 return Clp_OptionError(clp, "invalid dimensions `%s' (want WxH)", arg);
00590 else
00591 return 0;
00592 }
|
|
||||||||||||||||||||
|
Definition at line 488 of file support.c. References arg, c, Clp_OptionError(), frame_spec_1, frame_spec_2, frame_spec_name, Gif_GetNamedImage(), Gif_ImageCount, Gif_ImageNumber(), and input_stream(). Referenced by frame_argument().
00489 {
00490 char *c;
00491
00492 frame_spec_1 = 0;
00493 frame_spec_2 = -1;
00494 frame_spec_name = 0;
00495
00496 if (!input && !input_name)
00497 input_stream(0);
00498 if (!input)
00499 return 0;
00500
00501 if (arg[0] != '#') {
00502 if (complain)
00503 return Clp_OptionError(clp, "frame specifications must start with #");
00504 else
00505 return 0;
00506 }
00507 arg++;
00508 c = (char *)arg;
00509
00510 /* Get a number range (#x, #x-y, or #x-). First, read x. */
00511 if (isdigit(c[0]))
00512 frame_spec_1 = frame_spec_2 = strtol(c, &c, 10);
00513 else if (c[0] == '-' && isdigit(c[1])) {
00514 frame_spec_1 = frame_spec_2 = Gif_ImageCount(input) + strtol(c, &c, 10);
00515 if (frame_spec_1 < 0)
00516 return complain ? Clp_OptionError(clp, "there are only %d frames",
00517 Gif_ImageCount(input)) : 0;
00518 }
00519
00520 /* Then, if the next character is a dash, read y. Be careful to prevent
00521 #- from being interpreted as a frame range. */
00522 if (c[0] == '-' && (frame_spec_2 > 0 || c[1] != 0)) {
00523 c++;
00524 if (isdigit(c[0]))
00525 frame_spec_2 = strtol(c, &c, 10);
00526 else if (c[0] == '-' && isdigit(c[1]))
00527 frame_spec_2 = Gif_ImageCount(input) + strtol(c, &c, 10);
00528 else
00529 frame_spec_2 = Gif_ImageCount(input) - 1;
00530 }
00531
00532 /* It really was a number range (and not a frame name)
00533 only if c is now at the end of the argument. */
00534 if (c[0] != 0) {
00535 Gif_Image *gfi = Gif_GetNamedImage(input, arg);
00536 if (gfi) {
00537 frame_spec_name = (char *)arg;
00538 frame_spec_1 = frame_spec_2 = Gif_ImageNumber(input, gfi);
00539 return 1;
00540 } else if (complain < 0) /* -1 is special value meaning `don't complain
00541 about frame NAMES, but do complain about
00542 frame numbers.' */
00543 return -97; /* Return -97 on bad frame name. */
00544 else if (complain)
00545 return Clp_OptionError(clp, "no frame named `#%s'", arg);
00546 else
00547 return 0;
00548
00549 } else {
00550 if (frame_spec_1 >= 0 && frame_spec_1 <= frame_spec_2
00551 && frame_spec_2 < Gif_ImageCount(input))
00552 return 1;
00553 else if (!complain)
00554 return 0;
00555
00556 if (frame_spec_1 == frame_spec_2)
00557 return Clp_OptionError(clp, "no frame number #%d", frame_spec_1);
00558 else if (frame_spec_1 < 0)
00559 return Clp_OptionError(clp, "frame numbers can't be negative");
00560 else if (frame_spec_1 > frame_spec_2)
00561 return Clp_OptionError(clp, "empty frame range");
00562 else
00563 return Clp_OptionError(clp, "there are only %d frames",
00564 Gif_ImageCount(input));
00565 }
00566 }
|
|
||||||||||||
|
Definition at line 684 of file support.c. References xvalue(). Referenced by parse_color().
|
|
||||||||||||||||||||
|
Definition at line 595 of file support.c. References arg, Clp_OptionError(), position_x, and position_y. Referenced by parse_rectangle().
00596 {
00597 char *val;
00598
00599 position_x = strtol(arg, &val, 10);
00600 if (*val == ',') {
00601 position_y = strtol(val + 1, &val, 10);
00602 if (*val == 0)
00603 return 1;
00604 }
00605
00606 if (complain)
00607 return Clp_OptionError(clp, "invalid position `%s' (want `X,Y')", arg);
00608 else
00609 return 0;
00610 }
|
|
||||||||||||||||||||
|
Definition at line 634 of file support.c. References arg, Clp_OptionError(), dimensions_x, dimensions_y, parse_dimensions(), parse_position(), position_x, and position_y.
00635 {
00636 const char *input_arg = arg;
00637 char *val;
00638
00639 int x = position_x = strtol(arg, &val, 10);
00640 if (*val == ',') {
00641 int y = position_y = strtol(val + 1, &val, 10);
00642 if (*val == '-' && parse_position(clp, val + 1, 0, 0)) {
00643 if (x >= 0 && y >= 0 && x < position_x && y < position_y) {
00644 dimensions_x = position_x - x;
00645 dimensions_y = position_y - y;
00646 position_x = x;
00647 position_y = y;
00648 return 1;
00649 }
00650 } else if (*val == '+' && parse_dimensions(clp, val + 1, 0, 0))
00651 return 1;
00652 } else if (*val == 'x') {
00653 dimensions_x = position_x;
00654 dimensions_y = strtol(val + 1, &val, 10);
00655 if (*val == 0) {
00656 position_x = position_y = 0;
00657 return 1;
00658 }
00659 }
00660
00661 if (complain)
00662 return Clp_OptionError(clp, "invalid rectangle `%s' (want `X1,Y1-X2,Y2' or `X1,Y1+WxH'", input_arg);
00663 else
00664 return 0;
00665 }
|
|
||||||||||||||||||||
|
Definition at line 613 of file support.c. References arg, Clp_OptionError(), parsed_scale_factor_x, parsed_scale_factor_y, and strtod().
00614 {
00615 char *val;
00616
00617 parsed_scale_factor_x = strtod(arg, &val);
00618 if (*val == 'x') {
00619 parsed_scale_factor_y = strtod(val + 1, &val);
00620 if (*val == 0)
00621 return 1;
00622 } else if (*val == 0) {
00623 parsed_scale_factor_y = parsed_scale_factor_x;
00624 return 1;
00625 }
00626
00627 if (complain)
00628 return Clp_OptionError(clp, "invalid scale factor `%s' (want XxY)", arg);
00629 else
00630 return 0;
00631 }
|
|
||||||||||||||||||||
|
Definition at line 759 of file support.c. References arg, Clp_OptionError(), Clp_Shift(), and parse_color().
00760 {
00761 Gif_Color old_color;
00762 if (parse_color(clp, arg, complain, thunk) <= 0)
00763 return 0;
00764 old_color = parsed_color;
00765
00766 arg = Clp_Shift(clp, 0);
00767 if (!arg && complain)
00768 return Clp_OptionError(clp, "`%O' takes two color arguments");
00769 else if (!arg)
00770 return 0;
00771
00772 if (parse_color(clp, arg, complain, thunk) <= 0)
00773 return 0;
00774
00775 parsed_color2 = parsed_color;
00776 parsed_color = old_color;
00777 return 1;
00778 }
|
|
||||||||||||
|
Definition at line 841 of file support.c. References c, error(), Gif_Stream::errors, Gif_CopyColormap(), Gif_DeleteStream(), Gif_ReadFile, Gif_Stream::global, name, read_text_colormap(), strerror(), ungetc(), verbose_close(), verbose_open(), and warning(). Referenced by pipe_color_transformer(), and set_new_fixed_colormap().
00842 {
00843 Gif_Colormap *cm = 0;
00844 int c;
00845 int my_file = 0;
00846
00847 if (name && strcmp(name, "-") == 0)
00848 name = 0;
00849 if (!f) {
00850 my_file = 1;
00851 if (!name)
00852 f = stdin;
00853 else
00854 f = fopen(name, "rb");
00855 if (!f) {
00856 error("%s: %s", name, strerror(errno));
00857 return 0;
00858 }
00859 }
00860
00861 name = name ? name : "<stdin>";
00862 if (verbosing) verbose_open('<', name);
00863
00864 c = getc(f);
00865 ungetc(c, f);
00866 if (c == 'G') {
00867 Gif_Stream *gfs = Gif_ReadFile(f);
00868 if (!gfs)
00869 error("`%s' doesn't seem to contain a GIF", name);
00870 else if (!gfs->global)
00871 error("can't use `%s' as a palette (no global color table)", name);
00872 else {
00873 if (gfs->errors)
00874 warning("there were errors reading `%s'", name);
00875 cm = Gif_CopyColormap(gfs->global);
00876 }
00877
00878 Gif_DeleteStream(gfs);
00879 } else
00880 cm = read_text_colormap(f, name);
00881
00882 if (my_file) fclose(f);
00883 if (verbosing) verbose_close('>');
00884 return cm;
00885 }
|
|
||||||||||||
|
Definition at line 786 of file support.c. References c, Gif_Colormap::col, error(), Gif_DeleteColormap(), Gif_NewFullColormap(), name, Gif_Colormap::ncol, and ncol. Referenced by read_colormap_file().
00787 {
00788 char buf[BUFSIZ];
00789 Gif_Colormap *cm = Gif_NewFullColormap(0, 256);
00790 Gif_Color *col = cm->col;
00791 int ncol = 0;
00792 unsigned red, green, blue;
00793 float fred, fgreen, fblue;
00794
00795 while (fgets(buf, BUFSIZ, f)) {
00796
00797 if (sscanf(buf, "%g %g %g", &fred, &fgreen, &fblue) == 3) {
00798 if (fred < 0) fred = 0;
00799 if (fgreen < 0) fgreen = 0;
00800 if (fblue < 0) fblue = 0;
00801 red = (unsigned)(fred + .5);
00802 green = (unsigned)(fgreen + .5);
00803 blue = (unsigned)(fblue + .5);
00804 goto found;
00805
00806 } else if (sscanf(buf, "#%2x%2x%2x", &red, &green, &blue) == 3) {
00807 found:
00808 if (red > 255) red = 255;
00809 if (green > 255) green = 255;
00810 if (blue > 255) blue = 255;
00811 if (ncol >= 256) {
00812 error("%s: maximum 256 colors allowed in colormap", name);
00813 break;
00814 } else {
00815 col[ncol].red = red;
00816 col[ncol].green = green;
00817 col[ncol].blue = blue;
00818 ncol++;
00819 }
00820 }
00821
00822 /* handle too-long lines gracefully */
00823 if (strchr(buf, '\n') == 0) {
00824 int c;
00825 for (c = getc(f); c != '\n' && c != EOF; c = getc(f))
00826 ;
00827 }
00828 }
00829
00830 if (ncol == 0) {
00831 error("`%s' doesn't seem to contain a colormap", name);
00832 Gif_DeleteColormap(cm);
00833 return 0;
00834 } else {
00835 cm->ncol = ncol;
00836 return cm;
00837 }
00838 }
|
|
||||||||||||||||
|
Definition at line 246 of file support.c. References u_int32_t. Referenced by comment_info(), and extension_info().
00247 {
00248 const char *last_safe = s;
00249 for (; len > 0; len--, s++)
00250 if (*s < ' ' || *s >= 0x7F || *s == '\\') {
00251 if (last_safe != s)
00252 fwrite(last_safe, 1, s - last_safe, f);
00253 last_safe = s + 1;
00254 switch (*s) {
00255 case '\a': fputs("\\a", f); break;
00256 case '\b': fputs("\\b", f); break;
00257 case '\f': fputs("\\f", f); break;
00258 case '\n': fputs("\\n", f); break;
00259 case '\r': fputs("\\r", f); break;
00260 case '\t': fputs("\\t", f); break;
00261 case '\v': fputs("\\v", f); break;
00262 case '\\': fputs("\\\\", f); break;
00263 case 0: if (len > 1) fputs("\\000", f); break;
00264 default: fprintf(f, "\\%03o", *s); break;
00265 }
00266 }
00267 if (last_safe != s)
00268 fwrite(last_safe, 1, s - last_safe, f);
00269 }
|
|
|
Definition at line 103 of file support.c. References program_name.
00104 {
00105 fprintf(stderr, "Usage: %s [OPTION | FILE | FRAME]...\n\
00106 Try `%s --help' for more information.\n",
00107 program_name, program_name);
00108 }
|
|
||||||||||||||||||||||||
|
Definition at line 356 of file support.c. References Gif_Stream::background, colormap_info(), Gif_Stream::comment, comment_info(), extension_info(), Gif_Stream::extensions, Gif_Stream::global, Gif_Stream::loopcount, Gif_Colormap::ncol, Gif_Extension::next, Gif_Stream::nimages, Gif_Stream::screen_height, Gif_Stream::screen_width, and verbose_endline(). Referenced by output_information().
00358 {
00359 Gif_Extension *gfex;
00360 int n;
00361
00362 if (!gfs) return;
00363
00364 verbose_endline();
00365 fprintf(where, "* %s %d image%s\n", (filename ? filename : "<stdin>"),
00366 gfs->nimages, gfs->nimages == 1 ? "" : "s");
00367 fprintf(where, " logical screen %dx%d\n",
00368 gfs->screen_width, gfs->screen_height);
00369
00370 if (gfs->global) {
00371 fprintf(where, " global color table [%d]\n", gfs->global->ncol);
00372 if (colormaps) colormap_info(where, gfs->global, " |");
00373 fprintf(where, " background %d\n", gfs->background);
00374 }
00375
00376 if (gfs->comment)
00377 comment_info(where, gfs->comment, " end comment ");
00378
00379 if (gfs->loopcount == 0)
00380 fprintf(where, " loop forever\n");
00381 else if (gfs->loopcount > 0)
00382 fprintf(where, " loop count %u\n", (unsigned)gfs->loopcount);
00383
00384 for (n = 0, gfex = gfs->extensions; gfex; gfex = gfex->next, n++)
00385 if (extensions)
00386 extension_info(where, gfs, gfex, n);
00387 if (n && !extensions)
00388 fprintf(where, " extensions %d\n", n);
00389 }
|
|
|
Definition at line 112 of file support.c. References program_name.
00113 {
00114 printf("\
00115 `Gifsicle' manipulates GIF images. Its most common uses include combining\n\
00116 single images into animations, adding transparency, optimizing animations for\n\
00117 space, and printing information about GIFs.\n\
00118 \n\
00119 Usage: %s [OPTION | FILE | FRAME]...\n\
00120 \n\
00121 Mode options: at most one, before any filenames.\n\
00122 -m, --merge Merge mode: combine inputs, write stdout.\n\
00123 -b, --batch Batch mode: modify inputs, write back to\n\
00124 same filenames.\n\
00125 -e, --explode Explode mode: write N files for each input,\n\
00126 one per frame, to `input.frame-number'.\n\
00127 -E, --explode-by-name Explode mode, but write `input.name'.\n\
00128 \n\
00129 General options: Also --no-OPTION for info and verbose.\n\
00130 -I, --info Print info about input GIFs. Two -I's means\n\
00131 normal output is not suppressed.\n\
00132 --color-info, --cinfo --info plus colormap details.\n\
00133 --extension-info, --xinfo --info plus extension details.\n\
00134 -v, --verbose Prints progress information.\n\
00135 -h, --help Print this message and exit.\n\
00136 --version Print version number and exit.\n\
00137 -o, --output FILE Write output to FILE.\n\
00138 -w, --no-warnings Don't report warnings.\n\
00139 \n", program_name);
00140 printf("\
00141 Frame selections: #num, #num1-num2, #num1-, #name\n\
00142 \n\
00143 Frame change options:\n\
00144 --delete FRAMES Delete FRAMES from input.\n\
00145 --insert-before FRAME GIFS Insert GIFS before FRAMES in input.\n\
00146 --append GIFS Append GIFS to input.\n\
00147 --replace FRAMES GIFS Replace FRAMES with GIFS in input.\n\
00148 --done Done with frame changes.\n\
00149 \n\
00150 Image options: Also --no-OPTION and --same-OPTION.\n\
00151 -B, --background COL Makes COL the background color.\n\
00152 --crop X,Y+WxH, --crop X,Y-X2,Y2\n\
00153 Crops the image.\n\
00154 --flip-horizontal, --flip-vertical\n\
00155 Flips the image.\n\
00156 -i, --interlace Turns on interlacing.\n\
00157 -S, --logical-screen WxH Sets logical screen to WxH.\n\
00158 -p, --position X,Y Sets frame position to (X,Y).\n\
00159 --rotate-90, --rotate-180, --rotate-270, --no-rotate\n\
00160 Rotates the image.\n\
00161 -t, --transparent COL Makes COL transparent.\n\
00162 \n");
00163 printf("\
00164 Extension options: Also --no-OPTION and --same-OPTION.\n\
00165 -x, --app-extension N D Adds an app extension named N with data D.\n\
00166 -c, --comment TEXT Adds a comment before the next frame.\n\
00167 --extension N D Adds an extension number N with data D.\n\
00168 -n, --name TEXT Sets next frame's name.\n\
00169 \n\
00170 Animation options: Also --no-OPTION and --same-OPTION.\n\
00171 -d, --delay TIME Sets frame delay to TIME (in 1/100sec).\n\
00172 -D, --disposal METHOD Sets frame disposal to METHOD.\n\
00173 -l, --loopcount[=N] Sets loop extension to N (default forever).\n\
00174 -O, --optimize[=LEV] Optimize output GIFs.\n\
00175 -U, --unoptimize Unoptimize input GIFs.\n\
00176 \n");
00177 printf("\
00178 Whole-GIF options: Also --no-OPTION.\n\
00179 --careful Write larger GIFs that avoid bugs in other\n\
00180 programs.\n\
00181 --change-color COL1 COL2 Changes COL1 to COL2 throughout.\n\
00182 -k, --colors N Reduces the number of colors to N.\n\
00183 --color-method METHOD Set method for choosing reduced colors.\n\
00184 -f, --dither Dither image after changing colormap.\n\
00185 --resize WxH Resizes the output GIF to WxH.\n\
00186 --resize-width W Resizes to width W and proportional height.\n\
00187 --resize-height H Resizes to height H and proportional width.\n\
00188 --scale XFACTOR[xYFACTOR] Scales the output GIF by XFACTORxYFACTOR.\n\
00189 --transform-colormap CMD Transform each output colormap by shell CMD.\n\
00190 --use-colormap CMAP Set output GIF's colormap to CMAP, which can\n\
00191 be `web', `gray', `bw', or a GIF file.\n\
00192 \n\
00193 Report bugs to <eddietwo@lcs.mit.edu>.\n\
00194 Too much information? Try `%s --help | more'.\n", program_name);
00195 #ifdef GIF_UNGIF
00196 printf("\
00197 This version of Gifsicle writes uncompressed GIFs, which can be far larger\n\
00198 than compressed GIFs. See http://www.lcdf.org/gifsicle for more information.\n");
00199 #endif
00200 }
|
|
|
Definition at line 222 of file support.c. References close(), and verbose_pos. Referenced by input_done(), input_stream(), merge_and_write_frames(), and read_colormap_file().
00223 {
00224 fputc(close, stderr);
00225 verbose_pos++;
00226 }
|
|
|
Definition at line 230 of file support.c. References verbose_pos. Referenced by clp_error_handler(), image_info(), main(), stream_info(), and verror().
00231 {
00232 if (verbose_pos) {
00233 fputc('\n', stderr);
00234 fflush(stderr);
00235 verbose_pos = 0;
00236 }
00237 }
|
|
||||||||||||
|
Definition at line 204 of file support.c. References l, name, and verbose_pos. Referenced by input_stream(), merge_and_write_frames(), and read_colormap_file().
00205 {
00206 int l = strlen(name);
00207 if (verbose_pos && verbose_pos + 3 + l > 79) {
00208 fputc('\n', stderr);
00209 verbose_pos = 0;
00210 }
00211 if (verbose_pos) {
00212 fputc(' ', stderr);
00213 verbose_pos++;
00214 }
00215 fputc(open, stderr);
00216 fputs(name, stderr);
00217 verbose_pos += 1 + l;
00218 }
|
|
||||||||||||||||
|
Definition at line 26 of file support.c. References error_count, program_name, and verbose_endline(). Referenced by error(), fatal_error(), warncontext(), and warning().
00027 {
00028 char pattern[BUFSIZ];
00029 char buffer[BUFSIZ];
00030 verbose_endline();
00031
00032 if (seriousness > 2)
00033 sprintf(pattern, "%s: fatal error: %%s\n", program_name);
00034 else if (seriousness == 1)
00035 sprintf(pattern, "%s: warning: %%s\n", program_name);
00036 else
00037 sprintf(pattern, "%s: %%s\n", program_name);
00038
00039 if (seriousness > 1)
00040 error_count++;
00041 else if (no_warnings)
00042 return;
00043
00044 /* try and keep error messages together (no interleaving of error messages
00045 from two gifsicle processes in the same command line) by calling fprintf
00046 only once */
00047 if (strlen(message) + strlen(pattern) < BUFSIZ) {
00048 sprintf(buffer, pattern, message);
00049 vfprintf(stderr, buffer, val);
00050 } else {
00051 fwrite(pattern, 1, strlen(pattern) - 3, stderr);
00052 vfprintf(stderr, message, val);
00053 putc('\n', stderr);
00054 }
00055 }
|
|
||||||||||||
|
Definition at line 86 of file support.c. References verror(). Referenced by do_colormap_change(), find_background(), input_stream(), merge_colormap_if_possible(), print_useless_options(), and redundant_option_warning().
00087 {
00088 va_list val;
00089 va_start(val, message);
00090 verror(0, message, val);
00091 va_end(val);
00092 }
|
|
||||||||||||
|
Definition at line 77 of file support.c. References verror(). Referenced by colormap_diversity(), colormap_median_cut(), find_background(), input_stream(), merge_colormap_if_possible(), new_viewer(), parse_geometry(), pipe_color_transformer(), print_useless_options(), read_colormap_file(), and redundant_option_warning().
00078 {
00079 va_list val;
00080 va_start(val, message);
00081 verror(1, message, val);
00082 va_end(val);
00083 }
|
|
|
Definition at line 668 of file support.c. References c. Referenced by parse_hex_color_channel().
00669 {
00670 switch (c) {
00671 case '0': case '1': case '2': case '3': case '4':
00672 case '5': case '6': case '7': case '8': case '9':
00673 return c - '0';
00674 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
00675 return c - 'A' + 10;
00676 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
00677 return c - 'a' + 10;
00678 default:
00679 return -1;
00680 }
00681 }
|
Variable Documentation
|
|
Definition at line 478 of file support.c. Referenced by parse_dimensions(), and parse_rectangle(). |
|
|
Definition at line 479 of file support.c. Referenced by parse_dimensions(), and parse_rectangle(). |
|
|
Initial value: {
"none", "asis", "background", "previous", "4", "5", "6", "7"
}Definition at line 392 of file support.c. Referenced by image_info(). |
|
|
Definition at line 21 of file support.c. Referenced by verror(). |
|
|
Definition at line 475 of file support.c. Referenced by parse_frame_spec(). |
|
|
Definition at line 476 of file support.c. Referenced by parse_frame_spec(). |
|
|
Definition at line 477 of file support.c. Referenced by parse_frame_spec(). |
|
|
|
|
|
Definition at line 974 of file support.c. Referenced by merger_add(). |
|
|
Definition at line 973 of file support.c. Referenced by find_background(), fix_total_crop(), merge_frame_interval(), and merger_add(). |
|
|
|
|
|
|
|
|
|
|
|
Definition at line 484 of file support.c. Referenced by parse_scale_factor(). |
|
|
Definition at line 485 of file support.c. Referenced by parse_scale_factor(). |
|
|
Definition at line 480 of file support.c. Referenced by parse_position(), and parse_rectangle(). |
|
|
Definition at line 481 of file support.c. Referenced by parse_position(), and parse_rectangle(). |
|
|
Definition at line 19 of file support.c. Referenced by short_usage(), usage(), and verror(). |
|
|
Definition at line 20 of file support.c. Referenced by verbose_close(), verbose_endline(), and verbose_open(). |