nsBMPDecoder.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_image_decoders_nsBMPDecoder_h
  6. #define mozilla_image_decoders_nsBMPDecoder_h
  7. #include "BMPHeaders.h"
  8. #include "Decoder.h"
  9. #include "gfxColor.h"
  10. #include "StreamingLexer.h"
  11. #include "mozilla/UniquePtr.h"
  12. namespace mozilla {
  13. namespace image {
  14. namespace bmp {
  15. /// This struct contains the fields from the file header and info header that
  16. /// we use during decoding. (Excluding bitfields fields, which are kept in
  17. /// BitFields.)
  18. struct Header {
  19. uint32_t mDataOffset; // Offset to raster data.
  20. uint32_t mBIHSize; // Header size.
  21. int32_t mWidth; // Image width.
  22. int32_t mHeight; // Image height.
  23. uint16_t mBpp; // Bits per pixel.
  24. uint32_t mCompression; // See struct Compression for valid values.
  25. uint32_t mImageSize; // (compressed) image size. Can be 0 if
  26. // mCompression==0.
  27. uint32_t mNumColors; // Used colors.
  28. Header()
  29. : mDataOffset(0)
  30. , mBIHSize(0)
  31. , mWidth(0)
  32. , mHeight(0)
  33. , mBpp(0)
  34. , mCompression(0)
  35. , mImageSize(0)
  36. , mNumColors(0)
  37. {}
  38. };
  39. /// An entry in the color table.
  40. struct ColorTableEntry {
  41. uint8_t mRed;
  42. uint8_t mGreen;
  43. uint8_t mBlue;
  44. };
  45. /// All the color-related bitfields for 16bpp and 32bpp images. We use this
  46. /// even for older format BMPs that don't have explicit bitfields.
  47. class BitFields {
  48. class Value {
  49. friend class BitFields;
  50. uint32_t mMask; // The mask for the value.
  51. uint8_t mRightShift; // The amount to right-shift after masking.
  52. uint8_t mBitWidth; // The width (in bits) of the value.
  53. /// Sets the mask (and thus the right-shift and bit-width as well).
  54. void Set(uint32_t aMask);
  55. public:
  56. Value()
  57. {
  58. mMask = 0;
  59. mRightShift = 0;
  60. mBitWidth = 0;
  61. }
  62. /// Returns true if this channel is used. Only used for alpha.
  63. bool IsPresent() const { return mMask != 0x0; }
  64. /// Extracts the single color value from the multi-color value.
  65. uint8_t Get(uint32_t aVal) const;
  66. /// Like Get(), but specially for alpha.
  67. uint8_t GetAlpha(uint32_t aVal, bool& aHasAlphaOut) const;
  68. /// Specialized versions of Get() for when the bit-width is 5 or 8.
  69. /// (They will assert if called and the bit-width is not 5 or 8.)
  70. uint8_t Get5(uint32_t aVal) const;
  71. uint8_t Get8(uint32_t aVal) const;
  72. };
  73. public:
  74. /// The individual color channels.
  75. Value mRed;
  76. Value mGreen;
  77. Value mBlue;
  78. Value mAlpha;
  79. /// Set bitfields to the standard 5-5-5 16bpp values.
  80. void SetR5G5B5();
  81. /// Set bitfields to the standard 8-8-8 32bpp values.
  82. void SetR8G8B8();
  83. /// Test if bitfields have the standard 5-5-5 16bpp values.
  84. bool IsR5G5B5() const;
  85. /// Test if bitfields have the standard 8-8-8 32bpp values.
  86. bool IsR8G8B8() const;
  87. /// Read the bitfields from a header. The reading of the alpha mask is
  88. /// optional.
  89. void ReadFromHeader(const char* aData, bool aReadAlpha);
  90. /// Length of the bitfields structure in the BMP file.
  91. static const size_t LENGTH = 12;
  92. };
  93. } // namespace bmp
  94. class RasterImage;
  95. /// Decoder for BMP-Files, as used by Windows and OS/2.
  96. class nsBMPDecoder : public Decoder
  97. {
  98. public:
  99. ~nsBMPDecoder();
  100. /// Obtains the internal output image buffer.
  101. uint32_t* GetImageData() { return reinterpret_cast<uint32_t*>(mImageData); }
  102. /// Obtains the length of the internal output image buffer.
  103. size_t GetImageDataLength() const { return mImageDataLength; }
  104. /// Obtains the size of the compressed image resource.
  105. int32_t GetCompressedImageSize() const;
  106. /// Mark this BMP as being within an ICO file. Only used for testing purposes
  107. /// because the ICO-specific constructor does this marking automatically.
  108. void SetIsWithinICO() { mIsWithinICO = true; }
  109. /// Did the BMP file have alpha data of any kind? (Only use this after the
  110. /// bitmap has been fully decoded.)
  111. bool HasTransparency() const { return mDoesHaveTransparency; }
  112. LexerResult DoDecode(SourceBufferIterator& aIterator,
  113. IResumable* aOnResume) override;
  114. nsresult BeforeFinishInternal() override;
  115. nsresult FinishInternal() override;
  116. private:
  117. friend class DecoderFactory;
  118. enum class State {
  119. FILE_HEADER,
  120. INFO_HEADER_SIZE,
  121. INFO_HEADER_REST,
  122. BITFIELDS,
  123. COLOR_TABLE,
  124. GAP,
  125. AFTER_GAP,
  126. PIXEL_ROW,
  127. RLE_SEGMENT,
  128. RLE_DELTA,
  129. RLE_ABSOLUTE
  130. };
  131. // This is the constructor used for normal and clipboard BMP images.
  132. explicit nsBMPDecoder(RasterImage* aImage, bool aForClipboard = false);
  133. // This is the constructor used for BMP resources in ICO images.
  134. nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset);
  135. // Helper constructor called by the other two.
  136. nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength, bool aForClipboard);
  137. int32_t AbsoluteHeight() const { return abs(mH.mHeight); }
  138. uint32_t* RowBuffer();
  139. void FinishRow();
  140. LexerTransition<State> ReadFileHeader(const char* aData, size_t aLength);
  141. LexerTransition<State> ReadInfoHeaderSize(const char* aData, size_t aLength);
  142. LexerTransition<State> ReadInfoHeaderRest(const char* aData, size_t aLength);
  143. LexerTransition<State> ReadBitfields(const char* aData, size_t aLength);
  144. LexerTransition<State> ReadColorTable(const char* aData, size_t aLength);
  145. LexerTransition<State> SkipGap();
  146. LexerTransition<State> AfterGap();
  147. LexerTransition<State> ReadPixelRow(const char* aData);
  148. LexerTransition<State> ReadRLESegment(const char* aData);
  149. LexerTransition<State> ReadRLEDelta(const char* aData);
  150. LexerTransition<State> ReadRLEAbsolute(const char* aData, size_t aLength);
  151. StreamingLexer<State> mLexer;
  152. bmp::Header mH;
  153. // If the BMP is within an ICO file our treatment of it differs slightly.
  154. bool mIsWithinICO;
  155. // If the BMP is decoded from the clipboard, we start with a data offset.
  156. bool mIsForClipboard;
  157. bmp::BitFields mBitFields;
  158. // Might the image have transparency? Determined from the headers during
  159. // metadata decode. (Does not guarantee the image actually has transparency.)
  160. bool mMayHaveTransparency;
  161. // Does the image have transparency? Determined during full decoding, so only
  162. // use this after that has been completed.
  163. bool mDoesHaveTransparency;
  164. uint32_t mNumColors; // The number of used colors, i.e. the number of
  165. // entries in mColors, if it's present.
  166. UniquePtr<bmp::ColorTableEntry[]> mColors; // The color table, if it's present.
  167. uint32_t mBytesPerColor; // 3 or 4, depending on the format
  168. // The number of bytes prior to the optional gap that have been read. This
  169. // is used to find the start of the pixel data.
  170. uint32_t mPreGapLength;
  171. uint32_t mPixelRowSize; // The number of bytes per pixel row.
  172. int32_t mCurrentRow; // Index of the row of the image that's currently
  173. // being decoded: [height,1].
  174. int32_t mCurrentPos; // Index into the current line. Used when
  175. // doing RLE decoding and when filling in pixels
  176. // for truncated files.
  177. // Only used in RLE_ABSOLUTE state: the number of pixels to read.
  178. uint32_t mAbsoluteModeNumPixels;
  179. };
  180. } // namespace image
  181. } // namespace mozilla
  182. #endif // mozilla_image_decoders_nsBMPDecoder_h