File: giffiltr.c

package info (click to toggle)
giflib 3.0-11
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,052 kB
  • ctags: 967
  • sloc: ansic: 11,668; sh: 223; makefile: 212; perl: 54
file content (140 lines) | stat: -rw-r--r-- 4,960 bytes parent folder | download
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);
}