gdiplus/tests: Add more PNG color format tests.

Signed-off-by: Akihiro Sagawa <sagawa.aki@gmail.com>
Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Akihiro Sagawa 2018-11-08 22:17:01 +09:00 committed by Alexandre Julliard
parent 70a3e86997
commit 5855ff7846

View file

@ -3217,7 +3217,7 @@ static LONG obj_refcount(void *obj)
return IUnknown_Release((IUnknown *)obj);
}
static GpImage *load_image(const BYTE *image_data, UINT image_size)
static GpImage *load_image(const BYTE *image_data, UINT image_size, BOOL valid_data, BOOL todo_load)
{
IStream *stream;
HGLOBAL hmem;
@ -3241,8 +3241,12 @@ 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);
todo_wine_if(todo_load)
if (valid_data)
ok(status == Ok || broken(status == InvalidParameter), /* XP */
"GdipLoadImageFromStream error %d\n", status);
else
ok(status != Ok, "GdipLoadImageFromStream should fail\n");
if (status != Ok)
{
IStream_Release(stream);
@ -3313,7 +3317,7 @@ static void test_image_properties(void)
for (i = 0; i < ARRAY_SIZE(td); i++)
{
image = load_image(td[i].image_data, td[i].image_size);
image = load_image(td[i].image_data, td[i].image_size, TRUE, FALSE);
if (!image)
{
trace("%u: failed to load image data\n", i);
@ -3606,7 +3610,7 @@ static void test_tiff_properties(void)
PROPID *prop_id;
PropertyItem *prop_item;
image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data));
image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data), TRUE, FALSE);
if (!image)
{
win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
@ -3718,7 +3722,7 @@ static void test_GdipGetAllPropertyItems(void)
PropertyItem *prop_item;
const char *item_data;
image = load_image(tiffimage, sizeof(tiffimage));
image = load_image(tiffimage, sizeof(tiffimage), TRUE, FALSE);
ok(image != 0, "Failed to load TIFF image data\n");
if (!image) return;
@ -3866,7 +3870,7 @@ static void test_tiff_palette(void)
ARGB *entries = palette.pal.Entries;
/* 1bpp TIFF without palette */
image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data));
image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data), TRUE, FALSE);
if (!image)
{
win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
@ -4517,7 +4521,7 @@ static void test_gif_properties(void)
PropertyItem *prop_item;
const char *item_data;
image = load_image(animatedgif, sizeof(animatedgif));
image = load_image(animatedgif, sizeof(animatedgif), TRUE, FALSE);
if (!image) /* XP fails to load this GIF image */
{
trace("Failed to load GIF image data\n");
@ -5101,65 +5105,208 @@ static void test_imageabort(void)
static const char png_1x1_data[] = {
0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
0x00,0x00,0x00,0x0d,'I','H','D','R',0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,0xde,
0x00,0x00,0x03,0x00,'P','L','T','E',
0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,
0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,
0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,
0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x48,
0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,
0x51,0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,0x58,
0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,
0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,
0x69,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x70,
0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,
0x79,0x79,0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,
0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,
0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,
0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,
0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x48,
0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,
0x51,0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,0x58,
0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,
0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,
0x69,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x70,
0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,
0x79,0x79,0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,
0x76,0xb6,0x24,0x31,
0x00,0x00,0x00,0x02,'t','R','N','S',0xff,0x00,0xe5,0xb7,0x30,0x4a,
0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
};
#define PNG_COLOR_TYPE_GRAY 0
#define PNG_COLOR_TYPE_RGB 2
#define PNG_COLOR_TYPE_PALETTE 3
#define PNG_COLOR_TYPE_GRAY_ALPHA 4
#define PNG_COLOR_TYPE_RGB_ALPHA 6
static void test_png_color_formats(void)
{
static const struct
{
char bit_depth, color_type;
PixelFormat format;
UINT flags;
struct {
PixelFormat format;
ImageFlags flags;
BOOL todo;
BOOL todo_load;
} t[3];
} td[] =
{
/* 2 - PNG_COLOR_TYPE_RGB */
{ 8, 2, PixelFormat24bppRGB, ImageFlagsColorSpaceRGB },
/* 0 - PNG_COLOR_TYPE_GRAY */
{ 1, 0, PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB },
{ 2, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ 4, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ 8, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ 16, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
/* 0 */
{ 1, PNG_COLOR_TYPE_RGB },
{ 2, PNG_COLOR_TYPE_RGB },
{ 4, PNG_COLOR_TYPE_RGB },
{ 8, PNG_COLOR_TYPE_RGB,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{ PixelFormat24bppRGB, ImageFlagsColorSpaceRGB },
{ PixelFormat24bppRGB, ImageFlagsColorSpaceRGB }}},
/* libpng refuses to load our test image complaining about extra compressed data,
* but libpng is still able to load the image with other combination of type/depth
* making RGB 16 bpp case special for some reason. Therefore todo = TRUE.
*/
{ 16, PNG_COLOR_TYPE_RGB,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE, TRUE },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE, TRUE },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE, TRUE }}},
/* 5 */
{ 1, PNG_COLOR_TYPE_GRAY,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{ PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB },
{ PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB }}},
{ 2, PNG_COLOR_TYPE_GRAY,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }}},
{ 4, PNG_COLOR_TYPE_GRAY,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }}},
{ 8, PNG_COLOR_TYPE_GRAY,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }}},
{ 16, PNG_COLOR_TYPE_GRAY,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }}},
/* 10 */
{ 1, PNG_COLOR_TYPE_PALETTE,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{ PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB },
{ 0, 0 }}},
{ 2, PNG_COLOR_TYPE_PALETTE,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ 0, 0 }}},
{ 4, PNG_COLOR_TYPE_PALETTE,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB },
{ PixelFormat4bppIndexed, ImageFlagsColorSpaceRGB, TRUE },
{ 0, 0 }}},
{ 8, PNG_COLOR_TYPE_PALETTE,
{{ PixelFormat32bppARGB, ImageFlagsColorSpaceRGB, TRUE },
{ PixelFormat8bppIndexed, ImageFlagsColorSpaceRGB },
{ 0, 0 }}},
{ 16, PNG_COLOR_TYPE_PALETTE },
};
BYTE buf[sizeof(png_1x1_data)];
GpStatus status;
GpImage *image;
ImageType type;
PixelFormat format;
UINT flags;
int i;
ImageFlags flags;
BOOL valid;
int i, j, PLTE_off = 0, tRNS_off = 0;
const ImageFlags color_space_mask = ImageFlagsColorSpaceRGB | ImageFlagsColorSpaceCMYK | ImageFlagsColorSpaceGRAY | ImageFlagsColorSpaceYCBCR | ImageFlagsColorSpaceYCCK;
memcpy(buf, png_1x1_data, sizeof(png_1x1_data));
buf[24] = 2;
buf[25] = PNG_COLOR_TYPE_PALETTE;
image = load_image(buf, sizeof(buf), TRUE, FALSE);
status = GdipGetImageFlags(image, &flags);
expect(status, Ok);
ok((flags & color_space_mask) == ImageFlagsColorSpaceRGB || broken(flags == 0x12006) /* before win7 */,
"flags = %#x\n", flags);
if ((flags & color_space_mask) != ImageFlagsColorSpaceRGB) {
GdipDisposeImage(image);
win_skip("broken PNG color space support\n");
return;
}
GdipDisposeImage(image);
for (i = 0; i < sizeof(png_1x1_data) - 4; i++)
{
if (!memcmp(buf + i, "tRNS", 4))
tRNS_off = i;
else if (!memcmp(buf + i, "PLTE", 4))
PLTE_off = i;
}
ok(PLTE_off && tRNS_off, "PLTE offset %d, tRNS offset %d\n", PLTE_off, tRNS_off);
if (!PLTE_off || !tRNS_off) return;
/* In order to test the image data with and without PLTE and tRNS
* chunks, we mask the chunk name with private one (tEST).
*/
for (i = 0; i < ARRAY_SIZE(td); i++)
{
memcpy(buf, png_1x1_data, sizeof(png_1x1_data));
buf[24] = td[i].bit_depth;
buf[25] = td[i].color_type;
for (j = 0; j < 3; j++)
{
memcpy(buf, png_1x1_data, sizeof(png_1x1_data));
buf[24] = td[i].bit_depth;
buf[25] = td[i].color_type;
if (j >=1) memcpy(buf + tRNS_off, "tEST", 4);
if (j >=2) memcpy(buf + PLTE_off, "tEST", 4);
image = load_image(buf, sizeof(buf));
ok(image != NULL, "%d: failed to load image data\n", i);
if (!image) continue;
valid = (td[i].t[j].format != 0) || (td[i].t[j].flags != 0);
image = load_image(buf, sizeof(buf), valid, td[i].t[j].todo_load);
todo_wine_if(td[i].t[j].todo_load)
if (valid)
ok(image != NULL, "%d %d: failed to load image data\n", i, j);
else
{
ok(image == NULL, "%d %d: succeed to load image data\n", i, j);
if (image) GdipDisposeImage(image);
image = NULL;
}
if (!image) continue;
status = GdipGetImageType(image, &type);
ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status);
ok(type == ImageTypeBitmap, "%d: wrong image type %d\n", i, type);
status = GdipGetImageType(image, &type);
ok(status == Ok, "%d %d: GdipGetImageType error %d\n", i, j, status);
ok(type == ImageTypeBitmap, "%d %d: wrong image type %d\n", i, j, type);
status = GdipGetImagePixelFormat(image, &format);
expect(Ok, status);
ok(format == td[i].format ||
broken(td[i].bit_depth == 1 && td[i].color_type == 0 && format == PixelFormat32bppARGB), /* XP */
"%d: expected %#x, got %#x\n", i, td[i].format, format);
status = GdipGetImagePixelFormat(image, &format);
expect(Ok, status);
todo_wine_if(td[i].t[j].todo)
ok(format == td[i].t[j].format,
"%d %d: expected %#x, got %#x\n", i, j, td[i].t[j].format, format);
status = GdipGetImageFlags(image, &flags);
expect(Ok, status);
ok((flags & td[i].flags) == td[i].flags ||
broken(td[i].bit_depth == 1 && td[i].color_type == 0 && (flags & ImageFlagsColorSpaceGRAY)), /* XP */
"%d: expected %#x, got %#x\n", i, td[i].flags, flags);
GdipDisposeImage(image);
status = GdipGetImageFlags(image, &flags);
expect(Ok, status);
ok((flags & color_space_mask) == td[i].t[j].flags,
"%d %d: expected %#x, got %#x\n", i, j, td[i].t[j].flags, flags);
GdipDisposeImage(image);
}
}
}
#undef PNG_COLOR_TYPE_GRAY
#undef PNG_COLOR_TYPE_RGB
#undef PNG_COLOR_TYPE_PALETTE
#undef PNG_COLOR_TYPE_GRAY_ALPHA
#undef PNG_COLOR_TYPE_RGB_ALPHA
static void test_GdipLoadImageFromStream(void)
{