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