Logo Search packages:      
Sourcecode: giflib version File versions  Download package

giftext.c

/*****************************************************************************
*   "Gif-Lib" - Yet another gif library.                         *
*                                                          *
* Written by:  Gershon Elber                    Ver 0.1, Jun. 1989   *
******************************************************************************
* Program to dump GIF file content as TEXT information                       *
* Options:                                                 *
* -q : quiet printing mode.                                      *
* -c : include the color maps as well.                                 *
* -e : include encoded information packed as bytes as well.            *
* -z : include encoded information (12bits) codes as result from the zl alg. *
* -p : dump pixel information instead of encoded information.                *
* -r : same as -p but dump one pixel as one byte in binary form with no      *
*      other information. This will create a file of size Width by Height.   *
* -h : on-line help.                                             *
******************************************************************************
* History:                                                 *
* 28 Jun 89 - Version 1.0 by Gershon Elber.                            *
* 21 Dec 89 - Fix segmentation fault problem in PrintCodeBlock (Version 1.1) *
* 25 Dec 89 - Add the -r flag for raw output.                                *
*****************************************************************************/

#ifdef __MSDOS__
#include <stdlib.h>
#include <alloc.h>
#include <conio.h>
#include <io.h>
#endif /* __MSDOS__ */

#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include "gif_lib.h"
#include "getarg.h"

#define PROGRAM_NAME    "GifText"

#define MAKE_PRINTABLE(c)  (isprint(c) ? (c) : ' ')

#ifdef __MSDOS__
extern unsigned int
    _stklen = 16384;                     /* Increase default stack size. */
#endif /* __MSDOS__ */

#ifdef SYSV
static char *VersionStr =
        "Gif toolkit module,\t\tGershon Elber\n\
      (C) Copyright 1989 Gershon Elber.\n";
static char
    *CtrlStr = "GifText q%- c%- e%- z%- p%- r%- h%- GifFile!*s";
#else
static char
    *VersionStr =
      PROGRAM_NAME
      GIF_LIB_VERSION
      "     Gershon Elber,    "
      __DATE__ ",   " __TIME__ "\n"
      "(C) Copyright 1989 Gershon Elber.\n";
static char
    *CtrlStr =
      PROGRAM_NAME
      " q%- c%- e%- z%- p%- r%- h%- GifFile!*s";
#endif /* SYSV */

static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset);
static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset);
static void PrintExtBlock(GifByteType *Extension, int Reset);
static void PrintLZCodes(GifFileType *GifFile);

/******************************************************************************
* Interpret the command line and scan the given GIF file.               *
******************************************************************************/
void main(int argc, char **argv)
{
    int i, j, ExtCode, CodeSize, Error, NumFiles, Len,
      ColorMapFlag = FALSE, EncodedFlag = FALSE, LZCodesFlag = FALSE,
      PixelFlag = FALSE, HelpFlag = FALSE, RawFlag = FALSE, ImageNum = 1;
    char *GifFileName, **FileName = NULL;
    GifPixelType *Line;
    GifRecordType RecordType;
    GifByteType *CodeBlock, *Extension;
    GifFileType *GifFile;

    if ((Error = GAGetArgs(argc, argv, CtrlStr,
            &GifQuietPrint, &ColorMapFlag, &EncodedFlag,
            &LZCodesFlag, &PixelFlag, &RawFlag, &HelpFlag,
            &NumFiles, &FileName)) != FALSE ||
      (NumFiles > 1 && !HelpFlag)) {
      if (Error)
          GAPrintErrMsg(Error);
      else if (NumFiles > 1)
          GIF_MESSAGE("Error in command line parsing - one GIF file please.");
      GAPrintHowTo(CtrlStr);
      exit(1);
    }

    if (HelpFlag) {
      fprintf(stderr, VersionStr);
      GAPrintHowTo(CtrlStr);
      exit(0);
    }

    if (NumFiles == 1) {
      GifFileName = *FileName;
      if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
          PrintGifError();
          exit(-1);
      }
    }
    else {
      /* Use the stdin instead: */
      GifFileName = "Stdin";
      if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
          PrintGifError();
          exit(-1);
      }
    }

    /* Because we write binary data - make sure no text will be written. */
    if (RawFlag) {
      ColorMapFlag = EncodedFlag = LZCodesFlag = PixelFlag = FALSE;
#ifdef __MSDOS__
      setmode(1, O_BINARY);             /* Make sure it is in binary mode. */
#endif /* __MSDOS__ */
    }
    else {
      printf("\n%s:\n\n\tScreen Size - Width = %d, Height = %d.\n",
             GifFileName, GifFile->SWidth, GifFile->SHeight);
      printf("\tColorResolution = %d, BitsPerPixel = %d, BackGround = %d.\n",
             GifFile->SColorResolution,
             GifFile->SColorMap->BitsPerPixel,
             GifFile->SBackGroundColor);
      if (GifFile->SColorMap)
          printf("\tHas Global Color Map.\n\n");
      else
          printf("\tNo Global Color Map.\n\n");
      if (ColorMapFlag && GifFile->SColorMap) {
          printf("\tGlobal Color Map:\n");
          Len = GifFile->SColorMap->ColorCount;
          for (i = 0; i < Len; i+=4) {
            for (j = 0; j < 4 && j < Len; j++) {
                printf("%3d: %02xh %02xh %02xh   ", i + j,
                     GifFile->SColorMap->Colors[i + j].Red,
                     GifFile->SColorMap->Colors[i + j].Green,
                     GifFile->SColorMap->Colors[i + j].Blue);
            }
            printf("\n");
          }
      }
    }

    do {
      if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
          PrintGifError();
          exit(-1);
      }
      switch (RecordType) {
          case IMAGE_DESC_RECORD_TYPE:
            if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
                PrintGifError();
                exit(-1);
            }
            if (!RawFlag) {
                printf("\nImage #%d:\n\n\tImage Size - Left = %d, Top = %d, Width = %d, Height = %d.\n",
                     ImageNum++, GifFile->Image.Left, GifFile->Image.Top,
                     GifFile->Image.Width, GifFile->Image.Height);
                printf("\tImage is %s",
                     GifFile->Image.Interlace ? "Interlaced" :
                                        "Non Interlaced");
                if (GifFile->Image.ColorMap != NULL)
                  printf(", BitsPerPixel = %d.\n",
                        GifFile->Image.ColorMap->BitsPerPixel);
                else
                  printf(".\n");
                if (GifFile->Image.ColorMap)
                  printf("\tImage Has Color Map.\n");
                else
                  printf("\tNo Image Color Map.\n");
                if (ColorMapFlag && GifFile->Image.ColorMap) {
                  Len = 1 << GifFile->Image.ColorMap->BitsPerPixel;
                  for (i = 0; i < Len; i+=4) {
                      for (j = 0; j < 4 && j < Len; j++) {
                        printf("%3d: %02xh %02xh %02xh   ", i + j,
                               GifFile->Image.ColorMap->Colors[i + j].Red,
                               GifFile->Image.ColorMap->Colors[i + j].Green,
                               GifFile->Image.ColorMap->Colors[i + j].Blue);
                      }
                      printf("\n");
                  }
                }
            }

            if (EncodedFlag) {
                if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
                  PrintGifError();
                  exit(-1);
                }
                printf("\nImage LZ compressed Codes (Code Size = %d):\n",
                     CodeSize);
                PrintCodeBlock(GifFile, CodeBlock, TRUE);
                while (CodeBlock != NULL) {
                  if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
                      PrintGifError();
                      exit(-1);
                  }
                  PrintCodeBlock(GifFile, CodeBlock, FALSE);
                }
            }
            else if (LZCodesFlag) {
                PrintLZCodes(GifFile);
            }
            else if (PixelFlag) {
                Line = (GifPixelType *) malloc(GifFile->Image.Width *
                                    sizeof(GifPixelType));
                for (i = 0; i < GifFile->Image.Height; i++) {
                  if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
                      == GIF_ERROR) {
                      PrintGifError();
                      exit(-1);
                  }
                  PrintPixelBlock(Line, GifFile->Image.Width, i == 0);
                }
                PrintPixelBlock(NULL, GifFile->Image.Width, FALSE);
                free((char *) Line);
            }
            else if (RawFlag) {
                Line = (GifPixelType *) malloc(GifFile->Image.Width *
                                    sizeof(GifPixelType));
                for (i = 0; i < GifFile->Image.Height; i++) {
                  if (DGifGetLine(GifFile, Line, GifFile->Image.Width)
                      == GIF_ERROR) {
                      PrintGifError();
                      exit(-1);
                  }
                  fwrite(Line, 1, GifFile->Image.Width, stdout);
                }
                free((char *) Line);
            }
            else {
                /* Skip the image: */
                if (DGifGetCode(GifFile, &CodeSize, &CodeBlock) == GIF_ERROR) {
                  PrintGifError();
                  exit(-1);
                }
                while (CodeBlock != NULL) {
                  if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR) {
                      PrintGifError();
                      exit(-1);
                  }
                }

            }
            break;
          case EXTENSION_RECORD_TYPE:
            if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
                PrintGifError();
                exit(-1);
            }
            if (!RawFlag) {
                putchar('\n');
                switch (ExtCode)
                {
                case COMMENT_EXT_FUNC_CODE:
                  printf("GIF89 comment");
                  break;
                case GRAPHICS_EXT_FUNC_CODE:
                  printf("GIF89 graphics control");
                  break;
                case PLAINTEXT_EXT_FUNC_CODE:
                  printf("GIF89 plaintext");
                  break;
                case APPLICATION_EXT_FUNC_CODE:
                  printf("GIF89 application block");
                  break;
                default:
                  printf("Extension record of unknown type");
                  break;
                }
                printf(" (Ext Code = %d [%c]):\n",
                     ExtCode, MAKE_PRINTABLE(ExtCode));
                PrintExtBlock(Extension, TRUE);
            }
            for (;;) {
                if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
                  PrintGifError();
                  exit(-1);
                }
                if (Extension == NULL)
                  break;
                PrintExtBlock(Extension, FALSE);
            }
            break;
          case TERMINATE_RECORD_TYPE:
            break;
          default:                 /* Should be traps by DGifGetRecordType */
            break;
      }
    }
    while (RecordType != TERMINATE_RECORD_TYPE);

    if (DGifCloseFile(GifFile) == GIF_ERROR) {
      PrintGifError();
      exit(-1);
    }

    if (!RawFlag) printf("\nGif file terminated normally.\n");
}

/******************************************************************************
* Print the given CodeBlock - a string in pascal notation (size in first      *
* place). Save local information so printing can be performed continuously,   *
* or reset to start state if Reset. If CodeBlock is NULL, output is flushed   *
******************************************************************************/
static void PrintCodeBlock(GifFileType *GifFile, GifByteType *CodeBlock, int Reset)
{
    static int CrntPlace = 0, Print = TRUE;
    static long CodeCount = 0;
    char c;
    int i, Percent, Len;
    long NumBytes;

    if (Reset || CodeBlock == NULL) {
      if (CodeBlock == NULL) {
          if (CrntPlace > 0) {
            if (Print) printf("\n");
            CodeCount += CrntPlace - 16;
          }
          if (GifFile->Image.ColorMap)
            NumBytes = ((((long) GifFile->Image.Width) * GifFile->Image.Height)
                        * GifFile->Image.ColorMap->BitsPerPixel) / 8;
          else
            NumBytes = ((((long) GifFile->Image.Width) * GifFile->Image.Height)
                        * GifFile->SColorMap->BitsPerPixel) / 8;
          Percent = 100 * CodeCount / NumBytes;
          printf("\nCompression ratio: %ld/%ld (%d%%).\n",
                  CodeCount, NumBytes, Percent);
          return;
      }
      CrntPlace = 0;
      CodeCount = 0;
      Print = TRUE;
    }

    Len = CodeBlock[0];
    for (i = 1; i <= Len; i++) {
      if (CrntPlace == 0) {
          if (Print) printf("\n%05lxh:  ", CodeCount);
          CodeCount += 16;
      }
#ifdef __MSDOS__
      if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
#endif /* __MSDOS__ */
      if (Print) printf(" %02xh", CodeBlock[i]);
      if (++CrntPlace >= 16) CrntPlace = 0;
    }
}

/******************************************************************************
* Print the given Extension - a string in pascal notation (size in first      *
* place). Save local information so printing can be performed continuously,   *
* or reset to start state if Reset. If Extension is NULL, output is flushed   *
******************************************************************************/
static void PrintExtBlock(GifByteType *Extension, int Reset)
{
    static int CrntPlace = 0, Print = TRUE;
    static long ExtCount = 0;
    static char HexForm[49], AsciiForm[17];
    char c;
    int i, Len;

    if (Reset || Extension == NULL) {
      if (Extension == NULL) {
          if (CrntPlace > 0) {
            HexForm[CrntPlace * 3] = 0;
            AsciiForm[CrntPlace] = 0;
            if (Print) printf("\n%05lx: %-49s  %-17s\n",
                        ExtCount, HexForm, AsciiForm);
            return;
          }
          else if (Print)
            printf("\n");
      }
      CrntPlace = 0;
      ExtCount = 0;
      Print = TRUE;
    }

    if (!Print) return;

    Len = Extension[0];
    for (i = 1; i <= Len; i++) {
      sprintf(&HexForm[CrntPlace * 3], " %02x", Extension[i]);
      sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(Extension[i]));
#ifdef __MSDOS__
      if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
#endif /* __MSDOS__ */
      if (++CrntPlace == 16) {
          HexForm[CrntPlace * 3] = 0;
          AsciiForm[CrntPlace] = 0;
          if (Print) printf("\n%05lx: %-49s  %-17s",
                        ExtCount, HexForm, AsciiForm);
          ExtCount += 16;
          CrntPlace = 0;
      }
    }
}

/******************************************************************************
* Print the given PixelBlock of length Len.                             *
* Save local information so printing can be performed continuously,           *
* or reset to start state if Reset. If PixelBlock is NULL, output is flushed  *
******************************************************************************/
static void PrintPixelBlock(GifByteType *PixelBlock, int Len, int Reset)
{
    static int CrntPlace = 0, Print = TRUE;
    static long ExtCount = 0;
    static char HexForm[49], AsciiForm[17];
    char c;
    int i;

    if (Reset || PixelBlock == NULL) {
      if (PixelBlock == NULL) {
          if (CrntPlace > 0) {
            HexForm[CrntPlace * 3] = 0;
            AsciiForm[CrntPlace] = 0;
            if (Print) printf("\n%05lx: %-49s  %-17s\n",
                        ExtCount, HexForm, AsciiForm);
          }
          else if (Print)
            printf("\n");
      }
      CrntPlace = 0;
      ExtCount = 0;
      Print = TRUE;
      if (PixelBlock == NULL) return;
    }

    if (!Print) return;

    for (i = 0; i < Len; i++) {
      sprintf(&HexForm[CrntPlace * 3], " %02x", PixelBlock[i]);
      sprintf(&AsciiForm[CrntPlace], "%c", MAKE_PRINTABLE(PixelBlock[i]));
#ifdef __MSDOS__
      if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
#endif /* __MSDOS__ */
      if (++CrntPlace == 16) {
          HexForm[CrntPlace * 3] = 0;
          AsciiForm[CrntPlace] = 0;
          if (Print) printf("\n%05lx: %-49s  %-17s",
                        ExtCount, HexForm, AsciiForm);
          ExtCount += 16;
          CrntPlace = 0;
      }
    }
}

/******************************************************************************
* Print the image as LZ codes (each 12bits), until EOF marker is reached.     *
******************************************************************************/
static void PrintLZCodes(GifFileType *GifFile)
{
    char c;
    int Code, Print = TRUE, CrntPlace = 0;
    long CodeCount = 0;

    do {
      if (Print && CrntPlace == 0) printf("\n%05lx:", CodeCount);
      if (DGifGetLZCodes(GifFile, &Code) == GIF_ERROR) {
          PrintGifError();
          exit(-1);
      }
      if (Print && Code >= 0)
          printf(" %03x", Code);          /* EOF Code is returned as -1. */
      CodeCount++;
      if (++CrntPlace >= 16) CrntPlace = 0;
#ifdef __MSDOS__
      if (kbhit() && ((c = getch()) == 'q' || c == 'Q')) Print = FALSE;
#endif /* __MSDOS__ */
    }
    while (Code >= 0);
}

Generated by  Doxygen 1.6.0   Back to index