1 /******************************************************************************
3 dgif_lib.c - GIF decoding
5 The functions here and in egif_lib.c are partitioned carefully so that
6 if you only require one of read and write capability, only one of these
7 two modules will be linked. Preserve this property!
9 *****************************************************************************/
24 #include "gif_lib_private.h"
26 /* compose unsigned little endian value */
27 #define UNSIGNED_LITTLE_ENDIAN(lo, hi) ((lo) | ((hi) << 8))
29 /* avoid extra function call in case we use fread (TVT) */
30 #define READ(_gif,_buf,_len) \
31 (((GifFilePrivateType*)_gif->Private)->Read ? \
32 ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
33 fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
35 static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
36 static int DGifSetupDecompress(GifFileType *GifFile);
37 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
39 static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
40 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
41 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
42 GifByteType *NextByte);
44 /******************************************************************************
45 Open a new GIF file for read, given by its name.
46 Returns dynamically allocated GifFileType pointer which serves as the GIF
48 ******************************************************************************/
50 DGifOpenFileName(const char *FileName, int *Error)
55 if ((FileHandle = open(FileName, O_RDONLY)) == -1) {
57 *Error = D_GIF_ERR_OPEN_FAILED;
61 GifFile = DGifOpenFileHandle(FileHandle, Error);
65 /******************************************************************************
66 Update a new GIF file, given its file handle.
67 Returns dynamically allocated GifFileType pointer which serves as the GIF
69 ******************************************************************************/
71 DGifOpenFileHandle(int FileHandle, int *Error)
73 char Buf[GIF_STAMP_LEN + 1];
75 GifFilePrivateType *Private;
78 GifFile = (GifFileType *)malloc(sizeof(GifFileType));
79 if (GifFile == NULL) {
81 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
82 (void)close(FileHandle);
86 /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType));
88 /* Belt and suspenders, in case the null pointer isn't zero */
89 GifFile->SavedImages = NULL;
90 GifFile->SColorMap = NULL;
92 Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
93 if (Private == NULL) {
95 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
96 (void)close(FileHandle);
97 free((char *)GifFile);
101 /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
104 _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
107 f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
110 GifFile->Private = (void *)Private;
111 Private->FileHandle = FileHandle;
113 Private->FileState = FILE_STATE_READ;
114 Private->Read = NULL; /* don't use alternate input method (TVT) */
115 GifFile->UserData = NULL; /* TVT */
118 /* Let's see if this is a GIF file: */
119 /* coverity[check_return] */
120 if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
122 *Error = D_GIF_ERR_READ_FAILED;
124 free((char *)Private);
125 free((char *)GifFile);
129 /* Check for GIF prefix at start of file */
130 Buf[GIF_STAMP_LEN] = 0;
131 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
133 *Error = D_GIF_ERR_NOT_GIF_FILE;
135 free((char *)Private);
136 free((char *)GifFile);
140 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
142 free((char *)Private);
143 free((char *)GifFile);
149 /* What version of GIF? */
150 Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
155 /******************************************************************************
156 GifFileType constructor with user supplied input function (TVT)
157 ******************************************************************************/
159 DGifOpen(void *userData, InputFunc readFunc, int *Error)
161 char Buf[GIF_STAMP_LEN + 1];
162 GifFileType *GifFile;
163 GifFilePrivateType *Private;
165 GifFile = (GifFileType *)malloc(sizeof(GifFileType));
166 if (GifFile == NULL) {
168 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
172 memset(GifFile, '\0', sizeof(GifFileType));
174 /* Belt and suspenders, in case the null pointer isn't zero */
175 GifFile->SavedImages = NULL;
176 GifFile->SColorMap = NULL;
178 Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
181 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
182 free((char *)GifFile);
185 /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
187 GifFile->Private = (void *)Private;
188 Private->FileHandle = 0;
189 Private->File = NULL;
190 Private->FileState = FILE_STATE_READ;
192 Private->Read = readFunc; /* TVT */
193 GifFile->UserData = userData; /* TVT */
195 /* Lets see if this is a GIF file: */
196 /* coverity[check_return] */
197 if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
199 *Error = D_GIF_ERR_READ_FAILED;
200 free((char *)Private);
201 free((char *)GifFile);
205 /* Check for GIF prefix at start of file */
206 Buf[GIF_STAMP_LEN] = '\0';
207 if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
209 *Error = D_GIF_ERR_NOT_GIF_FILE;
210 free((char *)Private);
211 free((char *)GifFile);
215 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
216 free((char *)Private);
217 free((char *)GifFile);
219 *Error = D_GIF_ERR_NO_SCRN_DSCR;
225 /* What version of GIF? */
226 Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
231 /******************************************************************************
232 This routine should be called before any other DGif calls. Note that
233 this routine is called automatically from DGif file open routines.
234 ******************************************************************************/
236 DGifGetScreenDesc(GifFileType *GifFile)
241 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
243 if (!IS_READABLE(Private)) {
244 /* This file was NOT open for reading: */
245 GifFile->Error = D_GIF_ERR_NOT_READABLE;
249 /* Put the screen descriptor into the file: */
250 if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
251 DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
254 if (READ(GifFile, Buf, 3) != 3) {
255 GifFile->Error = D_GIF_ERR_READ_FAILED;
256 GifFreeMapObject(GifFile->SColorMap);
257 GifFile->SColorMap = NULL;
260 GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
261 SortFlag = (Buf[0] & 0x08) != 0;
262 BitsPerPixel = (Buf[0] & 0x07) + 1;
263 GifFile->SBackGroundColor = Buf[1];
264 GifFile->AspectByte = Buf[2];
265 if (Buf[0] & 0x80) { /* Do we have global color map? */
268 GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
269 if (GifFile->SColorMap == NULL) {
270 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
274 /* Get the global color map: */
275 GifFile->SColorMap->SortFlag = SortFlag;
276 for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
277 /* coverity[check_return] */
278 if (READ(GifFile, Buf, 3) != 3) {
279 GifFreeMapObject(GifFile->SColorMap);
280 GifFile->SColorMap = NULL;
281 GifFile->Error = D_GIF_ERR_READ_FAILED;
284 GifFile->SColorMap->Colors[i].Red = Buf[0];
285 GifFile->SColorMap->Colors[i].Green = Buf[1];
286 GifFile->SColorMap->Colors[i].Blue = Buf[2];
289 GifFile->SColorMap = NULL;
295 /******************************************************************************
296 This routine should be called before any attempt to read an image.
297 ******************************************************************************/
299 DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
302 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
304 if (!IS_READABLE(Private)) {
305 /* This file was NOT open for reading: */
306 GifFile->Error = D_GIF_ERR_NOT_READABLE;
310 /* coverity[check_return] */
311 if (READ(GifFile, &Buf, 1) != 1) {
312 GifFile->Error = D_GIF_ERR_READ_FAILED;
317 case DESCRIPTOR_INTRODUCER:
318 *Type = IMAGE_DESC_RECORD_TYPE;
320 case EXTENSION_INTRODUCER:
321 *Type = EXTENSION_RECORD_TYPE;
323 case TERMINATOR_INTRODUCER:
324 *Type = TERMINATE_RECORD_TYPE;
327 *Type = UNDEFINED_RECORD_TYPE;
328 GifFile->Error = D_GIF_ERR_WRONG_RECORD;
335 /******************************************************************************
336 This routine should be called before any attempt to read an image.
337 Note it is assumed the Image desc. header has been read.
338 ******************************************************************************/
340 DGifGetImageDesc(GifFileType *GifFile)
342 unsigned int BitsPerPixel;
344 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
347 if (!IS_READABLE(Private)) {
348 /* This file was NOT open for reading: */
349 GifFile->Error = D_GIF_ERR_NOT_READABLE;
353 if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
354 DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
355 DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
356 DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
358 if (READ(GifFile, Buf, 1) != 1) {
359 GifFile->Error = D_GIF_ERR_READ_FAILED;
360 GifFreeMapObject(GifFile->Image.ColorMap);
361 GifFile->Image.ColorMap = NULL;
364 BitsPerPixel = (Buf[0] & 0x07) + 1;
365 GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
367 /* Setup the colormap */
368 if (GifFile->Image.ColorMap) {
369 GifFreeMapObject(GifFile->Image.ColorMap);
370 GifFile->Image.ColorMap = NULL;
372 /* Does this image have local color map? */
376 GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
377 if (GifFile->Image.ColorMap == NULL) {
378 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
382 /* Get the image local color map: */
383 for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
384 /* coverity[check_return] */
385 if (READ(GifFile, Buf, 3) != 3) {
386 GifFreeMapObject(GifFile->Image.ColorMap);
387 GifFile->Error = D_GIF_ERR_READ_FAILED;
388 GifFile->Image.ColorMap = NULL;
391 GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
392 GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
393 GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
397 if (GifFile->SavedImages) {
398 SavedImage* new_saved_images =
399 (SavedImage *)reallocarray(GifFile->SavedImages,
400 (GifFile->ImageCount + 1), sizeof(SavedImage));
401 if (new_saved_images == NULL) {
402 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
405 GifFile->SavedImages = new_saved_images;
407 if ((GifFile->SavedImages =
408 (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
409 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
414 sp = &GifFile->SavedImages[GifFile->ImageCount];
415 memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
416 if (GifFile->Image.ColorMap != NULL) {
417 sp->ImageDesc.ColorMap = GifMakeMapObject(
418 GifFile->Image.ColorMap->ColorCount,
419 GifFile->Image.ColorMap->Colors);
420 if (sp->ImageDesc.ColorMap == NULL) {
421 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
425 sp->RasterBits = (unsigned char *)NULL;
426 sp->ExtensionBlockCount = 0;
427 sp->ExtensionBlocks = (ExtensionBlock *) NULL;
429 GifFile->ImageCount++;
431 Private->PixelCount = (long)GifFile->Image.Width *
432 (long)GifFile->Image.Height;
434 /* Reset decompress algorithm parameters. */
435 return DGifSetupDecompress(GifFile);
438 /******************************************************************************
439 Get one full scanned line (Line) of length LineLen from GIF file.
440 ******************************************************************************/
442 DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
445 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
447 if (!IS_READABLE(Private)) {
448 /* This file was NOT open for reading: */
449 GifFile->Error = D_GIF_ERR_NOT_READABLE;
454 LineLen = GifFile->Image.Width;
456 if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
457 GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
461 if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
462 if (Private->PixelCount == 0) {
463 /* We probably won't be called any more, so let's clean up
464 * everything before we return: need to flush out all the
465 * rest of image until an empty block (size 0)
466 * detected. We use GetCodeNext.
469 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
471 while (Dummy != NULL) ;
478 /******************************************************************************
479 Put one pixel (Pixel) into GIF file.
480 ******************************************************************************/
482 DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
485 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
487 if (!IS_READABLE(Private)) {
488 /* This file was NOT open for reading: */
489 GifFile->Error = D_GIF_ERR_NOT_READABLE;
492 if (--Private->PixelCount > 0xffff0000UL)
494 GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
498 if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
499 if (Private->PixelCount == 0) {
500 /* We probably won't be called any more, so let's clean up
501 * everything before we return: need to flush out all the
502 * rest of image until an empty block (size 0)
503 * detected. We use GetCodeNext.
506 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
508 while (Dummy != NULL) ;
515 /******************************************************************************
516 Get an extension block (see GIF manual) from GIF file. This routine only
517 returns the first data block, and DGifGetExtensionNext should be called
518 after this one until NULL extension is returned.
519 The Extension should NOT be freed by the user (not dynamically allocated).
520 Note it is assumed the Extension description header has been read.
521 ******************************************************************************/
523 DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
526 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
528 if (!IS_READABLE(Private)) {
529 /* This file was NOT open for reading: */
530 GifFile->Error = D_GIF_ERR_NOT_READABLE;
534 /* coverity[check_return] */
535 if (READ(GifFile, &Buf, 1) != 1) {
536 GifFile->Error = D_GIF_ERR_READ_FAILED;
541 return DGifGetExtensionNext(GifFile, Extension);
544 /******************************************************************************
545 Get a following extension block (see GIF manual) from GIF file. This
546 routine should be called until NULL Extension is returned.
547 The Extension should NOT be freed by the user (not dynamically allocated).
548 ******************************************************************************/
550 DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
553 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
555 if (READ(GifFile, &Buf, 1) != 1) {
556 GifFile->Error = D_GIF_ERR_READ_FAILED;
560 *Extension = Private->Buf; /* Use private unused buffer. */
561 (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
562 /* coverity[tainted_data,check_return] */
563 if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
564 GifFile->Error = D_GIF_ERR_READ_FAILED;
573 /******************************************************************************
574 Extract a Graphics Control Block from raw extension data
575 ******************************************************************************/
577 int DGifExtensionToGCB(const size_t GifExtensionLength,
578 const GifByteType *GifExtension,
579 GraphicsControlBlock *GCB)
581 if (GifExtensionLength != 4) {
585 GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
586 GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
587 GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
588 if (GifExtension[0] & 0x01)
589 GCB->TransparentColor = (int)GifExtension[3];
591 GCB->TransparentColor = NO_TRANSPARENT_COLOR;
596 /******************************************************************************
597 Extract the Graphics Control Block for a saved image, if it exists.
598 ******************************************************************************/
600 int DGifSavedExtensionToGCB(GifFileType *GifFile,
601 int ImageIndex, GraphicsControlBlock *GCB)
605 if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1)
608 GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
609 GCB->UserInputFlag = false;
611 GCB->TransparentColor = NO_TRANSPARENT_COLOR;
613 for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) {
614 ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
615 if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
616 return DGifExtensionToGCB(ep->ByteCount, ep->Bytes, GCB);
622 /******************************************************************************
623 This routine should be called last, to close the GIF file.
624 ******************************************************************************/
626 DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
628 GifFilePrivateType *Private;
630 if (GifFile == NULL || GifFile->Private == NULL)
633 if (GifFile->Image.ColorMap) {
634 GifFreeMapObject(GifFile->Image.ColorMap);
635 GifFile->Image.ColorMap = NULL;
638 if (GifFile->SColorMap) {
639 GifFreeMapObject(GifFile->SColorMap);
640 GifFile->SColorMap = NULL;
643 if (GifFile->SavedImages) {
644 GifFreeSavedImages(GifFile);
645 GifFile->SavedImages = NULL;
648 GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks);
650 Private = (GifFilePrivateType *) GifFile->Private;
652 if (!IS_READABLE(Private)) {
653 /* This file was NOT open for reading: */
654 if (ErrorCode != NULL)
655 *ErrorCode = D_GIF_ERR_NOT_READABLE;
656 free((char *)GifFile->Private);
661 if (Private->File && (fclose(Private->File) != 0)) {
662 if (ErrorCode != NULL)
663 *ErrorCode = D_GIF_ERR_CLOSE_FAILED;
664 free((char *)GifFile->Private);
669 free((char *)GifFile->Private);
671 if (ErrorCode != NULL)
672 *ErrorCode = D_GIF_SUCCEEDED;
676 /******************************************************************************
677 Get 2 bytes (word) from the given file:
678 ******************************************************************************/
680 DGifGetWord(GifFileType *GifFile, GifWord *Word)
684 /* coverity[check_return] */
685 if (READ(GifFile, c, 2) != 2) {
686 GifFile->Error = D_GIF_ERR_READ_FAILED;
690 *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
694 /******************************************************************************
695 Get the image code in compressed form. This routine can be called if the
696 information needed to be piped out as is. Obviously this is much faster
697 than decoding and encoding again. This routine should be followed by calls
698 to DGifGetCodeNext, until NULL block is returned.
699 The block should NOT be freed by the user (not dynamically allocated).
700 ******************************************************************************/
702 DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
704 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
706 if (!IS_READABLE(Private)) {
707 /* This file was NOT open for reading: */
708 GifFile->Error = D_GIF_ERR_NOT_READABLE;
712 *CodeSize = Private->BitsPerPixel;
714 return DGifGetCodeNext(GifFile, CodeBlock);
717 /******************************************************************************
718 Continue to get the image code in compressed form. This routine should be
719 called until NULL block is returned.
720 The block should NOT be freed by the user (not dynamically allocated).
721 ******************************************************************************/
723 DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
726 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
728 /* coverity[tainted_data_argument] */
729 /* coverity[check_return] */
730 if (READ(GifFile, &Buf, 1) != 1) {
731 GifFile->Error = D_GIF_ERR_READ_FAILED;
735 /* coverity[lower_bounds] */
737 *CodeBlock = Private->Buf; /* Use private unused buffer. */
738 (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
739 /* coverity[tainted_data] */
740 if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
741 GifFile->Error = D_GIF_ERR_READ_FAILED;
746 Private->Buf[0] = 0; /* Make sure the buffer is empty! */
747 Private->PixelCount = 0; /* And local info. indicate image read. */
753 /******************************************************************************
754 Setup the LZ decompression for this image:
755 ******************************************************************************/
757 DGifSetupDecompress(GifFileType *GifFile)
760 GifByteType CodeSize;
761 GifPrefixType *Prefix;
762 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
764 /* coverity[check_return] */
765 if (READ(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */
766 return GIF_ERROR; /* Failed to read Code size. */
768 BitsPerPixel = CodeSize;
770 /* this can only happen on a severely malformed GIF */
771 if (BitsPerPixel > 8 || Private->RunningBits > 32) {
772 GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
773 return GIF_ERROR; /* Failed to read Code size. */
776 Private->Buf[0] = 0; /* Input Buffer empty. */
777 Private->BitsPerPixel = BitsPerPixel;
778 Private->ClearCode = (1 << BitsPerPixel);
779 Private->EOFCode = Private->ClearCode + 1;
780 Private->RunningCode = Private->EOFCode + 1;
781 Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
782 Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
783 Private->StackPtr = 0; /* No pixels on the pixel stack. */
784 Private->LastCode = NO_SUCH_CODE;
785 Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
786 Private->CrntShiftDWord = 0;
788 Prefix = Private->Prefix;
789 for (i = 0; i <= LZ_MAX_CODE; i++)
790 Prefix[i] = NO_SUCH_CODE;
795 /******************************************************************************
796 The LZ decompression routine:
797 This version decompress the given GIF file into Line of length LineLen.
798 This routine can be called few times (one per scan line, for example), in
799 order the complete the whole image.
800 ******************************************************************************/
802 DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
805 int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
806 GifByteType *Stack, *Suffix;
807 GifPrefixType *Prefix;
808 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
810 StackPtr = Private->StackPtr;
811 Prefix = Private->Prefix;
812 Suffix = Private->Suffix;
813 Stack = Private->Stack;
814 EOFCode = Private->EOFCode;
815 ClearCode = Private->ClearCode;
816 LastCode = Private->LastCode;
818 if (StackPtr > LZ_MAX_CODE) {
823 /* Let pop the stack off before continueing to read the GIF file: */
824 while (StackPtr != 0 && i < LineLen)
825 Line[i++] = Stack[--StackPtr];
828 while (i < LineLen) { /* Decode LineLen items. */
829 if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
832 if (CrntCode == EOFCode) {
833 /* Note however that usually we will not be here as we will stop
834 * decoding as soon as we got all the pixel, or EOF code will
835 * not be read at all, and DGifGetLine/Pixel clean everything. */
836 GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;
838 } else if (CrntCode == ClearCode) {
839 /* We need to start over again: */
840 for (j = 0; j <= LZ_MAX_CODE; j++)
841 Prefix[j] = NO_SUCH_CODE;
842 Private->RunningCode = Private->EOFCode + 1;
843 Private->RunningBits = Private->BitsPerPixel + 1;
844 Private->MaxCode1 = 1 << Private->RunningBits;
845 LastCode = Private->LastCode = NO_SUCH_CODE;
847 /* Its regular code - if in pixel range simply add it to output
848 * stream, otherwise trace to codes linked list until the prefix
849 * is in pixel range: */
850 if (CrntCode < ClearCode) {
851 /* This is simple - its pixel scalar, so add it to output: */
852 Line[i++] = CrntCode;
854 /* Its a code to needed to be traced: trace the linked list
855 * until the prefix is a pixel, while pushing the suffix
856 * pixels on our stack. If we done, pop the stack in reverse
857 * (thats what stack is good for!) order to output. */
858 if (Prefix[CrntCode] == NO_SUCH_CODE) {
859 CrntPrefix = LastCode;
861 /* Only allowed if CrntCode is exactly the running code:
862 * In that case CrntCode = XXXCode, CrntCode or the
863 * prefix code is last code and the suffix char is
864 * exactly the prefix of last code! */
865 if (CrntCode == Private->RunningCode - 2) {
866 Suffix[Private->RunningCode - 2] =
867 Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
871 Suffix[Private->RunningCode - 2] =
872 Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
877 CrntPrefix = CrntCode;
879 /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
880 * during the trace. As we might loop forever, in case of
881 * defective image, we use StackPtr as loop counter and stop
882 * before overflowing Stack[]. */
883 while (StackPtr < LZ_MAX_CODE &&
884 CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
885 Stack[StackPtr++] = Suffix[CrntPrefix];
886 CrntPrefix = Prefix[CrntPrefix];
888 if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
889 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
892 /* Push the last character on stack: */
893 Stack[StackPtr++] = CrntPrefix;
895 /* Now lets pop all the stack into output: */
896 while (StackPtr != 0 && i < LineLen)
897 Line[i++] = Stack[--StackPtr];
899 if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
900 Prefix[Private->RunningCode - 2] = LastCode;
902 if (CrntCode == Private->RunningCode - 2) {
903 /* Only allowed if CrntCode is exactly the running code:
904 * In that case CrntCode = XXXCode, CrntCode or the
905 * prefix code is last code and the suffix char is
906 * exactly the prefix of last code! */
907 Suffix[Private->RunningCode - 2] =
908 DGifGetPrefixChar(Prefix, LastCode, ClearCode);
910 Suffix[Private->RunningCode - 2] =
911 DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
918 Private->LastCode = LastCode;
919 Private->StackPtr = StackPtr;
924 /******************************************************************************
925 Routine to trace the Prefixes linked list until we get a prefix which is
926 not code, but a pixel value (less than ClearCode). Returns that pixel value.
927 If image is defective, we might loop here forever, so we limit the loops to
928 the maximum possible if image O.k. - LZ_MAX_CODE times.
929 ******************************************************************************/
931 DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
935 while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
936 if (Code > LZ_MAX_CODE) {
944 /******************************************************************************
945 Interface for accessing the LZ codes directly. Set Code to the real code
946 (12bits), or to -1 if EOF code is returned.
947 ******************************************************************************/
949 DGifGetLZCodes(GifFileType *GifFile, int *Code)
951 GifByteType *CodeBlock;
952 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
954 if (!IS_READABLE(Private)) {
955 /* This file was NOT open for reading: */
956 GifFile->Error = D_GIF_ERR_NOT_READABLE;
960 if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
963 if (*Code == Private->EOFCode) {
964 /* Skip rest of codes (hopefully only NULL terminating block): */
966 if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
968 } while (CodeBlock != NULL) ;
971 } else if (*Code == Private->ClearCode) {
972 /* We need to start over again: */
973 Private->RunningCode = Private->EOFCode + 1;
974 Private->RunningBits = Private->BitsPerPixel + 1;
975 Private->MaxCode1 = 1 << Private->RunningBits;
981 /******************************************************************************
982 The LZ decompression input routine:
983 This routine is responsable for the decompression of the bit stream from
984 8 bits (bytes) packets, into the real codes.
985 Returns GIF_OK if read successfully.
986 ******************************************************************************/
988 DGifDecompressInput(GifFileType *GifFile, int *Code)
990 static const unsigned short CodeMasks[] = {
991 0x0000, 0x0001, 0x0003, 0x0007,
992 0x000f, 0x001f, 0x003f, 0x007f,
993 0x00ff, 0x01ff, 0x03ff, 0x07ff,
997 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
999 GifByteType NextByte;
1001 /* The image can't contain more than LZ_BITS per code. */
1002 if (Private->RunningBits > LZ_BITS) {
1003 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1007 while (Private->CrntShiftState < Private->RunningBits) {
1008 /* Needs to get more bytes from input stream for next code: */
1009 if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
1012 Private->CrntShiftDWord |=
1013 ((unsigned long)NextByte) << Private->CrntShiftState;
1014 Private->CrntShiftState += 8;
1016 *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
1018 Private->CrntShiftDWord >>= Private->RunningBits;
1019 Private->CrntShiftState -= Private->RunningBits;
1021 /* If code cannot fit into RunningBits bits, must raise its size. Note
1022 * however that codes above 4095 are used for special signaling.
1023 * If we're using LZ_BITS bits already and we're at the max code, just
1024 * keep using the table as it is, don't increment Private->RunningCode.
1026 if (Private->RunningCode < LZ_MAX_CODE + 2 &&
1027 ++Private->RunningCode > Private->MaxCode1 &&
1028 Private->RunningBits < LZ_BITS) {
1029 Private->MaxCode1 <<= 1;
1030 Private->RunningBits++;
1035 /******************************************************************************
1036 This routines read one GIF data block at a time and buffers it internally
1037 so that the decompression routine could access it.
1038 The routine returns the next byte from its internal buffer (or read next
1039 block in if buffer empty) and returns GIF_OK if succesful.
1040 ******************************************************************************/
1042 DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
1045 /* Needs to read the next buffer - this one is empty: */
1046 /* coverity[check_return] */
1047 if (READ(GifFile, Buf, 1) != 1) {
1048 GifFile->Error = D_GIF_ERR_READ_FAILED;
1051 /* There shouldn't be any empty data blocks here as the LZW spec
1052 * says the LZW termination code should come first. Therefore we
1053 * shouldn't be inside this routine at that point.
1056 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1059 if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1060 GifFile->Error = D_GIF_ERR_READ_FAILED;
1064 Buf[1] = 2; /* We use now the second place as last char read! */
1067 *NextByte = Buf[Buf[1]++];
1074 /******************************************************************************
1075 This routine reads an entire GIF into core, hanging all its state info off
1076 the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
1077 first to initialize I/O. Its inverse is EGifSpew().
1078 *******************************************************************************/
1080 DGifSlurp(GifFileType *GifFile)
1083 GifRecordType RecordType;
1085 GifByteType *ExtData;
1088 GifFile->ExtensionBlocks = NULL;
1089 GifFile->ExtensionBlockCount = 0;
1092 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
1095 switch (RecordType) {
1096 case IMAGE_DESC_RECORD_TYPE:
1097 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
1100 sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
1101 /* Allocate memory for the image */
1102 if (sp->ImageDesc.Width < 0 && sp->ImageDesc.Height < 0 &&
1103 sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
1106 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1108 if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
1111 sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
1112 sizeof(GifPixelType));
1114 if (sp->RasterBits == NULL) {
1118 if (sp->ImageDesc.Interlace) {
1121 * The way an interlaced image should be read -
1122 * offsets and jumps...
1124 int InterlacedOffset[] = { 0, 4, 2, 1 };
1125 int InterlacedJumps[] = { 8, 8, 4, 2 };
1126 /* Need to perform 4 passes on the image */
1127 for (i = 0; i < 4; i++)
1128 for (j = InterlacedOffset[i];
1129 j < sp->ImageDesc.Height;
1130 j += InterlacedJumps[i]) {
1131 if (DGifGetLine(GifFile,
1132 sp->RasterBits+j*sp->ImageDesc.Width,
1133 sp->ImageDesc.Width) == GIF_ERROR)
1138 if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
1142 if (GifFile->ExtensionBlocks) {
1143 sp->ExtensionBlocks = GifFile->ExtensionBlocks;
1144 sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
1146 GifFile->ExtensionBlocks = NULL;
1147 GifFile->ExtensionBlockCount = 0;
1151 case EXTENSION_RECORD_TYPE:
1152 if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
1154 /* Create an extension block with our data */
1155 if (ExtData != NULL) {
1156 if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1157 &GifFile->ExtensionBlocks,
1158 ExtFunction, ExtData[0], &ExtData[1])
1162 while (ExtData != NULL) {
1163 if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1165 /* Continue the extension block */
1166 if (ExtData != NULL)
1167 if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1168 &GifFile->ExtensionBlocks,
1169 CONTINUE_EXT_FUNC_CODE,
1170 ExtData[0], &ExtData[1]) == GIF_ERROR)
1175 case TERMINATE_RECORD_TYPE:
1178 default: /* Should be trapped by DGifGetRecordType */
1181 } while (RecordType != TERMINATE_RECORD_TYPE);
1183 /* Sanity check for corrupted file */
1184 if (GifFile->ImageCount == 0) {
1185 GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;