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