1 /******************************************************************************
2 * "Gif-Lib" - Yet another gif library.
3 *
4 * Written by: Gershon Elber IBM PC Ver 1.1, Aug. 1990
5 ******************************************************************************
6 * The kernel of the GIF Decoding process can be found here.
7 ******************************************************************************
8 * History:
9 * 16 Jun 89 - Version 1.0 by Gershon Elber.
10 * 3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
11 *****************************************************************************/
12
13 #ifdef HAVE_CONFIG_H
14 #include <config.h>
15 #endif
16
17 #include <stdlib.h>
18 #if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__)
19 #include <io.h>
20 #include <alloc.h>
21 #include <sys\stat.h>
22 #else
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #endif /* __MSDOS__ */
26
27 #ifdef HAVE_IO_H
28 #include <io.h>
29 #endif
30
31 #ifdef HAVE_FCNTL_H
32 #include <fcntl.h>
33 #endif /* HAVE_FCNTL_H */
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif /* HAVE_UNISTD_H */
37 #include <stdio.h>
38 #include <string.h>
39 #include "gif_lib.h"
40 #include "gif_lib_private.h"
41
42 #define COMMENT_EXT_FUNC_CODE 0xfe /* Extension function code for
43 comment. */
44
45 /* avoid extra function call in case we use fread (TVT) */
46 #define READ(_gif,_buf,_len) \
47 (((GifFilePrivateType*)_gif->Private)->Read ? \
48 ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
49 fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
50
51 static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
52 static int DGifSetupDecompress(GifFileType *GifFile);
53 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
54 int LineLen);
55 static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
56 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
57 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
58 GifByteType *NextByte);
59 #ifndef _GBA_NO_FILEIO
60
61 /******************************************************************************
62 * Open a new gif file for read, given by its name.
63 * Returns GifFileType pointer dynamically allocated which serves as the gif
64 * info record. _GifError is cleared if succesfull.
65 *****************************************************************************/
66 GifFileType *
DGifOpenFileName(const char * FileName)67 DGifOpenFileName(const char *FileName) {
68 int FileHandle;
69 GifFileType *GifFile;
70
71 if ((FileHandle = open(FileName, O_RDONLY
72 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY)
73 | O_BINARY
74 #endif /* __MSDOS__ || _OPEN_BINARY */
75 )) == -1) {
76 _GifError = D_GIF_ERR_OPEN_FAILED;
77 return NULL;
78 }
79
80 GifFile = DGifOpenFileHandle(FileHandle);
81 return GifFile;
82 }
83
84 /******************************************************************************
85 * Update a new gif file, given its file handle.
86 * Returns GifFileType pointer dynamically allocated which serves as the gif
87 * info record. _GifError is cleared if succesfull.
88 *****************************************************************************/
89 GifFileType *
DGifOpenFileHandle(int FileHandle)90 DGifOpenFileHandle(int FileHandle) {
91
92 unsigned char Buf[GIF_STAMP_LEN + 1];
93 GifFileType *GifFile;
94 GifFilePrivateType *Private;
95 FILE *f;
96
97 GifFile = (GifFileType *)malloc(sizeof(GifFileType));
98 if (GifFile == NULL) {
99 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
100 close(FileHandle);
101 return NULL;
102 }
103
104 memset(GifFile, '\0', sizeof(GifFileType));
105
106 Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
107 if (Private == NULL) {
108 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
109 close(FileHandle);
110 free((char *)GifFile);
111 return NULL;
112 }
113 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY)
114 setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
115 #endif /* __MSDOS__ */
116
117 f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
118
119 #if defined(__MSDOS__) || defined(WINDOWS32)
120 setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE); /* And inc. stream
121 buffer. */
122 #endif /* __MSDOS__ */
123
124 GifFile->Private = (VoidPtr)Private;
125 Private->FileHandle = FileHandle;
126 Private->File = f;
127 Private->FileState = FILE_STATE_READ;
128 Private->Read = 0; /* don't use alternate input method (TVT) */
129 GifFile->UserData = 0; /* TVT */
130
131 /* Lets see if this is a GIF file: */
132 if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
133 _GifError = D_GIF_ERR_READ_FAILED;
134 fclose(f);
135 free((char *)Private);
136 free((char *)GifFile);
137 return NULL;
138 }
139
140 /* The GIF Version number is ignored at this time. Maybe we should do
141 * something more useful with it. */
142 Buf[GIF_STAMP_LEN] = 0;
143 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
144 _GifError = D_GIF_ERR_NOT_GIF_FILE;
145 fclose(f);
146 free((char *)Private);
147 free((char *)GifFile);
148 return NULL;
149 }
150
151 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
152 fclose(f);
153 free((char *)Private);
154 free((char *)GifFile);
155 return NULL;
156 }
157
158 _GifError = 0;
159
160 return GifFile;
161 }
162
163 #endif /* _GBA_NO_FILEIO */
164
165 /******************************************************************************
166 * GifFileType constructor with user supplied input function (TVT)
167 *****************************************************************************/
168 GifFileType *
DGifOpen(void * userData,InputFunc readFunc)169 DGifOpen(void *userData,
170 InputFunc readFunc) {
171
172 unsigned char Buf[GIF_STAMP_LEN + 1];
173 GifFileType *GifFile;
174 GifFilePrivateType *Private;
175
176 GifFile = (GifFileType *)malloc(sizeof(GifFileType));
177 if (GifFile == NULL) {
178 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
179 return NULL;
180 }
181
182 memset(GifFile, '\0', sizeof(GifFileType));
183
184 Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
185 if (!Private) {
186 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
187 free((char *)GifFile);
188 return NULL;
189 }
190
191 GifFile->Private = (VoidPtr)Private;
192 Private->FileHandle = 0;
193 Private->File = 0;
194 Private->FileState = FILE_STATE_READ;
195
196 Private->Read = readFunc; /* TVT */
197 GifFile->UserData = userData; /* TVT */
198
199 /* Lets see if this is a GIF file: */
200 if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
201 _GifError = D_GIF_ERR_READ_FAILED;
202 free((char *)Private);
203 free((char *)GifFile);
204 return NULL;
205 }
206
207 /* The GIF Version number is ignored at this time. Maybe we should do
208 * something more useful with it. */
209 Buf[GIF_STAMP_LEN] = 0;
210 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
211 _GifError = D_GIF_ERR_NOT_GIF_FILE;
212 free((char *)Private);
213 free((char *)GifFile);
214 return NULL;
215 }
216
217 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
218 free((char *)Private);
219 free((char *)GifFile);
220 return NULL;
221 }
222
223 _GifError = 0;
224
225 return GifFile;
226 }
227
228 /******************************************************************************
229 * This routine should be called before any other DGif calls. Note that
230 * this routine is called automatically from DGif file open routines.
231 *****************************************************************************/
232 int
DGifGetScreenDesc(GifFileType * GifFile)233 DGifGetScreenDesc(GifFileType * GifFile) {
234
235 int i, BitsPerPixel;
236 GifByteType Buf[3];
237 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
238
239 if (!IS_READABLE(Private)) {
240 /* This file was NOT open for reading: */
241 _GifError = D_GIF_ERR_NOT_READABLE;
242 return GIF_ERROR;
243 }
244
245 /* Put the screen descriptor into the file: */
246 if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
247 DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
248 return GIF_ERROR;
249
250 if (READ(GifFile, Buf, 3) != 3) {
251 _GifError = D_GIF_ERR_READ_FAILED;
252 return GIF_ERROR;
253 }
254 GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
255 BitsPerPixel = (Buf[0] & 0x07) + 1;
256 GifFile->SBackGroundColor = Buf[1];
257 if (Buf[0] & 0x80) { /* Do we have global color map? */
258
259 GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
260 if (GifFile->SColorMap == NULL) {
261 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
262 return GIF_ERROR;
263 }
264
265 /* Get the global color map: */
266 for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
267 if (READ(GifFile, Buf, 3) != 3) {
268 FreeMapObject(GifFile->SColorMap);
269 GifFile->SColorMap = NULL;
270 _GifError = D_GIF_ERR_READ_FAILED;
271 return GIF_ERROR;
272 }
273 GifFile->SColorMap->Colors[i].Red = Buf[0];
274 GifFile->SColorMap->Colors[i].Green = Buf[1];
275 GifFile->SColorMap->Colors[i].Blue = Buf[2];
276 }
277 } else {
278 GifFile->SColorMap = NULL;
279 }
280
281 return GIF_OK;
282 }
283
284 /******************************************************************************
285 * This routine should be called before any attempt to read an image.
286 *****************************************************************************/
287 int
DGifGetRecordType(GifFileType * GifFile,GifRecordType * Type)288 DGifGetRecordType(GifFileType * GifFile,
289 GifRecordType * Type) {
290
291 GifByteType Buf;
292 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
293
294 if (!IS_READABLE(Private)) {
295 /* This file was NOT open for reading: */
296 _GifError = D_GIF_ERR_NOT_READABLE;
297 return GIF_ERROR;
298 }
299
300 if (READ(GifFile, &Buf, 1) != 1) {
301 _GifError = D_GIF_ERR_READ_FAILED;
302 return GIF_ERROR;
303 }
304
305 switch (Buf) {
306 case ',':
307 *Type = IMAGE_DESC_RECORD_TYPE;
308 break;
309 case '!':
310 *Type = EXTENSION_RECORD_TYPE;
311 break;
312 case ';':
313 *Type = TERMINATE_RECORD_TYPE;
314 break;
315 default:
316 *Type = UNDEFINED_RECORD_TYPE;
317 _GifError = D_GIF_ERR_WRONG_RECORD;
318 return GIF_ERROR;
319 }
320
321 return GIF_OK;
322 }
323
324 /******************************************************************************
325 * This routine should be called before any attempt to read an image.
326 * Note it is assumed the Image desc. header (',') has been read.
327 *****************************************************************************/
328 int
DGifGetImageDesc(GifFileType * GifFile)329 DGifGetImageDesc(GifFileType * GifFile) {
330
331 int i, BitsPerPixel;
332 GifByteType Buf[3];
333 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
334 SavedImage *sp;
335
336 if (!IS_READABLE(Private)) {
337 /* This file was NOT open for reading: */
338 _GifError = D_GIF_ERR_NOT_READABLE;
339 return GIF_ERROR;
340 }
341
342 if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
343 DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
344 DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
345 DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
346 return GIF_ERROR;
347 if (READ(GifFile, Buf, 1) != 1) {
348 _GifError = D_GIF_ERR_READ_FAILED;
349 return GIF_ERROR;
350 }
351 BitsPerPixel = (Buf[0] & 0x07) + 1;
352 GifFile->Image.Interlace = (Buf[0] & 0x40);
353 if (Buf[0] & 0x80) { /* Does this image have local color map? */
354
355 /*** FIXME: Why do we check both of these in order to do this?
356 * Why do we have both Image and SavedImages? */
357 if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)
358 FreeMapObject(GifFile->Image.ColorMap);
359
360 GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
361 if (GifFile->Image.ColorMap == NULL) {
362 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
363 return GIF_ERROR;
364 }
365
366 /* Get the image local color map: */
367 for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
368 if (READ(GifFile, Buf, 3) != 3) {
369 FreeMapObject(GifFile->Image.ColorMap);
370 _GifError = D_GIF_ERR_READ_FAILED;
371 GifFile->Image.ColorMap = NULL;
372 return GIF_ERROR;
373 }
374 GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
375 GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
376 GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
377 }
378 } else if (GifFile->Image.ColorMap) {
379 FreeMapObject(GifFile->Image.ColorMap);
380 GifFile->Image.ColorMap = NULL;
381 }
382
383 if (GifFile->SavedImages) {
384 if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
385 sizeof(SavedImage) *
386 (GifFile->ImageCount + 1))) == NULL) {
387 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
388 return GIF_ERROR;
389 }
390 } else {
391 if ((GifFile->SavedImages =
392 (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
393 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
394 return GIF_ERROR;
395 }
396 }
397
398 sp = &GifFile->SavedImages[GifFile->ImageCount];
399 memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
400 if (GifFile->Image.ColorMap != NULL) {
401 sp->ImageDesc.ColorMap = MakeMapObject(
402 GifFile->Image.ColorMap->ColorCount,
403 GifFile->Image.ColorMap->Colors);
404 if (sp->ImageDesc.ColorMap == NULL) {
405 _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
406 return GIF_ERROR;
407 }
408 }
409 sp->RasterBits = (unsigned char *)NULL;
410 sp->ExtensionBlockCount = 0;
411 sp->ExtensionBlocks = (ExtensionBlock *) NULL;
412
413 GifFile->ImageCount++;
414
415 Private->PixelCount = (long)GifFile->Image.Width *
416 (long)GifFile->Image.Height;
417
418 DGifSetupDecompress(GifFile); /* Reset decompress algorithm parameters. */
419
420 return GIF_OK;
421 }
422
423 /******************************************************************************
424 * Get one full scanned line (Line) of length LineLen from GIF file.
425 *****************************************************************************/
426 int
DGifGetLine(GifFileType * GifFile,GifPixelType * Line,int LineLen)427 DGifGetLine(GifFileType * GifFile,
428 GifPixelType * Line,
429 int LineLen) {
430
431 GifByteType *Dummy;
432 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
433
434 if (!IS_READABLE(Private)) {
435 /* This file was NOT open for reading: */
436 _GifError = D_GIF_ERR_NOT_READABLE;
437 return GIF_ERROR;
438 }
439
440 if (!LineLen)
441 LineLen = GifFile->Image.Width;
442
443 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__)
444 if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
445 #else
446 if ((Private->PixelCount -= LineLen) > 0xffff0000) {
447 #endif /* __MSDOS__ */
448 _GifError = D_GIF_ERR_DATA_TOO_BIG;
449 return GIF_ERROR;
450 }
451
452 if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
453 if (Private->PixelCount == 0) {
454 /* We probably would not be called any more, so lets clean
455 * everything before we return: need to flush out all rest of
456 * image until empty block (size 0) detected. We use GetCodeNext. */
457 do
458 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
459 return GIF_ERROR;
460 while (Dummy != NULL) ;
461 }
462 return GIF_OK;
463 } else
464 return GIF_ERROR;
465 }
466
467 /******************************************************************************
468 * Put one pixel (Pixel) into GIF file.
469 *****************************************************************************/
470 int
471 DGifGetPixel(GifFileType * GifFile,
472 GifPixelType Pixel) {
473
474 GifByteType *Dummy;
475 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
476
477 if (!IS_READABLE(Private)) {
478 /* This file was NOT open for reading: */
479 _GifError = D_GIF_ERR_NOT_READABLE;
480 return GIF_ERROR;
481 }
482 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__)
483 if (--Private->PixelCount > 0xffff0000UL)
484 #else
485 if (--Private->PixelCount > 0xffff0000)
486 #endif /* __MSDOS__ */
487 {
488 _GifError = D_GIF_ERR_DATA_TOO_BIG;
489 return GIF_ERROR;
490 }
491
492 if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
493 if (Private->PixelCount == 0) {
494 /* We probably would not be called any more, so lets clean
495 * everything before we return: need to flush out all rest of
496 * image until empty block (size 0) detected. We use GetCodeNext. */
497 do
498 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
499 return GIF_ERROR;
500 while (Dummy != NULL) ;
501 }
502 return GIF_OK;
503 } else
504 return GIF_ERROR;
505 }
506
507 /******************************************************************************
508 * Get an extension block (see GIF manual) from gif file. This routine only
509 * returns the first data block, and DGifGetExtensionNext should be called
510 * after this one until NULL extension is returned.
511 * The Extension should NOT be freed by the user (not dynamically allocated).
512 * Note it is assumed the Extension desc. header ('!') has been read.
513 *****************************************************************************/
514 int
515 DGifGetExtension(GifFileType * GifFile,
516 int *ExtCode,
517 GifByteType ** Extension) {
518
519 GifByteType Buf;
520 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
521
522 if (!IS_READABLE(Private)) {
523 /* This file was NOT open for reading: */
524 _GifError = D_GIF_ERR_NOT_READABLE;
525 return GIF_ERROR;
526 }
527
528 if (READ(GifFile, &Buf, 1) != 1) {
529 _GifError = D_GIF_ERR_READ_FAILED;
530 return GIF_ERROR;
531 }
532 *ExtCode = Buf;
533
534 return DGifGetExtensionNext(GifFile, Extension);
535 }
536
537 /******************************************************************************
538 * Get a following extension block (see GIF manual) from gif file. This
539 * routine should be called until NULL Extension is returned.
540 * The Extension should NOT be freed by the user (not dynamically allocated).
541 *****************************************************************************/
542 int
543 DGifGetExtensionNext(GifFileType * GifFile,
544 GifByteType ** Extension) {
545
546 GifByteType Buf;
547 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
548
549 if (READ(GifFile, &Buf, 1) != 1) {
550 _GifError = D_GIF_ERR_READ_FAILED;
551 return GIF_ERROR;
552 }
553 if (Buf > 0) {
554 *Extension = Private->Buf; /* Use private unused buffer. */
555 (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
556 if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
557 _GifError = D_GIF_ERR_READ_FAILED;
558 return GIF_ERROR;
559 }
560 } else
561 *Extension = NULL;
562
563 return GIF_OK;
564 }
565
566 /******************************************************************************
567 * This routine should be called last, to close the GIF file.
568 *****************************************************************************/
569 int
570 DGifCloseFile(GifFileType * GifFile) {
571
572 GifFilePrivateType *Private;
573 FILE *File;
574
575 if (GifFile == NULL)
576 return GIF_ERROR;
577
578 Private = (GifFilePrivateType *) GifFile->Private;
579
580 if (!IS_READABLE(Private)) {
581 /* This file was NOT open for reading: */
582 _GifError = D_GIF_ERR_NOT_READABLE;
583 return GIF_ERROR;
584 }
585
586 File = Private->File;
587
588 if (GifFile->Image.ColorMap) {
589 FreeMapObject(GifFile->Image.ColorMap);
590 GifFile->Image.ColorMap = NULL;
591 }
592
593 if (GifFile->SColorMap) {
594 FreeMapObject(GifFile->SColorMap);
595 GifFile->SColorMap = NULL;
596 }
597
598 if (Private) {
599 free((char *)Private);
600 Private = NULL;
601 }
602
603 if (GifFile->SavedImages) {
604 FreeSavedImages(GifFile);
605 GifFile->SavedImages = NULL;
606 }
607
608 free(GifFile);
609
610 if (File && (fclose(File) != 0)) {
611 _GifError = D_GIF_ERR_CLOSE_FAILED;
612 return GIF_ERROR;
613 }
614 return GIF_OK;
615 }
616
617 /******************************************************************************
618 * Get 2 bytes (word) from the given file:
619 *****************************************************************************/
620 static int
621 DGifGetWord(GifFileType * GifFile,
622 GifWord *Word) {
623
624 unsigned char c[2];
625
626 if (READ(GifFile, c, 2) != 2) {
627 _GifError = D_GIF_ERR_READ_FAILED;
628 return GIF_ERROR;
629 }
630
631 *Word = (((unsigned int)c[1]) << 8) + c[0];
632 return GIF_OK;
633 }
634
635 /******************************************************************************
636 * Get the image code in compressed form. This routine can be called if the
637 * information needed to be piped out as is. Obviously this is much faster
638 * than decoding and encoding again. This routine should be followed by calls
639 * to DGifGetCodeNext, until NULL block is returned.
640 * The block should NOT be freed by the user (not dynamically allocated).
641 *****************************************************************************/
642 int
643 DGifGetCode(GifFileType * GifFile,
644 int *CodeSize,
645 GifByteType ** CodeBlock) {
646
647 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
648
649 if (!IS_READABLE(Private)) {
650 /* This file was NOT open for reading: */
651 _GifError = D_GIF_ERR_NOT_READABLE;
652 return GIF_ERROR;
653 }
654
655 *CodeSize = Private->BitsPerPixel;
656
657 return DGifGetCodeNext(GifFile, CodeBlock);
658 }
659
660 /******************************************************************************
661 * Continue to get the image code in compressed form. This routine should be
662 * called until NULL block is returned.
663 * The block should NOT be freed by the user (not dynamically allocated).
664 *****************************************************************************/
665 int
666 DGifGetCodeNext(GifFileType * GifFile,
667 GifByteType ** CodeBlock) {
668
669 GifByteType Buf;
670 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
671
672 if (READ(GifFile, &Buf, 1) != 1) {
673 _GifError = D_GIF_ERR_READ_FAILED;
674 return GIF_ERROR;
675 }
676
677 if (Buf > 0) {
678 *CodeBlock = Private->Buf; /* Use private unused buffer. */
679 (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
680 if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
681 _GifError = D_GIF_ERR_READ_FAILED;
682 return GIF_ERROR;
683 }
684 } else {
685 *CodeBlock = NULL;
686 Private->Buf[0] = 0; /* Make sure the buffer is empty! */
687 Private->PixelCount = 0; /* And local info. indicate image read. */
688 }
689
690 return GIF_OK;
691 }
692
693 /******************************************************************************
694 * Setup the LZ decompression for this image:
695 *****************************************************************************/
696 static int
697 DGifSetupDecompress(GifFileType * GifFile) {
698
699 int i, BitsPerPixel;
700 GifByteType CodeSize;
701 GifPrefixType *Prefix;
702 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
703
704 READ(GifFile, &CodeSize, 1); /* Read Code size from file. */
705 BitsPerPixel = CodeSize;
706
707 Private->Buf[0] = 0; /* Input Buffer empty. */
708 Private->BitsPerPixel = BitsPerPixel;
709 Private->ClearCode = (1 << BitsPerPixel);
710 Private->EOFCode = Private->ClearCode + 1;
711 Private->RunningCode = Private->EOFCode + 1;
712 Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
713 Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
714 Private->StackPtr = 0; /* No pixels on the pixel stack. */
715 Private->LastCode = NO_SUCH_CODE;
716 Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
717 Private->CrntShiftDWord = 0;
718
719 Prefix = Private->Prefix;
720 for (i = 0; i <= LZ_MAX_CODE; i++)
721 Prefix[i] = NO_SUCH_CODE;
722
723 return GIF_OK;
724 }
725
726 /******************************************************************************
727 * The LZ decompression routine:
728 * This version decompress the given gif file into Line of length LineLen.
729 * This routine can be called few times (one per scan line, for example), in
730 * order the complete the whole image.
731 *****************************************************************************/
732 static int
733 DGifDecompressLine(GifFileType * GifFile,
734 GifPixelType * Line,
735 int LineLen) {
736
737 int i = 0;
738 int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
739 GifByteType *Stack, *Suffix;
740 GifPrefixType *Prefix;
741 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
742
743 StackPtr = Private->StackPtr;
744 Prefix = Private->Prefix;
745 Suffix = Private->Suffix;
746 Stack = Private->Stack;
747 EOFCode = Private->EOFCode;
748 ClearCode = Private->ClearCode;
749 LastCode = Private->LastCode;
750
751 if (StackPtr > LZ_MAX_CODE) {
752 return GIF_ERROR;
753 }
754
755 if (StackPtr != 0) {
756 /* Let pop the stack off before continueing to read the gif file: */
757 while (StackPtr != 0 && i < LineLen)
758 Line[i++] = Stack[--StackPtr];
759 }
760
761 while (i < LineLen) { /* Decode LineLen items. */
762 if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
763 return GIF_ERROR;
764
765 if (CrntCode == EOFCode) {
766 /* Note however that usually we will not be here as we will stop
767 * decoding as soon as we got all the pixel, or EOF code will
768 * not be read at all, and DGifGetLine/Pixel clean everything. */
769 if (i != LineLen - 1 || Private->PixelCount != 0) {
770 _GifError = D_GIF_ERR_EOF_TOO_SOON;
771 return GIF_ERROR;
772 }
773 i++;
774 } else if (CrntCode == ClearCode) {
775 /* We need to start over again: */
776 for (j = 0; j <= LZ_MAX_CODE; j++)
777 Prefix[j] = NO_SUCH_CODE;
778 Private->RunningCode = Private->EOFCode + 1;
779 Private->RunningBits = Private->BitsPerPixel + 1;
780 Private->MaxCode1 = 1 << Private->RunningBits;
781 LastCode = Private->LastCode = NO_SUCH_CODE;
782 } else {
783 /* Its regular code - if in pixel range simply add it to output
784 * stream, otherwise trace to codes linked list until the prefix
785 * is in pixel range: */
786 if (CrntCode < ClearCode) {
787 /* This is simple - its pixel scalar, so add it to output: */
788 Line[i++] = CrntCode;
789 } else {
790 /* Its a code to needed to be traced: trace the linked list
791 * until the prefix is a pixel, while pushing the suffix
792 * pixels on our stack. If we done, pop the stack in reverse
793 * (thats what stack is good for!) order to output. */
794 if (Prefix[CrntCode] == NO_SUCH_CODE) {
795 /* Only allowed if CrntCode is exactly the running code:
796 * In that case CrntCode = XXXCode, CrntCode or the
797 * prefix code is last code and the suffix char is
798 * exactly the prefix of last code! */
799 if (CrntCode == Private->RunningCode - 2) {
800 CrntPrefix = LastCode;
801 Suffix[Private->RunningCode - 2] =
802 Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
803 LastCode,
804 ClearCode);
805 } else {
806 _GifError = D_GIF_ERR_IMAGE_DEFECT;
807 return GIF_ERROR;
808 }
809 } else
810 CrntPrefix = CrntCode;
811
812 /* Now (if image is O.K.) we should not get an NO_SUCH_CODE
813 * During the trace. As we might loop forever, in case of
814 * defective image, we count the number of loops we trace
815 * and stop if we got LZ_MAX_CODE. obviously we can not
816 * loop more than that. */
817 j = 0;
818 while (j++ <= LZ_MAX_CODE &&
819 CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
820 Stack[StackPtr++] = Suffix[CrntPrefix];
821 CrntPrefix = Prefix[CrntPrefix];
822 }
823 if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
824 _GifError = D_GIF_ERR_IMAGE_DEFECT;
825 return GIF_ERROR;
826 }
827 /* Push the last character on stack: */
828 Stack[StackPtr++] = CrntPrefix;
829
830 /* Now lets pop all the stack into output: */
831 while (StackPtr != 0 && i < LineLen)
832 Line[i++] = Stack[--StackPtr];
833 }
834 if (LastCode != NO_SUCH_CODE) {
835 Prefix[Private->RunningCode - 2] = LastCode;
836
837 if (CrntCode == Private->RunningCode - 2) {
838 /* Only allowed if CrntCode is exactly the running code:
839 * In that case CrntCode = XXXCode, CrntCode or the
840 * prefix code is last code and the suffix char is
841 * exactly the prefix of last code! */
842 Suffix[Private->RunningCode - 2] =
843 DGifGetPrefixChar(Prefix, LastCode, ClearCode);
844 } else {
845 Suffix[Private->RunningCode - 2] =
846 DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
847 }
848 }
849 LastCode = CrntCode;
850 }
851 }
852
853 Private->LastCode = LastCode;
854 Private->StackPtr = StackPtr;
855
856 return GIF_OK;
857 }
858
859 /******************************************************************************
860 * Routine to trace the Prefixes linked list until we get a prefix which is
861 * not code, but a pixel value (less than ClearCode). Returns that pixel value.
862 * If image is defective, we might loop here forever, so we limit the loops to
863 * the maximum possible if image O.k. - LZ_MAX_CODE times.
864 *****************************************************************************/
865 static int
866 DGifGetPrefixChar(GifPrefixType *Prefix,
867 int Code,
868 int ClearCode) {
869
870 int i = 0;
871
872 while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
873 if (Code > LZ_MAX_CODE) {
874 return NO_SUCH_CODE;
875 }
876 Code = Prefix[Code];
877 }
878 return Code;
879 }
880
881 /******************************************************************************
882 * Interface for accessing the LZ codes directly. Set Code to the real code
883 * (12bits), or to -1 if EOF code is returned.
884 *****************************************************************************/
885 int
886 DGifGetLZCodes(GifFileType * GifFile,
887 int *Code) {
888
889 GifByteType *CodeBlock;
890 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
891
892 if (!IS_READABLE(Private)) {
893 /* This file was NOT open for reading: */
894 _GifError = D_GIF_ERR_NOT_READABLE;
895 return GIF_ERROR;
896 }
897
898 if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
899 return GIF_ERROR;
900
901 if (*Code == Private->EOFCode) {
902 /* Skip rest of codes (hopefully only NULL terminating block): */
903 do {
904 if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
905 return GIF_ERROR;
906 } while (CodeBlock != NULL) ;
907
908 *Code = -1;
909 } else if (*Code == Private->ClearCode) {
910 /* We need to start over again: */
911 Private->RunningCode = Private->EOFCode + 1;
912 Private->RunningBits = Private->BitsPerPixel + 1;
913 Private->MaxCode1 = 1 << Private->RunningBits;
914 }
915
916 return GIF_OK;
917 }
918
919 /******************************************************************************
920 * The LZ decompression input routine:
921 * This routine is responsable for the decompression of the bit stream from
922 * 8 bits (bytes) packets, into the real codes.
923 * Returns GIF_OK if read succesfully.
924 *****************************************************************************/
925 static int
926 DGifDecompressInput(GifFileType * GifFile,
927 int *Code) {
928
929 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
930
931 GifByteType NextByte;
932 static unsigned short CodeMasks[] = {
933 0x0000, 0x0001, 0x0003, 0x0007,
934 0x000f, 0x001f, 0x003f, 0x007f,
935 0x00ff, 0x01ff, 0x03ff, 0x07ff,
936 0x0fff
937 };
938 /* The image can't contain more than LZ_BITS per code. */
939 if (Private->RunningBits > LZ_BITS) {
940 _GifError = D_GIF_ERR_IMAGE_DEFECT;
941 return GIF_ERROR;
942 }
943
944 while (Private->CrntShiftState < Private->RunningBits) {
945 /* Needs to get more bytes from input stream for next code: */
946 if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
947 return GIF_ERROR;
948 }
949 Private->CrntShiftDWord |=
950 ((unsigned long)NextByte) << Private->CrntShiftState;
951 Private->CrntShiftState += 8;
952 }
953 *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
954
955 Private->CrntShiftDWord >>= Private->RunningBits;
956 Private->CrntShiftState -= Private->RunningBits;
957
958 /* If code cannot fit into RunningBits bits, must raise its size. Note
959 * however that codes above 4095 are used for special signaling.
960 * If we're using LZ_BITS bits already and we're at the max code, just
961 * keep using the table as it is, don't increment Private->RunningCode.
962 */
963 if (Private->RunningCode < LZ_MAX_CODE + 2 &&
964 ++Private->RunningCode > Private->MaxCode1 &&
965 Private->RunningBits < LZ_BITS) {
966 Private->MaxCode1 <<= 1;
967 Private->RunningBits++;
968 }
969 return GIF_OK;
970 }
971
972 /******************************************************************************
973 * This routines read one gif data block at a time and buffers it internally
974 * so that the decompression routine could access it.
975 * The routine returns the next byte from its internal buffer (or read next
976 * block in if buffer empty) and returns GIF_OK if succesful.
977 *****************************************************************************/
978 static int
979 DGifBufferedInput(GifFileType * GifFile,
980 GifByteType * Buf,
981 GifByteType * NextByte) {
982
983 if (Buf[0] == 0) {
984 /* Needs to read the next buffer - this one is empty: */
985 if (READ(GifFile, Buf, 1) != 1) {
986 _GifError = D_GIF_ERR_READ_FAILED;
987 return GIF_ERROR;
988 }
989 /* There shouldn't be any empty data blocks here as the LZW spec
990 * says the LZW termination code should come first. Therefore we
991 * shouldn't be inside this routine at that point.
992 */
993 if (Buf[0] == 0) {
994 _GifError = D_GIF_ERR_IMAGE_DEFECT;
995 return GIF_ERROR;
996 }
997 if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
998 _GifError = D_GIF_ERR_READ_FAILED;
999 return GIF_ERROR;
1000 }
1001 *NextByte = Buf[1];
1002 Buf[1] = 2; /* We use now the second place as last char read! */
1003 Buf[0]--;
1004 } else {
1005 *NextByte = Buf[Buf[1]++];
1006 Buf[0]--;
1007 }
1008
1009 return GIF_OK;
1010 }
1011 #ifndef _GBA_NO_FILEIO
1012
1013 /******************************************************************************
1014 * This routine reads an entire GIF into core, hanging all its state info off
1015 * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
1016 * first to initialize I/O. Its inverse is EGifSpew().
1017 ******************************************************************************/
1018 int
1019 DGifSlurp(GifFileType * GifFile) {
1020
1021 int ImageSize;
1022 GifRecordType RecordType;
1023 SavedImage *sp;
1024 GifByteType *ExtData;
1025 SavedImage temp_save;
1026
1027 temp_save.ExtensionBlocks = NULL;
1028 temp_save.ExtensionBlockCount = 0;
1029
1030 do {
1031 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
1032 return (GIF_ERROR);
1033
1034 switch (RecordType) {
1035 case IMAGE_DESC_RECORD_TYPE:
1036 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
1037 return (GIF_ERROR);
1038
1039 sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
1040 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1041
1042 sp->RasterBits = (unsigned char *)malloc(ImageSize *
1043 sizeof(GifPixelType));
1044 if (sp->RasterBits == NULL) {
1045 return GIF_ERROR;
1046 }
1047 if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==
1048 GIF_ERROR)
1049 return (GIF_ERROR);
1050 if (temp_save.ExtensionBlocks) {
1051 sp->ExtensionBlocks = temp_save.ExtensionBlocks;
1052 sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;
1053
1054 temp_save.ExtensionBlocks = NULL;
1055 temp_save.ExtensionBlockCount = 0;
1056
1057 /* FIXME: The following is wrong. It is left in only for
1058 * backwards compatibility. Someday it should go away. Use
1059 * the sp->ExtensionBlocks->Function variable instead. */
1060 sp->Function = sp->ExtensionBlocks[0].Function;
1061 }
1062 break;
1063
1064 case EXTENSION_RECORD_TYPE:
1065 if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==
1066 GIF_ERROR)
1067 return (GIF_ERROR);
1068 while (ExtData != NULL) {
1069
1070 /* Create an extension block with our data */
1071 if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])
1072 == GIF_ERROR)
1073 return (GIF_ERROR);
1074
1075 if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1076 return (GIF_ERROR);
1077 temp_save.Function = 0;
1078 }
1079 break;
1080
1081 case TERMINATE_RECORD_TYPE:
1082 break;
1083
1084 default: /* Should be trapped by DGifGetRecordType */
1085 break;
1086 }
1087 } while (RecordType != TERMINATE_RECORD_TYPE);
1088
1089 /* Just in case the Gif has an extension block without an associated
1090 * image... (Should we save this into a savefile structure with no image
1091 * instead? Have to check if the present writing code can handle that as
1092 * well.... */
1093 if (temp_save.ExtensionBlocks)
1094 FreeExtension(&temp_save);
1095
1096 return (GIF_OK);
1097 }
1098 #endif /* _GBA_NO_FILEIO */
1099