1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 // This is a cross-platform BMP Decoder, which should work everywhere,
8 // including big-endian machines like the PowerPC.
9 //
10 // BMP is a format that has been extended multiple times. To understand the
11 // decoder you need to understand this history. The summary of the history
12 // below was determined from the following documents.
13 //
14 // - http://www.fileformat.info/format/bmp/egff.htm
15 // - http://www.fileformat.info/format/os2bmp/egff.htm
16 // - http://fileformats.archiveteam.org/wiki/BMP
17 // - http://fileformats.archiveteam.org/wiki/OS/2_BMP
18 // - https://en.wikipedia.org/wiki/BMP_file_format
19 // - https://upload.wikimedia.org/wikipedia/commons/c/c4/BMPfileFormat.png
20 //
21 // WINDOWS VERSIONS OF THE BMP FORMAT
22 // ----------------------------------
23 // WinBMPv1.
24 // - This version is no longer used and can be ignored.
25 //
26 // WinBMPv2.
27 // - First is a 14 byte file header that includes: the magic number ("BM"),
28 //   file size, and offset to the pixel data (|mDataOffset|).
29 // - Next is a 12 byte info header which includes: the info header size
30 //   (mBIHSize), width, height, number of color planes, and bits-per-pixel
31 //   (|mBpp|) which must be 1, 4, 8 or 24.
32 // - Next is the semi-optional color table, which has length 2^|mBpp| and has 3
33 //   bytes per value (BGR). The color table is required if |mBpp| is 1, 4, or 8.
34 // - Next is an optional gap.
35 // - Next is the pixel data, which is pointed to by |mDataOffset|.
36 //
37 // WinBMPv3. This is the most widely used version.
38 // - It changed the info header to 40 bytes by taking the WinBMPv2 info
39 //   header, enlargening its width and height fields, and adding more fields
40 //   including: a compression type (|mCompression|) and number of colors
41 //   (|mNumColors|).
42 // - The semi-optional color table is now 4 bytes per value (BGR0), and its
43 //   length is |mNumColors|, or 2^|mBpp| if |mNumColors| is zero.
44 // - |mCompression| can be RGB (i.e. no compression), RLE4 (if |mBpp|==4) or
45 //   RLE8 (if |mBpp|==8) values.
46 //
47 // WinBMPv3-NT. A variant of WinBMPv3.
48 // - It did not change the info header layout from WinBMPv3.
49 // - |mBpp| can now be 16 or 32, in which case |mCompression| can be RGB or the
50 //   new BITFIELDS value; in the latter case an additional 12 bytes of color
51 //   bitfields follow the info header.
52 //
53 // WinBMPv4.
54 // - It extended the info header to 108 bytes, including the 12 bytes of color
55 //   mask data from WinBMPv3-NT, plus alpha mask data, and also color-space and
56 //   gamma correction fields.
57 //
58 // WinBMPv5.
59 // - It extended the info header to 124 bytes, adding color profile data.
60 // - It also added an optional color profile table after the pixel data (and
61 //   another optional gap).
62 //
63 // WinBMPv3-ICO. This is a variant of WinBMPv3.
64 // - It's the BMP format used for BMP images within ICO files.
65 // - The only difference with WinBMPv3 is that if an image is 32bpp and has no
66 //   compression, then instead of treating the pixel data as 0RGB it is treated
67 //   as ARGB, but only if one or more of the A values are non-zero.
68 //
69 // OS/2 VERSIONS OF THE BMP FORMAT
70 // -------------------------------
71 // OS2-BMPv1.
72 // - Almost identical to WinBMPv2; the differences are basically ignorable.
73 //
74 // OS2-BMPv2.
75 // - Similar to WinBMPv3.
76 // - The info header is 64 bytes but can be reduced to as little as 16; any
77 //   omitted fields are treated as zero. The first 40 bytes of these fields are
78 //   nearly identical to the WinBMPv3 info header; the remaining 24 bytes are
79 //   different.
80 // - Also adds compression types "Huffman 1D" and "RLE24", which we don't
81 //   support.
82 // - We treat OS2-BMPv2 files as if they are WinBMPv3 (i.e. ignore the extra 24
83 //   bytes in the info header), which in practice is good enough.
84 
85 #include "ImageLogging.h"
86 #include "nsBMPDecoder.h"
87 
88 #include <stdlib.h>
89 
90 #include "mozilla/Attributes.h"
91 #include "mozilla/EndianUtils.h"
92 #include "mozilla/Likely.h"
93 
94 #include "nsIInputStream.h"
95 #include "RasterImage.h"
96 #include <algorithm>
97 
98 using namespace mozilla::gfx;
99 
100 namespace mozilla {
101 namespace image {
102 namespace bmp {
103 
104 struct Compression {
105   enum {
106     RGB = 0,
107     RLE8 = 1,
108     RLE4 = 2,
109     BITFIELDS = 3
110   };
111 };
112 
113 // RLE escape codes and constants.
114 struct RLE {
115   enum {
116     ESCAPE = 0,
117     ESCAPE_EOL = 0,
118     ESCAPE_EOF = 1,
119     ESCAPE_DELTA = 2,
120 
121     SEGMENT_LENGTH = 2,
122     DELTA_LENGTH = 2
123   };
124 };
125 
126 } // namespace bmp
127 
128 using namespace bmp;
129 
130 /// Sets the pixel data in aDecoded to the given values.
131 /// @param aDecoded pointer to pixel to be set, will be incremented to point to
132 /// the next pixel.
133 static void
SetPixel(uint32_t * & aDecoded,uint8_t aRed,uint8_t aGreen,uint8_t aBlue,uint8_t aAlpha=0xFF)134 SetPixel(uint32_t*& aDecoded, uint8_t aRed, uint8_t aGreen,
135          uint8_t aBlue, uint8_t aAlpha = 0xFF)
136 {
137   *aDecoded++ = gfxPackedPixel(aAlpha, aRed, aGreen, aBlue);
138 }
139 
140 static void
SetPixel(uint32_t * & aDecoded,uint8_t idx,const UniquePtr<ColorTableEntry[]> & aColors)141 SetPixel(uint32_t*& aDecoded, uint8_t idx,
142          const UniquePtr<ColorTableEntry[]>& aColors)
143 {
144   SetPixel(aDecoded,
145            aColors[idx].mRed, aColors[idx].mGreen, aColors[idx].mBlue);
146 }
147 
148 /// Sets two (or one if aCount = 1) pixels
149 /// @param aDecoded where the data is stored. Will be moved 4 resp 8 bytes
150 /// depending on whether one or two pixels are written.
151 /// @param aData The values for the two pixels
152 /// @param aCount Current count. Is decremented by one or two.
153 static void
Set4BitPixel(uint32_t * & aDecoded,uint8_t aData,uint32_t & aCount,const UniquePtr<ColorTableEntry[]> & aColors)154 Set4BitPixel(uint32_t*& aDecoded, uint8_t aData, uint32_t& aCount,
155              const UniquePtr<ColorTableEntry[]>& aColors)
156 {
157   uint8_t idx = aData >> 4;
158   SetPixel(aDecoded, idx, aColors);
159   if (--aCount > 0) {
160     idx = aData & 0xF;
161     SetPixel(aDecoded, idx, aColors);
162     --aCount;
163   }
164 }
165 
166 static mozilla::LazyLogModule sBMPLog("BMPDecoder");
167 
168 // The length of the mBIHSize field in the info header.
169 static const uint32_t BIHSIZE_FIELD_LENGTH = 4;
170 
nsBMPDecoder(RasterImage * aImage,State aState,size_t aLength)171 nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, State aState, size_t aLength)
172   : Decoder(aImage)
173   , mLexer(Transition::To(aState, aLength), Transition::TerminateSuccess())
174   , mIsWithinICO(false)
175   , mMayHaveTransparency(false)
176   , mDoesHaveTransparency(false)
177   , mNumColors(0)
178   , mColors(nullptr)
179   , mBytesPerColor(0)
180   , mPreGapLength(0)
181   , mPixelRowSize(0)
182   , mCurrentRow(0)
183   , mCurrentPos(0)
184   , mAbsoluteModeNumPixels(0)
185 {
186 }
187 
188 // Constructor for normal BMP files.
nsBMPDecoder(RasterImage * aImage)189 nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
190   : nsBMPDecoder(aImage, State::FILE_HEADER, FILE_HEADER_LENGTH)
191 {
192 }
193 
194 // Constructor used for WinBMPv3-ICO files, which lack a file header.
nsBMPDecoder(RasterImage * aImage,uint32_t aDataOffset)195 nsBMPDecoder::nsBMPDecoder(RasterImage* aImage, uint32_t aDataOffset)
196   : nsBMPDecoder(aImage, State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH)
197 {
198   SetIsWithinICO();
199 
200   // Even though the file header isn't present in this case, the dataOffset
201   // field is set as if it is, and so we must increment mPreGapLength
202   // accordingly.
203   mPreGapLength += FILE_HEADER_LENGTH;
204 
205   // This is the one piece of data we normally get from a BMP file header, so
206   // it must be provided via an argument.
207   mH.mDataOffset = aDataOffset;
208 }
209 
~nsBMPDecoder()210 nsBMPDecoder::~nsBMPDecoder()
211 {
212 }
213 
214 // Obtains the size of the compressed image resource.
215 int32_t
GetCompressedImageSize() const216 nsBMPDecoder::GetCompressedImageSize() const
217 {
218   // In the RGB case mImageSize might not be set, so compute it manually.
219   MOZ_ASSERT(mPixelRowSize != 0);
220   return mH.mCompression == Compression::RGB
221        ? mPixelRowSize * AbsoluteHeight()
222        : mH.mImageSize;
223 }
224 
225 nsresult
BeforeFinishInternal()226 nsBMPDecoder::BeforeFinishInternal()
227 {
228   if (!IsMetadataDecode() && !mImageData) {
229     return NS_ERROR_FAILURE;  // No image; something went wrong.
230   }
231 
232   return NS_OK;
233 }
234 
235 nsresult
FinishInternal()236 nsBMPDecoder::FinishInternal()
237 {
238   // We shouldn't be called in error cases.
239   MOZ_ASSERT(!HasError(), "Can't call FinishInternal on error!");
240 
241   // We should never make multiple frames.
242   MOZ_ASSERT(GetFrameCount() <= 1, "Multiple BMP frames?");
243 
244   // Send notifications if appropriate.
245   if (!IsMetadataDecode() && HasSize()) {
246 
247     // We should have image data.
248     MOZ_ASSERT(mImageData);
249 
250     // If it was truncated, fill in the missing pixels as black.
251     while (mCurrentRow > 0) {
252       uint32_t* dst = RowBuffer();
253       while (mCurrentPos < mH.mWidth) {
254         SetPixel(dst, 0, 0, 0);
255         mCurrentPos++;
256       }
257       mCurrentPos = 0;
258       FinishRow();
259     }
260 
261     // Invalidate.
262     nsIntRect r(0, 0, mH.mWidth, AbsoluteHeight());
263     PostInvalidation(r);
264 
265     MOZ_ASSERT_IF(mDoesHaveTransparency, mMayHaveTransparency);
266 
267     // We have transparency if we either detected some in the image itself
268     // (i.e., |mDoesHaveTransparency| is true) or we're in an ICO, which could
269     // mean we have an AND mask that provides transparency (i.e., |mIsWithinICO|
270     // is true).
271     // XXX(seth): We can tell when we create the decoder if the AND mask is
272     // present, so we could be more precise about this.
273     const Opacity opacity = mDoesHaveTransparency || mIsWithinICO
274                           ? Opacity::SOME_TRANSPARENCY
275                           : Opacity::FULLY_OPAQUE;
276 
277     PostFrameStop(opacity);
278     PostDecodeDone();
279   }
280 
281   return NS_OK;
282 }
283 
284 // ----------------------------------------
285 // Actual Data Processing
286 // ----------------------------------------
287 
288 void
Set(uint32_t aMask)289 BitFields::Value::Set(uint32_t aMask)
290 {
291   mMask = aMask;
292 
293   // Handle this exceptional case first. The chosen values don't matter
294   // (because a mask of zero will always give a value of zero) except that
295   // mBitWidth:
296   // - shouldn't be zero, because that would cause an infinite loop in Get();
297   // - shouldn't be 5 or 8, because that could cause a false positive match in
298   //   IsR5G5B5() or IsR8G8B8().
299   if (mMask == 0x0) {
300     mRightShift = 0;
301     mBitWidth = 1;
302     return;
303   }
304 
305   // Find the rightmost 1.
306   uint8_t i;
307   for (i = 0; i < 32; i++) {
308     if (mMask & (1 << i)) {
309       break;
310     }
311   }
312   mRightShift = i;
313 
314   // Now find the leftmost 1 in the same run of 1s. (If there are multiple runs
315   // of 1s -- which isn't valid -- we'll behave as if only the lowest run was
316   // present, which seems reasonable.)
317   for (i = i + 1; i < 32; i++) {
318     if (!(mMask & (1 << i))) {
319       break;
320     }
321   }
322   mBitWidth = i - mRightShift;
323 }
324 
325 MOZ_ALWAYS_INLINE uint8_t
Get(uint32_t aValue) const326 BitFields::Value::Get(uint32_t aValue) const
327 {
328   // Extract the unscaled value.
329   uint32_t v = (aValue & mMask) >> mRightShift;
330 
331   // Idea: to upscale v precisely we need to duplicate its bits, possibly
332   // repeatedly, possibly partially in the last case, from bit 7 down to bit 0
333   // in v2. For example:
334   //
335   // - mBitWidth=1:  v2 = v<<7 | v<<6 | ... | v<<1 | v>>0     k -> kkkkkkkk
336   // - mBitWidth=2:  v2 = v<<6 | v<<4 | v<<2 | v>>0          jk -> jkjkjkjk
337   // - mBitWidth=3:  v2 = v<<5 | v<<2 | v>>1                ijk -> ijkijkij
338   // - mBitWidth=4:  v2 = v<<4 | v>>0                      hijk -> hijkhijk
339   // - mBitWidth=5:  v2 = v<<3 | v>>2                     ghijk -> ghijkghi
340   // - mBitWidth=6:  v2 = v<<2 | v>>4                    fghijk -> fghijkfg
341   // - mBitWidth=7:  v2 = v<<1 | v>>6                   efghijk -> efghijke
342   // - mBitWidth=8:  v2 = v>>0                         defghijk -> defghijk
343   // - mBitWidth=9:  v2 = v>>1                        cdefghijk -> cdefghij
344   // - mBitWidth=10: v2 = v>>2                       bcdefghijk -> bcdefghi
345   // - mBitWidth=11: v2 = v>>3                      abcdefghijk -> abcdefgh
346   // - etc.
347   //
348   uint8_t v2 = 0;
349   int32_t i;      // must be a signed integer
350   for (i = 8 - mBitWidth; i > 0; i -= mBitWidth) {
351     v2 |= v << uint32_t(i);
352   }
353   v2 |= v >> uint32_t(-i);
354   return v2;
355 }
356 
357 MOZ_ALWAYS_INLINE uint8_t
GetAlpha(uint32_t aValue,bool & aHasAlphaOut) const358 BitFields::Value::GetAlpha(uint32_t aValue, bool& aHasAlphaOut) const
359 {
360   if (mMask == 0x0) {
361     return 0xff;
362   }
363   aHasAlphaOut = true;
364   return Get(aValue);
365 }
366 
367 MOZ_ALWAYS_INLINE uint8_t
Get5(uint32_t aValue) const368 BitFields::Value::Get5(uint32_t aValue) const
369 {
370   MOZ_ASSERT(mBitWidth == 5);
371   uint32_t v = (aValue & mMask) >> mRightShift;
372   return (v << 3u) | (v >> 2u);
373 }
374 
375 MOZ_ALWAYS_INLINE uint8_t
Get8(uint32_t aValue) const376 BitFields::Value::Get8(uint32_t aValue) const
377 {
378   MOZ_ASSERT(mBitWidth == 8);
379   uint32_t v = (aValue & mMask) >> mRightShift;
380   return v;
381 }
382 
383 void
SetR5G5B5()384 BitFields::SetR5G5B5()
385 {
386   mRed.Set(0x7c00);
387   mGreen.Set(0x03e0);
388   mBlue.Set(0x001f);
389 }
390 
391 void
SetR8G8B8()392 BitFields::SetR8G8B8()
393 {
394   mRed.Set(0xff0000);
395   mGreen.Set(0xff00);
396   mBlue.Set(0x00ff);
397 }
398 
399 bool
IsR5G5B5() const400 BitFields::IsR5G5B5() const
401 {
402   return mRed.mBitWidth == 5 &&
403          mGreen.mBitWidth == 5 &&
404          mBlue.mBitWidth == 5 &&
405          mAlpha.mMask == 0x0;
406 }
407 
408 bool
IsR8G8B8() const409 BitFields::IsR8G8B8() const
410 {
411   return mRed.mBitWidth == 8 &&
412          mGreen.mBitWidth == 8 &&
413          mBlue.mBitWidth == 8 &&
414          mAlpha.mMask == 0x0;
415 }
416 
417 uint32_t*
RowBuffer()418 nsBMPDecoder::RowBuffer()
419 {
420   if (mDownscaler) {
421     return reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer()) + mCurrentPos;
422   }
423 
424   // Convert from row (1..mHeight) to absolute line (0..mHeight-1).
425   int32_t line = (mH.mHeight < 0)
426                ? -mH.mHeight - mCurrentRow
427                : mCurrentRow - 1;
428   int32_t offset = line * mH.mWidth + mCurrentPos;
429   return reinterpret_cast<uint32_t*>(mImageData) + offset;
430 }
431 
432 void
FinishRow()433 nsBMPDecoder::FinishRow()
434 {
435   if (mDownscaler) {
436     mDownscaler->CommitRow();
437 
438     if (mDownscaler->HasInvalidation()) {
439       DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
440       PostInvalidation(invalidRect.mOriginalSizeRect,
441                        Some(invalidRect.mTargetSizeRect));
442     }
443   } else {
444     PostInvalidation(IntRect(0, mCurrentRow, mH.mWidth, 1));
445   }
446   mCurrentRow--;
447 }
448 
449 LexerResult
DoDecode(SourceBufferIterator & aIterator,IResumable * aOnResume)450 nsBMPDecoder::DoDecode(SourceBufferIterator& aIterator, IResumable* aOnResume)
451 {
452   MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
453 
454   return mLexer.Lex(aIterator, aOnResume,
455                     [=](State aState, const char* aData, size_t aLength) {
456     switch (aState) {
457       case State::FILE_HEADER:      return ReadFileHeader(aData, aLength);
458       case State::INFO_HEADER_SIZE: return ReadInfoHeaderSize(aData, aLength);
459       case State::INFO_HEADER_REST: return ReadInfoHeaderRest(aData, aLength);
460       case State::BITFIELDS:        return ReadBitfields(aData, aLength);
461       case State::COLOR_TABLE:      return ReadColorTable(aData, aLength);
462       case State::GAP:              return SkipGap();
463       case State::AFTER_GAP:        return AfterGap();
464       case State::PIXEL_ROW:        return ReadPixelRow(aData);
465       case State::RLE_SEGMENT:      return ReadRLESegment(aData);
466       case State::RLE_DELTA:        return ReadRLEDelta(aData);
467       case State::RLE_ABSOLUTE:     return ReadRLEAbsolute(aData, aLength);
468       default:
469         MOZ_CRASH("Unknown State");
470     }
471   });
472 }
473 
474 LexerTransition<nsBMPDecoder::State>
ReadFileHeader(const char * aData,size_t aLength)475 nsBMPDecoder::ReadFileHeader(const char* aData, size_t aLength)
476 {
477   mPreGapLength += aLength;
478 
479   bool signatureOk = aData[0] == 'B' && aData[1] == 'M';
480   if (!signatureOk) {
481     return Transition::TerminateFailure();
482   }
483 
484   // We ignore the filesize (aData + 2) and reserved (aData + 6) fields.
485 
486   mH.mDataOffset = LittleEndian::readUint32(aData + 10);
487 
488   return Transition::To(State::INFO_HEADER_SIZE, BIHSIZE_FIELD_LENGTH);
489 }
490 
491 // We read the info header in two steps: (a) read the mBIHSize field to
492 // determine how long the header is; (b) read the rest of the header.
493 LexerTransition<nsBMPDecoder::State>
ReadInfoHeaderSize(const char * aData,size_t aLength)494 nsBMPDecoder::ReadInfoHeaderSize(const char* aData, size_t aLength)
495 {
496   mPreGapLength += aLength;
497 
498   mH.mBIHSize = LittleEndian::readUint32(aData);
499 
500   bool bihSizeOk = mH.mBIHSize == InfoHeaderLength::WIN_V2 ||
501                    mH.mBIHSize == InfoHeaderLength::WIN_V3 ||
502                    mH.mBIHSize == InfoHeaderLength::WIN_V4 ||
503                    mH.mBIHSize == InfoHeaderLength::WIN_V5 ||
504                    (mH.mBIHSize >= InfoHeaderLength::OS2_V2_MIN &&
505                     mH.mBIHSize <= InfoHeaderLength::OS2_V2_MAX);
506   if (!bihSizeOk) {
507     return Transition::TerminateFailure();
508   }
509   // ICO BMPs must have a WinBMPv3 header. nsICODecoder should have already
510   // terminated decoding if this isn't the case.
511   MOZ_ASSERT_IF(mIsWithinICO, mH.mBIHSize == InfoHeaderLength::WIN_V3);
512 
513   return Transition::To(State::INFO_HEADER_REST,
514                         mH.mBIHSize - BIHSIZE_FIELD_LENGTH);
515 }
516 
517 LexerTransition<nsBMPDecoder::State>
ReadInfoHeaderRest(const char * aData,size_t aLength)518 nsBMPDecoder::ReadInfoHeaderRest(const char* aData, size_t aLength)
519 {
520   mPreGapLength += aLength;
521 
522   // |mWidth| and |mHeight| may be signed (Windows) or unsigned (OS/2). We just
523   // read as unsigned because in practice that's good enough.
524   if (mH.mBIHSize == InfoHeaderLength::WIN_V2) {
525     mH.mWidth  = LittleEndian::readUint16(aData + 0);
526     mH.mHeight = LittleEndian::readUint16(aData + 2);
527     // We ignore the planes (aData + 4) field; it should always be 1.
528     mH.mBpp    = LittleEndian::readUint16(aData + 6);
529   } else {
530     mH.mWidth  = LittleEndian::readUint32(aData + 0);
531     mH.mHeight = LittleEndian::readUint32(aData + 4);
532     // We ignore the planes (aData + 4) field; it should always be 1.
533     mH.mBpp    = LittleEndian::readUint16(aData + 10);
534 
535     // For OS2-BMPv2 the info header may be as little as 16 bytes, so be
536     // careful for these fields.
537     mH.mCompression = aLength >= 16 ? LittleEndian::readUint32(aData + 12) : 0;
538     mH.mImageSize   = aLength >= 20 ? LittleEndian::readUint32(aData + 16) : 0;
539     // We ignore the xppm (aData + 20) and yppm (aData + 24) fields.
540     mH.mNumColors   = aLength >= 32 ? LittleEndian::readUint32(aData + 28) : 0;
541     // We ignore the important_colors (aData + 36) field.
542 
543     // For WinBMPv4, WinBMPv5 and (possibly) OS2-BMPv2 there are additional
544     // fields in the info header which we ignore, with the possible exception
545     // of the color bitfields (see below).
546   }
547 
548   // Run with MOZ_LOG=BMPDecoder:5 set to see this output.
549   MOZ_LOG(sBMPLog, LogLevel::Debug,
550           ("BMP: bihsize=%u, %d x %d, bpp=%u, compression=%u, colors=%u\n",
551           mH.mBIHSize, mH.mWidth, mH.mHeight, uint32_t(mH.mBpp),
552           mH.mCompression, mH.mNumColors));
553 
554   // BMPs with negative width are invalid. Also, reject extremely wide images
555   // to keep the math sane. And reject INT_MIN as a height because you can't
556   // get its absolute value (because -INT_MIN is one more than INT_MAX).
557   const int32_t k64KWidth = 0x0000FFFF;
558   bool sizeOk = 0 <= mH.mWidth && mH.mWidth <= k64KWidth &&
559                 mH.mHeight != INT_MIN;
560   if (!sizeOk) {
561     return Transition::TerminateFailure();
562   }
563 
564   // Check mBpp and mCompression.
565   bool bppCompressionOk =
566     (mH.mCompression == Compression::RGB &&
567       (mH.mBpp ==  1 || mH.mBpp ==  4 || mH.mBpp ==  8 ||
568        mH.mBpp == 16 || mH.mBpp == 24 || mH.mBpp == 32)) ||
569     (mH.mCompression == Compression::RLE8 && mH.mBpp == 8) ||
570     (mH.mCompression == Compression::RLE4 && mH.mBpp == 4) ||
571     (mH.mCompression == Compression::BITFIELDS &&
572       // For BITFIELDS compression we require an exact match for one of the
573       // WinBMP BIH sizes; this clearly isn't an OS2 BMP.
574       (mH.mBIHSize == InfoHeaderLength::WIN_V3 ||
575        mH.mBIHSize == InfoHeaderLength::WIN_V4 ||
576        mH.mBIHSize == InfoHeaderLength::WIN_V5) &&
577       (mH.mBpp == 16 || mH.mBpp == 32));
578   if (!bppCompressionOk) {
579     return Transition::TerminateFailure();
580   }
581 
582   // Initialize our current row to the top of the image.
583   mCurrentRow = AbsoluteHeight();
584 
585   // Round it up to the nearest byte count, then pad to 4-byte boundary.
586   // Compute this even for a metadate decode because GetCompressedImageSize()
587   // relies on it.
588   mPixelRowSize = (mH.mBpp * mH.mWidth + 7) / 8;
589   uint32_t surplus = mPixelRowSize % 4;
590   if (surplus != 0) {
591     mPixelRowSize += 4 - surplus;
592   }
593 
594   size_t bitFieldsLengthStillToRead = 0;
595   if (mH.mCompression == Compression::BITFIELDS) {
596     // Need to read bitfields.
597     if (mH.mBIHSize >= InfoHeaderLength::WIN_V4) {
598       // Bitfields are present in the info header, so we can read them
599       // immediately.
600       mBitFields.ReadFromHeader(aData + 36, /* aReadAlpha = */ true);
601     } else {
602       // Bitfields are present after the info header, so we will read them in
603       // ReadBitfields().
604       bitFieldsLengthStillToRead = BitFields::LENGTH;
605     }
606   } else if (mH.mBpp == 16) {
607     // No bitfields specified; use the default 5-5-5 values.
608     mBitFields.SetR5G5B5();
609   } else if (mH.mBpp == 32) {
610     // No bitfields specified; use the default 8-8-8 values.
611     mBitFields.SetR8G8B8();
612   }
613 
614   return Transition::To(State::BITFIELDS, bitFieldsLengthStillToRead);
615 }
616 
617 void
ReadFromHeader(const char * aData,bool aReadAlpha)618 BitFields::ReadFromHeader(const char* aData, bool aReadAlpha)
619 {
620   mRed.Set  (LittleEndian::readUint32(aData + 0));
621   mGreen.Set(LittleEndian::readUint32(aData + 4));
622   mBlue.Set (LittleEndian::readUint32(aData + 8));
623   if (aReadAlpha) {
624     mAlpha.Set(LittleEndian::readUint32(aData + 12));
625   }
626 }
627 
628 LexerTransition<nsBMPDecoder::State>
ReadBitfields(const char * aData,size_t aLength)629 nsBMPDecoder::ReadBitfields(const char* aData, size_t aLength)
630 {
631   mPreGapLength += aLength;
632 
633   // If aLength is zero there are no bitfields to read, or we already read them
634   // in ReadInfoHeader().
635   if (aLength != 0) {
636     mBitFields.ReadFromHeader(aData, /* aReadAlpha = */ false);
637   }
638 
639   // Note that RLE-encoded BMPs might be transparent because the 'delta' mode
640   // can skip pixels and cause implicit transparency.
641   mMayHaveTransparency =
642     mIsWithinICO ||
643     mH.mCompression == Compression::RLE8 ||
644     mH.mCompression == Compression::RLE4 ||
645     (mH.mCompression == Compression::BITFIELDS &&
646      mBitFields.mAlpha.IsPresent());
647   if (mMayHaveTransparency) {
648     PostHasTransparency();
649   }
650 
651   // Post our size to the superclass.
652   PostSize(mH.mWidth, AbsoluteHeight());
653 
654   // We've now read all the headers. If we're doing a metadata decode, we're
655   // done.
656   if (IsMetadataDecode()) {
657     return Transition::TerminateSuccess();
658   }
659 
660   // Set up the color table, if present; it'll be filled in by ReadColorTable().
661   if (mH.mBpp <= 8) {
662     mNumColors = 1 << mH.mBpp;
663     if (0 < mH.mNumColors && mH.mNumColors < mNumColors) {
664       mNumColors = mH.mNumColors;
665     }
666 
667     // Always allocate and zero 256 entries, even though mNumColors might be
668     // smaller, because the file might erroneously index past mNumColors.
669     mColors = MakeUnique<ColorTableEntry[]>(256);
670     memset(mColors.get(), 0, 256 * sizeof(ColorTableEntry));
671 
672     // OS/2 Bitmaps have no padding byte.
673     mBytesPerColor = (mH.mBIHSize == InfoHeaderLength::WIN_V2) ? 3 : 4;
674   }
675 
676   MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
677   nsresult rv = AllocateFrame(/* aFrameNum = */ 0, OutputSize(),
678                               FullOutputFrame(),
679                               mMayHaveTransparency ? SurfaceFormat::B8G8R8A8
680                                                    : SurfaceFormat::B8G8R8X8);
681   if (NS_FAILED(rv)) {
682     return Transition::TerminateFailure();
683   }
684   MOZ_ASSERT(mImageData, "Should have a buffer now");
685 
686   if (mDownscaler) {
687     // BMPs store their rows in reverse order, so the downscaler needs to
688     // reverse them again when writing its output. Unless the height is
689     // negative!
690     rv = mDownscaler->BeginFrame(Size(), Nothing(),
691                                  mImageData, mMayHaveTransparency,
692                                  /* aFlipVertically = */ mH.mHeight >= 0);
693     if (NS_FAILED(rv)) {
694       return Transition::TerminateFailure();
695     }
696   }
697 
698   return Transition::To(State::COLOR_TABLE, mNumColors * mBytesPerColor);
699 }
700 
701 LexerTransition<nsBMPDecoder::State>
ReadColorTable(const char * aData,size_t aLength)702 nsBMPDecoder::ReadColorTable(const char* aData, size_t aLength)
703 {
704   MOZ_ASSERT_IF(aLength != 0, mNumColors > 0 && mColors);
705 
706   mPreGapLength += aLength;
707 
708   for (uint32_t i = 0; i < mNumColors; i++) {
709     // The format is BGR or BGR0.
710     mColors[i].mBlue  = uint8_t(aData[0]);
711     mColors[i].mGreen = uint8_t(aData[1]);
712     mColors[i].mRed   = uint8_t(aData[2]);
713     aData += mBytesPerColor;
714   }
715 
716   // We know how many bytes we've read so far (mPreGapLength) and we know the
717   // offset of the pixel data (mH.mDataOffset), so we can determine the length
718   // of the gap (possibly zero) between the color table and the pixel data.
719   //
720   // If the gap is negative the file must be malformed (e.g. mH.mDataOffset
721   // points into the middle of the color palette instead of past the end) and
722   // we give up.
723   if (mPreGapLength > mH.mDataOffset) {
724     return Transition::TerminateFailure();
725   }
726 
727   uint32_t gapLength = mH.mDataOffset - mPreGapLength;
728   return Transition::ToUnbuffered(State::AFTER_GAP, State::GAP, gapLength);
729 }
730 
731 LexerTransition<nsBMPDecoder::State>
SkipGap()732 nsBMPDecoder::SkipGap()
733 {
734   return Transition::ContinueUnbuffered(State::GAP);
735 }
736 
737 LexerTransition<nsBMPDecoder::State>
AfterGap()738 nsBMPDecoder::AfterGap()
739 {
740   // If there are no pixels we can stop.
741   //
742   // XXX: normally, if there are no pixels we will have stopped decoding before
743   // now, outside of this decoder. However, if the BMP is within an ICO file,
744   // it's possible that the ICO claimed the image had a non-zero size while the
745   // BMP claims otherwise. This test is to catch that awkward case. If we ever
746   // come up with a more general solution to this ICO-and-BMP-disagree-on-size
747   // problem, this test can be removed.
748   if (mH.mWidth == 0 || mH.mHeight == 0) {
749     return Transition::TerminateSuccess();
750   }
751 
752   bool hasRLE = mH.mCompression == Compression::RLE8 ||
753                 mH.mCompression == Compression::RLE4;
754   return hasRLE
755        ? Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH)
756        : Transition::To(State::PIXEL_ROW, mPixelRowSize);
757 }
758 
759 LexerTransition<nsBMPDecoder::State>
ReadPixelRow(const char * aData)760 nsBMPDecoder::ReadPixelRow(const char* aData)
761 {
762   MOZ_ASSERT(mCurrentRow > 0);
763   MOZ_ASSERT(mCurrentPos == 0);
764 
765   const uint8_t* src = reinterpret_cast<const uint8_t*>(aData);
766   uint32_t* dst = RowBuffer();
767   uint32_t lpos = mH.mWidth;
768   switch (mH.mBpp) {
769     case 1:
770       while (lpos > 0) {
771         int8_t bit;
772         uint8_t idx;
773         for (bit = 7; bit >= 0 && lpos > 0; bit--) {
774           idx = (*src >> bit) & 1;
775           SetPixel(dst, idx, mColors);
776           --lpos;
777         }
778         ++src;
779       }
780       break;
781 
782     case 4:
783       while (lpos > 0) {
784         Set4BitPixel(dst, *src, lpos, mColors);
785         ++src;
786       }
787       break;
788 
789     case 8:
790       while (lpos > 0) {
791         SetPixel(dst, *src, mColors);
792         --lpos;
793         ++src;
794       }
795       break;
796 
797     case 16:
798       if (mBitFields.IsR5G5B5()) {
799         // Specialize this common case.
800         while (lpos > 0) {
801           uint16_t val = LittleEndian::readUint16(src);
802           SetPixel(dst, mBitFields.mRed.Get5(val),
803                         mBitFields.mGreen.Get5(val),
804                         mBitFields.mBlue.Get5(val));
805           --lpos;
806           src += 2;
807         }
808       } else {
809         bool anyHasAlpha = false;
810         while (lpos > 0) {
811           uint16_t val = LittleEndian::readUint16(src);
812           SetPixel(dst, mBitFields.mRed.Get(val),
813                         mBitFields.mGreen.Get(val),
814                         mBitFields.mBlue.Get(val),
815                         mBitFields.mAlpha.GetAlpha(val, anyHasAlpha));
816           --lpos;
817           src += 2;
818         }
819         if (anyHasAlpha) {
820           MOZ_ASSERT(mMayHaveTransparency);
821           mDoesHaveTransparency = true;
822         }
823       }
824       break;
825 
826     case 24:
827       while (lpos > 0) {
828         SetPixel(dst, src[2], src[1], src[0]);
829         --lpos;
830         src += 3;
831       }
832       break;
833 
834     case 32:
835       if (mH.mCompression == Compression::RGB && mIsWithinICO &&
836           mH.mBpp == 32) {
837         // This is a special case only used for 32bpp WinBMPv3-ICO files, which
838         // could be in either 0RGB or ARGB format. We start by assuming it's
839         // an 0RGB image. If we hit a non-zero alpha value, then we know it's
840         // actually an ARGB image, and change tack accordingly.
841         // (Note: a fully-transparent ARGB image is indistinguishable from a
842         // 0RGB image, and we will render such an image as a 0RGB image, i.e.
843         // opaquely. This is unlikely to be a problem in practice.)
844         while (lpos > 0) {
845           if (!mDoesHaveTransparency && src[3] != 0) {
846             // Up until now this looked like an 0RGB image, but we now know
847             // it's actually an ARGB image. Which means every pixel we've seen
848             // so far has been fully transparent. So we go back and redo them.
849 
850             // Tell the Downscaler to go back to the start.
851             if (mDownscaler) {
852               mDownscaler->ResetForNextProgressivePass();
853             }
854 
855             // Redo the complete rows we've already done.
856             MOZ_ASSERT(mCurrentPos == 0);
857             int32_t currentRow = mCurrentRow;
858             mCurrentRow = AbsoluteHeight();
859             while (mCurrentRow > currentRow) {
860               dst = RowBuffer();
861               for (int32_t i = 0; i < mH.mWidth; i++) {
862                 SetPixel(dst, 0, 0, 0, 0);
863               }
864               FinishRow();
865             }
866 
867             // Redo the part of this row we've already done.
868             dst = RowBuffer();
869             int32_t n = mH.mWidth - lpos;
870             for (int32_t i = 0; i < n; i++) {
871               SetPixel(dst, 0, 0, 0, 0);
872             }
873 
874             MOZ_ASSERT(mMayHaveTransparency);
875             mDoesHaveTransparency = true;
876           }
877 
878           // If mDoesHaveTransparency is false, treat this as an 0RGB image.
879           // Otherwise, treat this as an ARGB image.
880           SetPixel(dst, src[2], src[1], src[0],
881                    mDoesHaveTransparency ? src[3] : 0xff);
882           src += 4;
883           --lpos;
884         }
885       } else if (mBitFields.IsR8G8B8()) {
886         // Specialize this common case.
887         while (lpos > 0) {
888           uint32_t val = LittleEndian::readUint32(src);
889           SetPixel(dst, mBitFields.mRed.Get8(val),
890                         mBitFields.mGreen.Get8(val),
891                         mBitFields.mBlue.Get8(val));
892           --lpos;
893           src += 4;
894         }
895       } else {
896         bool anyHasAlpha = false;
897         while (lpos > 0) {
898           uint32_t val = LittleEndian::readUint32(src);
899           SetPixel(dst, mBitFields.mRed.Get(val),
900                         mBitFields.mGreen.Get(val),
901                         mBitFields.mBlue.Get(val),
902                         mBitFields.mAlpha.GetAlpha(val, anyHasAlpha));
903           --lpos;
904           src += 4;
905         }
906         if (anyHasAlpha) {
907           MOZ_ASSERT(mMayHaveTransparency);
908           mDoesHaveTransparency = true;
909         }
910       }
911       break;
912 
913     default:
914       MOZ_CRASH("Unsupported color depth; earlier check didn't catch it?");
915   }
916 
917   FinishRow();
918   return mCurrentRow == 0
919        ? Transition::TerminateSuccess()
920        : Transition::To(State::PIXEL_ROW, mPixelRowSize);
921 }
922 
923 LexerTransition<nsBMPDecoder::State>
ReadRLESegment(const char * aData)924 nsBMPDecoder::ReadRLESegment(const char* aData)
925 {
926   if (mCurrentRow == 0) {
927     return Transition::TerminateSuccess();
928   }
929 
930   uint8_t byte1 = uint8_t(aData[0]);
931   uint8_t byte2 = uint8_t(aData[1]);
932 
933   if (byte1 != RLE::ESCAPE) {
934     // Encoded mode consists of two bytes: byte1 specifies the number of
935     // consecutive pixels to be drawn using the color index contained in
936     // byte2.
937     //
938     // Work around bitmaps that specify too many pixels.
939     uint32_t pixelsNeeded =
940       std::min<uint32_t>(mH.mWidth - mCurrentPos, byte1);
941     if (pixelsNeeded) {
942       uint32_t* dst = RowBuffer();
943       mCurrentPos += pixelsNeeded;
944       if (mH.mCompression == Compression::RLE8) {
945         do {
946           SetPixel(dst, byte2, mColors);
947           pixelsNeeded --;
948         } while (pixelsNeeded);
949       } else {
950         do {
951           Set4BitPixel(dst, byte2, pixelsNeeded, mColors);
952         } while (pixelsNeeded);
953       }
954     }
955     return Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
956   }
957 
958   if (byte2 == RLE::ESCAPE_EOL) {
959     mCurrentPos = 0;
960     FinishRow();
961     return mCurrentRow == 0
962          ? Transition::TerminateSuccess()
963          : Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
964   }
965 
966   if (byte2 == RLE::ESCAPE_EOF) {
967     return Transition::TerminateSuccess();
968   }
969 
970   if (byte2 == RLE::ESCAPE_DELTA) {
971     return Transition::To(State::RLE_DELTA, RLE::DELTA_LENGTH);
972   }
973 
974   // Absolute mode. |byte2| gives the number of pixels. The length depends on
975   // whether it's 4-bit or 8-bit RLE. Also, the length must be even (and zero
976   // padding is used to achieve this when necessary).
977   MOZ_ASSERT(mAbsoluteModeNumPixels == 0);
978   mAbsoluteModeNumPixels = byte2;
979   uint32_t length = byte2;
980   if (mH.mCompression == Compression::RLE4) {
981     length = (length + 1) / 2;    // halve, rounding up
982   }
983   if (length & 1) {
984     length++;
985   }
986   return Transition::To(State::RLE_ABSOLUTE, length);
987 }
988 
989 LexerTransition<nsBMPDecoder::State>
ReadRLEDelta(const char * aData)990 nsBMPDecoder::ReadRLEDelta(const char* aData)
991 {
992   // Delta encoding makes it possible to skip pixels making part of the image
993   // transparent.
994   MOZ_ASSERT(mMayHaveTransparency);
995   mDoesHaveTransparency = true;
996 
997   if (mDownscaler) {
998     // Clear the skipped pixels. (This clears to the end of the row,
999     // which is perfect if there's a Y delta and harmless if not).
1000     mDownscaler->ClearRestOfRow(/* aStartingAtCol = */ mCurrentPos);
1001   }
1002 
1003   // Handle the XDelta.
1004   mCurrentPos += uint8_t(aData[0]);
1005   if (mCurrentPos > mH.mWidth) {
1006     mCurrentPos = mH.mWidth;
1007   }
1008 
1009   // Handle the Y Delta.
1010   int32_t yDelta = std::min<int32_t>(uint8_t(aData[1]), mCurrentRow);
1011   mCurrentRow -= yDelta;
1012 
1013   if (mDownscaler && yDelta > 0) {
1014     // Commit the current row (the first of the skipped rows).
1015     mDownscaler->CommitRow();
1016 
1017     // Clear and commit the remaining skipped rows.
1018     for (int32_t line = 1; line < yDelta; line++) {
1019       mDownscaler->ClearRow();
1020       mDownscaler->CommitRow();
1021     }
1022   }
1023 
1024   return mCurrentRow == 0
1025        ? Transition::TerminateSuccess()
1026        : Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
1027 }
1028 
1029 LexerTransition<nsBMPDecoder::State>
ReadRLEAbsolute(const char * aData,size_t aLength)1030 nsBMPDecoder::ReadRLEAbsolute(const char* aData, size_t aLength)
1031 {
1032   uint32_t n = mAbsoluteModeNumPixels;
1033   mAbsoluteModeNumPixels = 0;
1034 
1035   if (mCurrentPos + n > uint32_t(mH.mWidth)) {
1036     // Bad data. Stop decoding; at least part of the image may have been
1037     // decoded.
1038     return Transition::TerminateSuccess();
1039   }
1040 
1041   // In absolute mode, n represents the number of pixels that follow, each of
1042   // which contains the color index of a single pixel.
1043   uint32_t* dst = RowBuffer();
1044   uint32_t iSrc = 0;
1045   uint32_t* oldPos = dst;
1046   if (mH.mCompression == Compression::RLE8) {
1047     while (n > 0) {
1048       SetPixel(dst, aData[iSrc], mColors);
1049       n--;
1050       iSrc++;
1051     }
1052   } else {
1053     while (n > 0) {
1054       Set4BitPixel(dst, aData[iSrc], n, mColors);
1055       iSrc++;
1056     }
1057   }
1058   mCurrentPos += dst - oldPos;
1059 
1060   // We should read all the data (unless the last byte is zero padding).
1061   MOZ_ASSERT(iSrc == aLength - 1 || iSrc == aLength);
1062 
1063   return Transition::To(State::RLE_SEGMENT, RLE::SEGMENT_LENGTH);
1064 }
1065 
1066 } // namespace image
1067 } // namespace mozilla
1068