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