nsBMPDecoder.cpp 35 KB

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