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