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