diff --git a/.gitattributes b/.gitattributes index 07cff8b95e..d71bc86f13 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,7 +3,6 @@ # Denote all files that are truly binary and should not be modified. *.bmp binary -*.dds binary *.gif binary *.jpg binary *.pbm binary diff --git a/AK/Debug.h.in b/AK/Debug.h.in index f9b6494289..3045fe4534 100644 --- a/AK/Debug.h.in +++ b/AK/Debug.h.in @@ -54,10 +54,6 @@ # cmakedefine01 CSS_TOKENIZER_DEBUG #endif -#ifndef DDS_DEBUG -# cmakedefine01 DDS_DEBUG -#endif - #ifndef EDITOR_DEBUG # cmakedefine01 EDITOR_DEBUG #endif diff --git a/Base/res/html/misc/ddssuite.html b/Base/res/html/misc/ddssuite.html deleted file mode 100644 index f8d50e7947..0000000000 --- a/Base/res/html/misc/ddssuite.html +++ /dev/null @@ -1,35 +0,0 @@ - - DDS test suite - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeImage
DXT1
DXT3
DXT5
DXT3 - alpha
DXT5 - alpha
DXT1 - mipmap
- - diff --git a/Base/res/html/misc/ddssuite_files/DXT1-mipmap.dds b/Base/res/html/misc/ddssuite_files/DXT1-mipmap.dds deleted file mode 100644 index 581fc44f5d..0000000000 Binary files a/Base/res/html/misc/ddssuite_files/DXT1-mipmap.dds and /dev/null differ diff --git a/Base/res/html/misc/ddssuite_files/DXT1.dds b/Base/res/html/misc/ddssuite_files/DXT1.dds deleted file mode 100644 index 46c5cb57b5..0000000000 Binary files a/Base/res/html/misc/ddssuite_files/DXT1.dds and /dev/null differ diff --git a/Base/res/html/misc/ddssuite_files/DXT3-alpha.dds b/Base/res/html/misc/ddssuite_files/DXT3-alpha.dds deleted file mode 100644 index 4b1159e77c..0000000000 Binary files a/Base/res/html/misc/ddssuite_files/DXT3-alpha.dds and /dev/null differ diff --git a/Base/res/html/misc/ddssuite_files/DXT3.dds b/Base/res/html/misc/ddssuite_files/DXT3.dds deleted file mode 100644 index a5003f5417..0000000000 Binary files a/Base/res/html/misc/ddssuite_files/DXT3.dds and /dev/null differ diff --git a/Base/res/html/misc/ddssuite_files/DXT5-alpha.dds b/Base/res/html/misc/ddssuite_files/DXT5-alpha.dds deleted file mode 100644 index c5e2be7555..0000000000 Binary files a/Base/res/html/misc/ddssuite_files/DXT5-alpha.dds and /dev/null differ diff --git a/Base/res/html/misc/ddssuite_files/DXT5.dds b/Base/res/html/misc/ddssuite_files/DXT5.dds deleted file mode 100644 index 14f4bcb387..0000000000 Binary files a/Base/res/html/misc/ddssuite_files/DXT5.dds and /dev/null differ diff --git a/Base/res/html/misc/welcome.html b/Base/res/html/misc/welcome.html index fe69ba6915..7d368cb5dc 100644 --- a/Base/res/html/misc/welcome.html +++ b/Base/res/html/misc/welcome.html @@ -218,7 +218,6 @@
  • BMP test suite
  • JPG Images
  • GIF test suite
  • -
  • DDS test suite
  • PBM test suite
  • PGM test suite
  • PPM test suite
  • diff --git a/Meta/CMake/all_the_debug_macros.cmake b/Meta/CMake/all_the_debug_macros.cmake index 07a633eac5..ca78e800ba 100644 --- a/Meta/CMake/all_the_debug_macros.cmake +++ b/Meta/CMake/all_the_debug_macros.cmake @@ -9,7 +9,6 @@ set(CRYPTO_DEBUG ON) set(CSS_LOADER_DEBUG ON) set(CSS_PARSER_DEBUG ON) set(CSS_TOKENIZER_DEBUG ON) -set(DDS_DEBUG ON) set(EDITOR_DEBUG ON) set(EMOJI_DEBUG ON) set(FILE_WATCHER_DEBUG ON) diff --git a/Meta/Lagom/Fuzzers/FuzzDDSLoader.cpp b/Meta/Lagom/Fuzzers/FuzzDDSLoader.cpp deleted file mode 100644 index 400239b1df..0000000000 --- a/Meta/Lagom/Fuzzers/FuzzDDSLoader.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2023, MacDue - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include - -extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size) -{ - AK::set_debug_enabled(false); - auto decoder_or_error = Gfx::DDSImageDecoderPlugin::create({ data, size }); - if (decoder_or_error.is_error()) - return 0; - auto decoder = decoder_or_error.release_value(); - (void)decoder->frame(0); - return 0; -} diff --git a/Meta/Lagom/Fuzzers/fuzzers.cmake b/Meta/Lagom/Fuzzers/fuzzers.cmake index 9098f5b294..6142ad206a 100644 --- a/Meta/Lagom/Fuzzers/fuzzers.cmake +++ b/Meta/Lagom/Fuzzers/fuzzers.cmake @@ -4,7 +4,6 @@ set(FUZZER_TARGETS BLAKE2b BMPLoader Brotli - DDSLoader DeflateCompression DeflateDecompression FlacLoader @@ -68,7 +67,6 @@ set(FUZZER_DEPENDENCIES_BLAKE2b LibCrypto) set(FUZZER_DEPENDENCIES_BMPLoader LibGfx) set(FUZZER_DEPENDENCIES_Brotli LibCompress) set(FUZZER_DEPENDENCIES_CSSParser LibWeb) -set(FUZZER_DEPENDENCIES_DDSLoader LibGfx) set(FUZZER_DEPENDENCIES_DeflateCompression LibCompress) set(FUZZER_DEPENDENCIES_DeflateDecompression LibCompress) set(FUZZER_DEPENDENCIES_ELF LibELF) diff --git a/Meta/gn/secondary/AK/BUILD.gn b/Meta/gn/secondary/AK/BUILD.gn index a55d2ef9ed..85f38776c9 100644 --- a/Meta/gn/secondary/AK/BUILD.gn +++ b/Meta/gn/secondary/AK/BUILD.gn @@ -230,7 +230,6 @@ write_cmake_config("ak_debug_gen") { "CSS_LOADER_DEBUG=", "CSS_PARSER_DEBUG=", "CSS_TOKENIZER_DEBUG=", - "DDS_DEBUG=", "EDITOR_DEBUG=", "EMOJI_DEBUG=", "FILE_WATCHER_DEBUG=", diff --git a/Meta/gn/secondary/Userland/Libraries/LibGfx/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibGfx/BUILD.gn index 472f80f4ec..691dcd5bdc 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibGfx/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibGfx/BUILD.gn @@ -61,7 +61,6 @@ shared_library("LibGfx") { "ImageFormats/BMPWriter.cpp", "ImageFormats/BooleanDecoder.cpp", "ImageFormats/CCITTDecoder.cpp", - "ImageFormats/DDSLoader.cpp", "ImageFormats/GIFLoader.cpp", "ImageFormats/ICOLoader.cpp", "ImageFormats/ILBMLoader.cpp", diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index 18704da9a1..c1646fda9b 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -1463,18 +1462,3 @@ 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 = TRY_OR_FAIL(Core::MappedFile::map(file_name)); - EXPECT(Gfx::DDSImageDecoderPlugin::sniff(file->bytes())); - auto plugin_decoder = TRY_OR_FAIL(Gfx::DDSImageDecoderPlugin::create(file->bytes())); - TRY_OR_FAIL(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 deleted file mode 100644 index 9bca08b5ed..0000000000 Binary files a/Tests/LibGfx/test-inputs/dds/catdog-alert-29x29.dds and /dev/null differ diff --git a/Tests/LibGfx/test-inputs/dds/catdog-alert-32x32.dds b/Tests/LibGfx/test-inputs/dds/catdog-alert-32x32.dds deleted file mode 100644 index bc7e1d02d7..0000000000 Binary files a/Tests/LibGfx/test-inputs/dds/catdog-alert-32x32.dds and /dev/null differ diff --git a/Userland/Libraries/LibCore/MimeData.cpp b/Userland/Libraries/LibCore/MimeData.cpp index 27b6dcf1e0..77feda3e5d 100644 --- a/Userland/Libraries/LibCore/MimeData.cpp +++ b/Userland/Libraries/LibCore/MimeData.cpp @@ -124,7 +124,6 @@ static Array const s_registered_mime_type = { MimeType { .name = "image/tiff"sv, .common_extensions = { ".tiff"sv }, .description = "TIFF image data"sv, .magic_bytes = Vector { 'I', 'I', '*', 0x00 } }, MimeType { .name = "image/tiff"sv, .common_extensions = { ".tiff"sv }, .description = "TIFF image data"sv, .magic_bytes = Vector { 'M', 'M', 0x00, '*' } }, MimeType { .name = "image/tinyvg"sv, .common_extensions = { ".tvg"sv }, .description = "TinyVG vector graphics"sv, .magic_bytes = Vector { 0x72, 0x56 } }, - MimeType { .name = "image/vnd.ms-dds"sv, .common_extensions = { ".dds"sv }, .description = "DDS image data"sv, .magic_bytes = Vector { 'D', 'D', 'S', ' ' } }, MimeType { .name = "image/webp"sv, .common_extensions = { ".webp"sv }, .description = "WebP image data"sv, .magic_bytes = Vector { 'W', 'E', 'B', 'P' }, .offset = 8 }, MimeType { .name = "image/x-icon"sv, .common_extensions = { ".ico"sv }, .description = "ICO image data"sv }, MimeType { .name = "image/x-ilbm"sv, .common_extensions = { ".iff"sv, ".lbm"sv }, .description = "Interleaved bitmap image data"sv, .magic_bytes = Vector { 0x46, 0x4F, 0x52, 0x4F } }, diff --git a/Userland/Libraries/LibGfx/CMakeLists.txt b/Userland/Libraries/LibGfx/CMakeLists.txt index 00b0977a72..8fab476ef7 100644 --- a/Userland/Libraries/LibGfx/CMakeLists.txt +++ b/Userland/Libraries/LibGfx/CMakeLists.txt @@ -38,7 +38,6 @@ set(SOURCES ImageFormats/BMPWriter.cpp ImageFormats/BooleanDecoder.cpp ImageFormats/CCITTDecoder.cpp - ImageFormats/DDSLoader.cpp ImageFormats/GIFLoader.cpp ImageFormats/GIFWriter.cpp ImageFormats/ICOLoader.cpp diff --git a/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.cpp deleted file mode 100644 index 05f878c41b..0000000000 --- a/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.cpp +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Copyright (c) 2021, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Gfx { - -struct DDSLoadingContext { - DDSLoadingContext(FixedMemoryStream stream) - : stream(move(stream)) - { - } - - enum State { - NotDecoded = 0, - Error, - HeaderDecoded, - BitmapDecoded, - }; - - State state { State::NotDecoded }; - - FixedMemoryStream stream; - - DDSHeader header; - DDSHeaderDXT10 header10; - DXGIFormat format; - RefPtr bitmap; - - void dump_debug(); -}; - -static constexpr u32 create_four_cc(char c0, char c1, char c2, char c3) -{ - return c0 | c1 << 8 | c2 << 16 | c3 << 24; -} - -static u64 get_width(DDSHeader header, size_t mipmap_level) -{ - if (mipmap_level >= header.mip_map_count) { - return header.width; - } - - return header.width >> mipmap_level; -} - -static u64 get_height(DDSHeader header, size_t mipmap_level) -{ - if (mipmap_level >= header.mip_map_count) { - return header.height; - } - - return header.height >> mipmap_level; -} - -static constexpr bool has_bitmask(DDSPixelFormat format, u32 r, u32 g, u32 b, u32 a) -{ - return format.r_bit_mask == r && format.g_bit_mask == g && format.b_bit_mask == b && format.a_bit_mask == a; -} - -static DXGIFormat get_format(DDSPixelFormat format) -{ - if ((format.flags & PixelFormatFlags::DDPF_RGB) == PixelFormatFlags::DDPF_RGB) { - switch (format.rgb_bit_count) { - case 32: { - if (has_bitmask(format, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000)) - return DXGI_FORMAT_R8G8B8A8_UNORM; - if (has_bitmask(format, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000)) - return DXGI_FORMAT_B8G8R8A8_UNORM; - if (has_bitmask(format, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000)) - return DXGI_FORMAT_B8G8R8X8_UNORM; - if (has_bitmask(format, 0x3FF00000, 0x000FFC00, 0x000003FF, 0xC0000000)) - return DXGI_FORMAT_R10G10B10A2_UNORM; - if (has_bitmask(format, 0x0000FFFF, 0xFFFF0000, 0x00000000, 0x00000000)) - return DXGI_FORMAT_R16G16_UNORM; - if (has_bitmask(format, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000)) - return DXGI_FORMAT_R32_FLOAT; - break; - } - case 24: - break; - case 16: { - if (has_bitmask(format, 0x7C00, 0x03E0, 0x001F, 0x8000)) - return DXGI_FORMAT_B5G5R5A1_UNORM; - if (has_bitmask(format, 0xF800, 0x07E0, 0x001F, 0x0000)) - return DXGI_FORMAT_B5G6R5_UNORM; - if (has_bitmask(format, 0xF800, 0x07E0, 0x001F, 0x0000)) - return DXGI_FORMAT_B5G6R5_UNORM; - if (has_bitmask(format, 0x0F00, 0x00F0, 0x000F, 0xF000)) - return DXGI_FORMAT_B4G4R4A4_UNORM; - if (has_bitmask(format, 0x00FF, 0x0000, 0x0000, 0xFF00)) - return DXGI_FORMAT_R8G8_UNORM; - if (has_bitmask(format, 0xFFFF, 0x0000, 0x0000, 0x0000)) - return DXGI_FORMAT_R16_UNORM; - break; - } - case 8: { - if (has_bitmask(format, 0xFF, 0x00, 0x00, 0x00)) - return DXGI_FORMAT_R8_UNORM; - break; - } - } - } else if ((format.flags & PixelFormatFlags::DDPF_LUMINANCE) == PixelFormatFlags::DDPF_LUMINANCE) { - switch (format.rgb_bit_count) { - case 16: { - if (has_bitmask(format, 0xFFFF, 0x0000, 0x0000, 0x0000)) - return DXGI_FORMAT_R16_UNORM; - if (has_bitmask(format, 0x00FF, 0x0000, 0x0000, 0xFF00)) - return DXGI_FORMAT_R8G8_UNORM; - break; - } - case 8: { - if (has_bitmask(format, 0xFF, 0x00, 0x00, 0x00)) - return DXGI_FORMAT_R8_UNORM; - - // Some writers mistakenly write this as 8 bpp. - if (has_bitmask(format, 0x00FF, 0x0000, 0x0000, 0xFF00)) - return DXGI_FORMAT_R8G8_UNORM; - break; - } - } - } else if ((format.flags & PixelFormatFlags::DDPF_ALPHA) == PixelFormatFlags::DDPF_ALPHA) { - if (format.rgb_bit_count == 8) - return DXGI_FORMAT_A8_UNORM; - } else if ((format.flags & PixelFormatFlags::DDPF_BUMPDUDV) == PixelFormatFlags::DDPF_BUMPDUDV) { - switch (format.rgb_bit_count) { - case 32: { - if (has_bitmask(format, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000)) - return DXGI_FORMAT_R8G8B8A8_SNORM; - if (has_bitmask(format, 0x0000FFFF, 0xFFFF0000, 0x00000000, 0x00000000)) - return DXGI_FORMAT_R16G16_SNORM; - break; - } - case 16: { - if (has_bitmask(format, 0x00FF, 0xFF00, 0x0000, 0x0000)) - return DXGI_FORMAT_R8G8_SNORM; - break; - } - } - } else if ((format.flags & PixelFormatFlags::DDPF_FOURCC) == PixelFormatFlags::DDPF_FOURCC) { - if (format.four_cc == create_four_cc('D', 'X', 'T', '1')) - return DXGI_FORMAT_BC1_UNORM; - if (format.four_cc == create_four_cc('D', 'X', 'T', '2')) - return DXGI_FORMAT_BC2_UNORM; - if (format.four_cc == create_four_cc('D', 'X', 'T', '3')) - return DXGI_FORMAT_BC2_UNORM; - if (format.four_cc == create_four_cc('D', 'X', 'T', '4')) - return DXGI_FORMAT_BC3_UNORM; - if (format.four_cc == create_four_cc('D', 'X', 'T', '5')) - return DXGI_FORMAT_BC3_UNORM; - if (format.four_cc == create_four_cc('A', 'T', 'I', '1')) - return DXGI_FORMAT_BC4_UNORM; - if (format.four_cc == create_four_cc('B', 'C', '4', 'U')) - return DXGI_FORMAT_BC4_UNORM; - if (format.four_cc == create_four_cc('B', 'C', '4', 'S')) - return DXGI_FORMAT_BC4_SNORM; - if (format.four_cc == create_four_cc('A', 'T', 'I', '2')) - return DXGI_FORMAT_BC5_UNORM; - if (format.four_cc == create_four_cc('B', 'C', '5', 'U')) - return DXGI_FORMAT_BC5_UNORM; - if (format.four_cc == create_four_cc('B', 'C', '5', 'S')) - return DXGI_FORMAT_BC5_SNORM; - if (format.four_cc == create_four_cc('R', 'G', 'B', 'G')) - return DXGI_FORMAT_R8G8_B8G8_UNORM; - if (format.four_cc == create_four_cc('G', 'R', 'G', 'B')) - return DXGI_FORMAT_G8R8_G8B8_UNORM; - if (format.four_cc == create_four_cc('Y', 'U', 'Y', '2')) - return DXGI_FORMAT_YUY2; - - switch (format.four_cc) { - case 36: - return DXGI_FORMAT_R16G16B16A16_UNORM; - case 110: - return DXGI_FORMAT_R16G16B16A16_SNORM; - case 111: - return DXGI_FORMAT_R16_FLOAT; - case 112: - return DXGI_FORMAT_R16G16_FLOAT; - case 113: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case 114: - return DXGI_FORMAT_R32_FLOAT; - case 115: - return DXGI_FORMAT_R32G32_FLOAT; - case 116: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - } - } - - return DXGI_FORMAT_UNKNOWN; -} - -static ErrorOr decode_dx5_alpha_block(Stream& stream, DDSLoadingContext& context, u64 bitmap_x, u64 bitmap_y) -{ - auto color0 = TRY(stream.read_value>()); - auto color1 = TRY(stream.read_value>()); - - auto code0 = TRY(stream.read_value>()); - auto code1 = TRY(stream.read_value>()); - auto code2 = TRY(stream.read_value>()); - auto code3 = TRY(stream.read_value>()); - auto code4 = TRY(stream.read_value>()); - auto code5 = TRY(stream.read_value>()); - - u32 codes[6] = { 0 }; - codes[0] = code0 + 256 * (code1 + 256); - codes[1] = code1 + 256 * (code2 + 256); - codes[2] = code2 + 256 * (code3 + 256); - codes[3] = code3 + 256 * (code4 + 256); - codes[4] = code4 + 256 * code5; - codes[5] = code5; - - u32 color[8] = { 0 }; - - if (color0 > 128) { - color[0] = color0; - } - - if (color1 > 128) { - color[1] = color1; - } - - if (color0 > color1) { - color[2] = (6 * color[0] + 1 * color[1]) / 7; - color[3] = (5 * color[0] + 2 * color[1]) / 7; - color[4] = (4 * color[0] + 3 * color[1]) / 7; - color[5] = (3 * color[0] + 4 * color[1]) / 7; - color[6] = (2 * color[0] + 5 * color[1]) / 7; - color[7] = (1 * color[0] + 6 * color[1]) / 7; - } else { - color[2] = (4 * color[0] + 1 * color[1]) / 5; - color[3] = (3 * color[0] + 2 * color[1]) / 5; - color[4] = (2 * color[0] + 3 * color[1]) / 5; - color[5] = (1 * color[0] + 4 * color[1]) / 5; - color[6] = 0; - color[7] = 255; - } - - 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); - - u8 code = (codes[bit_location] >> adjusted_index) & 7; - u8 alpha = color[code]; - - Color color = Color(0, 0, 0, alpha); - context.bitmap->set_pixel(bitmap_x + x, bitmap_y + y, color); - } - } - - return {}; -} - -static ErrorOr decode_dx3_alpha_block(Stream& stream, DDSLoadingContext& context, u64 bitmap_x, u64 bitmap_y) -{ - auto a0 = TRY(stream.read_value>()); - auto a1 = TRY(stream.read_value>()); - auto a2 = TRY(stream.read_value>()); - auto a3 = TRY(stream.read_value>()); - auto a4 = TRY(stream.read_value>()); - auto a5 = TRY(stream.read_value>()); - auto a6 = TRY(stream.read_value>()); - auto a7 = TRY(stream.read_value>()); - - 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 && 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) { - code = code - 32; - u8 alpha = ((alpha_1 >> code) & 0x0F) * 17; - - Color color = Color(0, 0, 0, alpha); - context.bitmap->set_pixel(bitmap_x + x, bitmap_y + y, color); - } else { - u8 alpha = ((alpha_0 >> code) & 0x0F) * 17; - - Color color = Color(0, 0, 0, alpha); - context.bitmap->set_pixel(bitmap_x + x, bitmap_y + y, color); - } - } - } - - return {}; -} - -static void unpack_rbg_565(u32 rgb, u8* output) -{ - u8 r = (rgb >> 11) & 0x1F; - u8 g = (rgb >> 5) & 0x3F; - u8 b = rgb & 0x1F; - - output[0] = (r << 3) | (r >> 2); - output[1] = (g << 2) | (g >> 4); - output[2] = (b << 3) | (b >> 2); - output[3] = 255; -} - -static ErrorOr decode_color_block(Stream& stream, DDSLoadingContext& context, bool dxt1, u64 bitmap_x, u64 bitmap_y) -{ - auto c0_low = TRY(stream.read_value>()); - auto c0_high = TRY(stream.read_value>()); - auto c1_low = TRY(stream.read_value>()); - auto c1_high = TRY(stream.read_value>()); - - auto codes_0 = TRY(stream.read_value>()); - auto codes_1 = TRY(stream.read_value>()); - auto codes_2 = TRY(stream.read_value>()); - auto codes_3 = TRY(stream.read_value>()); - - u64 code = codes_0 + 256ul * (codes_1 + 256ul * (codes_2 + 256ul * codes_3)); - u32 color_0 = c0_low + (c0_high * 256); - u32 color_1 = c1_low + (c1_high * 256); - - u8 rgba[4][4]; - unpack_rbg_565(color_0, rgba[0]); - unpack_rbg_565(color_1, rgba[1]); - - if (color_0 > color_1) { - for (size_t i = 0; i < 3; i++) { - rgba[2][i] = (2 * rgba[0][i] + rgba[1][i]) / 3; - rgba[3][i] = (rgba[0][i] + 2 * rgba[1][i]) / 3; - } - - rgba[2][3] = 255; - rgba[3][3] = 255; - } else { - for (size_t i = 0; i < 3; i++) { - rgba[2][i] = (rgba[0][i] + rgba[1][i]) / 2; - rgba[3][i] = 0; - } - - rgba[2][3] = 255; - rgba[3][3] = dxt1 ? 0 : 255; - } - - size_t i = 0; - 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]; - u8 b = rgba[code_byte][2]; - u8 a = dxt1 ? rgba[code_byte][3] : context.bitmap->get_pixel(bitmap_x + x, bitmap_y + y).alpha(); - - Color color = Color(r, g, b, a); - context.bitmap->set_pixel(bitmap_x + x, bitmap_y + y, color); - i++; - } - } - - return {}; -} - -static ErrorOr decode_dxt(Stream& stream, DDSLoadingContext& context, u64 width, u64 y) -{ - if (context.format == DXGI_FORMAT_BC1_UNORM) { - for (size_t x = 0; x < width; x += 4) { - TRY(decode_color_block(stream, context, true, x, y)); - } - } - - if (context.format == DXGI_FORMAT_BC2_UNORM) { - for (size_t x = 0; x < width; x += 4) { - TRY(decode_dx3_alpha_block(stream, context, x, y)); - TRY(decode_color_block(stream, context, false, x, y)); - } - } - - if (context.format == DXGI_FORMAT_BC3_UNORM) { - for (size_t x = 0; x < width; x += 4) { - TRY(decode_dx5_alpha_block(stream, context, x, y)); - TRY(decode_color_block(stream, context, false, x, y)); - } - } - - return {}; -} -static ErrorOr decode_bitmap(Stream& stream, DDSLoadingContext& context, u64 width, u64 height) -{ - static constexpr Array dxt_formats = { DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC3_UNORM }; - if (dxt_formats.contains_slow(context.format)) { - for (u64 y = 0; y < height; y += 4) { - TRY(decode_dxt(stream, context, width, y)); - } - } - - // FIXME: Support more encodings (ATI, YUV, RAW, etc...). - return {}; -} - -static ErrorOr decode_header(DDSLoadingContext& context) -{ - // All valid DDS files are at least 128 bytes long. - if (TRY(context.stream.size()) < 128) { - dbgln_if(DDS_DEBUG, "File is too short for DDS"); - context.state = DDSLoadingContext::State::Error; - return Error::from_string_literal("File is too short for DDS"); - } - - auto magic = TRY(context.stream.read_value()); - - if (magic != create_four_cc('D', 'D', 'S', ' ')) { - dbgln_if(DDS_DEBUG, "Missing magic number"); - context.state = DDSLoadingContext::State::Error; - return Error::from_string_literal("Missing magic number"); - } - - context.header = TRY(context.stream.read_value()); - - if (context.header.size != 124) { - dbgln_if(DDS_DEBUG, "Header size is malformed"); - context.state = DDSLoadingContext::State::Error; - return Error::from_string_literal("Header size is malformed"); - } - if (context.header.pixel_format.size != 32) { - dbgln_if(DDS_DEBUG, "Pixel format size is malformed"); - context.state = DDSLoadingContext::State::Error; - return Error::from_string_literal("Pixel format size is malformed"); - } - - if ((context.header.pixel_format.flags & PixelFormatFlags::DDPF_FOURCC) == PixelFormatFlags::DDPF_FOURCC) { - if (context.header.pixel_format.four_cc == create_four_cc('D', 'X', '1', '0')) { - if (TRY(context.stream.size()) < 148) { - dbgln_if(DDS_DEBUG, "DX10 header is too short"); - context.state = DDSLoadingContext::State::Error; - return Error::from_string_literal("DX10 header is too short"); - } - - context.header10 = TRY(context.stream.read_value()); - } - } - - if constexpr (DDS_DEBUG) { - context.dump_debug(); - } - - context.format = get_format(context.header.pixel_format); - - static constexpr Array supported_formats = { DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC3_UNORM }; - if (!supported_formats.contains_slow(context.format)) { - dbgln_if(DDS_DEBUG, "Format of type {} is not supported at the moment", to_underlying(context.format)); - context.state = DDSLoadingContext::State::Error; - return Error::from_string_literal("Format type is not supported at the moment"); - } - - context.state = DDSLoadingContext::HeaderDecoded; - - return {}; -} - -static ErrorOr decode_dds(DDSLoadingContext& context) -{ - VERIFY(context.state == DDSLoadingContext::HeaderDecoded); - - // We support parsing mipmaps, but we only care about the largest one :^) (At least for now) - if (size_t mipmap_level = 0; mipmap_level < max(context.header.mip_map_count, 1u)) { - u64 width = get_width(context.header, mipmap_level); - u64 height = get_height(context.header, mipmap_level); - - context.bitmap = TRY(Bitmap::create(BitmapFormat::BGRA8888, { width, height })); - - TRY(decode_bitmap(context.stream, context, width, height)); - } - - context.state = DDSLoadingContext::State::BitmapDecoded; - - return {}; -} - -void DDSLoadingContext::dump_debug() -{ - StringBuilder builder; - - builder.append("\nDDS:\n"sv); - builder.appendff("\tHeader Size: {}\n", header.size); - - builder.append("\tFlags:"sv); - if ((header.flags & DDSFlags::DDSD_CAPS) == DDSFlags::DDSD_CAPS) - builder.append(" DDSD_CAPS"sv); - if ((header.flags & DDSFlags::DDSD_HEIGHT) == DDSFlags::DDSD_HEIGHT) - builder.append(" DDSD_HEIGHT"sv); - if ((header.flags & DDSFlags::DDSD_WIDTH) == DDSFlags::DDSD_WIDTH) - builder.append(" DDSD_WIDTH"sv); - if ((header.flags & DDSFlags::DDSD_PITCH) == DDSFlags::DDSD_PITCH) - builder.append(" DDSD_PITCH"sv); - if ((header.flags & DDSFlags::DDSD_PIXELFORMAT) == DDSFlags::DDSD_PIXELFORMAT) - builder.append(" DDSD_PIXELFORMAT"sv); - if ((header.flags & DDSFlags::DDSD_MIPMAPCOUNT) == DDSFlags::DDSD_MIPMAPCOUNT) - builder.append(" DDSD_MIPMAPCOUNT"sv); - if ((header.flags & DDSFlags::DDSD_LINEARSIZE) == DDSFlags::DDSD_LINEARSIZE) - builder.append(" DDSD_LINEARSIZE"sv); - if ((header.flags & DDSFlags::DDSD_DEPTH) == DDSFlags::DDSD_DEPTH) - builder.append(" DDSD_DEPTH"sv); - builder.append("\n"sv); - - builder.appendff("\tHeight: {}\n", header.height); - builder.appendff("\tWidth: {}\n", header.width); - builder.appendff("\tPitch: {}\n", header.pitch); - builder.appendff("\tDepth: {}\n", header.depth); - builder.appendff("\tMipmap Count: {}\n", header.mip_map_count); - - builder.append("\tCaps:"sv); - if ((header.caps1 & Caps1Flags::DDSCAPS_COMPLEX) == Caps1Flags::DDSCAPS_COMPLEX) - builder.append(" DDSCAPS_COMPLEX"sv); - if ((header.caps1 & Caps1Flags::DDSCAPS_MIPMAP) == Caps1Flags::DDSCAPS_MIPMAP) - builder.append(" DDSCAPS_MIPMAP"sv); - if ((header.caps1 & Caps1Flags::DDSCAPS_TEXTURE) == Caps1Flags::DDSCAPS_TEXTURE) - builder.append(" DDSCAPS_TEXTURE"sv); - builder.append("\n"sv); - - builder.append("\tCaps2:"sv); - if ((header.caps2 & Caps2Flags::DDSCAPS2_CUBEMAP) == Caps2Flags::DDSCAPS2_CUBEMAP) - builder.append(" DDSCAPS2_CUBEMAP"sv); - if ((header.caps2 & Caps2Flags::DDSCAPS2_CUBEMAP_POSITIVEX) == Caps2Flags::DDSCAPS2_CUBEMAP_POSITIVEX) - builder.append(" DDSCAPS2_CUBEMAP_POSITIVEX"sv); - if ((header.caps2 & Caps2Flags::DDSCAPS2_CUBEMAP_NEGATIVEX) == Caps2Flags::DDSCAPS2_CUBEMAP_NEGATIVEX) - builder.append(" DDSCAPS2_CUBEMAP_NEGATIVEX"sv); - if ((header.caps2 & Caps2Flags::DDSCAPS2_CUBEMAP_POSITIVEY) == Caps2Flags::DDSCAPS2_CUBEMAP_POSITIVEY) - builder.append(" DDSCAPS2_CUBEMAP_POSITIVEY"sv); - if ((header.caps2 & Caps2Flags::DDSCAPS2_CUBEMAP_NEGATIVEY) == Caps2Flags::DDSCAPS2_CUBEMAP_NEGATIVEY) - builder.append(" DDSCAPS2_CUBEMAP_NEGATIVEY"sv); - if ((header.caps2 & Caps2Flags::DDSCAPS2_CUBEMAP_POSITIVEZ) == Caps2Flags::DDSCAPS2_CUBEMAP_POSITIVEZ) - builder.append(" DDSCAPS2_CUBEMAP_POSITIVEZ"sv); - if ((header.caps2 & Caps2Flags::DDSCAPS2_CUBEMAP_NEGATIVEZ) == Caps2Flags::DDSCAPS2_CUBEMAP_NEGATIVEZ) - builder.append(" DDSCAPS2_CUBEMAP_NEGATIVEZ"sv); - if ((header.caps2 & Caps2Flags::DDSCAPS2_VOLUME) == Caps2Flags::DDSCAPS2_VOLUME) - builder.append(" DDSCAPS2_VOLUME"sv); - builder.append("\n"sv); - - builder.append("Pixel Format:\n"sv); - builder.appendff("\tStruct Size: {}\n", header.pixel_format.size); - - builder.append("\tFlags:"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_ALPHAPIXELS) == PixelFormatFlags::DDPF_ALPHAPIXELS) - builder.append(" DDPF_ALPHAPIXELS"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_ALPHA) == PixelFormatFlags::DDPF_ALPHA) - builder.append(" DDPF_ALPHA"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_FOURCC) == PixelFormatFlags::DDPF_FOURCC) - builder.append(" DDPF_FOURCC"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_PALETTEINDEXED8) == PixelFormatFlags::DDPF_PALETTEINDEXED8) - builder.append(" DDPF_PALETTEINDEXED8"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_RGB) == PixelFormatFlags::DDPF_RGB) - builder.append(" DDPF_RGB"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_YUV) == PixelFormatFlags::DDPF_YUV) - builder.append(" DDPF_YUV"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_LUMINANCE) == PixelFormatFlags::DDPF_LUMINANCE) - builder.append(" DDPF_LUMINANCE"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_BUMPDUDV) == PixelFormatFlags::DDPF_BUMPDUDV) - builder.append(" DDPF_BUMPDUDV"sv); - if ((header.pixel_format.flags & PixelFormatFlags::DDPF_NORMAL) == PixelFormatFlags::DDPF_NORMAL) - builder.append(" DDPF_NORMAL"sv); - builder.append("\n"sv); - - builder.append("\tFour CC: "sv); - builder.appendff("{:c}", (header.pixel_format.four_cc >> (8 * 0)) & 0xFF); - builder.appendff("{:c}", (header.pixel_format.four_cc >> (8 * 1)) & 0xFF); - builder.appendff("{:c}", (header.pixel_format.four_cc >> (8 * 2)) & 0xFF); - builder.appendff("{:c}", (header.pixel_format.four_cc >> (8 * 3)) & 0xFF); - builder.append("\n"sv); - builder.appendff("\tRGB Bit Count: {}\n", header.pixel_format.rgb_bit_count); - builder.appendff("\tR Bit Mask: {}\n", header.pixel_format.r_bit_mask); - builder.appendff("\tG Bit Mask: {}\n", header.pixel_format.g_bit_mask); - builder.appendff("\tB Bit Mask: {}\n", header.pixel_format.b_bit_mask); - builder.appendff("\tA Bit Mask: {}\n", header.pixel_format.a_bit_mask); - - builder.append("DDS10:\n"sv); - builder.appendff("\tFormat: {}\n", static_cast(header10.format)); - - builder.append("\tResource Dimension:"sv); - if ((header10.resource_dimension & ResourceDimensions::DDS_DIMENSION_UNKNOWN) == ResourceDimensions::DDS_DIMENSION_UNKNOWN) - builder.append(" DDS_DIMENSION_UNKNOWN"sv); - if ((header10.resource_dimension & ResourceDimensions::DDS_DIMENSION_BUFFER) == ResourceDimensions::DDS_DIMENSION_BUFFER) - builder.append(" DDS_DIMENSION_BUFFER"sv); - if ((header10.resource_dimension & ResourceDimensions::DDS_DIMENSION_TEXTURE1D) == ResourceDimensions::DDS_DIMENSION_TEXTURE1D) - builder.append(" DDS_DIMENSION_TEXTURE1D"sv); - if ((header10.resource_dimension & ResourceDimensions::DDS_DIMENSION_TEXTURE2D) == ResourceDimensions::DDS_DIMENSION_TEXTURE2D) - builder.append(" DDS_DIMENSION_TEXTURE2D"sv); - if ((header10.resource_dimension & ResourceDimensions::DDS_DIMENSION_TEXTURE3D) == ResourceDimensions::DDS_DIMENSION_TEXTURE3D) - builder.append(" DDS_DIMENSION_TEXTURE3D"sv); - builder.append("\n"sv); - - builder.appendff("\tArray Size: {}\n", header10.array_size); - - builder.append("\tMisc Flags:"sv); - if ((header10.misc_flag & MiscFlags::DDS_RESOURCE_MISC_TEXTURECUBE) == MiscFlags::DDS_RESOURCE_MISC_TEXTURECUBE) - builder.append(" DDS_RESOURCE_MISC_TEXTURECUBE"sv); - builder.append("\n"sv); - - builder.append("\tMisc Flags 2:"sv); - if ((header10.misc_flag2 & Misc2Flags::DDS_ALPHA_MODE_UNKNOWN) == Misc2Flags::DDS_ALPHA_MODE_UNKNOWN) - builder.append(" DDS_ALPHA_MODE_UNKNOWN"sv); - if ((header10.misc_flag2 & Misc2Flags::DDS_ALPHA_MODE_STRAIGHT) == Misc2Flags::DDS_ALPHA_MODE_STRAIGHT) - builder.append(" DDS_ALPHA_MODE_STRAIGHT"sv); - if ((header10.misc_flag2 & Misc2Flags::DDS_ALPHA_MODE_PREMULTIPLIED) == Misc2Flags::DDS_ALPHA_MODE_PREMULTIPLIED) - builder.append(" DDS_ALPHA_MODE_PREMULTIPLIED"sv); - if ((header10.misc_flag2 & Misc2Flags::DDS_ALPHA_MODE_OPAQUE) == Misc2Flags::DDS_ALPHA_MODE_OPAQUE) - builder.append(" DDS_ALPHA_MODE_OPAQUE"sv); - if ((header10.misc_flag2 & Misc2Flags::DDS_ALPHA_MODE_CUSTOM) == Misc2Flags::DDS_ALPHA_MODE_CUSTOM) - builder.append(" DDS_ALPHA_MODE_CUSTOM"sv); - builder.append("\n"sv); - - dbgln("{}", builder.to_byte_string()); -} - -DDSImageDecoderPlugin::DDSImageDecoderPlugin(FixedMemoryStream stream) -{ - m_context = make(move(stream)); -} - -DDSImageDecoderPlugin::~DDSImageDecoderPlugin() = default; - -IntSize DDSImageDecoderPlugin::size() -{ - return { m_context->header.width, m_context->header.height }; -} - -bool DDSImageDecoderPlugin::sniff(ReadonlyBytes data) -{ - // The header is always at least 128 bytes, so if the file is smaller, it can't be a DDS. - return data.size() > 128 - && data.data()[0] == 0x44 - && data.data()[1] == 0x44 - && data.data()[2] == 0x53 - && data.data()[3] == 0x20; -} - -ErrorOr> DDSImageDecoderPlugin::create(ReadonlyBytes data) -{ - FixedMemoryStream stream { data }; - auto plugin = TRY(adopt_nonnull_own_or_enomem(new (nothrow) DDSImageDecoderPlugin(move(stream)))); - TRY(decode_header(*plugin->m_context)); - return plugin; -} - -ErrorOr DDSImageDecoderPlugin::frame(size_t index, Optional) -{ - if (index > 0) - return Error::from_string_literal("DDSImageDecoderPlugin: Invalid frame index"); - - if (m_context->state == DDSLoadingContext::State::Error) - return Error::from_string_literal("DDSImageDecoderPlugin: Decoding failed"); - - if (m_context->state < DDSLoadingContext::State::BitmapDecoded) { - TRY(decode_dds(*m_context)); - } - - VERIFY(m_context->bitmap); - return ImageFrameDescriptor { m_context->bitmap, 0 }; -} - -} diff --git a/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.h b/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.h deleted file mode 100644 index 3bc77f1e41..0000000000 --- a/Userland/Libraries/LibGfx/ImageFormats/DDSLoader.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2021, the SerenityOS developers. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include - -namespace Gfx { - -enum MiscFlags : u32 { - DDS_RESOURCE_MISC_TEXTURECUBE = 0x4, -}; - -enum Misc2Flags : u32 { - DDS_ALPHA_MODE_UNKNOWN = 0x0, - DDS_ALPHA_MODE_STRAIGHT = 0x1, - DDS_ALPHA_MODE_PREMULTIPLIED = 0x2, - DDS_ALPHA_MODE_OPAQUE = 0x3, - DDS_ALPHA_MODE_CUSTOM = 0x4, -}; - -enum Caps1Flags : u32 { - DDSCAPS_COMPLEX = 0x8, - DDSCAPS_TEXTURE = 0x1000, - DDSCAPS_MIPMAP = 0x400000, -}; - -enum Caps2Flags : u32 { - DDSCAPS2_CUBEMAP = 0x200, - DDSCAPS2_CUBEMAP_POSITIVEX = 0x400, - DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800, - DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000, - DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000, - DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000, - DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000, - DDSCAPS2_VOLUME = 0x200000, -}; - -enum ResourceDimensions : u32 { - DDS_DIMENSION_UNKNOWN, - DDS_DIMENSION_BUFFER, - DDS_DIMENSION_TEXTURE1D = 2, - DDS_DIMENSION_TEXTURE2D = 3, - DDS_DIMENSION_TEXTURE3D = 4, -}; - -enum DXGIFormat : u32 { - DXGI_FORMAT_UNKNOWN = 0, - DXGI_FORMAT_R32G32B32A32_TYPELESS, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32_TYPELESS, - DXGI_FORMAT_R32G32B32_FLOAT, - DXGI_FORMAT_R32G32B32_UINT, - DXGI_FORMAT_R32G32B32_SINT, - DXGI_FORMAT_R16G16B16A16_TYPELESS, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_UNORM, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_SNORM, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R32G32_TYPELESS, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R32G32_UINT, - DXGI_FORMAT_R32G32_SINT, - DXGI_FORMAT_R32G8X24_TYPELESS, - DXGI_FORMAT_D32_FLOAT_S8X24_UINT, - DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, - DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, - DXGI_FORMAT_R10G10B10A2_TYPELESS, - DXGI_FORMAT_R10G10B10A2_UNORM, - DXGI_FORMAT_R10G10B10A2_UINT, - DXGI_FORMAT_R11G11B10_FLOAT, - DXGI_FORMAT_R8G8B8A8_TYPELESS, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R16G16_TYPELESS, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_R16G16_UNORM, - DXGI_FORMAT_R16G16_UINT, - DXGI_FORMAT_R16G16_SNORM, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_R32_TYPELESS, - DXGI_FORMAT_D32_FLOAT, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R32_UINT, - DXGI_FORMAT_R32_SINT, - DXGI_FORMAT_R24G8_TYPELESS, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS, - DXGI_FORMAT_X24_TYPELESS_G8_UINT, - DXGI_FORMAT_R8G8_TYPELESS, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R8G8_UINT, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_R8G8_SINT, - DXGI_FORMAT_R16_TYPELESS, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_D16_UNORM, - DXGI_FORMAT_R16_UNORM, - DXGI_FORMAT_R16_UINT, - DXGI_FORMAT_R16_SNORM, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_R8_TYPELESS, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R8_UINT, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_R8_SINT, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_R1_UNORM, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP, - DXGI_FORMAT_R8G8_B8G8_UNORM, - DXGI_FORMAT_G8R8_G8B8_UNORM, - DXGI_FORMAT_BC1_TYPELESS, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_BC1_UNORM_SRGB, - DXGI_FORMAT_BC2_TYPELESS, - DXGI_FORMAT_BC2_UNORM, - DXGI_FORMAT_BC2_UNORM_SRGB, - DXGI_FORMAT_BC3_TYPELESS, - DXGI_FORMAT_BC3_UNORM, - DXGI_FORMAT_BC3_UNORM_SRGB, - DXGI_FORMAT_BC4_TYPELESS, - DXGI_FORMAT_BC4_UNORM, - DXGI_FORMAT_BC4_SNORM, - DXGI_FORMAT_BC5_TYPELESS, - DXGI_FORMAT_BC5_UNORM, - DXGI_FORMAT_BC5_SNORM, - DXGI_FORMAT_B5G6R5_UNORM, - DXGI_FORMAT_B5G5R5A1_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8X8_UNORM, - DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, - DXGI_FORMAT_B8G8R8A8_TYPELESS, - DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, - DXGI_FORMAT_B8G8R8X8_TYPELESS, - DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, - DXGI_FORMAT_BC6H_TYPELESS, - DXGI_FORMAT_BC6H_UF16, - DXGI_FORMAT_BC6H_SF16, - DXGI_FORMAT_BC7_TYPELESS, - DXGI_FORMAT_BC7_UNORM, - DXGI_FORMAT_BC7_UNORM_SRGB, - DXGI_FORMAT_AYUV, - DXGI_FORMAT_Y410, - DXGI_FORMAT_Y416, - DXGI_FORMAT_NV12, - DXGI_FORMAT_P010, - DXGI_FORMAT_P016, - DXGI_FORMAT_420_OPAQUE, - DXGI_FORMAT_YUY2, - DXGI_FORMAT_Y210, - DXGI_FORMAT_Y216, - DXGI_FORMAT_NV11, - DXGI_FORMAT_AI44, - DXGI_FORMAT_IA44, - DXGI_FORMAT_P8, - DXGI_FORMAT_A8P8, - DXGI_FORMAT_B4G4R4A4_UNORM, - DXGI_FORMAT_P208, - DXGI_FORMAT_V208, - DXGI_FORMAT_V408, - DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE, - DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE, - DXGI_FORMAT_FORCE_UINT -}; - -enum DDSFlags : u32 { - DDSD_CAPS = 0x1, - DDSD_HEIGHT = 0x2, - DDSD_WIDTH = 0x4, - DDSD_PITCH = 0x8, - DDSD_PIXELFORMAT = 0x1000, - DDSD_MIPMAPCOUNT = 0x20000, - DDSD_LINEARSIZE = 0x80000, - DDSD_DEPTH = 0x800000, -}; - -enum PixelFormatFlags : u32 { - DDPF_ALPHAPIXELS = 0x1, - DDPF_ALPHA = 0x2, - DDPF_FOURCC = 0x4, - DDPF_PALETTEINDEXED8 = 0x20, - DDPF_RGB = 0x40, - DDPF_YUV = 0x200, - DDPF_LUMINANCE = 0x20000, - DDPF_BUMPDUDV = 0x80000, - DDPF_NORMAL = 0x80000000, -}; - -struct [[gnu::packed]] DDSPixelFormat { - u32 size {}; - u32 flags {}; - u32 four_cc {}; - u32 rgb_bit_count {}; - u32 r_bit_mask {}; - u32 g_bit_mask {}; - u32 b_bit_mask {}; - u32 a_bit_mask {}; -}; - -struct [[gnu::packed]] DDSHeader { - u32 size {}; - u32 flags {}; - u32 height {}; - u32 width {}; - u32 pitch {}; - u32 depth {}; - u32 mip_map_count {}; - u32 reserved[11]; - DDSPixelFormat pixel_format; - u32 caps1 {}; - u32 caps2 {}; - u32 caps3 {}; - u32 caps4 {}; - u32 reserved2 {}; -}; - -struct [[gnu::packed]] DDSHeaderDXT10 { - DXGIFormat format {}; - u32 resource_dimension {}; - u32 misc_flag {}; - u32 array_size {}; - u32 misc_flag2 {}; -}; - -struct DDSLoadingContext; - -class DDSImageDecoderPlugin final : public ImageDecoderPlugin { -public: - static bool sniff(ReadonlyBytes); - static ErrorOr> create(ReadonlyBytes); - - virtual ~DDSImageDecoderPlugin() override; - - virtual IntSize size() override; - - virtual ErrorOr frame(size_t index, Optional ideal_size = {}) override; - -private: - DDSImageDecoderPlugin(FixedMemoryStream); - - OwnPtr m_context; -}; - -} - -template<> -struct AK::Traits : public AK::DefaultTraits { - static constexpr bool is_trivially_serializable() { return true; } -}; - -template<> -struct AK::Traits : public AK::DefaultTraits { - static constexpr bool is_trivially_serializable() { return true; } -}; diff --git a/Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.cpp b/Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.cpp index 34e98705b2..6bee4b76d2 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/ImageDecoder.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -36,7 +35,6 @@ static ErrorOr> probe_and_sniff_for_appropriate_plugi static constexpr ImagePluginInitializer s_initializers[] = { { BMPImageDecoderPlugin::sniff, BMPImageDecoderPlugin::create }, - { DDSImageDecoderPlugin::sniff, DDSImageDecoderPlugin::create }, { GIFImageDecoderPlugin::sniff, GIFImageDecoderPlugin::create }, { ICOImageDecoderPlugin::sniff, ICOImageDecoderPlugin::create }, { ILBMImageDecoderPlugin::sniff, ILBMImageDecoderPlugin::create },