home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / giflib11 / util / giftext.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-03  |  14.1 KB  |  458 lines

  1. /*****************************************************************************
  2. *   "Gif-Lib" - Yet another gif library.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, Jun. 1989   *
  5. ******************************************************************************
  6. * Program to dump GIF file content as TEXT information                 *
  7. * Options:                                     *
  8. * -c : include the color maps as well.                         *
  9. * -e : include encoded information packed as bytes as well.             *
  10. * -z : include encoded information (12bits) codes as result from the zl alg. *
  11. * -p : dump pixel information instead of encoded information.             *
  12. * -r : same as -p but dump one pixel as one byte in binary form with no      *
  13. *      other information. This will create a file of size Width by Height.   *
  14. * -h : on line help.                                 *
  15. ******************************************************************************
  16. * History:                                     *
  17. * 28 Jun 89 - Version 1.0 by Gershon Elber.                     *
  18. * 21 Dec 89 - Fix segmentation fault problem in PrintCodeBlock (Version 1.1) *
  19. * 25 Dec 89 - Add the -r flag for raw output.                                *
  20. *****************************************************************************/
  21.  
  22. #ifdef __MSDOS__
  23. #include <stdlib.h>
  24. #include <alloc.h>
  25. #include <conio.h>
  26. #include <io.h>
  27. #endif /* __MSDOS__ */
  28.  
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. #include <fcntl.h>
  32. #include "gif_lib.h"
  33. #include "getarg.h"
  34.  
  35. #define PROGRAM_NAME    "GifText"
  36.  
  37. #define MAKE_PRINTABLE(c)  (isprint(c) ? (c) : ' ')
  38.  
  39. #ifdef __MSDOS__
  40. extern unsigned int
  41.     _stklen = 16384;                 /* Increase default stack size. */
  42. #endif /* __MSDOS__ */
  43.  
  44. #ifdef SYSV
  45. static char *VersionStr =
  46.         "Gif library module,\t\tGershon Elber\n\
  47.     (C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  48. static char
  49.     *CtrlStr = "GifText c%- e%- z%- p%- r%- h%- GifFile!*s";
  50. #else
  51. static char
  52.     *VersionStr =
  53.     PROGRAM_NAME
  54.     GIF_LIB_VERSION
  55.     "    Gershon Elber,    "
  56.     __DATE__ ",   " __TIME__ "\n"
  57.     "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  58. static char
  59.     *CtrlStr =
  60.     PROGRAM_NAME
  61.     " c%- e%- z%- p%- r%- h%- GifFile!*s";
  62. #endif /* SYSV */
  63.  
  64. static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset);
  65. static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset);
  66. static void PrintExtBlock(GifByteType *Extension, int Reset);
  67. static void PrintLZCodes(GifFileType *GifFile);
  68.  
  69. /******************************************************************************
  70. * Interpret the command line and scan the given GIF file.              *
  71. ******************************************************************************/
  72. void main(int argc, char **argv)
  73. {
  74.     int i, j, ExtCode, CodeSize, Error, NumFiles, Len,
  75.     ColorMapFlag = FALSE, EncodedFlag = FALSE, LZCodesFlag = FALSE,
  76.     PixelFlag = FALSE, HelpFlag = FALSE, RawFlag = FALSE, ImageNum = 1;
  77.     char *GifFileName, **FileName = NULL;
  78.     GifPixelType *Line;
  79.     GifRecordType RecordType;
  80.     GifByteType *CodeBlock, *Extension;
  81.     GifFileType *GifFile;
  82.  
  83.     if ((Error = GAGetArgs(argc, argv, CtrlStr, &ColorMapFlag,
  84.         &EncodedFlag, &LZCodesFlag, &PixelFlag, &RawFlag, &HelpFlag,
  85.         &NumFiles, &FileName)) != FALSE ||
  86.     (NumFiles > 1 && !HelpFlag)) {
  87.     if (Error)
  88.         GAPrintErrMsg(Error);
  89.     else if (NumFiles > 1)
  90.         GIF_MESSAGE("Error in command line parsing - one GIF file please.");
  91.     GAPrintHowTo(CtrlStr);
  92.     exit(1);
  93.     }
  94.  
  95.     if (HelpFlag) {
  96.     fprintf(stderr, VersionStr);
  97.     GAPrintHowTo(CtrlStr);
  98.     exit(0);
  99.     }
  100.  
  101.     if (NumFiles == 1) {
  102.     GifFileName = *FileName;
  103.     if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
  104.         PrintGifError();
  105.         exit(-1);
  106.     }
  107.     }
  108.     else {
  109.     /* Use the stdin instead: */
  110.     GifFileName = "Stdin";
  111.     if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
  112.         PrintGifError();
  113.         exit(-1);
  114.     }
  115.     }
  116.  
  117.     /* Because we write binary data - make sure no text will be written. */
  118.     if (RawFlag) {
  119.     ColorMapFlag = EncodedFlag = LZCodesFlag = PixelFlag = FALSE;
  120. #ifdef __MSDOS__
  121.     setmode(1, O_BINARY);             /* Make sure it is in binary mode. */
  122. #endif /* __MSDOS__ */
  123.     }
  124.     else {
  125.     printf("\n%s:\n\n\tScreen Size - Width = %d, Height = %d.\n",
  126.            GifFileName, GifFile -> SWidth, GifFile -> SHeight);
  127.     printf("\tColorResolution = %d, BitsPerPixel = %d, BackGround = %d.\n",
  128.            GifFile -> SColorResolution, GifFile -> SBitsPerPixel,
  129.            GifFile -> SBackGroundColor);
  130.     if (GifFile -> SColorMap)
  131.         printf("\tHas Global Color Map.\n\n");
  132.     else
  133.         printf("\tNo Global Color Map.\n\n");
  134.     if (ColorMapFlag && GifFile -> SColorMap) {
  135.         printf("\tGlobal Color Map:\n");
  136.         Len = 1 << GifFile -> SBitsPerPixel;
  137.         for (i = 0; i < Len; i+=4) {
  138.         for (j = 0; j < 4 && j < Len; j++) {
  139.             printf("%3d: %02xh %02xh %02xh   ", i + j,
  140.                GifFile -> SColorMap[i + j].Red,
  141.                GifFile -> SColorMap[i + j].Green,
  142.                GifFile -> SColorMap[i + j].Blue);
  143.         }
  144.         printf("\n");
  145.         }
  146.     }
  147.     }
  148.  
  149.     do {
  150.     if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
  151.         PrintGifError();
  152.         exit(-1);
  153.     }
  154.     switch (RecordType) {
  155.         case IMAGE_DESC_RECORD_TYPE:
  156.         if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
  157.             PrintGifError();
  158.             exit(-1);
  159.         }
  160.         if (!RawFlag) {
  161.             printf("\nImage #%d:\n\n\tImage Size - Left = %d, Top = %d, Width = %d, Height = %d.\n",
  162.                ImageNum++, GifFile -> ILeft, GifFile -> ITop,
  163.                GifFile -> IWidth, GifFile -> IHeight);
  164.             printf("\tImage is %s",
  165.                GifFile -> IInterlace ? "Interlaced" :
  166.                             "Non Interlaced");
  167.             if (GifFile -> IColorMap != NULL)
  168.             printf(", BitsPerPixel = %d.\n",
  169.                         GifFile -> IBitsPerPixel);
  170.             else
  171.             printf(".\n");
  172.             if (GifFile -> IColorMap)
  173.             printf("\tImage Has Color Map.\n");
  174.             else
  175.             printf("\tNo Image Color Map.\n");
  176.             if (ColorMapFlag && GifFile -> IColorMap) {
  177.             Len = 1 << GifFile -> IBitsPerPixel;
  178.             for (i = 0; i < Len; i+=4) {
  179.                 for (j = 0; j < 4 && j < Len; j++) {
  180.                 printf("%3d: %02xh %02xh %02xh   ", i + j,
  181.                        GifFile -> IColorMap[i + j].Red,
  182.                        GifFile -> IColorMap[i + j].Green,
  183.                        GifFile -> IColorMap[i + j].Blue);
  184.                 }
  185.                 printf("\n");
  186.             }
  187.             }
  188.         }
  189.  
  190.         if (EncodedFlag) {
  191.             if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
  192.             PrintGifError();
  193.             exit(-1);
  194.             }
  195.             printf("\nImage LZ compressed Codes (Code Size = %d):\n",
  196.                CodeSize);
  197.             PrintCodeBlock(GifFile, CodeBlock, TRUE);
  198.             while (CodeBlock != NULL) {
  199.             if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
  200.                 PrintGifError();
  201.                 exit(-1);
  202.             }
  203.             PrintCodeBlock(GifFile, CodeBlock, FALSE);
  204.             }
  205.         }
  206.         else if (LZCodesFlag) {
  207.             PrintLZCodes(GifFile);
  208.         }
  209.         else if (PixelFlag) {
  210.             Line = (GifPixelType *) malloc(GifFile -> IWidth *
  211.                         sizeof(GifPixelType));
  212.             for (i = 0; i < GifFile -> IHeight; i++) {
  213.             if (DGifGetLine(GifFile, Line, GifFile -> IWidth)
  214.                 == GIF_ERROR) {
  215.                 PrintGifError();
  216.                 exit(-1);
  217.             }
  218.             PrintPixelBlock(Line, GifFile -> IWidth, i == 0);
  219.             }
  220.             PrintPixelBlock(NULL, GifFile -> IWidth, FALSE);
  221.             free((char *) Line);
  222.         }
  223.         else if (RawFlag) {
  224.             Line = (GifPixelType *) malloc(GifFile -> IWidth *
  225.                         sizeof(GifPixelType));
  226.             for (i = 0; i < GifFile -> IHeight; i++) {
  227.             if (DGifGetLine(GifFile, Line, GifFile -> IWidth)
  228.                 == GIF_ERROR) {
  229.                 PrintGifError();
  230.                 exit(-1);
  231.             }
  232.             fwrite(Line, 1, GifFile -> IWidth, stdout);
  233.             }
  234.             free((char *) Line);
  235.         }
  236.         else {
  237.             /* Skip the image: */
  238.             if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
  239.             PrintGifError();
  240.             exit(-1);
  241.             }
  242.             while (CodeBlock != NULL) {
  243.             if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
  244.                 PrintGifError();
  245.                 exit(-1);
  246.             }
  247.             }
  248.  
  249.         }
  250.         break;
  251.         case EXTENSION_RECORD_TYPE:
  252.         if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
  253.             PrintGifError();
  254.             exit(-1);
  255.         }
  256.         if (!RawFlag) {
  257.             printf("\nExtension Record (Ext Code = %d [%c]):\n",
  258.                ExtCode, MAKE_PRINTABLE(ExtCode));
  259.             PrintExtBlock(Extension, TRUE);
  260.         }
  261.         while (Extension != NULL) {
  262.             if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
  263.             PrintGifError();
  264.             exit(-1);
  265.             }
  266.             PrintExtBlock(Extension, FALSE);
  267.         }
  268.         break;
  269.         case TERMINATE_RECORD_TYPE:
  270.         break;
  271.         default:             /* Should be traps by DGifGetRecordType */
  272.         break;
  273.     }
  274.     }
  275.     while (RecordType != TERMINATE_RECORD_TYPE);
  276.  
  277.     if (DGifCloseFile(GifFile) == GIF_ERROR) {
  278.     PrintGifError();
  279.     exit(-1);
  280.     }
  281.  
  282.     if (!RawFlag) printf("\nGif file terminated normally.\n");
  283. }
  284.  
  285. /******************************************************************************
  286. * Print the given CodeBlock - a string in pascal notation (size in first      *
  287. * place). Save local information so printing can be performed continuously,   *
  288. * or reset to start state if Reset. If CodeBlock is NULL, output is flushed   *
  289. ******************************************************************************/
  290. static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset)
  291. {
  292.     static int CrntPlace = 0, Print = TRUE;
  293.     static long CodeCount = 0;
  294.     char c;
  295.     int i, Percent, Len;
  296.     long NumBytes;
  297.  
  298.     if (Reset || CodeBlock == NULL) {
  299.     if (CodeBlock == NULL) {
  300.         if (CrntPlace > 0) {
  301.         if (Print) printf("\n");
  302.         CodeCount += CrntPlace - 16;
  303.         }
  304.         if (GifFile -> IColorMap)
  305.         NumBytes = ((((long) GifFile -> IWidth) * GifFile -> IHeight)
  306.                 * GifFile -> IBitsPerPixel) / 8;
  307.         else
  308.         NumBytes = ((((long) GifFile -> IWidth) * GifFile -> IHeight)
  309.                 * GifFile -> SBitsPerPixel) / 8;
  310.         Percent = 100 * CodeCount / NumBytes;
  311.         printf("\nCompression ratio: %ld/%ld (%d%%).\n",
  312.             CodeCount, NumBytes, Percent);
  313.         return;
  314.     }
  315.     CrntPlace = 0;
  316.     CodeCount = 0;
  317.     Print = TRUE;
  318.     }
  319.  
  320.     Len = CodeBlock[0];
  321.     for (i = 1; i <= Len; i++) {
  322.     if (CrntPlace == 0) {
  323.         if (Print) printf("\n%05lxh:  ", CodeCount);
  324.         CodeCount += 16;
  325.     }
  326. #ifdef __MSDOS__
  327.     if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
  328. #endif /* __MSDOS__ */
  329.     if (Print) printf(" %02xh", CodeBlock[i]);
  330.     if (++CrntPlace >= 16) CrntPlace = 0;
  331.     }
  332. }
  333.  
  334. /******************************************************************************
  335. * Print the given Extension - a string in pascal notation (size in first      *
  336. * place). Save local information so printing can be performed continuously,   *
  337. * or reset to start state if Reset. If Extension is NULL, output is flushed   *
  338. ******************************************************************************/
  339. static void PrintExtBlock(GifByteType *Extension, int Reset)
  340. {
  341.     static int CrntPlace = 0, Print = TRUE;
  342.     static long ExtCount = 0;
  343.     static char HexForm[49], AsciiForm[17];
  344.     char c;
  345.     int i, Len;
  346.  
  347.     if (Reset || Extension == NULL) {
  348.     if (Extension == NULL) {
  349.         if (CrntPlace > 0) {
  350.         HexForm[CrntPlace * 3] = 0;
  351.         AsciiForm[CrntPlace] = 0;
  352.         if (Print) printf("\n%05lx: %-49s  %-17s\n",
  353.                 ExtCount, HexForm, AsciiForm);
  354.         return;
  355.         }
  356.         else if (Print)
  357.         printf("\n");
  358.     }
  359.     CrntPlace = 0;
  360.     ExtCount = 0;
  361.     Print = TRUE;
  362.     }
  363.  
  364.     if (!Print) return;
  365.  
  366.     Len = Extension[0];
  367.     for (i = 1; i <= Len; i++) {
  368.     sprintf(&HexForm[CrntPlace * 3], " %02x", Extension[i]);
  369.     sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(Extension[i]));
  370. #ifdef __MSDOS__
  371.     if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
  372. #endif /* __MSDOS__ */
  373.     if (++CrntPlace == 16) {
  374.         HexForm[CrntPlace * 3] = 0;
  375.         AsciiForm[CrntPlace] = 0;
  376.         if (Print) printf("\n%05lx: %-49s  %-17s",
  377.                 ExtCount, HexForm, AsciiForm);
  378.         ExtCount += 16;
  379.         CrntPlace = 0;
  380.     }
  381.     }
  382. }
  383.  
  384. /******************************************************************************
  385. * Print the given PixelBlock of length Len.                      *
  386. * Save local information so printing can be performed continuously,           *
  387. * or reset to start state if Reset. If PixelBlock is NULL, output is flushed  *
  388. ******************************************************************************/
  389. static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset)
  390. {
  391.     static int CrntPlace = 0, Print = TRUE;
  392.     static long ExtCount = 0;
  393.     static char HexForm[49], AsciiForm[17];
  394.     char c;
  395.     int i;
  396.  
  397.     if (Reset || PixelBlock == NULL) {
  398.     if (PixelBlock == NULL) {
  399.         if (CrntPlace > 0) {
  400.         HexForm[CrntPlace * 3] = 0;
  401.         AsciiForm[CrntPlace] = 0;
  402.         if (Print) printf("\n%05lx: %-49s  %-17s\n",
  403.                 ExtCount, HexForm, AsciiForm);
  404.         }
  405.         else if (Print)
  406.         printf("\n");
  407.     }
  408.     CrntPlace = 0;
  409.     ExtCount = 0;
  410.     Print = TRUE;
  411.     if (PixelBlock == NULL) return;
  412.     }
  413.  
  414.     if (!Print) return;
  415.  
  416.     for (i = 0; i < Len; i++) {
  417.     sprintf(&HexForm[CrntPlace * 3], " %02x", PixelBlock[i]);
  418.     sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(PixelBlock[i]));
  419. #ifdef __MSDOS__
  420.     if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
  421. #endif /* __MSDOS__ */
  422.     if (++CrntPlace == 16) {
  423.         HexForm[CrntPlace * 3] = 0;
  424.         AsciiForm[CrntPlace] = 0;
  425.         if (Print) printf("\n%05lx: %-49s  %-17s",
  426.                 ExtCount, HexForm, AsciiForm);
  427.         ExtCount += 16;
  428.         CrntPlace = 0;
  429.     }
  430.     }
  431. }
  432.  
  433. /******************************************************************************
  434. * Print the image as LZ codes (each 12bits), until EOF marker is reached.     *
  435. ******************************************************************************/
  436. static void PrintLZCodes(GifFileType *GifFile)
  437. {
  438.     char c;
  439.     int Code, Print = TRUE, CrntPlace = 0;
  440.     long CodeCount = 0;
  441.  
  442.     do {
  443.     if (Print && CrntPlace == 0) printf("\n%05lx:", CodeCount);
  444.     if (DGifGetLZCodes(GifFile, &Code) == GIF_ERROR) {
  445.         PrintGifError();
  446.         exit(-1);
  447.     }
  448.     if (Print && Code >= 0)
  449.         printf(" %03x", Code);          /* EOF Code is returned as -1. */
  450.     CodeCount++;
  451.     if (++CrntPlace >= 16) CrntPlace = 0;
  452. #ifdef __MSDOS__
  453.     if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
  454. #endif /* __MSDOS__ */
  455.     }
  456.     while (Code >= 0);
  457. }
  458.