home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / giflib11 / util / gif2rle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-03  |  8.7 KB  |  276 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 RLE format (utah raster toolkit).             *
  7. * Options:                                     *
  8. * -a : add alpha channel with full coverage.                     *
  9. * -h : on line help.                                 *
  10. ******************************************************************************
  11. * History:                                     *
  12. * 5 Jan 90 - Version 1.0 by Gershon Elber.                     *
  13. *****************************************************************************/
  14.  
  15. #ifdef __MSDOS__
  16. #include <graphics.h>
  17. #include <stdlib.h>
  18. #include <alloc.h>
  19. #include <io.h>
  20. #include <dos.h>
  21. #include <bios.h>
  22. #endif /* __MSDOS__ */
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include <string.h>
  27. #include <fcntl.h>
  28. #include "gif_lib.h"
  29. #include "getarg.h"
  30.  
  31. #include "svfb_global.h"           /* The rle tool kit header files. */
  32.  
  33. #define PROGRAM_NAME    "Gif2Rle"
  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 = "Gif2Rle a%- 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.     " a%- 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.     AlphaFlag = 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 DumpScreen2Rle(GifRowType *ScreenBuffer,
  73.                     int ScreenWidth, int ScreenHeight);
  74.  
  75. /******************************************************************************
  76. * Interpret the command line and scan the given GIF file.              *
  77. ******************************************************************************/
  78. void main(int argc, char **argv)
  79. {
  80.     int    i, j, Error, NumFiles, Size, Row, Col, Width, Height, ExtCode, Count;
  81.     GifRecordType RecordType;
  82.     GifByteType *Extension;
  83.     char **FileName = NULL;
  84.     GifRowType *ScreenBuffer;
  85.     GifFileType *GifFile;
  86.  
  87.     if ((Error = GAGetArgs(argc, argv, CtrlStr,    &AlphaFlag, &HelpFlag,
  88.         &NumFiles, &FileName)) != FALSE ||
  89.         (NumFiles > 1 && !HelpFlag)) {
  90.     if (Error)
  91.         GAPrintErrMsg(Error);
  92.     else if (NumFiles > 1)
  93.         GIF_MESSAGE("Error in command line parsing - one GIF file please.");
  94.     GAPrintHowTo(CtrlStr);
  95.     exit(1);
  96.     }
  97.  
  98.     if (HelpFlag) {
  99.     fprintf(stderr, VersionStr);
  100.     GAPrintHowTo(CtrlStr);
  101.     exit(0);
  102.     }
  103.     
  104.     if (NumFiles == 1) {
  105.     if ((GifFile = DGifOpenFileName(*FileName)) == NULL) {
  106.         PrintGifError();
  107.         exit(-1);
  108.     }
  109.     }
  110.     else {
  111.     /* Use the stdin instead: */
  112.  
  113. #ifdef __MSDOS__
  114.     setmode(0, O_BINARY);
  115. #endif /* __MSDOS__ */
  116.     if ((GifFile = DGifOpenFileHandle(0)) == NULL) {
  117.         PrintGifError();
  118.         exit(-1);
  119.     }
  120.     }
  121.  
  122.     /* Allocate the screen as vector of column of rows. We cannt allocate    */
  123.     /* the all screen at once, as this broken minded CPU can allocate up to  */
  124.     /* 64k at a time and our image can be bigger than that:             */
  125.     /* Note this screen is device independent - its the screen as defined by */
  126.     /* the GIF file parameters itself.                         */
  127.     if ((ScreenBuffer = (GifRowType *)
  128.     malloc(GifFile -> SHeight * sizeof(GifRowType *))) == NULL)
  129.         GIF_EXIT("Failed to allocate memory required, aborted.");
  130.  
  131.     Size = GifFile -> SWidth * sizeof(GifPixelType);/* Size in bytes one row.*/
  132.     if ((ScreenBuffer[0] = (GifRowType) malloc(Size)) == NULL) /* First row. */
  133.     GIF_EXIT("Failed to allocate memory required, aborted.");
  134.  
  135.     for (i = 0; i < GifFile -> SWidth; i++)  /* Set its color to BackGround. */
  136.     ScreenBuffer[0][i] = GifFile -> SBackGroundColor;
  137.     for (i = 1; i < GifFile -> SHeight; i++) {
  138.     /* Allocate the other rows, and set their color to background too: */
  139.     if ((ScreenBuffer[i] = (GifRowType) malloc(Size)) == NULL)
  140.         GIF_EXIT("Failed to allocate memory required, aborted.");
  141.  
  142.     memcpy(ScreenBuffer[i], ScreenBuffer[0], Size);
  143.     }
  144.  
  145.     /* Scan the content of the GIF file and load the image(s) in: */
  146.     do {
  147.     if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) {
  148.         PrintGifError();
  149.         exit(-1);
  150.     }
  151.     switch (RecordType) {
  152.         case IMAGE_DESC_RECORD_TYPE:
  153.         if (DGifGetImageDesc(GifFile) == GIF_ERROR) {
  154.             PrintGifError();
  155.             exit(-1);
  156.         }
  157.         Row = GifFile -> ITop; /* Image Position relative to Screen. */
  158.         Col = GifFile -> ILeft;
  159.         Width = GifFile -> IWidth;
  160.         Height = GifFile -> IHeight;
  161.         fprintf(stderr, "\n%s: Image %d at (%d, %d) [%dx%d]:     ",
  162.             PROGRAM_NAME, ++ImageNum, Col, Row, Width, Height);
  163.         if (GifFile -> ILeft + GifFile -> IWidth > GifFile -> SWidth ||
  164.            GifFile -> ITop + GifFile -> IHeight > GifFile -> SHeight) {
  165.             fprintf(stderr, "Image %d is not confined to screen dimension, aborted.\n");
  166.             exit(-2);
  167.         }
  168.         if (GifFile -> IInterlace) {
  169.             /* Need to perform 4 passes on the images: */
  170.             for (Count = i = 0; i < 4; i++)
  171.             for (j = Row + InterlacedOffset[i]; j < Row + Height;
  172.                          j += InterlacedJumps[i]) {
  173.                 fprintf(stderr, "\b\b\b\b%-4d", Count++);
  174.                 if (DGifGetLine(GifFile, &ScreenBuffer[j][Col],
  175.                 Width) == GIF_ERROR) {
  176.                 PrintGifError();
  177.                 exit(-1);
  178.                 }
  179.             }
  180.         }
  181.         else {
  182.             for (i = 0; i < Height; i++) {
  183.             fprintf(stderr, "\b\b\b\b%-4d", i);
  184.             if (DGifGetLine(GifFile, &ScreenBuffer[Row++][Col],
  185.                 Width) == GIF_ERROR) {
  186.                 PrintGifError();
  187.                 exit(-1);
  188.             }
  189.             }
  190.         }
  191.         break;
  192.         case EXTENSION_RECORD_TYPE:
  193.         /* Skip any extension blocks in file: */
  194.         if (DGifGetExtension(GifFile, &ExtCode, &Extension) == GIF_ERROR) {
  195.             PrintGifError();
  196.             exit(-1);
  197.         }
  198.         while (Extension != NULL) {
  199.             if (DGifGetExtensionNext(GifFile, &Extension) == GIF_ERROR) {
  200.             PrintGifError();
  201.             exit(-1);
  202.             }
  203.         }
  204.         break;
  205.         case TERMINATE_RECORD_TYPE:
  206.         break;
  207.         default:            /* Should be traps by DGifGetRecordType. */
  208.         break;
  209.     }
  210.     }
  211.     while (RecordType != TERMINATE_RECORD_TYPE);
  212.  
  213.     /* Lets display it - set the global variables required and do it: */
  214.     BackGround = GifFile -> SBackGroundColor;
  215.     ColorMap = (GifFile -> IColorMap ? GifFile -> IColorMap :
  216.                        GifFile -> SColorMap);
  217.     ColorMapSize = 1 << (GifFile -> IColorMap ? GifFile -> IBitsPerPixel :
  218.                                 GifFile -> SBitsPerPixel);
  219.     DumpScreen2Rle(ScreenBuffer, GifFile -> SWidth, GifFile -> SHeight);
  220.  
  221.     if (DGifCloseFile(GifFile) == GIF_ERROR) {
  222.     PrintGifError();
  223.     exit(-1);
  224.     }
  225. }
  226.  
  227. /******************************************************************************
  228. * The real dumping routine.                              *
  229. ******************************************************************************/
  230. static void DumpScreen2Rle(GifRowType *ScreenBuffer,
  231.                     int ScreenWidth, int ScreenHeight)
  232. {
  233.     int i, j;
  234.     char Comment[80];
  235.     rle_pixel *rows[4];
  236.     GifRowType GifRow;
  237.     static GifColorType
  238.     *ColorMapEntry;
  239.  
  240.     if (AlphaFlag) SV_SET_BIT(sv_globals, SV_ALPHA);
  241.     sv_globals.sv_alpha = AlphaFlag != 0;
  242.     sv_globals.svfb_fd = stdout;
  243.     sv_globals.sv_xmin = 0;
  244.     sv_globals.sv_ymin = 0;
  245.     sv_globals.sv_xmax = ScreenWidth - 1;
  246.     sv_globals.sv_ymax = ScreenHeight - 1;
  247.     sprintf(Comment, "origin=GIF format, %d colors.", ColorMapSize);
  248.     rle_putcom(Comment, &sv_globals);
  249.     sv_setup(RUN_DISPATCH, &sv_globals);
  250.  
  251.     for (i = 0; i < 4; i++)
  252.     if ((rows[i] = (rle_pixel *) malloc(sizeof(rle_pixel) * ScreenWidth))
  253.                                      == NULL)
  254.         GIF_EXIT("Failed to allocated memory required, aborted.");
  255.  
  256.     if (AlphaFlag) {
  257.     /* Initial the alpha channel to full coverage: */
  258.     for (i = 0; i < ScreenWidth; i++) rows[0][i] = 255;
  259.     }
  260.  
  261.     for (i = 0; i < ScreenHeight; i++) {
  262.     /* Flip the image vertically as rle files start at the bollom... */
  263.     GifRow = ScreenBuffer[ScreenHeight - i - 1];
  264.     fprintf(stderr, "\b\b\b\b%-4d", ScreenHeight - i);
  265.     for (j = 0; j < ScreenWidth; j++) {
  266.         ColorMapEntry = &ColorMap[GifRow[j]];
  267.         rows[1][j] = ColorMapEntry -> Red;
  268.         rows[2][j] = ColorMapEntry -> Green;
  269.         rows[3][j] = ColorMapEntry -> Blue;
  270.     }
  271.     sv_putrow( &rows[1], ScreenWidth, &sv_globals );
  272.     }
  273.  
  274.     sv_puteof( &sv_globals );
  275. }
  276.