1 /*****************************************************************************
3 gifbuild - dump GIF data in a textual format, or undump it to a GIF
5 *****************************************************************************/
17 #define PROGRAM_NAME "gifbuild"
19 __attribute__((__section__(".tizen.build-id")))
25 __DATE__ ", " __TIME__ "\n"
26 "(C) Copyright 1992 Eric Raymond.\n";
30 " v%- d%- t%-Characters!s h%- GifFile(s)!*s";
32 static char KeyLetters[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&'()*+,-./:<=>?@[\\]^_`{|}~";
33 #define PRINTABLES (sizeof(KeyLetters) - 1)
35 static void Icon2Gif(char *FileName, FILE *txtin, int fdout);
36 static void Gif2Icon(char *FileName,
39 static int EscapeString(char *cp, char *tp);
41 /******************************************************************************
43 ******************************************************************************/
44 int main(int argc, char **argv)
47 bool Error, DisasmFlag = false, HelpFlag = false, TextLineFlag = false;
48 char **FileNames = NULL;
51 if ((Error = GAGetArgs(argc, argv, CtrlStr,
52 &GifNoisyPrint, &DisasmFlag, &TextLineFlag, &TextLines[0],
53 &HelpFlag, &NumFiles, &FileNames)) != false) {
55 GAPrintHowTo(CtrlStr);
60 (void)fprintf(stderr, VersionStr, GIFLIB_MAJOR, GIFLIB_MINOR);
61 GAPrintHowTo(CtrlStr);
65 if (!DisasmFlag && NumFiles > 1) {
66 GIF_MESSAGE("Error in command line parsing - one text input please.");
67 GAPrintHowTo(CtrlStr);
71 if (!DisasmFlag && TextLineFlag) {
72 GIF_MESSAGE("Error in command line parsing - -t invalid without -d.");
73 GAPrintHowTo(CtrlStr);
81 Gif2Icon("Stdin", 0, 1, TextLineFlag ? TextLines[0] : KeyLetters);
83 Icon2Gif("Stdin", stdin, 1);
88 for (i = 0; i < NumFiles; i++)
92 if ((fp = fopen(FileNames[i], "r")) == (FILE *)NULL)
94 (void) fprintf(stderr, "Can't open %s\n", FileNames[i]);
100 printf("#\n# GIF information from %s\n", FileNames[i]);
101 Gif2Icon(FileNames[i], -1, 1, TextLineFlag ? TextLines[0] : KeyLetters);
105 Icon2Gif(FileNames[i], fp, 1);
115 /******************************************************************************
116 Parse image directives
117 ******************************************************************************/
118 #define PARSE_ERROR(str) (void) fprintf(stderr,"%s:%d: %s\n",FileName,LineNum,str);
120 static void Icon2Gif(char *FileName, FILE *txtin, int fdout)
122 unsigned int ColorMapSize = 0;
123 GifColorType GlobalColorMap[256], LocalColorMap[256],
124 *ColorMap = GlobalColorMap;
125 char GlobalColorKeys[PRINTABLES], LocalColorKeys[PRINTABLES],
126 *KeyTable = GlobalColorKeys;
127 bool SortFlag = false;
128 unsigned int ExtCode, intval;
129 int red, green, blue, n;
130 char buf[BUFSIZ * 2], InclusionFile[64];
131 GifFileType *GifFileOut;
132 SavedImage *NewImage = NULL;
133 int LeadingExtensionBlockCount = 0;
134 ExtensionBlock *LeadingExtensionBlocks = NULL;
135 int ErrorCode, LineNum = 0;
137 if ((GifFileOut = EGifOpenFileHandle(fdout, &ErrorCode)) == NULL) {
138 PrintGifError(ErrorCode);
142 /* OK, interpret directives */
143 /* coverity[tainted_data_transitive] */
144 while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
151 * Skip lines consisting only of whitespace and comments
153 for (cp = buf; isspace((int)(*cp)); cp++)
155 if (*cp == '#' || *cp == '\0')
159 * If there's a trailing comment, nuke it and all preceding whitespace.
160 * But preserve the EOL.
162 if ((cp = strchr(buf, '#')) && (cp == strrchr(cp, '#')))
164 while (isspace((int)(*--cp)))
171 * Explicit header declarations
174 if (sscanf(buf, "screen width %d\n", &GifFileOut->SWidth) == 1)
177 else if (sscanf(buf, "screen height %d\n", &GifFileOut->SHeight) == 1)
180 else if (sscanf(buf, "screen colors %d\n", &n) == 1)
182 int ResBits = GifBitSize(n);
184 if (n > 256 || n < 0 || n != (1 << ResBits))
186 PARSE_ERROR("Invalid color resolution value.");
190 GifFileOut->SColorResolution = ResBits;
195 "screen background %d\n",
196 &GifFileOut->SBackGroundColor) == 1)
199 else if (sscanf(buf, "pixel aspect byte %u\n", &intval) == 1) {
200 GifFileOut->AspectByte = (GifByteType)(intval & 0xff);
205 * Color table parsing
208 else if (strcmp(buf, "screen map\n") == 0)
210 if (GifFileOut->SColorMap != NULL)
212 PARSE_ERROR("You've already declared a global color map.");
217 ColorMap = GlobalColorMap;
219 KeyTable = GlobalColorKeys;
220 memset(GlobalColorKeys, '\0', sizeof(GlobalColorKeys));
223 else if (strcmp(buf, "image map\n") == 0)
225 if (NewImage == NULL)
227 PARSE_ERROR("No previous image declaration.");
232 ColorMap = LocalColorMap;
233 KeyTable = LocalColorKeys;
234 memset(LocalColorKeys, '\0', sizeof(LocalColorKeys));
237 else if (sscanf(buf, " rgb %d %d %d is %c",
238 &red, &green, &blue, &KeyTable[ColorMapSize]) == 4)
240 ColorMap[ColorMapSize].Red = red;
241 ColorMap[ColorMapSize].Green = green;
242 ColorMap[ColorMapSize].Blue = blue;
246 else if (sscanf(buf, " rgb %d %d %d", &red, &green, &blue) == 3)
248 ColorMap[ColorMapSize].Red = red;
249 ColorMap[ColorMapSize].Green = green;
250 ColorMap[ColorMapSize].Blue = blue;
254 else if (strcmp(buf, " sort flag on\n") == 0)
257 else if (strcmp(buf, " sort flag off\n") == 0)
260 else if (strcmp(buf, "end\n") == 0)
262 ColorMapObject *NewMap;
264 NewMap = GifMakeMapObject(1 << GifBitSize(ColorMapSize), ColorMap);
265 if (NewMap == (ColorMapObject *)NULL)
267 PARSE_ERROR("Out of memory while allocating new color map.");
271 NewMap->SortFlag = SortFlag;
274 NewImage->ImageDesc.ColorMap = NewMap;
276 GifFileOut->SColorMap = NewMap;
280 /* ugly magic number is because scanf has no */
281 else if (sscanf(buf, "include %63s", InclusionFile) == 1)
285 GifPixelType Translation[256];
287 GifFileType *Inclusion;
288 SavedImage *CopyFrom;
290 if ((Inclusion = DGifOpenFileName(InclusionFile, &ErrorCode)) == NULL) {
291 PrintGifError(ErrorCode);
295 if (DGifSlurp(Inclusion) == GIF_ERROR)
297 PARSE_ERROR("Inclusion read failed.");
298 if (Inclusion != NULL) {
299 PrintGifError(Inclusion->Error);
300 DGifCloseFile(Inclusion, NULL);
302 if (GifFileOut != NULL) {
303 EGifCloseFile(GifFileOut, NULL);
308 //cppcheck-suppress nullPointerRedundantCheck
309 if ((DoTranslation = (GifFileOut->SColorMap!=(ColorMapObject*)NULL)))
311 ColorMapObject *UnionMap;
313 //cppcheck-suppress nullPointerRedundantCheck
314 UnionMap = GifUnionColorMap(GifFileOut->SColorMap, Inclusion->SColorMap, Translation);
316 if (UnionMap == NULL)
318 PARSE_ERROR("Inclusion failed --- global map conflict.");
319 //cppcheck-suppress nullPointerRedundantCheck
320 PrintGifError(GifFileOut->Error);
321 if (Inclusion != NULL) DGifCloseFile(Inclusion, NULL);
322 if (GifFileOut != NULL) EGifCloseFile(GifFileOut, NULL);
326 GifFreeMapObject(GifFileOut->SColorMap);
327 GifFileOut->SColorMap = UnionMap;
330 //cppcheck-suppress nullPointerRedundantCheck
331 for (CopyFrom = Inclusion->SavedImages;
332 //cppcheck-suppress nullPointerRedundantCheck
333 CopyFrom < Inclusion->SavedImages + Inclusion->ImageCount;
336 SavedImage *NewImage;
337 if ((NewImage = GifMakeSavedImage(GifFileOut, CopyFrom)) == NULL)
339 PARSE_ERROR("Inclusion failed --- out of memory.");
340 //cppcheck-suppress nullPointerRedundantCheck
341 PrintGifError(GifFileOut->Error);
342 if (Inclusion != NULL) DGifCloseFile(Inclusion, NULL);
343 if (GifFileOut != NULL) EGifCloseFile(GifFileOut, NULL);
346 else if (DoTranslation)
347 GifApplyTranslation(NewImage, Translation);
350 "%s: Image %d at (%d, %d) [%dx%d]: from %s\n",
351 PROGRAM_NAME, GifFileOut->ImageCount,
352 NewImage->ImageDesc.Left, NewImage->ImageDesc.Top,
353 NewImage->ImageDesc.Width, NewImage->ImageDesc.Height,
357 (void) DGifCloseFile(Inclusion, NULL);
363 else if (strcmp(buf, "comment\n") == 0)
366 while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
367 if (strcmp(buf, "end\n") == 0)
373 buf[strlen(buf) - 1] = '\0';
374 Len = EscapeString(buf, buf);
375 if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
376 &LeadingExtensionBlocks,
377 bc++ == CONTINUE_EXT_FUNC_CODE ? COMMENT_EXT_FUNC_CODE : 0,
379 (unsigned char *)buf) == GIF_ERROR) {
380 PARSE_ERROR("out of memory while adding comment block.");
385 else if (strcmp(buf, "plaintext\n") == 0)
388 while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
389 if (strcmp(buf, "end\n") == 0)
395 buf[strlen(buf) - 1] = '\0';
396 Len = EscapeString(buf, buf);
397 if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
398 &LeadingExtensionBlocks,
399 bc++ == CONTINUE_EXT_FUNC_CODE ? PLAINTEXT_EXT_FUNC_CODE : 0,
401 (unsigned char *)buf) == GIF_ERROR) {
402 PARSE_ERROR("out of memory while adding plaintext block.");
407 else if (strcmp(buf, "graphics control\n") == 0)
409 GraphicsControlBlock gcb;
412 memset(&gcb, '\0', sizeof(gcb));
413 gcb.TransparentColor = NO_TRANSPARENT_COLOR;
414 while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
415 if (strcmp(buf, "end\n") == 0)
423 if (sscanf(tp, "disposal mode %d\n", &gcb.DisposalMode))
425 if (strcmp(tp, "user input flag on\n") == 0) {
426 gcb.UserInputFlag = true;
429 if (strcmp(tp, "user input flag off\n") == 0) {
430 gcb.UserInputFlag = false;
433 if (sscanf(tp, "delay %d\n", &gcb.DelayTime))
435 if (sscanf(tp, "transparent index %d\n",
436 &gcb.TransparentColor))
438 (void) fputs(tp, stderr);
439 PARSE_ERROR("unrecognized directive in GCB block.");
442 Len = EGifGCBToExtension(&gcb, (GifByteType *)buf);
443 if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
444 &LeadingExtensionBlocks,
445 GRAPHICS_EXT_FUNC_CODE,
447 (unsigned char *)buf) == GIF_ERROR) {
448 PARSE_ERROR("out of memory while adding GCB.");
453 else if (sscanf(buf, "netscape loop %u", &intval))
455 unsigned char params[3] = {1, 0, 0};
456 /* Create a Netscape 2.0 loop block */
457 if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
458 &LeadingExtensionBlocks,
459 APPLICATION_EXT_FUNC_CODE,
461 (unsigned char *)"NETSCAPE2.0")==GIF_ERROR) {
462 PARSE_ERROR("out of memory while adding loop block.");
465 params[1] = (intval & 0xff);
466 params[2] = (intval >> 8) & 0xff;
467 if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
468 &LeadingExtensionBlocks,
469 0, sizeof(params), params) == GIF_ERROR) {
470 PARSE_ERROR("out of memory while adding loop continuation.");
475 else if (sscanf(buf, "extension %x", &ExtCode))
478 while (fgets(buf, sizeof(buf), txtin) != (char *)NULL)
479 if (strcmp(buf, "end\n") == 0)
485 buf[strlen(buf) - 1] = '\0';
486 Len = EscapeString(buf, buf);
487 if (GifAddExtensionBlock(&LeadingExtensionBlockCount,
488 &LeadingExtensionBlocks,
489 bc++ == CONTINUE_EXT_FUNC_CODE ? ExtCode : 0,
491 (unsigned char *)buf) == GIF_ERROR) {
492 PARSE_ERROR("out of memory while adding extension block.");
499 * Explicit image declarations
502 else if (strcmp(buf, "image\n") == 0)
504 if ((NewImage = GifMakeSavedImage(GifFileOut, NULL)) == (SavedImage *)NULL)
506 PARSE_ERROR("Out of memory while allocating image block.");
510 /* use global table unless user specifies a local one */
511 ColorMap = GlobalColorMap;
512 KeyTable = GlobalColorKeys;
514 /* connect leading extension blocks */
515 NewImage->ExtensionBlockCount = LeadingExtensionBlockCount;
516 NewImage->ExtensionBlocks = LeadingExtensionBlocks;
517 LeadingExtensionBlockCount = 0;
518 LeadingExtensionBlocks = NULL;
522 * Nothing past this point is valid unless we've seen a previous
525 else if (NewImage == (SavedImage *)NULL)
527 (void) fputs(buf, stderr);
528 PARSE_ERROR("Syntax error in header block.");
533 * Accept image attributes
535 else if (sscanf(buf, "image top %d\n", &NewImage->ImageDesc.Top) == 1)
538 else if (sscanf(buf, "image left %d\n", &NewImage->ImageDesc.Left)== 1)
541 else if (strcmp(buf, "image interlaced\n") == 0)
543 NewImage->ImageDesc.Interlace = true;
548 "image bits %d by %d",
549 &NewImage->ImageDesc.Width,
550 &NewImage->ImageDesc.Height) == 2)
553 static GifPixelType *Raster, *cp;
555 bool hex = (strstr(buf, "hex") != NULL);
557 /* coverity[overflow_sink] */
558 if ((Raster = (GifPixelType *) malloc(sizeof(GifPixelType) * NewImage->ImageDesc.Width * NewImage->ImageDesc.Height))
560 PARSE_ERROR("Failed to allocate raster block, aborted.");
564 GifQprintf("%s: Image %d at (%d, %d) [%dx%d]: ",
565 PROGRAM_NAME, GifFileOut->ImageCount,
566 NewImage->ImageDesc.Left, NewImage->ImageDesc.Top,
567 NewImage->ImageDesc.Width, NewImage->ImageDesc.Height);
570 for (i = 0; i < NewImage->ImageDesc.Height; i++) {
574 for (j = 0; j < NewImage->ImageDesc.Width; j++)
575 if ((c = fgetc(txtin)) == EOF) {
576 PARSE_ERROR("input file ended prematurely.");
588 const static char *hexdigits = "0123456789ABCDEF";
589 unsigned char hi, lo;
590 dp = strchr(hexdigits, toupper(c));
592 PARSE_ERROR("Invalid hex high byte.");
595 hi = (dp - hexdigits);
596 if ((c = fgetc(txtin)) == EOF) {
597 PARSE_ERROR("input file ended prematurely.");
600 dp = strchr(hexdigits, toupper(c));
602 PARSE_ERROR("Invalid hex low byte.");
605 lo = (dp - hexdigits);
606 *cp++ = (hi << 4) | lo;
608 else if ((dp = strchr(KeyTable, c)))
609 *cp++ = (dp - KeyTable);
611 PARSE_ERROR("Invalid ASCII pixel key.");
616 fprintf(stderr, "\b\b\b\b%-4d", i);
622 NewImage->RasterBits = (unsigned char *) Raster;
626 (void) fputs(buf, stderr);
627 PARSE_ERROR("Syntax error in image description.");
632 /* connect trailing extension blocks */
633 GifFileOut->ExtensionBlockCount = LeadingExtensionBlockCount;
634 GifFileOut->ExtensionBlocks = LeadingExtensionBlocks;
635 //LeadingExtensionBlockCount = 0;
636 LeadingExtensionBlocks = NULL;
638 EGifSpew(GifFileOut);
641 static void VisibleDumpBuffer(GifByteType *buf, int len)
642 /* Visibilize a given string */
646 for (cp = buf; cp < buf + len; cp++)
648 if (isprint((int)(*cp)) || *cp == ' ')
650 else if (*cp == '\n')
652 putchar('\\'); putchar('n');
654 else if (*cp == '\r')
656 putchar('\\'); putchar('r');
658 else if (*cp == '\b')
660 putchar('\\'); putchar('b');
664 putchar('\\'); putchar('^'); putchar('@' + *cp);
667 printf("\\0x%02x", *cp);
671 static void DumpExtensions(GifFileType *GifFileOut,
672 int ExtensionBlockCount,
673 ExtensionBlock *ExtensionBlocks)
677 for (ep = ExtensionBlocks;
678 ep < ExtensionBlocks + ExtensionBlockCount;
680 bool last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
681 if (ep->Function == COMMENT_EXT_FUNC_CODE) {
683 VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
685 while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
687 last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
688 VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
693 else if (ep->Function == PLAINTEXT_EXT_FUNC_CODE) {
694 printf("plaintext\n");
695 VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
697 while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
699 last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
700 VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
705 else if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
707 GraphicsControlBlock gcb;
708 printf("graphics control\n");
709 if (DGifExtensionToGCB(ep->ByteCount, ep->Bytes, &gcb) == GIF_ERROR) {
710 GIF_MESSAGE("invalid graphics control block");
713 printf("\tdisposal mode %d\n", gcb.DisposalMode);
714 printf("\tuser input flag %s\n",
715 gcb.UserInputFlag ? "on" : "off");
716 printf("\tdelay %d\n", gcb.DelayTime);
717 printf("\ttransparent index %d\n", gcb.TransparentColor);
721 && ep->Function == APPLICATION_EXT_FUNC_CODE
722 && ep->ByteCount >= 11
723 && (ep+1)->ByteCount >= 3
724 && memcmp(ep->Bytes, "NETSCAPE2.0", 11) == 0) {
725 unsigned char *params = (++ep)->Bytes;
726 unsigned int loopcount = params[1] | (params[2] << 8);
727 printf("netscape loop %u\n\n", loopcount);
730 printf("extension 0x%02x\n", ep->Function);
731 VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
732 while (!last && ep[1].Function == CONTINUE_EXT_FUNC_CODE) {
734 last = (ep - ExtensionBlocks == (ExtensionBlockCount - 1));
735 VisibleDumpBuffer(ep->Bytes, ep->ByteCount);
743 static void Gif2Icon(char *FileName,
747 int ErrorCode, im, i, j, ColorCount = 0;
748 GifFileType *GifFile;
751 if ((GifFile = DGifOpenFileName(FileName, &ErrorCode)) == NULL) {
752 PrintGifError(ErrorCode);
757 /* Use stdin instead: */
758 if ((GifFile = DGifOpenFileHandle(fdin, &ErrorCode)) == NULL) {
759 PrintGifError(ErrorCode);
764 if (DGifSlurp(GifFile) == GIF_ERROR) {
765 PrintGifError(GifFile->Error);
769 printf("screen width %d\nscreen height %d\n",
770 GifFile->SWidth, GifFile->SHeight);
772 printf("screen colors %d\nscreen background %d\npixel aspect byte %u\n\n",
773 1 << GifFile->SColorResolution,
774 GifFile->SBackGroundColor,
775 (unsigned)GifFile->AspectByte);
777 if (GifFile->SColorMap)
779 printf("screen map\n");
781 printf("\tsort flag %s\n", GifFile->SColorMap->SortFlag ? "on" : "off");
783 for (i = 0; i < GifFile->SColorMap->ColorCount; i++)
784 if (GifFile->SColorMap->ColorCount < PRINTABLES)
785 printf("\trgb %03d %03d %03d is %c\n",
786 GifFile->SColorMap ->Colors[i].Red,
787 GifFile->SColorMap ->Colors[i].Green,
788 GifFile->SColorMap ->Colors[i].Blue,
791 printf("\trgb %03d %03d %03d\n",
792 GifFile->SColorMap ->Colors[i].Red,
793 GifFile->SColorMap ->Colors[i].Green,
794 GifFile->SColorMap ->Colors[i].Blue);
798 for (im = 0; im < GifFile->ImageCount; im++) {
799 SavedImage *image = &GifFile->SavedImages[im];
801 DumpExtensions(GifFile,
802 image->ExtensionBlockCount, image->ExtensionBlocks);
804 printf("image # %d\nimage left %d\nimage top %d\n",
805 im+1, image->ImageDesc.Left, image->ImageDesc.Top);
806 if (image->ImageDesc.Interlace)
807 printf("image interlaced\n");
809 if (image->ImageDesc.ColorMap)
811 printf("image map\n");
813 printf("\tsort flag %s\n",
814 image->ImageDesc.ColorMap->SortFlag ? "on" : "off");
816 if (image->ImageDesc.ColorMap->ColorCount < PRINTABLES)
817 for (i = 0; i < image->ImageDesc.ColorMap->ColorCount; i++)
818 printf("\trgb %03d %03d %03d is %c\n",
819 image->ImageDesc.ColorMap ->Colors[i].Red,
820 image->ImageDesc.ColorMap ->Colors[i].Green,
821 image->ImageDesc.ColorMap ->Colors[i].Blue,
824 for (i = 0; i < image->ImageDesc.ColorMap->ColorCount; i++)
825 printf("\trgb %03d %03d %03d\n",
826 image->ImageDesc.ColorMap ->Colors[i].Red,
827 image->ImageDesc.ColorMap ->Colors[i].Green,
828 image->ImageDesc.ColorMap ->Colors[i].Blue);
832 /* one of these conditions has to be true */
833 if (image->ImageDesc.ColorMap)
834 ColorCount = image->ImageDesc.ColorMap->ColorCount;
835 else if (GifFile->SColorMap)
836 ColorCount = GifFile->SColorMap->ColorCount;
838 if (ColorCount < PRINTABLES)
839 printf("image bits %d by %d\n",
840 image->ImageDesc.Width, image->ImageDesc.Height);
842 printf("image bits %d by %d hex\n",
843 image->ImageDesc.Width, image->ImageDesc.Height);
844 for (i = 0; i < image->ImageDesc.Height; i++) {
845 for (j = 0; j < image->ImageDesc.Width; j++) {
846 GifByteType ch = image->RasterBits[i*image->ImageDesc.Width + j];
847 if (ColorCount < PRINTABLES && ch < PRINTABLES)
848 putchar(NameTable[ch]);
857 DumpExtensions(GifFile,
858 GifFile->ExtensionBlockCount, GifFile->ExtensionBlocks);
860 /* Tell EMACS this is a picture... */
861 printf("# The following sets edit modes for GNU EMACS\n");
862 printf("# Local "); /* ...break this up, so that EMACS doesn't */
863 printf("Variables:\n"); /* get confused when visiting *this* file! */
864 printf("# mode:picture\n");
865 printf("# truncate-lines:t\n");
869 (void) printf("# End of %s dump\n", FileName);
876 /* check that the background color isn't garbage (SF bug #87) */
877 if (GifFile->SBackGroundColor < 0
878 || GifFile->SBackGroundColor >= GifFile->SColorMap->ColorCount) {
879 fprintf(stderr, "gifbuild: background color invalid for screen colormap.\n");
882 if (DGifCloseFile(GifFile, &ErrorCode) == GIF_ERROR) {
883 PrintGifError(ErrorCode);
888 static int EscapeString(char *cp, char *tp)
889 /* process standard C-style escape sequences in a string */
891 char *StartAddr = tp;
897 if (*cp == '\\' && strchr("0123456789xX", cp[1]))
901 if (*++cp == 'x' || *cp == 'X') {
902 char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
903 for (++cp; (dp = strchr(hex, *cp)) && (dcount++ < 2); cp++)
904 cval = (cval * 16) + (dp - hex) / 2;
905 } else if (*cp == '0')
906 while (strchr("01234567",*cp) != (char*)NULL && (dcount++ < 3))
907 cval = (cval * 8) + (*cp++ - '0');
909 while ((strchr("0123456789",*cp)!=(char*)NULL)&&(dcount++ < 3))
910 cval = (cval * 10) + (*cp++ - '0');
912 else if (*cp == '\\') /* C-style character escapes */
916 case '\\': cval = '\\'; break;
917 case 'n': cval = '\n'; break;
918 case 't': cval = '\t'; break;
919 case 'b': cval = '\b'; break;
920 case 'r': cval = '\r'; break;
925 else if (*cp == '^') /* expand control-character syntax */
927 cval = (*++cp & 0x1f);
935 return(tp - StartAddr);