1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
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.
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
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."
27 For further information, please contact :
29 CompuServe Incorporated
30 Graphics Technology Department
31 5000 Arlington Center Boulevard
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
41 #include "nsGIFDecoder2.h"
46 #include "mozilla/EndianUtils.h"
47 #include "RasterImage.h"
48 #include "SurfacePipeFactory.h"
51 #include "gfxPlatform.h"
54 #include "mozilla/Telemetry.h"
56 using namespace mozilla::gfx
;
63 //////////////////////////////////////////////////////////////////////
64 // GIF Decoder Implementation
66 static const size_t GIF_HEADER_LEN
= 6;
67 static const size_t GIF_SCREEN_DESCRIPTOR_LEN
= 7;
68 static const size_t BLOCK_HEADER_LEN
= 1;
69 static const size_t SUB_BLOCK_HEADER_LEN
= 1;
70 static const size_t EXTENSION_HEADER_LEN
= 2;
71 static const size_t GRAPHIC_CONTROL_EXTENSION_LEN
= 4;
72 static const size_t APPLICATION_EXTENSION_LEN
= 11;
73 static const size_t IMAGE_DESCRIPTOR_LEN
= 9;
75 // Masks for reading color table information from packed fields in the screen
76 // descriptor and image descriptor blocks.
77 static const uint8_t PACKED_FIELDS_COLOR_TABLE_BIT
= 0x80;
78 static const uint8_t PACKED_FIELDS_INTERLACED_BIT
= 0x40;
79 static const uint8_t PACKED_FIELDS_TABLE_DEPTH_MASK
= 0x07;
81 nsGIFDecoder2::nsGIFDecoder2(RasterImage
* aImage
)
83 mLexer(Transition::To(State::GIF_HEADER
, GIF_HEADER_LEN
),
84 Transition::TerminateSuccess()),
86 mCurrentFrameIndex(-1),
92 mSawTransparency(false),
94 // Clear out the structure, excluding the arrays. Ensure that the global
95 // colormap is initialized as opaque.
96 memset(&mGIFStruct
, 0, sizeof(mGIFStruct
));
97 memset(mGIFStruct
.global_colormap
, 0xFF, sizeof(mGIFStruct
.global_colormap
));
99 // Each color table will need to be unpacked.
100 mSwizzleFn
= SwizzleRow(SurfaceFormat::R8G8B8
, SurfaceFormat::OS_RGBA
);
101 MOZ_ASSERT(mSwizzleFn
);
104 nsGIFDecoder2::~nsGIFDecoder2() { free(mGIFStruct
.local_colormap
); }
106 nsresult
nsGIFDecoder2::FinishWithErrorInternal() {
108 if (WantsFrameCount()) {
109 PostFrameCount(mGIFStruct
.images_decoded
);
111 PostLoopCount(mGIFStruct
.loop_count
);
115 return Decoder::FinishWithErrorInternal();
118 nsresult
nsGIFDecoder2::FinishInternal() {
119 MOZ_ASSERT(!HasError(), "Shouldn't call FinishInternal after error!");
125 PostLoopCount(mGIFStruct
.loop_count
);
127 // If the GIF got cut off, handle it anyway
128 if (mCurrentFrameIndex
== mGIFStruct
.images_decoded
) {
132 if (WantsFrameCount()) {
133 PostFrameCount(mGIFStruct
.images_decoded
);
136 if (!IsMetadataDecode()) {
144 void nsGIFDecoder2::FlushImageData() {
145 Maybe
<SurfaceInvalidRect
> invalidRect
= mPipe
.TakeInvalidRect();
150 PostInvalidation(invalidRect
->mInputSpaceRect
,
151 Some(invalidRect
->mOutputSpaceRect
));
154 //******************************************************************************
155 // GIF decoder callback methods. Part of public API for GIF2
156 //******************************************************************************
158 //******************************************************************************
159 void nsGIFDecoder2::BeginGIF() {
166 PostSize(mGIFStruct
.screen_width
, mGIFStruct
.screen_height
);
169 bool nsGIFDecoder2::CheckForTransparency(const OrientedIntRect
& aFrameRect
) {
170 // Check if the image has a transparent color in its palette.
171 if (mGIFStruct
.is_transparent
) {
172 PostHasTransparency();
176 // This is a bit of a hack. Some sites will use a 1x1 gif that includes no
177 // header information indicating it is transparent, no palette, and no image
178 // data at all (so no pixels get written) to represent a transparent pixel
179 // using the absolute least number of bytes. Generally things are setup to
180 // detect transparency without decoding the image data. So to detect this kind
181 // of transparency without decoing the image data we would have to assume
182 // every gif is transparent, which we would like to avoid. Changing things so
183 // that we can detect transparency at any point of decoding is a bigger change
184 // and not worth it for one questionable 1x1 gif. Using this "trick" for
185 // anything but 1x1 transparent spacer gifs doesn't make sense, so it's
186 // reasonable to target 1x1 gifs just for this.
187 if (mGIFStruct
.screen_width
== 1 && mGIFStruct
.screen_height
== 1) {
188 PostHasTransparency();
192 if (mGIFStruct
.images_decoded
> 0) {
193 return false; // We only care about first frame padding below.
196 // If we need padding on the first frame, that means we don't draw into part
197 // of the image at all. Report that as transparency.
198 OrientedIntRect
imageRect(0, 0, mGIFStruct
.screen_width
,
199 mGIFStruct
.screen_height
);
200 if (!imageRect
.IsEqualEdges(aFrameRect
)) {
201 PostHasTransparency();
202 mSawTransparency
= true; // Make sure we don't optimize it away.
209 //******************************************************************************
210 nsresult
nsGIFDecoder2::BeginImageFrame(const OrientedIntRect
& aFrameRect
,
211 uint16_t aDepth
, bool aIsInterlaced
) {
212 MOZ_ASSERT(HasSize());
214 // If we are just counting frames for a metadata decode, there is no actual
215 // decoding done. We are just iterating over the blocks to find when a frame
217 if (WantsFrameCount()) {
218 mCurrentFrameIndex
= mGIFStruct
.images_decoded
;
222 bool hasTransparency
= CheckForTransparency(aFrameRect
);
224 // Make sure there's no animation if we're downscaling.
225 MOZ_ASSERT_IF(Size() != OutputSize(), !GetImageMetadata().HasAnimation());
227 Maybe
<AnimationParams
> animParams
;
228 if (!IsFirstFrameDecode()) {
229 animParams
.emplace(aFrameRect
.ToUnknownRect(),
230 FrameTimeout::FromRawMilliseconds(mGIFStruct
.delay_time
),
231 uint32_t(mGIFStruct
.images_decoded
), BlendMethod::OVER
,
232 DisposalMethod(mGIFStruct
.disposal_method
));
235 SurfacePipeFlags pipeFlags
=
236 aIsInterlaced
? SurfacePipeFlags::DEINTERLACE
: SurfacePipeFlags();
238 gfx::SurfaceFormat format
;
239 if (mGIFStruct
.images_decoded
== 0) {
240 // The first frame may be displayed progressively.
241 pipeFlags
|= SurfacePipeFlags::PROGRESSIVE_DISPLAY
;
243 // Only allow opaque surfaces if we are decoding a single image without
244 // transparency. For an animation, there isn't much benefit to RGBX given
245 // the current frame is constantly changing, and there are many risks
246 // since BlendAnimationFilter is able to clear rows of data.
247 format
= hasTransparency
|| animParams
? SurfaceFormat::OS_RGBA
248 : SurfaceFormat::OS_RGBX
;
250 format
= SurfaceFormat::OS_RGBA
;
253 Maybe
<SurfacePipe
> pipe
= SurfacePipeFactory::CreateSurfacePipe(
254 this, Size(), OutputSize(), aFrameRect
, format
, format
, animParams
,
255 mTransform
, pipeFlags
);
256 mCurrentFrameIndex
= mGIFStruct
.images_decoded
;
259 mPipe
= SurfacePipe();
260 return NS_ERROR_FAILURE
;
263 mPipe
= std::move(*pipe
);
267 //******************************************************************************
268 void nsGIFDecoder2::EndImageFrame() {
269 if (WantsFrameCount()) {
270 mGIFStruct
.pixels_remaining
= 0;
271 mGIFStruct
.images_decoded
++;
272 mGIFStruct
.delay_time
= 0;
275 mCurrentFrameIndex
= -1;
277 // Keep updating the count every time we find a frame.
278 PostFrameCount(mGIFStruct
.images_decoded
);
282 Opacity opacity
= Opacity::SOME_TRANSPARENCY
;
284 if (mGIFStruct
.images_decoded
== 0) {
285 // We need to send invalidations for the first frame.
288 // The first frame was preallocated with alpha; if it wasn't transparent, we
289 // should fix that. We can also mark it opaque unconditionally if we didn't
290 // actually see any transparent pixels - this test is only valid for the
292 if (!mGIFStruct
.is_transparent
&& !mSawTransparency
) {
293 opacity
= Opacity::FULLY_OPAQUE
;
297 // Unconditionally increment images_decoded, because we unconditionally
298 // append frames in BeginImageFrame(). This ensures that images_decoded
299 // always refers to the frame in mImage we're currently decoding,
300 // even if some of them weren't decoded properly and thus are blank.
301 mGIFStruct
.images_decoded
++;
303 // Reset graphic control extension parameters that we shouldn't reuse
305 mGIFStruct
.delay_time
= 0;
307 // Tell the superclass we finished a frame
308 PostFrameStop(opacity
);
310 // Reset the transparent pixel
312 mColormap
[mGIFStruct
.tpixel
] = mOldColor
;
318 mCurrentFrameIndex
= -1;
321 template <typename PixelSize
>
322 PixelSize
nsGIFDecoder2::ColormapIndexToPixel(uint8_t aIndex
) {
323 MOZ_ASSERT(sizeof(PixelSize
) == sizeof(uint32_t));
325 // Retrieve the next color, clamping to the size of the colormap.
326 uint32_t color
= mColormap
[aIndex
& mColorMask
];
328 // Check for transparency.
329 if (mGIFStruct
.is_transparent
) {
330 mSawTransparency
= mSawTransparency
|| color
== 0;
337 uint8_t nsGIFDecoder2::ColormapIndexToPixel
<uint8_t>(uint8_t aIndex
) {
338 return aIndex
& mColorMask
;
341 template <typename PixelSize
>
342 std::tuple
<int32_t, Maybe
<WriteState
>> nsGIFDecoder2::YieldPixels(
343 const uint8_t* aData
, size_t aLength
, size_t* aBytesReadOut
,
344 PixelSize
* aPixelBlock
, int32_t aBlockSize
) {
346 MOZ_ASSERT(aBytesReadOut
);
347 MOZ_ASSERT(mGIFStruct
.stackp
>= mGIFStruct
.stack
);
349 // Advance to the next byte we should read.
350 const uint8_t* data
= aData
+ *aBytesReadOut
;
353 while (aBlockSize
> written
) {
354 // If we don't have any decoded data to yield, try to read some input and
356 if (mGIFStruct
.stackp
== mGIFStruct
.stack
) {
357 while (mGIFStruct
.bits
< mGIFStruct
.codesize
&&
358 *aBytesReadOut
< aLength
) {
359 // Feed the next byte into the decoder's 32-bit input buffer.
360 mGIFStruct
.datum
+= int32_t(*data
) << mGIFStruct
.bits
;
361 mGIFStruct
.bits
+= 8;
366 if (mGIFStruct
.bits
< mGIFStruct
.codesize
) {
367 return std::make_tuple(written
, Some(WriteState::NEED_MORE_DATA
));
370 // Get the leading variable-length symbol from the data stream.
371 int code
= mGIFStruct
.datum
& mGIFStruct
.codemask
;
372 mGIFStruct
.datum
>>= mGIFStruct
.codesize
;
373 mGIFStruct
.bits
-= mGIFStruct
.codesize
;
375 const int clearCode
= ClearCode();
377 // Reset the dictionary to its original state, if requested
378 if (code
== clearCode
) {
379 mGIFStruct
.codesize
= mGIFStruct
.datasize
+ 1;
380 mGIFStruct
.codemask
= (1 << mGIFStruct
.codesize
) - 1;
381 mGIFStruct
.avail
= clearCode
+ 2;
382 mGIFStruct
.oldcode
= -1;
383 return std::make_tuple(written
, Some(WriteState::NEED_MORE_DATA
));
386 // Check for explicit end-of-stream code. It should only appear after all
387 // image data, but if that was the case we wouldn't be in this function,
388 // so this is always an error condition.
389 if (code
== (clearCode
+ 1)) {
390 return std::make_tuple(written
, Some(WriteState::FAILURE
));
393 if (mGIFStruct
.oldcode
== -1) {
394 if (code
>= MAX_BITS
) {
395 // The code's too big; something's wrong.
396 return std::make_tuple(written
, Some(WriteState::FAILURE
));
399 mGIFStruct
.firstchar
= mGIFStruct
.oldcode
= code
;
401 // Yield a pixel at the appropriate index in the colormap.
402 mGIFStruct
.pixels_remaining
--;
403 aPixelBlock
[written
++] =
404 ColormapIndexToPixel
<PixelSize
>(mGIFStruct
.suffix
[code
]);
409 if (code
>= mGIFStruct
.avail
) {
410 *mGIFStruct
.stackp
++ = mGIFStruct
.firstchar
;
411 code
= mGIFStruct
.oldcode
;
413 if (mGIFStruct
.stackp
>= mGIFStruct
.stack
+ MAX_BITS
) {
414 // Stack overflow; something's wrong.
415 return std::make_tuple(written
, Some(WriteState::FAILURE
));
419 while (code
>= clearCode
) {
420 if ((code
>= MAX_BITS
) || (code
== mGIFStruct
.prefix
[code
])) {
421 return std::make_tuple(written
, Some(WriteState::FAILURE
));
424 *mGIFStruct
.stackp
++ = mGIFStruct
.suffix
[code
];
425 code
= mGIFStruct
.prefix
[code
];
427 if (mGIFStruct
.stackp
>= mGIFStruct
.stack
+ MAX_BITS
) {
428 // Stack overflow; something's wrong.
429 return std::make_tuple(written
, Some(WriteState::FAILURE
));
433 *mGIFStruct
.stackp
++ = mGIFStruct
.firstchar
= mGIFStruct
.suffix
[code
];
435 // Define a new codeword in the dictionary.
436 if (mGIFStruct
.avail
< 4096) {
437 mGIFStruct
.prefix
[mGIFStruct
.avail
] = mGIFStruct
.oldcode
;
438 mGIFStruct
.suffix
[mGIFStruct
.avail
] = mGIFStruct
.firstchar
;
441 // If we've used up all the codewords of a given length increase the
442 // length of codewords by one bit, but don't exceed the specified
443 // maximum codeword size of 12 bits.
444 if (((mGIFStruct
.avail
& mGIFStruct
.codemask
) == 0) &&
445 (mGIFStruct
.avail
< 4096)) {
446 mGIFStruct
.codesize
++;
447 mGIFStruct
.codemask
+= mGIFStruct
.avail
;
451 mGIFStruct
.oldcode
= incode
;
454 if (MOZ_UNLIKELY(mGIFStruct
.stackp
<= mGIFStruct
.stack
)) {
455 MOZ_ASSERT_UNREACHABLE("No decoded data but we didn't return early?");
456 return std::make_tuple(written
, Some(WriteState::FAILURE
));
459 // Yield a pixel at the appropriate index in the colormap.
460 mGIFStruct
.pixels_remaining
--;
461 aPixelBlock
[written
++] =
462 ColormapIndexToPixel
<PixelSize
>(*--mGIFStruct
.stackp
);
465 return std::make_tuple(written
, Maybe
<WriteState
>());
468 /// Expand the colormap from RGB to Packed ARGB as needed by Cairo.
469 /// And apply any LCMS transformation.
470 void nsGIFDecoder2::ConvertColormap(uint32_t* aColormap
, uint32_t aColors
) {
471 // If we are just counting frames for a metadata decode, there is no need to
472 // prep the colormap.
473 if (!aColors
|| WantsFrameCount()) {
477 // Apply CMS transformation if enabled and available
478 if (mCMSMode
== CMSMode::All
) {
479 qcms_transform
* transform
= GetCMSsRGBTransform(SurfaceFormat::R8G8B8
);
481 qcms_transform_data(transform
, aColormap
, aColormap
, aColors
);
485 // Expand color table from RGB to BGRA.
486 MOZ_ASSERT(mSwizzleFn
);
487 uint8_t* data
= reinterpret_cast<uint8_t*>(aColormap
);
488 mSwizzleFn(data
, data
, aColors
);
491 LexerResult
nsGIFDecoder2::DoDecode(SourceBufferIterator
& aIterator
,
492 IResumable
* aOnResume
) {
493 MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
496 aIterator
, aOnResume
,
497 [=](State aState
, const char* aData
, size_t aLength
) {
499 case State::GIF_HEADER
:
500 return ReadGIFHeader(aData
);
501 case State::SCREEN_DESCRIPTOR
:
502 return ReadScreenDescriptor(aData
);
503 case State::GLOBAL_COLOR_TABLE
:
504 return ReadGlobalColorTable(aData
, aLength
);
505 case State::FINISHED_GLOBAL_COLOR_TABLE
:
506 return FinishedGlobalColorTable();
507 case State::BLOCK_HEADER
:
508 return ReadBlockHeader(aData
);
509 case State::EXTENSION_HEADER
:
510 return ReadExtensionHeader(aData
);
511 case State::GRAPHIC_CONTROL_EXTENSION
:
512 return ReadGraphicControlExtension(aData
);
513 case State::APPLICATION_IDENTIFIER
:
514 return ReadApplicationIdentifier(aData
);
515 case State::NETSCAPE_EXTENSION_SUB_BLOCK
:
516 return ReadNetscapeExtensionSubBlock(aData
);
517 case State::NETSCAPE_EXTENSION_DATA
:
518 return ReadNetscapeExtensionData(aData
);
519 case State::IMAGE_DESCRIPTOR
:
520 return ReadImageDescriptor(aData
);
521 case State::LOCAL_COLOR_TABLE
:
522 return ReadLocalColorTable(aData
, aLength
);
523 case State::FINISHED_LOCAL_COLOR_TABLE
:
524 return FinishedLocalColorTable();
525 case State::IMAGE_DATA_BLOCK
:
526 return ReadImageDataBlock(aData
);
527 case State::IMAGE_DATA_SUB_BLOCK
:
528 return ReadImageDataSubBlock(aData
);
529 case State::LZW_DATA
:
530 return ReadLZWData(aData
, aLength
);
531 case State::SKIP_LZW_DATA
:
532 return Transition::ContinueUnbuffered(State::SKIP_LZW_DATA
);
533 case State::FINISHED_LZW_DATA
:
534 return Transition::To(State::IMAGE_DATA_SUB_BLOCK
,
535 SUB_BLOCK_HEADER_LEN
);
536 case State::FINISH_END_IMAGE_FRAME
:
537 return Transition::To(State::BLOCK_HEADER
, BLOCK_HEADER_LEN
);
538 case State::SKIP_SUB_BLOCKS
:
539 return SkipSubBlocks(aData
);
540 case State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS
:
541 return Transition::ContinueUnbuffered(
542 State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS
);
543 case State::FINISHED_SKIPPING_DATA
:
544 return Transition::To(State::SKIP_SUB_BLOCKS
, SUB_BLOCK_HEADER_LEN
);
546 MOZ_CRASH("Unknown State");
551 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadGIFHeader(
553 // We retrieve the version here but because many GIF encoders set header
554 // fields incorrectly, we barely use it; features which should only appear in
555 // GIF89a are always accepted.
556 if (strncmp(aData
, "GIF87a", GIF_HEADER_LEN
) == 0) {
557 mGIFStruct
.version
= 87;
558 } else if (strncmp(aData
, "GIF89a", GIF_HEADER_LEN
) == 0) {
559 mGIFStruct
.version
= 89;
561 return Transition::TerminateFailure();
564 return Transition::To(State::SCREEN_DESCRIPTOR
, GIF_SCREEN_DESCRIPTOR_LEN
);
567 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadScreenDescriptor(
569 mGIFStruct
.screen_width
= LittleEndian::readUint16(aData
+ 0);
570 mGIFStruct
.screen_height
= LittleEndian::readUint16(aData
+ 2);
572 const uint8_t packedFields
= aData
[4];
574 // XXX: Should we be capturing these values even if there is no global color
576 mGIFStruct
.global_colormap_depth
=
577 (packedFields
& PACKED_FIELDS_TABLE_DEPTH_MASK
) + 1;
578 mGIFStruct
.global_colormap_count
= 1 << mGIFStruct
.global_colormap_depth
;
580 // We ignore several fields in the header. We don't care about the 'sort
581 // flag', which indicates if the global color table's entries are sorted in
582 // order of importance - if we need to render this image for a device with a
583 // narrower color gamut than GIF supports we'll handle that at a different
584 // layer. We have no use for the pixel aspect ratio as well. Finally, we
585 // intentionally ignore the background color index, as implementing that
586 // feature would not be web compatible - when a GIF image frame doesn't cover
587 // the entire area of the image, the area that's not covered should always be
590 if (packedFields
& PACKED_FIELDS_COLOR_TABLE_BIT
) {
591 MOZ_ASSERT(mColorTablePos
== 0);
593 // We read the global color table in unbuffered mode since it can be quite
594 // large and it'd be preferable to avoid unnecessary copies.
595 const size_t globalColorTableSize
= 3 * mGIFStruct
.global_colormap_count
;
596 return Transition::ToUnbuffered(State::FINISHED_GLOBAL_COLOR_TABLE
,
597 State::GLOBAL_COLOR_TABLE
,
598 globalColorTableSize
);
601 return Transition::To(State::BLOCK_HEADER
, BLOCK_HEADER_LEN
);
604 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadGlobalColorTable(
605 const char* aData
, size_t aLength
) {
607 reinterpret_cast<uint8_t*>(mGIFStruct
.global_colormap
) + mColorTablePos
;
608 memcpy(dest
, aData
, aLength
);
609 mColorTablePos
+= aLength
;
610 return Transition::ContinueUnbuffered(State::GLOBAL_COLOR_TABLE
);
613 LexerTransition
<nsGIFDecoder2::State
>
614 nsGIFDecoder2::FinishedGlobalColorTable() {
615 ConvertColormap(mGIFStruct
.global_colormap
, mGIFStruct
.global_colormap_count
);
617 return Transition::To(State::BLOCK_HEADER
, BLOCK_HEADER_LEN
);
620 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadBlockHeader(
622 // Determine what type of block we're dealing with.
624 case GIF_EXTENSION_INTRODUCER
:
625 return Transition::To(State::EXTENSION_HEADER
, EXTENSION_HEADER_LEN
);
627 case GIF_IMAGE_SEPARATOR
:
628 return Transition::To(State::IMAGE_DESCRIPTOR
, IMAGE_DESCRIPTOR_LEN
);
632 return Transition::TerminateSuccess();
635 // If we get anything other than GIF_IMAGE_SEPARATOR,
636 // GIF_EXTENSION_INTRODUCER, or GIF_TRAILER, there is extraneous data
637 // between blocks. The GIF87a spec tells us to keep reading until we find
638 // an image separator, but GIF89a says such a file is corrupt. We follow
639 // GIF89a and bail out.
641 if (mGIFStruct
.images_decoded
> 0) {
642 // The file is corrupt, but we successfully decoded some frames, so we
643 // may as well consider the decode successful and display them.
645 return Transition::TerminateSuccess();
648 // No images decoded; there is nothing to display.
649 return Transition::TerminateFailure();
653 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadExtensionHeader(
655 const uint8_t label
= aData
[0];
656 const uint8_t extensionHeaderLength
= aData
[1];
658 // If the extension header is zero length, just treat it as a block terminator
659 // and move on to the next block immediately.
660 if (extensionHeaderLength
== 0) {
661 return Transition::To(State::BLOCK_HEADER
, BLOCK_HEADER_LEN
);
665 case GIF_GRAPHIC_CONTROL_LABEL
:
666 // The GIF spec mandates that the Control Extension header block length is
667 // 4 bytes, and the parser for this block reads 4 bytes, so we must
668 // enforce that the buffer contains at least this many bytes. If the GIF
669 // specifies a different length, we allow that, so long as it's larger;
670 // the additional data will simply be ignored.
671 return Transition::To(
672 State::GRAPHIC_CONTROL_EXTENSION
,
673 max
<uint8_t>(extensionHeaderLength
, GRAPHIC_CONTROL_EXTENSION_LEN
));
675 case GIF_APPLICATION_EXTENSION_LABEL
:
676 // Again, the spec specifies that an application extension header is 11
677 // bytes, but for compatibility with GIFs in the wild, we allow deviation
678 // from the spec. This is important for real-world compatibility, as GIFs
679 // in the wild exist with application extension headers that are both
680 // shorter and longer than 11 bytes. However, we only try to actually
681 // interpret the application extension if the length is correct;
682 // otherwise, we just skip the block unconditionally.
683 return extensionHeaderLength
== APPLICATION_EXTENSION_LEN
684 ? Transition::To(State::APPLICATION_IDENTIFIER
,
685 extensionHeaderLength
)
686 : Transition::ToUnbuffered(
687 State::FINISHED_SKIPPING_DATA
,
688 State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS
,
689 extensionHeaderLength
);
692 // Skip over any other type of extension block, including comment and
693 // plain text blocks.
694 return Transition::ToUnbuffered(State::FINISHED_SKIPPING_DATA
,
695 State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS
,
696 extensionHeaderLength
);
700 LexerTransition
<nsGIFDecoder2::State
>
701 nsGIFDecoder2::ReadGraphicControlExtension(const char* aData
) {
702 mGIFStruct
.is_transparent
= aData
[0] & 0x1;
703 mGIFStruct
.tpixel
= uint8_t(aData
[3]);
704 mGIFStruct
.disposal_method
= (aData
[0] >> 2) & 0x7;
706 if (mGIFStruct
.disposal_method
== 4) {
707 // Some encoders (and apparently some specs) represent
708 // DisposalMethod::RESTORE_PREVIOUS as 4, but 3 is used in the canonical
709 // spec and is more popular, so we normalize to 3.
710 mGIFStruct
.disposal_method
= 3;
711 } else if (mGIFStruct
.disposal_method
> 4) {
712 // This GIF is using a disposal method which is undefined in the spec.
713 // Treat it as DisposalMethod::NOT_SPECIFIED.
714 mGIFStruct
.disposal_method
= 0;
717 DisposalMethod method
= DisposalMethod(mGIFStruct
.disposal_method
);
718 if (method
== DisposalMethod::CLEAR_ALL
|| method
== DisposalMethod::CLEAR
) {
719 // We may have to display the background under this image during animation
720 // playback, so we regard it as transparent.
721 PostHasTransparency();
724 mGIFStruct
.delay_time
= LittleEndian::readUint16(aData
+ 1) * 10;
725 if (!HasAnimation() && mGIFStruct
.delay_time
> 0) {
726 PostIsAnimated(FrameTimeout::FromRawMilliseconds(mGIFStruct
.delay_time
));
729 return Transition::To(State::SKIP_SUB_BLOCKS
, SUB_BLOCK_HEADER_LEN
);
732 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadApplicationIdentifier(
734 if ((strncmp(aData
, "NETSCAPE2.0", 11) == 0) ||
735 (strncmp(aData
, "ANIMEXTS1.0", 11) == 0)) {
736 // This is a Netscape application extension block.
737 return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK
,
738 SUB_BLOCK_HEADER_LEN
);
741 // This is an application extension we don't care about. Just skip it.
742 return Transition::To(State::SKIP_SUB_BLOCKS
, SUB_BLOCK_HEADER_LEN
);
745 LexerTransition
<nsGIFDecoder2::State
>
746 nsGIFDecoder2::ReadNetscapeExtensionSubBlock(const char* aData
) {
747 const uint8_t blockLength
= aData
[0];
748 if (blockLength
== 0) {
749 // We hit the block terminator.
750 return Transition::To(State::BLOCK_HEADER
, BLOCK_HEADER_LEN
);
753 // We consume a minimum of 3 bytes in accordance with the specs for the
754 // Netscape application extension block, such as they are.
755 const size_t extensionLength
= max
<uint8_t>(blockLength
, 3);
756 return Transition::To(State::NETSCAPE_EXTENSION_DATA
, extensionLength
);
759 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadNetscapeExtensionData(
761 // Documentation for NETSCAPE2.0 / ANIMEXTS1.0 extensions can be found at:
762 // https://wiki.whatwg.org/wiki/GIF
763 static const uint8_t NETSCAPE_LOOPING_EXTENSION_SUB_BLOCK_ID
= 1;
764 static const uint8_t NETSCAPE_BUFFERING_EXTENSION_SUB_BLOCK_ID
= 2;
766 const uint8_t subBlockID
= aData
[0] & 7;
767 switch (subBlockID
) {
768 case NETSCAPE_LOOPING_EXTENSION_SUB_BLOCK_ID
:
769 // This is looping extension.
770 mGIFStruct
.loop_count
= LittleEndian::readUint16(aData
+ 1);
771 // Zero loop count is infinite animation loop request.
772 if (mGIFStruct
.loop_count
== 0) {
773 mGIFStruct
.loop_count
= -1;
776 return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK
,
777 SUB_BLOCK_HEADER_LEN
);
779 case NETSCAPE_BUFFERING_EXTENSION_SUB_BLOCK_ID
:
780 // We allow, but ignore, this extension.
781 return Transition::To(State::NETSCAPE_EXTENSION_SUB_BLOCK
,
782 SUB_BLOCK_HEADER_LEN
);
785 return Transition::TerminateFailure();
789 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadImageDescriptor(
791 // On the first frame, we don't need to yield, and none of the other checks
792 // below apply, so we can just jump right into FinishImageDescriptor().
793 if (mGIFStruct
.images_decoded
== 0) {
794 return FinishImageDescriptor(aData
);
797 if (!HasAnimation()) {
798 // We should've already called PostIsAnimated(); this must be a corrupt
799 // animated image with a first frame timeout of zero. Signal that we're
800 // animated now, before the first-frame decode early exit below, so that
801 // RasterImage can detect that this happened.
802 PostIsAnimated(FrameTimeout::FromRawMilliseconds(0));
805 if (IsFirstFrameDecode()) {
806 // We're about to get a second frame, but we only want the first. Stop
809 return Transition::TerminateSuccess();
812 MOZ_ASSERT(Size() == OutputSize(), "Downscaling an animated image?");
813 return FinishImageDescriptor(aData
);
816 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::FinishImageDescriptor(
818 OrientedIntRect frameRect
;
820 // Get image offsets with respect to the screen origin.
822 LittleEndian::readUint16(aData
+ 0), LittleEndian::readUint16(aData
+ 2),
823 LittleEndian::readUint16(aData
+ 4), LittleEndian::readUint16(aData
+ 6));
825 if (!mGIFStruct
.images_decoded
) {
826 // Work around GIF files where
827 // * at least one of the logical screen dimensions is smaller than the
828 // same dimension in the first image, or
829 // * GIF87a files where the first image's dimensions do not match the
830 // logical screen dimensions.
831 if (mGIFStruct
.screen_height
< frameRect
.Height() ||
832 mGIFStruct
.screen_width
< frameRect
.Width() ||
833 mGIFStruct
.version
== 87) {
834 mGIFStruct
.screen_height
= frameRect
.Height();
835 mGIFStruct
.screen_width
= frameRect
.Width();
836 frameRect
.MoveTo(0, 0);
839 // Create the image container with the right size.
842 // Setting the size led to an error.
843 return Transition::TerminateFailure();
846 // If we're doing a metadata decode without the frame count, we're done.
847 if (IsMetadataDecode() && !WantsFrameCount()) {
848 CheckForTransparency(frameRect
);
850 return Transition::TerminateSuccess();
854 // Work around broken GIF files that have zero frame width or height; in this
855 // case, we'll treat the frame as having the same size as the overall image.
856 if (frameRect
.Height() == 0 || frameRect
.Width() == 0) {
857 frameRect
.SetHeight(mGIFStruct
.screen_height
);
858 frameRect
.SetWidth(mGIFStruct
.screen_width
);
860 // If that still resulted in zero frame width or height, give up.
861 if (frameRect
.Height() == 0 || frameRect
.Width() == 0) {
862 return Transition::TerminateFailure();
866 // Determine |depth| (log base 2 of the number of colors in the palette).
867 bool haveLocalColorTable
= false;
869 uint8_t packedFields
= aData
[8];
871 if (packedFields
& PACKED_FIELDS_COLOR_TABLE_BIT
) {
872 // Get the palette depth from the local color table.
873 depth
= (packedFields
& PACKED_FIELDS_TABLE_DEPTH_MASK
) + 1;
874 haveLocalColorTable
= true;
876 // Get the palette depth from the global color table.
877 depth
= mGIFStruct
.global_colormap_depth
;
880 // If the transparent color index is greater than the number of colors in the
881 // color table, we may need a higher color depth than |depth| would specify.
882 // Our internal representation of the image will instead use |realDepth|,
883 // which is the smallest color depth that can accommodate the existing palette
884 // *and* the transparent color index.
885 uint16_t realDepth
= depth
;
886 while (mGIFStruct
.tpixel
>= (1 << realDepth
) && realDepth
< 8) {
890 // Create a mask used to ensure that color values fit within the colormap.
891 mColorMask
= 0xFF >> (8 - realDepth
);
893 // Determine if this frame is interlaced or not.
894 const bool isInterlaced
= packedFields
& PACKED_FIELDS_INTERLACED_BIT
;
896 // Create the SurfacePipe we'll use to write output for this frame.
897 if (NS_FAILED(BeginImageFrame(frameRect
, realDepth
, isInterlaced
))) {
898 return Transition::TerminateFailure();
901 // Clear state from last image.
902 mGIFStruct
.pixels_remaining
=
903 int64_t(frameRect
.Width()) * int64_t(frameRect
.Height());
905 if (haveLocalColorTable
) {
906 // We have a local color table, so prepare to read it into the palette of
907 // the current frame.
908 mGIFStruct
.local_colormap_size
= 1 << depth
;
911 // Ensure our current colormap buffer is large enough to hold the new one.
912 mColormapSize
= sizeof(uint32_t) << realDepth
;
913 if (mGIFStruct
.local_colormap_buffer_size
< mColormapSize
) {
914 if (mGIFStruct
.local_colormap
) {
915 free(mGIFStruct
.local_colormap
);
917 mGIFStruct
.local_colormap_buffer_size
= mColormapSize
;
918 mGIFStruct
.local_colormap
=
919 static_cast<uint32_t*>(moz_xmalloc(mColormapSize
));
920 // Ensure the local colormap is initialized as opaque.
921 memset(mGIFStruct
.local_colormap
, 0xFF, mColormapSize
);
923 mColormapSize
= mGIFStruct
.local_colormap_buffer_size
;
926 mColormap
= mGIFStruct
.local_colormap
;
929 MOZ_ASSERT(mColormap
);
931 const size_t size
= 3 << depth
;
932 if (mColormapSize
> size
) {
933 // Clear the part of the colormap which will be unused with this palette.
934 // If a GIF references an invalid palette entry, ensure the entry is
935 // opaque white. This is needed for Skia as if it isn't, RGBX surfaces
936 // will cause blending issues with Skia.
937 memset(reinterpret_cast<uint8_t*>(mColormap
) + size
, 0xFF,
938 mColormapSize
- size
);
941 MOZ_ASSERT(mColorTablePos
== 0);
943 // We read the local color table in unbuffered mode since it can be quite
944 // large and it'd be preferable to avoid unnecessary copies.
945 return Transition::ToUnbuffered(State::FINISHED_LOCAL_COLOR_TABLE
,
946 State::LOCAL_COLOR_TABLE
, size
);
949 // There's no local color table; copy the global color table into the palette
950 // of the current frame.
952 memcpy(mColormap
, mGIFStruct
.global_colormap
, mColormapSize
);
954 mColormap
= mGIFStruct
.global_colormap
;
957 return Transition::To(State::IMAGE_DATA_BLOCK
, BLOCK_HEADER_LEN
);
960 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadLocalColorTable(
961 const char* aData
, size_t aLength
) {
962 // If we are just counting frames for a metadata decode, there is no need to
963 // prep the colormap.
964 if (!WantsFrameCount()) {
965 uint8_t* dest
= reinterpret_cast<uint8_t*>(mColormap
) + mColorTablePos
;
966 memcpy(dest
, aData
, aLength
);
967 mColorTablePos
+= aLength
;
969 return Transition::ContinueUnbuffered(State::LOCAL_COLOR_TABLE
);
972 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::FinishedLocalColorTable() {
973 ConvertColormap(mColormap
, mGIFStruct
.local_colormap_size
);
975 return Transition::To(State::IMAGE_DATA_BLOCK
, BLOCK_HEADER_LEN
);
978 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadImageDataBlock(
980 // Make sure the transparent pixel is transparent in the colormap.
981 if (mGIFStruct
.is_transparent
) {
982 // Save the old value so we can restore it later.
983 if (mColormap
== mGIFStruct
.global_colormap
) {
984 mOldColor
= mColormap
[mGIFStruct
.tpixel
];
986 mColormap
[mGIFStruct
.tpixel
] = 0;
989 // Initialize the LZW decoder.
990 mGIFStruct
.datasize
= uint8_t(aData
[0]);
991 if (mGIFStruct
.datasize
> MAX_LZW_BITS
) {
992 return Transition::TerminateFailure();
994 const int clearCode
= ClearCode();
995 if (clearCode
>= MAX_BITS
) {
996 return Transition::TerminateFailure();
999 mGIFStruct
.avail
= clearCode
+ 2;
1000 mGIFStruct
.oldcode
= -1;
1001 mGIFStruct
.codesize
= mGIFStruct
.datasize
+ 1;
1002 mGIFStruct
.codemask
= (1 << mGIFStruct
.codesize
) - 1;
1003 mGIFStruct
.datum
= mGIFStruct
.bits
= 0;
1005 // Initialize the tables.
1006 for (int i
= 0; i
< clearCode
; i
++) {
1007 mGIFStruct
.suffix
[i
] = i
;
1010 mGIFStruct
.stackp
= mGIFStruct
.stack
;
1012 // Begin reading image data sub-blocks.
1013 return Transition::To(State::IMAGE_DATA_SUB_BLOCK
, SUB_BLOCK_HEADER_LEN
);
1016 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadImageDataSubBlock(
1017 const char* aData
) {
1018 const uint8_t subBlockLength
= aData
[0];
1019 if (subBlockLength
== 0) {
1020 // We hit the block terminator. Yield if we are decoding multiple frames.
1022 if (IsFirstFrameDecode()) {
1023 return Transition::To(State::BLOCK_HEADER
, BLOCK_HEADER_LEN
);
1025 return Transition::ToAfterYield(State::FINISH_END_IMAGE_FRAME
);
1028 if (mGIFStruct
.pixels_remaining
== 0) {
1029 // We've already written to the entire image; we should've hit the block
1030 // terminator at this point. This image is corrupt, but we'll tolerate it.
1032 if (subBlockLength
== GIF_TRAILER
) {
1033 // This GIF is missing the block terminator for the final block; we'll put
1036 return Transition::TerminateSuccess();
1039 // We're not at the end of the image, so just skip the extra data.
1040 return Transition::ToUnbuffered(State::FINISHED_LZW_DATA
,
1041 State::SKIP_LZW_DATA
, subBlockLength
);
1044 // Handle the standard case: there's data in the sub-block and pixels left to
1045 // fill in the image. We read the sub-block unbuffered so we can get pixels on
1046 // the screen as soon as possible.
1047 return Transition::ToUnbuffered(State::FINISHED_LZW_DATA
, State::LZW_DATA
,
1051 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::ReadLZWData(
1052 const char* aData
, size_t aLength
) {
1053 // If we are just counting frames for a metadata decode, there is no need to
1054 // do the actual decode.
1055 if (WantsFrameCount()) {
1056 return Transition::ContinueUnbuffered(State::LZW_DATA
);
1059 const uint8_t* data
= reinterpret_cast<const uint8_t*>(aData
);
1060 size_t length
= aLength
;
1062 while (mGIFStruct
.pixels_remaining
> 0 &&
1063 (length
> 0 || mGIFStruct
.bits
>= mGIFStruct
.codesize
)) {
1064 size_t bytesRead
= 0;
1066 auto result
= mPipe
.WritePixelBlocks
<uint32_t>(
1067 [&](uint32_t* aPixelBlock
, int32_t aBlockSize
) {
1068 return YieldPixels
<uint32_t>(data
, length
, &bytesRead
, aPixelBlock
,
1072 if (MOZ_UNLIKELY(bytesRead
> length
)) {
1073 MOZ_ASSERT_UNREACHABLE("Overread?");
1077 // Advance our position in the input based upon what YieldPixel() consumed.
1079 length
-= bytesRead
;
1082 case WriteState::NEED_MORE_DATA
:
1085 case WriteState::FINISHED
:
1086 NS_WARNING_ASSERTION(mGIFStruct
.pixels_remaining
<= 0,
1088 mGIFStruct
.pixels_remaining
= 0;
1091 case WriteState::FAILURE
:
1092 if (mGIFStruct
.images_decoded
> 0) {
1093 return Transition::TerminateSuccess();
1095 return Transition::TerminateFailure();
1099 // We're done, but keep going until we consume all the data in the sub-block.
1100 return Transition::ContinueUnbuffered(State::LZW_DATA
);
1103 LexerTransition
<nsGIFDecoder2::State
> nsGIFDecoder2::SkipSubBlocks(
1104 const char* aData
) {
1105 // In the SKIP_SUB_BLOCKS state we skip over data sub-blocks that we're not
1106 // interested in. Blocks consist of a block header (which can be up to 255
1107 // bytes in length) and a series of data sub-blocks. Each data sub-block
1108 // consists of a single byte length value, followed by the data itself. A data
1109 // sub-block with a length of zero terminates the overall block.
1110 // SKIP_SUB_BLOCKS reads a sub-block length value. If it's zero, we've arrived
1111 // at the next block. Otherwise, we enter the SKIP_DATA_THEN_SKIP_SUB_BLOCKS
1112 // state to skip over the sub-block data and return to SKIP_SUB_BLOCKS at the
1113 // start of the next sub-block.
1115 const uint8_t nextSubBlockLength
= aData
[0];
1116 if (nextSubBlockLength
== 0) {
1117 // We hit the block terminator, so the sequence of data sub-blocks is over;
1118 // begin processing another block.
1119 return Transition::To(State::BLOCK_HEADER
, BLOCK_HEADER_LEN
);
1122 // Skip to the next sub-block length value.
1123 return Transition::ToUnbuffered(State::FINISHED_SKIPPING_DATA
,
1124 State::SKIP_DATA_THEN_SKIP_SUB_BLOCKS
,
1125 nextSubBlockLength
);
1128 Maybe
<Telemetry::HistogramID
> nsGIFDecoder2::SpeedHistogram() const {
1129 return Some(Telemetry::IMAGE_DECODE_SPEED_GIF
);
1132 } // namespace image
1133 } // namespace mozilla