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