Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/image/decoders/nsGIFDecoder2.h
Line
Count
Source (jump to first uncovered line)
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
#ifndef mozilla_image_decoders_nsGIFDecoder2_h
8
#define mozilla_image_decoders_nsGIFDecoder2_h
9
10
#include "Decoder.h"
11
#include "GIF2.h"
12
#include "StreamingLexer.h"
13
#include "SurfacePipe.h"
14
15
namespace mozilla {
16
namespace image {
17
class RasterImage;
18
19
//////////////////////////////////////////////////////////////////////
20
// nsGIFDecoder2 Definition
21
22
class nsGIFDecoder2 : public Decoder
23
{
24
public:
25
  ~nsGIFDecoder2();
26
27
0
  DecoderType GetType() const override { return DecoderType::GIF; }
28
29
protected:
30
  LexerResult DoDecode(SourceBufferIterator& aIterator,
31
                       IResumable* aOnResume) override;
32
  nsresult FinishInternal() override;
33
34
  Maybe<Telemetry::HistogramID> SpeedHistogram() const override;
35
36
private:
37
  friend class DecoderFactory;
38
39
  // Decoders should only be instantiated via DecoderFactory.
40
  explicit nsGIFDecoder2(RasterImage* aImage);
41
42
  /// Called when we begin decoding the image.
43
  void      BeginGIF();
44
45
  /**
46
   * Called when we begin decoding a frame.
47
   *
48
   * @param aFrameRect The region of the image that contains data. The region
49
   *                   outside this rect is transparent.
50
   * @param aDepth The palette depth of this frame.
51
   * @param aIsInterlaced If true, this frame is an interlaced frame.
52
   */
53
  nsresult  BeginImageFrame(const gfx::IntRect& aFrameRect,
54
                            uint16_t aDepth,
55
                            bool aIsInterlaced);
56
57
  /// Called when we finish decoding a frame.
58
  void      EndImageFrame();
59
60
  /// Called when we finish decoding the entire image.
61
  void      FlushImageData();
62
63
  /// Transforms a palette index into a pixel.
64
  template <typename PixelSize> PixelSize
65
  ColormapIndexToPixel(uint8_t aIndex);
66
67
  /// A generator function that performs LZW decompression and yields pixels.
68
  template <typename PixelSize> Tuple<int32_t, Maybe<WriteState>>
69
  YieldPixels(const uint8_t* aData,
70
              size_t aLength,
71
              size_t* aBytesReadOut,
72
              PixelSize* aPixelBlock,
73
              int32_t aBlockSize);
74
75
  /// Checks if we have transparency, either because the header indicates that
76
  /// there's alpha, or because the frame rect doesn't cover the entire image.
77
  bool CheckForTransparency(const gfx::IntRect& aFrameRect);
78
79
  // @return the clear code used for LZW decompression.
80
0
  int ClearCode() const {
81
0
    MOZ_ASSERT(mGIFStruct.datasize <= MAX_LZW_BITS);
82
0
    return 1 << mGIFStruct.datasize;
83
0
  }
84
85
  enum class State
86
  {
87
    FAILURE,
88
    SUCCESS,
89
    GIF_HEADER,
90
    SCREEN_DESCRIPTOR,
91
    GLOBAL_COLOR_TABLE,
92
    FINISHED_GLOBAL_COLOR_TABLE,
93
    BLOCK_HEADER,
94
    EXTENSION_HEADER,
95
    GRAPHIC_CONTROL_EXTENSION,
96
    APPLICATION_IDENTIFIER,
97
    NETSCAPE_EXTENSION_SUB_BLOCK,
98
    NETSCAPE_EXTENSION_DATA,
99
    IMAGE_DESCRIPTOR,
100
    FINISH_IMAGE_DESCRIPTOR,
101
    LOCAL_COLOR_TABLE,
102
    FINISHED_LOCAL_COLOR_TABLE,
103
    IMAGE_DATA_BLOCK,
104
    IMAGE_DATA_SUB_BLOCK,
105
    LZW_DATA,
106
    SKIP_LZW_DATA,
107
    FINISHED_LZW_DATA,
108
    SKIP_SUB_BLOCKS,
109
    SKIP_DATA_THEN_SKIP_SUB_BLOCKS,
110
    FINISHED_SKIPPING_DATA
111
  };
112
113
  LexerTransition<State> ReadGIFHeader(const char* aData);
114
  LexerTransition<State> ReadScreenDescriptor(const char* aData);
115
  LexerTransition<State> ReadGlobalColorTable(const char* aData, size_t aLength);
116
  LexerTransition<State> FinishedGlobalColorTable();
117
  LexerTransition<State> ReadBlockHeader(const char* aData);
118
  LexerTransition<State> ReadExtensionHeader(const char* aData);
119
  LexerTransition<State> ReadGraphicControlExtension(const char* aData);
120
  LexerTransition<State> ReadApplicationIdentifier(const char* aData);
121
  LexerTransition<State> ReadNetscapeExtensionSubBlock(const char* aData);
122
  LexerTransition<State> ReadNetscapeExtensionData(const char* aData);
123
  LexerTransition<State> ReadImageDescriptor(const char* aData);
124
  LexerTransition<State> FinishImageDescriptor(const char* aData);
125
  LexerTransition<State> ReadLocalColorTable(const char* aData, size_t aLength);
126
  LexerTransition<State> FinishedLocalColorTable();
127
  LexerTransition<State> ReadImageDataBlock(const char* aData);
128
  LexerTransition<State> ReadImageDataSubBlock(const char* aData);
129
  LexerTransition<State> ReadLZWData(const char* aData, size_t aLength);
130
  LexerTransition<State> SkipSubBlocks(const char* aData);
131
132
  // The StreamingLexer used to manage input. The initial size of the buffer is
133
  // chosen as a little larger than the maximum size of any fixed-length data we
134
  // have to read for a state. We read variable-length data in unbuffered mode
135
  // so the buffer shouldn't have to be resized during decoding.
136
  StreamingLexer<State, 16> mLexer;
137
138
  uint32_t mOldColor;        // The old value of the transparent pixel
139
140
  // The frame number of the currently-decoding frame when we're in the middle
141
  // of decoding it, and -1 otherwise.
142
  int32_t mCurrentFrameIndex;
143
144
  // When we're reading in the global or local color table, this records our
145
  // current position - i.e., the offset into which the next byte should be
146
  // written.
147
  size_t mColorTablePos;
148
149
  uint8_t mColorMask;        // Apply this to the pixel to keep within colormap
150
  bool mGIFOpen;
151
  bool mSawTransparency;
152
153
  gif_struct mGIFStruct;
154
155
  SurfacePipe mPipe;  /// The SurfacePipe used to write to the output surface.
156
};
157
158
} // namespace image
159
} // namespace mozilla
160
161
#endif // mozilla_image_decoders_nsGIFDecoder2_h