19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /******************************************************************************
26
27 dgif_lib.c - GIF decoding
28
29 The functions here and in egif_lib.c are partitioned carefully so that
30 if you only require one of read and write capability, only one of these
31 two modules will be linked. Preserve this property!
32
33 *****************************************************************************/
34
35 #include <stdlib.h>
36 #include <limits.h>
37 #include <stdint.h>
38 #include <fcntl.h>
39 #include <stdio.h>
40 #include <string.h>
41
42 #ifdef _WIN32
43 #include <io.h>
44 #else
45 #include <unistd.h>
46 #endif /* _WIN32 */
47
48 #include "gif_lib.h"
49 #include "gif_lib_private.h"
50
51 /* compose unsigned little endian value */
52 #define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8))
53
54 /* avoid extra function call in case we use fread (TVT) */
55 #define READ(_gif,_buf,_len) \
56 (((GifFilePrivateType*)_gif->Private)->Read ? \
57 ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
58 fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
59
60 static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
61 static int DGifSetupDecompress(GifFileType *GifFile);
62 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
63 int LineLen);
64 static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
65 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
66 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
67 GifByteType *NextByte);
68
69 /******************************************************************************
70 Open a new GIF file for read, given by its name.
71 Returns dynamically allocated GifFileType pointer which serves as the GIF
72 info record.
73 ******************************************************************************/
74 GifFileType *
75 DGifOpenFileName(const char *FileName, int *Error)
76 {
77 int FileHandle;
78 GifFileType *GifFile;
125
126 /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
127
128 #ifdef _WIN32
129 _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
130 #endif /* _WIN32 */
131
132 f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
133
134 /*@-mustfreeonly@*/
135 GifFile->Private = (void *)Private;
136 Private->FileHandle = FileHandle;
137 Private->File = f;
138 Private->FileState = FILE_STATE_READ;
139 Private->Read = NULL; /* don't use alternate input method (TVT) */
140 GifFile->UserData = NULL; /* TVT */
141 /*@=mustfreeonly@*/
142
143 /* Let's see if this is a GIF file: */
144 /* coverity[check_return] */
145 if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
146 if (Error != NULL)
147 *Error = D_GIF_ERR_READ_FAILED;
148 (void)fclose(f);
149 free((char *)Private);
150 free((char *)GifFile);
151 return NULL;
152 }
153
154 /* Check for GIF prefix at start of file */
155 Buf[GIF_STAMP_LEN] = 0;
156 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
157 if (Error != NULL)
158 *Error = D_GIF_ERR_NOT_GIF_FILE;
159 (void)fclose(f);
160 free((char *)Private);
161 free((char *)GifFile);
162 return NULL;
163 }
164
165 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
202
203 Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
204 if (!Private) {
205 if (Error != NULL)
206 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
207 free((char *)GifFile);
208 return NULL;
209 }
210 /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
211
212 GifFile->Private = (void *)Private;
213 Private->FileHandle = 0;
214 Private->File = NULL;
215 Private->FileState = FILE_STATE_READ;
216
217 Private->Read = readFunc; /* TVT */
218 GifFile->UserData = userData; /* TVT */
219
220 /* Lets see if this is a GIF file: */
221 /* coverity[check_return] */
222 if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
223 if (Error != NULL)
224 *Error = D_GIF_ERR_READ_FAILED;
225 free((char *)Private);
226 free((char *)GifFile);
227 return NULL;
228 }
229
230 /* Check for GIF prefix at start of file */
231 Buf[GIF_STAMP_LEN] = '\0';
232 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
233 if (Error != NULL)
234 *Error = D_GIF_ERR_NOT_GIF_FILE;
235 free((char *)Private);
236 free((char *)GifFile);
237 return NULL;
238 }
239
240 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
241 free((char *)Private);
242 free((char *)GifFile);
259 ******************************************************************************/
260 int
261 DGifGetScreenDesc(GifFileType *GifFile)
262 {
263 int BitsPerPixel;
264 bool SortFlag;
265 GifByteType Buf[3];
266 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
267
268 if (!IS_READABLE(Private)) {
269 /* This file was NOT open for reading: */
270 GifFile->Error = D_GIF_ERR_NOT_READABLE;
271 return GIF_ERROR;
272 }
273
274 /* Put the screen descriptor into the file: */
275 if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
276 DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
277 return GIF_ERROR;
278
279 if (READ(GifFile, Buf, 3) != 3) {
280 GifFile->Error = D_GIF_ERR_READ_FAILED;
281 GifFreeMapObject(GifFile->SColorMap);
282 GifFile->SColorMap = NULL;
283 return GIF_ERROR;
284 }
285 GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
286 SortFlag = (Buf[0] & 0x08) != 0;
287 BitsPerPixel = (Buf[0] & 0x07) + 1;
288 GifFile->SBackGroundColor = Buf[1];
289 GifFile->AspectByte = Buf[2];
290 if (Buf[0] & 0x80) { /* Do we have global color map? */
291 int i;
292
293 GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
294 if (GifFile->SColorMap == NULL) {
295 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
296 return GIF_ERROR;
297 }
298
299 /* Get the global color map: */
300 GifFile->SColorMap->SortFlag = SortFlag;
301 for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
302 /* coverity[check_return] */
303 if (READ(GifFile, Buf, 3) != 3) {
304 GifFreeMapObject(GifFile->SColorMap);
305 GifFile->SColorMap = NULL;
306 GifFile->Error = D_GIF_ERR_READ_FAILED;
307 return GIF_ERROR;
308 }
309 GifFile->SColorMap->Colors[i].Red = Buf[0];
310 GifFile->SColorMap->Colors[i].Green = Buf[1];
311 GifFile->SColorMap->Colors[i].Blue = Buf[2];
312 }
313 } else {
314 GifFile->SColorMap = NULL;
315 }
316
317 return GIF_OK;
318 }
319
320 /******************************************************************************
321 This routine should be called before any attempt to read an image.
322 ******************************************************************************/
323 int
324 DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
325 {
326 GifByteType Buf;
327 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
328
329 if (!IS_READABLE(Private)) {
330 /* This file was NOT open for reading: */
331 GifFile->Error = D_GIF_ERR_NOT_READABLE;
332 return GIF_ERROR;
333 }
334
335 /* coverity[check_return] */
336 if (READ(GifFile, &Buf, 1) != 1) {
337 GifFile->Error = D_GIF_ERR_READ_FAILED;
338 return GIF_ERROR;
339 }
340
341 switch (Buf) {
342 case DESCRIPTOR_INTRODUCER:
343 *Type = IMAGE_DESC_RECORD_TYPE;
344 break;
345 case EXTENSION_INTRODUCER:
346 *Type = EXTENSION_RECORD_TYPE;
347 break;
348 case TERMINATOR_INTRODUCER:
349 *Type = TERMINATE_RECORD_TYPE;
350 break;
351 default:
352 *Type = UNDEFINED_RECORD_TYPE;
353 GifFile->Error = D_GIF_ERR_WRONG_RECORD;
354 return GIF_ERROR;
355 }
356
357 return GIF_OK;
358 }
359
360 /******************************************************************************
361 This routine should be called before any attempt to read an image.
362 Note it is assumed the Image desc. header has been read.
363 ******************************************************************************/
364 int
365 DGifGetImageDesc(GifFileType *GifFile)
366 {
367 unsigned int BitsPerPixel;
368 GifByteType Buf[3];
369 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
370 SavedImage *sp;
371
372 if (!IS_READABLE(Private)) {
373 /* This file was NOT open for reading: */
374 GifFile->Error = D_GIF_ERR_NOT_READABLE;
375 return GIF_ERROR;
376 }
377
378 if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
379 DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
380 DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
381 DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
382 return GIF_ERROR;
383 if (READ(GifFile, Buf, 1) != 1) {
384 GifFile->Error = D_GIF_ERR_READ_FAILED;
385 GifFreeMapObject(GifFile->Image.ColorMap);
386 GifFile->Image.ColorMap = NULL;
387 return GIF_ERROR;
388 }
389 BitsPerPixel = (Buf[0] & 0x07) + 1;
390 GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
391
392 /* Setup the colormap */
393 if (GifFile->Image.ColorMap) {
394 GifFreeMapObject(GifFile->Image.ColorMap);
395 GifFile->Image.ColorMap = NULL;
396 }
397 /* Does this image have local color map? */
398 if (Buf[0] & 0x80) {
399 unsigned int i;
400
401 GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
402 if (GifFile->Image.ColorMap == NULL) {
403 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
404 return GIF_ERROR;
405 }
406
407 /* Get the image local color map: */
408 for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
409 /* coverity[check_return] */
410 if (READ(GifFile, Buf, 3) != 3) {
411 GifFreeMapObject(GifFile->Image.ColorMap);
412 GifFile->Error = D_GIF_ERR_READ_FAILED;
413 GifFile->Image.ColorMap = NULL;
414 return GIF_ERROR;
415 }
416 GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
417 GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
418 GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
419 }
420 }
421
422 if (GifFile->SavedImages) {
423 SavedImage* new_saved_images =
424 (SavedImage *)reallocarray(GifFile->SavedImages,
425 (GifFile->ImageCount + 1), sizeof(SavedImage));
426 if (new_saved_images == NULL) {
427 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
428 return GIF_ERROR;
429 }
430 GifFile->SavedImages = new_saved_images;
431 } else {
432 if ((GifFile->SavedImages =
433 (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
434 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
435 return GIF_ERROR;
436 }
437 }
438
439 sp = &GifFile->SavedImages[GifFile->ImageCount];
440 memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
441 if (GifFile->Image.ColorMap != NULL) {
442 sp->ImageDesc.ColorMap = GifMakeMapObject(
443 GifFile->Image.ColorMap->ColorCount,
444 GifFile->Image.ColorMap->Colors);
445 if (sp->ImageDesc.ColorMap == NULL) {
446 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
447 return GIF_ERROR;
448 }
449 }
450 sp->RasterBits = (unsigned char *)NULL;
451 sp->ExtensionBlockCount = 0;
452 sp->ExtensionBlocks = (ExtensionBlock *) NULL;
453
454 GifFile->ImageCount++;
455
456 Private->PixelCount = (long)GifFile->Image.Width *
457 (long)GifFile->Image.Height;
458
459 /* Reset decompress algorithm parameters. */
460 return DGifSetupDecompress(GifFile);
461 }
462
463 /******************************************************************************
464 Get one full scanned line (Line) of length LineLen from GIF file.
465 ******************************************************************************/
466 int
467 DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
468 {
469 GifByteType *Dummy;
470 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
471
472 if (!IS_READABLE(Private)) {
473 /* This file was NOT open for reading: */
474 GifFile->Error = D_GIF_ERR_NOT_READABLE;
475 return GIF_ERROR;
476 }
477
478 if (!LineLen)
479 LineLen = GifFile->Image.Width;
480
533 while (Dummy != NULL) ;
534 }
535 return GIF_OK;
536 } else
537 return GIF_ERROR;
538 }
539
540 /******************************************************************************
541 Get an extension block (see GIF manual) from GIF file. This routine only
542 returns the first data block, and DGifGetExtensionNext should be called
543 after this one until NULL extension is returned.
544 The Extension should NOT be freed by the user (not dynamically allocated).
545 Note it is assumed the Extension description header has been read.
546 ******************************************************************************/
547 int
548 DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
549 {
550 GifByteType Buf;
551 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
552
553 if (!IS_READABLE(Private)) {
554 /* This file was NOT open for reading: */
555 GifFile->Error = D_GIF_ERR_NOT_READABLE;
556 return GIF_ERROR;
557 }
558
559 /* coverity[check_return] */
560 if (READ(GifFile, &Buf, 1) != 1) {
561 GifFile->Error = D_GIF_ERR_READ_FAILED;
562 return GIF_ERROR;
563 }
564 *ExtCode = Buf;
565
566 return DGifGetExtensionNext(GifFile, Extension);
567 }
568
569 /******************************************************************************
570 Get a following extension block (see GIF manual) from GIF file. This
571 routine should be called until NULL Extension is returned.
572 The Extension should NOT be freed by the user (not dynamically allocated).
573 ******************************************************************************/
574 int
575 DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
576 {
577 GifByteType Buf;
578 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
579
580 if (READ(GifFile, &Buf, 1) != 1) {
581 GifFile->Error = D_GIF_ERR_READ_FAILED;
582 return GIF_ERROR;
583 }
584 if (Buf > 0) {
585 *Extension = Private->Buf; /* Use private unused buffer. */
586 (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
587 /* coverity[tainted_data,check_return] */
588 if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
589 GifFile->Error = D_GIF_ERR_READ_FAILED;
590 return GIF_ERROR;
591 }
592 } else
593 *Extension = NULL;
594
595 return GIF_OK;
596 }
597
598 /******************************************************************************
599 Extract a Graphics Control Block from raw extension data
600 ******************************************************************************/
601
602 int DGifExtensionToGCB(const size_t GifExtensionLength,
603 const GifByteType *GifExtension,
604 GraphicsControlBlock *GCB)
605 {
606 if (GifExtensionLength != 4) {
607 return GIF_ERROR;
608 }
609
610 GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
611 GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
612 GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
613 if (GifExtension[0] & 0x01)
690 free(GifFile);
691 return GIF_ERROR;
692 }
693
694 free((char *)GifFile->Private);
695 free(GifFile);
696 if (ErrorCode != NULL)
697 *ErrorCode = D_GIF_SUCCEEDED;
698 return GIF_OK;
699 }
700
701 /******************************************************************************
702 Get 2 bytes (word) from the given file:
703 ******************************************************************************/
704 static int
705 DGifGetWord(GifFileType *GifFile, GifWord *Word)
706 {
707 unsigned char c[2];
708
709 /* coverity[check_return] */
710 if (READ(GifFile, c, 2) != 2) {
711 GifFile->Error = D_GIF_ERR_READ_FAILED;
712 return GIF_ERROR;
713 }
714
715 *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
716 return GIF_OK;
717 }
718
719 /******************************************************************************
720 Get the image code in compressed form. This routine can be called if the
721 information needed to be piped out as is. Obviously this is much faster
722 than decoding and encoding again. This routine should be followed by calls
723 to DGifGetCodeNext, until NULL block is returned.
724 The block should NOT be freed by the user (not dynamically allocated).
725 ******************************************************************************/
726 int
727 DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
728 {
729 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
730
735 }
736
737 *CodeSize = Private->BitsPerPixel;
738
739 return DGifGetCodeNext(GifFile, CodeBlock);
740 }
741
742 /******************************************************************************
743 Continue to get the image code in compressed form. This routine should be
744 called until NULL block is returned.
745 The block should NOT be freed by the user (not dynamically allocated).
746 ******************************************************************************/
747 int
748 DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
749 {
750 GifByteType Buf;
751 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
752
753 /* coverity[tainted_data_argument] */
754 /* coverity[check_return] */
755 if (READ(GifFile, &Buf, 1) != 1) {
756 GifFile->Error = D_GIF_ERR_READ_FAILED;
757 return GIF_ERROR;
758 }
759
760 /* coverity[lower_bounds] */
761 if (Buf > 0) {
762 *CodeBlock = Private->Buf; /* Use private unused buffer. */
763 (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
764 /* coverity[tainted_data] */
765 if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
766 GifFile->Error = D_GIF_ERR_READ_FAILED;
767 return GIF_ERROR;
768 }
769 } else {
770 *CodeBlock = NULL;
771 Private->Buf[0] = 0; /* Make sure the buffer is empty! */
772 Private->PixelCount = 0; /* And local info. indicate image read. */
773 }
774
775 return GIF_OK;
776 }
777
778 /******************************************************************************
779 Setup the LZ decompression for this image:
780 ******************************************************************************/
781 static int
782 DGifSetupDecompress(GifFileType *GifFile)
783 {
784 int i, BitsPerPixel;
785 GifByteType CodeSize;
786 GifPrefixType *Prefix;
787 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
788
789 /* coverity[check_return] */
790 if (READ(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */
791 return GIF_ERROR; /* Failed to read Code size. */
792 }
793 BitsPerPixel = CodeSize;
794
795 /* this can only happen on a severely malformed GIF */
796 if (BitsPerPixel > 8) {
797 GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
798 return GIF_ERROR; /* Failed to read Code size. */
799 }
800
801 Private->Buf[0] = 0; /* Input Buffer empty. */
802 Private->BitsPerPixel = BitsPerPixel;
803 Private->ClearCode = (1 << BitsPerPixel);
804 Private->EOFCode = Private->ClearCode + 1;
805 Private->RunningCode = Private->EOFCode + 1;
806 Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
807 Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
808 Private->StackPtr = 0; /* No pixels on the pixel stack. */
809 Private->LastCode = NO_SUCH_CODE;
810 Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
904 /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
905 * during the trace. As we might loop forever, in case of
906 * defective image, we use StackPtr as loop counter and stop
907 * before overflowing Stack[]. */
908 while (StackPtr < LZ_MAX_CODE &&
909 CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
910 Stack[StackPtr++] = Suffix[CrntPrefix];
911 CrntPrefix = Prefix[CrntPrefix];
912 }
913 if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
914 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
915 return GIF_ERROR;
916 }
917 /* Push the last character on stack: */
918 Stack[StackPtr++] = CrntPrefix;
919
920 /* Now lets pop all the stack into output: */
921 while (StackPtr != 0 && i < LineLen)
922 Line[i++] = Stack[--StackPtr];
923 }
924 if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
925 Prefix[Private->RunningCode - 2] = LastCode;
926
927 if (CrntCode == Private->RunningCode - 2) {
928 /* Only allowed if CrntCode is exactly the running code:
929 * In that case CrntCode = XXXCode, CrntCode or the
930 * prefix code is last code and the suffix char is
931 * exactly the prefix of last code! */
932 Suffix[Private->RunningCode - 2] =
933 DGifGetPrefixChar(Prefix, LastCode, ClearCode);
934 } else {
935 Suffix[Private->RunningCode - 2] =
936 DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
937 }
938 }
939 LastCode = CrntCode;
940 }
941 }
942
943 Private->LastCode = LastCode;
944 Private->StackPtr = StackPtr;
1052 ++Private->RunningCode > Private->MaxCode1 &&
1053 Private->RunningBits < LZ_BITS) {
1054 Private->MaxCode1 <<= 1;
1055 Private->RunningBits++;
1056 }
1057 return GIF_OK;
1058 }
1059
1060 /******************************************************************************
1061 This routines read one GIF data block at a time and buffers it internally
1062 so that the decompression routine could access it.
1063 The routine returns the next byte from its internal buffer (or read next
1064 block in if buffer empty) and returns GIF_OK if succesful.
1065 ******************************************************************************/
1066 static int
1067 DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
1068 {
1069 if (Buf[0] == 0) {
1070 /* Needs to read the next buffer - this one is empty: */
1071 /* coverity[check_return] */
1072 if (READ(GifFile, Buf, 1) != 1) {
1073 GifFile->Error = D_GIF_ERR_READ_FAILED;
1074 return GIF_ERROR;
1075 }
1076 /* There shouldn't be any empty data blocks here as the LZW spec
1077 * says the LZW termination code should come first. Therefore we
1078 * shouldn't be inside this routine at that point.
1079 */
1080 if (Buf[0] == 0) {
1081 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1082 return GIF_ERROR;
1083 }
1084 if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1085 GifFile->Error = D_GIF_ERR_READ_FAILED;
1086 return GIF_ERROR;
1087 }
1088 *NextByte = Buf[1];
1089 Buf[1] = 2; /* We use now the second place as last char read! */
1090 Buf[0]--;
1091 } else {
1092 *NextByte = Buf[Buf[1]++];
1093 Buf[0]--;
1094 }
1095
1096 return GIF_OK;
1097 }
1098
1099 /******************************************************************************
1100 This routine reads an entire GIF into core, hanging all its state info off
1101 the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
1102 first to initialize I/O. Its inverse is EGifSpew().
1103 *******************************************************************************/
1104 int
1107 size_t ImageSize;
1108 GifRecordType RecordType;
1109 SavedImage *sp;
1110 GifByteType *ExtData;
1111 int ExtFunction;
1112
1113 GifFile->ExtensionBlocks = NULL;
1114 GifFile->ExtensionBlockCount = 0;
1115
1116 do {
1117 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
1118 return (GIF_ERROR);
1119
1120 switch (RecordType) {
1121 case IMAGE_DESC_RECORD_TYPE:
1122 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
1123 return (GIF_ERROR);
1124
1125 sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
1126 /* Allocate memory for the image */
1127 if (sp->ImageDesc.Width < 0 && sp->ImageDesc.Height < 0 &&
1128 sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
1129 return GIF_ERROR;
1130 }
1131 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1132
1133 if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
1134 return GIF_ERROR;
1135 }
1136 sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
1137 sizeof(GifPixelType));
1138
1139 if (sp->RasterBits == NULL) {
1140 return GIF_ERROR;
1141 }
1142
1143 if (sp->ImageDesc.Interlace) {
1144 int i, j;
1145 /*
1146 * The way an interlaced image should be read -
1147 * offsets and jumps...
1167 if (GifFile->ExtensionBlocks) {
1168 sp->ExtensionBlocks = GifFile->ExtensionBlocks;
1169 sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
1170
1171 GifFile->ExtensionBlocks = NULL;
1172 GifFile->ExtensionBlockCount = 0;
1173 }
1174 break;
1175
1176 case EXTENSION_RECORD_TYPE:
1177 if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
1178 return (GIF_ERROR);
1179 /* Create an extension block with our data */
1180 if (ExtData != NULL) {
1181 if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1182 &GifFile->ExtensionBlocks,
1183 ExtFunction, ExtData[0], &ExtData[1])
1184 == GIF_ERROR)
1185 return (GIF_ERROR);
1186 }
1187 while (ExtData != NULL) {
1188 if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1189 return (GIF_ERROR);
1190 /* Continue the extension block */
1191 if (ExtData != NULL)
1192 if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1193 &GifFile->ExtensionBlocks,
1194 CONTINUE_EXT_FUNC_CODE,
1195 ExtData[0], &ExtData[1]) == GIF_ERROR)
1196 return (GIF_ERROR);
1197 }
1198 break;
1199
1200 case TERMINATE_RECORD_TYPE:
1201 break;
1202
1203 default: /* Should be trapped by DGifGetRecordType */
1204 break;
1205 }
1206 } while (RecordType != TERMINATE_RECORD_TYPE);
1207
1208 /* Sanity check for corrupted file */
1209 if (GifFile->ImageCount == 0) {
|
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /******************************************************************************
26
27 dgif_lib.c - GIF decoding
28
29 The functions here and in egif_lib.c are partitioned carefully so that
30 if you only require one of read and write capability, only one of these
31 two modules will be linked. Preserve this property!
32
33 *****************************************************************************/
34
35 #include <stdlib.h>
36 #include <limits.h>
37 #include <stdint.h>
38 #include <fcntl.h>
39 /** Begin JDK modifications to support building on Windows **/
40 #ifndef _WIN32
41 #include <unistd.h>
42 #endif
43 /** End JDK modifications to support building on Windows **/
44 #include <stdio.h>
45 #include <string.h>
46
47 #ifdef _WIN32
48 #include <io.h>
49 #endif /* _WIN32 */
50
51 #include "gif_lib.h"
52 #include "gif_lib_private.h"
53
54 /* compose unsigned little endian value */
55 #define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8))
56
57 /* avoid extra function call in case we use fread (TVT) */
58 /** JDK modification "inline" is dropped to support c89 **/
59 static /**inline**/ int InternalRead(GifFileType *gif, GifByteType *buf, int len) {
60 //fprintf(stderr, "### Read: %d\n", len);
61 return
62 (((GifFilePrivateType*)gif->Private)->Read ?
63 ((GifFilePrivateType*)gif->Private)->Read(gif,buf,len) :
64 fread(buf,1,len,((GifFilePrivateType*)gif->Private)->File));
65 }
66
67 static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
68 static int DGifSetupDecompress(GifFileType *GifFile);
69 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
70 int LineLen);
71 static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
72 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
73 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
74 GifByteType *NextByte);
75
76 /******************************************************************************
77 Open a new GIF file for read, given by its name.
78 Returns dynamically allocated GifFileType pointer which serves as the GIF
79 info record.
80 ******************************************************************************/
81 GifFileType *
82 DGifOpenFileName(const char *FileName, int *Error)
83 {
84 int FileHandle;
85 GifFileType *GifFile;
132
133 /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
134
135 #ifdef _WIN32
136 _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
137 #endif /* _WIN32 */
138
139 f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
140
141 /*@-mustfreeonly@*/
142 GifFile->Private = (void *)Private;
143 Private->FileHandle = FileHandle;
144 Private->File = f;
145 Private->FileState = FILE_STATE_READ;
146 Private->Read = NULL; /* don't use alternate input method (TVT) */
147 GifFile->UserData = NULL; /* TVT */
148 /*@=mustfreeonly@*/
149
150 /* Let's see if this is a GIF file: */
151 /* coverity[check_return] */
152 if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
153 if (Error != NULL)
154 *Error = D_GIF_ERR_READ_FAILED;
155 (void)fclose(f);
156 free((char *)Private);
157 free((char *)GifFile);
158 return NULL;
159 }
160
161 /* Check for GIF prefix at start of file */
162 Buf[GIF_STAMP_LEN] = 0;
163 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
164 if (Error != NULL)
165 *Error = D_GIF_ERR_NOT_GIF_FILE;
166 (void)fclose(f);
167 free((char *)Private);
168 free((char *)GifFile);
169 return NULL;
170 }
171
172 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
209
210 Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
211 if (!Private) {
212 if (Error != NULL)
213 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
214 free((char *)GifFile);
215 return NULL;
216 }
217 /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
218
219 GifFile->Private = (void *)Private;
220 Private->FileHandle = 0;
221 Private->File = NULL;
222 Private->FileState = FILE_STATE_READ;
223
224 Private->Read = readFunc; /* TVT */
225 GifFile->UserData = userData; /* TVT */
226
227 /* Lets see if this is a GIF file: */
228 /* coverity[check_return] */
229 if (InternalRead(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
230 if (Error != NULL)
231 *Error = D_GIF_ERR_READ_FAILED;
232 free((char *)Private);
233 free((char *)GifFile);
234 return NULL;
235 }
236
237 /* Check for GIF prefix at start of file */
238 Buf[GIF_STAMP_LEN] = '\0';
239 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
240 if (Error != NULL)
241 *Error = D_GIF_ERR_NOT_GIF_FILE;
242 free((char *)Private);
243 free((char *)GifFile);
244 return NULL;
245 }
246
247 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
248 free((char *)Private);
249 free((char *)GifFile);
266 ******************************************************************************/
267 int
268 DGifGetScreenDesc(GifFileType *GifFile)
269 {
270 int BitsPerPixel;
271 bool SortFlag;
272 GifByteType Buf[3];
273 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
274
275 if (!IS_READABLE(Private)) {
276 /* This file was NOT open for reading: */
277 GifFile->Error = D_GIF_ERR_NOT_READABLE;
278 return GIF_ERROR;
279 }
280
281 /* Put the screen descriptor into the file: */
282 if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
283 DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
284 return GIF_ERROR;
285
286 if (InternalRead(GifFile, Buf, 3) != 3) {
287 GifFile->Error = D_GIF_ERR_READ_FAILED;
288 GifFreeMapObject(GifFile->SColorMap);
289 GifFile->SColorMap = NULL;
290 return GIF_ERROR;
291 }
292 GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
293 SortFlag = (Buf[0] & 0x08) != 0;
294 BitsPerPixel = (Buf[0] & 0x07) + 1;
295 GifFile->SBackGroundColor = Buf[1];
296 GifFile->AspectByte = Buf[2];
297 if (Buf[0] & 0x80) { /* Do we have global color map? */
298 int i;
299
300 GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
301 if (GifFile->SColorMap == NULL) {
302 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
303 return GIF_ERROR;
304 }
305
306 /* Get the global color map: */
307 GifFile->SColorMap->SortFlag = SortFlag;
308 for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
309 /* coverity[check_return] */
310 if (InternalRead(GifFile, Buf, 3) != 3) {
311 GifFreeMapObject(GifFile->SColorMap);
312 GifFile->SColorMap = NULL;
313 GifFile->Error = D_GIF_ERR_READ_FAILED;
314 return GIF_ERROR;
315 }
316 GifFile->SColorMap->Colors[i].Red = Buf[0];
317 GifFile->SColorMap->Colors[i].Green = Buf[1];
318 GifFile->SColorMap->Colors[i].Blue = Buf[2];
319 }
320 } else {
321 GifFile->SColorMap = NULL;
322 }
323
324 /*
325 * No check here for whether the background color is in range for the
326 * screen color map. Possibly there should be.
327 */
328
329 return GIF_OK;
330 }
331
332 const char *
333 DGifGetGifVersion(GifFileType *GifFile)
334 {
335 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
336
337 if (Private->gif89)
338 return GIF89_STAMP;
339 else
340 return GIF87_STAMP;
341 }
342
343 /******************************************************************************
344 This routine should be called before any attempt to read an image.
345 ******************************************************************************/
346 int
347 DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
348 {
349 GifByteType Buf;
350 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
351
352 if (!IS_READABLE(Private)) {
353 /* This file was NOT open for reading: */
354 GifFile->Error = D_GIF_ERR_NOT_READABLE;
355 return GIF_ERROR;
356 }
357
358 /* coverity[check_return] */
359 if (InternalRead(GifFile, &Buf, 1) != 1) {
360 GifFile->Error = D_GIF_ERR_READ_FAILED;
361 return GIF_ERROR;
362 }
363
364 //fprintf(stderr, "### DGifGetRecordType: %02x\n", Buf);
365 switch (Buf) {
366 case DESCRIPTOR_INTRODUCER:
367 *Type = IMAGE_DESC_RECORD_TYPE;
368 break;
369 case EXTENSION_INTRODUCER:
370 *Type = EXTENSION_RECORD_TYPE;
371 break;
372 case TERMINATOR_INTRODUCER:
373 *Type = TERMINATE_RECORD_TYPE;
374 break;
375 default:
376 *Type = UNDEFINED_RECORD_TYPE;
377 GifFile->Error = D_GIF_ERR_WRONG_RECORD;
378 return GIF_ERROR;
379 }
380
381 return GIF_OK;
382 }
383
384 int
385 DGifGetImageHeader(GifFileType *GifFile)
386 {
387 unsigned int BitsPerPixel;
388 GifByteType Buf[3];
389 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
390
391 if (!IS_READABLE(Private)) {
392 /* This file was NOT open for reading: */
393 GifFile->Error = D_GIF_ERR_NOT_READABLE;
394 return GIF_ERROR;
395 }
396
397 if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
398 DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
399 DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
400 DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
401 return GIF_ERROR;
402 if (InternalRead(GifFile, Buf, 1) != 1) {
403 GifFile->Error = D_GIF_ERR_READ_FAILED;
404 GifFreeMapObject(GifFile->Image.ColorMap);
405 GifFile->Image.ColorMap = NULL;
406 return GIF_ERROR;
407 }
408 BitsPerPixel = (Buf[0] & 0x07) + 1;
409 GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
410
411 /* Setup the colormap */
412 if (GifFile->Image.ColorMap) {
413 GifFreeMapObject(GifFile->Image.ColorMap);
414 GifFile->Image.ColorMap = NULL;
415 }
416 /* Does this image have local color map? */
417 if (Buf[0] & 0x80) {
418 unsigned int i;
419
420 GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
421 if (GifFile->Image.ColorMap == NULL) {
422 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
423 return GIF_ERROR;
424 }
425
426 /* Get the image local color map: */
427 for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
428 /* coverity[check_return] */
429 if (InternalRead(GifFile, Buf, 3) != 3) {
430 GifFreeMapObject(GifFile->Image.ColorMap);
431 GifFile->Error = D_GIF_ERR_READ_FAILED;
432 GifFile->Image.ColorMap = NULL;
433 return GIF_ERROR;
434 }
435 GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
436 GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
437 GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
438 }
439 }
440
441 Private->PixelCount = (long)GifFile->Image.Width *
442 (long)GifFile->Image.Height;
443
444 /* Reset decompress algorithm parameters. */
445 return DGifSetupDecompress(GifFile);
446 }
447
448 /******************************************************************************
449 This routine should be called before any attempt to read an image.
450 Note it is assumed the Image desc. header has been read.
451 ******************************************************************************/
452 int
453 DGifGetImageDesc(GifFileType *GifFile)
454 {
455 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
456 SavedImage *sp;
457
458 if (!IS_READABLE(Private)) {
459 /* This file was NOT open for reading: */
460 GifFile->Error = D_GIF_ERR_NOT_READABLE;
461 return GIF_ERROR;
462 }
463
464 if (DGifGetImageHeader(GifFile) == GIF_ERROR) {
465 return GIF_ERROR;
466 }
467
468 if (GifFile->SavedImages) {
469 SavedImage* new_saved_images =
470 (SavedImage *)reallocarray(GifFile->SavedImages,
471 (GifFile->ImageCount + 1), sizeof(SavedImage));
472 if (new_saved_images == NULL) {
473 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
474 return GIF_ERROR;
475 }
476 GifFile->SavedImages = new_saved_images;
477 } else {
478 if ((GifFile->SavedImages =
479 (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
480 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
481 return GIF_ERROR;
482 }
483 }
484
485 sp = &GifFile->SavedImages[GifFile->ImageCount];
486 memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
487 if (GifFile->Image.ColorMap != NULL) {
488 sp->ImageDesc.ColorMap = GifMakeMapObject(
489 GifFile->Image.ColorMap->ColorCount,
490 GifFile->Image.ColorMap->Colors);
491 if (sp->ImageDesc.ColorMap == NULL) {
492 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
493 return GIF_ERROR;
494 }
495 }
496 sp->RasterBits = (unsigned char *)NULL;
497 sp->ExtensionBlockCount = 0;
498 sp->ExtensionBlocks = (ExtensionBlock *) NULL;
499
500 GifFile->ImageCount++;
501
502 return GIF_OK;
503 }
504
505 /******************************************************************************
506 Get one full scanned line (Line) of length LineLen from GIF file.
507 ******************************************************************************/
508 int
509 DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
510 {
511 GifByteType *Dummy;
512 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
513
514 if (!IS_READABLE(Private)) {
515 /* This file was NOT open for reading: */
516 GifFile->Error = D_GIF_ERR_NOT_READABLE;
517 return GIF_ERROR;
518 }
519
520 if (!LineLen)
521 LineLen = GifFile->Image.Width;
522
575 while (Dummy != NULL) ;
576 }
577 return GIF_OK;
578 } else
579 return GIF_ERROR;
580 }
581
582 /******************************************************************************
583 Get an extension block (see GIF manual) from GIF file. This routine only
584 returns the first data block, and DGifGetExtensionNext should be called
585 after this one until NULL extension is returned.
586 The Extension should NOT be freed by the user (not dynamically allocated).
587 Note it is assumed the Extension description header has been read.
588 ******************************************************************************/
589 int
590 DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
591 {
592 GifByteType Buf;
593 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
594
595 //fprintf(stderr, "### -> DGifGetExtension:\n");
596 if (!IS_READABLE(Private)) {
597 /* This file was NOT open for reading: */
598 GifFile->Error = D_GIF_ERR_NOT_READABLE;
599 return GIF_ERROR;
600 }
601
602 /* coverity[check_return] */
603 if (InternalRead(GifFile, &Buf, 1) != 1) {
604 GifFile->Error = D_GIF_ERR_READ_FAILED;
605 return GIF_ERROR;
606 }
607 *ExtCode = Buf;
608 //fprintf(stderr, "### <- DGifGetExtension: %02x, about to call next\n", Buf);
609
610 return DGifGetExtensionNext(GifFile, Extension);
611 }
612
613 /******************************************************************************
614 Get a following extension block (see GIF manual) from GIF file. This
615 routine should be called until NULL Extension is returned.
616 The Extension should NOT be freed by the user (not dynamically allocated).
617 ******************************************************************************/
618 int
619 DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
620 {
621 GifByteType Buf;
622 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
623
624 //fprintf(stderr, "### -> DGifGetExtensionNext\n");
625 if (InternalRead(GifFile, &Buf, 1) != 1) {
626 GifFile->Error = D_GIF_ERR_READ_FAILED;
627 return GIF_ERROR;
628 }
629 //fprintf(stderr, "### DGifGetExtensionNext sees %d\n", Buf);
630
631 if (Buf > 0) {
632 *Extension = Private->Buf; /* Use private unused buffer. */
633 (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
634 /* coverity[tainted_data,check_return] */
635 if (InternalRead(GifFile, &((*Extension)[1]), Buf) != Buf) {
636 GifFile->Error = D_GIF_ERR_READ_FAILED;
637 return GIF_ERROR;
638 }
639 } else
640 *Extension = NULL;
641 //fprintf(stderr, "### <- DGifGetExtensionNext: %p\n", Extension);
642
643 return GIF_OK;
644 }
645
646 /******************************************************************************
647 Extract a Graphics Control Block from raw extension data
648 ******************************************************************************/
649
650 int DGifExtensionToGCB(const size_t GifExtensionLength,
651 const GifByteType *GifExtension,
652 GraphicsControlBlock *GCB)
653 {
654 if (GifExtensionLength != 4) {
655 return GIF_ERROR;
656 }
657
658 GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
659 GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
660 GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
661 if (GifExtension[0] & 0x01)
738 free(GifFile);
739 return GIF_ERROR;
740 }
741
742 free((char *)GifFile->Private);
743 free(GifFile);
744 if (ErrorCode != NULL)
745 *ErrorCode = D_GIF_SUCCEEDED;
746 return GIF_OK;
747 }
748
749 /******************************************************************************
750 Get 2 bytes (word) from the given file:
751 ******************************************************************************/
752 static int
753 DGifGetWord(GifFileType *GifFile, GifWord *Word)
754 {
755 unsigned char c[2];
756
757 /* coverity[check_return] */
758 if (InternalRead(GifFile, c, 2) != 2) {
759 GifFile->Error = D_GIF_ERR_READ_FAILED;
760 return GIF_ERROR;
761 }
762
763 *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
764 return GIF_OK;
765 }
766
767 /******************************************************************************
768 Get the image code in compressed form. This routine can be called if the
769 information needed to be piped out as is. Obviously this is much faster
770 than decoding and encoding again. This routine should be followed by calls
771 to DGifGetCodeNext, until NULL block is returned.
772 The block should NOT be freed by the user (not dynamically allocated).
773 ******************************************************************************/
774 int
775 DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
776 {
777 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
778
783 }
784
785 *CodeSize = Private->BitsPerPixel;
786
787 return DGifGetCodeNext(GifFile, CodeBlock);
788 }
789
790 /******************************************************************************
791 Continue to get the image code in compressed form. This routine should be
792 called until NULL block is returned.
793 The block should NOT be freed by the user (not dynamically allocated).
794 ******************************************************************************/
795 int
796 DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
797 {
798 GifByteType Buf;
799 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
800
801 /* coverity[tainted_data_argument] */
802 /* coverity[check_return] */
803 if (InternalRead(GifFile, &Buf, 1) != 1) {
804 GifFile->Error = D_GIF_ERR_READ_FAILED;
805 return GIF_ERROR;
806 }
807
808 /* coverity[lower_bounds] */
809 if (Buf > 0) {
810 *CodeBlock = Private->Buf; /* Use private unused buffer. */
811 (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
812 /* coverity[tainted_data] */
813 if (InternalRead(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
814 GifFile->Error = D_GIF_ERR_READ_FAILED;
815 return GIF_ERROR;
816 }
817 } else {
818 *CodeBlock = NULL;
819 Private->Buf[0] = 0; /* Make sure the buffer is empty! */
820 Private->PixelCount = 0; /* And local info. indicate image read. */
821 }
822
823 return GIF_OK;
824 }
825
826 /******************************************************************************
827 Setup the LZ decompression for this image:
828 ******************************************************************************/
829 static int
830 DGifSetupDecompress(GifFileType *GifFile)
831 {
832 int i, BitsPerPixel;
833 GifByteType CodeSize;
834 GifPrefixType *Prefix;
835 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
836
837 /* coverity[check_return] */
838 if (InternalRead(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */
839 return GIF_ERROR; /* Failed to read Code size. */
840 }
841 BitsPerPixel = CodeSize;
842
843 /* this can only happen on a severely malformed GIF */
844 if (BitsPerPixel > 8) {
845 GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
846 return GIF_ERROR; /* Failed to read Code size. */
847 }
848
849 Private->Buf[0] = 0; /* Input Buffer empty. */
850 Private->BitsPerPixel = BitsPerPixel;
851 Private->ClearCode = (1 << BitsPerPixel);
852 Private->EOFCode = Private->ClearCode + 1;
853 Private->RunningCode = Private->EOFCode + 1;
854 Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
855 Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
856 Private->StackPtr = 0; /* No pixels on the pixel stack. */
857 Private->LastCode = NO_SUCH_CODE;
858 Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
952 /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
953 * during the trace. As we might loop forever, in case of
954 * defective image, we use StackPtr as loop counter and stop
955 * before overflowing Stack[]. */
956 while (StackPtr < LZ_MAX_CODE &&
957 CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
958 Stack[StackPtr++] = Suffix[CrntPrefix];
959 CrntPrefix = Prefix[CrntPrefix];
960 }
961 if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
962 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
963 return GIF_ERROR;
964 }
965 /* Push the last character on stack: */
966 Stack[StackPtr++] = CrntPrefix;
967
968 /* Now lets pop all the stack into output: */
969 while (StackPtr != 0 && i < LineLen)
970 Line[i++] = Stack[--StackPtr];
971 }
972 if (LastCode != NO_SUCH_CODE && Private->RunningCode - 2 < LZ_MAX_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
973 Prefix[Private->RunningCode - 2] = LastCode;
974
975 if (CrntCode == Private->RunningCode - 2) {
976 /* Only allowed if CrntCode is exactly the running code:
977 * In that case CrntCode = XXXCode, CrntCode or the
978 * prefix code is last code and the suffix char is
979 * exactly the prefix of last code! */
980 Suffix[Private->RunningCode - 2] =
981 DGifGetPrefixChar(Prefix, LastCode, ClearCode);
982 } else {
983 Suffix[Private->RunningCode - 2] =
984 DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
985 }
986 }
987 LastCode = CrntCode;
988 }
989 }
990
991 Private->LastCode = LastCode;
992 Private->StackPtr = StackPtr;
1100 ++Private->RunningCode > Private->MaxCode1 &&
1101 Private->RunningBits < LZ_BITS) {
1102 Private->MaxCode1 <<= 1;
1103 Private->RunningBits++;
1104 }
1105 return GIF_OK;
1106 }
1107
1108 /******************************************************************************
1109 This routines read one GIF data block at a time and buffers it internally
1110 so that the decompression routine could access it.
1111 The routine returns the next byte from its internal buffer (or read next
1112 block in if buffer empty) and returns GIF_OK if succesful.
1113 ******************************************************************************/
1114 static int
1115 DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
1116 {
1117 if (Buf[0] == 0) {
1118 /* Needs to read the next buffer - this one is empty: */
1119 /* coverity[check_return] */
1120 if (InternalRead(GifFile, Buf, 1) != 1) {
1121 GifFile->Error = D_GIF_ERR_READ_FAILED;
1122 return GIF_ERROR;
1123 }
1124 /* There shouldn't be any empty data blocks here as the LZW spec
1125 * says the LZW termination code should come first. Therefore we
1126 * shouldn't be inside this routine at that point.
1127 */
1128 if (Buf[0] == 0) {
1129 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1130 return GIF_ERROR;
1131 }
1132 if (InternalRead(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1133 GifFile->Error = D_GIF_ERR_READ_FAILED;
1134 return GIF_ERROR;
1135 }
1136 *NextByte = Buf[1];
1137 Buf[1] = 2; /* We use now the second place as last char read! */
1138 Buf[0]--;
1139 } else {
1140 *NextByte = Buf[Buf[1]++];
1141 Buf[0]--;
1142 }
1143
1144 return GIF_OK;
1145 }
1146
1147 /******************************************************************************
1148 This routine reads an entire GIF into core, hanging all its state info off
1149 the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
1150 first to initialize I/O. Its inverse is EGifSpew().
1151 *******************************************************************************/
1152 int
1155 size_t ImageSize;
1156 GifRecordType RecordType;
1157 SavedImage *sp;
1158 GifByteType *ExtData;
1159 int ExtFunction;
1160
1161 GifFile->ExtensionBlocks = NULL;
1162 GifFile->ExtensionBlockCount = 0;
1163
1164 do {
1165 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
1166 return (GIF_ERROR);
1167
1168 switch (RecordType) {
1169 case IMAGE_DESC_RECORD_TYPE:
1170 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
1171 return (GIF_ERROR);
1172
1173 sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
1174 /* Allocate memory for the image */
1175 if (sp->ImageDesc.Width <= 0 || sp->ImageDesc.Height <= 0 ||
1176 sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
1177 return GIF_ERROR;
1178 }
1179 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1180
1181 if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
1182 return GIF_ERROR;
1183 }
1184 sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
1185 sizeof(GifPixelType));
1186
1187 if (sp->RasterBits == NULL) {
1188 return GIF_ERROR;
1189 }
1190
1191 if (sp->ImageDesc.Interlace) {
1192 int i, j;
1193 /*
1194 * The way an interlaced image should be read -
1195 * offsets and jumps...
1215 if (GifFile->ExtensionBlocks) {
1216 sp->ExtensionBlocks = GifFile->ExtensionBlocks;
1217 sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
1218
1219 GifFile->ExtensionBlocks = NULL;
1220 GifFile->ExtensionBlockCount = 0;
1221 }
1222 break;
1223
1224 case EXTENSION_RECORD_TYPE:
1225 if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
1226 return (GIF_ERROR);
1227 /* Create an extension block with our data */
1228 if (ExtData != NULL) {
1229 if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1230 &GifFile->ExtensionBlocks,
1231 ExtFunction, ExtData[0], &ExtData[1])
1232 == GIF_ERROR)
1233 return (GIF_ERROR);
1234 }
1235 for (;;) {
1236 if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1237 return (GIF_ERROR);
1238 if (ExtData == NULL)
1239 break;
1240 /* Continue the extension block */
1241 if (ExtData != NULL)
1242 if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1243 &GifFile->ExtensionBlocks,
1244 CONTINUE_EXT_FUNC_CODE,
1245 ExtData[0], &ExtData[1]) == GIF_ERROR)
1246 return (GIF_ERROR);
1247 }
1248 break;
1249
1250 case TERMINATE_RECORD_TYPE:
1251 break;
1252
1253 default: /* Should be trapped by DGifGetRecordType */
1254 break;
1255 }
1256 } while (RecordType != TERMINATE_RECORD_TYPE);
1257
1258 /* Sanity check for corrupted file */
1259 if (GifFile->ImageCount == 0) {
|