nsGIFDecoder2.h 5.2 KB

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