BMPLoader.cpp 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390
  1. /*
  2. * Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <AK/Function.h>
  27. #include <AK/LexicalPath.h>
  28. #include <AK/MappedFile.h>
  29. #include <LibGfx/BMPLoader.h>
  30. #ifndef BMP_DEBUG
  31. # define BMP_DEBUG 0
  32. #endif
  33. #define IF_BMP_DEBUG(x) \
  34. if (BMP_DEBUG) \
  35. x
  36. namespace Gfx {
  37. const u8 bmp_header_size = 14;
  38. const u32 color_palette_limit = 1024;
  39. // Compression flags
  40. struct Compression {
  41. enum : u32 {
  42. RGB = 0,
  43. RLE8,
  44. RLE4,
  45. BITFIELDS,
  46. RLE24, // doubles as JPEG for V4+, but that is unsupported
  47. PNG,
  48. ALPHABITFIELDS,
  49. CMYK = 11,
  50. CMYKRLE8,
  51. CMYKRLE4,
  52. };
  53. };
  54. struct DIBCore {
  55. // u16 for BITMAPHEADERCORE, but i32 for everything else. If the dib type is
  56. // BITMAPHEADERCORE, this is range checked.
  57. i32 width;
  58. i32 height;
  59. u16 bpp;
  60. };
  61. struct DIBInfo {
  62. u32 compression { Compression::RGB };
  63. u32 image_size { 0 };
  64. i32 horizontal_resolution { 0 };
  65. i32 vertical_resolution { 0 };
  66. u32 number_of_palette_colors { 0 };
  67. u32 number_of_important_palette_colors { number_of_palette_colors };
  68. // Introduced in the BITMAPV2INFOHEADER and would ideally be stored in the
  69. // DIBV2 struct, however with a compression value of BI_BITFIELDS or
  70. // BI_ALPHABITFIELDS, these can be specified with the Info header.
  71. Vector<u32> masks;
  72. Vector<i8> mask_shifts;
  73. Vector<u8> mask_sizes;
  74. };
  75. struct DIBOSV2 {
  76. u16 recording;
  77. u16 halftoning;
  78. u16 size1;
  79. u16 size2;
  80. };
  81. template<typename T>
  82. struct Endpoint {
  83. T x;
  84. T y;
  85. T z;
  86. };
  87. struct DIBV4 {
  88. u32 color_space { 0 };
  89. Endpoint<i32> red_endpoint { 0, 0, 0 };
  90. Endpoint<i32> green_endpoint { 0, 0, 0 };
  91. Endpoint<i32> blue_endpoint { 0, 0, 0 };
  92. Endpoint<u32> gamma_endpoint { 0, 0, 0 };
  93. };
  94. struct DIBV5 {
  95. u32 intent { 0 };
  96. u32 profile_data { 0 };
  97. u32 profile_size { 0 };
  98. };
  99. struct DIB {
  100. DIBCore core;
  101. DIBInfo info;
  102. DIBOSV2 osv2;
  103. DIBV4 v4;
  104. DIBV5 v5;
  105. };
  106. enum class DIBType {
  107. Core = 0,
  108. OSV2Short,
  109. OSV2,
  110. Info,
  111. V2,
  112. V3,
  113. V4,
  114. V5
  115. };
  116. struct BMPLoadingContext {
  117. enum class State {
  118. NotDecoded = 0,
  119. HeaderDecoded,
  120. DIBDecoded,
  121. ColorTableDecoded,
  122. PixelDataDecoded,
  123. Error,
  124. };
  125. State state { State::NotDecoded };
  126. const u8* data { nullptr };
  127. size_t data_size { 0 };
  128. u32 data_offset { 0 };
  129. DIB dib;
  130. DIBType dib_type;
  131. Vector<u32> color_table;
  132. RefPtr<Gfx::Bitmap> bitmap;
  133. u32 dib_size() const
  134. {
  135. switch (dib_type) {
  136. case DIBType::Core:
  137. return 12;
  138. case DIBType::OSV2Short:
  139. return 16;
  140. case DIBType::OSV2:
  141. return 64;
  142. case DIBType::Info:
  143. return 40;
  144. case DIBType::V2:
  145. return 52;
  146. case DIBType::V3:
  147. return 56;
  148. case DIBType::V4:
  149. return 108;
  150. case DIBType::V5:
  151. return 124;
  152. }
  153. ASSERT_NOT_REACHED();
  154. }
  155. };
  156. static RefPtr<Bitmap> load_bmp_impl(const u8*, size_t);
  157. RefPtr<Gfx::Bitmap> load_bmp(const StringView& path)
  158. {
  159. MappedFile mapped_file(path);
  160. if (!mapped_file.is_valid())
  161. return nullptr;
  162. auto bitmap = load_bmp_impl((const u8*)mapped_file.data(), mapped_file.size());
  163. if (bitmap)
  164. bitmap->set_mmap_name(String::format("Gfx::Bitmap [%dx%d] - Decoded BMP: %s", bitmap->width(), bitmap->height(), LexicalPath::canonicalized_path(path).characters()));
  165. return bitmap;
  166. }
  167. RefPtr<Gfx::Bitmap> load_bmp_from_memory(const u8* data, size_t length)
  168. {
  169. auto bitmap = load_bmp_impl(data, length);
  170. if (bitmap)
  171. bitmap->set_mmap_name(String::format("Gfx::Bitmap [%dx%d] - Decoded BMP: <memory>", bitmap->width(), bitmap->height()));
  172. return bitmap;
  173. }
  174. static const LogStream& operator<<(const LogStream& out, Endpoint<i32> ep)
  175. {
  176. return out << "(" << ep.x << ", " << ep.y << ", " << ep.z << ")";
  177. }
  178. static const LogStream& operator<<(const LogStream& out, Endpoint<u32> ep)
  179. {
  180. return out << "(" << ep.x << ", " << ep.y << ", " << ep.z << ")";
  181. }
  182. class Streamer {
  183. public:
  184. Streamer(const u8* data, size_t size)
  185. : m_data_ptr(data)
  186. , m_size_remaining(size)
  187. {
  188. }
  189. u8 read_u8()
  190. {
  191. ASSERT(m_size_remaining >= 1);
  192. m_size_remaining--;
  193. return *(m_data_ptr++);
  194. }
  195. u16 read_u16()
  196. {
  197. return read_u8() | (read_u8() << 8);
  198. }
  199. u32 read_u24()
  200. {
  201. return read_u8() | (read_u8() << 8) | (read_u8() << 16);
  202. }
  203. i32 read_i32()
  204. {
  205. return static_cast<i32>(read_u16() | (read_u16() << 16));
  206. }
  207. u32 read_u32()
  208. {
  209. return read_u16() | (read_u16() << 16);
  210. }
  211. void drop_bytes(u8 num_bytes)
  212. {
  213. ASSERT(m_size_remaining >= num_bytes);
  214. m_size_remaining -= num_bytes;
  215. m_data_ptr += num_bytes;
  216. }
  217. bool at_end() const { return !m_size_remaining; }
  218. bool has_u8() const { return m_size_remaining >= 1; }
  219. bool has_u16() const { return m_size_remaining >= 2; }
  220. bool has_u24() const { return m_size_remaining >= 3; }
  221. bool has_u32() const { return m_size_remaining >= 4; }
  222. size_t remaining() const { return m_size_remaining; }
  223. void set_remaining(size_t remaining) { m_size_remaining = remaining; }
  224. private:
  225. const u8* m_data_ptr { nullptr };
  226. size_t m_size_remaining { 0 };
  227. };
  228. // Lookup table for distributing all possible 2-bit numbers evenly into 8-bit numbers
  229. static u8 scaling_factors_2bit[4] = {
  230. 0x00,
  231. 0x55,
  232. 0xaa,
  233. 0xff,
  234. };
  235. // Lookup table for distributing all possible 3-bit numbers evenly into 8-bit numbers
  236. static u8 scaling_factors_3bit[8] = {
  237. 0x00,
  238. 0x24,
  239. 0x48,
  240. 0x6d,
  241. 0x91,
  242. 0xb6,
  243. 0xdb,
  244. 0xff,
  245. };
  246. static u8 scale_masked_8bit_number(u8 number, u8 bits_set)
  247. {
  248. // If there are more than 4 bit set, an easy way to scale the number is to
  249. // just copy the most significant bits into the least significant bits
  250. if (bits_set >= 4)
  251. return number | (number >> bits_set);
  252. if (!bits_set)
  253. return 0;
  254. if (bits_set == 1)
  255. return number ? 0xff : 0;
  256. if (bits_set == 2)
  257. return scaling_factors_2bit[number >> 6];
  258. return scaling_factors_3bit[number >> 5];
  259. }
  260. static u8 get_scaled_color(u32 data, u8 mask_size, i8 mask_shift)
  261. {
  262. // A negative mask_shift indicates we actually need to left shift
  263. // the result in order to get out a valid 8-bit color (for example, the blue
  264. // value in an RGB555 encoding is XXXBBBBB, which needs to be shifted to the
  265. // left by 3, hence it would have a "mask_shift" value of -3).
  266. if (mask_shift < 0)
  267. return scale_masked_8bit_number(data << -mask_shift, mask_size);
  268. return scale_masked_8bit_number(data >> mask_shift, mask_size);
  269. }
  270. // Scales an 8-bit number with "mask_size" bits set (and "8 - mask_size" bits
  271. // ignored). This function scales the number appropriately over the entire
  272. // 256 value color spectrum.
  273. // Note that a much simpler scaling can be done by simple bit shifting. If you
  274. // just ignore the bottom 8-mask_size bits, then you get *close*. However,
  275. // consider, as an example, a 5 bit number (so the bottom 3 bits are ignored).
  276. // The purest white you could get is 0xf8, which is 248 in RGB-land. We need
  277. // to scale the values in order to reach the proper value of 255.
  278. static u32 int_to_scaled_rgb(BMPLoadingContext& context, u32 data)
  279. {
  280. IF_BMP_DEBUG(dbg() << "DIB info sizes before access: #masks=" << context.dib.info.masks.size() << ", #mask_sizes=" << context.dib.info.mask_sizes.size() << ", #mask_shifts=" << context.dib.info.mask_shifts.size());
  281. u8 r = get_scaled_color(data & context.dib.info.masks[0], context.dib.info.mask_sizes[0], context.dib.info.mask_shifts[0]);
  282. u8 g = get_scaled_color(data & context.dib.info.masks[1], context.dib.info.mask_sizes[1], context.dib.info.mask_shifts[1]);
  283. u8 b = get_scaled_color(data & context.dib.info.masks[2], context.dib.info.mask_sizes[2], context.dib.info.mask_shifts[2]);
  284. u32 color = (r << 16) | (g << 8) | b;
  285. if (context.dib.info.masks.size() == 4) {
  286. // The bitmap has an alpha mask
  287. u8 a = get_scaled_color(data & context.dib.info.masks[3], context.dib.info.mask_sizes[3], context.dib.info.mask_shifts[3]);
  288. color |= (a << 24);
  289. } else {
  290. color |= 0xff000000;
  291. }
  292. return color;
  293. }
  294. static void populate_dib_mask_info(BMPLoadingContext& context)
  295. {
  296. if (context.dib.info.masks.is_empty())
  297. return;
  298. // Mask shift is the number of right shifts needed to align the MSb of the
  299. // mask to the MSb of the LSB.
  300. // Mask size is the number of set bits in the mask. This is required for
  301. // color scaling (for example, ensuring that a 4-bit color value spans the
  302. // entire 256 value color spectrum.
  303. auto& masks = context.dib.info.masks;
  304. auto& mask_shifts = context.dib.info.mask_shifts;
  305. auto& mask_sizes = context.dib.info.mask_sizes;
  306. if (!mask_shifts.is_empty() && !mask_sizes.is_empty())
  307. return;
  308. ASSERT(mask_shifts.is_empty() && mask_sizes.is_empty());
  309. mask_shifts.ensure_capacity(masks.size());
  310. mask_sizes.ensure_capacity(masks.size());
  311. for (size_t i = 0; i < masks.size(); ++i) {
  312. u32 mask = masks[i];
  313. u8 shift = 0;
  314. u8 size = 0;
  315. bool found_set_bit = false;
  316. while (shift <= 32) {
  317. u8 bit = (mask >> shift) & 0x1;
  318. if (found_set_bit)
  319. size++;
  320. if (!found_set_bit && bit) {
  321. found_set_bit = true;
  322. } else if (found_set_bit && !bit) {
  323. break;
  324. }
  325. shift++;
  326. }
  327. if (shift > 32) {
  328. mask_shifts.append(0);
  329. mask_sizes.append(0);
  330. } else {
  331. mask_shifts.append(shift - 8);
  332. mask_sizes.append(size);
  333. }
  334. }
  335. }
  336. static bool check_for_invalid_bitmask_combinations(BMPLoadingContext& context)
  337. {
  338. auto& bpp = context.dib.core.bpp;
  339. auto& compression = context.dib.info.compression;
  340. if (compression == Compression::ALPHABITFIELDS && context.dib_type != DIBType::Info)
  341. return false;
  342. switch (context.dib_type) {
  343. case DIBType::Core:
  344. if (bpp == 2 || bpp == 16 || bpp == 32)
  345. return false;
  346. break;
  347. case DIBType::Info:
  348. switch (compression) {
  349. case Compression::BITFIELDS:
  350. case Compression::ALPHABITFIELDS:
  351. if (bpp != 16 && bpp != 32)
  352. return false;
  353. break;
  354. case Compression::RGB:
  355. break;
  356. case Compression::RLE8:
  357. if (bpp > 8)
  358. return false;
  359. break;
  360. case Compression::RLE4:
  361. // TODO: This is a guess
  362. if (bpp > 4)
  363. return false;
  364. break;
  365. default:
  366. // Other compressions are not officially supported.
  367. // Technically, we could even drop ALPHABITFIELDS.
  368. return false;
  369. }
  370. break;
  371. case DIBType::OSV2Short:
  372. case DIBType::OSV2:
  373. case DIBType::V2:
  374. case DIBType::V3:
  375. case DIBType::V4:
  376. case DIBType::V5:
  377. if (compression == Compression::BITFIELDS && bpp != 16 && bpp != 32)
  378. return false;
  379. break;
  380. }
  381. return true;
  382. }
  383. static bool set_dib_bitmasks(BMPLoadingContext& context, Streamer& streamer)
  384. {
  385. if (!check_for_invalid_bitmask_combinations(context))
  386. return false;
  387. auto& bpp = context.dib.core.bpp;
  388. if (bpp <= 8 || bpp == 24)
  389. return true;
  390. auto& compression = context.dib.info.compression;
  391. auto& type = context.dib_type;
  392. if (type > DIBType::OSV2 && bpp == 16 && compression == Compression::RGB) {
  393. context.dib.info.masks.append({ 0x7c00, 0x03e0, 0x001f });
  394. context.dib.info.mask_shifts.append({ 7, 2, -3 });
  395. context.dib.info.mask_sizes.append({ 5, 5, 5 });
  396. populate_dib_mask_info(context);
  397. } else if (type == DIBType::Info && (compression == Compression::BITFIELDS || compression == Compression::ALPHABITFIELDS)) {
  398. // Consume the extra BITFIELDS bytes
  399. auto number_of_mask_fields = compression == Compression::ALPHABITFIELDS ? 4 : 3;
  400. streamer.set_remaining(number_of_mask_fields * 4);
  401. for (auto i = 0; i < number_of_mask_fields; i++)
  402. context.dib.info.masks.append(streamer.read_u32());
  403. populate_dib_mask_info(context);
  404. } else if (type >= DIBType::V2 && compression == Compression::BITFIELDS) {
  405. populate_dib_mask_info(context);
  406. }
  407. return true;
  408. }
  409. static bool decode_bmp_header(BMPLoadingContext& context)
  410. {
  411. if (context.state == BMPLoadingContext::State::Error)
  412. return false;
  413. if (context.state >= BMPLoadingContext::State::HeaderDecoded)
  414. return true;
  415. if (!context.data || context.data_size < bmp_header_size) {
  416. IF_BMP_DEBUG(dbg() << "Missing BMP header");
  417. context.state = BMPLoadingContext::State::Error;
  418. return false;
  419. }
  420. Streamer streamer(context.data, bmp_header_size);
  421. u16 header = streamer.read_u16();
  422. if (header != 0x4d42) {
  423. IF_BMP_DEBUG(dbgprintf("BMP has invalid magic header number: %04x\n", header));
  424. context.state = BMPLoadingContext::State::Error;
  425. return false;
  426. }
  427. // The reported size of the file in the header is actually not important
  428. // for decoding the file. Some specifications say that this value should
  429. // be the size of the header instead, so we just rely on the known file
  430. // size, instead of a possibly-correct-but-also-possibly-incorrect reported
  431. // value of the file size.
  432. streamer.drop_bytes(4);
  433. // Ignore reserved bytes
  434. streamer.drop_bytes(4);
  435. context.data_offset = streamer.read_u32();
  436. IF_BMP_DEBUG(dbg() << "BMP data size: " << context.data_size);
  437. IF_BMP_DEBUG(dbg() << "BMP data offset: " << context.data_offset);
  438. if (context.data_offset >= context.data_size) {
  439. IF_BMP_DEBUG(dbg() << "BMP data offset is beyond file end?!");
  440. return false;
  441. }
  442. context.state = BMPLoadingContext::State::HeaderDecoded;
  443. return true;
  444. }
  445. static bool decode_bmp_core_dib(BMPLoadingContext& context, Streamer& streamer)
  446. {
  447. auto& core = context.dib.core;
  448. // The width and height are u16 fields in the actual BITMAPCOREHEADER format.
  449. if (context.dib_type == DIBType::Core) {
  450. core.width = streamer.read_u16();
  451. core.height = streamer.read_u16();
  452. } else {
  453. core.width = streamer.read_i32();
  454. core.height = streamer.read_i32();
  455. }
  456. if (core.width < 0) {
  457. IF_BMP_DEBUG(dbg() << "BMP has a negative width: " << core.width);
  458. return false;
  459. }
  460. auto color_planes = streamer.read_u16();
  461. if (color_planes != 1) {
  462. IF_BMP_DEBUG(dbg() << "BMP has an invalid number of color planes: " << color_planes);
  463. return false;
  464. }
  465. core.bpp = streamer.read_u16();
  466. switch (core.bpp) {
  467. case 1:
  468. case 2:
  469. case 4:
  470. case 8:
  471. case 16:
  472. case 24:
  473. case 32:
  474. break;
  475. default:
  476. IF_BMP_DEBUG(dbg() << "BMP has an invalid bpp: " << core.bpp);
  477. context.state = BMPLoadingContext::State::Error;
  478. return false;
  479. }
  480. IF_BMP_DEBUG(dbg() << "BMP width: " << core.width);
  481. IF_BMP_DEBUG(dbg() << "BMP height: " << core.height);
  482. IF_BMP_DEBUG(dbg() << "BMP bits_per_pixel: " << core.bpp);
  483. return true;
  484. }
  485. ALWAYS_INLINE static bool is_supported_compression_format(BMPLoadingContext& context, u32 compression)
  486. {
  487. return compression == Compression::RGB || compression == Compression::BITFIELDS
  488. || compression == Compression::ALPHABITFIELDS || compression == Compression::RLE8
  489. || compression == Compression::RLE4 || (compression == Compression::RLE24 && context.dib_type <= DIBType::OSV2);
  490. }
  491. static bool decode_bmp_osv2_dib(BMPLoadingContext& context, Streamer& streamer, bool short_variant = false)
  492. {
  493. auto& core = context.dib.core;
  494. core.width = streamer.read_u32();
  495. core.height = streamer.read_u32();
  496. if (core.width < 0) {
  497. IF_BMP_DEBUG(dbg() << "BMP has a negative width: " << core.width);
  498. return false;
  499. }
  500. auto color_planes = streamer.read_u16();
  501. if (color_planes != 1) {
  502. IF_BMP_DEBUG(dbg() << "BMP has an invalid number of color planes: " << color_planes);
  503. return false;
  504. }
  505. core.bpp = streamer.read_u16();
  506. IF_BMP_DEBUG(dbg() << "BMP width: " << core.width);
  507. IF_BMP_DEBUG(dbg() << "BMP height: " << core.height);
  508. IF_BMP_DEBUG(dbg() << "BMP bpp: " << core.bpp);
  509. if (short_variant)
  510. return true;
  511. auto& info = context.dib.info;
  512. auto& osv2 = context.dib.osv2;
  513. info.compression = streamer.read_u32();
  514. info.image_size = streamer.read_u32();
  515. info.horizontal_resolution = streamer.read_u32();
  516. info.vertical_resolution = streamer.read_u32();
  517. info.number_of_palette_colors = streamer.read_u32();
  518. info.number_of_important_palette_colors = streamer.read_u32();
  519. if (!is_supported_compression_format(context, info.compression)) {
  520. IF_BMP_DEBUG(dbg() << "BMP has unsupported compression value: " << info.compression);
  521. return false;
  522. }
  523. if (info.number_of_palette_colors > color_palette_limit || info.number_of_important_palette_colors > color_palette_limit) {
  524. IF_BMP_DEBUG(dbg() << "BMP header indicates too many palette colors: " << info.number_of_palette_colors);
  525. return false;
  526. }
  527. // Units (2) + reserved (2)
  528. streamer.drop_bytes(4);
  529. osv2.recording = streamer.read_u16();
  530. osv2.halftoning = streamer.read_u16();
  531. osv2.size1 = streamer.read_u32();
  532. osv2.size2 = streamer.read_u32();
  533. // ColorEncoding (4) + Identifier (4)
  534. streamer.drop_bytes(8);
  535. IF_BMP_DEBUG(dbg() << "BMP compression: " << info.compression);
  536. IF_BMP_DEBUG(dbg() << "BMP image size: " << info.image_size);
  537. IF_BMP_DEBUG(dbg() << "BMP horizontal res: " << info.horizontal_resolution);
  538. IF_BMP_DEBUG(dbg() << "BMP vertical res: " << info.vertical_resolution);
  539. IF_BMP_DEBUG(dbg() << "BMP colors: " << info.number_of_palette_colors);
  540. IF_BMP_DEBUG(dbg() << "BMP important colors: " << info.number_of_important_palette_colors);
  541. return true;
  542. }
  543. static bool decode_bmp_info_dib(BMPLoadingContext& context, Streamer& streamer)
  544. {
  545. if (!decode_bmp_core_dib(context, streamer))
  546. return false;
  547. auto& info = context.dib.info;
  548. auto compression = streamer.read_u32();
  549. info.compression = compression;
  550. if (!is_supported_compression_format(context, compression)) {
  551. IF_BMP_DEBUG(dbg() << "BMP has unsupported compression value: " << compression);
  552. return false;
  553. }
  554. info.image_size = streamer.read_u32();
  555. info.horizontal_resolution = streamer.read_i32();
  556. info.vertical_resolution = streamer.read_i32();
  557. info.number_of_palette_colors = streamer.read_u32();
  558. info.number_of_important_palette_colors = streamer.read_u32();
  559. if (info.number_of_palette_colors > color_palette_limit || info.number_of_important_palette_colors > color_palette_limit) {
  560. IF_BMP_DEBUG(dbg() << "BMP header indicates too many palette colors: " << info.number_of_palette_colors);
  561. return false;
  562. }
  563. if (info.number_of_important_palette_colors == 0)
  564. info.number_of_important_palette_colors = info.number_of_palette_colors;
  565. IF_BMP_DEBUG(dbg() << "BMP compression: " << info.compression);
  566. IF_BMP_DEBUG(dbg() << "BMP image size: " << info.image_size);
  567. IF_BMP_DEBUG(dbg() << "BMP horizontal resolution: " << info.horizontal_resolution);
  568. IF_BMP_DEBUG(dbg() << "BMP vertical resolution: " << info.vertical_resolution);
  569. IF_BMP_DEBUG(dbg() << "BMP palette colors: " << info.number_of_palette_colors);
  570. IF_BMP_DEBUG(dbg() << "BMP important palette colors: " << info.number_of_important_palette_colors);
  571. return true;
  572. }
  573. static bool decode_bmp_v2_dib(BMPLoadingContext& context, Streamer& streamer)
  574. {
  575. if (!decode_bmp_info_dib(context, streamer))
  576. return false;
  577. context.dib.info.masks.append(streamer.read_u32());
  578. context.dib.info.masks.append(streamer.read_u32());
  579. context.dib.info.masks.append(streamer.read_u32());
  580. IF_BMP_DEBUG(dbgprintf("BMP red mask: %08x\n", context.dib.info.masks[0]));
  581. IF_BMP_DEBUG(dbgprintf("BMP green mask: %08x\n", context.dib.info.masks[1]));
  582. IF_BMP_DEBUG(dbgprintf("BMP blue mask: %08x\n", context.dib.info.masks[2]));
  583. return true;
  584. }
  585. static bool decode_bmp_v3_dib(BMPLoadingContext& context, Streamer& streamer)
  586. {
  587. if (!decode_bmp_v2_dib(context, streamer))
  588. return false;
  589. // There is zero documentation about when alpha masks actually get applied.
  590. // Well, there's some, but it's not even close to comprehensive. So, this is
  591. // in no way based off of any spec, it's simply based off of the BMP test
  592. // suite results.
  593. if (context.dib.info.compression == Compression::ALPHABITFIELDS) {
  594. context.dib.info.masks.append(streamer.read_u32());
  595. IF_BMP_DEBUG(dbgprintf("BMP alpha mask: %08x\n", context.dib.info.masks[3]));
  596. } else if (context.dib_size() >= 56 && context.dib.core.bpp >= 16) {
  597. auto mask = streamer.read_u32();
  598. if ((context.dib.core.bpp == 32 && mask != 0) || context.dib.core.bpp == 16) {
  599. context.dib.info.masks.append(mask);
  600. IF_BMP_DEBUG(dbgprintf("BMP alpha mask: %08x\n", mask));
  601. }
  602. } else {
  603. streamer.drop_bytes(4);
  604. }
  605. return true;
  606. }
  607. static bool decode_bmp_v4_dib(BMPLoadingContext& context, Streamer& streamer)
  608. {
  609. if (!decode_bmp_v3_dib(context, streamer))
  610. return false;
  611. auto& v4 = context.dib.v4;
  612. v4.color_space = streamer.read_u32();
  613. v4.red_endpoint = { streamer.read_i32(), streamer.read_i32(), streamer.read_i32() };
  614. v4.green_endpoint = { streamer.read_i32(), streamer.read_i32(), streamer.read_i32() };
  615. v4.blue_endpoint = { streamer.read_i32(), streamer.read_i32(), streamer.read_i32() };
  616. v4.gamma_endpoint = { streamer.read_u32(), streamer.read_u32(), streamer.read_u32() };
  617. IF_BMP_DEBUG(dbg() << "BMP color space: " << v4.color_space);
  618. IF_BMP_DEBUG(dbg() << "BMP red endpoint: " << v4.red_endpoint);
  619. IF_BMP_DEBUG(dbg() << "BMP green endpoint: " << v4.green_endpoint);
  620. IF_BMP_DEBUG(dbg() << "BMP blue endpoint: " << v4.blue_endpoint);
  621. IF_BMP_DEBUG(dbg() << "BMP gamma endpoint: " << v4.gamma_endpoint);
  622. return true;
  623. }
  624. static bool decode_bmp_v5_dib(BMPLoadingContext& context, Streamer& streamer)
  625. {
  626. if (!decode_bmp_v4_dib(context, streamer))
  627. return false;
  628. auto& v5 = context.dib.v5;
  629. v5.intent = streamer.read_u32();
  630. v5.profile_data = streamer.read_u32();
  631. v5.profile_size = streamer.read_u32();
  632. IF_BMP_DEBUG(dbg() << "BMP intent: " << v5.intent);
  633. IF_BMP_DEBUG(dbg() << "BMP profile data: " << v5.profile_data);
  634. IF_BMP_DEBUG(dbg() << "BMP profile size: " << v5.profile_size);
  635. return true;
  636. }
  637. static bool decode_bmp_dib(BMPLoadingContext& context)
  638. {
  639. if (context.state == BMPLoadingContext::State::Error)
  640. return false;
  641. if (context.state >= BMPLoadingContext::State::DIBDecoded)
  642. return true;
  643. if (context.state < BMPLoadingContext::State::HeaderDecoded && !decode_bmp_header(context))
  644. return false;
  645. if (context.data_size < bmp_header_size + 4)
  646. return false;
  647. Streamer streamer(context.data + bmp_header_size, 4);
  648. u32 dib_size = streamer.read_u32();
  649. if (context.data_size < bmp_header_size + dib_size)
  650. return false;
  651. if (context.data_offset < bmp_header_size + dib_size) {
  652. IF_BMP_DEBUG(dbg() << "Shenanigans! BMP pixel data and header usually don't overlap.");
  653. return false;
  654. }
  655. streamer.set_remaining(dib_size - 4);
  656. IF_BMP_DEBUG(dbg() << "BMP dib size: " << dib_size);
  657. bool error = false;
  658. if (dib_size == 12) {
  659. context.dib_type = DIBType::Core;
  660. if (!decode_bmp_core_dib(context, streamer))
  661. error = true;
  662. } else if (dib_size == 64) {
  663. context.dib_type = DIBType::OSV2;
  664. if (!decode_bmp_osv2_dib(context, streamer))
  665. error = true;
  666. } else if (dib_size == 16) {
  667. context.dib_type = DIBType::OSV2Short;
  668. if (!decode_bmp_osv2_dib(context, streamer, true))
  669. error = true;
  670. } else if (dib_size == 40) {
  671. context.dib_type = DIBType::Info;
  672. if (!decode_bmp_info_dib(context, streamer))
  673. error = true;
  674. } else if (dib_size == 52) {
  675. context.dib_type = DIBType::V2;
  676. if (!decode_bmp_v2_dib(context, streamer))
  677. error = true;
  678. } else if (dib_size == 56) {
  679. context.dib_type = DIBType::V3;
  680. if (!decode_bmp_v3_dib(context, streamer))
  681. error = true;
  682. } else if (dib_size == 108) {
  683. context.dib_type = DIBType::V4;
  684. if (!decode_bmp_v4_dib(context, streamer))
  685. error = true;
  686. } else if (dib_size == 124) {
  687. context.dib_type = DIBType::V5;
  688. if (!decode_bmp_v5_dib(context, streamer))
  689. error = true;
  690. } else {
  691. IF_BMP_DEBUG(dbg() << "Unsupported BMP DIB size: " << dib_size);
  692. error = true;
  693. }
  694. switch (context.dib.info.compression) {
  695. case Compression::RGB:
  696. case Compression::RLE8:
  697. case Compression::RLE4:
  698. case Compression::BITFIELDS:
  699. case Compression::RLE24:
  700. case Compression::PNG:
  701. case Compression::ALPHABITFIELDS:
  702. case Compression::CMYK:
  703. case Compression::CMYKRLE8:
  704. case Compression::CMYKRLE4:
  705. break;
  706. default:
  707. error = true;
  708. }
  709. if (!error && !set_dib_bitmasks(context, streamer))
  710. error = true;
  711. if (error) {
  712. IF_BMP_DEBUG(dbg() << "BMP has an invalid DIB");
  713. context.state = BMPLoadingContext::State::Error;
  714. return false;
  715. }
  716. context.state = BMPLoadingContext::State::DIBDecoded;
  717. return true;
  718. }
  719. static bool decode_bmp_color_table(BMPLoadingContext& context)
  720. {
  721. if (context.state == BMPLoadingContext::State::Error)
  722. return false;
  723. if (context.state < BMPLoadingContext::State::DIBDecoded && !decode_bmp_dib(context))
  724. return false;
  725. if (context.state >= BMPLoadingContext::State::ColorTableDecoded)
  726. return true;
  727. if (context.dib.core.bpp > 8) {
  728. context.state = BMPLoadingContext::State::ColorTableDecoded;
  729. return true;
  730. }
  731. auto bytes_per_color = context.dib_type == DIBType::Core ? 3 : 4;
  732. u32 max_colors = 1 << context.dib.core.bpp;
  733. ASSERT(context.data_offset >= bmp_header_size + context.dib_size());
  734. auto size_of_color_table = context.data_offset - bmp_header_size - context.dib_size();
  735. if (context.dib_type <= DIBType::OSV2) {
  736. // Partial color tables are not supported, so the space of the color
  737. // table must be at least enough for the maximum amount of colors
  738. if (size_of_color_table < 3 * max_colors) {
  739. // This is against the spec, but most viewers process it anyways
  740. IF_BMP_DEBUG(dbg() << "BMP with CORE header does not have enough colors. Has: " << size_of_color_table << ", expected: " << (3 * max_colors));
  741. }
  742. }
  743. Streamer streamer(context.data + bmp_header_size + context.dib_size(), size_of_color_table);
  744. for (u32 i = 0; !streamer.at_end() && i < max_colors; ++i) {
  745. if (bytes_per_color == 4) {
  746. if (!streamer.has_u32())
  747. return false;
  748. context.color_table.append(streamer.read_u32());
  749. } else {
  750. if (!streamer.has_u24())
  751. return false;
  752. context.color_table.append(streamer.read_u24());
  753. }
  754. }
  755. context.state = BMPLoadingContext::State::ColorTableDecoded;
  756. return true;
  757. }
  758. struct RLEState {
  759. enum : u8 {
  760. PixelCount = 0,
  761. PixelValue,
  762. Meta, // Represents just consuming a null byte, which indicates something special
  763. };
  764. };
  765. static bool uncompress_bmp_rle_data(BMPLoadingContext& context, ByteBuffer& buffer)
  766. {
  767. // RLE-compressed images cannot be stored top-down
  768. if (context.dib.core.height < 0) {
  769. IF_BMP_DEBUG(dbg() << "BMP is top-down and RLE compressed");
  770. context.state = BMPLoadingContext::State::Error;
  771. return false;
  772. }
  773. Streamer streamer(context.data + context.data_offset, context.data_size);
  774. auto compression = context.dib.info.compression;
  775. u32 total_rows = static_cast<u32>(context.dib.core.height);
  776. u32 total_columns = round_up_to_power_of_two(static_cast<u32>(context.dib.core.width), 4);
  777. u32 column = 0;
  778. u32 row = 0;
  779. auto currently_consuming = RLEState::PixelCount;
  780. i16 pixel_count = 0;
  781. if (compression == Compression::RLE24) {
  782. buffer = ByteBuffer::create_zeroed(total_rows * round_up_to_power_of_two(total_columns, 4) * 4);
  783. } else {
  784. buffer = ByteBuffer::create_zeroed(total_rows * round_up_to_power_of_two(total_columns, 4));
  785. }
  786. // Avoid as many if statements as possible by pulling out
  787. // compression-dependent actions into separate lambdas
  788. Function<u32()> get_buffer_index;
  789. Function<bool(u32, bool)> set_byte;
  790. Function<Optional<u32>()> read_byte;
  791. if (compression == Compression::RLE8) {
  792. get_buffer_index = [&]() -> u32 { return row * total_columns + column; };
  793. } else if (compression == Compression::RLE4) {
  794. get_buffer_index = [&]() -> u32 { return (row * total_columns + column) / 2; };
  795. } else {
  796. get_buffer_index = [&]() -> u32 { return (row * total_columns + column) * 3; };
  797. }
  798. if (compression == Compression::RLE8) {
  799. set_byte = [&](u32 color, bool) -> bool {
  800. if (column >= total_columns) {
  801. column = 0;
  802. row++;
  803. }
  804. auto index = get_buffer_index();
  805. if (index >= buffer.size()) {
  806. IF_BMP_DEBUG(dbg() << "BMP has badly-formatted RLE data");
  807. return false;
  808. }
  809. buffer[index] = color;
  810. column++;
  811. return true;
  812. };
  813. } else if (compression == Compression::RLE24) {
  814. set_byte = [&](u32 color, bool) -> bool {
  815. if (column >= total_columns) {
  816. column = 0;
  817. row++;
  818. }
  819. auto index = get_buffer_index();
  820. if (index + 3 >= buffer.size()) {
  821. IF_BMP_DEBUG(dbg() << "BMP has badly-formatted RLE data");
  822. return false;
  823. }
  824. ((u32&)buffer[index]) = color;
  825. column++;
  826. return true;
  827. };
  828. } else {
  829. set_byte = [&](u32 byte, bool rle4_set_second_nibble) -> bool {
  830. if (column >= total_columns) {
  831. column = 0;
  832. row++;
  833. }
  834. u32 index = get_buffer_index();
  835. if (index >= buffer.size() || (rle4_set_second_nibble && index + 1 >= buffer.size())) {
  836. IF_BMP_DEBUG(dbg() << "BMP has badly-formatted RLE data");
  837. return false;
  838. }
  839. if (column % 2) {
  840. buffer[index] |= byte >> 4;
  841. if (rle4_set_second_nibble) {
  842. buffer[index + 1] |= byte << 4;
  843. column++;
  844. }
  845. } else {
  846. if (rle4_set_second_nibble) {
  847. buffer[index] = byte;
  848. column++;
  849. } else {
  850. buffer[index] |= byte & 0xf0;
  851. }
  852. }
  853. column++;
  854. return true;
  855. };
  856. }
  857. if (compression == Compression::RLE24) {
  858. read_byte = [&]() -> Optional<u32> {
  859. if (!streamer.has_u24()) {
  860. IF_BMP_DEBUG(dbg() << "BMP has badly-formatted RLE data");
  861. return {};
  862. }
  863. return streamer.read_u24();
  864. };
  865. } else {
  866. read_byte = [&]() -> Optional<u32> {
  867. if (!streamer.has_u8()) {
  868. IF_BMP_DEBUG(dbg() << "BMP has badly-formatted RLE data");
  869. return {};
  870. }
  871. return streamer.read_u8();
  872. };
  873. }
  874. while (true) {
  875. u32 byte;
  876. switch (currently_consuming) {
  877. case RLEState::PixelCount:
  878. if (!streamer.has_u8())
  879. return false;
  880. byte = streamer.read_u8();
  881. if (!byte) {
  882. currently_consuming = RLEState::Meta;
  883. } else {
  884. pixel_count = byte;
  885. currently_consuming = RLEState::PixelValue;
  886. }
  887. break;
  888. case RLEState::PixelValue: {
  889. auto result = read_byte();
  890. if (!result.has_value())
  891. return false;
  892. byte = result.value();
  893. for (u8 i = 0; i < pixel_count; ++i) {
  894. if (compression != Compression::RLE4) {
  895. if (!set_byte(byte, true))
  896. return false;
  897. } else {
  898. if (!set_byte(byte, i != pixel_count - 1))
  899. return false;
  900. i++;
  901. }
  902. }
  903. currently_consuming = RLEState::PixelCount;
  904. break;
  905. }
  906. case RLEState::Meta:
  907. if (!streamer.has_u8())
  908. return false;
  909. byte = streamer.read_u8();
  910. if (!byte) {
  911. column = 0;
  912. row++;
  913. currently_consuming = RLEState::PixelCount;
  914. continue;
  915. }
  916. if (byte == 1)
  917. return true;
  918. if (byte == 2) {
  919. if (!streamer.has_u8())
  920. return false;
  921. u8 offset_x = streamer.read_u8();
  922. if (!streamer.has_u8())
  923. return false;
  924. u8 offset_y = streamer.read_u8();
  925. column += offset_x;
  926. if (column >= total_columns) {
  927. column -= total_columns;
  928. row++;
  929. }
  930. row += offset_y;
  931. currently_consuming = RLEState::PixelCount;
  932. continue;
  933. }
  934. // Consume literal bytes
  935. pixel_count = byte;
  936. i16 i = byte;
  937. while (i >= 1) {
  938. auto result = read_byte();
  939. if (!result.has_value())
  940. return false;
  941. byte = result.value();
  942. if (!set_byte(byte, i != 1))
  943. return false;
  944. i--;
  945. if (compression == Compression::RLE4)
  946. i--;
  947. }
  948. // Optionally consume a padding byte
  949. if (compression != Compression::RLE4) {
  950. if (pixel_count % 2) {
  951. if (!streamer.has_u8())
  952. return false;
  953. byte = streamer.read_u8();
  954. }
  955. } else {
  956. if (((pixel_count + 1) / 2) % 2) {
  957. if (!streamer.has_u8())
  958. return false;
  959. byte = streamer.read_u8();
  960. }
  961. }
  962. currently_consuming = RLEState::PixelCount;
  963. break;
  964. }
  965. }
  966. ASSERT_NOT_REACHED();
  967. }
  968. static bool decode_bmp_pixel_data(BMPLoadingContext& context)
  969. {
  970. if (context.state == BMPLoadingContext::State::Error)
  971. return false;
  972. if (context.state <= BMPLoadingContext::State::ColorTableDecoded && !decode_bmp_color_table(context))
  973. return false;
  974. const u16 bits_per_pixel = context.dib.core.bpp;
  975. BitmapFormat format = [&]() -> BitmapFormat {
  976. switch (bits_per_pixel) {
  977. case 1:
  978. return BitmapFormat::Indexed1;
  979. case 2:
  980. return BitmapFormat::Indexed2;
  981. case 4:
  982. return BitmapFormat::Indexed4;
  983. case 8:
  984. return BitmapFormat::Indexed8;
  985. case 16:
  986. if (context.dib.info.masks.size() == 4)
  987. return BitmapFormat::RGBA32;
  988. return BitmapFormat::RGB32;
  989. case 24:
  990. return BitmapFormat::RGB32;
  991. case 32:
  992. return BitmapFormat::RGBA32;
  993. default:
  994. return BitmapFormat::Invalid;
  995. }
  996. }();
  997. if (format == BitmapFormat::Invalid) {
  998. IF_BMP_DEBUG(dbg() << "BMP has invalid bpp of " << bits_per_pixel);
  999. context.state = BMPLoadingContext::State::Error;
  1000. return false;
  1001. }
  1002. const u32 width = abs(context.dib.core.width);
  1003. const u32 height = abs(context.dib.core.height);
  1004. context.bitmap = Bitmap::create_purgeable(format, { static_cast<int>(width), static_cast<int>(height) });
  1005. if (!context.bitmap) {
  1006. IF_BMP_DEBUG(dbg() << "BMP appears to have overly large dimensions");
  1007. return false;
  1008. }
  1009. auto buffer = ByteBuffer::wrap(const_cast<u8*>(context.data + context.data_offset), context.data_size);
  1010. if (context.dib.info.compression == Compression::RLE4 || context.dib.info.compression == Compression::RLE8
  1011. || context.dib.info.compression == Compression::RLE24) {
  1012. if (!uncompress_bmp_rle_data(context, buffer))
  1013. return false;
  1014. }
  1015. Streamer streamer(buffer.data(), buffer.size());
  1016. auto process_row = [&](u32 row) -> bool {
  1017. u32 space_remaining_before_consuming_row = streamer.remaining();
  1018. for (u32 column = 0; column < width;) {
  1019. switch (bits_per_pixel) {
  1020. case 1: {
  1021. if (!streamer.has_u8())
  1022. return false;
  1023. u8 byte = streamer.read_u8();
  1024. u8 mask = 8;
  1025. while (column < width && mask > 0) {
  1026. mask -= 1;
  1027. context.bitmap->scanline_u8(row)[column++] = (byte >> mask) & 0x1;
  1028. }
  1029. break;
  1030. }
  1031. case 2: {
  1032. if (!streamer.has_u8())
  1033. return false;
  1034. u8 byte = streamer.read_u8();
  1035. u8 mask = 8;
  1036. while (column < width && mask > 0) {
  1037. mask -= 2;
  1038. context.bitmap->scanline_u8(row)[column++] = (byte >> mask) & 0x3;
  1039. }
  1040. break;
  1041. }
  1042. case 4: {
  1043. if (!streamer.has_u8())
  1044. return false;
  1045. u8 byte = streamer.read_u8();
  1046. context.bitmap->scanline_u8(row)[column++] = (byte >> 4) & 0xf;
  1047. if (column < width)
  1048. context.bitmap->scanline_u8(row)[column++] = byte & 0xf;
  1049. break;
  1050. }
  1051. case 8:
  1052. if (!streamer.has_u8())
  1053. return false;
  1054. context.bitmap->scanline_u8(row)[column++] = streamer.read_u8();
  1055. break;
  1056. case 16: {
  1057. if (!streamer.has_u16())
  1058. return false;
  1059. context.bitmap->scanline(row)[column++] = int_to_scaled_rgb(context, streamer.read_u16());
  1060. break;
  1061. }
  1062. case 24: {
  1063. if (!streamer.has_u24())
  1064. return false;
  1065. context.bitmap->scanline(row)[column++] = streamer.read_u24();
  1066. break;
  1067. }
  1068. case 32:
  1069. if (!streamer.has_u32())
  1070. return false;
  1071. if (context.dib.info.masks.is_empty()) {
  1072. context.bitmap->scanline(row)[column++] = streamer.read_u32() | 0xff000000;
  1073. } else {
  1074. context.bitmap->scanline(row)[column++] = int_to_scaled_rgb(context, streamer.read_u32());
  1075. }
  1076. break;
  1077. }
  1078. }
  1079. auto consumed = space_remaining_before_consuming_row - streamer.remaining();
  1080. // Calculate padding
  1081. u8 bytes_to_drop = [consumed]() -> u8 {
  1082. switch (consumed % 4) {
  1083. case 0:
  1084. return 0;
  1085. case 1:
  1086. return 3;
  1087. case 2:
  1088. return 2;
  1089. case 3:
  1090. return 1;
  1091. }
  1092. ASSERT_NOT_REACHED();
  1093. }();
  1094. if (streamer.remaining() < bytes_to_drop)
  1095. return false;
  1096. streamer.drop_bytes(bytes_to_drop);
  1097. return true;
  1098. };
  1099. if (context.dib.core.height < 0) {
  1100. // BMP is stored top-down
  1101. for (u32 row = 0; row < height; ++row) {
  1102. if (!process_row(row))
  1103. return false;
  1104. }
  1105. } else {
  1106. for (i32 row = height - 1; row >= 0; --row) {
  1107. if (!process_row(row))
  1108. return false;
  1109. }
  1110. }
  1111. for (size_t i = 0; i < context.color_table.size(); ++i)
  1112. context.bitmap->set_palette_color(i, Color::from_rgb(context.color_table[i]));
  1113. context.state = BMPLoadingContext::State::PixelDataDecoded;
  1114. return true;
  1115. }
  1116. static RefPtr<Bitmap> load_bmp_impl(const u8* data, size_t data_size)
  1117. {
  1118. BMPLoadingContext context;
  1119. context.data = data;
  1120. context.data_size = data_size;
  1121. // Forces a decode of the header, dib, and color table as well
  1122. if (!decode_bmp_pixel_data(context)) {
  1123. context.state = BMPLoadingContext::State::Error;
  1124. return nullptr;
  1125. }
  1126. return context.bitmap;
  1127. }
  1128. BMPImageDecoderPlugin::BMPImageDecoderPlugin(const u8* data, size_t data_size)
  1129. {
  1130. m_context = make<BMPLoadingContext>();
  1131. m_context->data = data;
  1132. m_context->data_size = data_size;
  1133. }
  1134. BMPImageDecoderPlugin::~BMPImageDecoderPlugin()
  1135. {
  1136. }
  1137. IntSize BMPImageDecoderPlugin::size()
  1138. {
  1139. if (m_context->state == BMPLoadingContext::State::Error)
  1140. return {};
  1141. if (m_context->state < BMPLoadingContext::State::DIBDecoded && !decode_bmp_dib(*m_context))
  1142. return {};
  1143. return { m_context->dib.core.width, abs(m_context->dib.core.height) };
  1144. }
  1145. RefPtr<Gfx::Bitmap> BMPImageDecoderPlugin::bitmap()
  1146. {
  1147. if (m_context->state == BMPLoadingContext::State::Error)
  1148. return nullptr;
  1149. if (m_context->state < BMPLoadingContext::State::PixelDataDecoded && !decode_bmp_pixel_data(*m_context))
  1150. return nullptr;
  1151. ASSERT(m_context->bitmap);
  1152. return m_context->bitmap;
  1153. }
  1154. void BMPImageDecoderPlugin::set_volatile()
  1155. {
  1156. if (m_context->bitmap)
  1157. m_context->bitmap->set_volatile();
  1158. }
  1159. bool BMPImageDecoderPlugin::set_nonvolatile()
  1160. {
  1161. if (!m_context->bitmap)
  1162. return false;
  1163. return m_context->bitmap->set_nonvolatile();
  1164. }
  1165. bool BMPImageDecoderPlugin::sniff()
  1166. {
  1167. return decode_bmp_header(*m_context);
  1168. }
  1169. bool BMPImageDecoderPlugin::is_animated()
  1170. {
  1171. return false;
  1172. }
  1173. size_t BMPImageDecoderPlugin::loop_count()
  1174. {
  1175. return 0;
  1176. }
  1177. size_t BMPImageDecoderPlugin::frame_count()
  1178. {
  1179. return 1;
  1180. }
  1181. ImageFrameDescriptor BMPImageDecoderPlugin::frame(size_t i)
  1182. {
  1183. if (i > 0)
  1184. return { bitmap(), 0 };
  1185. return {};
  1186. }
  1187. }