home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / viewers / giflib12 / util / gif2rgb.c < prev    next >
C/C++ Source or Header  |  1991-08-02  |  10KB  |  338 lines

  1. /*****************************************************************************
  2. *   "Gif-Lib" - Yet another gif library.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, Jul. 1989   *
  5. ******************************************************************************
  6. * Program to convert GIF file to RGB 24 bits.                     *
  7. * Options:                                     *
  8. * -q : quite printing mode.                             *
  9. * -1 : dump as one file using RGBRGB triples.                     *
  10. * -h : on line help.                                 *
  11. * -o FileName : specify the output file name(s).                 *
  12. ******************************************************************************
  13. * History:                                     *
  14. * 5 Jan 90 - Version 1.0 by Gershon Elber.                     *
  15. *****************************************************************************/
  16.  
  17. #ifdef __MSDOS__
  18. #include <graphics.h>
  19. #include <stdlib.h>
  20. #include <alloc.h>
  21. #include <io.h>
  22. #include <dos.h>
  23. #include <bios.h>
  24. #endif /* __MSDOS__ */
  25.  
  26. #include <stdio.h>
  27. #include <ctype.h>
  28. #include <string.h>
  29. #include <fcntl.h>
  30. #include "gif_lib.h"
  31. #include "getarg.h"
  32.  
  33. #define PROGRAM_NAME    "Gif2RGB"
  34.  
  35. #ifdef __MSDOS__
  36. extern unsigned int
  37.     _stklen = 16384;                 /* Increase default stack size. */
  38. #endif /* __MSDOS__ */
  39.  
  40. #ifdef SYSV
  41. static char *VersionStr =
  42.     "Gif library module,\t\tGershon Elber\n\
  43.     (C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  44. static char
  45.     *CtrlStr = "Gif2RGB q%- 1%- o%-OutFileName!s h%- GifFile!*s";
  46. #else
  47. static char
  48.     *VersionStr =
  49.     PROGRAM_NAME
  50.     GIF_LIB_VERSION
  51.     "    Gershon Elber,    "
  52.     __DATE__ ",   " __TIME__ "\n"
  53.     "(C) Copyright 1989 Gershon Elber, Non commercial use only.\n";
  54. static char
  55.     *CtrlStr =
  56.     PROGRAM_NAME
  57.     " q%- 1%- o%-OutFileName!s h%- GifFile!*s";
  58. #endif /* SYSV */
  59.  
  60. /* Make some variables global, so we could access them faster: */
  61. static int
  62.     ImageNum = 0,
  63.     BackGround = 0,
  64.     OneFileFlag = FALSE,
  65.     HelpFlag = FALSE,
  66.     ColorMapSize = 0,
  67.     InterlacedOffset[] = { 0, 4, 2, 1 }, /* The way Interlaced image should. */
  68.     InterlacedJumps[] = { 8, 8, 4, 2 };    /* be read - offsets and jumps... */
  69. static GifColorType
  70.     *ColorMap;
  71.  
  72. static void DumpScreen2RGB(char *FileName, int OneFileFlag,
  73.                GifRowType *ScreenBuffer,
  74.                int ScreenWidth, int ScreenHeight);
  75.  
  76. /******************************************************************************
  77. * Interpret the command line and scan the given GIF file.              *
  78. ******************************************************************************/
  79. void main(int argc, char **argv)
  80. {
  81.     int    i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count,
  82.     OutFileFlag = FALSE;
  83.     GifRecordType RecordType;
  84.     GifByteType *Extension;
  85.     char *OutFileName,
  86.     **FileName = NULL;
  87.     GifRowType *ScreenBuffer;
  88.     GifFileType *GifFile;
  89.  
  90.     if ((Error = GAGetArgs(argc, argv, CtrlStr, &GifQuitePrint,
  91.         &OneFileFlag, &OutFileFlag, &OutFileName,
  92.         &HelpFlag, &NumFiles, &FileName)) != FALSE ||
  93.         (NumFiles > 1 && !HelpFlag)) {
  94.     if (Error)
  95.         GAPrintErrMsg(Error);
  96.     else if (NumFiles > 1)
  97.         GIF_MESSAGE("Error in command line parsing - one GIF file please.");
  98.     GAPrintHowTo(CtrlStr);
  99.     exit(1);
  100.     }
  101.  
  102.     if (HelpFlag) {
  103.     fprintf(stderr, VersionStr);
  104.     GAPrintHowTo(CtrlStr);
  105.     exit(0);
  106.     }
  107.  
  108.     if (!OutFileFlag) OutFileName = NULL;
  109.  
  110.     if (NumFiles == 1) {
  111.     if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
  112.         PrintGifError();
  113.         exit(-1);
  114.     }
  115.     }
  116.     else {
  117.     /* Use the stdin instead: */
  118.  
  119. #ifdef __MSDOS__
  120.     setmode(0, O_BINARY);
  121. #endif /* __MSDOS__ */
  122.     if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
  123.         PrintGifError();
  124.         exit(-1);
  125.     }
  126.     }
  127.  
  128.     /* Allocate the screen as vector of column of rows. We cannt allocate    */
  129.     /* the all screen at once, as this broken minded CPU can allocate up to  */
  130.     /* 64k at a time and our image can be bigger than that:             */
  131.     /* Note this screen is device independent - its the screen as defined by */
  132.     /* the GIF file parameters itself.                         */
  133.     if ((ScreenBuffer = (GifRowType *)
  134.     malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
  135.         GIF_EXIT("Failed to allocate memory required, aborted.");
  136.  
  137.     Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
  138.     if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
  139.     GIF_EXIT("Failed to allocate memory required, aborted.");
  140.  
  141.     for (i = 0; i < GifFile -> SWidth; i++)  /* Set its color to BackGround. */
  142.     ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
  143.     for (i = 1; i < GifFile -> SHeight; i++) {
  144.     /* Allocate the other rows, and set their color to background too: */
  145.     if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
  146.         GIF_EXIT("Failed to allocate memory required, aborted.");
  147.  
  148.     memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
  149.     }
  150.  
  151.     /* Scan the content of the GIF file and load the image(s) in: */
  152.     do {
  153.     if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
  154.         PrintGifError();
  155.         exit(-1);
  156.     }
  157.     switch (RecordType) {
  158.         case IMAGE_DESC_RECORD_TYPE:
  159.         if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
  160.             PrintGifError();
  161.             exit(-1);
  162.         }
  163.         Row = GifFile -> ITop; /* Image Position relative to Screen. */
  164.         Col = GifFile -> ILeft;
  165.         Width = GifFile -> IWidth;
  166.         Height = GifFile -> IHeight;
  167.         GifQprintf("\n%s: Image %d at (%d, %d) [%dx%d]:     ",
  168.             PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
  169.         if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
  170.            GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
  171.             fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
  172.             exit(-2);
  173.         }
  174.         if (GifFile -> IInterlace) {
  175.             /* Need to perform 4 passes on the images: */
  176.             for (Count = i = 0; i < 4; i++)
  177.             for (j = Row + InterlacedOffset[i]; j < Row + Height;
  178.                          j += InterlacedJumps[i]) {
  179.                 GifQprintf("\b\b\b\b%-4d", Count++);
  180.                 if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
  181.                 Width) == GIF_ERROR) {
  182.                 PrintGifError();
  183.                 exit(-1);
  184.                 }
  185.             }
  186.         }
  187.         else {
  188.             for (i = 0; i < Height; i++) {
  189.             GifQprintf("\b\b\b\b%-4d", i);
  190.             if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
  191.                 Width) == GIF_ERROR) {
  192.                 PrintGifError();
  193.                 exit(-1);
  194.             }
  195.             }
  196.         }
  197.         break;
  198.         case EXTENSION_RECORD_TYPE:
  199.         /* Skip any extension blocks in file: */
  200.         if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
  201.             PrintGifError();
  202.             exit(-1);
  203.         }
  204.         while (Extension != NULL) {
  205.             if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
  206.             PrintGifError();
  207.             exit(-1);
  208.             }
  209.         }
  210.         break;
  211.         case TERMINATE_RECORD_TYPE:
  212.         break;
  213.         default:            /* Should be traps by DGifGetRecordType. */
  214.         break;
  215.     }
  216.     }
  217.     while (RecordType != TERMINATE_RECORD_TYPE);
  218.  
  219.     /* Lets dump it - set the global variables required and do it: */
  220.     BackGround = GifFile -> SBackGroundColor;
  221.     ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
  222.                        GifFile -> SColorMap);
  223.     ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
  224.                                 GifFile -> SBitsPerPixel);
  225.     DumpScreen2RGB(OutFileName, OneFileFlag,
  226.            ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);
  227.  
  228.     if (DGifCloseFile(GifFile) == GIF_ERROR) {
  229.     PrintGifError();
  230.     exit(-1);
  231.     }
  232. }
  233.  
  234. /******************************************************************************
  235. * The real dumping routine.                              *
  236. ******************************************************************************/
  237. static void DumpScreen2RGB(char *FileName, int OneFileFlag,
  238.                GifRowType *ScreenBuffer,
  239.                int ScreenWidth, int ScreenHeight)
  240. {
  241.     int i, j;
  242.     GifRowType GifRow;
  243.     static GifColorType
  244.     *ColorMapEntry;
  245.     FILE *f[3];
  246.  
  247.     if (FileName != NULL) {
  248.     char OneFileName[80];
  249.  
  250.     if (OneFileFlag) {
  251. #ifdef __MSDOS__
  252.         if ((f[0] = fopen(FileName, "wb")) == NULL)
  253. #else
  254.         if ((f[0] = fopen(FileName, "w")) == NULL)
  255. #endif /* __MSDOS__ */
  256.         GIF_EXIT("Can't open input file name.");
  257.     }
  258.     else {
  259.         static char *Postfixes[] = { ".R", ".G", ".B" };
  260.  
  261.         for (i = 0; i < 3; i++) {
  262.         strcpy(OneFileName, FileName);
  263.         strcat(OneFileName, Postfixes[i]);
  264.  
  265. #ifdef __MSDOS__
  266.         if ((f[i] = fopen(OneFileName, "wb")) == NULL)
  267. #else
  268.         if ((f[i] = fopen(OneFileName, "w")) == NULL)
  269. #endif /* __MSDOS__ */
  270.  
  271.             GIF_EXIT("Can't open input file name.");
  272.         }
  273.     }
  274.     }
  275.     else {
  276.     OneFileFlag = TRUE;
  277.  
  278. #ifdef __MSDOS__
  279.     setmode(0, O_BINARY);
  280. #endif /* __MSDOS__ */
  281.  
  282.     f[0] = stdout;
  283.     }
  284.  
  285.     if (OneFileFlag) {
  286.     unsigned char *Buffer, *BufferP;
  287.  
  288.     if ((Buffer = (unsigned char *) malloc(ScreenWidth * 3)) == NULL)
  289.         GIF_EXIT("Failed to allocate memory required, aborted.");
  290.  
  291.     for (i = 0; i < ScreenHeight; i++) {
  292.         GifRow = ScreenBuffer[i];
  293.         GifQprintf("\b\b\b\b%-4d", ScreenHeight - i);
  294.         for (j = 0, BufferP = Buffer; j < ScreenWidth; j++) {
  295.         ColorMapEntry = &ColorMap[GifRow[j]];
  296.         *BufferP++ = ColorMapEntry -> Red;
  297.         *BufferP++ = ColorMapEntry -> Green;
  298.         *BufferP++ = ColorMapEntry -> Blue;
  299.         }
  300.         if (fwrite(Buffer, ScreenWidth * 3, 1, f[0]) != 1)
  301.         GIF_EXIT("Write to file(s) failed.");
  302.     }
  303.  
  304.     free((char *) Buffer);
  305.     fclose(f[0]);
  306.     }
  307.     else {
  308.     unsigned char *Buffers[3];
  309.  
  310.     if ((Buffers[0] = (unsigned char *) malloc(ScreenWidth)) == NULL ||
  311.         (Buffers[1] = (unsigned char *) malloc(ScreenWidth)) == NULL ||
  312.         (Buffers[2] = (unsigned char *) malloc(ScreenWidth)) == NULL)
  313.         GIF_EXIT("Failed to allocate memory required, aborted.");
  314.  
  315.     for (i = 0; i < ScreenHeight; i++) {
  316.         GifRow = ScreenBuffer[i];
  317.         GifQprintf("\b\b\b\b%-4d", ScreenHeight - i);
  318.         for (j = 0; j < ScreenWidth; j++) {
  319.         ColorMapEntry = &ColorMap[GifRow[j]];
  320.         Buffers[0][j] = ColorMapEntry -> Red;
  321.         Buffers[1][j] = ColorMapEntry -> Green;
  322.         Buffers[2][j] = ColorMapEntry -> Blue;
  323.         }
  324.         if (fwrite(Buffers[0], ScreenWidth, 1, f[0]) != 1 ||
  325.         fwrite(Buffers[1], ScreenWidth, 1, f[1]) != 1 ||
  326.         fwrite(Buffers[2], ScreenWidth, 1, f[2]) != 1)
  327.         GIF_EXIT("Write to file(s) failed.");
  328.     }
  329.  
  330.     free((char *) Buffers[0]);
  331.     free((char *) Buffers[1]);
  332.     free((char *) Buffers[2]);
  333.     fclose(f[0]);
  334.     fclose(f[1]);
  335.     fclose(f[2]);
  336.     }
  337. }
  338.