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