1*324bb76bSAndroid Build Coastguard Worker /*****************************************************************************
2*324bb76bSAndroid Build Coastguard Worker
3*324bb76bSAndroid Build Coastguard Worker gifbuild - dump GIF data in a textual format, or undump it to a GIF
4*324bb76bSAndroid Build Coastguard Worker
5*324bb76bSAndroid Build Coastguard Worker SPDX-License-Identifier: MIT
6*324bb76bSAndroid Build Coastguard Worker
7*324bb76bSAndroid Build Coastguard Worker *****************************************************************************/
8*324bb76bSAndroid Build Coastguard Worker
9*324bb76bSAndroid Build Coastguard Worker #include <ctype.h>
10*324bb76bSAndroid Build Coastguard Worker #include <stdbool.h>
11*324bb76bSAndroid Build Coastguard Worker #include <stdio.h>
12*324bb76bSAndroid Build Coastguard Worker #include <stdlib.h>
13*324bb76bSAndroid Build Coastguard Worker #include <string.h>
14*324bb76bSAndroid Build Coastguard Worker
15*324bb76bSAndroid Build Coastguard Worker #include "getarg.h"
16*324bb76bSAndroid Build Coastguard Worker #include "gif_lib.h"
17*324bb76bSAndroid Build Coastguard Worker
18*324bb76bSAndroid Build Coastguard Worker #define PROGRAM_NAME "gifbuild"
19*324bb76bSAndroid Build Coastguard Worker
20*324bb76bSAndroid Build Coastguard Worker static char *VersionStr = PROGRAM_NAME VERSION_COOKIE
21*324bb76bSAndroid Build Coastguard Worker " Eric Raymond, " __DATE__ ", " __TIME__ "\n"
22*324bb76bSAndroid Build Coastguard Worker "(C) Copyright 1992 Eric Raymond.\n";
23*324bb76bSAndroid Build Coastguard Worker static char *CtrlStr =
24*324bb76bSAndroid Build Coastguard Worker PROGRAM_NAME " v%- d%- t%-Characters!s h%- GifFile(s)!*s";
25*324bb76bSAndroid Build Coastguard Worker
26*324bb76bSAndroid Build Coastguard Worker static char KeyLetters[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO"
27*324bb76bSAndroid Build Coastguard Worker "PQRSTUVWXYZ!\"#$%&'()*+,-./:<=>?@[\\]^_`{|}~";
28*324bb76bSAndroid Build Coastguard Worker #define PRINTABLES (sizeof(KeyLetters) - 1)
29*324bb76bSAndroid Build Coastguard Worker
30*324bb76bSAndroid Build Coastguard Worker static void Icon2Gif(char *FileName, FILE *txtin, bool, int fdout);
31*324bb76bSAndroid Build Coastguard Worker static void Gif2Icon(char *FileName, int fdin, int fdout, char NameTable[]);
32*324bb76bSAndroid Build Coastguard Worker static int EscapeString(char *cp, char *tp);
33*324bb76bSAndroid Build Coastguard Worker
34*324bb76bSAndroid Build Coastguard Worker /******************************************************************************
35*324bb76bSAndroid Build Coastguard Worker Main sequence
36*324bb76bSAndroid Build Coastguard Worker ******************************************************************************/
main(int argc,char ** argv)37*324bb76bSAndroid Build Coastguard Worker int main(int argc, char **argv) {
38*324bb76bSAndroid Build Coastguard Worker int NumFiles;
39*324bb76bSAndroid Build Coastguard Worker bool Error, DisasmFlag = false, HelpFlag = false, TextLineFlag = false,
40*324bb76bSAndroid Build Coastguard Worker GifNoisyPrint = false;
41*324bb76bSAndroid Build Coastguard Worker char **FileNames = NULL;
42*324bb76bSAndroid Build Coastguard Worker char *TextLines[1];
43*324bb76bSAndroid Build Coastguard Worker
44*324bb76bSAndroid Build Coastguard Worker if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifNoisyPrint, &DisasmFlag,
45*324bb76bSAndroid Build Coastguard Worker &TextLineFlag, &TextLines[0], &HelpFlag,
46*324bb76bSAndroid Build Coastguard Worker &NumFiles, &FileNames)) != false) {
47*324bb76bSAndroid Build Coastguard Worker GAPrintErrMsg(Error);
48*324bb76bSAndroid Build Coastguard Worker GAPrintHowTo(CtrlStr);
49*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
50*324bb76bSAndroid Build Coastguard Worker }
51*324bb76bSAndroid Build Coastguard Worker
52*324bb76bSAndroid Build Coastguard Worker if (HelpFlag) {
53*324bb76bSAndroid Build Coastguard Worker (void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR);
54*324bb76bSAndroid Build Coastguard Worker GAPrintHowTo(CtrlStr);
55*324bb76bSAndroid Build Coastguard Worker exit(EXIT_SUCCESS);
56*324bb76bSAndroid Build Coastguard Worker }
57*324bb76bSAndroid Build Coastguard Worker
58*324bb76bSAndroid Build Coastguard Worker if (!DisasmFlag && NumFiles > 1) {
59*324bb76bSAndroid Build Coastguard Worker GIF_MESSAGE(
60*324bb76bSAndroid Build Coastguard Worker "Error in command line parsing - one text input please.");
61*324bb76bSAndroid Build Coastguard Worker GAPrintHowTo(CtrlStr);
62*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
63*324bb76bSAndroid Build Coastguard Worker }
64*324bb76bSAndroid Build Coastguard Worker
65*324bb76bSAndroid Build Coastguard Worker if (!DisasmFlag && TextLineFlag) {
66*324bb76bSAndroid Build Coastguard Worker GIF_MESSAGE(
67*324bb76bSAndroid Build Coastguard Worker "Error in command line parsing - -t invalid without -d.");
68*324bb76bSAndroid Build Coastguard Worker GAPrintHowTo(CtrlStr);
69*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
70*324bb76bSAndroid Build Coastguard Worker }
71*324bb76bSAndroid Build Coastguard Worker
72*324bb76bSAndroid Build Coastguard Worker if (NumFiles == 0) {
73*324bb76bSAndroid Build Coastguard Worker if (DisasmFlag)
74*324bb76bSAndroid Build Coastguard Worker Gif2Icon("Stdin", 0, 1,
75*324bb76bSAndroid Build Coastguard Worker TextLineFlag ? TextLines[0] : KeyLetters);
76*324bb76bSAndroid Build Coastguard Worker else
77*324bb76bSAndroid Build Coastguard Worker Icon2Gif("Stdin", stdin, GifNoisyPrint, 1);
78*324bb76bSAndroid Build Coastguard Worker } else {
79*324bb76bSAndroid Build Coastguard Worker int i;
80*324bb76bSAndroid Build Coastguard Worker for (i = 0; i < NumFiles; i++) {
81*324bb76bSAndroid Build Coastguard Worker FILE *fp;
82*324bb76bSAndroid Build Coastguard Worker
83*324bb76bSAndroid Build Coastguard Worker if ((fp = fopen(FileNames[i], "r")) == (FILE *)NULL) {
84*324bb76bSAndroid Build Coastguard Worker (void)fprintf(stderr, "Can't open %s\n",
85*324bb76bSAndroid Build Coastguard Worker FileNames[i]);
86*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
87*324bb76bSAndroid Build Coastguard Worker }
88*324bb76bSAndroid Build Coastguard Worker
89*324bb76bSAndroid Build Coastguard Worker if (DisasmFlag) {
90*324bb76bSAndroid Build Coastguard Worker printf("#\n# GIF information from %s\n",
91*324bb76bSAndroid Build Coastguard Worker FileNames[i]);
92*324bb76bSAndroid Build Coastguard Worker Gif2Icon(FileNames[i], -1, 1,
93*324bb76bSAndroid Build Coastguard Worker TextLineFlag ? TextLines[0]
94*324bb76bSAndroid Build Coastguard Worker : KeyLetters);
95*324bb76bSAndroid Build Coastguard Worker } else {
96*324bb76bSAndroid Build Coastguard Worker Icon2Gif(FileNames[i], fp, GifNoisyPrint, 1);
97*324bb76bSAndroid Build Coastguard Worker }
98*324bb76bSAndroid Build Coastguard Worker
99*324bb76bSAndroid Build Coastguard Worker (void)fclose(fp);
100*324bb76bSAndroid Build Coastguard Worker }
101*324bb76bSAndroid Build Coastguard Worker }
102*324bb76bSAndroid Build Coastguard Worker
103*324bb76bSAndroid Build Coastguard Worker return 0;
104*324bb76bSAndroid Build Coastguard Worker }
105*324bb76bSAndroid Build Coastguard Worker
106*324bb76bSAndroid Build Coastguard Worker /******************************************************************************
107*324bb76bSAndroid Build Coastguard Worker Parse image directives
108*324bb76bSAndroid Build Coastguard Worker ******************************************************************************/
109*324bb76bSAndroid Build Coastguard Worker #define PARSE_ERROR(str) \
110*324bb76bSAndroid Build Coastguard Worker (void)fprintf(stderr, "%s:%d: %s\n", FileName, LineNum, str);
111*324bb76bSAndroid Build Coastguard Worker
Icon2Gif(char * FileName,FILE * txtin,bool GifNoisyPrint,int fdout)112*324bb76bSAndroid Build Coastguard Worker static void Icon2Gif(char *FileName, FILE *txtin, bool GifNoisyPrint,
113*324bb76bSAndroid Build Coastguard Worker int fdout) {
114*324bb76bSAndroid Build Coastguard Worker unsigned int ColorMapSize = 0;
115*324bb76bSAndroid Build Coastguard Worker GifColorType GlobalColorMap[256], LocalColorMap[256],
116*324bb76bSAndroid Build Coastguard Worker *ColorMap = GlobalColorMap;
117*324bb76bSAndroid Build Coastguard Worker char GlobalColorKeys[PRINTABLES], LocalColorKeys[PRINTABLES],
118*324bb76bSAndroid Build Coastguard Worker *KeyTable = GlobalColorKeys;
119*324bb76bSAndroid Build Coastguard Worker bool SortFlag = false;
120*324bb76bSAndroid Build Coastguard Worker unsigned int ExtCode, intval;
121*324bb76bSAndroid Build Coastguard Worker int red, green, blue, n;
122*324bb76bSAndroid Build Coastguard Worker char buf[BUFSIZ * 2], InclusionFile[64];
123*324bb76bSAndroid Build Coastguard Worker GifFileType *GifFileOut;
124*324bb76bSAndroid Build Coastguard Worker SavedImage *NewImage = NULL;
125*324bb76bSAndroid Build Coastguard Worker int LeadingExtensionBlockCount = 0;
126*324bb76bSAndroid Build Coastguard Worker ExtensionBlock *LeadingExtensionBlocks = NULL;
127*324bb76bSAndroid Build Coastguard Worker int ErrorCode, LineNum = 0;
128*324bb76bSAndroid Build Coastguard Worker
129*324bb76bSAndroid Build Coastguard Worker if ((GifFileOut = EGifOpenFileHandle(fdout, &ErrorCode)) == NULL) {
130*324bb76bSAndroid Build Coastguard Worker PrintGifError(ErrorCode);
131*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
132*324bb76bSAndroid Build Coastguard Worker }
133*324bb76bSAndroid Build Coastguard Worker
134*324bb76bSAndroid Build Coastguard Worker /* OK, interpret directives */
135*324bb76bSAndroid Build Coastguard Worker /* coverity[tainted_data_transitive] */
136*324bb76bSAndroid Build Coastguard Worker while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) {
137*324bb76bSAndroid Build Coastguard Worker char *cp;
138*324bb76bSAndroid Build Coastguard Worker
139*324bb76bSAndroid Build Coastguard Worker ++LineNum;
140*324bb76bSAndroid Build Coastguard Worker
141*324bb76bSAndroid Build Coastguard Worker /*
142*324bb76bSAndroid Build Coastguard Worker * Skip lines consisting only of whitespace and comments
143*324bb76bSAndroid Build Coastguard Worker */
144*324bb76bSAndroid Build Coastguard Worker for (cp = buf; isspace((int)(*cp)); cp++) {
145*324bb76bSAndroid Build Coastguard Worker continue;
146*324bb76bSAndroid Build Coastguard Worker }
147*324bb76bSAndroid Build Coastguard Worker if (*cp == '#' || *cp == '\0') {
148*324bb76bSAndroid Build Coastguard Worker continue;
149*324bb76bSAndroid Build Coastguard Worker }
150*324bb76bSAndroid Build Coastguard Worker
151*324bb76bSAndroid Build Coastguard Worker /*
152*324bb76bSAndroid Build Coastguard Worker * If there's a trailing comment, nuke it and all preceding
153*324bb76bSAndroid Build Coastguard Worker * whitespace. But preserve the EOL.
154*324bb76bSAndroid Build Coastguard Worker */
155*324bb76bSAndroid Build Coastguard Worker if ((cp = strchr(buf, '#')) && (cp == strrchr(cp, '#'))) {
156*324bb76bSAndroid Build Coastguard Worker while (isspace((int)(*--cp))) {
157*324bb76bSAndroid Build Coastguard Worker continue;
158*324bb76bSAndroid Build Coastguard Worker }
159*324bb76bSAndroid Build Coastguard Worker *++cp = '\n';
160*324bb76bSAndroid Build Coastguard Worker *++cp = '\0';
161*324bb76bSAndroid Build Coastguard Worker }
162*324bb76bSAndroid Build Coastguard Worker
163*324bb76bSAndroid Build Coastguard Worker /*
164*324bb76bSAndroid Build Coastguard Worker * Explicit header declarations
165*324bb76bSAndroid Build Coastguard Worker */
166*324bb76bSAndroid Build Coastguard Worker
167*324bb76bSAndroid Build Coastguard Worker if (sscanf(buf, "screen width %d\n", &GifFileOut->SWidth) ==
168*324bb76bSAndroid Build Coastguard Worker 1) {
169*324bb76bSAndroid Build Coastguard Worker continue;
170*324bb76bSAndroid Build Coastguard Worker }
171*324bb76bSAndroid Build Coastguard Worker
172*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, "screen height %d\n",
173*324bb76bSAndroid Build Coastguard Worker &GifFileOut->SHeight) == 1) {
174*324bb76bSAndroid Build Coastguard Worker continue;
175*324bb76bSAndroid Build Coastguard Worker }
176*324bb76bSAndroid Build Coastguard Worker
177*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, "screen colors %d\n", &n) == 1) {
178*324bb76bSAndroid Build Coastguard Worker int ResBits = GifBitSize(n);
179*324bb76bSAndroid Build Coastguard Worker
180*324bb76bSAndroid Build Coastguard Worker if (n > 256 || n < 0 || n != (1 << ResBits)) {
181*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Invalid color resolution value.");
182*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
183*324bb76bSAndroid Build Coastguard Worker }
184*324bb76bSAndroid Build Coastguard Worker
185*324bb76bSAndroid Build Coastguard Worker GifFileOut->SColorResolution = ResBits;
186*324bb76bSAndroid Build Coastguard Worker continue;
187*324bb76bSAndroid Build Coastguard Worker }
188*324bb76bSAndroid Build Coastguard Worker
189*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, "screen background %d\n",
190*324bb76bSAndroid Build Coastguard Worker &GifFileOut->SBackGroundColor) == 1) {
191*324bb76bSAndroid Build Coastguard Worker continue;
192*324bb76bSAndroid Build Coastguard Worker }
193*324bb76bSAndroid Build Coastguard Worker
194*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, "pixel aspect byte %u\n", &intval) == 1) {
195*324bb76bSAndroid Build Coastguard Worker GifFileOut->AspectByte = (GifByteType)(intval & 0xff);
196*324bb76bSAndroid Build Coastguard Worker continue;
197*324bb76bSAndroid Build Coastguard Worker }
198*324bb76bSAndroid Build Coastguard Worker
199*324bb76bSAndroid Build Coastguard Worker /*
200*324bb76bSAndroid Build Coastguard Worker * Color table parsing
201*324bb76bSAndroid Build Coastguard Worker */
202*324bb76bSAndroid Build Coastguard Worker
203*324bb76bSAndroid Build Coastguard Worker else if (strcmp(buf, "screen map\n") == 0) {
204*324bb76bSAndroid Build Coastguard Worker if (GifFileOut->SColorMap != NULL) {
205*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("You've already declared a global "
206*324bb76bSAndroid Build Coastguard Worker "color map.");
207*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
208*324bb76bSAndroid Build Coastguard Worker }
209*324bb76bSAndroid Build Coastguard Worker
210*324bb76bSAndroid Build Coastguard Worker ColorMapSize = 0;
211*324bb76bSAndroid Build Coastguard Worker ColorMap = GlobalColorMap;
212*324bb76bSAndroid Build Coastguard Worker SortFlag = false;
213*324bb76bSAndroid Build Coastguard Worker KeyTable = GlobalColorKeys;
214*324bb76bSAndroid Build Coastguard Worker memset(GlobalColorKeys, '\0', sizeof(GlobalColorKeys));
215*324bb76bSAndroid Build Coastguard Worker }
216*324bb76bSAndroid Build Coastguard Worker
217*324bb76bSAndroid Build Coastguard Worker else if (strcmp(buf, "image map\n") == 0) {
218*324bb76bSAndroid Build Coastguard Worker if (NewImage == NULL) {
219*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("No previous image declaration.");
220*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
221*324bb76bSAndroid Build Coastguard Worker }
222*324bb76bSAndroid Build Coastguard Worker
223*324bb76bSAndroid Build Coastguard Worker ColorMapSize = 0;
224*324bb76bSAndroid Build Coastguard Worker ColorMap = LocalColorMap;
225*324bb76bSAndroid Build Coastguard Worker KeyTable = LocalColorKeys;
226*324bb76bSAndroid Build Coastguard Worker memset(LocalColorKeys, '\0', sizeof(LocalColorKeys));
227*324bb76bSAndroid Build Coastguard Worker }
228*324bb76bSAndroid Build Coastguard Worker
229*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, " rgb %d %d %d is %c", &red, &green,
230*324bb76bSAndroid Build Coastguard Worker &blue, &KeyTable[ColorMapSize]) == 4) {
231*324bb76bSAndroid Build Coastguard Worker if (ColorMapSize >= 256) {
232*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Too many color entries.");
233*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
234*324bb76bSAndroid Build Coastguard Worker }
235*324bb76bSAndroid Build Coastguard Worker ColorMap[ColorMapSize].Red = red;
236*324bb76bSAndroid Build Coastguard Worker ColorMap[ColorMapSize].Green = green;
237*324bb76bSAndroid Build Coastguard Worker ColorMap[ColorMapSize].Blue = blue;
238*324bb76bSAndroid Build Coastguard Worker ColorMapSize++;
239*324bb76bSAndroid Build Coastguard Worker }
240*324bb76bSAndroid Build Coastguard Worker
241*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, " rgb %d %d %d", &red, &green, &blue) ==
242*324bb76bSAndroid Build Coastguard Worker 3) {
243*324bb76bSAndroid Build Coastguard Worker if (ColorMapSize >= 256) {
244*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Too many color entries.");
245*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
246*324bb76bSAndroid Build Coastguard Worker }
247*324bb76bSAndroid Build Coastguard Worker ColorMap[ColorMapSize].Red = red;
248*324bb76bSAndroid Build Coastguard Worker ColorMap[ColorMapSize].Green = green;
249*324bb76bSAndroid Build Coastguard Worker ColorMap[ColorMapSize].Blue = blue;
250*324bb76bSAndroid Build Coastguard Worker ColorMapSize++;
251*324bb76bSAndroid Build Coastguard Worker }
252*324bb76bSAndroid Build Coastguard Worker
253*324bb76bSAndroid Build Coastguard Worker else if (strcmp(buf, " sort flag on\n") == 0) {
254*324bb76bSAndroid Build Coastguard Worker SortFlag = true;
255*324bb76bSAndroid Build Coastguard Worker }
256*324bb76bSAndroid Build Coastguard Worker
257*324bb76bSAndroid Build Coastguard Worker else if (strcmp(buf, " sort flag off\n") == 0) {
258*324bb76bSAndroid Build Coastguard Worker SortFlag = false;
259*324bb76bSAndroid Build Coastguard Worker }
260*324bb76bSAndroid Build Coastguard Worker
261*324bb76bSAndroid Build Coastguard Worker else if (strcmp(buf, "end\n") == 0) {
262*324bb76bSAndroid Build Coastguard Worker ColorMapObject *NewMap;
263*324bb76bSAndroid Build Coastguard Worker
264*324bb76bSAndroid Build Coastguard Worker NewMap = GifMakeMapObject(1 << GifBitSize(ColorMapSize),
265*324bb76bSAndroid Build Coastguard Worker ColorMap);
266*324bb76bSAndroid Build Coastguard Worker if (NewMap == (ColorMapObject *)NULL) {
267*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Out of memory while allocating "
268*324bb76bSAndroid Build Coastguard Worker "new color map.");
269*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
270*324bb76bSAndroid Build Coastguard Worker }
271*324bb76bSAndroid Build Coastguard Worker
272*324bb76bSAndroid Build Coastguard Worker NewMap->SortFlag = SortFlag;
273*324bb76bSAndroid Build Coastguard Worker
274*324bb76bSAndroid Build Coastguard Worker if (NewImage) {
275*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.ColorMap = NewMap;
276*324bb76bSAndroid Build Coastguard Worker } else {
277*324bb76bSAndroid Build Coastguard Worker GifFileOut->SColorMap = NewMap;
278*324bb76bSAndroid Build Coastguard Worker }
279*324bb76bSAndroid Build Coastguard Worker }
280*324bb76bSAndroid Build Coastguard Worker
281*324bb76bSAndroid Build Coastguard Worker /* GIF inclusion */
282*324bb76bSAndroid Build Coastguard Worker /* ugly magic number is because scanf has no */
283*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, "include %63s", InclusionFile) == 1) {
284*324bb76bSAndroid Build Coastguard Worker bool DoTranslation;
285*324bb76bSAndroid Build Coastguard Worker GifPixelType Translation[256];
286*324bb76bSAndroid Build Coastguard Worker
287*324bb76bSAndroid Build Coastguard Worker GifFileType *Inclusion;
288*324bb76bSAndroid Build Coastguard Worker SavedImage *CopyFrom;
289*324bb76bSAndroid Build Coastguard Worker
290*324bb76bSAndroid Build Coastguard Worker if ((Inclusion = DGifOpenFileName(
291*324bb76bSAndroid Build Coastguard Worker InclusionFile, &ErrorCode)) == NULL) {
292*324bb76bSAndroid Build Coastguard Worker PrintGifError(ErrorCode);
293*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
294*324bb76bSAndroid Build Coastguard Worker }
295*324bb76bSAndroid Build Coastguard Worker
296*324bb76bSAndroid Build Coastguard Worker if (DGifSlurp(Inclusion) == GIF_ERROR) {
297*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Inclusion read failed.");
298*324bb76bSAndroid Build Coastguard Worker // cppcheck-suppress knownConditionTrueFalse
299*324bb76bSAndroid Build Coastguard Worker if (Inclusion != NULL) {
300*324bb76bSAndroid Build Coastguard Worker PrintGifError(Inclusion->Error);
301*324bb76bSAndroid Build Coastguard Worker DGifCloseFile(Inclusion, NULL);
302*324bb76bSAndroid Build Coastguard Worker }
303*324bb76bSAndroid Build Coastguard Worker if (GifFileOut != NULL) {
304*324bb76bSAndroid Build Coastguard Worker EGifCloseFile(GifFileOut, NULL);
305*324bb76bSAndroid Build Coastguard Worker };
306*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
307*324bb76bSAndroid Build Coastguard Worker }
308*324bb76bSAndroid Build Coastguard Worker
309*324bb76bSAndroid Build Coastguard Worker // cppcheck-suppress nullPointerRedundantCheck
310*324bb76bSAndroid Build Coastguard Worker if ((DoTranslation = (GifFileOut->SColorMap !=
311*324bb76bSAndroid Build Coastguard Worker (ColorMapObject *)NULL))) {
312*324bb76bSAndroid Build Coastguard Worker ColorMapObject *UnionMap;
313*324bb76bSAndroid Build Coastguard Worker
314*324bb76bSAndroid Build Coastguard Worker UnionMap = GifUnionColorMap(
315*324bb76bSAndroid Build Coastguard Worker // cppcheck-suppress nullPointerRedundantCheck
316*324bb76bSAndroid Build Coastguard Worker GifFileOut->SColorMap, Inclusion->SColorMap,
317*324bb76bSAndroid Build Coastguard Worker Translation);
318*324bb76bSAndroid Build Coastguard Worker
319*324bb76bSAndroid Build Coastguard Worker if (UnionMap == NULL) {
320*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Inclusion failed --- "
321*324bb76bSAndroid Build Coastguard Worker "global map conflict.");
322*324bb76bSAndroid Build Coastguard Worker // cppcheck-suppress nullPointerRedundantCheck
323*324bb76bSAndroid Build Coastguard Worker PrintGifError(GifFileOut->Error);
324*324bb76bSAndroid Build Coastguard Worker // cppcheck-suppress knownConditionTrueFalse
325*324bb76bSAndroid Build Coastguard Worker if (Inclusion != NULL) {
326*324bb76bSAndroid Build Coastguard Worker DGifCloseFile(Inclusion, NULL);
327*324bb76bSAndroid Build Coastguard Worker }
328*324bb76bSAndroid Build Coastguard Worker if (GifFileOut != NULL) {
329*324bb76bSAndroid Build Coastguard Worker EGifCloseFile(GifFileOut, NULL);
330*324bb76bSAndroid Build Coastguard Worker }
331*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
332*324bb76bSAndroid Build Coastguard Worker }
333*324bb76bSAndroid Build Coastguard Worker
334*324bb76bSAndroid Build Coastguard Worker GifFreeMapObject(GifFileOut->SColorMap);
335*324bb76bSAndroid Build Coastguard Worker GifFileOut->SColorMap = UnionMap;
336*324bb76bSAndroid Build Coastguard Worker }
337*324bb76bSAndroid Build Coastguard Worker
338*324bb76bSAndroid Build Coastguard Worker for (CopyFrom = Inclusion->SavedImages;
339*324bb76bSAndroid Build Coastguard Worker CopyFrom <
340*324bb76bSAndroid Build Coastguard Worker Inclusion->SavedImages + Inclusion->ImageCount;
341*324bb76bSAndroid Build Coastguard Worker CopyFrom++) {
342*324bb76bSAndroid Build Coastguard Worker if ((NewImage = GifMakeSavedImage(
343*324bb76bSAndroid Build Coastguard Worker GifFileOut, CopyFrom)) == NULL) {
344*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Inclusion failed --- out "
345*324bb76bSAndroid Build Coastguard Worker "of memory.");
346*324bb76bSAndroid Build Coastguard Worker // cppcheck-suppress nullPointerRedundantCheck
347*324bb76bSAndroid Build Coastguard Worker PrintGifError(GifFileOut->Error);
348*324bb76bSAndroid Build Coastguard Worker // cppcheck-suppress knownConditionTrueFalse
349*324bb76bSAndroid Build Coastguard Worker if (Inclusion != NULL) {
350*324bb76bSAndroid Build Coastguard Worker DGifCloseFile(Inclusion, NULL);
351*324bb76bSAndroid Build Coastguard Worker }
352*324bb76bSAndroid Build Coastguard Worker if (GifFileOut != NULL) {
353*324bb76bSAndroid Build Coastguard Worker EGifCloseFile(GifFileOut, NULL);
354*324bb76bSAndroid Build Coastguard Worker }
355*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
356*324bb76bSAndroid Build Coastguard Worker } else if (DoTranslation) {
357*324bb76bSAndroid Build Coastguard Worker GifApplyTranslation(NewImage,
358*324bb76bSAndroid Build Coastguard Worker Translation);
359*324bb76bSAndroid Build Coastguard Worker }
360*324bb76bSAndroid Build Coastguard Worker
361*324bb76bSAndroid Build Coastguard Worker GifQprintf("%s: Image %d at (%d, %d) [%dx%d]: "
362*324bb76bSAndroid Build Coastguard Worker "from %s\n",
363*324bb76bSAndroid Build Coastguard Worker PROGRAM_NAME, GifFileOut->ImageCount,
364*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Left,
365*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Top,
366*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Width,
367*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Height,
368*324bb76bSAndroid Build Coastguard Worker InclusionFile);
369*324bb76bSAndroid Build Coastguard Worker }
370*324bb76bSAndroid Build Coastguard Worker
371*324bb76bSAndroid Build Coastguard Worker (void)DGifCloseFile(Inclusion, NULL);
372*324bb76bSAndroid Build Coastguard Worker }
373*324bb76bSAndroid Build Coastguard Worker
374*324bb76bSAndroid Build Coastguard Worker /*
375*324bb76bSAndroid Build Coastguard Worker * Extension blocks.
376*324bb76bSAndroid Build Coastguard Worker */
377*324bb76bSAndroid Build Coastguard Worker else if (strcmp(buf, "comment\n") == 0) {
378*324bb76bSAndroid Build Coastguard Worker int bc = 0;
379*324bb76bSAndroid Build Coastguard Worker while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) {
380*324bb76bSAndroid Build Coastguard Worker if (strcmp(buf, "end\n") == 0) {
381*324bb76bSAndroid Build Coastguard Worker break;
382*324bb76bSAndroid Build Coastguard Worker } else {
383*324bb76bSAndroid Build Coastguard Worker int Len;
384*324bb76bSAndroid Build Coastguard Worker
385*324bb76bSAndroid Build Coastguard Worker buf[strlen(buf) - 1] = '\0';
386*324bb76bSAndroid Build Coastguard Worker Len = EscapeString(buf, buf);
387*324bb76bSAndroid Build Coastguard Worker if (GifAddExtensionBlock(
388*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlockCount,
389*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlocks,
390*324bb76bSAndroid Build Coastguard Worker bc++ == CONTINUE_EXT_FUNC_CODE
391*324bb76bSAndroid Build Coastguard Worker ? COMMENT_EXT_FUNC_CODE
392*324bb76bSAndroid Build Coastguard Worker : 0,
393*324bb76bSAndroid Build Coastguard Worker Len, (unsigned char *)buf) ==
394*324bb76bSAndroid Build Coastguard Worker GIF_ERROR) {
395*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR(
396*324bb76bSAndroid Build Coastguard Worker "out of memory while "
397*324bb76bSAndroid Build Coastguard Worker "adding comment block.");
398*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
399*324bb76bSAndroid Build Coastguard Worker }
400*324bb76bSAndroid Build Coastguard Worker }
401*324bb76bSAndroid Build Coastguard Worker }
402*324bb76bSAndroid Build Coastguard Worker } else if (strcmp(buf, "plaintext\n") == 0) {
403*324bb76bSAndroid Build Coastguard Worker int bc = 0;
404*324bb76bSAndroid Build Coastguard Worker while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) {
405*324bb76bSAndroid Build Coastguard Worker if (strcmp(buf, "end\n") == 0) {
406*324bb76bSAndroid Build Coastguard Worker break;
407*324bb76bSAndroid Build Coastguard Worker } else {
408*324bb76bSAndroid Build Coastguard Worker int Len;
409*324bb76bSAndroid Build Coastguard Worker
410*324bb76bSAndroid Build Coastguard Worker buf[strlen(buf) - 1] = '\0';
411*324bb76bSAndroid Build Coastguard Worker Len = EscapeString(buf, buf);
412*324bb76bSAndroid Build Coastguard Worker if (GifAddExtensionBlock(
413*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlockCount,
414*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlocks,
415*324bb76bSAndroid Build Coastguard Worker bc++ == CONTINUE_EXT_FUNC_CODE
416*324bb76bSAndroid Build Coastguard Worker ? PLAINTEXT_EXT_FUNC_CODE
417*324bb76bSAndroid Build Coastguard Worker : 0,
418*324bb76bSAndroid Build Coastguard Worker Len, (unsigned char *)buf) ==
419*324bb76bSAndroid Build Coastguard Worker GIF_ERROR) {
420*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR(
421*324bb76bSAndroid Build Coastguard Worker "out of memory while "
422*324bb76bSAndroid Build Coastguard Worker "adding plaintext block.");
423*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
424*324bb76bSAndroid Build Coastguard Worker }
425*324bb76bSAndroid Build Coastguard Worker }
426*324bb76bSAndroid Build Coastguard Worker }
427*324bb76bSAndroid Build Coastguard Worker } else if (strcmp(buf, "graphics control\n") == 0) {
428*324bb76bSAndroid Build Coastguard Worker GraphicsControlBlock gcb;
429*324bb76bSAndroid Build Coastguard Worker size_t Len;
430*324bb76bSAndroid Build Coastguard Worker
431*324bb76bSAndroid Build Coastguard Worker memset(&gcb, '\0', sizeof(gcb));
432*324bb76bSAndroid Build Coastguard Worker gcb.TransparentColor = NO_TRANSPARENT_COLOR;
433*324bb76bSAndroid Build Coastguard Worker while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) {
434*324bb76bSAndroid Build Coastguard Worker if (strcmp(buf, "end\n") == 0) {
435*324bb76bSAndroid Build Coastguard Worker break;
436*324bb76bSAndroid Build Coastguard Worker } else {
437*324bb76bSAndroid Build Coastguard Worker char *tp = buf;
438*324bb76bSAndroid Build Coastguard Worker
439*324bb76bSAndroid Build Coastguard Worker while (isspace(*tp)) {
440*324bb76bSAndroid Build Coastguard Worker tp++;
441*324bb76bSAndroid Build Coastguard Worker }
442*324bb76bSAndroid Build Coastguard Worker if (sscanf(tp, "disposal mode %d\n",
443*324bb76bSAndroid Build Coastguard Worker &gcb.DisposalMode)) {
444*324bb76bSAndroid Build Coastguard Worker continue;
445*324bb76bSAndroid Build Coastguard Worker }
446*324bb76bSAndroid Build Coastguard Worker if (strcmp(tp,
447*324bb76bSAndroid Build Coastguard Worker "user input flag on\n") ==
448*324bb76bSAndroid Build Coastguard Worker 0) {
449*324bb76bSAndroid Build Coastguard Worker gcb.UserInputFlag = true;
450*324bb76bSAndroid Build Coastguard Worker continue;
451*324bb76bSAndroid Build Coastguard Worker }
452*324bb76bSAndroid Build Coastguard Worker if (strcmp(tp,
453*324bb76bSAndroid Build Coastguard Worker "user input flag off\n") ==
454*324bb76bSAndroid Build Coastguard Worker 0) {
455*324bb76bSAndroid Build Coastguard Worker gcb.UserInputFlag = false;
456*324bb76bSAndroid Build Coastguard Worker continue;
457*324bb76bSAndroid Build Coastguard Worker }
458*324bb76bSAndroid Build Coastguard Worker if (sscanf(tp, "delay %d\n",
459*324bb76bSAndroid Build Coastguard Worker &gcb.DelayTime)) {
460*324bb76bSAndroid Build Coastguard Worker continue;
461*324bb76bSAndroid Build Coastguard Worker }
462*324bb76bSAndroid Build Coastguard Worker if (sscanf(tp, "transparent index %d\n",
463*324bb76bSAndroid Build Coastguard Worker &gcb.TransparentColor)) {
464*324bb76bSAndroid Build Coastguard Worker continue;
465*324bb76bSAndroid Build Coastguard Worker }
466*324bb76bSAndroid Build Coastguard Worker (void)fputs(tp, stderr);
467*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("unrecognized directive in "
468*324bb76bSAndroid Build Coastguard Worker "GCB block.");
469*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
470*324bb76bSAndroid Build Coastguard Worker }
471*324bb76bSAndroid Build Coastguard Worker }
472*324bb76bSAndroid Build Coastguard Worker Len = EGifGCBToExtension(&gcb, (GifByteType *)buf);
473*324bb76bSAndroid Build Coastguard Worker if (GifAddExtensionBlock(
474*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlockCount,
475*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlocks, GRAPHICS_EXT_FUNC_CODE,
476*324bb76bSAndroid Build Coastguard Worker Len, (unsigned char *)buf) == GIF_ERROR) {
477*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("out of memory while adding GCB.");
478*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
479*324bb76bSAndroid Build Coastguard Worker }
480*324bb76bSAndroid Build Coastguard Worker
481*324bb76bSAndroid Build Coastguard Worker } else if (sscanf(buf, "netscape loop %u", &intval)) {
482*324bb76bSAndroid Build Coastguard Worker unsigned char params[3] = {1, 0, 0};
483*324bb76bSAndroid Build Coastguard Worker /* Create a Netscape 2.0 loop block */
484*324bb76bSAndroid Build Coastguard Worker if (GifAddExtensionBlock(
485*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlockCount,
486*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlocks,
487*324bb76bSAndroid Build Coastguard Worker APPLICATION_EXT_FUNC_CODE, 11,
488*324bb76bSAndroid Build Coastguard Worker (unsigned char *)"NETSCAPE2.0") == GIF_ERROR) {
489*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR(
490*324bb76bSAndroid Build Coastguard Worker "out of memory while adding loop block.");
491*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
492*324bb76bSAndroid Build Coastguard Worker }
493*324bb76bSAndroid Build Coastguard Worker params[1] = (intval & 0xff);
494*324bb76bSAndroid Build Coastguard Worker params[2] = (intval >> 8) & 0xff;
495*324bb76bSAndroid Build Coastguard Worker if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
496*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlocks, 0,
497*324bb76bSAndroid Build Coastguard Worker sizeof(params),
498*324bb76bSAndroid Build Coastguard Worker params) == GIF_ERROR) {
499*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("out of memory while adding loop "
500*324bb76bSAndroid Build Coastguard Worker "continuation.");
501*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
502*324bb76bSAndroid Build Coastguard Worker }
503*324bb76bSAndroid Build Coastguard Worker
504*324bb76bSAndroid Build Coastguard Worker } else if (sscanf(buf, "extension %x", &ExtCode)) {
505*324bb76bSAndroid Build Coastguard Worker int bc = 0;
506*324bb76bSAndroid Build Coastguard Worker while (fgets(buf, sizeof(buf), txtin) != (char *)NULL) {
507*324bb76bSAndroid Build Coastguard Worker if (strcmp(buf, "end\n") == 0) {
508*324bb76bSAndroid Build Coastguard Worker break;
509*324bb76bSAndroid Build Coastguard Worker } else {
510*324bb76bSAndroid Build Coastguard Worker int Len;
511*324bb76bSAndroid Build Coastguard Worker
512*324bb76bSAndroid Build Coastguard Worker buf[strlen(buf) - 1] = '\0';
513*324bb76bSAndroid Build Coastguard Worker Len = EscapeString(buf, buf);
514*324bb76bSAndroid Build Coastguard Worker if (GifAddExtensionBlock(
515*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlockCount,
516*324bb76bSAndroid Build Coastguard Worker &LeadingExtensionBlocks,
517*324bb76bSAndroid Build Coastguard Worker bc++ == CONTINUE_EXT_FUNC_CODE
518*324bb76bSAndroid Build Coastguard Worker ? ExtCode
519*324bb76bSAndroid Build Coastguard Worker : 0,
520*324bb76bSAndroid Build Coastguard Worker Len, (unsigned char *)buf) ==
521*324bb76bSAndroid Build Coastguard Worker GIF_ERROR) {
522*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR(
523*324bb76bSAndroid Build Coastguard Worker "out of memory while "
524*324bb76bSAndroid Build Coastguard Worker "adding extension block.");
525*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
526*324bb76bSAndroid Build Coastguard Worker }
527*324bb76bSAndroid Build Coastguard Worker }
528*324bb76bSAndroid Build Coastguard Worker }
529*324bb76bSAndroid Build Coastguard Worker }
530*324bb76bSAndroid Build Coastguard Worker
531*324bb76bSAndroid Build Coastguard Worker /*
532*324bb76bSAndroid Build Coastguard Worker * Explicit image declarations
533*324bb76bSAndroid Build Coastguard Worker */
534*324bb76bSAndroid Build Coastguard Worker
535*324bb76bSAndroid Build Coastguard Worker else if (strcmp(buf, "image\n") == 0) {
536*324bb76bSAndroid Build Coastguard Worker if ((NewImage = GifMakeSavedImage(GifFileOut, NULL)) ==
537*324bb76bSAndroid Build Coastguard Worker (SavedImage *)NULL) {
538*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Out of memory while allocating "
539*324bb76bSAndroid Build Coastguard Worker "image block.");
540*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
541*324bb76bSAndroid Build Coastguard Worker }
542*324bb76bSAndroid Build Coastguard Worker
543*324bb76bSAndroid Build Coastguard Worker /* use global table unless user specifies a local one */
544*324bb76bSAndroid Build Coastguard Worker ColorMap = GlobalColorMap;
545*324bb76bSAndroid Build Coastguard Worker KeyTable = GlobalColorKeys;
546*324bb76bSAndroid Build Coastguard Worker
547*324bb76bSAndroid Build Coastguard Worker /* connect leading extension blocks */
548*324bb76bSAndroid Build Coastguard Worker NewImage->ExtensionBlockCount =
549*324bb76bSAndroid Build Coastguard Worker LeadingExtensionBlockCount;
550*324bb76bSAndroid Build Coastguard Worker NewImage->ExtensionBlocks = LeadingExtensionBlocks;
551*324bb76bSAndroid Build Coastguard Worker LeadingExtensionBlockCount = 0;
552*324bb76bSAndroid Build Coastguard Worker LeadingExtensionBlocks = NULL;
553*324bb76bSAndroid Build Coastguard Worker }
554*324bb76bSAndroid Build Coastguard Worker
555*324bb76bSAndroid Build Coastguard Worker /*
556*324bb76bSAndroid Build Coastguard Worker * Nothing past this point is valid unless we've seen a previous
557*324bb76bSAndroid Build Coastguard Worker * image declaration.
558*324bb76bSAndroid Build Coastguard Worker */
559*324bb76bSAndroid Build Coastguard Worker else if (NewImage == (SavedImage *)NULL) {
560*324bb76bSAndroid Build Coastguard Worker (void)fputs(buf, stderr);
561*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Syntax error in header block.");
562*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
563*324bb76bSAndroid Build Coastguard Worker }
564*324bb76bSAndroid Build Coastguard Worker
565*324bb76bSAndroid Build Coastguard Worker /*
566*324bb76bSAndroid Build Coastguard Worker * Accept image attributes
567*324bb76bSAndroid Build Coastguard Worker */
568*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, "image top %d\n",
569*324bb76bSAndroid Build Coastguard Worker &NewImage->ImageDesc.Top) == 1) {
570*324bb76bSAndroid Build Coastguard Worker continue;
571*324bb76bSAndroid Build Coastguard Worker }
572*324bb76bSAndroid Build Coastguard Worker
573*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, "image left %d\n",
574*324bb76bSAndroid Build Coastguard Worker &NewImage->ImageDesc.Left) == 1) {
575*324bb76bSAndroid Build Coastguard Worker continue;
576*324bb76bSAndroid Build Coastguard Worker }
577*324bb76bSAndroid Build Coastguard Worker
578*324bb76bSAndroid Build Coastguard Worker else if (strcmp(buf, "image interlaced\n") == 0) {
579*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Interlace = true;
580*324bb76bSAndroid Build Coastguard Worker continue;
581*324bb76bSAndroid Build Coastguard Worker }
582*324bb76bSAndroid Build Coastguard Worker
583*324bb76bSAndroid Build Coastguard Worker else if (sscanf(buf, "image bits %d by %d",
584*324bb76bSAndroid Build Coastguard Worker &NewImage->ImageDesc.Width,
585*324bb76bSAndroid Build Coastguard Worker &NewImage->ImageDesc.Height) == 2) {
586*324bb76bSAndroid Build Coastguard Worker int i, j;
587*324bb76bSAndroid Build Coastguard Worker static GifPixelType *Raster;
588*324bb76bSAndroid Build Coastguard Worker int c;
589*324bb76bSAndroid Build Coastguard Worker bool hex = (strstr(buf, "hex") != NULL);
590*324bb76bSAndroid Build Coastguard Worker
591*324bb76bSAndroid Build Coastguard Worker /* coverity[overflow_sink] */
592*324bb76bSAndroid Build Coastguard Worker if ((Raster = (GifPixelType *)malloc(
593*324bb76bSAndroid Build Coastguard Worker sizeof(GifPixelType) *
594*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Width *
595*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Height)) == NULL) {
596*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Failed to allocate raster block, "
597*324bb76bSAndroid Build Coastguard Worker "aborted.");
598*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
599*324bb76bSAndroid Build Coastguard Worker }
600*324bb76bSAndroid Build Coastguard Worker
601*324bb76bSAndroid Build Coastguard Worker GifQprintf("%s: Image %d at (%d, %d) [%dx%d]: ",
602*324bb76bSAndroid Build Coastguard Worker PROGRAM_NAME, GifFileOut->ImageCount,
603*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Left,
604*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Top,
605*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Width,
606*324bb76bSAndroid Build Coastguard Worker NewImage->ImageDesc.Height);
607*324bb76bSAndroid Build Coastguard Worker
608*324bb76bSAndroid Build Coastguard Worker GifByteType *tp = Raster;
609*324bb76bSAndroid Build Coastguard Worker for (i = 0; i < NewImage->ImageDesc.Height; i++) {
610*324bb76bSAndroid Build Coastguard Worker
611*324bb76bSAndroid Build Coastguard Worker char *dp;
612*324bb76bSAndroid Build Coastguard Worker
613*324bb76bSAndroid Build Coastguard Worker for (j = 0; j < NewImage->ImageDesc.Width;
614*324bb76bSAndroid Build Coastguard Worker j++) {
615*324bb76bSAndroid Build Coastguard Worker if ((c = fgetc(txtin)) == EOF) {
616*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("input file ended "
617*324bb76bSAndroid Build Coastguard Worker "prematurely.");
618*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
619*324bb76bSAndroid Build Coastguard Worker } else if (c == '\n') {
620*324bb76bSAndroid Build Coastguard Worker --j;
621*324bb76bSAndroid Build Coastguard Worker ++LineNum;
622*324bb76bSAndroid Build Coastguard Worker } else if (isspace(c)) {
623*324bb76bSAndroid Build Coastguard Worker --j;
624*324bb76bSAndroid Build Coastguard Worker } else if (hex) {
625*324bb76bSAndroid Build Coastguard Worker const static char *hexdigits =
626*324bb76bSAndroid Build Coastguard Worker "0123456789ABCDEF";
627*324bb76bSAndroid Build Coastguard Worker unsigned char hi, lo;
628*324bb76bSAndroid Build Coastguard Worker dp = strchr(hexdigits,
629*324bb76bSAndroid Build Coastguard Worker toupper(c));
630*324bb76bSAndroid Build Coastguard Worker if (dp == NULL) {
631*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR(
632*324bb76bSAndroid Build Coastguard Worker "Invalid hex high "
633*324bb76bSAndroid Build Coastguard Worker "byte.");
634*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
635*324bb76bSAndroid Build Coastguard Worker }
636*324bb76bSAndroid Build Coastguard Worker hi = (dp - hexdigits);
637*324bb76bSAndroid Build Coastguard Worker if ((c = fgetc(txtin)) == EOF) {
638*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR(
639*324bb76bSAndroid Build Coastguard Worker "input file ended "
640*324bb76bSAndroid Build Coastguard Worker "prematurely.");
641*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
642*324bb76bSAndroid Build Coastguard Worker }
643*324bb76bSAndroid Build Coastguard Worker dp = strchr(hexdigits,
644*324bb76bSAndroid Build Coastguard Worker toupper(c));
645*324bb76bSAndroid Build Coastguard Worker if (dp == NULL) {
646*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR(
647*324bb76bSAndroid Build Coastguard Worker "Invalid hex low "
648*324bb76bSAndroid Build Coastguard Worker "byte.");
649*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
650*324bb76bSAndroid Build Coastguard Worker }
651*324bb76bSAndroid Build Coastguard Worker lo = (dp - hexdigits);
652*324bb76bSAndroid Build Coastguard Worker *tp++ = (hi << 4) | lo;
653*324bb76bSAndroid Build Coastguard Worker } else if ((dp = strchr(KeyTable, c))) {
654*324bb76bSAndroid Build Coastguard Worker *tp++ = (dp - KeyTable);
655*324bb76bSAndroid Build Coastguard Worker } else {
656*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR(
657*324bb76bSAndroid Build Coastguard Worker "Invalid ASCII pixel key.");
658*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
659*324bb76bSAndroid Build Coastguard Worker }
660*324bb76bSAndroid Build Coastguard Worker }
661*324bb76bSAndroid Build Coastguard Worker
662*324bb76bSAndroid Build Coastguard Worker if (GifNoisyPrint) {
663*324bb76bSAndroid Build Coastguard Worker fprintf(stderr, "\b\b\b\b%-4d", i);
664*324bb76bSAndroid Build Coastguard Worker }
665*324bb76bSAndroid Build Coastguard Worker }
666*324bb76bSAndroid Build Coastguard Worker
667*324bb76bSAndroid Build Coastguard Worker if (GifNoisyPrint) {
668*324bb76bSAndroid Build Coastguard Worker putc('\n', stderr);
669*324bb76bSAndroid Build Coastguard Worker }
670*324bb76bSAndroid Build Coastguard Worker
671*324bb76bSAndroid Build Coastguard Worker NewImage->RasterBits = (unsigned char *)Raster;
672*324bb76bSAndroid Build Coastguard Worker } else {
673*324bb76bSAndroid Build Coastguard Worker (void)fputs(buf, stderr);
674*324bb76bSAndroid Build Coastguard Worker PARSE_ERROR("Syntax error in image description.");
675*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
676*324bb76bSAndroid Build Coastguard Worker }
677*324bb76bSAndroid Build Coastguard Worker }
678*324bb76bSAndroid Build Coastguard Worker
679*324bb76bSAndroid Build Coastguard Worker /* connect trailing extension blocks */
680*324bb76bSAndroid Build Coastguard Worker GifFileOut->ExtensionBlockCount = LeadingExtensionBlockCount;
681*324bb76bSAndroid Build Coastguard Worker GifFileOut->ExtensionBlocks = LeadingExtensionBlocks;
682*324bb76bSAndroid Build Coastguard Worker // LeadingExtensionBlockCount = 0;
683*324bb76bSAndroid Build Coastguard Worker LeadingExtensionBlocks = NULL;
684*324bb76bSAndroid Build Coastguard Worker
685*324bb76bSAndroid Build Coastguard Worker EGifSpew(GifFileOut);
686*324bb76bSAndroid Build Coastguard Worker }
687*324bb76bSAndroid Build Coastguard Worker
VisibleDumpBuffer(GifByteType * buf,int len)688*324bb76bSAndroid Build Coastguard Worker static void VisibleDumpBuffer(GifByteType *buf, int len)
689*324bb76bSAndroid Build Coastguard Worker /* Visibilize a given string */
690*324bb76bSAndroid Build Coastguard Worker {
691*324bb76bSAndroid Build Coastguard Worker GifByteType *cp;
692*324bb76bSAndroid Build Coastguard Worker
693*324bb76bSAndroid Build Coastguard Worker for (cp = buf; cp < buf + len; cp++) {
694*324bb76bSAndroid Build Coastguard Worker if (isprint((int)(*cp)) || *cp == ' ') {
695*324bb76bSAndroid Build Coastguard Worker putchar(*cp);
696*324bb76bSAndroid Build Coastguard Worker } else if (*cp == '\n') {
697*324bb76bSAndroid Build Coastguard Worker putchar('\\');
698*324bb76bSAndroid Build Coastguard Worker putchar('n');
699*324bb76bSAndroid Build Coastguard Worker } else if (*cp == '\r') {
700*324bb76bSAndroid Build Coastguard Worker putchar('\\');
701*324bb76bSAndroid Build Coastguard Worker putchar('r');
702*324bb76bSAndroid Build Coastguard Worker } else if (*cp == '\b') {
703*324bb76bSAndroid Build Coastguard Worker putchar('\\');
704*324bb76bSAndroid Build Coastguard Worker putchar('b');
705*324bb76bSAndroid Build Coastguard Worker } else if (*cp < ' ') {
706*324bb76bSAndroid Build Coastguard Worker putchar('\\');
707*324bb76bSAndroid Build Coastguard Worker putchar('^');
708*324bb76bSAndroid Build Coastguard Worker putchar('@' + *cp);
709*324bb76bSAndroid Build Coastguard Worker } else {
710*324bb76bSAndroid Build Coastguard Worker printf("\\0x%02x", *cp);
711*324bb76bSAndroid Build Coastguard Worker }
712*324bb76bSAndroid Build Coastguard Worker }
713*324bb76bSAndroid Build Coastguard Worker }
714*324bb76bSAndroid Build Coastguard Worker
DumpExtensions(GifFileType * GifFileOut,int ExtensionBlockCount,ExtensionBlock * ExtensionBlocks)715*324bb76bSAndroid Build Coastguard Worker static void DumpExtensions(GifFileType *GifFileOut, int ExtensionBlockCount,
716*324bb76bSAndroid Build Coastguard Worker ExtensionBlock *ExtensionBlocks) {
717*324bb76bSAndroid Build Coastguard Worker ExtensionBlock *ep;
718*324bb76bSAndroid Build Coastguard Worker
719*324bb76bSAndroid Build Coastguard Worker for (ep = ExtensionBlocks; ep < ExtensionBlocks + ExtensionBlockCount;
720*324bb76bSAndroid Build Coastguard Worker ep++) {
721*324bb76bSAndroid Build Coastguard Worker bool last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
722*324bb76bSAndroid Build Coastguard Worker if (ep->Function == COMMENT_EXT_FUNC_CODE) {
723*324bb76bSAndroid Build Coastguard Worker printf("comment\n");
724*324bb76bSAndroid Build Coastguard Worker VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
725*324bb76bSAndroid Build Coastguard Worker putchar('\n');
726*324bb76bSAndroid Build Coastguard Worker while (!last &&
727*324bb76bSAndroid Build Coastguard Worker ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
728*324bb76bSAndroid Build Coastguard Worker ++ep;
729*324bb76bSAndroid Build Coastguard Worker last = (ep - ExtensionBlocks ==
730*324bb76bSAndroid Build Coastguard Worker (ExtensionBlockCount - 1));
731*324bb76bSAndroid Build Coastguard Worker VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
732*324bb76bSAndroid Build Coastguard Worker putchar('\n');
733*324bb76bSAndroid Build Coastguard Worker }
734*324bb76bSAndroid Build Coastguard Worker printf("end\n\n");
735*324bb76bSAndroid Build Coastguard Worker } else if (ep->Function == PLAINTEXT_EXT_FUNC_CODE) {
736*324bb76bSAndroid Build Coastguard Worker printf("plaintext\n");
737*324bb76bSAndroid Build Coastguard Worker VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
738*324bb76bSAndroid Build Coastguard Worker putchar('\n');
739*324bb76bSAndroid Build Coastguard Worker while (!last &&
740*324bb76bSAndroid Build Coastguard Worker ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
741*324bb76bSAndroid Build Coastguard Worker ++ep;
742*324bb76bSAndroid Build Coastguard Worker last = (ep - ExtensionBlocks ==
743*324bb76bSAndroid Build Coastguard Worker (ExtensionBlockCount - 1));
744*324bb76bSAndroid Build Coastguard Worker VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
745*324bb76bSAndroid Build Coastguard Worker putchar('\n');
746*324bb76bSAndroid Build Coastguard Worker }
747*324bb76bSAndroid Build Coastguard Worker printf("end\n\n");
748*324bb76bSAndroid Build Coastguard Worker } else if (ep->Function == GRAPHICS_EXT_FUNC_CODE) {
749*324bb76bSAndroid Build Coastguard Worker GraphicsControlBlock gcb;
750*324bb76bSAndroid Build Coastguard Worker printf("graphics control\n");
751*324bb76bSAndroid Build Coastguard Worker if (DGifExtensionToGCB(ep->ByteCount, ep->Bytes,
752*324bb76bSAndroid Build Coastguard Worker &gcb) == GIF_ERROR) {
753*324bb76bSAndroid Build Coastguard Worker GIF_MESSAGE("invalid graphics control block");
754*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
755*324bb76bSAndroid Build Coastguard Worker }
756*324bb76bSAndroid Build Coastguard Worker printf("\tdisposal mode %d\n", gcb.DisposalMode);
757*324bb76bSAndroid Build Coastguard Worker printf("\tuser input flag %s\n",
758*324bb76bSAndroid Build Coastguard Worker gcb.UserInputFlag ? "on" : "off");
759*324bb76bSAndroid Build Coastguard Worker printf("\tdelay %d\n", gcb.DelayTime);
760*324bb76bSAndroid Build Coastguard Worker printf("\ttransparent index %d\n",
761*324bb76bSAndroid Build Coastguard Worker gcb.TransparentColor);
762*324bb76bSAndroid Build Coastguard Worker printf("end\n\n");
763*324bb76bSAndroid Build Coastguard Worker } else if (!last && ep->Function == APPLICATION_EXT_FUNC_CODE &&
764*324bb76bSAndroid Build Coastguard Worker ep->ByteCount >= 11 && (ep + 1)->ByteCount >= 3 &&
765*324bb76bSAndroid Build Coastguard Worker memcmp(ep->Bytes, "NETSCAPE2.0", 11) == 0) {
766*324bb76bSAndroid Build Coastguard Worker unsigned char *params = (++ep)->Bytes;
767*324bb76bSAndroid Build Coastguard Worker unsigned int loopcount = params[1] | (params[2] << 8);
768*324bb76bSAndroid Build Coastguard Worker printf("netscape loop %u\n\n", loopcount);
769*324bb76bSAndroid Build Coastguard Worker } else {
770*324bb76bSAndroid Build Coastguard Worker printf("extension 0x%02x\n", ep->Function);
771*324bb76bSAndroid Build Coastguard Worker VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
772*324bb76bSAndroid Build Coastguard Worker while (!last &&
773*324bb76bSAndroid Build Coastguard Worker ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
774*324bb76bSAndroid Build Coastguard Worker ++ep;
775*324bb76bSAndroid Build Coastguard Worker last = (ep - ExtensionBlocks ==
776*324bb76bSAndroid Build Coastguard Worker (ExtensionBlockCount - 1));
777*324bb76bSAndroid Build Coastguard Worker VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
778*324bb76bSAndroid Build Coastguard Worker putchar('\n');
779*324bb76bSAndroid Build Coastguard Worker }
780*324bb76bSAndroid Build Coastguard Worker printf("end\n\n");
781*324bb76bSAndroid Build Coastguard Worker }
782*324bb76bSAndroid Build Coastguard Worker }
783*324bb76bSAndroid Build Coastguard Worker }
784*324bb76bSAndroid Build Coastguard Worker
Gif2Icon(char * FileName,int fdin,int fdout,char NameTable[])785*324bb76bSAndroid Build Coastguard Worker static void Gif2Icon(char *FileName, int fdin, int fdout, char NameTable[]) {
786*324bb76bSAndroid Build Coastguard Worker int ErrorCode, im, i, j, ColorCount = 0;
787*324bb76bSAndroid Build Coastguard Worker GifFileType *GifFile;
788*324bb76bSAndroid Build Coastguard Worker
789*324bb76bSAndroid Build Coastguard Worker if (fdin == -1) {
790*324bb76bSAndroid Build Coastguard Worker if ((GifFile = DGifOpenFileName(FileName, &ErrorCode)) ==
791*324bb76bSAndroid Build Coastguard Worker NULL) {
792*324bb76bSAndroid Build Coastguard Worker PrintGifError(ErrorCode);
793*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
794*324bb76bSAndroid Build Coastguard Worker }
795*324bb76bSAndroid Build Coastguard Worker } else {
796*324bb76bSAndroid Build Coastguard Worker /* Use stdin instead: */
797*324bb76bSAndroid Build Coastguard Worker if ((GifFile = DGifOpenFileHandle(fdin, &ErrorCode)) == NULL) {
798*324bb76bSAndroid Build Coastguard Worker PrintGifError(ErrorCode);
799*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
800*324bb76bSAndroid Build Coastguard Worker }
801*324bb76bSAndroid Build Coastguard Worker }
802*324bb76bSAndroid Build Coastguard Worker
803*324bb76bSAndroid Build Coastguard Worker if (DGifSlurp(GifFile) == GIF_ERROR) {
804*324bb76bSAndroid Build Coastguard Worker PrintGifError(GifFile->Error);
805*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
806*324bb76bSAndroid Build Coastguard Worker }
807*324bb76bSAndroid Build Coastguard Worker
808*324bb76bSAndroid Build Coastguard Worker printf("screen width %d\nscreen height %d\n", GifFile->SWidth,
809*324bb76bSAndroid Build Coastguard Worker GifFile->SHeight);
810*324bb76bSAndroid Build Coastguard Worker
811*324bb76bSAndroid Build Coastguard Worker printf(
812*324bb76bSAndroid Build Coastguard Worker "screen colors %d\nscreen background %d\npixel aspect byte %u\n\n",
813*324bb76bSAndroid Build Coastguard Worker 1 << GifFile->SColorResolution, GifFile->SBackGroundColor,
814*324bb76bSAndroid Build Coastguard Worker (unsigned)GifFile->AspectByte);
815*324bb76bSAndroid Build Coastguard Worker
816*324bb76bSAndroid Build Coastguard Worker if (GifFile->SColorMap) {
817*324bb76bSAndroid Build Coastguard Worker printf("screen map\n");
818*324bb76bSAndroid Build Coastguard Worker
819*324bb76bSAndroid Build Coastguard Worker printf("\tsort flag %s\n",
820*324bb76bSAndroid Build Coastguard Worker GifFile->SColorMap->SortFlag ? "on" : "off");
821*324bb76bSAndroid Build Coastguard Worker
822*324bb76bSAndroid Build Coastguard Worker for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
823*324bb76bSAndroid Build Coastguard Worker if (GifFile->SColorMap->ColorCount < PRINTABLES) {
824*324bb76bSAndroid Build Coastguard Worker printf("\trgb %03d %03d %03d is %c\n",
825*324bb76bSAndroid Build Coastguard Worker GifFile->SColorMap->Colors[i].Red,
826*324bb76bSAndroid Build Coastguard Worker GifFile->SColorMap->Colors[i].Green,
827*324bb76bSAndroid Build Coastguard Worker GifFile->SColorMap->Colors[i].Blue,
828*324bb76bSAndroid Build Coastguard Worker NameTable[i]);
829*324bb76bSAndroid Build Coastguard Worker } else {
830*324bb76bSAndroid Build Coastguard Worker printf("\trgb %03d %03d %03d\n",
831*324bb76bSAndroid Build Coastguard Worker GifFile->SColorMap->Colors[i].Red,
832*324bb76bSAndroid Build Coastguard Worker GifFile->SColorMap->Colors[i].Green,
833*324bb76bSAndroid Build Coastguard Worker GifFile->SColorMap->Colors[i].Blue);
834*324bb76bSAndroid Build Coastguard Worker }
835*324bb76bSAndroid Build Coastguard Worker }
836*324bb76bSAndroid Build Coastguard Worker printf("end\n\n");
837*324bb76bSAndroid Build Coastguard Worker }
838*324bb76bSAndroid Build Coastguard Worker
839*324bb76bSAndroid Build Coastguard Worker for (im = 0; im < GifFile->ImageCount; im++) {
840*324bb76bSAndroid Build Coastguard Worker SavedImage *image = &GifFile->SavedImages[im];
841*324bb76bSAndroid Build Coastguard Worker
842*324bb76bSAndroid Build Coastguard Worker DumpExtensions(GifFile, image->ExtensionBlockCount,
843*324bb76bSAndroid Build Coastguard Worker image->ExtensionBlocks);
844*324bb76bSAndroid Build Coastguard Worker
845*324bb76bSAndroid Build Coastguard Worker printf("image # %d\nimage left %d\nimage top %d\n", im + 1,
846*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.Left, image->ImageDesc.Top);
847*324bb76bSAndroid Build Coastguard Worker if (image->ImageDesc.Interlace) {
848*324bb76bSAndroid Build Coastguard Worker printf("image interlaced\n");
849*324bb76bSAndroid Build Coastguard Worker }
850*324bb76bSAndroid Build Coastguard Worker
851*324bb76bSAndroid Build Coastguard Worker if (image->ImageDesc.ColorMap) {
852*324bb76bSAndroid Build Coastguard Worker printf("image map\n");
853*324bb76bSAndroid Build Coastguard Worker
854*324bb76bSAndroid Build Coastguard Worker printf("\tsort flag %s\n",
855*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.ColorMap->SortFlag ? "on"
856*324bb76bSAndroid Build Coastguard Worker : "off");
857*324bb76bSAndroid Build Coastguard Worker
858*324bb76bSAndroid Build Coastguard Worker if (image->ImageDesc.ColorMap->ColorCount <
859*324bb76bSAndroid Build Coastguard Worker PRINTABLES) {
860*324bb76bSAndroid Build Coastguard Worker for (i = 0;
861*324bb76bSAndroid Build Coastguard Worker i < image->ImageDesc.ColorMap->ColorCount;
862*324bb76bSAndroid Build Coastguard Worker i++) {
863*324bb76bSAndroid Build Coastguard Worker printf(
864*324bb76bSAndroid Build Coastguard Worker "\trgb %03d %03d %03d is %c\n",
865*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.ColorMap->Colors[i]
866*324bb76bSAndroid Build Coastguard Worker .Red,
867*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.ColorMap->Colors[i]
868*324bb76bSAndroid Build Coastguard Worker .Green,
869*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.ColorMap->Colors[i]
870*324bb76bSAndroid Build Coastguard Worker .Blue,
871*324bb76bSAndroid Build Coastguard Worker NameTable[i]);
872*324bb76bSAndroid Build Coastguard Worker }
873*324bb76bSAndroid Build Coastguard Worker } else {
874*324bb76bSAndroid Build Coastguard Worker for (i = 0;
875*324bb76bSAndroid Build Coastguard Worker i < image->ImageDesc.ColorMap->ColorCount;
876*324bb76bSAndroid Build Coastguard Worker i++) {
877*324bb76bSAndroid Build Coastguard Worker printf(
878*324bb76bSAndroid Build Coastguard Worker "\trgb %03d %03d %03d\n",
879*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.ColorMap->Colors[i]
880*324bb76bSAndroid Build Coastguard Worker .Red,
881*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.ColorMap->Colors[i]
882*324bb76bSAndroid Build Coastguard Worker .Green,
883*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.ColorMap->Colors[i]
884*324bb76bSAndroid Build Coastguard Worker .Blue);
885*324bb76bSAndroid Build Coastguard Worker }
886*324bb76bSAndroid Build Coastguard Worker }
887*324bb76bSAndroid Build Coastguard Worker printf("end\n\n");
888*324bb76bSAndroid Build Coastguard Worker }
889*324bb76bSAndroid Build Coastguard Worker
890*324bb76bSAndroid Build Coastguard Worker /* one of these conditions has to be true */
891*324bb76bSAndroid Build Coastguard Worker if (image->ImageDesc.ColorMap) {
892*324bb76bSAndroid Build Coastguard Worker ColorCount = image->ImageDesc.ColorMap->ColorCount;
893*324bb76bSAndroid Build Coastguard Worker } else if (GifFile->SColorMap) {
894*324bb76bSAndroid Build Coastguard Worker ColorCount = GifFile->SColorMap->ColorCount;
895*324bb76bSAndroid Build Coastguard Worker }
896*324bb76bSAndroid Build Coastguard Worker
897*324bb76bSAndroid Build Coastguard Worker if (ColorCount < PRINTABLES) {
898*324bb76bSAndroid Build Coastguard Worker printf("image bits %d by %d\n", image->ImageDesc.Width,
899*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.Height);
900*324bb76bSAndroid Build Coastguard Worker } else {
901*324bb76bSAndroid Build Coastguard Worker printf("image bits %d by %d hex\n",
902*324bb76bSAndroid Build Coastguard Worker image->ImageDesc.Width, image->ImageDesc.Height);
903*324bb76bSAndroid Build Coastguard Worker }
904*324bb76bSAndroid Build Coastguard Worker for (i = 0; i < image->ImageDesc.Height; i++) {
905*324bb76bSAndroid Build Coastguard Worker for (j = 0; j < image->ImageDesc.Width; j++) {
906*324bb76bSAndroid Build Coastguard Worker GifByteType ch =
907*324bb76bSAndroid Build Coastguard Worker image->RasterBits
908*324bb76bSAndroid Build Coastguard Worker [i * image->ImageDesc.Width + j];
909*324bb76bSAndroid Build Coastguard Worker if (ColorCount < PRINTABLES &&
910*324bb76bSAndroid Build Coastguard Worker ch < PRINTABLES) {
911*324bb76bSAndroid Build Coastguard Worker putchar(NameTable[ch]);
912*324bb76bSAndroid Build Coastguard Worker } else {
913*324bb76bSAndroid Build Coastguard Worker printf("%02x", ch);
914*324bb76bSAndroid Build Coastguard Worker }
915*324bb76bSAndroid Build Coastguard Worker }
916*324bb76bSAndroid Build Coastguard Worker putchar('\n');
917*324bb76bSAndroid Build Coastguard Worker }
918*324bb76bSAndroid Build Coastguard Worker putchar('\n');
919*324bb76bSAndroid Build Coastguard Worker }
920*324bb76bSAndroid Build Coastguard Worker
921*324bb76bSAndroid Build Coastguard Worker DumpExtensions(GifFile, GifFile->ExtensionBlockCount,
922*324bb76bSAndroid Build Coastguard Worker GifFile->ExtensionBlocks);
923*324bb76bSAndroid Build Coastguard Worker
924*324bb76bSAndroid Build Coastguard Worker /* Tell EMACS this is a picture... */
925*324bb76bSAndroid Build Coastguard Worker printf("# The following sets edit modes for GNU EMACS\n");
926*324bb76bSAndroid Build Coastguard Worker printf("# Local "); /* ...break this up, so that EMACS doesn't */
927*324bb76bSAndroid Build Coastguard Worker printf("Variables:\n"); /* get confused when visiting *this* file! */
928*324bb76bSAndroid Build Coastguard Worker printf("# mode:picture\n");
929*324bb76bSAndroid Build Coastguard Worker printf("# truncate-lines:t\n");
930*324bb76bSAndroid Build Coastguard Worker printf("# End:\n");
931*324bb76bSAndroid Build Coastguard Worker
932*324bb76bSAndroid Build Coastguard Worker if (fdin == -1) {
933*324bb76bSAndroid Build Coastguard Worker (void)printf("# End of %s dump\n", FileName);
934*324bb76bSAndroid Build Coastguard Worker }
935*324bb76bSAndroid Build Coastguard Worker
936*324bb76bSAndroid Build Coastguard Worker /*
937*324bb76bSAndroid Build Coastguard Worker * Sanity checks.
938*324bb76bSAndroid Build Coastguard Worker */
939*324bb76bSAndroid Build Coastguard Worker
940*324bb76bSAndroid Build Coastguard Worker /* check that the background color isn't garbage (SF bug #87) */
941*324bb76bSAndroid Build Coastguard Worker if (GifFile->SBackGroundColor < 0 ||
942*324bb76bSAndroid Build Coastguard Worker (GifFile->SColorMap &&
943*324bb76bSAndroid Build Coastguard Worker GifFile->SBackGroundColor >= GifFile->SColorMap->ColorCount)) {
944*324bb76bSAndroid Build Coastguard Worker fprintf(stderr, "gifbuild: background color invalid for screen "
945*324bb76bSAndroid Build Coastguard Worker "colormap.\n");
946*324bb76bSAndroid Build Coastguard Worker }
947*324bb76bSAndroid Build Coastguard Worker
948*324bb76bSAndroid Build Coastguard Worker if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) {
949*324bb76bSAndroid Build Coastguard Worker PrintGifError(ErrorCode);
950*324bb76bSAndroid Build Coastguard Worker exit(EXIT_FAILURE);
951*324bb76bSAndroid Build Coastguard Worker }
952*324bb76bSAndroid Build Coastguard Worker }
953*324bb76bSAndroid Build Coastguard Worker
EscapeString(char * cp,char * tp)954*324bb76bSAndroid Build Coastguard Worker static int EscapeString(char *cp, char *tp)
955*324bb76bSAndroid Build Coastguard Worker /* process standard C-style escape sequences in a string */
956*324bb76bSAndroid Build Coastguard Worker {
957*324bb76bSAndroid Build Coastguard Worker char *StartAddr = tp;
958*324bb76bSAndroid Build Coastguard Worker
959*324bb76bSAndroid Build Coastguard Worker while (*cp) {
960*324bb76bSAndroid Build Coastguard Worker int cval = 0;
961*324bb76bSAndroid Build Coastguard Worker
962*324bb76bSAndroid Build Coastguard Worker if (*cp == '\\' && strchr("0123456789xX", cp[1])) {
963*324bb76bSAndroid Build Coastguard Worker int dcount = 0;
964*324bb76bSAndroid Build Coastguard Worker
965*324bb76bSAndroid Build Coastguard Worker if (*++cp == 'x' || *cp == 'X') {
966*324bb76bSAndroid Build Coastguard Worker char *dp,
967*324bb76bSAndroid Build Coastguard Worker *hex = "00112233445566778899aAbBcCdDeEfF";
968*324bb76bSAndroid Build Coastguard Worker for (++cp;
969*324bb76bSAndroid Build Coastguard Worker (dp = strchr(hex, *cp)) && (dcount++ < 2);
970*324bb76bSAndroid Build Coastguard Worker cp++) {
971*324bb76bSAndroid Build Coastguard Worker cval = (cval * 16) + (dp - hex) / 2;
972*324bb76bSAndroid Build Coastguard Worker }
973*324bb76bSAndroid Build Coastguard Worker } else if (*cp == '0') {
974*324bb76bSAndroid Build Coastguard Worker while (strchr("01234567", *cp) !=
975*324bb76bSAndroid Build Coastguard Worker (char *)NULL &&
976*324bb76bSAndroid Build Coastguard Worker (dcount++ < 3)) {
977*324bb76bSAndroid Build Coastguard Worker cval = (cval * 8) + (*cp++ - '0');
978*324bb76bSAndroid Build Coastguard Worker }
979*324bb76bSAndroid Build Coastguard Worker } else {
980*324bb76bSAndroid Build Coastguard Worker while ((strchr("0123456789", *cp) !=
981*324bb76bSAndroid Build Coastguard Worker (char *)NULL) &&
982*324bb76bSAndroid Build Coastguard Worker (dcount++ < 3)) {
983*324bb76bSAndroid Build Coastguard Worker cval = (cval * 10) + (*cp++ - '0');
984*324bb76bSAndroid Build Coastguard Worker }
985*324bb76bSAndroid Build Coastguard Worker }
986*324bb76bSAndroid Build Coastguard Worker } else if (*cp == '\\') /* C-style character escapes */
987*324bb76bSAndroid Build Coastguard Worker {
988*324bb76bSAndroid Build Coastguard Worker switch (*++cp) {
989*324bb76bSAndroid Build Coastguard Worker case '\\':
990*324bb76bSAndroid Build Coastguard Worker cval = '\\';
991*324bb76bSAndroid Build Coastguard Worker break;
992*324bb76bSAndroid Build Coastguard Worker case 'n':
993*324bb76bSAndroid Build Coastguard Worker cval = '\n';
994*324bb76bSAndroid Build Coastguard Worker break;
995*324bb76bSAndroid Build Coastguard Worker case 't':
996*324bb76bSAndroid Build Coastguard Worker cval = '\t';
997*324bb76bSAndroid Build Coastguard Worker break;
998*324bb76bSAndroid Build Coastguard Worker case 'b':
999*324bb76bSAndroid Build Coastguard Worker cval = '\b';
1000*324bb76bSAndroid Build Coastguard Worker break;
1001*324bb76bSAndroid Build Coastguard Worker case 'r':
1002*324bb76bSAndroid Build Coastguard Worker cval = '\r';
1003*324bb76bSAndroid Build Coastguard Worker break;
1004*324bb76bSAndroid Build Coastguard Worker default:
1005*324bb76bSAndroid Build Coastguard Worker cval = *cp;
1006*324bb76bSAndroid Build Coastguard Worker }
1007*324bb76bSAndroid Build Coastguard Worker cp++;
1008*324bb76bSAndroid Build Coastguard Worker } else if (*cp == '^') /* expand control-character syntax */
1009*324bb76bSAndroid Build Coastguard Worker {
1010*324bb76bSAndroid Build Coastguard Worker cval = (*++cp & 0x1f);
1011*324bb76bSAndroid Build Coastguard Worker cp++;
1012*324bb76bSAndroid Build Coastguard Worker } else {
1013*324bb76bSAndroid Build Coastguard Worker cval = *cp++;
1014*324bb76bSAndroid Build Coastguard Worker }
1015*324bb76bSAndroid Build Coastguard Worker *tp++ = cval;
1016*324bb76bSAndroid Build Coastguard Worker }
1017*324bb76bSAndroid Build Coastguard Worker
1018*324bb76bSAndroid Build Coastguard Worker return (tp - StartAddr);
1019*324bb76bSAndroid Build Coastguard Worker }
1020*324bb76bSAndroid Build Coastguard Worker
1021*324bb76bSAndroid Build Coastguard Worker /* end */
1022