1 /* gif.c - load GIF image from file
3 * Raster graphics library
5 * Copyright (c) 1998 Alfredo K. Kojima
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 static int InterlacedOffset
[] = { 0, 4, 2, 1 };
37 static int InterlacedJumps
[] = { 8, 8, 4, 2 };
41 * Partially based on code in gif2rgb from giflib, by Gershon Elber.
44 RLoadGIF(RContext
*context
, char *file
, int index
)
47 GifFileType
*gif
= NULL
;
48 GifPixelType
*buffer
= NULL
;
51 GifRecordType recType
;
52 ColorMapObject
*colormap
;
53 unsigned char rmap
[256];
54 unsigned char gmap
[256];
55 unsigned char bmap
[256];
60 /* default error message */
61 sprintf(RErrorString
, "file does not contain image of index %i", index
);
63 gif
= DGifOpenFileName(file
);
66 sprintf(RErrorString
, "could not load gif file");
70 colormap
= gif
->SColorMap
;
76 GifByteType
*extension
;
78 if (DGifGetRecordType(gif
, &recType
) == GIF_ERROR
) {
79 sprintf(RErrorString
, "error while loading gif");
83 case IMAGE_DESC_RECORD_TYPE
:
87 if (DGifGetImageDesc(gif
)==GIF_ERROR
) {
88 sprintf(RErrorString
, "error while loading gif");
92 width
= gif
->Image
.Width
;
93 height
= gif
->Image
.Height
;
95 if (gif
->Image
.ColorMap
)
96 colormap
= gif
->Image
.ColorMap
;
98 /* the gif specs talk about a default colormap, but it
99 * doesnt say what the heck is this default colormap */
102 * Well, since the spec says the colormap can be anything,
103 * lets just render it with whatever garbage the stack
106 sprintf(RErrorString, "bad gif file");
111 for (j
= 0; j
< colormap
->ColorCount
; j
++) {
112 rmap
[j
] = colormap
->Colors
[j
].Red
;
113 gmap
[j
] = colormap
->Colors
[j
].Green
;
114 bmap
[j
] = colormap
->Colors
[j
].Blue
;
118 buffer
= malloc(width
* sizeof(GifColorType
));
120 sprintf(RErrorString
, "out of memory while loading gif");
124 image
= RCreateImage(width
, height
, False
);
126 sprintf(RErrorString
, "out of memory while loading gif");
130 if (gif
->Image
.Interlace
) {
133 for (j
= 0; j
< 4; j
++) {
134 for (k
= InterlacedOffset
[j
]; k
< height
;
135 k
+= InterlacedJumps
[j
]) {
136 if (DGifGetLine(gif
, buffer
, width
)==GIF_ERROR
) {
137 sprintf(RErrorString
, "error while loading gif");
141 for (l
= 0; l
< width
; l
++, ofs
++) {
142 int pixel
= buffer
[l
];
143 image
->data
[0][ofs
] = rmap
[pixel
];
144 image
->data
[1][ofs
] = gmap
[pixel
];
145 image
->data
[2][ofs
] = bmap
[pixel
];
150 for (j
= 0; j
< height
; j
++) {
151 if (DGifGetLine(gif
, buffer
, width
)==GIF_ERROR
) {
152 sprintf(RErrorString
, "error while loading gif");
155 for (k
= 0; k
< width
; k
++, ofs
++) {
156 int pixel
= buffer
[k
];
157 image
->data
[0][ofs
] = rmap
[pixel
];
158 image
->data
[1][ofs
] = gmap
[pixel
];
159 image
->data
[2][ofs
] = bmap
[pixel
];
165 case EXTENSION_RECORD_TYPE
:
166 /* skip all extension blocks */
167 if (DGifGetExtension(gif
, &extCode
, &extension
)==GIF_ERROR
) {
168 sprintf(RErrorString
, "error while loading gif");
172 if (DGifGetExtensionNext(gif
, &extension
)==GIF_ERROR
) {
173 sprintf(RErrorString
, "error while loading gif");
182 } while (recType
!= TERMINATE_RECORD_TYPE
&& i
<= index
);
185 goto did_not_get_any_errors
;
188 RDestroyImage(image
);
190 did_not_get_any_errors
: