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 return GifFile;
63 }
64
65 /******************************************************************************
66 Update a new GIF file, given its file handle.
67 Returns dynamically allocated GifFileType pointer which serves as the GIF
68 info record.
69 ******************************************************************************/
70 GifFileType *
DGifOpenFileHandle(int FileHandle,int * Error)71 DGifOpenFileHandle(int FileHandle, int *Error)
72 {
73 char Buf[GIF_STAMP_LEN + 1];
74 GifFileType *GifFile;
75 GifFilePrivateType *Private;
76 FILE *f;
77
78 GifFile = (GifFileType *)malloc(sizeof(GifFileType));
79 if (GifFile == NULL) {
80 if (Error != NULL)
81 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
82 (void)close(FileHandle);
83 return NULL;
84 }
85
86 /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType));
87
88 /* Belt and suspenders, in case the null pointer isn't zero */
89 GifFile->SavedImages = NULL;
90 GifFile->SColorMap = NULL;
91
92 Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
93 if (Private == NULL) {
94 if (Error != NULL)
95 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
96 (void)close(FileHandle);
97 free((char *)GifFile);
98 return NULL;
99 }
100
101 /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
102
103 #ifdef _WIN32
104 _setmode(FileHandle, O_BINARY); /* Make sure it is in binary mode. */
105 #endif /* _WIN32 */
106
107 f = fdopen(FileHandle, "rb"); /* Make it into a stream: */
108
109 /*@-mustfreeonly@*/
110 GifFile->Private = (void *)Private;
111 Private->FileHandle = FileHandle;
112 Private->File = f;
113 Private->FileState = FILE_STATE_READ;
114 Private->Read = NULL; /* don't use alternate input method (TVT) */
115 GifFile->UserData = NULL; /* TVT */
116 /*@=mustfreeonly@*/
117
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) {
121 if (Error != NULL)
122 *Error = D_GIF_ERR_READ_FAILED;
123 (void)fclose(f);
124 free((char *)Private);
125 free((char *)GifFile);
126 return NULL;
127 }
128
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) {
132 if (Error != NULL)
133 *Error = D_GIF_ERR_NOT_GIF_FILE;
134 (void)fclose(f);
135 free((char *)Private);
136 free((char *)GifFile);
137 return NULL;
138 }
139
140 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
141 (void)fclose(f);
142 free((char *)Private);
143 free((char *)GifFile);
144 return NULL;
145 }
146
147 GifFile->Error = 0;
148
149 /* What version of GIF? */
150 Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
151
152 return GifFile;
153 }
154
155 /******************************************************************************
156 GifFileType constructor with user supplied input function (TVT)
157 ******************************************************************************/
158 GifFileType *
DGifOpen(void * userData,InputFunc readFunc,int * Error)159 DGifOpen(void *userData, InputFunc readFunc, int *Error)
160 {
161 char Buf[GIF_STAMP_LEN + 1];
162 GifFileType *GifFile;
163 GifFilePrivateType *Private;
164
165 GifFile = (GifFileType *)malloc(sizeof(GifFileType));
166 if (GifFile == NULL) {
167 if (Error != NULL)
168 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
169 return NULL;
170 }
171
172 memset(GifFile, '\0', sizeof(GifFileType));
173
174 /* Belt and suspenders, in case the null pointer isn't zero */
175 GifFile->SavedImages = NULL;
176 GifFile->SColorMap = NULL;
177
178 Private = (GifFilePrivateType *)calloc(1, sizeof(GifFilePrivateType));
179 if (!Private) {
180 if (Error != NULL)
181 *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
182 free((char *)GifFile);
183 return NULL;
184 }
185 /*@i1@*/memset(Private, '\0', sizeof(GifFilePrivateType));
186
187 GifFile->Private = (void *)Private;
188 Private->FileHandle = 0;
189 Private->File = NULL;
190 Private->FileState = FILE_STATE_READ;
191
192 Private->Read = readFunc; /* TVT */
193 GifFile->UserData = userData; /* TVT */
194
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) {
198 if (Error != NULL)
199 *Error = D_GIF_ERR_READ_FAILED;
200 free((char *)Private);
201 free((char *)GifFile);
202 return NULL;
203 }
204
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) {
208 if (Error != NULL)
209 *Error = D_GIF_ERR_NOT_GIF_FILE;
210 free((char *)Private);
211 free((char *)GifFile);
212 return NULL;
213 }
214
215 if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
216 free((char *)Private);
217 free((char *)GifFile);
218 if (Error != NULL)
219 *Error = D_GIF_ERR_NO_SCRN_DSCR;
220 return NULL;
221 }
222
223 GifFile->Error = 0;
224
225 /* What version of GIF? */
226 Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
227
228 return GifFile;
229 }
230
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 ******************************************************************************/
235 int
DGifGetScreenDesc(GifFileType * GifFile)236 DGifGetScreenDesc(GifFileType *GifFile)
237 {
238 int BitsPerPixel;
239 bool SortFlag;
240 GifByteType Buf[3];
241 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
242
243 if (!IS_READABLE(Private)) {
244 /* This file was NOT open for reading: */
245 GifFile->Error = D_GIF_ERR_NOT_READABLE;
246 return GIF_ERROR;
247 }
248
249 /* Put the screen descriptor into the file: */
250 if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
251 DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
252 return GIF_ERROR;
253
254 if (READ(GifFile, Buf, 3) != 3) {
255 GifFile->Error = D_GIF_ERR_READ_FAILED;
256 GifFreeMapObject(GifFile->SColorMap);
257 GifFile->SColorMap = NULL;
258 return GIF_ERROR;
259 }
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? */
266 int i;
267
268 GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
269 if (GifFile->SColorMap == NULL) {
270 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
271 return GIF_ERROR;
272 }
273
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;
282 return GIF_ERROR;
283 }
284 GifFile->SColorMap->Colors[i].Red = Buf[0];
285 GifFile->SColorMap->Colors[i].Green = Buf[1];
286 GifFile->SColorMap->Colors[i].Blue = Buf[2];
287 }
288 } else {
289 GifFile->SColorMap = NULL;
290 }
291
292 return GIF_OK;
293 }
294
295 /******************************************************************************
296 This routine should be called before any attempt to read an image.
297 ******************************************************************************/
298 int
DGifGetRecordType(GifFileType * GifFile,GifRecordType * Type)299 DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
300 {
301 GifByteType Buf;
302 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
303
304 if (!IS_READABLE(Private)) {
305 /* This file was NOT open for reading: */
306 GifFile->Error = D_GIF_ERR_NOT_READABLE;
307 return GIF_ERROR;
308 }
309
310 /* coverity[check_return] */
311 if (READ(GifFile, &Buf, 1) != 1) {
312 GifFile->Error = D_GIF_ERR_READ_FAILED;
313 return GIF_ERROR;
314 }
315
316 switch (Buf) {
317 case DESCRIPTOR_INTRODUCER:
318 *Type = IMAGE_DESC_RECORD_TYPE;
319 break;
320 case EXTENSION_INTRODUCER:
321 *Type = EXTENSION_RECORD_TYPE;
322 break;
323 case TERMINATOR_INTRODUCER:
324 *Type = TERMINATE_RECORD_TYPE;
325 break;
326 default:
327 *Type = UNDEFINED_RECORD_TYPE;
328 GifFile->Error = D_GIF_ERR_WRONG_RECORD;
329 return GIF_ERROR;
330 }
331
332 return GIF_OK;
333 }
334
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 ******************************************************************************/
339 int
DGifGetImageDesc(GifFileType * GifFile)340 DGifGetImageDesc(GifFileType *GifFile)
341 {
342 unsigned int BitsPerPixel;
343 GifByteType Buf[3];
344 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
345 SavedImage *sp;
346
347 if (!IS_READABLE(Private)) {
348 /* This file was NOT open for reading: */
349 GifFile->Error = D_GIF_ERR_NOT_READABLE;
350 return GIF_ERROR;
351 }
352
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)
357 return 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;
362 return GIF_ERROR;
363 }
364 BitsPerPixel = (Buf[0] & 0x07) + 1;
365 GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
366
367 /* Setup the colormap */
368 if (GifFile->Image.ColorMap) {
369 GifFreeMapObject(GifFile->Image.ColorMap);
370 GifFile->Image.ColorMap = NULL;
371 }
372 /* Does this image have local color map? */
373 if (Buf[0] & 0x80) {
374 unsigned int i;
375
376 GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
377 if (GifFile->Image.ColorMap == NULL) {
378 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
379 return GIF_ERROR;
380 }
381
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;
389 return GIF_ERROR;
390 }
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];
394 }
395 }
396
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;
403 return GIF_ERROR;
404 }
405 GifFile->SavedImages = new_saved_images;
406 } else {
407 if ((GifFile->SavedImages =
408 (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
409 GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
410 return GIF_ERROR;
411 }
412 }
413
414 sp = &GifFile->SavedImages[GifFile->ImageCount];
415 memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
416 if (GifFile->Image.ColorMap != NULL) {
417 sp->ImageDesc.ColorMap = 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;
422 return GIF_ERROR;
423 }
424 }
425 sp->RasterBits = (unsigned char *)NULL;
426 sp->ExtensionBlockCount = 0;
427 sp->ExtensionBlocks = (ExtensionBlock *) NULL;
428
429 GifFile->ImageCount++;
430
431 Private->PixelCount = (long)GifFile->Image.Width *
432 (long)GifFile->Image.Height;
433
434 /* Reset decompress algorithm parameters. */
435 return DGifSetupDecompress(GifFile);
436 }
437
438 /******************************************************************************
439 Get one full scanned line (Line) of length LineLen from GIF file.
440 ******************************************************************************/
441 int
DGifGetLine(GifFileType * GifFile,GifPixelType * Line,int LineLen)442 DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
443 {
444 GifByteType *Dummy;
445 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
446
447 if (!IS_READABLE(Private)) {
448 /* This file was NOT open for reading: */
449 GifFile->Error = D_GIF_ERR_NOT_READABLE;
450 return GIF_ERROR;
451 }
452
453 if (!LineLen)
454 LineLen = GifFile->Image.Width;
455
456 if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
457 GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
458 return GIF_ERROR;
459 }
460
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.
467 */
468 do
469 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
470 return GIF_ERROR;
471 while (Dummy != NULL) ;
472 }
473 return GIF_OK;
474 } else
475 return GIF_ERROR;
476 }
477
478 /******************************************************************************
479 Put one pixel (Pixel) into GIF file.
480 ******************************************************************************/
481 int
DGifGetPixel(GifFileType * GifFile,GifPixelType Pixel)482 DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
483 {
484 GifByteType *Dummy;
485 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
486
487 if (!IS_READABLE(Private)) {
488 /* This file was NOT open for reading: */
489 GifFile->Error = D_GIF_ERR_NOT_READABLE;
490 return GIF_ERROR;
491 }
492 if (--Private->PixelCount > 0xffff0000UL)
493 {
494 GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
495 return GIF_ERROR;
496 }
497
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.
504 */
505 do
506 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
507 return GIF_ERROR;
508 while (Dummy != NULL) ;
509 }
510 return GIF_OK;
511 } else
512 return GIF_ERROR;
513 }
514
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 ******************************************************************************/
522 int
DGifGetExtension(GifFileType * GifFile,int * ExtCode,GifByteType ** Extension)523 DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
524 {
525 GifByteType Buf;
526 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
527
528 if (!IS_READABLE(Private)) {
529 /* This file was NOT open for reading: */
530 GifFile->Error = D_GIF_ERR_NOT_READABLE;
531 return GIF_ERROR;
532 }
533
534 /* coverity[check_return] */
535 if (READ(GifFile, &Buf, 1) != 1) {
536 GifFile->Error = D_GIF_ERR_READ_FAILED;
537 return GIF_ERROR;
538 }
539 *ExtCode = Buf;
540
541 return DGifGetExtensionNext(GifFile, Extension);
542 }
543
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 ******************************************************************************/
549 int
DGifGetExtensionNext(GifFileType * GifFile,GifByteType ** Extension)550 DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
551 {
552 GifByteType Buf;
553 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
554
555 if (READ(GifFile, &Buf, 1) != 1) {
556 GifFile->Error = D_GIF_ERR_READ_FAILED;
557 return GIF_ERROR;
558 }
559 if (Buf > 0) {
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;
565 return GIF_ERROR;
566 }
567 } else
568 *Extension = NULL;
569
570 return GIF_OK;
571 }
572
573 /******************************************************************************
574 Extract a Graphics Control Block from raw extension data
575 ******************************************************************************/
576
DGifExtensionToGCB(const size_t GifExtensionLength,const GifByteType * GifExtension,GraphicsControlBlock * GCB)577 int DGifExtensionToGCB(const size_t GifExtensionLength,
578 const GifByteType *GifExtension,
579 GraphicsControlBlock *GCB)
580 {
581 if (GifExtensionLength != 4) {
582 return GIF_ERROR;
583 }
584
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];
590 else
591 GCB->TransparentColor = NO_TRANSPARENT_COLOR;
592
593 return GIF_OK;
594 }
595
596 /******************************************************************************
597 Extract the Graphics Control Block for a saved image, if it exists.
598 ******************************************************************************/
599
DGifSavedExtensionToGCB(GifFileType * GifFile,int ImageIndex,GraphicsControlBlock * GCB)600 int DGifSavedExtensionToGCB(GifFileType *GifFile,
601 int ImageIndex, GraphicsControlBlock *GCB)
602 {
603 int i;
604
605 if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1)
606 return GIF_ERROR;
607
608 GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
609 GCB->UserInputFlag = false;
610 GCB->DelayTime = 0;
611 GCB->TransparentColor = NO_TRANSPARENT_COLOR;
612
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);
617 }
618
619 return GIF_ERROR;
620 }
621
622 /******************************************************************************
623 This routine should be called last, to close the GIF file.
624 ******************************************************************************/
625 int
DGifCloseFile(GifFileType * GifFile,int * ErrorCode)626 DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
627 {
628 GifFilePrivateType *Private;
629
630 if (GifFile == NULL || GifFile->Private == NULL)
631 return GIF_ERROR;
632
633 if (GifFile->Image.ColorMap) {
634 GifFreeMapObject(GifFile->Image.ColorMap);
635 GifFile->Image.ColorMap = NULL;
636 }
637
638 if (GifFile->SColorMap) {
639 GifFreeMapObject(GifFile->SColorMap);
640 GifFile->SColorMap = NULL;
641 }
642
643 if (GifFile->SavedImages) {
644 GifFreeSavedImages(GifFile);
645 GifFile->SavedImages = NULL;
646 }
647
648 GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks);
649
650 Private = (GifFilePrivateType *) GifFile->Private;
651
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);
657 free(GifFile);
658 return GIF_ERROR;
659 }
660
661 if (Private->File && (fclose(Private->File) != 0)) {
662 if (ErrorCode != NULL)
663 *ErrorCode = D_GIF_ERR_CLOSE_FAILED;
664 free((char *)GifFile->Private);
665 free(GifFile);
666 return GIF_ERROR;
667 }
668
669 free((char *)GifFile->Private);
670 free(GifFile);
671 if (ErrorCode != NULL)
672 *ErrorCode = D_GIF_SUCCEEDED;
673 return GIF_OK;
674 }
675
676 /******************************************************************************
677 Get 2 bytes (word) from the given file:
678 ******************************************************************************/
679 static int
DGifGetWord(GifFileType * GifFile,GifWord * Word)680 DGifGetWord(GifFileType *GifFile, GifWord *Word)
681 {
682 unsigned char c[2];
683
684 /* coverity[check_return] */
685 if (READ(GifFile, c, 2) != 2) {
686 GifFile->Error = D_GIF_ERR_READ_FAILED;
687 return GIF_ERROR;
688 }
689
690 *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
691 return GIF_OK;
692 }
693
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 ******************************************************************************/
701 int
DGifGetCode(GifFileType * GifFile,int * CodeSize,GifByteType ** CodeBlock)702 DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
703 {
704 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
705
706 if (!IS_READABLE(Private)) {
707 /* This file was NOT open for reading: */
708 GifFile->Error = D_GIF_ERR_NOT_READABLE;
709 return GIF_ERROR;
710 }
711
712 *CodeSize = Private->BitsPerPixel;
713
714 return DGifGetCodeNext(GifFile, CodeBlock);
715 }
716
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 ******************************************************************************/
722 int
DGifGetCodeNext(GifFileType * GifFile,GifByteType ** CodeBlock)723 DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
724 {
725 GifByteType Buf;
726 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
727
728 /* coverity[tainted_data_argument] */
729 /* coverity[check_return] */
730 if (READ(GifFile, &Buf, 1) != 1) {
731 GifFile->Error = D_GIF_ERR_READ_FAILED;
732 return GIF_ERROR;
733 }
734
735 /* coverity[lower_bounds] */
736 if (Buf > 0) {
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;
742 return GIF_ERROR;
743 }
744 } else {
745 *CodeBlock = NULL;
746 Private->Buf[0] = 0; /* Make sure the buffer is empty! */
747 Private->PixelCount = 0; /* And local info. indicate image read. */
748 }
749
750 return GIF_OK;
751 }
752
753 /******************************************************************************
754 Setup the LZ decompression for this image:
755 ******************************************************************************/
756 static int
DGifSetupDecompress(GifFileType * GifFile)757 DGifSetupDecompress(GifFileType *GifFile)
758 {
759 int i, BitsPerPixel;
760 GifByteType CodeSize;
761 GifPrefixType *Prefix;
762 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
763
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. */
767 }
768 BitsPerPixel = CodeSize;
769
770 /* this can only happen on a severely malformed GIF */
771 if (BitsPerPixel > 8) {
772 GifFile->Error = D_GIF_ERR_READ_FAILED; /* somewhat bogus error code */
773 return GIF_ERROR; /* Failed to read Code size. */
774 }
775
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;
787
788 Prefix = Private->Prefix;
789 for (i = 0; i <= LZ_MAX_CODE; i++)
790 Prefix[i] = NO_SUCH_CODE;
791
792 return GIF_OK;
793 }
794
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 ******************************************************************************/
801 static int
DGifDecompressLine(GifFileType * GifFile,GifPixelType * Line,int LineLen)802 DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
803 {
804 int i = 0;
805 int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
806 GifByteType *Stack, *Suffix;
807 GifPrefixType *Prefix;
808 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
809
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;
817
818 if (StackPtr > LZ_MAX_CODE) {
819 return GIF_ERROR;
820 }
821
822 if (StackPtr != 0) {
823 /* Let pop the stack off before continueing to read the GIF file: */
824 while (StackPtr != 0 && i < LineLen)
825 Line[i++] = Stack[--StackPtr];
826 }
827
828 while (i < LineLen) { /* Decode LineLen items. */
829 if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
830 return GIF_ERROR;
831
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;
837 return GIF_ERROR;
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;
846 } else {
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;
853 } else {
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;
860
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,
868 LastCode,
869 ClearCode);
870 } else {
871 Suffix[Private->RunningCode - 2] =
872 Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
873 CrntCode,
874 ClearCode);
875 }
876 } else
877 CrntPrefix = CrntCode;
878
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];
887 }
888 if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
889 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
890 return GIF_ERROR;
891 }
892 /* Push the last character on stack: */
893 Stack[StackPtr++] = CrntPrefix;
894
895 /* Now lets pop all the stack into output: */
896 while (StackPtr != 0 && i < LineLen)
897 Line[i++] = Stack[--StackPtr];
898 }
899 if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
900 Prefix[Private->RunningCode - 2] = LastCode;
901
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);
909 } else {
910 Suffix[Private->RunningCode - 2] =
911 DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
912 }
913 }
914 LastCode = CrntCode;
915 }
916 }
917
918 Private->LastCode = LastCode;
919 Private->StackPtr = StackPtr;
920
921 return GIF_OK;
922 }
923
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 ******************************************************************************/
930 static int
DGifGetPrefixChar(GifPrefixType * Prefix,int Code,int ClearCode)931 DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
932 {
933 int i = 0;
934
935 while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
936 if (Code > LZ_MAX_CODE) {
937 return NO_SUCH_CODE;
938 }
939 Code = Prefix[Code];
940 }
941 return Code;
942 }
943
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 ******************************************************************************/
948 int
DGifGetLZCodes(GifFileType * GifFile,int * Code)949 DGifGetLZCodes(GifFileType *GifFile, int *Code)
950 {
951 GifByteType *CodeBlock;
952 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
953
954 if (!IS_READABLE(Private)) {
955 /* This file was NOT open for reading: */
956 GifFile->Error = D_GIF_ERR_NOT_READABLE;
957 return GIF_ERROR;
958 }
959
960 if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
961 return GIF_ERROR;
962
963 if (*Code == Private->EOFCode) {
964 /* Skip rest of codes (hopefully only NULL terminating block): */
965 do {
966 if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
967 return GIF_ERROR;
968 } while (CodeBlock != NULL) ;
969
970 *Code = -1;
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;
976 }
977
978 return GIF_OK;
979 }
980
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 ******************************************************************************/
987 static int
DGifDecompressInput(GifFileType * GifFile,int * Code)988 DGifDecompressInput(GifFileType *GifFile, int *Code)
989 {
990 static const unsigned short CodeMasks[] = {
991 0x0000, 0x0001, 0x0003, 0x0007,
992 0x000f, 0x001f, 0x003f, 0x007f,
993 0x00ff, 0x01ff, 0x03ff, 0x07ff,
994 0x0fff
995 };
996
997 GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
998
999 GifByteType NextByte;
1000
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;
1004 return GIF_ERROR;
1005 }
1006
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) {
1010 return GIF_ERROR;
1011 }
1012 Private->CrntShiftDWord |=
1013 ((unsigned long)NextByte) << Private->CrntShiftState;
1014 Private->CrntShiftState += 8;
1015 }
1016 *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
1017
1018 Private->CrntShiftDWord >>= Private->RunningBits;
1019 Private->CrntShiftState -= Private->RunningBits;
1020
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.
1025 */
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++;
1031 }
1032 return GIF_OK;
1033 }
1034
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 ******************************************************************************/
1041 static int
DGifBufferedInput(GifFileType * GifFile,GifByteType * Buf,GifByteType * NextByte)1042 DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
1043 {
1044 if (Buf[0] == 0) {
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;
1049 return GIF_ERROR;
1050 }
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.
1054 */
1055 if (Buf[0] == 0) {
1056 GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1057 return GIF_ERROR;
1058 }
1059 if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1060 GifFile->Error = D_GIF_ERR_READ_FAILED;
1061 return GIF_ERROR;
1062 }
1063 *NextByte = Buf[1];
1064 Buf[1] = 2; /* We use now the second place as last char read! */
1065 Buf[0]--;
1066 } else {
1067 *NextByte = Buf[Buf[1]++];
1068 Buf[0]--;
1069 }
1070
1071 return GIF_OK;
1072 }
1073
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 *******************************************************************************/
1079 int
DGifSlurp(GifFileType * GifFile)1080 DGifSlurp(GifFileType *GifFile)
1081 {
1082 size_t ImageSize;
1083 GifRecordType RecordType;
1084 SavedImage *sp;
1085 GifByteType *ExtData;
1086 int ExtFunction;
1087
1088 GifFile->ExtensionBlocks = NULL;
1089 GifFile->ExtensionBlockCount = 0;
1090
1091 do {
1092 if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
1093 return (GIF_ERROR);
1094
1095 switch (RecordType) {
1096 case IMAGE_DESC_RECORD_TYPE:
1097 if (DGifGetImageDesc(GifFile) == GIF_ERROR)
1098 return (GIF_ERROR);
1099
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)) {
1104 return GIF_ERROR;
1105 }
1106 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1107
1108 if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
1109 return GIF_ERROR;
1110 }
1111 sp->RasterBits = (unsigned char *)reallocarray(NULL, ImageSize,
1112 sizeof(GifPixelType));
1113
1114 if (sp->RasterBits == NULL) {
1115 return GIF_ERROR;
1116 }
1117
1118 if (sp->ImageDesc.Interlace) {
1119 int i, j;
1120 /*
1121 * The way an interlaced image should be read -
1122 * offsets and jumps...
1123 */
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)
1134 return GIF_ERROR;
1135 }
1136 }
1137 else {
1138 if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
1139 return (GIF_ERROR);
1140 }
1141
1142 if (GifFile->ExtensionBlocks) {
1143 sp->ExtensionBlocks = GifFile->ExtensionBlocks;
1144 sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
1145
1146 GifFile->ExtensionBlocks = NULL;
1147 GifFile->ExtensionBlockCount = 0;
1148 }
1149 break;
1150
1151 case EXTENSION_RECORD_TYPE:
1152 if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
1153 return (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])
1159 == GIF_ERROR)
1160 return (GIF_ERROR);
1161 }
1162 while (ExtData != NULL) {
1163 if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1164 return (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)
1171 return (GIF_ERROR);
1172 }
1173 break;
1174
1175 case TERMINATE_RECORD_TYPE:
1176 break;
1177
1178 default: /* Should be trapped by DGifGetRecordType */
1179 break;
1180 }
1181 } while (RecordType != TERMINATE_RECORD_TYPE);
1182
1183 /* Sanity check for corrupted file */
1184 if (GifFile->ImageCount == 0) {
1185 GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
1186 return(GIF_ERROR);
1187 }
1188
1189 return (GIF_OK);
1190 }
1191
1192 /* end */
1193