From 8f67fbfbc3aadf0092be770106419a0944bf8333 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 21 Dec 2016 02:52:59 +0100 Subject: [PATCH] Added patch to improve TIFF support in windowscodecs.dll. --- patches/patchinstall.sh | 64 +++ ...sts-Add-a-test-for-8bpp-indexed-TIFF.patch | 242 +++++++++ ...sts-Make-the-test-for-8bpp-indexed-T.patch | 33 ++ ...x-the-SupportsTransparency-flag-valu.patch | 62 +++ ...il-earlier-in-TIFF-decoder-s-Initial.patch | 47 ++ ...oid-redundant-checks-when-reading-a-.patch | 103 ++++ ...d-support-for-16bppGray-and-32bppGra.patch | 68 +++ ...d-support-for-3bps-RGB-format-to-TIF.patch | 118 +++++ ...d-support-for-12bpp-RGB-format-to-TI.patch | 66 +++ ...d-support-for-128bppRGBAFloat-format.patch | 82 +++ ...GUID_WICPixelFormat32bppCMYK-definit.patch | 25 + ...d-support-for-32bppCMYK-and-64bppCMY.patch | 95 ++++ ...d-support-for-4bpp-RGBA-format-to-TI.patch | 50 ++ ...d-support-for-16bpp-RGBA-format-to-T.patch | 48 ++ ...d-some-tests-for-various-TIFF-color-.patch | 473 ++++++++++++++++++ ...lerate-partial-reads-in-the-IFD-meta.patch | 161 ++++++ ...support-for-more-image-color-formats.patch | 36 ++ ...d-some-tests-for-loading-TIFF-images.patch | 221 ++++++++ patches/windowscodecs-TIFF_Support/definition | 3 + 19 files changed, 1997 insertions(+) create mode 100644 patches/windowscodecs-TIFF_Support/0001-windowscodecs-tests-Add-a-test-for-8bpp-indexed-TIFF.patch create mode 100644 patches/windowscodecs-TIFF_Support/0002-windowscodecs-tests-Make-the-test-for-8bpp-indexed-T.patch create mode 100644 patches/windowscodecs-TIFF_Support/0003-windowscodecs-Fix-the-SupportsTransparency-flag-valu.patch create mode 100644 patches/windowscodecs-TIFF_Support/0004-windowscodecs-Fail-earlier-in-TIFF-decoder-s-Initial.patch create mode 100644 patches/windowscodecs-TIFF_Support/0005-windowscodecs-Avoid-redundant-checks-when-reading-a-.patch create mode 100644 patches/windowscodecs-TIFF_Support/0006-windowscodecs-Add-support-for-16bppGray-and-32bppGra.patch create mode 100644 patches/windowscodecs-TIFF_Support/0007-windowscodecs-Add-support-for-3bps-RGB-format-to-TIF.patch create mode 100644 patches/windowscodecs-TIFF_Support/0008-windowscodecs-Add-support-for-12bpp-RGB-format-to-TI.patch create mode 100644 patches/windowscodecs-TIFF_Support/0009-windowscodecs-Add-support-for-128bppRGBAFloat-format.patch create mode 100644 patches/windowscodecs-TIFF_Support/0010-include-Fix-the-GUID_WICPixelFormat32bppCMYK-definit.patch create mode 100644 patches/windowscodecs-TIFF_Support/0011-windowscodecs-Add-support-for-32bppCMYK-and-64bppCMY.patch create mode 100644 patches/windowscodecs-TIFF_Support/0012-windowscodecs-Add-support-for-4bpp-RGBA-format-to-TI.patch create mode 100644 patches/windowscodecs-TIFF_Support/0013-windowscodecs-Add-support-for-16bpp-RGBA-format-to-T.patch create mode 100644 patches/windowscodecs-TIFF_Support/0014-windowscodecs-Add-some-tests-for-various-TIFF-color-.patch create mode 100644 patches/windowscodecs-TIFF_Support/0015-windowscodecs-Tolerate-partial-reads-in-the-IFD-meta.patch create mode 100644 patches/windowscodecs-TIFF_Support/0016-gdiplus-Add-support-for-more-image-color-formats.patch create mode 100644 patches/windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch create mode 100644 patches/windowscodecs-TIFF_Support/definition diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index d20acc08..34ca45ae 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -357,6 +357,7 @@ patch_enable_all () enable_windowscodecs_IMILBitmapSource="$1" enable_windowscodecs_IWICPalette_InitializeFromBitmap="$1" enable_windowscodecs_Palette_Images="$1" + enable_windowscodecs_TIFF_Support="$1" enable_windowscodecs_WICCreateBitmapFromSection="$1" enable_wine_inf_Directory_ContextMenuHandlers="$1" enable_wine_inf_Dummy_CA_Certificate="$1" @@ -1258,6 +1259,9 @@ patch_enable () windowscodecs-Palette_Images) enable_windowscodecs_Palette_Images="$2" ;; + windowscodecs-TIFF_Support) + enable_windowscodecs_TIFF_Support="$2" + ;; windowscodecs-WICCreateBitmapFromSection) enable_windowscodecs_WICCreateBitmapFromSection="$2" ;; @@ -2068,6 +2072,17 @@ if test "$enable_wined3d_CSMT_Helper" -eq 1; then enable_wined3d_Silence_FIXMEs=1 fi +if test "$enable_windowscodecs_TIFF_Support" -eq 1; then + if test "$enable_windowscodecs_GIF_Encoder" -gt 1; then + abort "Patchset windowscodecs-GIF_Encoder disabled, but windowscodecs-TIFF_Support depends on that." + fi + if test "$enable_windowscodecs_IWICPalette_InitializeFromBitmap" -gt 1; then + abort "Patchset windowscodecs-IWICPalette_InitializeFromBitmap disabled, but windowscodecs-TIFF_Support depends on that." + fi + enable_windowscodecs_GIF_Encoder=1 + enable_windowscodecs_IWICPalette_InitializeFromBitmap=1 +fi + if test "$enable_windowscodecs_IWICPalette_InitializeFromBitmap" -eq 1; then if test "$enable_gdiplus_Grayscale_PNG" -gt 1; then abort "Patchset gdiplus-Grayscale_PNG disabled, but windowscodecs-IWICPalette_InitializeFromBitmap depends on that." @@ -7478,6 +7493,55 @@ if test "$enable_windowscodecs_IWICPalette_InitializeFromBitmap" -eq 1; then ) >> "$patchlist" fi +# Patchset windowscodecs-TIFF_Support +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * gdiplus-Grayscale_PNG, windowscodecs-32bppGrayFloat, windowscodecs-Palette_Images, windowscodecs-GIF_Encoder, +# | windowscodecs-IWICPalette_InitializeFromBitmap +# | +# | Modified files: +# | * dlls/gdiplus/image.c, dlls/gdiplus/tests/image.c, dlls/windowscodecs/metadatahandler.c, dlls/windowscodecs/regsvr.c, +# | dlls/windowscodecs/tests/tiffformat.c, dlls/windowscodecs/tiffformat.c, include/wincodec.idl +# | +if test "$enable_windowscodecs_TIFF_Support" -eq 1; then + patch_apply windowscodecs-TIFF_Support/0001-windowscodecs-tests-Add-a-test-for-8bpp-indexed-TIFF.patch + patch_apply windowscodecs-TIFF_Support/0002-windowscodecs-tests-Make-the-test-for-8bpp-indexed-T.patch + patch_apply windowscodecs-TIFF_Support/0003-windowscodecs-Fix-the-SupportsTransparency-flag-valu.patch + patch_apply windowscodecs-TIFF_Support/0004-windowscodecs-Fail-earlier-in-TIFF-decoder-s-Initial.patch + patch_apply windowscodecs-TIFF_Support/0005-windowscodecs-Avoid-redundant-checks-when-reading-a-.patch + patch_apply windowscodecs-TIFF_Support/0006-windowscodecs-Add-support-for-16bppGray-and-32bppGra.patch + patch_apply windowscodecs-TIFF_Support/0007-windowscodecs-Add-support-for-3bps-RGB-format-to-TIF.patch + patch_apply windowscodecs-TIFF_Support/0008-windowscodecs-Add-support-for-12bpp-RGB-format-to-TI.patch + patch_apply windowscodecs-TIFF_Support/0009-windowscodecs-Add-support-for-128bppRGBAFloat-format.patch + patch_apply windowscodecs-TIFF_Support/0010-include-Fix-the-GUID_WICPixelFormat32bppCMYK-definit.patch + patch_apply windowscodecs-TIFF_Support/0011-windowscodecs-Add-support-for-32bppCMYK-and-64bppCMY.patch + patch_apply windowscodecs-TIFF_Support/0012-windowscodecs-Add-support-for-4bpp-RGBA-format-to-TI.patch + patch_apply windowscodecs-TIFF_Support/0013-windowscodecs-Add-support-for-16bpp-RGBA-format-to-T.patch + patch_apply windowscodecs-TIFF_Support/0014-windowscodecs-Add-some-tests-for-various-TIFF-color-.patch + patch_apply windowscodecs-TIFF_Support/0015-windowscodecs-Tolerate-partial-reads-in-the-IFD-meta.patch + patch_apply windowscodecs-TIFF_Support/0016-gdiplus-Add-support-for-more-image-color-formats.patch + patch_apply windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch + ( + echo '+ { "Dmitry Timoshkov", "windowscodecs/tests: Add a test for 8bpp indexed TIFF format.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs/tests: Make the test for 8bpp indexed TIFF format run under XP.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Fix the SupportsTransparency flag value for various pixel formats.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Fail earlier in TIFF decoder'\''s Initialize method for unsupported pixel formats.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Avoid redundant checks when reading a TIFF tile.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Add support for 16bppGray and 32bppGrayFloat formats to TIFF decoder.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Add support for 3bps RGB format to TIFF decoder.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Add support for 12bpp RGB format to TIFF decoder.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Add support for 128bppRGBAFloat format to TIFF decoder.", 1 },'; + echo '+ { "Dmitry Timoshkov", "include: Fix the GUID_WICPixelFormat32bppCMYK definition.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Add support for 32bppCMYK and 64bppCMYK formats to TIFF decoder.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Add support for 4bpp RGBA format to TIFF decoder.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Add support for 16bpp RGBA format to TIFF decoder.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Add some tests for various TIFF color formats.", 1 },'; + echo '+ { "Dmitry Timoshkov", "windowscodecs: Tolerate partial reads in the IFD metadata loader.", 1 },'; + echo '+ { "Dmitry Timoshkov", "gdiplus: Add support for more image color formats.", 1 },'; + echo '+ { "Dmitry Timoshkov", "gdiplus/tests: Add some tests for loading TIFF images in various color formats.", 1 },'; + ) >> "$patchlist" +fi + # Patchset windowscodecs-WICCreateBitmapFromSection # | # | This patchset fixes the following Wine bugs: diff --git a/patches/windowscodecs-TIFF_Support/0001-windowscodecs-tests-Add-a-test-for-8bpp-indexed-TIFF.patch b/patches/windowscodecs-TIFF_Support/0001-windowscodecs-tests-Add-a-test-for-8bpp-indexed-TIFF.patch new file mode 100644 index 00000000..e73128ff --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0001-windowscodecs-tests-Add-a-test-for-8bpp-indexed-TIFF.patch @@ -0,0 +1,242 @@ +From b303a2aee86042ffd0fe3881f7831be247ad6c2c Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Mon, 28 Nov 2016 21:17:59 +0800 +Subject: windowscodecs/tests: Add a test for 8bpp indexed TIFF format. + +--- + dlls/windowscodecs/tests/tiffformat.c | 174 ++++++++++++++++++++++++++++++---- + 1 file changed, 154 insertions(+), 20 deletions(-) + +diff --git a/dlls/windowscodecs/tests/tiffformat.c b/dlls/windowscodecs/tests/tiffformat.c +index e4a4b66..3291b48 100644 +--- a/dlls/windowscodecs/tests/tiffformat.c ++++ b/dlls/windowscodecs/tests/tiffformat.c +@@ -134,6 +134,49 @@ static const struct tiff_8bpp_alpha + { 96, 1 }, + { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 } + }; ++ ++static const struct tiff_8bpp_data ++{ ++ USHORT byte_order; ++ USHORT version; ++ ULONG dir_offset; ++ USHORT number_of_entries; ++ struct IFD_entry entry[14]; ++ ULONG next_IFD; ++ struct IFD_rational res; ++ short palette_data[3][256]; ++ BYTE pixel_data[4]; ++} tiff_8bpp_data = ++{ ++#ifdef WORDS_BIGENDIAN ++ 'M' | 'M' << 8, ++#else ++ 'I' | 'I' << 8, ++#endif ++ 42, ++ FIELD_OFFSET(struct tiff_8bpp_data, number_of_entries), ++ 14, ++ { ++ { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ ++ { 0x100, IFD_LONG, 1, 4 }, /* IMAGEWIDTH */ ++ { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ ++ { 0x102, IFD_LONG, 1, 8 }, /* BITSPERSAMPLE */ ++ { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ ++ { 0x106, IFD_SHORT, 1, 3 }, /* PHOTOMETRIC */ ++ { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_8bpp_data, pixel_data) }, /* STRIPOFFSETS */ ++ { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */ ++ { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */ ++ { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */ ++ { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_data, res) }, ++ { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_8bpp_data, res) }, ++ { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ ++ { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_8bpp_data, palette_data) } /* COLORMAP */ ++ }, ++ 0, ++ { 96, 1 }, ++ { { 0 } }, ++ { 0,1,2,3 } ++}; + #include "poppack.h" + + static IWICImagingFactory *factory; +@@ -159,29 +202,41 @@ static IStream *create_stream(const void *data, int data_size) + return stream; + } + +-static IWICBitmapDecoder *create_decoder(const void *image_data, UINT image_size) ++static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitmapDecoder **decoder) + { ++ HGLOBAL hmem; ++ BYTE *data; + HRESULT hr; + IStream *stream; +- IWICBitmapDecoder *decoder = NULL; +- GUID guid; ++ GUID format; ++ LONG refcount; + +- stream = create_stream(image_data, image_size); ++ *decoder = NULL; + +- hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, &decoder); +- ok(hr == S_OK, "CreateDecoderFromStream error %#x\n", hr); +- if (FAILED(hr)) return NULL; ++ hmem = GlobalAlloc(0, image_size); ++ data = GlobalLock(hmem); ++ memcpy(data, image_data, image_size); ++ GlobalUnlock(hmem); + +- hr = IWICBitmapDecoder_GetContainerFormat(decoder, &guid); +- ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); +- ok(IsEqualGUID(&guid, &GUID_ContainerFormatTiff), "container format is not TIFF\n"); ++ hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); ++ ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); + +- IStream_Release(stream); ++ hr = IWICImagingFactory_CreateDecoderFromStream(factory, stream, NULL, 0, decoder); ++ if (hr == S_OK) ++ { ++ hr = IWICBitmapDecoder_GetContainerFormat(*decoder, &format); ++ ok(hr == S_OK, "GetContainerFormat error %#x\n", hr); ++ ok(IsEqualGUID(&format, &GUID_ContainerFormatTiff), ++ "wrong container format %s\n", wine_dbgstr_guid(&format)); ++ ++ refcount = IStream_Release(stream); ++ ok(refcount > 0, "expected stream refcount > 0\n"); ++ } + +- return decoder; ++ return hr; + } + +-static void test_tiff_palette(void) ++static void test_tiff_1bpp_palette(void) + { + HRESULT hr; + IWICBitmapDecoder *decoder; +@@ -189,9 +244,9 @@ static void test_tiff_palette(void) + IWICPalette *palette; + GUID format; + +- decoder = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data)); +- ok(decoder != 0, "Failed to load TIFF image data\n"); +- if (!decoder) return; ++ hr = create_decoder(&tiff_1bpp_data, sizeof(tiff_1bpp_data), &decoder); ++ ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); ++ if (hr != S_OK) return; + + hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); + ok(hr == S_OK, "GetFrame error %#x\n", hr); +@@ -323,9 +378,9 @@ static void test_tiff_8bpp_alpha(void) + static const BYTE expected_data[16] = { 0x11,0x11,0x11,0x22,0x33,0x33,0x33,0x44, + 0x55,0x55,0x55,0x66,0x77,0x77,0x77,0x88 }; + +- decoder = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha)); +- ok(decoder != 0, "Failed to load TIFF image data\n"); +- if (!decoder) return; ++ hr = create_decoder(&tiff_8bpp_alpha, sizeof(tiff_8bpp_alpha), &decoder); ++ ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); ++ if (hr != S_OK) return; + + hr = IWICBitmapDecoder_GetFrameCount(decoder, &frame_count); + ok(hr == S_OK, "GetFrameCount error %#x\n", hr); +@@ -370,6 +425,84 @@ static void test_tiff_8bpp_alpha(void) + IWICBitmapDecoder_Release(decoder); + } + ++static void generate_tiff_palette(void *buf, unsigned count) ++{ ++ unsigned short *r, *g, *b; ++ unsigned i; ++ ++ r = buf; ++ g = r + count; ++ b = g + count; ++ ++ r[0] = 0x11 * 257; ++ g[0] = 0x22 * 257; ++ b[0] = 0x33 * 257; ++ r[1] = 0x44 * 257; ++ g[1] = 0x55 * 257; ++ b[1] = 0x66 * 257; ++ r[2] = 0x77 * 257; ++ g[2] = 0x88 * 257; ++ b[2] = 0x99 * 257; ++ r[3] = 0xa1 * 257; ++ g[3] = 0xb5 * 257; ++ b[3] = 0xff * 257; ++ ++ for (i = 4; i < count; i++) ++ { ++ r[i] = i * 257; ++ g[i] = (i | 0x40) * 257; ++ b[i] = (i | 0x80) * 257; ++ } ++} ++ ++static void test_tiff_8bpp_palette(void) ++{ ++ char buf[sizeof(tiff_8bpp_data)]; ++ HRESULT hr; ++ IWICBitmapDecoder *decoder; ++ IWICBitmapFrameDecode *frame; ++ IWICPalette *palette; ++ GUID format; ++ UINT count, ret; ++ WICColor color[256]; ++ ++ memcpy(buf, &tiff_8bpp_data, sizeof(tiff_8bpp_data)); ++ generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_8bpp_data, palette_data), 256); ++ ++ hr = create_decoder(buf, sizeof(buf), &decoder); ++ ok(hr == S_OK, "Failed to load TIFF image data %#x\n", hr); ++ if (hr != S_OK) return; ++ ++ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ++ ok(hr == S_OK, "GetFrame error %#x\n", hr); ++ ++ hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ++ ok(hr == S_OK, "GetPixelFormat error %#x\n", hr); ++ ok(IsEqualGUID(&format, &GUID_WICPixelFormat8bppIndexed), ++ "expected GUID_WICPixelFormat8bppIndexed, got %s\n", wine_dbgstr_guid(&format)); ++ ++ hr = IWICImagingFactory_CreatePalette(factory, &palette); ++ ok(hr == S_OK, "CreatePalette error %#x\n", hr); ++ hr = IWICBitmapFrameDecode_CopyPalette(frame, palette); ++ ok(hr == S_OK, "CopyPalette error %#x\n", hr); ++ ++ hr = IWICPalette_GetColorCount(palette, &count); ++ ok(hr == S_OK, "GetColorCount error %#x\n", hr); ++ ok(count == 256, "expected 256, got %u\n", count); ++ ++ hr = IWICPalette_GetColors(palette, 256, color, &ret); ++ ok(hr == S_OK, "GetColors error %#x\n", hr); ++ ok(ret == count, "expected %u, got %u\n", count, ret); ++ ok(color[0] == 0xff112233, "got %#x\n", color[0]); ++ ok(color[1] == 0xff445566, "got %#x\n", color[1]); ++ ok(color[2] == 0xff778899, "got %#x\n", color[2]); ++ ok(color[3] == 0xffa1b5ff, "got %#x\n", color[3]); ++ ++ IWICPalette_Release(palette); ++ IWICBitmapFrameDecode_Release(frame); ++ IWICBitmapDecoder_Release(decoder); ++} ++ + START_TEST(tiffformat) + { + HRESULT hr; +@@ -381,7 +514,8 @@ START_TEST(tiffformat) + ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + if (FAILED(hr)) return; + +- test_tiff_palette(); ++ test_tiff_1bpp_palette(); ++ test_tiff_8bpp_palette(); + test_QueryCapability(); + test_tiff_8bpp_alpha(); + +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0002-windowscodecs-tests-Make-the-test-for-8bpp-indexed-T.patch b/patches/windowscodecs-TIFF_Support/0002-windowscodecs-tests-Make-the-test-for-8bpp-indexed-T.patch new file mode 100644 index 00000000..6f6d3167 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0002-windowscodecs-tests-Make-the-test-for-8bpp-indexed-T.patch @@ -0,0 +1,33 @@ +From 2ce792b674a71ef69b83421269cac9c3a6b1a621 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:10:29 +0800 +Subject: windowscodecs/tests: Make the test for 8bpp indexed TIFF format run + under XP. + +--- + dlls/windowscodecs/tests/tiffformat.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/dlls/windowscodecs/tests/tiffformat.c b/dlls/windowscodecs/tests/tiffformat.c +index 3291b48..a742627 100644 +--- a/dlls/windowscodecs/tests/tiffformat.c ++++ b/dlls/windowscodecs/tests/tiffformat.c +@@ -1,5 +1,5 @@ + /* +- * Copyright 2012 Dmitry Timoshkov ++ * Copyright 2012,2016 Dmitry Timoshkov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -160,7 +160,7 @@ static const struct tiff_8bpp_data + { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ + { 0x100, IFD_LONG, 1, 4 }, /* IMAGEWIDTH */ + { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ +- { 0x102, IFD_LONG, 1, 8 }, /* BITSPERSAMPLE */ ++ { 0x102, IFD_SHORT, 1, 8 }, /* BITSPERSAMPLE: XP doesn't accept IFD_LONG here */ + { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ + { 0x106, IFD_SHORT, 1, 3 }, /* PHOTOMETRIC */ + { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_8bpp_data, pixel_data) }, /* STRIPOFFSETS */ +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0003-windowscodecs-Fix-the-SupportsTransparency-flag-valu.patch b/patches/windowscodecs-TIFF_Support/0003-windowscodecs-Fix-the-SupportsTransparency-flag-valu.patch new file mode 100644 index 00000000..a8d17ebd --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0003-windowscodecs-Fix-the-SupportsTransparency-flag-valu.patch @@ -0,0 +1,62 @@ +From cd8ae040a9f84ac17905714a527713f7ed80dd7f Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:12:31 +0800 +Subject: windowscodecs: Fix the SupportsTransparency flag value for various + pixel formats. + +--- + dlls/windowscodecs/regsvr.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c +index 4516d3f..ca9ca94 100644 +--- a/dlls/windowscodecs/regsvr.c ++++ b/dlls/windowscodecs/regsvr.c +@@ -1784,7 +1784,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { + 1, /* channel count */ + channel_masks_1bit, + WICPixelFormatNumericRepresentationIndexed, +- 1 ++ 0 + }, + { &GUID_WICPixelFormat2bppIndexed, + "The Wine Project", +@@ -1795,7 +1795,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { + 1, /* channel count */ + channel_masks_2bit, + WICPixelFormatNumericRepresentationIndexed, +- 1 ++ 0 + }, + { &GUID_WICPixelFormat4bppIndexed, + "The Wine Project", +@@ -1806,7 +1806,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { + 1, /* channel count */ + channel_masks_4bit, + WICPixelFormatNumericRepresentationIndexed, +- 1 ++ 0 + }, + { &GUID_WICPixelFormat8bppIndexed, + "The Wine Project", +@@ -1817,7 +1817,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { + 1, /* channel count */ + channel_masks_8bit, + WICPixelFormatNumericRepresentationIndexed, +- 1 ++ 0 + }, + { &GUID_WICPixelFormatBlackWhite, + "The Wine Project", +@@ -1971,7 +1971,7 @@ static struct regsvr_pixelformat const pixelformat_list[] = { + 1, /* channel count */ + channel_masks_32bit, + WICPixelFormatNumericRepresentationFloat, +- 1 ++ 0 + }, + { &GUID_WICPixelFormat48bppRGB, + "The Wine Project", +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0004-windowscodecs-Fail-earlier-in-TIFF-decoder-s-Initial.patch b/patches/windowscodecs-TIFF_Support/0004-windowscodecs-Fail-earlier-in-TIFF-decoder-s-Initial.patch new file mode 100644 index 00000000..d0e3c62d --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0004-windowscodecs-Fail-earlier-in-TIFF-decoder-s-Initial.patch @@ -0,0 +1,47 @@ +From 31f25db57624b0c9eb71e65499621180f7eb8336 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:14:37 +0800 +Subject: windowscodecs: Fail earlier in TIFF decoder's Initialize method for + unsupported pixel formats. + +--- + dlls/windowscodecs/tiffformat.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index 12e03f2..89ebb4d 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -631,6 +631,7 @@ static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream * + { + TiffDecoder *This = impl_from_IWICBitmapDecoder(iface); + TIFF *tiff; ++ tiff_decode_info decode_info; + HRESULT hr=S_OK; + + TRACE("(%p,%p,%x)\n", iface, pIStream, cacheOptions); +@@ -644,13 +645,20 @@ static HRESULT WINAPI TiffDecoder_Initialize(IWICBitmapDecoder *iface, IStream * + } + + tiff = tiff_open_stream(pIStream, "r"); +- + if (!tiff) + { + hr = E_FAIL; + goto exit; + } + ++ /* make sure that TIFF format is supported */ ++ hr = tiff_get_decode_info(tiff, &decode_info); ++ if (hr != S_OK) ++ { ++ pTIFFClose(tiff); ++ goto exit; ++ } ++ + This->tiff = tiff; + This->stream = pIStream; + IStream_AddRef(pIStream); +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0005-windowscodecs-Avoid-redundant-checks-when-reading-a-.patch b/patches/windowscodecs-TIFF_Support/0005-windowscodecs-Avoid-redundant-checks-when-reading-a-.patch new file mode 100644 index 00000000..7f3556d9 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0005-windowscodecs-Avoid-redundant-checks-when-reading-a-.patch @@ -0,0 +1,103 @@ +From 12dcbc874f228a3e3ff1f3ef4f2918487430ad45 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:19:55 +0800 +Subject: windowscodecs: Avoid redundant checks when reading a TIFF tile. + +--- + dlls/windowscodecs/tiffformat.c | 40 ++++++++++++++-------------------------- + 1 file changed, 14 insertions(+), 26 deletions(-) + +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index 89ebb4d..c72fadf 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -974,34 +974,25 @@ static HRESULT WINAPI TiffFrameDecode_CopyPalette(IWICBitmapFrameDecode *iface, + + static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT tile_y) + { +- HRESULT hr=S_OK; + tsize_t ret; + int swap_bytes; + + swap_bytes = pTIFFIsByteSwapped(This->parent->tiff); + + ret = pTIFFSetDirectory(This->parent->tiff, This->index); +- + if (ret == -1) +- hr = E_FAIL; ++ return E_FAIL; + +- if (hr == S_OK) +- { +- if (This->decode_info.tiled) +- { +- ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size); +- } +- else +- { +- ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size); +- } ++ if (This->decode_info.tiled) ++ ret = pTIFFReadEncodedTile(This->parent->tiff, tile_x + tile_y * This->decode_info.tiles_across, This->cached_tile, This->decode_info.tile_size); ++ else ++ ret = pTIFFReadEncodedStrip(This->parent->tiff, tile_y, This->cached_tile, This->decode_info.tile_size); + +- if (ret == -1) +- hr = E_FAIL; +- } ++ if (ret == -1) ++ return E_FAIL; + + /* 8bpp grayscale with extra alpha */ +- if (hr == S_OK && This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) ++ if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) + { + BYTE *src; + DWORD *dst, count = This->decode_info.tile_width * This->decode_info.tile_height; +@@ -1016,7 +1007,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT + } + } + +- if (hr == S_OK && This->decode_info.reverse_bgr) ++ if (This->decode_info.reverse_bgr) + { + if (This->decode_info.bps == 8) + { +@@ -1027,7 +1018,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT + } + } + +- if (hr == S_OK && swap_bytes && This->decode_info.bps > 8) ++ if (swap_bytes && This->decode_info.bps > 8) + { + UINT row, i, samples_per_row; + BYTE *sample, temp; +@@ -1055,7 +1046,7 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT + } + } + +- if (hr == S_OK && This->decode_info.invert_grayscale) ++ if (This->decode_info.invert_grayscale) + { + BYTE *byte, *end; + +@@ -1071,13 +1062,10 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT + *byte = ~(*byte); + } + +- if (hr == S_OK) +- { +- This->cached_tile_x = tile_x; +- This->cached_tile_y = tile_y; +- } ++ This->cached_tile_x = tile_x; ++ This->cached_tile_y = tile_y; + +- return hr; ++ return S_OK; + } + + static HRESULT WINAPI TiffFrameDecode_CopyPixels(IWICBitmapFrameDecode *iface, +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0006-windowscodecs-Add-support-for-16bppGray-and-32bppGra.patch b/patches/windowscodecs-TIFF_Support/0006-windowscodecs-Add-support-for-16bppGray-and-32bppGra.patch new file mode 100644 index 00000000..1eb72f7f --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0006-windowscodecs-Add-support-for-16bppGray-and-32bppGra.patch @@ -0,0 +1,68 @@ +From a528571c8c5ffd11b0fbc4c2f16a4374dc766b76 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:28:02 +0800 +Subject: windowscodecs: Add support for 16bppGray and 32bppGrayFloat formats + to TIFF decoder. + +--- + dlls/windowscodecs/regsvr.c | 2 ++ + dlls/windowscodecs/tiffformat.c | 22 ++++++++++++++++++++-- + 2 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c +index ca9ca94..d1649fa 100644 +--- a/dlls/windowscodecs/regsvr.c ++++ b/dlls/windowscodecs/regsvr.c +@@ -1211,6 +1211,8 @@ static GUID const * const tiff_decode_formats[] = { + &GUID_WICPixelFormatBlackWhite, + &GUID_WICPixelFormat4bppGray, + &GUID_WICPixelFormat8bppGray, ++ &GUID_WICPixelFormat16bppGray, ++ &GUID_WICPixelFormat32bppGrayFloat, + &GUID_WICPixelFormat1bppIndexed, + &GUID_WICPixelFormat2bppIndexed, + &GUID_WICPixelFormat4bppIndexed, +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index c72fadf..166bacd 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -319,6 +319,8 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) + } + decode_info->planar = planar; + ++ TRACE("planar %u, photometric %u, samples %u, bps %u\n", planar, photometric, samples, bps); ++ + switch(photometric) + { + case 0: /* WhiteIsZero */ +@@ -383,9 +385,25 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) + } + } + break; ++ case 16: ++ if (samples != 1) ++ { ++ FIXME("unhandled 16bpp grayscale sample count %u\n", samples); ++ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; ++ } ++ decode_info->format = &GUID_WICPixelFormat16bppGray; ++ break; ++ case 32: ++ if (samples != 1) ++ { ++ FIXME("unhandled 32bpp grayscale sample count %u\n", samples); ++ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; ++ } ++ decode_info->format = &GUID_WICPixelFormat32bppGrayFloat; ++ break; + default: +- FIXME("unhandled greyscale bit count %u\n", bps); +- return E_FAIL; ++ WARN("unhandled greyscale bit count %u\n", bps); ++ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + case 2: /* RGB */ +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0007-windowscodecs-Add-support-for-3bps-RGB-format-to-TIF.patch b/patches/windowscodecs-TIFF_Support/0007-windowscodecs-Add-support-for-3bps-RGB-format-to-TIF.patch new file mode 100644 index 00000000..473c6e9e --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0007-windowscodecs-Add-support-for-3bps-RGB-format-to-TIF.patch @@ -0,0 +1,118 @@ +From 72930dc0724b3bf88e4f888b339e9d567c09d44a Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:33:30 +0800 +Subject: windowscodecs: Add support for 3bps RGB format to TIFF decoder. + +--- + dlls/windowscodecs/tiffformat.c | 78 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 75 insertions(+), 3 deletions(-) + +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index 166bacd..9906d75 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -407,8 +407,6 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) + } + break; + case 2: /* RGB */ +- decode_info->bpp = bps * samples; +- + if (samples == 4) + { + ret = pTIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &extra_sample_count, &extra_samples); +@@ -425,8 +423,11 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) + return E_FAIL; + } + ++ decode_info->bpp = max(bps, 8) * samples; ++ decode_info->source_bpp = bps * samples; + switch(bps) + { ++ case 1: + case 8: + decode_info->reverse_bgr = 1; + if (samples == 3) +@@ -1009,8 +1010,79 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT + if (ret == -1) + return E_FAIL; + ++ /* 3bpp RGB */ ++ if (This->decode_info.source_bpp == 3 && This->decode_info.samples == 3 && This->decode_info.bpp == 24) ++ { ++ BYTE *srcdata, *src, *dst; ++ DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 3 + 7) / 8; ++ ++ count = width_bytes * This->decode_info.tile_height; ++ ++ srcdata = HeapAlloc(GetProcessHeap(), 0, count); ++ if (!srcdata) return E_OUTOFMEMORY; ++ memcpy(srcdata, This->cached_tile, count); ++ ++ for (y = 0; y < This->decode_info.tile_height; y++) ++ { ++ src = srcdata + y * width_bytes; ++ dst = This->cached_tile + y * This->decode_info.tile_width * 3; ++ ++ for (x = 0; x < This->decode_info.tile_width; x += 8) ++ { ++ dst[2] = (src[0] & 0x80) ? 0xff : 0; /* R */ ++ dst[1] = (src[0] & 0x40) ? 0xff : 0; /* G */ ++ dst[0] = (src[0] & 0x20) ? 0xff : 0; /* B */ ++ if (x + 1 < This->decode_info.tile_width) ++ { ++ dst[5] = (src[0] & 0x10) ? 0xff : 0; /* R */ ++ dst[4] = (src[0] & 0x08) ? 0xff : 0; /* G */ ++ dst[3] = (src[0] & 0x04) ? 0xff : 0; /* B */ ++ } ++ if (x + 2 < This->decode_info.tile_width) ++ { ++ dst[8] = (src[0] & 0x02) ? 0xff : 0; /* R */ ++ dst[7] = (src[0] & 0x01) ? 0xff : 0; /* G */ ++ dst[6] = (src[1] & 0x80) ? 0xff : 0; /* B */ ++ } ++ if (x + 3 < This->decode_info.tile_width) ++ { ++ dst[11] = (src[1] & 0x40) ? 0xff : 0; /* R */ ++ dst[10] = (src[1] & 0x20) ? 0xff : 0; /* G */ ++ dst[9] = (src[1] & 0x10) ? 0xff : 0; /* B */ ++ } ++ if (x + 4 < This->decode_info.tile_width) ++ { ++ dst[14] = (src[1] & 0x08) ? 0xff : 0; /* R */ ++ dst[13] = (src[1] & 0x04) ? 0xff : 0; /* G */ ++ dst[12] = (src[1] & 0x02) ? 0xff : 0; /* B */ ++ } ++ if (x + 5 < This->decode_info.tile_width) ++ { ++ dst[17] = (src[1] & 0x01) ? 0xff : 0; /* R */ ++ dst[16] = (src[2] & 0x80) ? 0xff : 0; /* G */ ++ dst[15] = (src[2] & 0x40) ? 0xff : 0; /* B */ ++ } ++ if (x + 6 < This->decode_info.tile_width) ++ { ++ dst[20] = (src[2] & 0x20) ? 0xff : 0; /* R */ ++ dst[19] = (src[2] & 0x10) ? 0xff : 0; /* G */ ++ dst[18] = (src[2] & 0x08) ? 0xff : 0; /* B */ ++ } ++ if (x + 7 < This->decode_info.tile_width) ++ { ++ dst[23] = (src[2] & 0x04) ? 0xff : 0; /* R */ ++ dst[22] = (src[2] & 0x02) ? 0xff : 0; /* G */ ++ dst[21] = (src[2] & 0x01) ? 0xff : 0; /* B */ ++ } ++ src += 3; ++ dst += 24; ++ } ++ } ++ ++ HeapFree(GetProcessHeap(), 0, srcdata); ++ } + /* 8bpp grayscale with extra alpha */ +- if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) ++ else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) + { + BYTE *src; + DWORD *dst, count = This->decode_info.tile_width * This->decode_info.tile_height; +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0008-windowscodecs-Add-support-for-12bpp-RGB-format-to-TI.patch b/patches/windowscodecs-TIFF_Support/0008-windowscodecs-Add-support-for-12bpp-RGB-format-to-TI.patch new file mode 100644 index 00000000..90a941f8 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0008-windowscodecs-Add-support-for-12bpp-RGB-format-to-TI.patch @@ -0,0 +1,66 @@ +From 163cf44e74082d92b0f5b85a97ad6952a457b83f Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:36:56 +0800 +Subject: windowscodecs: Add support for 12bpp RGB format to TIFF decoder. + +--- + dlls/windowscodecs/tiffformat.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index 9906d75..f17e508 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -428,6 +428,7 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) + switch(bps) + { + case 1: ++ case 4: + case 8: + decode_info->reverse_bgr = 1; + if (samples == 3) +@@ -1081,6 +1082,41 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT + + HeapFree(GetProcessHeap(), 0, srcdata); + } ++ /* 12bpp RGB */ ++ else if (This->decode_info.source_bpp == 12 && This->decode_info.samples == 3 && This->decode_info.bpp == 24) ++ { ++ BYTE *srcdata, *src, *dst; ++ DWORD x, y, count, width_bytes = (This->decode_info.tile_width * 12 + 7) / 8; ++ ++ count = width_bytes * This->decode_info.tile_height; ++ ++ srcdata = HeapAlloc(GetProcessHeap(), 0, count); ++ if (!srcdata) return E_OUTOFMEMORY; ++ memcpy(srcdata, This->cached_tile, count); ++ ++ for (y = 0; y < This->decode_info.tile_height; y++) ++ { ++ src = srcdata + y * width_bytes; ++ dst = This->cached_tile + y * This->decode_info.tile_width * 3; ++ ++ for (x = 0; x < This->decode_info.tile_width; x += 2) ++ { ++ dst[0] = ((src[1] & 0xf0) >> 4) * 17; /* B */ ++ dst[1] = (src[0] & 0x0f) * 17; /* G */ ++ dst[2] = ((src[0] & 0xf0) >> 4) * 17; /* R */ ++ if (x + 1 < This->decode_info.tile_width) ++ { ++ dst[5] = (src[1] & 0x0f) * 17; /* B */ ++ dst[4] = ((src[2] & 0xf0) >> 4) * 17; /* G */ ++ dst[3] = (src[2] & 0x0f) * 17; /* R */ ++ } ++ src += 3; ++ dst += 6; ++ } ++ } ++ ++ HeapFree(GetProcessHeap(), 0, srcdata); ++ } + /* 8bpp grayscale with extra alpha */ + else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) + { +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0009-windowscodecs-Add-support-for-128bppRGBAFloat-format.patch b/patches/windowscodecs-TIFF_Support/0009-windowscodecs-Add-support-for-128bppRGBAFloat-format.patch new file mode 100644 index 00000000..0bd64579 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0009-windowscodecs-Add-support-for-128bppRGBAFloat-format.patch @@ -0,0 +1,82 @@ +From badd83bc062034d92c62518210f7a578880c3f96 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:46:00 +0800 +Subject: windowscodecs: Add support for 128bppRGBAFloat format to TIFF + decoder. + +--- + dlls/windowscodecs/regsvr.c | 12 ++++++++++++ + dlls/windowscodecs/tiffformat.c | 12 ++++++++++-- + include/wincodec.idl | 2 ++ + 3 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c +index d1649fa..2d6a5d2 100644 +--- a/dlls/windowscodecs/regsvr.c ++++ b/dlls/windowscodecs/regsvr.c +@@ -1224,6 +1224,7 @@ static GUID const * const tiff_decode_formats[] = { + &GUID_WICPixelFormat48bppRGB, + &GUID_WICPixelFormat64bppRGBA, + &GUID_WICPixelFormat64bppPRGBA, ++ &GUID_WICPixelFormat128bppRGBAFloat, + NULL + }; + +@@ -2019,6 +2020,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { + WICPixelFormatNumericRepresentationUnsignedInteger, + 0 + }, ++ { &GUID_WICPixelFormat128bppRGBAFloat, ++ "The Wine Project", ++ "128bpp RGBAFloat", ++ NULL, /* no version */ ++ &GUID_VendorMicrosoft, ++ 128, /* bitsperpixel */ ++ 4, /* channel count */ ++ channel_masks_32bit, ++ WICPixelFormatNumericRepresentationUnsignedInteger, ++ 1 ++ }, + { NULL } /* list terminator */ + }; + +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index f17e508..48e46d6 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -466,9 +466,17 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) + return E_FAIL; + } + break; ++ case 32: ++ if (samples != 4) ++ { ++ FIXME("unhandled 32bpp RGB sample count %u\n", samples); ++ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; ++ } ++ decode_info->format = &GUID_WICPixelFormat128bppRGBAFloat; ++ break; + default: +- FIXME("unhandled RGB bit count %u\n", bps); +- return E_FAIL; ++ WARN("unhandled RGB bit count %u\n", bps); ++ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; + } + break; + case 3: /* RGB Palette */ +diff --git a/include/wincodec.idl b/include/wincodec.idl +index c0afe52..e8c7023 100644 +--- a/include/wincodec.idl ++++ b/include/wincodec.idl +@@ -219,6 +219,8 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat48bppRGB, 0x6fddc324,0x4e03,0x4bfe,0xb + cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppRGBA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x16);") + cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppPRGBA, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x17);") + ++cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBAFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x19);") ++ + cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppCMYK, 0x6fddc324,0x4e03,0x4fbe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1c);") + + typedef struct WICRect { +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0010-include-Fix-the-GUID_WICPixelFormat32bppCMYK-definit.patch b/patches/windowscodecs-TIFF_Support/0010-include-Fix-the-GUID_WICPixelFormat32bppCMYK-definit.patch new file mode 100644 index 00000000..a32ad03c --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0010-include-Fix-the-GUID_WICPixelFormat32bppCMYK-definit.patch @@ -0,0 +1,25 @@ +From 7d9df59da745fe72a232617a340b795d23fa4dc8 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:47:24 +0800 +Subject: include: Fix the GUID_WICPixelFormat32bppCMYK definition. + +--- + include/wincodec.idl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/wincodec.idl b/include/wincodec.idl +index e8c7023..04765b4 100644 +--- a/include/wincodec.idl ++++ b/include/wincodec.idl +@@ -221,7 +221,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppPRGBA, 0x6fddc324,0x4e03,0x4bfe,0 + + cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBAFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x19);") + +-cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppCMYK, 0x6fddc324,0x4e03,0x4fbe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1c);") ++cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppCMYK, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1c);") + + typedef struct WICRect { + INT X; +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0011-windowscodecs-Add-support-for-32bppCMYK-and-64bppCMY.patch b/patches/windowscodecs-TIFF_Support/0011-windowscodecs-Add-support-for-32bppCMYK-and-64bppCMY.patch new file mode 100644 index 00000000..c0f1e93c --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0011-windowscodecs-Add-support-for-32bppCMYK-and-64bppCMY.patch @@ -0,0 +1,95 @@ +From 6da55c50c6ab752a39ef43aec768ffb1e2072c6a Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:52:36 +0800 +Subject: windowscodecs: Add support for 32bppCMYK and 64bppCMYK formats to + TIFF decoder. + +--- + dlls/windowscodecs/regsvr.c | 13 +++++++++++++ + dlls/windowscodecs/tiffformat.c | 25 ++++++++++++++++++++++++- + include/wincodec.idl | 1 + + 3 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c +index 2d6a5d2..b5bbff3 100644 +--- a/dlls/windowscodecs/regsvr.c ++++ b/dlls/windowscodecs/regsvr.c +@@ -1224,6 +1224,8 @@ static GUID const * const tiff_decode_formats[] = { + &GUID_WICPixelFormat48bppRGB, + &GUID_WICPixelFormat64bppRGBA, + &GUID_WICPixelFormat64bppPRGBA, ++ &GUID_WICPixelFormat32bppCMYK, ++ &GUID_WICPixelFormat64bppCMYK, + &GUID_WICPixelFormat128bppRGBAFloat, + NULL + }; +@@ -2020,6 +2022,17 @@ static struct regsvr_pixelformat const pixelformat_list[] = { + WICPixelFormatNumericRepresentationUnsignedInteger, + 0 + }, ++ { &GUID_WICPixelFormat64bppCMYK, ++ "The Wine Project", ++ "64bpp CMYK", ++ NULL, /* no version */ ++ &GUID_VendorMicrosoft, ++ 64, /* bitsperpixel */ ++ 4, /* channel count */ ++ channel_masks_8bit, ++ WICPixelFormatNumericRepresentationUnsignedInteger, ++ 0 ++ }, + { &GUID_WICPixelFormat128bppRGBAFloat, + "The Wine Project", + "128bpp RGBAFloat", +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index 48e46d6..15c4b69 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -507,8 +507,31 @@ static HRESULT tiff_get_decode_info(TIFF *tiff, tiff_decode_info *decode_info) + return E_FAIL; + } + break; ++ ++ case 5: /* Separated */ ++ if (samples != 4) ++ { ++ FIXME("unhandled Separated sample count %u\n", samples); ++ return E_FAIL; ++ } ++ ++ decode_info->bpp = bps * samples; ++ switch(bps) ++ { ++ case 8: ++ decode_info->format = &GUID_WICPixelFormat32bppCMYK; ++ break; ++ case 16: ++ decode_info->format = &GUID_WICPixelFormat64bppCMYK; ++ break; ++ ++ default: ++ WARN("unhandled Separated bit count %u\n", bps); ++ return WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT; ++ } ++ break; ++ + case 4: /* Transparency mask */ +- case 5: /* CMYK */ + case 6: /* YCbCr */ + case 8: /* CIELab */ + default: +diff --git a/include/wincodec.idl b/include/wincodec.idl +index 04765b4..c0248cd 100644 +--- a/include/wincodec.idl ++++ b/include/wincodec.idl +@@ -222,6 +222,7 @@ cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppPRGBA, 0x6fddc324,0x4e03,0x4bfe,0 + cpp_quote("DEFINE_GUID(GUID_WICPixelFormat128bppRGBAFloat, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x19);") + + cpp_quote("DEFINE_GUID(GUID_WICPixelFormat32bppCMYK, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1c);") ++cpp_quote("DEFINE_GUID(GUID_WICPixelFormat64bppCMYK, 0x6fddc324,0x4e03,0x4bfe,0xb1,0x85,0x3d,0x77,0x76,0x8d,0xc9,0x1f);") + + typedef struct WICRect { + INT X; +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0012-windowscodecs-Add-support-for-4bpp-RGBA-format-to-TI.patch b/patches/windowscodecs-TIFF_Support/0012-windowscodecs-Add-support-for-4bpp-RGBA-format-to-TI.patch new file mode 100644 index 00000000..545e3500 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0012-windowscodecs-Add-support-for-4bpp-RGBA-format-to-TI.patch @@ -0,0 +1,50 @@ +From f77dade774e5a9652fe487b1468c56db8c68bdd2 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:58:30 +0800 +Subject: windowscodecs: Add support for 4bpp RGBA format to TIFF decoder. + +--- + dlls/windowscodecs/tiffformat.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index 15c4b69..bfb495c 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -1148,6 +1148,33 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT + + HeapFree(GetProcessHeap(), 0, srcdata); + } ++ /* 4bpp RGBA */ ++ else if (This->decode_info.source_bpp == 4 && This->decode_info.samples == 4 && This->decode_info.bpp == 32) ++ { ++ BYTE *src, *dst; ++ DWORD count; ++ ++ /* 1 source byte expands to 2 BGRA samples */ ++ count = (This->decode_info.tile_width * This->decode_info.tile_height + 1) / 2; ++ ++ src = This->cached_tile + count - 1; ++ dst = This->cached_tile + This->decode_info.tile_size; ++ ++ while (count--) ++ { ++ BYTE b = *src--; ++ ++ dst -= 8; ++ dst[2] = (b & 0x80) ? 0xff : 0; /* R */ ++ dst[1] = (b & 0x40) ? 0xff : 0; /* G */ ++ dst[0] = (b & 0x20) ? 0xff : 0; /* B */ ++ dst[3] = (b & 0x10) ? 0xff : 0; /* A */ ++ dst[6] = (b & 0x08) ? 0xff : 0; /* R */ ++ dst[5] = (b & 0x04) ? 0xff : 0; /* G */ ++ dst[4] = (b & 0x02) ? 0xff : 0; /* B */ ++ dst[7] = (b & 0x01) ? 0xff : 0; /* A */ ++ } ++ } + /* 8bpp grayscale with extra alpha */ + else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) + { +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0013-windowscodecs-Add-support-for-16bpp-RGBA-format-to-T.patch b/patches/windowscodecs-TIFF_Support/0013-windowscodecs-Add-support-for-16bpp-RGBA-format-to-T.patch new file mode 100644 index 00000000..a8f5ae98 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0013-windowscodecs-Add-support-for-16bpp-RGBA-format-to-T.patch @@ -0,0 +1,48 @@ +From 7d79785f0687d5f4dba7a43b12dd68751b3d022a Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 12:59:58 +0800 +Subject: windowscodecs: Add support for 16bpp RGBA format to TIFF decoder. + +--- + dlls/windowscodecs/tiffformat.c | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/dlls/windowscodecs/tiffformat.c b/dlls/windowscodecs/tiffformat.c +index bfb495c..c8f16f2 100644 +--- a/dlls/windowscodecs/tiffformat.c ++++ b/dlls/windowscodecs/tiffformat.c +@@ -1175,6 +1175,31 @@ static HRESULT TiffFrameDecode_ReadTile(TiffFrameDecode *This, UINT tile_x, UINT + dst[7] = (b & 0x01) ? 0xff : 0; /* A */ + } + } ++ /* 16bpp RGBA */ ++ else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 4 && This->decode_info.bpp == 32) ++ { ++ BYTE *src, *dst; ++ DWORD count = This->decode_info.tile_width * This->decode_info.tile_height; ++ ++ src = This->cached_tile + count * 2; ++ dst = This->cached_tile + This->decode_info.tile_size; ++ ++ while (count--) ++ { ++ BYTE b[2]; ++ ++ src -= 2; ++ dst -= 4; ++ ++ b[0] = src[0]; ++ b[1] = src[1]; ++ ++ dst[0] = ((b[1] & 0xf0) >> 4) * 17; /* B */ ++ dst[1] = (b[0] & 0x0f) * 17; /* G */ ++ dst[2] = ((b[0] & 0xf0) >> 4) * 17; /* R */ ++ dst[3] = (b[1] & 0x0f) * 17; /* A */ ++ } ++ } + /* 8bpp grayscale with extra alpha */ + else if (This->decode_info.source_bpp == 16 && This->decode_info.samples == 2 && This->decode_info.bpp == 32) + { +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0014-windowscodecs-Add-some-tests-for-various-TIFF-color-.patch b/patches/windowscodecs-TIFF_Support/0014-windowscodecs-Add-some-tests-for-various-TIFF-color-.patch new file mode 100644 index 00000000..9820552f --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0014-windowscodecs-Add-some-tests-for-various-TIFF-color-.patch @@ -0,0 +1,473 @@ +From 7657472835db56f6f11c5465c70bddbe62902b38 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 9 Dec 2016 13:02:07 +0800 +Subject: windowscodecs: Add some tests for various TIFF color formats. + +--- + dlls/windowscodecs/tests/tiffformat.c | 436 ++++++++++++++++++++++++++++++++++ + 1 file changed, 436 insertions(+) + +diff --git a/dlls/windowscodecs/tests/tiffformat.c b/dlls/windowscodecs/tests/tiffformat.c +index a742627..2389dbc 100644 +--- a/dlls/windowscodecs/tests/tiffformat.c ++++ b/dlls/windowscodecs/tests/tiffformat.c +@@ -236,6 +236,61 @@ static HRESULT create_decoder(const void *image_data, UINT image_size, IWICBitma + return hr; + } + ++static HRESULT get_pixelformat_info(const GUID *format, UINT *bpp, UINT *channels, BOOL *trasparency) ++{ ++ HRESULT hr; ++ IWICComponentInfo *info; ++ IWICPixelFormatInfo2 *formatinfo; ++ ++ hr = IWICImagingFactory_CreateComponentInfo(factory, format, &info); ++ ok(hr == S_OK, "CreateComponentInfo(%s) error %#x\n", wine_dbgstr_guid(format), hr); ++ if (hr == S_OK) ++ { ++ hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo2, (void **)&formatinfo); ++ if (hr == S_OK) ++ { ++ hr = IWICPixelFormatInfo2_SupportsTransparency(formatinfo, trasparency); ++ ok(hr == S_OK, "SupportsTransparency error %#x\n", hr); ++ IWICPixelFormatInfo2_Release(formatinfo); ++ } ++ hr = IWICComponentInfo_QueryInterface(info, &IID_IWICPixelFormatInfo, (void **)&formatinfo); ++ if (hr == S_OK) ++ { ++ hr = IWICPixelFormatInfo2_GetBitsPerPixel(formatinfo, bpp); ++ ok(hr == S_OK, "GetBitsPerPixel error %#x\n", hr); ++ hr = IWICPixelFormatInfo2_GetChannelCount(formatinfo, channels); ++ ok(hr == S_OK, "GetChannelCount error %#x\n", hr); ++ IWICPixelFormatInfo2_Release(formatinfo); ++ } ++ IWICComponentInfo_Release(info); ++ } ++ return hr; ++} ++ ++static void dump_tiff(void *buf) ++{ ++ UINT count, i; ++ struct tiff_1bpp_data *tiff; ++ struct IFD_entry *tag; ++ ++ tiff = buf; ++ count = *(short *)((char *)tiff + tiff->dir_offset); ++ tag = (struct IFD_entry *)((char *)tiff + tiff->dir_offset + sizeof(short)); ++ ++ for (i = 0; i < count; i++) ++ { ++ printf("tag %u: id %04x, type %04x, count %u, value %d", ++ i, tag[i].id, tag[i].type, tag[i].count, tag[i].value); ++ if (tag[i].id == 0x102 && tag[i].count > 2) ++ { ++ short *bps = (short *)((char *)tiff + tag[i].value); ++ printf(" (%d,%d,%d,%d)\n", bps[0], bps[1], bps[2], bps[3]); ++ } ++ else ++ printf("\n"); ++ } ++} ++ + static void test_tiff_1bpp_palette(void) + { + HRESULT hr; +@@ -503,6 +558,386 @@ static void test_tiff_8bpp_palette(void) + IWICBitmapDecoder_Release(decoder); + } + ++#include "pshpack2.h" ++static const struct tiff_1x1_data ++{ ++ USHORT byte_order; ++ USHORT version; ++ ULONG dir_offset; ++ USHORT number_of_entries; ++ struct IFD_entry entry[12]; ++ ULONG next_IFD; ++ struct IFD_rational res; ++ short palette_data[3][256]; ++ short bps_data[4]; ++ BYTE pixel_data[32]; ++} tiff_1x1_data = ++{ ++#ifdef WORDS_BIGENDIAN ++ 'M' | 'M' << 8, ++#else ++ 'I' | 'I' << 8, ++#endif ++ 42, ++ FIELD_OFFSET(struct tiff_1x1_data, number_of_entries), ++ 12, ++ { ++ { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ ++ { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ ++ { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ ++ { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */ ++ { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ ++ { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */ ++ { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */ ++ { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */ ++ { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, ++ { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, ++ { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ ++ { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */ ++ }, ++ 0, ++ { 96, 1 }, ++ { { 0 } }, ++ { 8,8,8,0 }, ++ { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 } ++}; ++#include "poppack.h" ++ ++static UINT width_bytes(UINT width, UINT bpp) ++{ ++ return (width * bpp + 7) / 8; ++} ++ ++static void test_color_formats(void) ++{ ++ struct bitmap_data ++ { ++ UINT bpp; ++ UINT width; ++ UINT height; ++ const WICPixelFormatGUID *format; ++ const BYTE *bits; ++ }; ++ static const BYTE bits_1bpsBGR[] = { 0,255,0,255,0,255,255,255,0,0,0,255,255,0,0,0,255,255,255,255,255,0,0,0,0,255,0,255,0,255 }; ++ static const struct bitmap_data data_1bpsBGR = ++ { ++ 24, 10, 2, &GUID_WICPixelFormat24bppBGR, bits_1bpsBGR ++ }; ++ static const BYTE bits_4bpsBGR[] = { 204,85,85,136,187,51,0,85,85,85,0,68,0,102,0,136,0,119,0,153,0 }; ++ static const struct bitmap_data data_4bpsBGR = ++ { ++ 24, 5, 2, &GUID_WICPixelFormat24bppBGR, bits_4bpsBGR ++ }; ++ static const BYTE bits_8bpsBGR[] = { 2,0,1,5,4,3,8,7,6 }; ++ static const struct bitmap_data data_8bpsBGR = ++ { ++ 24, 3, 1, &GUID_WICPixelFormat24bppBGR, bits_8bpsBGR ++ }; ++ static const BYTE bits_48bppRGB[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; ++ static const struct bitmap_data data_48bppRGB = ++ { ++ 48, 2, 1, &GUID_WICPixelFormat48bppRGB, bits_48bppRGB ++ }; ++ static const BYTE bits_1bpsBGRA[] = { 0,255,0,255,0,255,0,255,0,255,255,0,255,0,0,255,255,0,255,255,0,0,255,0,0,255,0,255,0,255,0,255,0,0,0,0,0,255,0,0 }; ++ static const struct bitmap_data data_1bpsBGRA = ++ { ++ 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_1bpsBGRA ++ }; ++ static const BYTE bits_4bpsBGRA[] = { 204,85,85,51,85,136,187,85,0,68,0,85,0,102,0,119,0,136,0,153,0,0,0,17,0,34,0,51 }; ++ static const struct bitmap_data data_4bpsBGRA = ++ { ++ 32, 5, 2, &GUID_WICPixelFormat32bppBGRA, bits_4bpsBGRA ++ }; ++ static const BYTE bits_8bpsBGRA[] = { 2,0,1,3,6,5,4,7,0,9,8,1,4,3,2,5 }; ++ static const struct bitmap_data data_8bpsBGRA = ++ { ++ 32, 4, 1, &GUID_WICPixelFormat32bppBGRA, bits_8bpsBGRA ++ }; ++ static const BYTE bits_64bppRGBA[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; ++ static const struct bitmap_data data_64bppRGBA = ++ { ++ 64, 2, 1, &GUID_WICPixelFormat64bppRGBA, bits_64bppRGBA ++ }; ++ static const BYTE bits_BlackWhite[] = { 85,195,184,85 }; ++ static const struct bitmap_data data_BlackWhite = ++ { ++ 1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite ++ }; ++ static const BYTE bits_BlackWhite_xp[] = { 85,195,184,84 }; ++ static const struct bitmap_data data_BlackWhite_xp = ++ { ++ 1, 30, 1, &GUID_WICPixelFormatBlackWhite, bits_BlackWhite_xp ++ }; ++ static const BYTE bits_4bppGray[] = { 85,195,184,85 }; ++ static const struct bitmap_data data_4bppGray = ++ { ++ 4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray ++ }; ++ static const BYTE bits_4bppGray_xp[] = { 85,195,184,80 }; ++ static const struct bitmap_data data_4bppGray_xp = ++ { ++ 4, 7, 1, &GUID_WICPixelFormat4bppGray, bits_4bppGray_xp ++ }; ++ static const BYTE bits_8bppGray[] = { 1,0,2,3,4,5,6,7,8,9 }; ++ static const struct bitmap_data data_8bppGray = ++ { ++ 8, 10, 1, &GUID_WICPixelFormat8bppGray, bits_8bppGray ++ }; ++ static const BYTE bits_16bppGray[] = { 1,0,2,3,4,5 }; ++ static const struct bitmap_data data_16bppGray = ++ { ++ 16, 3, 1, &GUID_WICPixelFormat16bppGray, bits_16bppGray ++ }; ++ static const BYTE bits_32bppGrayFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; ++ static const struct bitmap_data data_32bppGrayFloat = ++ { ++ 32, 3, 1, &GUID_WICPixelFormat32bppGrayFloat, bits_32bppGrayFloat ++ }; ++#if 0 /* FIXME */ ++ static const BYTE bits_96bpp3Channels[] = { 0 }; ++ static const struct bitmap_data data_96bpp3Channels = ++ { ++ 64, 1, 1, &GUID_WICPixelFormat96bpp3Channels, bits_96bpp3Channels ++ }; ++#endif ++ static const BYTE bits_128bppRGBAFloat[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; ++ static const struct bitmap_data data_128bppRGBAFloat = ++ { ++ 128, 1, 1, &GUID_WICPixelFormat128bppRGBAFloat, bits_128bppRGBAFloat ++ }; ++ static const BYTE bits_1bppIndexed[] = { 85,195,184,85 }; ++ static const struct bitmap_data data_1bppIndexed = ++ { ++ 1, 32, 1, &GUID_WICPixelFormat1bppIndexed, bits_1bppIndexed ++ }; ++ static const BYTE bits_4bppIndexed[] = { 85,195,184,85 }; ++ static const struct bitmap_data data_4bppIndexed = ++ { ++ 4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed ++ }; ++ static const BYTE bits_4bppIndexed_xp[] = { 85,195,184,80 }; ++ static const struct bitmap_data data_4bppIndexed_xp = ++ { ++ 4, 7, 1, &GUID_WICPixelFormat4bppIndexed, bits_4bppIndexed_xp ++ }; ++ static const BYTE bits_8bppIndexed[] = { 1,0,2,3,4,5,6,7,8,9 }; ++ static const struct bitmap_data data_8bppIndexed = ++ { ++ 8, 3, 1, &GUID_WICPixelFormat8bppIndexed, bits_8bppIndexed ++ }; ++ static const BYTE bits_32bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1 }; ++ static const struct bitmap_data data_32bppCMYK = ++ { ++ 32, 3, 1, &GUID_WICPixelFormat32bppCMYK, bits_32bppCMYK ++ }; ++ static const BYTE bits_64bppCMYK[] = { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 }; ++ static const struct bitmap_data data_64bppCMYK = ++ { ++ 64, 2, 1, &GUID_WICPixelFormat64bppCMYK, bits_64bppCMYK ++ }; ++ static const struct ++ { ++ int photometric; /* PhotometricInterpretation */ ++ int samples; /* SamplesPerPixel */ ++ int bps; /* BitsPerSample */ ++ const struct bitmap_data *data; ++ const struct bitmap_data *alt_data; ++ } td[] = ++ { ++ /* 2 - RGB */ ++ { 2, 3, 1, &data_1bpsBGR }, ++ { 2, 3, 4, &data_4bpsBGR }, ++ { 2, 3, 8, &data_8bpsBGR }, ++ { 2, 3, 16, &data_48bppRGB }, ++ { 2, 3, 24, NULL }, ++#if 0 /* FIXME */ ++ { 2, 3, 32, &data_96bpp3Channels }, ++#endif ++ { 2, 4, 1, &data_1bpsBGRA }, ++ { 2, 4, 4, &data_4bpsBGRA }, ++ { 2, 4, 8, &data_8bpsBGRA }, ++ { 2, 4, 16, &data_64bppRGBA }, ++ { 2, 4, 24, NULL }, ++ { 2, 4, 32, &data_128bppRGBAFloat }, ++ /* 1 - BlackIsZero (Bilevel) */ ++ { 1, 1, 1, &data_BlackWhite, &data_BlackWhite_xp }, ++ { 1, 1, 4, &data_4bppGray, &data_4bppGray_xp }, ++ { 1, 1, 8, &data_8bppGray }, ++ { 1, 1, 16, &data_16bppGray }, ++ { 1, 1, 24, NULL }, ++ { 1, 1, 32, &data_32bppGrayFloat }, ++ /* 3 - Palette Color */ ++ { 3, 1, 1, &data_1bppIndexed }, ++ { 3, 1, 4, &data_4bppIndexed, &data_4bppIndexed_xp }, ++ { 3, 1, 8, &data_8bppIndexed }, ++#if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */ ++ { 3, 1, 16, &data_8bppIndexed }, ++ { 3, 1, 24, &data_8bppIndexed }, ++ { 3, 1, 32, &data_8bppIndexed }, ++#endif ++ /* 5 - Separated */ ++ { 5, 4, 1, NULL }, ++ { 5, 4, 4, NULL }, ++ { 5, 4, 8, &data_32bppCMYK }, ++ { 5, 4, 16, &data_64bppCMYK }, ++ { 5, 4, 24, NULL }, ++ { 5, 4, 32, NULL }, ++ }; ++ BYTE buf[sizeof(tiff_1x1_data)]; ++ BYTE pixels[256]; ++ HRESULT hr; ++ IWICBitmapDecoder *decoder; ++ IWICBitmapFrameDecode *frame; ++ GUID format; ++ UINT count, i, bpp, channels, ret; ++ BOOL trasparency; ++ struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL; ++ struct IFD_entry *tag_width = NULL, *tag_height = NULL; ++ short *bps; ++ ++ memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data)); ++ generate_tiff_palette(buf + FIELD_OFFSET(struct tiff_1x1_data, palette_data), 256); ++ ++ count = *(short *)(buf + tiff_1x1_data.dir_offset); ++ tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short)); ++ ++ /* verify the TIFF structure */ ++ for (i = 0; i < count; i++) ++ { ++ if (tag[i].id == 0x100) /* ImageWidth */ ++ tag_width = &tag[i]; ++ else if (tag[i].id == 0x101) /* ImageLength */ ++ tag_height = &tag[i]; ++ else if (tag[i].id == 0x102) /* BitsPerSample */ ++ tag_bps = &tag[i]; ++ else if (tag[i].id == 0x106) /* PhotometricInterpretation */ ++ tag_photo = &tag[i]; ++ else if (tag[i].id == 0x115) /* SamplesPerPixel */ ++ tag_samples = &tag[i]; ++ else if (tag[i].id == 0x140) /* ColorMap */ ++ tag_colormap = &tag[i]; ++ } ++ ++ ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n"); ++ if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return; ++ ++ ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n"); ++ bps = (short *)(buf + tag_bps->value); ++ ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0, ++ "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]); ++ ++ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) ++ { ++ if (td[i].data) ++ { ++ bpp = td[i].samples * td[i].bps; ++ if (winetest_debug > 1) ++ trace("samples %u, bps %u, bpp %u, width %u => width_bytes %u\n", td[i].samples, td[i].bps, bpp, ++ td[i].data->width, width_bytes(td[i].data->width, bpp)); ++ tag_width->value = td[i].data->width; ++ tag_height->value = td[i].data->height; ++ } ++ else ++ { ++ tag_width->value = 1; ++ tag_height->value = 1; ++ } ++ ++ tag_colormap->count = (1 << td[i].bps) * 3; ++ ++ if (td[i].bps < 8) ++ { ++ buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 0x55; ++ buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0xc3; ++ buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 0xb8; ++ buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 0x55; ++ } ++ else ++ { ++ buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data)] = 1; ++ buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 1] = 0; ++ buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 2] = 2; ++ buf[FIELD_OFFSET(struct tiff_1x1_data, pixel_data) + 3] = 3; ++ } ++ ++ tag_photo->value = td[i].photometric; ++ tag_bps->count = td[i].samples; ++ tag_samples->value = td[i].samples; ++ ++ if (td[i].samples == 1) ++ tag_bps->value = td[i].bps; ++ else if (td[i].samples == 2) ++ tag_bps->value = MAKELONG(td[i].bps, td[i].bps); ++ else if (td[i].samples == 3) ++ { ++ tag_bps->value = (BYTE *)bps - buf; ++ bps[0] = bps[1] = bps[2] = td[i].bps; ++ } ++ else if (td[i].samples == 4) ++ { ++ tag_bps->value = (BYTE *)bps - buf; ++ bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps; ++ } ++ else ++ { ++ ok(0, "%u: unsupported samples count %d\n", i, td[i].samples); ++ continue; ++ } ++ ++ hr = create_decoder(buf, sizeof(buf), &decoder); ++ if (!td[i].data) ++ { ++ ok(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_COMPONENTNOTFOUND /* win8+ */ || WINCODEC_ERR_BADIMAGE /* XP */, ++ "%u: (%d,%d,%d) wrong error %#x\n", i, td[i].photometric, td[i].samples, td[i].bps, hr); ++ if (hr == S_OK) ++ { ++ IWICBitmapDecoder_Release(decoder); ++ dump_tiff(buf); ++ } ++ continue; ++ } ++ else ++ ok(hr == S_OK || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT || hr == WINCODEC_ERR_BADIMAGE) /* XP */, ++ "%u: failed to load TIFF image data (%d,%d,%d) %#x\n", ++ i, td[i].photometric, td[i].samples, td[i].bps, hr); ++ if (hr != S_OK) continue; ++ ++ hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame); ++ ok(hr == S_OK, "%u: GetFrame error %#x\n", i, hr); ++ ++ hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format); ++ ok(hr == S_OK, "%u: GetPixelFormat error %#x\n", i, hr); ++ ok(IsEqualGUID(&format, td[i].data->format), ++ "%u (%d,%d,%d): expected %s, got %s\n", ++ i, td[i].photometric, td[i].samples, td[i].bps, ++ wine_dbgstr_guid(td[i].data->format), wine_dbgstr_guid(&format)); ++ ++ trasparency = (td[i].photometric == 2 && td[i].samples == 4); /* for XP */ ++ hr = get_pixelformat_info(&format, &bpp, &channels, &trasparency); ++ ok(hr == S_OK, "%u: get_pixelformat_bpp error %#x\n", i, hr); ++ ok(bpp == td[i].data->bpp, "%u: expected %u, got %u\n", i, td[i].data->bpp, bpp); ++ ok(channels == td[i].samples, "%u: expected %u, got %u\n", i, td[i].samples, channels); ++ ok(trasparency == (td[i].photometric == 2 && td[i].samples == 4), "%u: got %u\n", i, trasparency); ++ ++ memset(pixels, 0, sizeof(pixels)); ++ hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, width_bytes(td[i].data->width, bpp), sizeof(pixels), pixels); ++ ok(hr == S_OK, "%u: CopyPixels error %#x\n", i, hr); ++ ret = memcmp(pixels, td[i].data->bits, width_bytes(td[i].data->width, bpp)); ++ if (ret && td[i].alt_data) ++ ret = memcmp(pixels, td[i].alt_data->bits, width_bytes(td[i].data->width, bpp)); ++ ok(ret == 0, "%u: (%d,%d,%d) wrong pixel data\n", i, td[i].photometric, td[i].samples, td[i].bps); ++ if (ret) ++ { ++ UINT j, n = width_bytes(td[i].data->width, bpp); ++ for (j = 0; j < n; j++) ++ printf("%u%s", pixels[j], (j + 1) < n ? "," : "\n"); ++ } ++ ++ IWICBitmapFrameDecode_Release(frame); ++ IWICBitmapDecoder_Release(decoder); ++ } ++} ++ + START_TEST(tiffformat) + { + HRESULT hr; +@@ -514,6 +949,7 @@ START_TEST(tiffformat) + ok(hr == S_OK, "CoCreateInstance error %#x\n", hr); + if (FAILED(hr)) return; + ++ test_color_formats(); + test_tiff_1bpp_palette(); + test_tiff_8bpp_palette(); + test_QueryCapability(); +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0015-windowscodecs-Tolerate-partial-reads-in-the-IFD-meta.patch b/patches/windowscodecs-TIFF_Support/0015-windowscodecs-Tolerate-partial-reads-in-the-IFD-meta.patch new file mode 100644 index 00000000..652e10f8 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0015-windowscodecs-Tolerate-partial-reads-in-the-IFD-meta.patch @@ -0,0 +1,161 @@ +From 8e48978fab82ddf03bf80cde19495a528e1f82ae Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 16 Dec 2016 18:08:51 +0800 +Subject: windowscodecs: Tolerate partial reads in the IFD metadata loader. + +--- + dlls/windowscodecs/metadatahandler.c | 47 +++++++++++++++--------------------- + 1 file changed, 20 insertions(+), 27 deletions(-) + +diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c +index 571f8b5..d066306 100644 +--- a/dlls/windowscodecs/metadatahandler.c ++++ b/dlls/windowscodecs/metadatahandler.c +@@ -777,7 +777,7 @@ static int tag_to_vt(SHORT tag) + static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + MetadataItem *item, BOOL native_byte_order) + { +- ULONG count, value, i, bytesread; ++ ULONG count, value, i; + SHORT type; + LARGE_INTEGER pos; + HRESULT hr; +@@ -819,7 +819,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + + item->value.vt |= VT_VECTOR; + item->value.u.caub.cElems = count; +- item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count); ++ item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count); + if (!item->value.u.caub.pElems) return E_OUTOFMEMORY; + + pos.QuadPart = value; +@@ -829,9 +829,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems); + return hr; + } +- hr = IStream_Read(input, item->value.u.caub.pElems, count, &bytesread); +- if (bytesread != count) hr = E_FAIL; +- if (hr != S_OK) ++ hr = IStream_Read(input, item->value.u.caub.pElems, count, NULL); ++ if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems); + return hr; +@@ -864,7 +863,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + + item->value.vt |= VT_VECTOR; + item->value.u.caui.cElems = count; +- item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2); ++ item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 2); + if (!item->value.u.caui.pElems) return E_OUTOFMEMORY; + + pos.QuadPart = value; +@@ -874,9 +873,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems); + return hr; + } +- hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, &bytesread); +- if (bytesread != count * 2) hr = E_FAIL; +- if (hr != S_OK) ++ hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, NULL); ++ if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems); + return hr; +@@ -897,7 +895,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + + item->value.vt |= VT_VECTOR; + item->value.u.caul.cElems = count; +- item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), 0, count * 4); ++ item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 4); + if (!item->value.u.caul.pElems) return E_OUTOFMEMORY; + + pos.QuadPart = value; +@@ -907,9 +905,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems); + return hr; + } +- hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, &bytesread); +- if (bytesread != count * 4) hr = E_FAIL; +- if (hr != S_OK) ++ hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, NULL); ++ if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems); + return hr; +@@ -935,8 +932,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + hr = IStream_Seek(input, pos, SEEK_SET, NULL); + if (FAILED(hr)) return hr; + +- hr = IStream_Read(input, &ull, sizeof(ull), &bytesread); +- if (bytesread != sizeof(ull)) hr = E_FAIL; ++ hr = IStream_Read(input, &ull, sizeof(ull), NULL); + if (hr != S_OK) return hr; + + item->value.u.uhVal.QuadPart = ull; +@@ -954,7 +950,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + { + item->value.vt |= VT_VECTOR; + item->value.u.cauh.cElems = count; +- item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), 0, count * 8); ++ item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count * 8); + if (!item->value.u.cauh.pElems) return E_OUTOFMEMORY; + + pos.QuadPart = value; +@@ -964,9 +960,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems); + return hr; + } +- hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, &bytesread); +- if (bytesread != count * 8) hr = E_FAIL; +- if (hr != S_OK) ++ hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, NULL); ++ if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems); + return hr; +@@ -984,7 +979,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + } + break; + case IFD_ASCII: +- item->value.u.pszVal = HeapAlloc(GetProcessHeap(), 0, count + 1); ++ item->value.u.pszVal = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count + 1); + if (!item->value.u.pszVal) return E_OUTOFMEMORY; + + if (count <= 4) +@@ -1002,9 +997,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + HeapFree(GetProcessHeap(), 0, item->value.u.pszVal); + return hr; + } +- hr = IStream_Read(input, item->value.u.pszVal, count, &bytesread); +- if (bytesread != count) hr = E_FAIL; +- if (hr != S_OK) ++ hr = IStream_Read(input, item->value.u.pszVal, count, NULL); ++ if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, item->value.u.pszVal); + return hr; +@@ -1019,7 +1013,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + break; + } + +- item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), 0, count); ++ item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, count); + if (!item->value.u.blob.pBlobData) return E_OUTOFMEMORY; + + item->value.u.blob.cbSize = count; +@@ -1038,9 +1032,8 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry, + HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData); + return hr; + } +- hr = IStream_Read(input, item->value.u.blob.pBlobData, count, &bytesread); +- if (bytesread != count) hr = E_FAIL; +- if (hr != S_OK) ++ hr = IStream_Read(input, item->value.u.blob.pBlobData, count, NULL); ++ if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData); + return hr; +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0016-gdiplus-Add-support-for-more-image-color-formats.patch b/patches/windowscodecs-TIFF_Support/0016-gdiplus-Add-support-for-more-image-color-formats.patch new file mode 100644 index 00000000..936eee1f --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0016-gdiplus-Add-support-for-more-image-color-formats.patch @@ -0,0 +1,36 @@ +From a2ad6b7fb8674d821659685d838690d9637d5844 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 16 Dec 2016 18:09:55 +0800 +Subject: gdiplus: Add support for more image color formats. + +--- + dlls/gdiplus/image.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c +index ac17104..aa1ff10 100644 +--- a/dlls/gdiplus/image.c ++++ b/dlls/gdiplus/image.c +@@ -55,13 +55,19 @@ static const struct + { + { &GUID_WICPixelFormatBlackWhite, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW }, + { &GUID_WICPixelFormat1bppIndexed, PixelFormat1bppIndexed, WICBitmapPaletteTypeFixedBW }, ++ { &GUID_WICPixelFormat4bppIndexed, PixelFormat4bppIndexed, WICBitmapPaletteTypeFixedHalftone8 }, + { &GUID_WICPixelFormat8bppGray, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedGray256 }, ++ { &GUID_WICPixelFormat32bppGrayFloat, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedGray256 }, + { &GUID_WICPixelFormat8bppIndexed, PixelFormat8bppIndexed, WICBitmapPaletteTypeFixedHalftone256 }, + { &GUID_WICPixelFormat16bppBGR555, PixelFormat16bppRGB555, WICBitmapPaletteTypeFixedHalftone256 }, + { &GUID_WICPixelFormat24bppBGR, PixelFormat24bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, + { &GUID_WICPixelFormat32bppBGR, PixelFormat32bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, ++ { &GUID_WICPixelFormat48bppRGB, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, + { &GUID_WICPixelFormat32bppBGRA, PixelFormat32bppARGB, WICBitmapPaletteTypeFixedHalftone256 }, + { &GUID_WICPixelFormat32bppPBGRA, PixelFormat32bppPARGB, WICBitmapPaletteTypeFixedHalftone256 }, ++ { &GUID_WICPixelFormat32bppCMYK, PixelFormat32bppCMYK, WICBitmapPaletteTypeFixedHalftone256 }, ++ { &GUID_WICPixelFormat64bppCMYK, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, ++ { &GUID_WICPixelFormat64bppRGBA, PixelFormat48bppRGB, WICBitmapPaletteTypeFixedHalftone256 }, + { NULL } + }; + +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch b/patches/windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch new file mode 100644 index 00000000..12d63e39 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/0017-gdiplus-tests-Add-some-tests-for-loading-TIFF-images.patch @@ -0,0 +1,221 @@ +From 29530ea2e00204e1beb741bc6932cd86824128d6 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Fri, 16 Dec 2016 18:10:30 +0800 +Subject: gdiplus/tests: Add some tests for loading TIFF images in various + color formats. + +--- + dlls/gdiplus/tests/image.c | 183 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 181 insertions(+), 2 deletions(-) + +diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c +index 05dab89..79cdfa3 100644 +--- a/dlls/gdiplus/tests/image.c ++++ b/dlls/gdiplus/tests/image.c +@@ -3087,8 +3087,6 @@ static GpImage *load_image(const BYTE *image_data, UINT image_size) + ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount); + + status = GdipLoadImageFromStream(stream, &image); +- ok(status == Ok || broken(status == InvalidParameter), /* XP */ +- "GdipLoadImageFromStream error %d\n", status); + if (status != Ok) + { + IStream_Release(stream); +@@ -5148,6 +5146,186 @@ todo_wine + GdipDisposeImage((GpImage *)bitmap); + } + ++#include "pshpack2.h" ++static const struct tiff_1x1_data ++{ ++ USHORT byte_order; ++ USHORT version; ++ ULONG dir_offset; ++ USHORT number_of_entries; ++ struct IFD_entry entry[12]; ++ ULONG next_IFD; ++ struct IFD_rational res; ++ short palette_data[3][256]; ++ short bps_data[4]; ++ BYTE pixel_data[32]; ++} tiff_1x1_data = ++{ ++#ifdef WORDS_BIGENDIAN ++ 'M' | 'M' << 8, ++#else ++ 'I' | 'I' << 8, ++#endif ++ 42, ++ FIELD_OFFSET(struct tiff_1x1_data, number_of_entries), ++ 12, ++ { ++ { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ ++ { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ ++ { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ ++ { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */ ++ { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ ++ { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */ ++ { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */ ++ { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */ ++ { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, ++ { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, ++ { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ ++ { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */ ++ }, ++ 0, ++ { 96, 1 }, ++ { { 0 } }, ++ { 8,8,8,0 }, ++ { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 } ++}; ++#include "poppack.h" ++ ++static void test_tiff_color_formats(void) ++{ ++ static const struct ++ { ++ int photometric; /* PhotometricInterpretation */ ++ int samples; /* SamplesPerPixel */ ++ int bps; /* BitsPerSample */ ++ PixelFormat format; ++ } td[] = ++ { ++ /* 2 - RGB */ ++ { 2, 3, 1, PixelFormat24bppRGB }, ++ { 2, 3, 4, PixelFormat24bppRGB }, ++ { 2, 3, 8, PixelFormat24bppRGB }, ++ { 2, 3, 16, PixelFormat48bppRGB }, ++ { 2, 3, 24, 0 }, ++#if 0 /* FIXME */ ++ { 2, 3, 32, 0 }, ++#endif ++ { 2, 4, 1, PixelFormat32bppARGB }, ++ { 2, 4, 4, PixelFormat32bppARGB }, ++ { 2, 4, 8, PixelFormat32bppARGB }, ++ { 2, 4, 16, PixelFormat48bppRGB }, ++ { 2, 4, 24, 0 }, ++ { 2, 4, 32, 0 }, ++ /* 1 - BlackIsZero (Bilevel) */ ++ { 1, 1, 1, PixelFormat1bppIndexed }, ++#if 0 /* FIXME: PNG vs TIFF mismatch */ ++ { 1, 1, 4, PixelFormat8bppIndexed }, ++#endif ++ { 1, 1, 8, PixelFormat8bppIndexed }, ++ { 1, 1, 16, PixelFormat32bppARGB }, ++ { 1, 1, 24, 0 }, ++ { 1, 1, 32, PixelFormat32bppARGB }, ++ /* 3 - Palette Color */ ++ { 3, 1, 1, PixelFormat1bppIndexed }, ++ { 3, 1, 4, PixelFormat4bppIndexed }, ++ { 3, 1, 8, PixelFormat8bppIndexed }, ++#if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */ ++ { 3, 1, 16, 0 }, ++ { 3, 1, 24, 0 }, ++ { 3, 1, 32, 0 }, ++#endif ++ /* 5 - Separated */ ++ { 5, 4, 1, 0 }, ++ { 5, 4, 4, 0 }, ++ { 5, 4, 8, PixelFormat32bppCMYK }, ++ { 5, 4, 16, PixelFormat48bppRGB }, ++ { 5, 4, 24, 0 }, ++ { 5, 4, 32, 0 }, ++ }; ++ BYTE buf[sizeof(tiff_1x1_data)]; ++ GpStatus status; ++ GpImage *image; ++ UINT count, i; ++ struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL; ++ short *bps; ++ ImageType type; ++ PixelFormat format; ++ ++ memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data)); ++ ++ count = *(short *)(buf + tiff_1x1_data.dir_offset); ++ tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short)); ++ ++ /* verify the TIFF structure */ ++ for (i = 0; i < count; i++) ++ { ++ if (tag[i].id == 0x102) /* BitsPerSample */ ++ tag_bps = &tag[i]; ++ else if (tag[i].id == 0x106) /* PhotometricInterpretation */ ++ tag_photo = &tag[i]; ++ else if (tag[i].id == 0x115) /* SamplesPerPixel */ ++ tag_samples = &tag[i]; ++ else if (tag[i].id == 0x140) /* ColorMap */ ++ tag_colormap = &tag[i]; ++ } ++ ++ ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n"); ++ if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return; ++ ++ ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n"); ++ bps = (short *)(buf + tag_bps->value); ++ ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0, ++ "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]); ++ ++ for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) ++ { ++ tag_colormap->count = (1 << td[i].bps) * 3; ++ tag_photo->value = td[i].photometric; ++ tag_bps->count = td[i].samples; ++ tag_samples->value = td[i].samples; ++ ++ if (td[i].samples == 1) ++ tag_bps->value = td[i].bps; ++ else if (td[i].samples == 2) ++ tag_bps->value = MAKELONG(td[i].bps, td[i].bps); ++ else if (td[i].samples == 3) ++ { ++ tag_bps->value = (BYTE *)bps - buf; ++ bps[0] = bps[1] = bps[2] = td[i].bps; ++ } ++ else if (td[i].samples == 4) ++ { ++ tag_bps->value = (BYTE *)bps - buf; ++ bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps; ++ } ++ else ++ { ++ ok(0, "%u: unsupported samples count %d\n", i, td[i].samples); ++ continue; ++ } ++ ++ image = load_image(buf, sizeof(buf)); ++ if (!td[i].format) ++ ok(!image, ++ "%u: (%d,%d,%d) TIFF image loading should have failed\n", i, td[i].photometric, td[i].samples, td[i].bps); ++ else ++ ok(image != NULL || broken(!image) /* XP */, "%u: failed to load TIFF image data (%d,%d,%d)\n", ++ i, td[i].photometric, td[i].samples, td[i].bps); ++ if (!image) continue; ++ ++ status = GdipGetImageType(image, &type); ++ ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status); ++ ok(type == ImageTypeBitmap, "%u: wrong image type %d\n", i, type); ++ ++ status = GdipGetImagePixelFormat(image, &format); ++ expect(Ok, status); ++ ok(format == td[i].format, ++ "%u: expected %#x, got %#x\n", i, td[i].format, format); ++ ++ GdipDisposeImage(image); ++ } ++} ++ + START_TEST(image) + { + HMODULE mod = GetModuleHandleA("gdiplus.dll"); +@@ -5165,6 +5343,7 @@ START_TEST(image) + pGdipBitmapGetHistogram = (void*)GetProcAddress(mod, "GdipBitmapGetHistogram"); + pGdipImageSetAbort = (void*)GetProcAddress(mod, "GdipImageSetAbort"); + ++ test_tiff_color_formats(); + test_GdipInitializePalette(); + test_png_color_formats(); + test_supported_encoders(); +-- +2.9.0 + diff --git a/patches/windowscodecs-TIFF_Support/definition b/patches/windowscodecs-TIFF_Support/definition new file mode 100644 index 00000000..8528e806 --- /dev/null +++ b/patches/windowscodecs-TIFF_Support/definition @@ -0,0 +1,3 @@ +Fixes: Improve TIFF support in windowscodecs.dll +Depends: windowscodecs-GIF_Encoder +Depends: windowscodecs-IWICPalette_InitializeFromBitmap