1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
/*
* Skeleton file for generic GIF `filter' program --- sequentially read GIF
* records from stdin, process them, send them out. Most of the junk above
* `void main' isn't needed for the skeleton, but is likely to be for what
* you'll do with it.
*
* If you compile this, it will turn into an expensive GIF copying routine;
* stdin to stdout with no changes and minimal validation. Well, it's a
* decent test of the low-level routines, anyway.
*
* Note: due to the vicissitudes of Lempel-Ziv compression, the output of this
* copier may not be bitwise identical to its input. This can happen if you
* copy an image from a much more (or much *less*) memory-limited system; your
* compression may use more (or fewer) bits. The uncompressed rasters should,
* however, be identical (you can check this with icon2gif -d).
*/
#ifdef __MSDOS__
#include <dos.h>
#include <alloc.h>
#include <stdlib.h>
#include <graphics.h>
#include <io.h>
#endif /* __MSDOS__ */
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "gagetarg.h"
#include "gif_lib.h"
#define PROGRAM_NAME "giffiltr"
#ifdef __MSDOS__
extern unsigned int
_stklen = 16384; /* Increase default stack size. */
#endif /* __MSDOS__ */
/******************************************************************************
* Close both input and output file (if open), and exit. *
******************************************************************************/
static void QuitGifError(GifFileType *GifFileIn, GifFileType *GifFileOut)
{
PrintGifError();
if (GifFileIn != NULL) DGifCloseFile(GifFileIn);
if (GifFileOut != NULL) EGifCloseFile(GifFileOut);
exit(1);
}
/******************************************************************************
* Main sequence *
******************************************************************************/
void main(int argc, char **argv)
{
GifFileType *GifFileIn = NULL, *GifFileOut = NULL;
GifRecordType RecordType;
int CodeSize, ExtCode;
GifByteType *CodeBlock, *Extension;
/*
* Command-line processing goes here.
*/
/* Use the stdin as input (note this also read screen descriptor in: */
if ((GifFileIn = DGifOpenFileHandle(0)) == NULL)
QuitGifError(GifFileIn, GifFileOut);
/* Use the stdout as output: */
if ((GifFileOut = EGifOpenFileHandle(1)) == NULL)
QuitGifError(GifFileIn, GifFileOut);
/* And dump out its screen information: */
if (EGifPutScreenDesc(GifFileOut,
GifFileIn->SWidth, GifFileIn->SHeight,
GifFileIn->SColorResolution, GifFileIn->SBackGroundColor,
GifFileIn->SColorMap) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Scan the content of the input GIF file and load the image(s) in: */
do {
if (DGifGetRecordType(GifFileIn, &RecordType) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(GifFileIn) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Put image descriptor to out file: */
if (EGifPutImageDesc(GifFileOut,
GifFileIn->Image.Left, GifFileIn->Image.Top,
GifFileIn->Image.Width, GifFileIn->Image.Height,
GifFileIn->Image.Interlace,
GifFileIn->Image.ColorMap) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Now read image itself in decoded form as we dont really */
/* care what we have there, and this is much faster. */
if (DGifGetCode(GifFileIn, &CodeSize, &CodeBlock) == GIF_ERROR ||
EGifPutCode(GifFileOut, CodeSize, CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
while (CodeBlock != NULL) {
if (DGifGetCodeNext(GifFileIn, &CodeBlock) == GIF_ERROR ||
EGifPutCodeNext(GifFileOut, CodeBlock) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
break;
case EXTENSION_RECORD_TYPE:
/* Copy the extension header */
if (DGifGetExtension(GifFileIn, &ExtCode, &Extension) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifPutExtensionHeader(GifFileOut, ExtCode) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
/* Copy the extension data blocks */
while (Extension != NULL) {
if (EGifPutExtensionBlock(GifFileOut, Extension[0],
Extension+1) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (DGifGetExtensionNext(GifFileIn, &Extension) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
}
/* Close the extension with a 0 length data block */
if (EGifPutExtensionBlock(GifFileOut, 0, NULL) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
break;
case TERMINATE_RECORD_TYPE:
break;
default: /* Should be trapped by DGifGetRecordType */
break;
}
}
while (RecordType != TERMINATE_RECORD_TYPE);
if (DGifCloseFile(GifFileIn) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
if (EGifCloseFile(GifFileOut) == GIF_ERROR)
QuitGifError(GifFileIn, GifFileOut);
exit(0);
}
|