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