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