1 /* gifsicle.h - Function declarations for gifsicle.
2    Copyright (C) 1997-2021 Eddie Kohler, ekohler@gmail.com
3    This file is part of gifsicle.
4 
5    Gifsicle is free software. It is distributed under the GNU Public License,
6    version 2; you can copy, distribute, or alter it at will, as long
7    as this notice is kept intact and this source code is made available. There
8    is no warranty, express or implied. */
9 
10 #ifndef GIFSICLE_H
11 #define GIFSICLE_H
12 #include <lcdfgif/gif.h>
13 #include <lcdf/clp.h>
14 #ifdef __GNUC__
15 #define NORETURN __attribute__ ((noreturn))
16 #define USED_ATTR __attribute__ ((used))
17 #else
18 #define NORETURN
19 #define USED_ATTR
20 #endif
21 
22 typedef struct Gt_Frameset Gt_Frameset;
23 typedef struct Gt_Crop Gt_Crop;
24 typedef struct Gt_ColorTransform Gt_ColorTransform;
25 
26 #if ENABLE_THREADS
27 #include <pthread.h>
28 extern pthread_mutex_t kd3_sort_lock;
29 #endif
30 
31 typedef struct Gt_Frame {
32 
33   Gif_Stream *stream;
34   Gif_Image *image;
35   int use;
36 
37   const char *name;
38   int no_name;
39   Gif_Comment *comment;
40   int no_comments;
41 
42   Gif_Color transparent;        /* also background */
43   int interlacing;
44   int left;
45   int top;
46 
47   Gt_Crop *crop;
48   int left_offset;
49   int top_offset;
50 
51   int delay;
52   int disposal;
53 
54   Gt_Frameset *nest;
55   int explode_by_name;
56 
57   int no_extensions;
58   int no_app_extensions;
59   Gif_Extension *extensions;
60 
61   unsigned flip_horizontal: 1;
62   unsigned flip_vertical: 1;
63   unsigned info_flags: 3;
64   unsigned position_is_offset: 1;
65   unsigned total_crop: 1;
66   unsigned rotation;
67 
68   const char *input_filename;
69 
70 } Gt_Frame;
71 
72 
73 struct Gt_Frameset {
74   int count;
75   int cap;
76   Gt_Frame *f;
77 };
78 
79 
80 struct Gt_Crop {
81   int ready;
82   int transparent_edges;
83   int spec_x;
84   int spec_y;
85   int spec_w;
86   int spec_h;
87   int x;
88   int y;
89   int w;
90   int h;
91   int left_offset;
92   int top_offset;
93 };
94 
95 
96 typedef void (*colormap_transform_func)(Gif_Colormap *, void *);
97 
98 struct Gt_ColorTransform {
99   Gt_ColorTransform *prev;
100   Gt_ColorTransform *next;
101   colormap_transform_func func;
102   void *data;
103 };
104 
105 
106 typedef struct {
107 
108   const char *output_name;
109   const char *active_output_name;
110 
111   int screen_width;
112   int screen_height;
113 
114   Gif_Color background;
115   int loopcount;
116 
117   int colormap_size;
118   Gif_Colormap *colormap_fixed;
119   int colormap_algorithm;
120   int colormap_needs_transparency;
121   int dither_type;
122   const uint8_t* dither_data;
123   const char* dither_name;
124   int colormap_gamma_type;
125   double colormap_gamma;
126 
127   int optimizing;
128 
129   int scaling;
130   int resize_width;
131   int resize_height;
132   int resize_flags;
133   double scale_x;
134   double scale_y;
135   int scale_method;
136   int scale_colors;
137 
138   int conserve_memory;
139 
140 } Gt_OutputData;
141 
142 extern Gt_OutputData active_output_data;
143 extern Clp_Parser* clp;
144 
145 #define GT_SCALING_NONE         0
146 #define GT_SCALING_RESIZE       1
147 #define GT_SCALING_SCALE        2
148 
149 #define GT_RESIZE_FIT           1
150 #define GT_RESIZE_FIT_DOWN      2
151 #define GT_RESIZE_FIT_UP        4
152 #define GT_RESIZE_MIN_DIMEN     8
153 
154 #define SCALE_METHOD_POINT      0
155 #define SCALE_METHOD_BOX        1
156 #define SCALE_METHOD_MIX        2
157 #define SCALE_METHOD_CATROM     3
158 #define SCALE_METHOD_LANCZOS2   4
159 #define SCALE_METHOD_LANCZOS3   5
160 #define SCALE_METHOD_MITCHELL   6
161 
162 #define GT_OPT_MASK             0xFFFF
163 #define GT_OPT_KEEPEMPTY        0x10000
164 
165 
166 /*****
167  * helper
168  **/
169 
170 static inline int
constrain(int low,int x,int high)171 constrain(int low, int x, int high)
172 {
173   return x < low ? low : (x < high ? x : high);
174 }
175 
176 
177 /*****
178  * error & verbose
179  **/
180 extern const char *program_name;
181 extern int verbosing;
182 extern int error_count;
183 extern int no_warnings;
184 extern int thread_count;
185 extern Gif_CompressInfo gif_write_info;
186 
187 void fatal_error(const char* format, ...) NORETURN;
188 void warning(int need_file, const char* format, ...);
189 void lwarning(const char* landmark, const char* format, ...);
190 void error(int need_file, const char* format, ...);
191 void lerror(const char* landmark, const char* format, ...);
192 void clp_error_handler(Clp_Parser *clp, const char *clp_message);
193 void usage(void);
194 void short_usage(void);
195 
196 void verbose_open(char, const char *);
197 void verbose_close(char);
198 void verbose_endline(void);
199 
200 const char* debug_color_str(const Gif_Color* gfc);
201 
202 #define EXIT_OK         0
203 #define EXIT_ERR        1
204 #define EXIT_USER_ERR   1
205 
206 /*****
207  * info &c
208  **/
209 #define INFO_COLORMAPS  1
210 #define INFO_EXTENSIONS 2
211 #define INFO_SIZES      4
212 void stream_info(FILE *f, Gif_Stream *gfs, const char *filename, int flags);
213 void image_info(FILE *f, Gif_Stream *gfs, Gif_Image *gfi, int flags);
214 
215 char *explode_filename(const char *filename, int number,
216                        const char *name, int max_nimg);
217 
218 /*****
219  * merging images
220  **/
221 void    unmark_colors(Gif_Colormap *);
222 void    unmark_colors_2(Gif_Colormap *);
223 void    mark_used_colors(Gif_Stream *gfs, Gif_Image *gfi, Gt_Crop *crop,
224                          int compress_immediately);
225 int     find_color_index(Gif_Color *c, int nc, Gif_Color *);
226 int     merge_colormap_if_possible(Gif_Colormap *, Gif_Colormap *);
227 
228 extern int warn_local_colormaps;
229 void    merge_stream(Gif_Stream *dest, Gif_Stream *src, int no_comments);
230 void    merge_comments(Gif_Comment *destc, Gif_Comment *srcc);
231 Gif_Image* merge_image(Gif_Stream* dest, Gif_Stream* src, Gif_Image* srci,
232                        Gt_Frame* srcfr, int same_compressed_ok);
233 
234 void    optimize_fragments(Gif_Stream *, int optimizeness, int huge_stream);
235 
236 /*****
237  * image/colormap transformations
238  **/
239 Gif_Colormap *read_colormap_file(const char *, FILE *);
240 void    apply_color_transforms(Gt_ColorTransform *, Gif_Stream *);
241 
242 typedef void (*color_transform_func)(Gif_Colormap *, void *);
243 Gt_ColorTransform *append_color_transform
244         (Gt_ColorTransform *list, color_transform_func, void *);
245 Gt_ColorTransform *delete_color_transforms
246         (Gt_ColorTransform *list, color_transform_func);
247 
248 void    color_change_transformer(Gif_Colormap *, void *);
249 Gt_ColorTransform *append_color_change
250         (Gt_ColorTransform *list, Gif_Color, Gif_Color);
251 
252 void    pipe_color_transformer(Gif_Colormap *, void *);
253 
254 void    combine_crop(Gt_Crop *dstcrop, const Gt_Crop *srccrop, const Gif_Image *gfi);
255 int     crop_image(Gif_Image* gfi, Gt_Frame* fr, int preserve_total_crop);
256 
257 void    flip_image(Gif_Image* gfi, Gt_Frame* fr, int is_vert);
258 void    rotate_image(Gif_Image* gfi, Gt_Frame* fr, int rotation);
259 void    resize_dimensions(int* w, int* h, double new_width, double new_height,
260                           int flags);
261 void    resize_stream(Gif_Stream* gfs, double new_width, double new_height,
262                       int flags, int method, int scale_colors);
263 
264 /*****
265  * quantization
266  **/
267 #define KC_GAMMA_SRGB                   0
268 #define KC_GAMMA_NUMERIC                1
269 void    kc_set_gamma(int type, double gamma);
270 
271 #define COLORMAP_DIVERSITY              0
272 #define COLORMAP_BLEND_DIVERSITY        1
273 #define COLORMAP_MEDIAN_CUT             2
274 
275 enum {
276     dither_none = 0, dither_default, dither_floyd_steinberg,
277     dither_ordered, dither_ordered_new
278 };
279 int     set_dither_type(Gt_OutputData* od, const char* name);
280 void    colormap_stream(Gif_Stream*, Gif_Colormap*, Gt_OutputData*);
281 
282 /*****
283  * parsing stuff
284  **/
285 extern int      frame_spec_1;
286 extern int      frame_spec_2;
287 extern char *   frame_spec_name;
288 extern int      dimensions_x;
289 extern int      dimensions_y;
290 extern int      position_x;
291 extern int      position_y;
292 extern Gif_Color parsed_color;
293 extern Gif_Color parsed_color2;
294 extern double   parsed_scale_factor_x;
295 extern double   parsed_scale_factor_y;
296 
297 int             parse_frame_spec(Clp_Parser *, const char *, int, void *);
298 int             parse_dimensions(Clp_Parser *, const char *, int, void *);
299 int             parse_position(Clp_Parser *, const char *, int, void *);
300 int             parse_scale_factor(Clp_Parser *, const char *, int, void *);
301 int             parse_color(Clp_Parser *, const char *, int, void *);
302 int             parse_rectangle(Clp_Parser *, const char *, int, void *);
303 int             parse_two_colors(Clp_Parser *, const char *, int, void *);
304 
305 extern Gif_Stream *input;
306 extern const char *input_name;
307 
308 void            input_stream(const char *);
309 void            input_done(void);
310 void            output_frames(void);
311 
312 /*****
313  * stuff with frames
314  **/
315 extern Gt_Frame def_frame;
316 #define         FRAME(fs, i)    ((fs)->f[i])
317 
318 Gt_Frameset *   new_frameset(int initial_cap);
319 Gt_Frame*       add_frame(Gt_Frameset*, Gif_Stream*, Gif_Image*);
320 void            clear_def_frame_once_options(void);
321 
322 Gif_Stream *    merge_frame_interval(Gt_Frameset *, int f1, int f2,
323                                      Gt_OutputData *, int compress, int *huge);
324 void            clear_frameset(Gt_Frameset *, int from);
325 void            blank_frameset(Gt_Frameset *, int from, int to, int delete_ob);
326 
327 /*****
328  * mode
329  **/
330 #define BLANK_MODE      0
331 #define MERGING         1
332 #define BATCHING        2
333 #define EXPLODING       3
334 #define INFOING         4
335 #define DELETING        5
336 #define INSERTING       6
337 
338 extern int mode;
339 extern int nested_mode;
340 
341 #endif
342