From b25efa219ba6c9195e7b22ee94808a22af903466 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Fri, 6 Oct 2023 18:51:57 +0100 Subject: [PATCH] LibGfx/DDSLoader: Allow image dimensions that are not divisible by 4 --- Tests/LibGfx/TestImageDecoder.cpp | 16 ++++++++++++++++ .../test-inputs/dds/catdog-alert-29x29.dds | Bin 0 -> 1152 bytes .../test-inputs/dds/catdog-alert-32x32.dds | Bin 0 -> 1520 bytes .../Libraries/LibGfx/ImageFormats/DDSLoader.cpp | 12 ++++++------ 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 Tests/LibGfx/test-inputs/dds/catdog-alert-29x29.dds create mode 100644 Tests/LibGfx/test-inputs/dds/catdog-alert-32x32.dds diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index f36a6afe35..001b68acea 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -617,3 +618,18 @@ TEST_CASE(test_jxl_modular_property_8) } } } + +TEST_CASE(test_dds) +{ + Array file_names = { + TEST_INPUT("dds/catdog-alert-29x29.dds"sv), + TEST_INPUT("dds/catdog-alert-32x32.dds"sv) + }; + + for (auto file_name : file_names) { + auto file = MUST(Core::MappedFile::map(file_name)); + EXPECT(Gfx::DDSImageDecoderPlugin::sniff(file->bytes())); + auto plugin_decoder = MUST(Gfx::DDSImageDecoderPlugin::create(file->bytes())); + expect_single_frame(*plugin_decoder); + } +} diff --git a/Tests/LibGfx/test-inputs/dds/catdog-alert-29x29.dds b/Tests/LibGfx/test-inputs/dds/catdog-alert-29x29.dds new file mode 100644 index 0000000000000000000000000000000000000000..9bca08b5ed2ecf760d2fe08d658f83ca456a524c GIT binary patch literal 1152 zcmZ>930A0KU|?Vu;9!ttU;twV76ve2WME+M^mTN1^>uXjboK^|;Ug3n7{FRxB0@~D zsuRE>%8Dw+-Pn2eKwd&POmqoDrI3Z?ERYkyLis&zxmVnBkAgW23=GQ{P6|IhW~>h5 zv&}S1-jcEQ7L3n;W=G+NRLcx z+|N)rS;dnHCe6V5_1lBi)06GF)-W)HmgXifHHI;%cCS4KQ=rq_D0>6Re02NK`TH4S zoZLJouzeQ)Ium1Zn|NsC0|4ZL3l3-+daDago#QXoh$aud-j-+$(tlO- z>eWk+e)j+W_5XkAGX{>ee;MKS1%GRL@IQ1B!{fLAKg<9B`oHikgTSk-f(PFj{3b2w zUnp_ZlYt>LR8&;^=eE0I|9{)RUJT+_RLCl`B``1`B}BCJvG>rn^y+Qt(op}0!u(hI zuHb5Na&j_^U;J(3T^Sh}85n=!U6-taf`Wp}3?3aV9vv--0t^i9;o-60|NQ?b|No=B zdbfi>Qc_ZqvIZ<=Kxs7lBfgj=eKyN~8v2ZZVXEj>FKz<-p1;rhN64NU+3f42Ysormuz14C6tMI5^_qW}X# z0@QK_2K4ZsH2oMqNb=ks1_sqtt5z|v{s;5dZt2~Uj>3PnI01?OYOzXE0TN#|$;r}b Y)v8sDrTjb~^Be>i7$U&(ARYn(0PDF(uK)l5 literal 0 HcmV?d00001 diff --git a/Tests/LibGfx/test-inputs/dds/catdog-alert-32x32.dds b/Tests/LibGfx/test-inputs/dds/catdog-alert-32x32.dds new file mode 100644 index 0000000000000000000000000000000000000000..bc7e1d02d76b5a6e7907ea68fe8d56551557c8b1 GIT binary patch literal 1520 zcmZ>930A0KU|?Vu;9^iuXjboK^|;Uhr$L0VlRLQJu# z;}CGb6lO&eVzp>sKEU_@F3QTlAj7~1=Q6M|@I7FtLy>1-;FEzXU}Y#^U|>L!w`gEy zhs!cBVAzMOm;ogJK^|EMWdD!;{}TTh7(zo`SwZ$QfUSU<2{w=K&&tIh`A|^?kp1=_ z9=BG3_#q(-tPCIiLzRLluzD~HLSXO@G%{O2q`)NWkN*Gv|AXykWo2Y!UD1@=_Kg!#G zUF`yWO{{tN0Apf&6B8R{KSr$h}r10=R>lhFa z01AJY|HHuk|Iz>d0RJDKH4F@_tfHXs0*4PMec%Znr1T569vuISjEoHk|N5VGbaWIz z<_81>Oo4{~e~^6<5fKRttOxl29Owu0MMXtfq4M&0?B{!Mfd3E3zoDU`Q(@*y{P$V& z;>9jd{DK`6{LN>LfdLN^f92v88n58|Pfr&Ieri&H^Zm~zrX(A(?AfvG&zBx;E>8CXLXo* z1(&kq{B4QSF#iAkMmGj#1BT#l>|QUGAOHUE(!_Ltf#<-drwSZZ8Cg{V5skJtw&mW2 zsb^8xmMy(4-5SR4zW=xX|L^(#P2MGXtp3Z)^k0X8N27snfzUe!iK?oKg8vMjpT4nH zG#)QvUG&b-LrId6&QG#Rd928Ph9Q$_E;|1lpFKql|rb~7?Ft!nuF|6~3C&;Nzq zEmSB-Sg`6pt9V311CPn8#S9FY*$H+38Gg!N-#CSv|0n}P=u=i+# decode_dx5_alpha_block(Stream& stream, DDSLoadingContext& c color[7] = 255; } - for (size_t y = 0; y < 4; y++) { - for (size_t x = 0; x < 4; x++) { + for (size_t y = 0; y < 4 && bitmap_y + y < static_cast(context.bitmap->height()); y++) { + for (size_t x = 0; x < 4 && bitmap_x + x < static_cast(context.bitmap->width()); x++) { u8 index = 3 * (4 * y + x); u8 bit_location = floor(index / 8.0); u8 adjusted_index = index - (bit_location * 8); @@ -284,8 +284,8 @@ static ErrorOr decode_dx3_alpha_block(Stream& stream, DDSLoadingContext& c u64 alpha_0 = a0 + 256u * (a1 + 256u * (a2 + 256u * (a3 + 256u))); u64 alpha_1 = a4 + 256u * (a5 + 256u * (a6 + 256u * a7)); - for (size_t y = 0; y < 4; y++) { - for (size_t x = 0; x < 4; x++) { + for (size_t y = 0; y < 4 && bitmap_y + y < static_cast(context.bitmap->height()); y++) { + for (size_t x = 0; x < 4 && bitmap_x + x < static_cast(context.bitmap->width()); x++) { u8 code = 4 * (4 * y + x); if (code >= 32) { @@ -357,8 +357,8 @@ static ErrorOr decode_color_block(Stream& stream, DDSLoadingContext& conte } size_t i = 0; - for (size_t y = 0; y < 4; y++) { - for (size_t x = 0; x < 4; x++) { + for (size_t y = 0; y < 4 && bitmap_y + y < static_cast(context.bitmap->height()); y++) { + for (size_t x = 0; x < 4 && bitmap_x + x < static_cast(context.bitmap->width()); x++) { u8 code_byte = (code >> (i * 2)) & 3; u8 r = rgba[code_byte][0]; u8 g = rgba[code_byte][1];