home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / graphics / gif-util.zip / GIFTEXT.C < prev    next >
C/C++ Source or Header  |  1989-08-01  |  13KB  |  402 lines

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