BMPLoader.cpp 44 KB

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