nsGIFDecoder2.cpp (42497B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 /* 7 The Graphics Interchange Format(c) is the copyright property of CompuServe 8 Incorporated. Only CompuServe Incorporated is authorized to define, redefine, 9 enhance, alter, modify or change in any way the definition of the format. 10 11 CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free 12 license for the use of the Graphics Interchange Format(sm) in computer 13 software; computer software utilizing GIF(sm) must acknowledge ownership of the 14 Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in 15 User and Technical Documentation. Computer software utilizing GIF, which is 16 distributed or may be distributed without User or Technical Documentation must 17 display to the screen or printer a message acknowledging ownership of the 18 Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in 19 this case, the acknowledgement may be displayed in an opening screen or leading 20 banner, or a closing screen or trailing banner. A message such as the following 21 may be used: 22 23 "The Graphics Interchange Format(c) is the Copyright property of 24 CompuServe Incorporated. GIF(sm) is a Service Mark property of 25 CompuServe Incorporated." 26 27 For further information, please contact : 28 29 CompuServe Incorporated 30 Graphics Technology Department 31 5000 Arlington Center Boulevard 32 Columbus, Ohio 43220 33 U. S. A. 34 35 CompuServe Incorporated maintains a mailing list with all those individuals and 36 organizations who wish to receive copies of this document when it is corrected 37 or revised. This service is offered free of charge; please provide us with your 38 mailing address. 39 */ 40 41 #include "nsGIFDecoder2.h" 42 43 #include <stddef.h> 44 45 #include "imgFrame.h" 46 #include "mozilla/EndianUtils.h" 47 #include "RasterImage.h" 48 #include "SurfacePipeFactory.h" 49 50 #include "gfxColor.h" 51 #include "gfxPlatform.h" 52 #include "qcms.h" 53 #include <algorithm> 54 55 using namespace mozilla::gfx; 56 57 using std::max; 58 59 namespace mozilla { 60 namespace image { 61 62 ////////////////////////////////////////////////////////////////////// 63 // GIF Decoder Implementation 64 65 static const size_t GIF_HEADER_LEN = 6; 66 static const size_t GIF_SCREEN_DESCRIPTOR_LEN = 7; 67 static const size_t BLOCK_HEADER_LEN = 1; 68 static const size_t SUB_BLOCK_HEADER_LEN = 1; 69 static const size_t EXTENSION_HEADER_LEN = 2; 70 static const size_t GRAPHIC_CONTROL_EXTENSION_LEN = 4; 71 static const size_t APPLICATION_EXTENSION_LEN = 11; 72 static const size_t IMAGE_DESCRIPTOR_LEN = 9; 73 74 // Masks for reading color table information from packed fields in the screen 75 // descriptor and image descriptor blocks. 76 static const uint8_t PACKED_FIELDS_COLOR_TABLE_BIT = 0x80; 77 static const uint8_t PACKED_FIELDS_INTERLACED_BIT = 0x40; 78 static const uint8_t PACKED_FIELDS_TABLE_DEPTH_MASK = 0x07; 79 80 nsGIFDecoder2::nsGIFDecoder2(RasterImage* aImage) 81 : Decoder(aImage), 82 mLexer(Transition::To(State::GIF_HEADER, GIF_HEADER_LEN), 83 Transition::TerminateSuccess()), 84 mOldColor(0), 85 mCurrentFrameIndex(-1), 86 mColorTablePos(0), 87 mColormap(nullptr), 88 mColormapSize(0), 89 mColorMask('\0'), 90 mGIFOpen(false), 91 mSawTransparency(false), 92 mSwizzleFn(nullptr) { 93 // Clear out the structure, excluding the arrays. Ensure that the global 94 // colormap is initialized as opaque. 95 memset(&mGIFStruct, 0, sizeof(mGIFStruct)); 96 memset(mGIFStruct.global_colormap, 0xFF, sizeof(mGIFStruct.global_colormap)); 97 98 // Each color table will need to be unpacked. 99 mSwizzleFn = SwizzleRow(SurfaceFormat::R8G8B8, SurfaceFormat::OS_RGBA); 100 MOZ_ASSERT(mSwizzleFn); 101 } 102 103 nsGIFDecoder2::~nsGIFDecoder2() { free(mGIFStruct.local_colormap); } 104 105 nsresult nsGIFDecoder2::FinishWithErrorInternal() { 106 if (mGIFOpen) { 107 if (WantsFrameCount()) { 108 PostFrameCount(mGIFStruct.images_decoded); 109 } 110 PostLoopCount(mGIFStruct.loop_count); 111 mGIFOpen = false; 112 } 113 114 return Decoder::FinishWithErrorInternal(); 115 } 116 117 nsresult nsGIFDecoder2::FinishInternal() { 118 MOZ_ASSERT(!HasError(), "Shouldn't call FinishInternal after error!"); 119 120 if (!mGIFOpen) { 121 return NS_OK; 122 } 123 124 PostLoopCount(mGIFStruct.loop_count); 125 126 // If the GIF got cut off, handle it anyway 127 if (mCurrentFrameIndex == mGIFStruct.images_decoded) { 128 EndImageFrame(); 129 } 130 131 if (WantsFrameCount()) { 132 PostFrameCount(mGIFStruct.images_decoded); 133 } 134 135 if (!IsMetadataDecode()) { 136 PostDecodeDone(); 137 } 138 139 mGIFOpen = false; 140 return NS_OK; 141 } 142 143 void nsGIFDecoder2::FlushImageData() { 144 Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect(); 145 if (!invalidRect) { 146 return; 147 } 148 149 PostInvalidation(invalidRect->mInputSpaceRect, 150 Some(invalidRect->mOutputSpaceRect)); 151 } 152 153 //****************************************************************************** 154 // GIF decoder callback methods. Part of public API for GIF2 155 //****************************************************************************** 156 157 //****************************************************************************** 158 void nsGIFDecoder2::BeginGIF() { 159 if (mGIFOpen) { 160 return; 161 } 162 163 mGIFOpen = true; 164 165 PostSize(mGIFStruct.screen_width, mGIFStruct.screen_height); 166 } 167 168 bool nsGIFDecoder2::CheckForTransparency(const OrientedIntRect& aFrameRect) { 169 // Check if the image has a transparent color in its palette. 170 if (mGIFStruct.is_transparent) { 171 PostHasTransparency(); 172 return true; 173 } 174 175 // This is a bit of a hack. Some sites will use a 1x1 gif that includes no 176 // header information indicating it is transparent, no palette, and no image 177 // data at all (so no pixels get written) to represent a transparent pixel 178 // using the absolute least number of bytes. Generally things are setup to 179 // detect transparency without decoding the image data. So to detect this kind 180 // of transparency without decoing the image data we would have to assume 181 // every gif is transparent, which we would like to avoid. Changing things so 182 // that we can detect transparency at any point of decoding is a bigger change 183 // and not worth it for one questionable 1x1 gif. Using this "trick" for 184 // anything but 1x1 transparent spacer gifs doesn't make sense, so it's 185 // reasonable to target 1x1 gifs just for this. 186 if (mGIFStruct.screen_width == 1 && mGIFStruct.screen_height == 1) { 187 PostHasTransparency(); 188 return true; 189 } 190 191 if (mGIFStruct.images_decoded > 0) { 192 return false; // We only care about first frame padding below. 193 } 194 195 // If we need padding on the first frame, that means we don't draw into part 196 // of the image at all. Report that as transparency. 197 OrientedIntRect imageRect(0, 0, mGIFStruct.screen_width, 198 mGIFStruct.screen_height); 199 if (!imageRect.IsEqualEdges(aFrameRect)) { 200 PostHasTransparency(); 201 mSawTransparency = true; // Make sure we don't optimize it away. 202 return true; 203 } 204 205 return false; 206 } 207 208 //****************************************************************************** 209 nsresult nsGIFDecoder2::BeginImageFrame(const OrientedIntRect& aFrameRect, 210 uint16_t aDepth, bool aIsInterlaced) { 211 MOZ_ASSERT(HasSize()); 212 213 // If we are just counting frames for a metadata decode, there is no actual 214 // decoding done. We are just iterating over the blocks to find when a frame 215 // begins and ends. 216 if (WantsFrameCount()) { 217 mCurrentFrameIndex = mGIFStruct.images_decoded; 218 return NS_OK; 219 } 220 221 bool hasTransparency = CheckForTransparency(aFrameRect); 222 223 // Make sure there's no animation if we're downscaling. 224 MOZ_ASSERT_IF(Size() != OutputSize(), !GetImageMetadata().HasAnimation()); 225 226 Maybe<AnimationParams> animParams; 227 if (!IsFirstFrameDecode()) { 228 animParams.emplace(aFrameRect.ToUnknownRect(), 229 FrameTimeout::FromRawMilliseconds(mGIFStruct.delay_time), 230 uint32_t(mGIFStruct.images_decoded), BlendMethod::OVER, 231 DisposalMethod(mGIFStruct.disposal_method)); 232 } 233 234 SurfacePipeFlags pipeFlags = 235 aIsInterlaced ? SurfacePipeFlags::DEINTERLACE : SurfacePipeFlags(); 236 237 gfx::SurfaceFormat format; 238 if (mGIFStruct.images_decoded == 0) { 239 // The first frame may be displayed progressively. 240 pipeFlags |= SurfacePipeFlags::PROGRESSIVE_DISPLAY; 241 242 // Only allow opaque surfaces if we are decoding a single image without 243 // transparency. For an animation, there isn't much benefit to RGBX given 244 // the current frame is constantly changing, and there are many risks 245 // since BlendAnimationFilter is able to clear rows of data. 246 format = hasTransparency || animParams ? SurfaceFormat::OS_RGBA 247 : SurfaceFormat::OS_RGBX; 248 } else { 249 format = SurfaceFormat::OS_RGBA; 250 } 251 252 Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe( 253 this, Size(), OutputSize(), aFrameRect, format, format, animParams, 254 mTransform, pipeFlags); 255 mCurrentFrameIndex = mGIFStruct.images_decoded; 256 257 if (!pipe) { 258 mPipe = SurfacePipe(); 259 return NS_ERROR_FAILURE; 260 } 261 262 mPipe = std::move(*pipe); 263 return NS_OK; 264 } 265 266 //****************************************************************************** 267 void nsGIFDecoder2::EndImageFrame() { 268 if (WantsFrameCount()) { 269 mGIFStruct.pixels_remaining = 0; 270 mGIFStruct.images_decoded++; 271 mGIFStruct.delay_time = 0; 272 mColormap = nullptr; 273 mColormapSize = 0; 274 mCurrentFrameIndex = -1; 275 276 // Keep updating the count every time we find a frame. 277 PostFrameCount(mGIFStruct.images_decoded); 278 return; 279 } 280 281 Opacity opacity = Opacity::SOME_TRANSPARENCY; 282 283 if (mGIFStruct.images_decoded == 0) { 284 // We need to send invalidations for the first frame. 285 FlushImageData(); 286 287 // The first frame was preallocated with alpha; if it wasn't transparent, we 288 // should fix that. We can also mark it opaque unconditionally if we didn't 289 // actually see any transparent pixels - this test is only valid for the 290 // first frame. 291 if (!mGIFStruct.is_transparent && !mSawTransparency) { 292 opacity = Opacity::FULLY_OPAQUE; 293 } 294 } 295 296 // Unconditionally increment images_decoded, because we unconditionally 297 // append frames in BeginImageFrame(). This ensures that images_decoded 298 // always refers to the frame in mImage we're currently decoding, 299 // even if some of them weren't decoded properly and thus are blank. 300 mGIFStruct.images_decoded++; 301 302 // Tell the superclass we finished a frame 303 PostFrameStop(opacity); 304 305 // Reset the transparent pixel 306 if (mOldColor) { 307 mColormap[mGIFStruct.tpixel] = mOldColor; 308 mOldColor = 0; 309 } 310 311 // Reset graphic control extension parameters that we shouldn't reuse 312 // between frames. 313 mGIFStruct.delay_time = 0; 314 mGIFStruct.is_transparent = 0; 315 mGIFStruct.tpixel = 0; 316 mGIFStruct.disposal_method = 0; 317 318 mColormap = nullptr; 319 mColormapSize = 0; 320 mCurrentFrameIndex = -1; 321 } 322 323 template <typename PixelSize> 324 PixelSize nsGIFDecoder2::ColormapIndexToPixel(uint8_t aIndex) { 325 MOZ_ASSERT(sizeof(PixelSize) == sizeof(uint32_t)); 326 327 // Retrieve the next color, clamping to the size of the colormap. 328 uint32_t color = mColormap[aIndex & mColorMask]; 329 330 // Check for transparency. 331 if (mGIFStruct.is_transparent) { 332 mSawTransparency = mSawTransparency || color == 0; 333 } 334 335 return color; 336 } 337 338 template <> 339 uint8_t nsGIFDecoder2::ColormapIndexToPixel<uint8_t>(uint8_t aIndex) { 340 return aIndex & mColorMask; 341 } 342 343 template <typename PixelSize> 344 std::tuple<int32_t, Maybe<WriteState>> nsGIFDecoder2::YieldPixels( 345 const uint8_t* aData, size_t aLength, size_t* aBytesReadOut, 346 PixelSize* aPixelBlock, int32_t aBlockSize) { 347 MOZ_ASSERT(aData); 348 MOZ_ASSERT(aBytesReadOut); 349 MOZ_ASSERT(mGIFStruct.stackp >= mGIFStruct.stack); 350 351 // Advance to the next byte we should read. 352 const uint8_t* data = aData + *aBytesReadOut; 353 354 int32_t written = 0; 355 while (aBlockSize > written) { 356 // If we don't have any decoded data to yield, try to read some input and 357 // produce some. 358 if (mGIFStruct.stackp == mGIFStruct.stack) { 359 while (mGIFStruct.bits < mGIFStruct.codesize && 360 *aBytesReadOut < aLength) { 361 // Feed the next byte into the decoder's 32-bit input buffer. 362 mGIFStruct.datum += int32_t(*data) << mGIFStruct.bits; 363 mGIFStruct.bits += 8; 364 data += 1; 365 *aBytesReadOut += 1; 366 } 367 368 if (mGIFStruct.bits < mGIFStruct.codesize) { 369 return std::make_tuple(written, Some(WriteState::NEED_MORE_DATA)); 370 } 371 372 // Get the leading variable-length symbol from the data stream. 373 int code = mGIFStruct.datum & mGIFStruct.codemask; 374 mGIFStruct.datum >>= mGIFStruct.codesize; 375 mGIFStruct.bits -= mGIFStruct.codesize; 376 377 const int clearCode = ClearCode(); 378 379 // Reset the dictionary to its original state, if requested 380 if (code == clearCode) { 381 mGIFStruct.codesize = mGIFStruct.datasize + 1; 382 mGIFStruct.codemask = (1 << mGIFStruct.codesize) - 1; 383 mGIFStruct.avail = clearCode + 2; 384 mGIFStruct.oldcode = -1; 385 return std::make_tuple(written, Some(WriteState::NEED_MORE_DATA)); 386 } 387 388 // Check for explicit end-of-stream code. It should only appear after all 389 // image data, but if that was the case we wouldn't be in this function, 390 // so this is always an error condition. 391 if (code == (clearCode + 1)) { 392 return std::make_tuple(written, Some(WriteState::FAILURE)); 393 } 394 395 if (mGIFStruct.oldcode == -1) { 396 if (code >= MAX_BITS) { 397 // The code's too big; something's wrong. 398 return std::make_tuple(written, Some(WriteState::FAILURE)); 399 } 400 401 mGIFStruct.firstchar = mGIFStruct.oldcode = code; 402 403 // Yield a pixel at the appropriate index in the colormap. 404 mGIFStruct.pixels_remaining--; 405 aPixelBlock[written++] = 406 ColormapIndexToPixel<PixelSize>(mGIFStruct.suffix[code]); 407 continue; 408 } 409 410 int incode = code; 411 if (code >= mGIFStruct.avail) { 412 *mGIFStruct.stackp++ = mGIFStruct.firstchar; 413 code = mGIFStruct.oldcode; 414 415 if (mGIFStruct.stackp >= mGIFStruct.stack + MAX_BITS) { 416 // Stack overflow; something's wrong. 417 return std::make_tuple(written, Some(WriteState::FAILURE)); 418 } 419 } 420 421 while (code >= clearCode) { 422 if ((code >= MAX_BITS) || (code == mGIFStruct.prefix[code])) { 423 return std::make_tuple(written, Some(WriteState::FAILURE)); 424 } 425 426 *mGIFStruct.stackp++ = mGIFStruct.suffix[code]; 427 code = mGIFStruct.prefix[code]; 428 429 if (mGIFStruct.stackp >= mGIFStruct.stack + MAX_BITS) { 430 // Stack overflow; something's wrong. 431 return std::make_tuple(written, Some(WriteState::FAILURE)); 432 } 433 } 434 435 *mGIFStruct.stackp++ = mGIFStruct.firstchar = mGIFStruct.suffix[code]; 436 437 // Define a new codeword in the dictionary. 438 if (mGIFStruct.avail < 4096) { 439 mGIFStruct.prefix[mGIFStruct.avail] = mGIFStruct.oldcode; 440 mGIFStruct.suffix[mGIFStruct.avail] = mGIFStruct.firstchar; 441 mGIFStruct.avail++; 442 443 // If we've used up all the codewords of a given length increase the 444 // length of codewords by one bit, but don't exceed the specified 445 // maximum codeword size of 12 bits. 446 if (((mGIFStruct.avail & mGIFStruct.codemask) == 0) && 447 (mGIFStruct.avail < 4096)) { 448 mGIFStruct.codesize++; 449 mGIFStruct.codemask += mGIFStruct.avail; 450 } 451 } 452 453 mGIFStruct.oldcode = incode; 454 } 455 456 if (MOZ_UNLIKELY(mGIFStruct.stackp <= mGIFStruct.stack)) { 457 MOZ_ASSERT_UNREACHABLE("No decoded data but we didn't return early?"); 458 return std::make_tuple(written, Some(WriteState::FAILURE)); 459 } 460 461 // Yield a pixel at the appropriate index in the colormap. 462 mGIFStruct.pixels_remaining--; 463 aPixelBlock[written++] = 464 ColormapIndexToPixel<PixelSize>(*--mGIFStruct.stackp); 465 } 466 467 return std::make_tuple(written, Maybe<WriteState>()); 468 } 469 470 /// Expand the colormap from RGB to Packed ARGB as needed by Cairo. 471 /// And apply any LCMS transformation. 472 void nsGIFDecoder2::ConvertColormap(uint32_t* aColormap, uint32_t aColors) { 473 // If we are just counting frames for a metadata decode, there is no need to 474 // prep the colormap. 475 if (!aColors || WantsFrameCount()) { 476 return; 477 } 478 479 // Apply CMS transformation if enabled and available 480 if (mCMSMode == CMSMode::All) { 481 qcms_transform* transform = GetCMSsRGBTransform(SurfaceFormat::R8G8B8); 482 if (transform) { 483 qcms_transform_data(transform, aColormap, aColormap, aColors); 484 } 485 } 486 487 // Expand color table from RGB to BGRA. 488 MOZ_ASSERT(mSwizzleFn); 489 uint8_t* data = reinterpret_cast<uint8_t*>(aColormap); 490 mSwizzleFn(data, data, aColors); 491 } 492 493 LexerResult nsGIFDecoder2::DoDecode(SourceBufferIterator& aIterator, 494 IResumable* aOnResume) { 495 MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!"); 496 497 return mLexer.Lex( 498 aIterator, aOnResume, 499 [=](State aState, const char* aData, size_t aLength) { 500 switch (aState) { 501 case State::GIF_HEADER: 502 return ReadGIFHeader(aData); 503 case State::SCREEN_DESCRIPTOR: 504 return ReadScreenDescriptor(aData); 505 case State::GLOBAL_COLOR_TABLE: 506 return ReadGlobalColorTable(aData, aLength); 507 case State::FINISHED_GLOBAL_COLOR_TABLE: 508 return FinishedGlobalColorTable(); 509 case State::BLOCK_HEADER: 510 return ReadBlockHeader(aData); 511 case State::EXTENSION_HEADER: 512 return ReadExtensionHeader(aData); 513 case State::GRAPHIC_CONTROL_EXTENSION: 514 return ReadGraphicControlExtension(aData); 515 case State::APPLICATION_IDENTIFIER: 516 return ReadApplicationIdentifier(aData); 517 case State::NETSCAPE_EXTENSION_SUB_BLOCK: 518 return ReadNetscapeExtensionSubBlock(aData); 519 case State::NETSCAPE_EXTENSION_DATA: 520 return ReadNetscapeExtensionData(aData); 521 case State::IMAGE_DESCRIPTOR: 522 return ReadImageDescriptor(aData); 523 case State::LOCAL_COLOR_TABLE: 524 return ReadLocalColorTable(aData, aLength); 525 case State::FINISHED_LOCAL_COLOR_TABLE: 526 return FinishedLocalColorTable(); 527 case State::IMAGE_DATA_BLOCK: 528 return ReadImageDataBlock(aData); 529 case State::IMAGE_DATA_SUB_BLOCK: 530 return ReadImageDataSubBlock(aData); 531 case State::LZW_DATA: 532 return ReadLZWData(aData, aLength); 533 case State::SKIP_LZW_DATA: 534 return Transition::ContinueUnbuffered(State::SKIP_LZW_DATA); 535 case State::FINISHED_LZW_DATA: 536 return Transition::To(State::IMAGE_DATA_SUB_BLOCK, 537 SUB_BLOCK_HEADER_LEN); 538 case State::FINISH_END_IMAGE_FRAME: 539 return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN); 540 case State::SKIP_SUB_BLOCKS: 541 return SkipSubBlocks(aData); 542 case State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS: 543 return Transition::ContinueUnbuffered( 544 State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS); 545 case State::FINISHED_SKIPPING_DATA: 546 return Transition::To(State::SKIP_SUB_BLOCKS, SUB_BLOCK_HEADER_LEN); 547 default: 548 MOZ_CRASH("Unknown State"); 549 } 550 }); 551 } 552 553 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadGIFHeader( 554 const char* aData) { 555 // We retrieve the version here but because many GIF encoders set header 556 // fields incorrectly, we barely use it; features which should only appear in 557 // GIF89a are always accepted. 558 if (strncmp(aData, "GIF87a", GIF_HEADER_LEN) == 0) { 559 mGIFStruct.version = 87; 560 } else if (strncmp(aData, "GIF89a", GIF_HEADER_LEN) == 0) { 561 mGIFStruct.version = 89; 562 } else { 563 return Transition::TerminateFailure(); 564 } 565 566 return Transition::To(State::SCREEN_DESCRIPTOR, GIF_SCREEN_DESCRIPTOR_LEN); 567 } 568 569 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadScreenDescriptor( 570 const char* aData) { 571 mGIFStruct.screen_width = LittleEndian::readUint16(aData + 0); 572 mGIFStruct.screen_height = LittleEndian::readUint16(aData + 2); 573 574 const uint8_t packedFields = aData[4]; 575 576 // XXX: Should we be capturing these values even if there is no global color 577 // table? 578 mGIFStruct.global_colormap_depth = 579 (packedFields & PACKED_FIELDS_TABLE_DEPTH_MASK) + 1; 580 mGIFStruct.global_colormap_count = 1 << mGIFStruct.global_colormap_depth; 581 582 // We ignore several fields in the header. We don't care about the 'sort 583 // flag', which indicates if the global color table's entries are sorted in 584 // order of importance - if we need to render this image for a device with a 585 // narrower color gamut than GIF supports we'll handle that at a different 586 // layer. We have no use for the pixel aspect ratio as well. Finally, we 587 // intentionally ignore the background color index, as implementing that 588 // feature would not be web compatible - when a GIF image frame doesn't cover 589 // the entire area of the image, the area that's not covered should always be 590 // transparent. 591 592 if (packedFields & PACKED_FIELDS_COLOR_TABLE_BIT) { 593 MOZ_ASSERT(mColorTablePos == 0); 594 595 // We read the global color table in unbuffered mode since it can be quite 596 // large and it'd be preferable to avoid unnecessary copies. 597 const size_t globalColorTableSize = 3 * mGIFStruct.global_colormap_count; 598 return Transition::ToUnbuffered(State::FINISHED_GLOBAL_COLOR_TABLE, 599 State::GLOBAL_COLOR_TABLE, 600 globalColorTableSize); 601 } 602 603 return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN); 604 } 605 606 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadGlobalColorTable( 607 const char* aData, size_t aLength) { 608 uint8_t* dest = 609 reinterpret_cast<uint8_t*>(mGIFStruct.global_colormap) + mColorTablePos; 610 memcpy(dest, aData, aLength); 611 mColorTablePos += aLength; 612 return Transition::ContinueUnbuffered(State::GLOBAL_COLOR_TABLE); 613 } 614 615 LexerTransition<nsGIFDecoder2::State> 616 nsGIFDecoder2::FinishedGlobalColorTable() { 617 ConvertColormap(mGIFStruct.global_colormap, mGIFStruct.global_colormap_count); 618 mColorTablePos = 0; 619 return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN); 620 } 621 622 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadBlockHeader( 623 const char* aData) { 624 // Determine what type of block we're dealing with. 625 switch (aData[0]) { 626 case GIF_EXTENSION_INTRODUCER: 627 return Transition::To(State::EXTENSION_HEADER, EXTENSION_HEADER_LEN); 628 629 case GIF_IMAGE_SEPARATOR: 630 return Transition::To(State::IMAGE_DESCRIPTOR, IMAGE_DESCRIPTOR_LEN); 631 632 case GIF_TRAILER: 633 FinishInternal(); 634 return Transition::TerminateSuccess(); 635 636 default: 637 // If we get anything other than GIF_IMAGE_SEPARATOR, 638 // GIF_EXTENSION_INTRODUCER, or GIF_TRAILER, there is extraneous data 639 // between blocks. The GIF87a spec tells us to keep reading until we find 640 // an image separator, but GIF89a says such a file is corrupt. We follow 641 // GIF89a and bail out. 642 643 if (mGIFStruct.images_decoded > 0) { 644 // The file is corrupt, but we successfully decoded some frames, so we 645 // may as well consider the decode successful and display them. 646 FinishInternal(); 647 return Transition::TerminateSuccess(); 648 } 649 650 // No images decoded; there is nothing to display. 651 return Transition::TerminateFailure(); 652 } 653 } 654 655 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadExtensionHeader( 656 const char* aData) { 657 const uint8_t label = aData[0]; 658 const uint8_t extensionHeaderLength = aData[1]; 659 660 // If the extension header is zero length, just treat it as a block terminator 661 // and move on to the next block immediately. 662 if (extensionHeaderLength == 0) { 663 return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN); 664 } 665 666 switch (label) { 667 case GIF_GRAPHIC_CONTROL_LABEL: 668 // The GIF spec mandates that the Control Extension header block length is 669 // 4 bytes, and the parser for this block reads 4 bytes, so we must 670 // enforce that the buffer contains at least this many bytes. If the GIF 671 // specifies a different length, we allow that, so long as it's larger; 672 // the additional data will simply be ignored. 673 return Transition::To( 674 State::GRAPHIC_CONTROL_EXTENSION, 675 max<uint8_t>(extensionHeaderLength, GRAPHIC_CONTROL_EXTENSION_LEN)); 676 677 case GIF_APPLICATION_EXTENSION_LABEL: 678 // Again, the spec specifies that an application extension header is 11 679 // bytes, but for compatibility with GIFs in the wild, we allow deviation 680 // from the spec. This is important for real-world compatibility, as GIFs 681 // in the wild exist with application extension headers that are both 682 // shorter and longer than 11 bytes. However, we only try to actually 683 // interpret the application extension if the length is correct; 684 // otherwise, we just skip the block unconditionally. 685 return extensionHeaderLength == APPLICATION_EXTENSION_LEN 686 ? Transition::To(State::APPLICATION_IDENTIFIER, 687 extensionHeaderLength) 688 : Transition::ToUnbuffered( 689 State::FINISHED_SKIPPING_DATA, 690 State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS, 691 extensionHeaderLength); 692 693 default: 694 // Skip over any other type of extension block, including comment and 695 // plain text blocks. 696 return Transition::ToUnbuffered(State::FINISHED_SKIPPING_DATA, 697 State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS, 698 extensionHeaderLength); 699 } 700 } 701 702 LexerTransition<nsGIFDecoder2::State> 703 nsGIFDecoder2::ReadGraphicControlExtension(const char* aData) { 704 mGIFStruct.is_transparent = aData[0] & 0x1; 705 mGIFStruct.tpixel = uint8_t(aData[3]); 706 mGIFStruct.disposal_method = (aData[0] >> 2) & 0x7; 707 708 if (mGIFStruct.disposal_method == 4) { 709 // Some encoders (and apparently some specs) represent 710 // DisposalMethod::RESTORE_PREVIOUS as 4, but 3 is used in the canonical 711 // spec and is more popular, so we normalize to 3. 712 mGIFStruct.disposal_method = 3; 713 } else if (mGIFStruct.disposal_method > 4) { 714 // This GIF is using a disposal method which is undefined in the spec. 715 // Treat it as DisposalMethod::NOT_SPECIFIED. 716 mGIFStruct.disposal_method = 0; 717 } 718 719 DisposalMethod method = DisposalMethod(mGIFStruct.disposal_method); 720 if (method == DisposalMethod::CLEAR_ALL || method == DisposalMethod::CLEAR) { 721 // We may have to display the background under this image during animation 722 // playback, so we regard it as transparent. 723 PostHasTransparency(); 724 } 725 726 mGIFStruct.delay_time = LittleEndian::readUint16(aData + 1) * 10; 727 if (!HasAnimation() && mGIFStruct.delay_time > 0) { 728 PostIsAnimated(FrameTimeout::FromRawMilliseconds(mGIFStruct.delay_time)); 729 } 730 731 return Transition::To(State::SKIP_SUB_BLOCKS, SUB_BLOCK_HEADER_LEN); 732 } 733 734 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadApplicationIdentifier( 735 const char* aData) { 736 if ((strncmp(aData, "NETSCAPE2.0", 11) == 0) || 737 (strncmp(aData, "ANIMEXTS1.0", 11) == 0)) { 738 // This is a Netscape application extension block. 739 return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK, 740 SUB_BLOCK_HEADER_LEN); 741 } 742 743 // This is an application extension we don't care about. Just skip it. 744 return Transition::To(State::SKIP_SUB_BLOCKS, SUB_BLOCK_HEADER_LEN); 745 } 746 747 LexerTransition<nsGIFDecoder2::State> 748 nsGIFDecoder2::ReadNetscapeExtensionSubBlock(const char* aData) { 749 const uint8_t blockLength = aData[0]; 750 if (blockLength == 0) { 751 // We hit the block terminator. 752 return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN); 753 } 754 755 // We consume a minimum of 3 bytes in accordance with the specs for the 756 // Netscape application extension block, such as they are. 757 const size_t extensionLength = max<uint8_t>(blockLength, 3); 758 return Transition::To(State::NETSCAPE_EXTENSION_DATA, extensionLength); 759 } 760 761 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadNetscapeExtensionData( 762 const char* aData) { 763 // Documentation for NETSCAPE2.0 / ANIMEXTS1.0 extensions can be found at: 764 // https://wiki.whatwg.org/wiki/GIF 765 static const uint8_t NETSCAPE_LOOPING_EXTENSION_SUB_BLOCK_ID = 1; 766 static const uint8_t NETSCAPE_BUFFERING_EXTENSION_SUB_BLOCK_ID = 2; 767 768 const uint8_t subBlockID = aData[0] & 7; 769 switch (subBlockID) { 770 case NETSCAPE_LOOPING_EXTENSION_SUB_BLOCK_ID: 771 // This is looping extension. 772 mGIFStruct.loop_count = LittleEndian::readUint16(aData + 1); 773 // Zero loop count is infinite animation loop request. 774 if (mGIFStruct.loop_count == 0) { 775 mGIFStruct.loop_count = -1; 776 } 777 778 return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK, 779 SUB_BLOCK_HEADER_LEN); 780 781 case NETSCAPE_BUFFERING_EXTENSION_SUB_BLOCK_ID: 782 // We allow, but ignore, this extension. 783 return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK, 784 SUB_BLOCK_HEADER_LEN); 785 786 default: 787 return Transition::TerminateFailure(); 788 } 789 } 790 791 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadImageDescriptor( 792 const char* aData) { 793 // On the first frame, we don't need to yield, and none of the other checks 794 // below apply, so we can just jump right into FinishImageDescriptor(). 795 if (mGIFStruct.images_decoded == 0) { 796 return FinishImageDescriptor(aData); 797 } 798 799 if (!HasAnimation()) { 800 // We should've already called PostIsAnimated(); this must be a corrupt 801 // animated image with a first frame timeout of zero. Signal that we're 802 // animated now, before the first-frame decode early exit below, so that 803 // RasterImage can detect that this happened. 804 PostIsAnimated(FrameTimeout::FromRawMilliseconds(0)); 805 } 806 807 if (IsFirstFrameDecode()) { 808 // We're about to get a second frame, but we only want the first. Stop 809 // decoding now. 810 FinishInternal(); 811 return Transition::TerminateSuccess(); 812 } 813 814 MOZ_ASSERT(Size() == OutputSize(), "Downscaling an animated image?"); 815 return FinishImageDescriptor(aData); 816 } 817 818 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::FinishImageDescriptor( 819 const char* aData) { 820 OrientedIntRect frameRect; 821 822 // Get image offsets with respect to the screen origin. 823 frameRect.SetRect( 824 LittleEndian::readUint16(aData + 0), LittleEndian::readUint16(aData + 2), 825 LittleEndian::readUint16(aData + 4), LittleEndian::readUint16(aData + 6)); 826 827 if (!mGIFStruct.images_decoded) { 828 // Work around GIF files where 829 // * at least one of the logical screen dimensions is smaller than the 830 // same dimension in the first image, or 831 // * GIF87a files where the first image's dimensions do not match the 832 // logical screen dimensions. 833 if (mGIFStruct.screen_height < frameRect.Height() || 834 mGIFStruct.screen_width < frameRect.Width() || 835 mGIFStruct.version == 87) { 836 mGIFStruct.screen_height = frameRect.Height(); 837 mGIFStruct.screen_width = frameRect.Width(); 838 frameRect.MoveTo(0, 0); 839 } 840 841 // Create the image container with the right size. 842 BeginGIF(); 843 if (HasError()) { 844 // Setting the size led to an error. 845 return Transition::TerminateFailure(); 846 } 847 848 // If we're doing a metadata decode without the frame count, we're done. 849 if (IsMetadataDecode() && !WantsFrameCount()) { 850 CheckForTransparency(frameRect); 851 FinishInternal(); 852 return Transition::TerminateSuccess(); 853 } 854 } 855 856 // Work around broken GIF files that have zero frame width or height; in this 857 // case, we'll treat the frame as having the same size as the overall image. 858 if (frameRect.Height() == 0 || frameRect.Width() == 0) { 859 frameRect.SetHeight(mGIFStruct.screen_height); 860 frameRect.SetWidth(mGIFStruct.screen_width); 861 862 // If that still resulted in zero frame width or height, give up. 863 if (frameRect.Height() == 0 || frameRect.Width() == 0) { 864 return Transition::TerminateFailure(); 865 } 866 } 867 868 // Determine |depth| (log base 2 of the number of colors in the palette). 869 bool haveLocalColorTable = false; 870 uint16_t depth = 0; 871 uint8_t packedFields = aData[8]; 872 873 if (packedFields & PACKED_FIELDS_COLOR_TABLE_BIT) { 874 // Get the palette depth from the local color table. 875 depth = (packedFields & PACKED_FIELDS_TABLE_DEPTH_MASK) + 1; 876 haveLocalColorTable = true; 877 } else { 878 // Get the palette depth from the global color table. 879 depth = mGIFStruct.global_colormap_depth; 880 } 881 882 // If the transparent color index is greater than the number of colors in the 883 // color table, we may need a higher color depth than |depth| would specify. 884 // Our internal representation of the image will instead use |realDepth|, 885 // which is the smallest color depth that can accommodate the existing palette 886 // *and* the transparent color index. 887 uint16_t realDepth = depth; 888 while (mGIFStruct.tpixel >= (1 << realDepth) && realDepth < 8) { 889 realDepth++; 890 } 891 892 // Create a mask used to ensure that color values fit within the colormap. 893 mColorMask = 0xFF >> (8 - realDepth); 894 895 // Determine if this frame is interlaced or not. 896 const bool isInterlaced = packedFields & PACKED_FIELDS_INTERLACED_BIT; 897 898 // Create the SurfacePipe we'll use to write output for this frame. 899 if (NS_FAILED(BeginImageFrame(frameRect, realDepth, isInterlaced))) { 900 return Transition::TerminateFailure(); 901 } 902 903 // Clear state from last image. 904 mGIFStruct.pixels_remaining = 905 int64_t(frameRect.Width()) * int64_t(frameRect.Height()); 906 907 if (haveLocalColorTable) { 908 // We have a local color table, so prepare to read it into the palette of 909 // the current frame. 910 mGIFStruct.local_colormap_size = 1 << depth; 911 912 if (!mColormap) { 913 // Ensure our current colormap buffer is large enough to hold the new one. 914 mColormapSize = sizeof(uint32_t) << realDepth; 915 if (mGIFStruct.local_colormap_buffer_size < mColormapSize) { 916 if (mGIFStruct.local_colormap) { 917 free(mGIFStruct.local_colormap); 918 } 919 mGIFStruct.local_colormap_buffer_size = mColormapSize; 920 mGIFStruct.local_colormap = 921 static_cast<uint32_t*>(moz_xmalloc(mColormapSize)); 922 // Ensure the local colormap is initialized as opaque. 923 memset(mGIFStruct.local_colormap, 0xFF, mColormapSize); 924 } else { 925 mColormapSize = mGIFStruct.local_colormap_buffer_size; 926 } 927 928 mColormap = mGIFStruct.local_colormap; 929 } 930 931 MOZ_ASSERT(mColormap); 932 933 const size_t size = 3 << depth; 934 if (mColormapSize > size) { 935 // Clear the part of the colormap which will be unused with this palette. 936 // If a GIF references an invalid palette entry, ensure the entry is 937 // opaque white. This is needed for Skia as if it isn't, RGBX surfaces 938 // will cause blending issues with Skia. 939 memset(reinterpret_cast<uint8_t*>(mColormap) + size, 0xFF, 940 mColormapSize - size); 941 } 942 943 MOZ_ASSERT(mColorTablePos == 0); 944 945 // We read the local color table in unbuffered mode since it can be quite 946 // large and it'd be preferable to avoid unnecessary copies. 947 return Transition::ToUnbuffered(State::FINISHED_LOCAL_COLOR_TABLE, 948 State::LOCAL_COLOR_TABLE, size); 949 } 950 951 // There's no local color table; copy the global color table into the palette 952 // of the current frame. 953 if (mColormap) { 954 memcpy(mColormap, mGIFStruct.global_colormap, mColormapSize); 955 } else { 956 mColormap = mGIFStruct.global_colormap; 957 } 958 959 return Transition::To(State::IMAGE_DATA_BLOCK, BLOCK_HEADER_LEN); 960 } 961 962 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadLocalColorTable( 963 const char* aData, size_t aLength) { 964 // If we are just counting frames for a metadata decode, there is no need to 965 // prep the colormap. 966 if (!WantsFrameCount()) { 967 uint8_t* dest = reinterpret_cast<uint8_t*>(mColormap) + mColorTablePos; 968 memcpy(dest, aData, aLength); 969 mColorTablePos += aLength; 970 } 971 return Transition::ContinueUnbuffered(State::LOCAL_COLOR_TABLE); 972 } 973 974 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::FinishedLocalColorTable() { 975 ConvertColormap(mColormap, mGIFStruct.local_colormap_size); 976 mColorTablePos = 0; 977 return Transition::To(State::IMAGE_DATA_BLOCK, BLOCK_HEADER_LEN); 978 } 979 980 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadImageDataBlock( 981 const char* aData) { 982 // Make sure the transparent pixel is transparent in the colormap. 983 if (mGIFStruct.is_transparent) { 984 // Save the old value so we can restore it later. 985 if (mColormap == mGIFStruct.global_colormap) { 986 mOldColor = mColormap[mGIFStruct.tpixel]; 987 } 988 mColormap[mGIFStruct.tpixel] = 0; 989 } 990 991 // Initialize the LZW decoder. 992 mGIFStruct.datasize = uint8_t(aData[0]); 993 if (mGIFStruct.datasize > MAX_LZW_BITS) { 994 return Transition::TerminateFailure(); 995 } 996 const int clearCode = ClearCode(); 997 if (clearCode >= MAX_BITS) { 998 return Transition::TerminateFailure(); 999 } 1000 1001 mGIFStruct.avail = clearCode + 2; 1002 mGIFStruct.oldcode = -1; 1003 mGIFStruct.codesize = mGIFStruct.datasize + 1; 1004 mGIFStruct.codemask = (1 << mGIFStruct.codesize) - 1; 1005 mGIFStruct.datum = mGIFStruct.bits = 0; 1006 1007 // Initialize the tables. 1008 for (int i = 0; i < clearCode; i++) { 1009 mGIFStruct.suffix[i] = i; 1010 } 1011 1012 mGIFStruct.stackp = mGIFStruct.stack; 1013 1014 // Begin reading image data sub-blocks. 1015 return Transition::To(State::IMAGE_DATA_SUB_BLOCK, SUB_BLOCK_HEADER_LEN); 1016 } 1017 1018 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadImageDataSubBlock( 1019 const char* aData) { 1020 const uint8_t subBlockLength = aData[0]; 1021 if (subBlockLength == 0) { 1022 // We hit the block terminator. Yield if we are decoding multiple frames. 1023 EndImageFrame(); 1024 if (IsFirstFrameDecode()) { 1025 return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN); 1026 } 1027 return Transition::ToAfterYield(State::FINISH_END_IMAGE_FRAME); 1028 } 1029 1030 if (mGIFStruct.pixels_remaining == 0) { 1031 // We've already written to the entire image; we should've hit the block 1032 // terminator at this point. This image is corrupt, but we'll tolerate it. 1033 1034 if (subBlockLength == GIF_TRAILER) { 1035 // This GIF is missing the block terminator for the final block; we'll put 1036 // up with it. 1037 FinishInternal(); 1038 return Transition::TerminateSuccess(); 1039 } 1040 1041 // We're not at the end of the image, so just skip the extra data. 1042 return Transition::ToUnbuffered(State::FINISHED_LZW_DATA, 1043 State::SKIP_LZW_DATA, subBlockLength); 1044 } 1045 1046 // Handle the standard case: there's data in the sub-block and pixels left to 1047 // fill in the image. We read the sub-block unbuffered so we can get pixels on 1048 // the screen as soon as possible. 1049 return Transition::ToUnbuffered(State::FINISHED_LZW_DATA, State::LZW_DATA, 1050 subBlockLength); 1051 } 1052 1053 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::ReadLZWData( 1054 const char* aData, size_t aLength) { 1055 // If we are just counting frames for a metadata decode, there is no need to 1056 // do the actual decode. 1057 if (WantsFrameCount()) { 1058 return Transition::ContinueUnbuffered(State::LZW_DATA); 1059 } 1060 1061 const uint8_t* data = reinterpret_cast<const uint8_t*>(aData); 1062 size_t length = aLength; 1063 1064 while (mGIFStruct.pixels_remaining > 0 && 1065 (length > 0 || mGIFStruct.bits >= mGIFStruct.codesize)) { 1066 size_t bytesRead = 0; 1067 1068 auto result = mPipe.WritePixelBlocks<uint32_t>( 1069 [&](uint32_t* aPixelBlock, int32_t aBlockSize) { 1070 return YieldPixels<uint32_t>(data, length, &bytesRead, aPixelBlock, 1071 aBlockSize); 1072 }); 1073 1074 if (MOZ_UNLIKELY(bytesRead > length)) { 1075 MOZ_ASSERT_UNREACHABLE("Overread?"); 1076 bytesRead = length; 1077 } 1078 1079 // Advance our position in the input based upon what YieldPixel() consumed. 1080 data += bytesRead; 1081 length -= bytesRead; 1082 1083 switch (result) { 1084 case WriteState::NEED_MORE_DATA: 1085 continue; 1086 1087 case WriteState::FINISHED: 1088 NS_WARNING_ASSERTION(mGIFStruct.pixels_remaining <= 0, 1089 "too many pixels"); 1090 mGIFStruct.pixels_remaining = 0; 1091 break; 1092 1093 case WriteState::FAILURE: 1094 if (mGIFStruct.images_decoded > 0) { 1095 return Transition::TerminateSuccess(); 1096 } 1097 return Transition::TerminateFailure(); 1098 } 1099 } 1100 1101 // We're done, but keep going until we consume all the data in the sub-block. 1102 return Transition::ContinueUnbuffered(State::LZW_DATA); 1103 } 1104 1105 LexerTransition<nsGIFDecoder2::State> nsGIFDecoder2::SkipSubBlocks( 1106 const char* aData) { 1107 // In the SKIP_SUB_BLOCKS state we skip over data sub-blocks that we're not 1108 // interested in. Blocks consist of a block header (which can be up to 255 1109 // bytes in length) and a series of data sub-blocks. Each data sub-block 1110 // consists of a single byte length value, followed by the data itself. A data 1111 // sub-block with a length of zero terminates the overall block. 1112 // SKIP_SUB_BLOCKS reads a sub-block length value. If it's zero, we've arrived 1113 // at the next block. Otherwise, we enter the SKIP_DATA_THEN_SKIP_SUB_BLOCKS 1114 // state to skip over the sub-block data and return to SKIP_SUB_BLOCKS at the 1115 // start of the next sub-block. 1116 1117 const uint8_t nextSubBlockLength = aData[0]; 1118 if (nextSubBlockLength == 0) { 1119 // We hit the block terminator, so the sequence of data sub-blocks is over; 1120 // begin processing another block. 1121 return Transition::To(State::BLOCK_HEADER, BLOCK_HEADER_LEN); 1122 } 1123 1124 // Skip to the next sub-block length value. 1125 return Transition::ToUnbuffered(State::FINISHED_SKIPPING_DATA, 1126 State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS, 1127 nextSubBlockLength); 1128 } 1129 1130 Maybe<glean::impl::MemoryDistributionMetric> nsGIFDecoder2::SpeedMetric() 1131 const { 1132 return Some(glean::image_decode::speed_gif); 1133 } 1134 1135 } // namespace image 1136 } // namespace mozilla