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 * 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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