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;
293 * No check here for whether the background color is in range for the
294 * screen color map. Possibly there should be.
300 /******************************************************************************
301 This routine should be called before any attempt to read an image.
302 ******************************************************************************/
304 DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
307 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
309 if (!IS_READABLE(Private)) {
310 /* This file was NOT open for reading: */
311 GifFile->Error = D_GIF_ERR_NOT_READABLE;
315 /* coverity[check_return] */
316 if (READ(GifFile, &Buf, 1) != 1) {
317 GifFile->Error = D_GIF_ERR_READ_FAILED;
322 case DESCRIPTOR_INTRODUCER:
323 *Type = IMAGE_DESC_RECORD_TYPE;
325 case EXTENSION_INTRODUCER:
326 *Type = EXTENSION_RECORD_TYPE;
328 case TERMINATOR_INTRODUCER:
329 *Type = TERMINATE_RECORD_TYPE;
332 *Type = UNDEFINED_RECORD_TYPE;
333 GifFile->Error = D_GIF_ERR_WRONG_RECORD;
340 /******************************************************************************
341 This routine should be called before any attempt to read an image.
342 Note it is assumed the Image desc. header has been read.
343 ******************************************************************************/
345 DGifGetImageDesc(GifFileType *GifFile)
347 unsigned int BitsPerPixel;
349 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
352 if (!IS_READABLE(Private)) {
353 /* This file was NOT open for reading: */
354 GifFile->Error = D_GIF_ERR_NOT_READABLE;
358 if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
359 DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
360 DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
361 DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
363 if (READ(GifFile, Buf, 1) != 1) {
364 GifFile->Error = D_GIF_ERR_READ_FAILED;
365 GifFreeMapObject(GifFile->Image.ColorMap);
366 GifFile->Image.ColorMap = NULL;
369 BitsPerPixel = (Buf[0] & 0x07) + 1;
370 GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
372 /* Setup the colormap */
373 if (GifFile->Image.ColorMap) {
374 GifFreeMapObject(GifFile->Image.ColorMap);
375 GifFile->Image.ColorMap = NULL;
377 /* Does this image have local color map? */
381 GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
382 if (GifFile->Image.ColorMap == NULL) {
383 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
387 /* Get the image local color map: */
388 for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
389 /* coverity[check_return] */
390 if (READ(GifFile, Buf, 3) != 3) {
391 GifFreeMapObject(GifFile->Image.ColorMap);
392 GifFile->Error = D_GIF_ERR_READ_FAILED;
393 GifFile->Image.ColorMap = NULL;
396 GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
397 GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
398 GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
402 if (GifFile->SavedImages) {
403 SavedImage* new_saved_images =
404 (SavedImage *)reallocarray(GifFile->SavedImages,
405 (GifFile->ImageCount + 1), sizeof(SavedImage));
406 if (new_saved_images == NULL) {
407 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
410 GifFile->SavedImages = new_saved_images;
412 if ((GifFile->SavedImages =
413 (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
414 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
419 sp = &GifFile->SavedImages[GifFile->ImageCount];
420 memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
421 if (GifFile->Image.ColorMap != NULL) {
422 sp->ImageDesc.ColorMap = GifMakeMapObject(
423 GifFile->Image.ColorMap->ColorCount,
424 GifFile->Image.ColorMap->Colors);
425 if (sp->ImageDesc.ColorMap == NULL) {
426 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
430 sp->RasterBits = (unsigned char *)NULL;
431 sp->ExtensionBlockCount = 0;
432 sp->ExtensionBlocks = (ExtensionBlock *) NULL;
434 GifFile->ImageCount++;
436 Private->PixelCount = (long)GifFile->Image.Width *
437 (long)GifFile->Image.Height;
439 /* Reset decompress algorithm parameters. */
440 return DGifSetupDecompress(GifFile);
443 /******************************************************************************
444 Get one full scanned line (Line) of length LineLen from GIF file.
445 ******************************************************************************/
447 DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
450 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
452 if (!IS_READABLE(Private)) {
453 /* This file was NOT open for reading: */
454 GifFile->Error = D_GIF_ERR_NOT_READABLE;
459 LineLen = GifFile->Image.Width;
461 if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
462 GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
466 if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
467 if (Private->PixelCount == 0) {
468 /* We probably won't be called any more, so let's clean up
469 * everything before we return: need to flush out all the
470 * rest of image until an empty block (size 0)
471 * detected. We use GetCodeNext.
474 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
476 while (Dummy != NULL) ;
483 /******************************************************************************
484 Put one pixel (Pixel) into GIF file.
485 ******************************************************************************/
487 DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
490 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
492 if (!IS_READABLE(Private)) {
493 /* This file was NOT open for reading: */
494 GifFile->Error = D_GIF_ERR_NOT_READABLE;
497 if (--Private->PixelCount > 0xffff0000UL)
499 GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
503 if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
504 if (Private->PixelCount == 0) {
505 /* We probably won't be called any more, so let's clean up
506 * everything before we return: need to flush out all the
507 * rest of image until an empty block (size 0)
508 * detected. We use GetCodeNext.
511 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
513 while (Dummy != NULL) ;
520 /******************************************************************************
521 Get an extension block (see GIF manual) from GIF file. This routine only
522 returns the first data block, and DGifGetExtensionNext should be called
523 after this one until NULL extension is returned.
524 The Extension should NOT be freed by the user (not dynamically allocated).
525 Note it is assumed the Extension description header has been read.
526 ******************************************************************************/
528 DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
531 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
533 if (!IS_READABLE(Private)) {
534 /* This file was NOT open for reading: */
535 GifFile->Error = D_GIF_ERR_NOT_READABLE;
539 /* coverity[check_return] */
540 if (READ(GifFile, &Buf, 1) != 1) {
541 GifFile->Error = D_GIF_ERR_READ_FAILED;
546 return DGifGetExtensionNext(GifFile, Extension);
549 /******************************************************************************
550 Get a following extension block (see GIF manual) from GIF file. This
551 routine should be called until NULL Extension is returned.
552 The Extension should NOT be freed by the user (not dynamically allocated).
553 ******************************************************************************/
555 DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
558 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
560 if (READ(GifFile, &Buf, 1) != 1) {
561 GifFile->Error = D_GIF_ERR_READ_FAILED;
565 *Extension = Private->Buf; /* Use private unused buffer. */
566 (*Extension)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
567 /* coverity[tainted_data,check_return] */
568 if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
569 GifFile->Error = D_GIF_ERR_READ_FAILED;
578 /******************************************************************************
579 Extract a Graphics Control Block from raw extension data
580 ******************************************************************************/
582 int DGifExtensionToGCB(const size_t GifExtensionLength,
583 const GifByteType *GifExtension,
584 GraphicsControlBlock *GCB)
586 if (GifExtensionLength != 4) {
590 GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
591 GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
592 GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
593 if (GifExtension[0] & 0x01)
594 GCB->TransparentColor = (int)GifExtension[3];
596 GCB->TransparentColor = NO_TRANSPARENT_COLOR;
601 /******************************************************************************
602 Extract the Graphics Control Block for a saved image, if it exists.
603 ******************************************************************************/
605 int DGifSavedExtensionToGCB(GifFileType *GifFile,
606 int ImageIndex, GraphicsControlBlock *GCB)
610 if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1)
613 GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
614 GCB->UserInputFlag = false;
616 GCB->TransparentColor = NO_TRANSPARENT_COLOR;
618 for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) {
619 ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
620 if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
621 return DGifExtensionToGCB(ep->ByteCount, ep->Bytes, GCB);
627 /******************************************************************************
628 This routine should be called last, to close the GIF file.
629 ******************************************************************************/
631 DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
633 GifFilePrivateType *Private;
635 if (GifFile == NULL || GifFile->Private == NULL)
638 if (GifFile->Image.ColorMap) {
639 GifFreeMapObject(GifFile->Image.ColorMap);
640 GifFile->Image.ColorMap = NULL;
643 if (GifFile->SColorMap) {
644 GifFreeMapObject(GifFile->SColorMap);
645 GifFile->SColorMap = NULL;
648 if (GifFile->SavedImages) {
649 GifFreeSavedImages(GifFile);
650 GifFile->SavedImages = NULL;
653 GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks);
655 Private = (GifFilePrivateType *) GifFile->Private;
657 if (!IS_READABLE(Private)) {
658 /* This file was NOT open for reading: */
659 if (ErrorCode != NULL)
660 *ErrorCode = D_GIF_ERR_NOT_READABLE;
661 free((char *)GifFile->Private);
666 if (Private->File && (fclose(Private->File) != 0)) {
667 if (ErrorCode != NULL)
668 *ErrorCode = D_GIF_ERR_CLOSE_FAILED;
669 free((char *)GifFile->Private);
674 free((char *)GifFile->Private);
676 if (ErrorCode != NULL)
677 *ErrorCode = D_GIF_SUCCEEDED;
681 /******************************************************************************
682 Get 2 bytes (word) from the given file:
683 ******************************************************************************/
685 DGifGetWord(GifFileType *GifFile, GifWord *Word)
689 /* coverity[check_return] */
690 if (READ(GifFile, c, 2) != 2) {
691 GifFile->Error = D_GIF_ERR_READ_FAILED;
695 *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
699 /******************************************************************************
700 Get the image code in compressed form. This routine can be called if the
701 information needed to be piped out as is. Obviously this is much faster
702 than decoding and encoding again. This routine should be followed by calls
703 to DGifGetCodeNext, until NULL block is returned.
704 The block should NOT be freed by the user (not dynamically allocated).
705 ******************************************************************************/
707 DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
709 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
711 if (!IS_READABLE(Private)) {
712 /* This file was NOT open for reading: */
713 GifFile->Error = D_GIF_ERR_NOT_READABLE;
717 *CodeSize = Private->BitsPerPixel;
719 return DGifGetCodeNext(GifFile, CodeBlock);
722 /******************************************************************************
723 Continue to get the image code in compressed form. This routine should be
724 called until NULL block is returned.
725 The block should NOT be freed by the user (not dynamically allocated).
726 ******************************************************************************/
728 DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
731 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
733 /* coverity[tainted_data_argument] */
734 /* coverity[check_return] */
735 if (READ(GifFile, &Buf, 1) != 1) {
736 GifFile->Error = D_GIF_ERR_READ_FAILED;
740 /* coverity[lower_bounds] */
742 *CodeBlock = Private->Buf; /* Use private unused buffer. */
743 (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
744 /* coverity[tainted_data] */
745 if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
746 GifFile->Error = D_GIF_ERR_READ_FAILED;
751 Private->Buf[0] = 0; /* Make sure the buffer is empty! */
752 Private->PixelCount = 0; /* And local info. indicate image read. */
758 /******************************************************************************
759 Setup the LZ decompression for this image:
760 ******************************************************************************/
762 DGifSetupDecompress(GifFileType *GifFile)
765 GifByteType CodeSize;
766 GifPrefixType *Prefix;
767 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
769 /* coverity[check_return] */
770 if (READ(GifFile, &CodeSize, 1) < 1) { /* Read Code size from file. */
771 return GIF_ERROR; /* Failed to read Code size. */
773 BitsPerPixel = CodeSize;
775 /* this can only happen on a severely malformed GIF */
776 if (BitsPerPixel > 8 || Private->RunningBits > 32) {
777 GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
778 return GIF_ERROR; /* Failed to read Code size. */
781 Private->Buf[0] = 0; /* Input Buffer empty. */
782 Private->BitsPerPixel = BitsPerPixel;
783 Private->ClearCode = (1 << BitsPerPixel);
784 Private->EOFCode = Private->ClearCode + 1;
785 Private->RunningCode = Private->EOFCode + 1;
786 Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
787 Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
788 Private->StackPtr = 0; /* No pixels on the pixel stack. */
789 Private->LastCode = NO_SUCH_CODE;
790 Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
791 Private->CrntShiftDWord = 0;
793 Prefix = Private->Prefix;
794 for (i = 0; i <= LZ_MAX_CODE; i++)
795 Prefix[i] = NO_SUCH_CODE;
800 /******************************************************************************
801 The LZ decompression routine:
802 This version decompress the given GIF file into Line of length LineLen.
803 This routine can be called few times (one per scan line, for example), in
804 order the complete the whole image.
805 ******************************************************************************/
807 DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
810 int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
811 GifByteType *Stack, *Suffix;
812 GifPrefixType *Prefix;
813 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
815 StackPtr = Private->StackPtr;
816 Prefix = Private->Prefix;
817 Suffix = Private->Suffix;
818 Stack = Private->Stack;
819 EOFCode = Private->EOFCode;
820 ClearCode = Private->ClearCode;
821 LastCode = Private->LastCode;
823 if (StackPtr > LZ_MAX_CODE) {
828 /* Let pop the stack off before continueing to read the GIF file: */
829 while (StackPtr != 0 && i < LineLen)
830 Line[i++] = Stack[--StackPtr];
833 while (i < LineLen) { /* Decode LineLen items. */
834 if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
837 if (CrntCode == EOFCode) {
838 /* Note however that usually we will not be here as we will stop
839 * decoding as soon as we got all the pixel, or EOF code will
840 * not be read at all, and DGifGetLine/Pixel clean everything. */
841 GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;
843 } else if (CrntCode == ClearCode) {
844 /* We need to start over again: */
845 for (j = 0; j <= LZ_MAX_CODE; j++)
846 Prefix[j] = NO_SUCH_CODE;
847 Private->RunningCode = Private->EOFCode + 1;
848 Private->RunningBits = Private->BitsPerPixel + 1;
849 Private->MaxCode1 = 1 << Private->RunningBits;
850 LastCode = Private->LastCode = NO_SUCH_CODE;
852 /* Its regular code - if in pixel range simply add it to output
853 * stream, otherwise trace to codes linked list until the prefix
854 * is in pixel range: */
855 if (CrntCode < ClearCode) {
856 /* This is simple - its pixel scalar, so add it to output: */
857 Line[i++] = CrntCode;
859 /* Its a code to needed to be traced: trace the linked list
860 * until the prefix is a pixel, while pushing the suffix
861 * pixels on our stack. If we done, pop the stack in reverse
862 * (thats what stack is good for!) order to output. */
863 if (Prefix[CrntCode] == NO_SUCH_CODE) {
864 CrntPrefix = LastCode;
866 /* Only allowed if CrntCode is exactly the running code:
867 * In that case CrntCode = XXXCode, CrntCode or the
868 * prefix code is last code and the suffix char is
869 * exactly the prefix of last code! */
870 if (CrntCode == Private->RunningCode - 2) {
871 Suffix[Private->RunningCode - 2] =
872 Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
876 Suffix[Private->RunningCode - 2] =
877 Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
882 CrntPrefix = CrntCode;
884 /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
885 * during the trace. As we might loop forever, in case of
886 * defective image, we use StackPtr as loop counter and stop
887 * before overflowing Stack[]. */
888 while (StackPtr < LZ_MAX_CODE &&
889 CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
890 Stack[StackPtr++] = Suffix[CrntPrefix];
891 CrntPrefix = Prefix[CrntPrefix];
893 if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
894 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
897 /* Push the last character on stack: */
898 Stack[StackPtr++] = CrntPrefix;
900 /* Now lets pop all the stack into output: */
901 while (StackPtr != 0 && i < LineLen)
902 Line[i++] = Stack[--StackPtr];
904 if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
905 Prefix[Private->RunningCode - 2] = LastCode;
907 if (CrntCode == Private->RunningCode - 2) {
908 /* Only allowed if CrntCode is exactly the running code:
909 * In that case CrntCode = XXXCode, CrntCode or the
910 * prefix code is last code and the suffix char is
911 * exactly the prefix of last code! */
912 Suffix[Private->RunningCode - 2] =
913 DGifGetPrefixChar(Prefix, LastCode, ClearCode);
915 Suffix[Private->RunningCode - 2] =
916 DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
923 Private->LastCode = LastCode;
924 Private->StackPtr = StackPtr;
929 /******************************************************************************
930 Routine to trace the Prefixes linked list until we get a prefix which is
931 not code, but a pixel value (less than ClearCode). Returns that pixel value.
932 If image is defective, we might loop here forever, so we limit the loops to
933 the maximum possible if image O.k. - LZ_MAX_CODE times.
934 ******************************************************************************/
936 DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
940 while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
941 if (Code > LZ_MAX_CODE) {
949 /******************************************************************************
950 Interface for accessing the LZ codes directly. Set Code to the real code
951 (12bits), or to -1 if EOF code is returned.
952 ******************************************************************************/
954 DGifGetLZCodes(GifFileType *GifFile, int *Code)
956 GifByteType *CodeBlock;
957 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
959 if (!IS_READABLE(Private)) {
960 /* This file was NOT open for reading: */
961 GifFile->Error = D_GIF_ERR_NOT_READABLE;
965 if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
968 if (*Code == Private->EOFCode) {
969 /* Skip rest of codes (hopefully only NULL terminating block): */
971 if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
973 } while (CodeBlock != NULL) ;
976 } else if (*Code == Private->ClearCode) {
977 /* We need to start over again: */
978 Private->RunningCode = Private->EOFCode + 1;
979 Private->RunningBits = Private->BitsPerPixel + 1;
980 Private->MaxCode1 = 1 << Private->RunningBits;
986 /******************************************************************************
987 The LZ decompression input routine:
988 This routine is responsable for the decompression of the bit stream from
989 8 bits (bytes) packets, into the real codes.
990 Returns GIF_OK if read successfully.
991 ******************************************************************************/
993 DGifDecompressInput(GifFileType *GifFile, int *Code)
995 static const unsigned short CodeMasks[] = {
996 0x0000, 0x0001, 0x0003, 0x0007,
997 0x000f, 0x001f, 0x003f, 0x007f,
998 0x00ff, 0x01ff, 0x03ff, 0x07ff,
1002 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
1004 GifByteType NextByte;
1006 /* The image can't contain more than LZ_BITS per code. */
1007 if (Private->RunningBits > LZ_BITS) {
1008 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1012 while (Private->CrntShiftState < Private->RunningBits) {
1013 /* Needs to get more bytes from input stream for next code: */
1014 if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
1017 Private->CrntShiftDWord |=
1018 ((unsigned long)NextByte) << Private->CrntShiftState;
1019 Private->CrntShiftState += 8;
1021 *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
1023 Private->CrntShiftDWord >>= Private->RunningBits;
1024 Private->CrntShiftState -= Private->RunningBits;
1026 /* If code cannot fit into RunningBits bits, must raise its size. Note
1027 * however that codes above 4095 are used for special signaling.
1028 * If we're using LZ_BITS bits already and we're at the max code, just
1029 * keep using the table as it is, don't increment Private->RunningCode.
1031 if (Private->RunningCode < LZ_MAX_CODE + 2 &&
1032 ++Private->RunningCode > Private->MaxCode1 &&
1033 Private->RunningBits < LZ_BITS) {
1034 Private->MaxCode1 <<= 1;
1035 Private->RunningBits++;
1040 /******************************************************************************
1041 This routines read one GIF data block at a time and buffers it internally
1042 so that the decompression routine could access it.
1043 The routine returns the next byte from its internal buffer (or read next
1044 block in if buffer empty) and returns GIF_OK if succesful.
1045 ******************************************************************************/
1047 DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
1050 /* Needs to read the next buffer - this one is empty: */
1051 /* coverity[check_return] */
1052 if (READ(GifFile, Buf, 1) != 1) {
1053 GifFile->Error = D_GIF_ERR_READ_FAILED;
1056 /* There shouldn't be any empty data blocks here as the LZW spec
1057 * says the LZW termination code should come first. Therefore we
1058 * shouldn't be inside this routine at that point.
1061 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1064 if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1065 GifFile->Error = D_GIF_ERR_READ_FAILED;
1069 Buf[1] = 2; /* We use now the second place as last char read! */
1072 *NextByte = Buf[Buf[1]++];
1079 /******************************************************************************
1080 This routine reads an entire GIF into core, hanging all its state info off
1081 the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle()
1082 first to initialize I/O. Its inverse is EGifSpew().
1083 *******************************************************************************/
1085 DGifSlurp(GifFileType *GifFile)
1088 GifRecordType RecordType;
1090 GifByteType *ExtData;
1093 GifFile->ExtensionBlocks = NULL;
1094 GifFile->ExtensionBlockCount = 0;
1097 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
1100 switch (RecordType) {
1101 case IMAGE_DESC_RECORD_TYPE:
1102 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
1105 sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
1106 /* Allocate memory for the image */
1107 if (sp->ImageDesc.Width < 0 && sp->ImageDesc.Height < 0 &&
1108 sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
1111 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1113 if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
1116 sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
1117 sizeof(GifPixelType));
1119 if (sp->RasterBits == NULL) {
1123 if (sp->ImageDesc.Interlace) {
1126 * The way an interlaced image should be read -
1127 * offsets and jumps...
1129 int InterlacedOffset[] = { 0, 4, 2, 1 };
1130 int InterlacedJumps[] = { 8, 8, 4, 2 };
1131 /* Need to perform 4 passes on the image */
1132 for (i = 0; i < 4; i++)
1133 for (j = InterlacedOffset[i];
1134 j < sp->ImageDesc.Height;
1135 j += InterlacedJumps[i]) {
1136 if (DGifGetLine(GifFile,
1137 sp->RasterBits+j*sp->ImageDesc.Width,
1138 sp->ImageDesc.Width) == GIF_ERROR)
1143 if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
1147 if (GifFile->ExtensionBlocks) {
1148 sp->ExtensionBlocks = GifFile->ExtensionBlocks;
1149 sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
1151 GifFile->ExtensionBlocks = NULL;
1152 GifFile->ExtensionBlockCount = 0;
1156 case EXTENSION_RECORD_TYPE:
1157 if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
1159 /* Create an extension block with our data */
1160 if (ExtData != NULL) {
1161 if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1162 &GifFile->ExtensionBlocks,
1163 ExtFunction, ExtData[0], &ExtData[1])
1167 while (ExtData != NULL) {
1168 if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1170 /* Continue the extension block */
1171 if (ExtData != NULL)
1172 if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1173 &GifFile->ExtensionBlocks,
1174 CONTINUE_EXT_FUNC_CODE,
1175 ExtData[0], &ExtData[1]) == GIF_ERROR)
1180 case TERMINATE_RECORD_TYPE:
1183 default: /* Should be trapped by DGifGetRecordType */
1186 } while (RecordType != TERMINATE_RECORD_TYPE);
1188 /* Sanity check for corrupted file */
1189 if (GifFile->ImageCount == 0) {
1190 GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;