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