home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / viewers / giflib12 / doc / gif_lib.doc < prev    next >
Text File  |  1991-05-28  |  19KB  |  478 lines

  1.             GIF library document
  2.             --------------------
  3.  
  4.                Gershon Elber, May 1991
  5.                -----------------------
  6.  
  7.                 Version 1.2
  8.                 -----------
  9.  
  10.     The Graphics Interchange Format(c) is the Copyright property of
  11. CompuServe Incorporated. GIF(sm) is a Service Mark property of CompuServe
  12. Incorporated.
  13.  
  14.     This library was written once I didnt find anything similar and I
  15. wanted one. I was inspired from the rle Utah tool kit, which I hoped to port
  16. to an IBM PC, but found it to be too machine specific, and its compression
  17. ratio too low. I compromised on the GIF format while I am not sure how long
  18. 8 bits per pixel will be enough.
  19.  
  20.  
  21.     This document explains the GIF library kernel on directory GIF/LIB.
  22. The kernel is built to the gif_libl.lib which is used in all the utilities
  23. on GIF/UTIL, or can be used in any application needs to read/write GIF file
  24. format. This document does NOT explain the GIF file format and assumes it
  25. is known, at list to the level of the GIF file structure.
  26.  
  27.     When a GIF file is opened, a GIF file descriptor is maintained which
  28. is a pointer to GifFileType structure as follows:
  29.  
  30. typedef struct GifFileType {
  31.     int SWidth, SHeight,                /* Screen dimensions */
  32.     SColorResolution, SBitsPerPixel; /* How many colors can we generate? */
  33.     SBackGroundColor,        /* I hope you understand this one... */
  34.     ILeft, ITop, IWidth, IHeight,         /* Current image dimensions */
  35.     IInterlace,                  /* Sequential/Interlaced lines */
  36.     IBitsPerPixel;              /* How many colors this image has? */
  37.     GifColorType *SColorMap, *IColorMap;           /* NULL if not exists */
  38.     void *Private;      /* The regular user should not mess with this one! */
  39. } GifFileType;
  40.  
  41.     This structure was copied from gif_lib.h - the header file for the GIF
  42. library. Any application program that uses the gif_libl.lib library should
  43. include it. All items begin with S refer to GIF Screen, while the ones with I
  44. to current image (note GIF file may have more than one image). The user NEVER
  45. writes into this structure, but can read any of these items at any time it is
  46. proper (image information is invalid until first image was read/write).
  47.     As the library needs to save its own internal data also, a Private
  48. pointer to internal structure is also saved there. Applications should ignore
  49. this item.
  50.     The library has no static data. This means that it is fully reentrant
  51. and any number of GIF files (up to memory limits) can be opened for
  52. read/write. Instead of the static data, internal structure pointed by the
  53. Private pointer is used.
  54.     The library do allocates its own memory dynamically, on opening of
  55. file, and releases that once closed. The user is NEVER requires to allocate
  56. any memory for any of the functions of this library (unless the provided
  57. parameters, such as image line, were prefered to be allocated dynammically by
  58. the user) nor to free them directly. In order to reduce disk access, the file
  59. buffer is increased to FILE_BUFFER_SIZE (defined in gif_lib.h). The library
  60. was compiled in large model as the memory allocated per file is quite big:
  61. about 17k for decoding (DGIF_LIB.C), and 32k for encoding (EGIF_LIB.C),
  62. excluding the FILE_BUFFER_SIZE.
  63.  
  64.     We now can see what the library contains (directory GIF/LIB):
  65.  
  66. 1. EGIF_LIB.C - Encoding routines, all prefixed with E.
  67. 2. DGIF_LIB.C - Decoding routines, all prefixed with D.
  68. 3. DEV2GIF.C - Routines to convert specific device buffers into GIF files.
  69. 4. GIF_ERR.C - Error handler for the library.
  70.   The library has fifth hashing table file in which is accessed internally
  71. only.
  72.   Major part of the routines returns ERROR (see gif_lib.h) if something went
  73. wrong or OK otherwise. Once ERROR received, GIF_ERR.C module can be used to
  74. do something about it.
  75.  
  76.     In addition a module to scan the command line arguments was added.
  77. This module is called GETARG.C and its headers are in GETARG.H. see header
  78. of GETARG.C for details on its usage.
  79.  
  80.  
  81. ENCODING (EGIF_LIB.C)
  82. ---------------------
  83.  
  84. GifFileType *EGifOpenFileName(char *GifFileName, int GifTestExistance);
  85.  
  86.       Open a new GIF file using the given GifFileName. If GifTestExistance
  87.     is TRUE, and file exists, the file is not destroyed, and NULL returned.
  88.       If any error occurs, NULL is returned and Error handler can be used
  89.     to get the exact error (see GIF_ERR.C).
  90.       The file is opened in binary mode, and its buffer size is set to
  91.     FILE_BUFFER_SIZE bytes.
  92.  
  93.  
  94. GifFileType *EGifOpenFileHandle(int GifFileHandle);
  95.  
  96.       Open a new GIF file using the given GifFileHandle
  97.       If any error occurs, NULL is returned and Error handler can be used
  98.     to get the exact error (see GIF_ERR.C)
  99.       The file is opened in binary mode, and its buffer size is set to
  100.     FILE_BUFFER_SIZE bytes.
  101.  
  102.  
  103. void EGifSetGifVersion(char *Version);
  104.  
  105.          Sets the GIF version of all files to be open from this point (until
  106.     another call to this routine is made. Version is a 3 characters
  107.     string of the form "87a" or "89a". No test is made to validate this
  108.     string.
  109.  
  110.  
  111. int EGifPutScreenDesc(GifFileType *GifFile,
  112.     int GifWidth, int GifHeight, int GifColorRes, int GifBackGround,
  113.     int GifBitsPerPixel, GifColorType *GifColorMap);
  114.  
  115.       Update GifFile Screen parameters, in GifFile structure and in real
  116.     file. if error occurs returns ERROR (see gif_lib.h), otherwise OK.
  117.       This routine should be called immediately after the GIF file was
  118.     opened.
  119.  
  120.  
  121. int EGifPutImageDesc(GifFileType *GifFile,
  122.     int GifLeft, int GifTop, int Width, int GifHeight, int GifInterlace,
  123.     int GifBitsPerPixel, GifColorType *GifColorMap);
  124.  
  125.       Update GifFile Image parameters, in GifFile structure and in real
  126.     file. if error occurs returns ERROR (see gif_lib.h), otherwise OK.
  127.       This routine should be called each time a new image should be
  128.     dumped to the file.
  129.  
  130.  
  131. int EGifPutLine(GifFileType *GifFile, PixelType *GifLine, int GifLineLen);
  132.  
  133.       Dumps block of pixels out to the GIF file. The line length can be
  134.     of any length. More than that, this routine may be interleaved with
  135.     EGifPutPixel, until all pixels were sent.
  136.       Returns ERROR if something went wrong, OK otherwise.
  137.  
  138.  
  139. int EGifPutPixel(GifFileType *GifFile, PixelType GifPixel);
  140.  
  141.       Dumps one pixel to the GIF file. This routine may be interleaved
  142.     with EGifPutLine, until all pixels were sent. Because of the overhead
  143.     per each call, the usage of this routine is not recommended.
  144.       Returns ERROR if something went wrong, OK otherwise.
  145.  
  146.  
  147. int EGifPutComment(GifFileType *GifFile, char *GifComment);
  148.  
  149.       Uses extension GIF records to save a string as a comment is the file.
  150.     The extension code is 'C' (for Comment). This is optional in GIF file.
  151.       Returns ERROR if something went wrong, OK otherwise.
  152.  
  153.  
  154. int EGifPutExtension(GifFileType *GifFile, int GifExtCode, int GifExtLen,
  155.                             void *GifExtension);
  156.  
  157.       Dumps the given extension block into the GIF file. Extension blocks
  158.     are optional in GIF file. Extension blocks of more than 255 bytes or
  159.     more than one block are not supported.
  160.       Returns ERROR if something went wrong, OK otherwise.
  161.  
  162.  
  163. int EGifPutCode(GifFileType *GifFile, int *GifCodeSize,
  164.                         ByteType **GifCodeBlock);
  165.  
  166.       It sometimes may be desired to write the compressed code as is
  167.     without decoding it. For example a filter for GIF file that change
  168.     only screen size (GifPos), does not need the exact pixel values and
  169.     pipes out the compressed image as is, make this process much faster.
  170.       This routine do exactly that (with EGifPutCodeNext), and can be
  171.     used instead of EGifPutLine. This usually works with the
  172.     DGifGetCode/DgifGetCodeNext routines, which reads the compressed
  173.     code, while EGifPutCode/EGifPutCodeNext write it out. See GifPos.c
  174.     for example.
  175.       Returns ERROR if something went wrong, OK otherwise.
  176.  
  177.  
  178. int EGifPutCodeNext(GifFileType *GifFile, ByteType **GifCodeBlock);
  179.  
  180.       See EGifPutCode above.
  181.  
  182.  
  183. int EGifCloseFile(GifFileType *GifFile);
  184.  
  185.       Close GIF file and free all memory allocated for it. GifFile should
  186.     not be used, once this routine was called.
  187.       Returns ERROR if something went wrong, OK otherwise.
  188.  
  189.  
  190. DECODING (DGIF_LIB.C)
  191. ---------------------
  192.  
  193. GifFileType *DGifOpenFileName(char *GifFileName);
  194.  
  195.       Open a new GIF file using the given GifFileName, and read its Screen
  196.     information.
  197.       If any error occurs, NULL is returned and Error handler can be used
  198.     to get the exact error (see GIF_ERR.C).
  199.       The file is opened in binary mode, and its buffer size is set to
  200.     FILE_BUFFER_SIZE bytes.
  201.  
  202.  
  203. GifFileType *DGifOpenFileHandle(int GifFileHandle);
  204.  
  205.       Open a new GIF file using the given GifFileHandle, and read its
  206.     Screen information.
  207.       If any error occurs, NULL is returned and Error handler can be used
  208.     to get the exact error (see GIF_ERR.C)
  209.       The file is opened in binary mode, and its buffer size is set to
  210.     FILE_BUFFER_SIZE bytes.
  211.  
  212.  
  213. int DGifGetScreenDesc(GifFileType *GifFile);
  214.  
  215.       Reads the screen information into the GifFile structure. Note this
  216.     routine is automatically called once a file is opened, and therefore
  217.     usually not needed.
  218.       Returns ERROR if something went wrong, OK otherwise.
  219.  
  220.  
  221. int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
  222.  
  223.       As the GIF file can have different records in arbitrary order, this
  224.     routine should be called once the file was open to detect the next
  225.     record type, and act upon it. Few types might be returned in GifType:
  226.     1. UndefinedRecordType - something is wrong!
  227.     2. ScreenDescRecordType - screen information. As the screen information
  228.        is automatically read in when the file is open, this usually would
  229.        not happen.
  230.     3. ImageDescRecordType - next record is Image.
  231.     4. ExtensionRecordType - next record is extension block.
  232.     5. TerminateRecordType - last record reached, can close the file.
  233.       The first Two types can usually be ignored.
  234.       Returns ERROR if something went wrong, OK otherwise.
  235.  
  236.  
  237. int DGifGetImageDesc(GifFileType *GifFile);
  238.  
  239.       Reads the image information into the GifFile structure.
  240.       Returns ERROR if something went wrong, OK otherwise.
  241.  
  242.  
  243. int DGifGetLine(GifFileType *GifFile, PixelType *GifLine, int GifLineLen);
  244.  
  245.       Load block of pixels from the GIF file. The line length can be
  246.     of any length. More than that, this routine may be interleaved with
  247.     DGifGetPixel, until all pixels were read.
  248.       Returns ERROR if something went wrong, OK otherwise.
  249.  
  250. int DGifGetPixel(GifFileType *GifFile, PixelType GifPixel);
  251.  
  252.       Loads one pixel from the GIF file. This routine may be interleaved
  253.     with DGifGetLine, until all pixels were read. Because of the overhead
  254.     per each call, the usage of this routine is not recommended.
  255.       Returns ERROR if something went wrong, OK otherwise.
  256.  
  257. int DGifGetComment(GifFileType *GifFile, char *GifComment);
  258.  
  259.       Load comment from the GIF file. Because DGifGetRecordType will
  260.     only tell this records is of type extension, this routine should be
  261.     called iff it is known %100 that is must be a comment.
  262.       For definition of comment, see EGifPutComment.
  263.       Returns ERROR if something went wrong, OK otherwise.
  264.  
  265.       
  266. int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
  267.                         ByteType **GifExtension);
  268.  
  269.       Loads the given extension block from the GIF file. Extension blocks
  270.     are optional in GIF file. This routine should be follows by
  271.     DGifGetExtensionNext - see below
  272.       Returns ERROR if something went wrong, OK otherwise.
  273.  
  274.  
  275. int DGifGetExtensionNext(GifFileType *GifFile, ByteType **GifExtension);
  276.  
  277.       As extensions may contain more than one block, use this routine to
  278.     continue after DGifGetExtension, until *GifExtension is NULL.
  279.       Returns ERROR if something went wrong, OK otherwise.
  280.  
  281.  
  282. int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
  283.                         ByteType **GifCodeBlock);
  284.  
  285.       It sometimes may be desired to read the compressed code as is
  286.     without decoding it. This routine do exactly that (with
  287.     DGifGetCodeNext), and can be used instead of DGifGetLine.
  288.     This compressed code information can be written out using the
  289.     EGifPutCode/EGifPutCodeNext sequence (see GifPos.c for example).
  290.       Returns ERROR if something went wrong, OK otherwise.
  291.  
  292.  
  293. int DGifGetCodeNext(GifFileType *GifFile, ByteType **GifCodeBlock);
  294.  
  295.       See DGifGetCode above.
  296.       
  297.  
  298. int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
  299.  
  300.       This routine can be called instead of DGifGetLine/DGifGetPixel or
  301.     DGifGetCode/DGifGetCodeNext to get the 12 bits LZ codes of the images.
  302.     It may be used mainly for debugging purposes (see GifText.c for
  303.     example).
  304.       Returns ERROR if something went wrong, OK otherwise.
  305.  
  306.  
  307. int DGifCloseFile(GifFileType *GifFile);
  308.  
  309.       Close GIF file and free all memory allocated for it. GifFile should
  310.     not be used, once this routine was called.
  311.       Returns ERROR if something went wrong, OK otherwise.
  312.  
  313.  
  314.  
  315. ERROR HANDLING (EGIF_LIB.C)
  316. ---------------------------
  317.  
  318. void PrintGifError(void)
  319.  
  320.       Print one line diagnostic on the last gif_lib error to stderr.
  321.  
  322.  
  323. int GifLastError(void)
  324.  
  325.       Return last gif_lib error, and clear the error.
  326.       Note it is the user responsibility to call the file closing routine,
  327.     so the file will be closed (if was opened), and memory will be released
  328.     (if was allocated).
  329.       The different error types are defined in gif_lib.h.
  330.  
  331.  
  332. DEVICE SPECIFIC (XXX2GIF.C)
  333. ---------------------------
  334.  
  335. int DumpScreen2Gif(char *FileName, int ReqGraphDriver, int ReqGraphMode1,
  336.                                int ReqGraphMode2);
  337.  
  338.       Dumps the whole device buffer as specified by GraphDriver and
  339.     GraphMode (as defined in TC 2.0 graphics.h) into FileName as GIF file.
  340.     Current devices supported:
  341.     1. Hercules.
  342.     2. EGA, EGA64, EGAMONO (all modes - see TC graphics.h).
  343.     3. VGA (all modes - see TC graphics.h).
  344.     4. SVGA_SPECIAL. This mode is special and not supported by Borland
  345.        graphics.h. ReqGraphDriver must be equal to 999, and ReqGraphMode
  346.        is ignored. This modes assumes 800 by 600 in 16 colors.
  347.       Returns ERROR if something went wrong, OK otherwise.
  348.     5. SGI 4D using gl graphic library - window dump.
  349.     6. X11 window dump.
  350.  
  351.  
  352. COMMAND LINE PARSING (GETARG.C)
  353. -------------------------------
  354.  
  355. int GAGetArgs(int argc, char **argv, char *CtrlStr, ...);
  356.  
  357.       Main routine of this module. Given the argc & argv as received by
  358.     the main procedure, the command line CtrlStr, and the addresses of
  359.     all parameters, parse the command line, and update the parameters.
  360.       The CtrlStr defines what types of variables should follow. Look
  361.     at the beginning of getarg.c for exact usage.
  362.       Returns 0 if successful, error number (as defined by getarg.h)
  363.     otherwise.
  364.  
  365.  
  366. void GAPrintErrMsg(int Error);
  367.  
  368.       If error occurred in GAGetARgs, this routine may be used to print
  369.     one line diagnostic to stderr.
  370.  
  371.  
  372. void GAPrintHowTo(char *CtrlStr);
  373.  
  374.       Given same CtrlStr as for GAGetArgs, can be used to print a
  375.     one line 'how to use'
  376.  
  377.  
  378. Skeleton of GIF filter
  379. ----------------------
  380.  
  381.     This completes the functions, application can access. An application
  382. skeleton usually will look like (assuming it is a filter - read GIF file,
  383. modifies it, and write new GIF file) the following example, which only copy
  384. a GIF file from stdin to stdout. Please give a pick to the utilities on the
  385. util directory to get more idea once you fill comfortable with this skeleton.
  386. Also try to follow the coding standards of this package if you want me to
  387. officially add your new utility to it.
  388.  
  389. #include "getarg.h"
  390.  
  391. main(... )
  392. {
  393.     GifFile *GifFileIn, *GifFileOut;
  394.  
  395.     GAGetArgs( argc, argv, CtrlStr, ... );        /* Process command line */
  396.  
  397.     /* Use the stdin as input (note this also read screen descriptor in: */
  398.     if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
  399.     QuitGifError(GifFileIn, GifFileOut);
  400.  
  401.     /* Use the stdout as output: */
  402.     if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
  403.     QuitGifError(GifFileIn, GifFileOut);
  404.     /* And dump out its screen information: */
  405.     if (EGifPutScreenDesc(GifFileOut,
  406.     GifFileIn -> SWidth, GifFileIn -> SHeight,
  407.     GifFileIn -> SColorResolution, GifFileIn -> SBackGroundColor,
  408.     GifFileIn -> SBitsPerPixel, GifFileIn -> SColorMap) == ERROR)
  409.     QuitGifError(GifFileIn, GifFileOut);
  410.  
  411.     /* Scan the content of the input GIF file and load the image(s) in: */
  412.     do {
  413.     if (DGifGetRecordType(GifFileIn, &RecordType) == ERROR)
  414.         QuitGifError(GifFileIn, GifFileOut);
  415.  
  416.     switch (RecordType) {
  417.         case IMAGE_DESC_RECORD_TYPE:
  418.         if (DGifGetImageDesc(GifFileIn) == ERROR)
  419.             QuitGifError(GifFileIn, GifFileOut);
  420.         /* Put image descriptor to out file: */
  421.         if (EGifPutImageDesc(GifFileOut,
  422.             GifFileIn -> ILeft, GifFileIn -> ITop,
  423.             GifFileIn -> IWidth, GifFileIn -> IHeight,
  424.             GifFileIn -> IInterlace, GifFileIn -> IBitsPerPixel,
  425.             GifFileIn -> IColorMap) == ERROR)
  426.             QuitGifError(GifFileIn, GifFileOut);
  427.  
  428.         /* Now read image itself in decoded form as we dont really   */
  429.         /* care what we have there, and this is much faster.         */
  430.         if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == ERROR ||
  431.             EGifPutCode(GifFileOut, CodeSize, CodeBlock) == ERROR)
  432.             QuitGifError(GifFileIn, GifFileOut);
  433.         while (CodeBlock != NULL) {
  434.             if (DGifGetCodeNext(GifFileIn, &CodeBlock) == ERROR ||
  435.             EGifPutCodeNext(GifFileOut, CodeBlock) == ERROR)
  436.             QuitGifError(GifFileIn, GifFileOut);
  437.         }
  438.         break;
  439.         case EXTENSION_RECORD_TYPE:
  440.         /* Skip any extension blocks in file: */
  441.         if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == ERROR)
  442.             QuitGifError(GifFileIn, GifFileOut);
  443.         if (EGifPutExtension(GifFileOut, ExtCode, Extension[0],
  444.                             Extension) == ERROR)
  445.             QuitGifError(GifFileIn, GifFileOut);
  446.  
  447.         /* No support to more than one extension blocks, so discard: */
  448.         while (Extension != NULL) {
  449.             if (DGifGetExtensionNext(GifFileIn, &Extension) == ERROR)
  450.             QuitGifError(GifFileIn, GifFileOut);
  451.         }
  452.         break;
  453.         case TERMINATE_RECORD_TYPE:
  454.         break;
  455.         default:             /* Should be traps by DGifGetRecordType */
  456.         break;
  457.     }
  458.     }
  459.     while (RecordType != TERMINATE_RECORD_TYPE);
  460.  
  461.     if (DGifCloseFile(GifFileIn) == ERROR)
  462.     QuitGifError(GifFileIn, GifFileOut);
  463.     if (EGifCloseFile(GifFileOut) == ERROR)
  464.     QuitGifError(GifFileIn, GifFileOut);
  465. }
  466.  
  467.  
  468. /******************************************************************************
  469. * Close both input and output file (if open), and exit.                  *
  470. ******************************************************************************/
  471. static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
  472. {
  473.     PrintGifError();
  474.     if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
  475.     if (GifFileOut != NULL) EGifCloseFile(GifFileOut);
  476.     exit(1);
  477. }
  478.