1 #ifdef WIN32
2 #ifndef __cplusplus
3 #error Please compile with a C++ compiler.
4 #endif
5 #endif
6
7 #if defined(USE_WINDOWS_GDIPLUS)
8 #include <Windows.h>
9 #include <GdiPlus.h>
10
11 #pragma comment(lib, "gdiplus.lib")
12 #else
13 #include <GdiPlusFlat.h>
14 #endif
15
16 #if defined(USE_WINDOWS_GDIPLUS)
17 using namespace Gdiplus;
18 using namespace DllExports;
19 #endif
20
21 #include <assert.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "testhelpers.h"
25
26 static const char *file = "temp_asset.png";
27 static WCHAR wFile[] = {'t', 'e', 'm', 'p', '_', 'a', 's', 's', 'e', 't', '.', 'p', 'n', 'g', 0};
28 GpImage *image;
29
30 #define createFile(buffer, expectedStatus) \
31 { \
32 GpStatus status; \
33 FILE *f = fopen (file, "wb+"); \
34 assert (f); \
35 fwrite ((void *) buffer, sizeof (BYTE), sizeof (buffer), f); \
36 fclose (f); \
37 \
38 status = GdipLoadImageFromFile (wFile, &image); \
39 assertEqualInt (status, expectedStatus); \
40 }
41
42 #define createFileSuccess(buffer, format, width, height, flags, propertyCount) \
43 { \
44 createFile (buffer, Ok); \
45 /* FIXME: grayscale image flags are incorrect. */ \
46 verifyBitmap (image, pngRawFormat, format, width, height, flags, propertyCount, FALSE); \
47 GdipDisposeImage (image); \
48 }
49
test_valid1bpp()50 static void test_valid1bpp()
51 {
52 BYTE grayscale1bpp1x1Interlaced[] = {
53 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
54 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x69, 0xC9, 0xB2,
55 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x68, 0x00, 0x00, 0x00, 0x82, 0x00, 0x81, 0xA7, 0x01, 0xBA, 0x10,
56 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
57 };
58 BYTE grayscale1bpp1x1NotInterlaced[] = {
59 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
60 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x37, 0x6E, 0xF9, 0x24,
61 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x98, 0x63, 0x6C, 0xD7,
62 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
63 };
64 BYTE grayscale1bpp1x1WithPalette[] = {
65 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
66 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x69, 0xC9, 0xB2,
67 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x68, 0x00, 0x00, 0x00, 0x82, 0x00, 0x81, 0xA7, 0x01, 0xBA, 0x10,
68 /* PLTE */ 0x00, 0x00, 0x00, 0x06, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xA5, 0xD9, 0x9F, 0xDD,
69 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
70 };
71 BYTE indexed1bpp1x1PaletteFirst[] = {
72 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
73 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 0xDB, 0x56, 0xCA,
74 /* PLTE */ 0x00, 0x00, 0x00, 0x06, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xA5, 0xD9, 0x9F, 0xDD,
75 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x68, 0x00, 0x00, 0x00, 0x82, 0x00, 0x81, 0xA7, 0x01, 0xBA, 0x10,
76 /* IEND*/ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
77 };
78 #if defined(USE_WINDOWS_GDIPLUS)
79 BYTE indexed1bpp1x1PaletteLast[] = {
80 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
81 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 0xDB, 0x56, 0xCA,
82 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x68, 0x00, 0x00, 0x00, 0x82, 0x00, 0x81, 0xA7, 0x01, 0xBA, 0x10,
83 /* PLTE */ 0x00, 0x00, 0x00, 0x06, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xA5, 0xD9, 0x9F, 0xDD,
84 /* IEND*/ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
85 };
86 #endif
87
88 createFileSuccess (grayscale1bpp1x1Interlaced, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
89 createFileSuccess (grayscale1bpp1x1NotInterlaced, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
90 createFileSuccess (grayscale1bpp1x1WithPalette, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
91 createFileSuccess (indexed1bpp1x1PaletteFirst, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
92
93 // FIXME: GDI+ allows indexed images with palettes last.
94 #if defined(USE_WINDOWS_GDIPLUS)
95 createFileSuccess (indexed1bpp1x1PaletteLast, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
96 #endif
97 }
98
test_valid2bpp()99 static void test_valid2bpp ()
100 {
101 #if defined(USE_WINDOWS_GDIPLUS)
102 BYTE grayscale2bpp1x1Interlaced[] = {
103 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
104 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x07, 0xC9, 0xB3, 0x62,
105 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x70, 0x00, 0x00, 0x00, 0x42, 0x00, 0x41, 0xF9, 0xFB, 0x3C, 0x49,
106 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
107 };
108 BYTE grayscale2bpp6x4NotInterlaced[] = {
109 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
110 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xDF, 0x09, 0x3E,
111 /* IDAT */ 0x00, 0x00, 0x00, 0x14, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x08, 0x0D, 0x60, 0xC8, 0x9A, 0xC0, 0x50, 0x70, 0x81, 0x81, 0x81, 0x01, 0x00, 0x13, 0x83, 0x02, 0xE0, 0x20, 0x93, 0x79, 0xCF,
112 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
113 };
114 BYTE grayscale2bpp1x1WithPalette[] = {
115 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
116 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x07, 0xC9, 0xB3, 0x62,
117 /* PLTE */ 0x00, 0x00, 0x00, 0x09, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xE6, 0xE6, 0xFA, 0x0D, 0xB2, 0xEB, 0x46,
118 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x70, 0x00, 0x00, 0x00, 0x42, 0x00, 0x41, 0xF9, 0xFB, 0x3C, 0x49,
119 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
120 };
121 #endif
122 BYTE indexed2bpp1x1PaletteFirst[] = {
123 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
124 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0x00, 0x01, 0x15, 0x7C, 0x1C, 0x8C,
125 /* PLTE */ 0x00, 0x00, 0x00, 0x09, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xE6, 0xE6, 0xFA, 0x0D, 0xB2, 0xEB, 0x46,
126 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x70, 0x00, 0x00, 0x00, 0x42, 0x00, 0x41, 0xF9, 0xFB, 0x3C, 0x49,
127 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
128 };
129 #if defined(USE_WINDOWS_GDIPLUS)
130 BYTE indexed2bpp6x4PaletteLast[] = {
131 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
132 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x02, 0x03, 0x00, 0x00, 0x01, 0xA7, 0x6D, 0x96, 0x46,
133 /* IDAT */ 0x00, 0x00, 0x00, 0x16, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x70, 0x00, 0x43, 0x1F, 0x86, 0x10, 0x86, 0x23, 0x0C, 0x59, 0x13, 0x18, 0x18, 0x18, 0x00, 0x1B, 0x38, 0x03, 0x1F, 0xE2, 0xF7, 0x9D, 0x3B,
134 /* PLTE */ 0x00, 0x00, 0x00, 0x09, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xE6, 0xE6, 0xFA, 0x0D, 0xB2, 0xEB, 0x46,
135 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
136 };
137 #endif
138
139 // FIXME: this causes an AV in libgdiplus when trying to convert this image to 32bpp as we assume
140 // the image has a palette.
141 #if defined(USE_WINDOWS_GDIPLUS)
142 createFileSuccess (grayscale2bpp1x1Interlaced, PixelFormat32bppARGB, 1, 1, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
143 createFileSuccess (grayscale2bpp6x4NotInterlaced, PixelFormat32bppARGB, 6, 4, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
144 createFileSuccess (grayscale2bpp1x1WithPalette, PixelFormat32bppARGB, 1, 1, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
145 #endif
146 createFileSuccess (indexed2bpp1x1PaletteFirst, PixelFormat32bppARGB, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
147 // FIXME: GDI+ allows indexed images with palettes last.
148 #if defined(USE_WINDOWS_GDIPLUS)
149 createFileSuccess (indexed2bpp6x4PaletteLast, PixelFormat32bppARGB, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
150 #endif
151 }
152
test_valid4bpp()153 static void test_valid4bpp()
154 {
155 BYTE grayscaleWithAlpha1x1Interlaced[] = {
156 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
157 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x01, 0x88, 0x89, 0x46, 0xC2,
158 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x11, 0x75, 0x9A, 0x0F, 0xE8,
159 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
160 };
161 BYTE grayscaleWithAlpha6x4NotInterlaced[] = {
162 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
163 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x9F, 0xFC, 0x9E,
164 /* IDAT */ 0x00, 0x00, 0x00, 0x18, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x10, 0x14, 0x14, 0x64, 0x10, 0x71, 0x71, 0x64, 0x90, 0x2F, 0xFF, 0xC8, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x10, 0xFF, 0x02, 0x54, 0xB8, 0xE8, 0x8D, 0xCD,
165 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
166 };
167 BYTE grayscaleWithAlpha1x1WithPalette[] = {
168 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
169 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x01, 0x88, 0x89, 0x46, 0xC2,
170 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
171 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x11, 0x75, 0x9A, 0x0F, 0xE8,
172 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
173 };
174 BYTE indexed4bpp1x1PaletteFirst[] = {
175 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
176 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 0x03, 0x00, 0x00, 0x01, 0x9A, 0x3C, 0xE9, 0x2C,
177 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
178 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x11, 0x75, 0x9A, 0x0F, 0xE8,
179 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
180 };
181 #if defined(USE_WINDOWS_GDIPLUS)
182 BYTE indexed4bpp6x4PaletteLast[] = {
183 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
184 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
185 /* IDAT */ 0x00, 0x00, 0x00, 0x1B, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x10, 0x00, 0x43, 0xF1, 0x0F, 0x0C, 0x82, 0x02, 0x0C, 0xDF, 0x05, 0x18, 0x44, 0x5C, 0x1C, 0x19, 0x18, 0x18, 0x18, 0x00, 0x22, 0x93, 0x02, 0xF9, 0x27, 0x14, 0x52, 0x58,
186 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
187 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
188 };
189 #endif
190
191 // FIXME: GDI+ converts grayscale alpha 4bpp images to 32bpp.
192 #if defined(USE_WINDOWS_GDIPLUS)
193 PixelFormat expectedGrayscalePixelFormat = PixelFormat32bppARGB;
194 #else
195 PixelFormat expectedGrayscalePixelFormat = PixelFormat4bppIndexed;
196 #endif
197 createFileSuccess (grayscaleWithAlpha1x1Interlaced, expectedGrayscalePixelFormat, 1, 1, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
198 createFileSuccess (grayscaleWithAlpha6x4NotInterlaced, expectedGrayscalePixelFormat, 6, 4, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
199 createFileSuccess (grayscaleWithAlpha1x1WithPalette, expectedGrayscalePixelFormat, 1, 1, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
200 createFileSuccess (indexed4bpp1x1PaletteFirst, PixelFormat4bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
201 // FIXME: GDI+ allows indexed images with palettes last.
202 #if defined(USE_WINDOWS_GDIPLUS)
203 createFileSuccess (indexed4bpp6x4PaletteLast, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
204 #endif
205 }
206
test_valid8bpp()207 static void test_valid8bpp ()
208 {
209 BYTE grayscale1x1Interlaced[] = {
210 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
211 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x4D, 0x79, 0xAB, 0xC3,
212 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0x60, 0x04, 0x00, 0x00, 0x03, 0x00, 0x02, 0xA0, 0x80, 0x44, 0x0F,
213 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
214 };
215 BYTE grayscale6x4NotInterlaced[] = {
216 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
217 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R',0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x88, 0x6F, 0x11, 0x9F,
218 /* IDAT */ 0x00, 0x00, 0x00, 0x1D, 'I', 'D', 'A', 'T',0x18, 0x57, 0x63, 0x64, 0x64, 0x00, 0x01, 0x46, 0x46, 0x26, 0x20, 0xF9, 0x8F, 0x89, 0xE1, 0x0F, 0x0B, 0xCB, 0x1F, 0xB0, 0x08, 0x03, 0x03, 0x03, 0x00, 0x24, 0xA0, 0x03, 0x07, 0xA7, 0x85, 0xE0, 0xA2,
219 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D',0xAE, 0x42, 0x60, 0x82
220 };
221 BYTE grayscale1x1WithPalette[] = {
222 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
223 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x4D, 0x79, 0xAB, 0xC3,
224 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
225 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0x60, 0x04, 0x00, 0x00, 0x03, 0x00, 0x02, 0xA0, 0x80, 0x44, 0x0F,
226 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
227 };
228 BYTE indexed1x1PaletteFirst[] = {
229 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
230 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x03, 0x00, 0x00, 0x01, 0x5F, 0xCC, 0x04, 0x2D,
231 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
232 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x11, 0x75, 0x9A, 0x0F, 0xE8,
233 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
234 };
235 #if defined(USE_WINDOWS_GDIPLUS)
236 BYTE indexed6x4PaletteLast[] = {
237 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
238 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x08, 0x03, 0x00, 0x00, 0x01, 0xED, 0xDD, 0x8E, 0xE7,
239 /* IDAT */ 0x00, 0x00, 0x00, 0x1E, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0x60, 0x84, 0x40, 0xF6, 0xFF, 0x0C, 0x8C, 0x8C, 0x8C, 0x0C, 0xFF, 0xD9, 0x81, 0x6C, 0x66, 0x20, 0x60, 0x64, 0x00, 0x01, 0x06, 0x06, 0x00, 0x2A, 0x5E, 0x02, 0x23, 0xF7, 0x26, 0x7C, 0xAC,
240 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
241 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
242 };
243 #endif
244 BYTE trueColor1x1Interlaced[] = {
245 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
246 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x01, 0xE7, 0x70, 0x63, 0x48,
247 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xCF, 0xC0, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x63, 0x24, 0x55, 0xD3,
248 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
249 };
250 BYTE trueColor6x4NotInterlaced[] = {
251 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
252 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x08, 0x02, 0x00, 0x00, 0x00, 0x22, 0x66, 0xD9, 0x14,
253 /* IDAT */ 0x00, 0x00, 0x00, 0x2A, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xFC, 0xCF, 0x80, 0x0E, 0x40, 0x42, 0xCF, 0x9F, 0xFD, 0x82, 0xF2, 0x18, 0x18, 0x24, 0xA5, 0xD8, 0x18, 0x20, 0xAA, 0xDE, 0x35, 0xBD, 0x03, 0x22, 0x20, 0x03, 0xC8, 0x65, 0x04, 0x93, 0x48, 0x80, 0x81, 0x01, 0x00, 0xEE, 0x67, 0x0C, 0xBB, 0x0E, 0x63, 0x55, 0x28,
254 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
255 };
256 BYTE trueColor1x1WithPalette[] = {
257 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
258 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x01, 0xE7, 0x70, 0x63, 0x48,
259 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
260 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xCF, 0xC0, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x63, 0x24, 0x55, 0xD3,
261 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
262 };
263 BYTE trueColorWithAlpha1x1Interlaced[] = {
264 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
265 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x01, 0x68, 0x12, 0xF4, 0x1F,
266 /* IDAT */ 0x00, 0x00, 0x00, 0x0D, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xCF, 0xC0, 0xB0, 0x1F, 0x00, 0x04, 0xC0, 0x01, 0xBF, 0xBD, 0x98, 0x5E, 0x91,
267 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
268 };
269 BYTE trueColorWithAlpha6x4NotInterlaced[] = {
270 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
271 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x08, 0x06, 0x00, 0x00, 0x00, 0xAD, 0x04, 0x4E, 0x43,
272 /* IDAT */ 0x00, 0x00, 0x00, 0x3E, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xFC, 0xCF, 0xC0, 0xB0, 0x9F, 0x81, 0x81, 0xE1, 0x00, 0x10, 0x5F, 0x03, 0x62, 0x10, 0xD0, 0x02, 0x62, 0x07, 0x06, 0xA0, 0x44, 0xFD, 0xB3, 0x67, 0xBF, 0xFE, 0x23, 0x63, 0x90, 0x18, 0x13, 0x48, 0x89, 0x94, 0x14, 0x1B, 0x23, 0xC7, 0x9C, 0x2F, 0x61, 0x20, 0x0C, 0x62, 0x83, 0xC4, 0x80, 0x04, 0x48, 0x01, 0x3A, 0x60, 0x60, 0x00, 0x00, 0x90, 0x2B, 0x1C, 0x23, 0xE8, 0xDB, 0x69, 0x10,
273 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
274 };
275 BYTE trueColorWithAlpha1x1WithPalette[] = {
276 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
277 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x01, 0x68, 0x12, 0xF4, 0x1F,
278 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
279 /* IDAT */ 0x00, 0x00, 0x00, 0x0D, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xCF, 0xC0, 0xB0, 0x1F, 0x00, 0x04, 0xC0, 0x01, 0xBF, 0xBD, 0x98, 0x5E, 0x91,
280 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
281 };
282
283 // FIXME: GDI+ converts grayscale 8bpp images to 32bpp.
284 #if defined(USE_WINDOWS_GDIPLUS)
285 PixelFormat expectedGrayscalePixelFormat = PixelFormat32bppARGB;
286 #else
287 PixelFormat expectedGrayscalePixelFormat = PixelFormat8bppIndexed;
288 #endif
289 createFileSuccess (grayscale1x1Interlaced, expectedGrayscalePixelFormat, 1, 1, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
290 createFileSuccess (grayscale6x4NotInterlaced, expectedGrayscalePixelFormat, 6, 4, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
291 createFileSuccess (grayscale1x1WithPalette, expectedGrayscalePixelFormat, 1, 1, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
292 createFileSuccess (indexed1x1PaletteFirst, PixelFormat8bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
293 // FIXME: GDI+ allows indexed images with palettes last.
294 #if defined(USE_WINDOWS_GDIPLUS)
295 createFileSuccess (indexed6x4PaletteLast, PixelFormat8bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
296 #endif
297 createFileSuccess (trueColor1x1Interlaced, PixelFormat24bppRGB, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
298 createFileSuccess (trueColor6x4NotInterlaced, PixelFormat24bppRGB, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
299 createFileSuccess (trueColor1x1WithPalette, PixelFormat24bppRGB, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
300 createFileSuccess (trueColorWithAlpha1x1Interlaced, PixelFormat32bppARGB, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
301 createFileSuccess (trueColorWithAlpha6x4NotInterlaced, PixelFormat32bppARGB, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
302 createFileSuccess (trueColorWithAlpha1x1WithPalette, PixelFormat32bppARGB, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
303 }
304
test_valid16bpp()305 static void test_valid16bpp ()
306 {
307 BYTE grayscale1x1Interlaced[] = {
308 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
309 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x01, 0x1D, 0xE9, 0x77, 0x80,
310 /* IDAT */ 0x00, 0x00, 0x00, 0x0B, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xA8, 0xFF, 0x0F, 0x00, 0x02, 0x00, 0x01, 0x7F, 0x2F, 0x5A, 0xAA, 0x27,
311 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
312 };
313 BYTE grayscale6x4NotInterlaced[] = {
314 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
315 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xCD, 0xDC,
316 /* IDAT */ 0x00, 0x00, 0x00, 0x21, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xFC, 0xFF, 0x9F, 0x01, 0x0E, 0x80, 0x9C, 0x06, 0x28, 0xB3, 0x81, 0x81, 0x85, 0x81, 0xE1, 0x5A, 0x18, 0x94, 0xB7, 0x0A, 0x4A, 0x83, 0x00, 0x03, 0x03, 0x00, 0xF4, 0x31, 0x06, 0xD9, 0x82, 0x8E, 0x6A, 0xA9,
317 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
318 };
319 BYTE grayscale1x1WithPalette[] = {
320 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
321 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x01, 0x1D, 0xE9, 0x77, 0x80,
322 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
323 /* IDAT */ 0x00, 0x00, 0x00, 0x0B, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xA8, 0xFF, 0x0F, 0x00, 0x02, 0x00, 0x01, 0x7F, 0x2F, 0x5A, 0xAA, 0x27,
324 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
325 };
326 BYTE trueColor1x1Interlaced[] = {
327 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
328 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00, 0x01, 0xB7, 0xE0, 0xBF, 0x0B,
329 /* IDAT */ 0x00, 0x00, 0x00, 0x0F, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xFF, 0x9F, 0x81, 0x81, 0x81, 0x01, 0x00, 0x0A, 0xFC, 0x01, 0xFF, 0xC0, 0x18, 0x7E, 0x3E,
330 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
331 };
332 BYTE trueColor6x4NotInterlaced[] = {
333 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
334 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x10, 0x02, 0x00, 0x00, 0x00, 0x72, 0xF6, 0x05, 0x57,
335 /* IDAT */ 0x00, 0x00, 0x00, 0x36, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xFC, 0xFF, 0x9F, 0x81, 0x20, 0x80, 0x2A, 0x7A, 0xFE, 0xFC, 0xD9, 0xB3, 0x5F, 0xBF, 0xC0, 0x22, 0x28, 0x40, 0x52, 0x52, 0x4A, 0x8A, 0x8D, 0x8D, 0x01, 0xD9, 0xA4, 0x77, 0xEF, 0x9A, 0x9A, 0xDE, 0x01, 0x01, 0x88, 0x84, 0x88, 0x40, 0x64, 0x19, 0x11, 0x4C, 0x5C, 0x80, 0x81, 0x01, 0x00, 0x87, 0xD4, 0x19, 0x72, 0xFD, 0x0D, 0x0C, 0x10,
336 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
337 };
338 BYTE trueColor1x1WithPalette[] = {
339 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
340 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x02, 0x00, 0x00, 0x01, 0xB7, 0xE0, 0xBF, 0x0B,
341 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
342 /* IDAT */ 0x00, 0x00, 0x00, 0x0F, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xFF, 0x9F, 0x81, 0x81, 0x81, 0x01, 0x00, 0x0A, 0xFC, 0x01, 0xFF, 0xC0, 0x18, 0x7E, 0x3E,
343 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
344 };
345 BYTE trueColorWithAlpha1x1Interlaced[] = {
346 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
347 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00, 0x01, 0x38, 0x82, 0x28, 0x5C,
348 /* IDAT */ 0x00, 0x00, 0x00, 0x10, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xFF, 0x9F, 0x01, 0x08, 0xEA, 0xFF, 0x03, 0x00, 0x10, 0xF7, 0x03, 0x7D, 0xF1, 0xE9, 0x90, 0xF9,
349 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
350 };
351 BYTE trueColorWithAlpha6x4NotInterlaced[] = {
352 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
353 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x10, 0x06, 0x00, 0x00, 0x00, 0xFD, 0x94, 0x92, 0x00,
354 /* IDAT */ 0x00, 0x00, 0x00, 0x5C, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xFC, 0xFF, 0x9F, 0x01, 0x08, 0xF6, 0x83, 0x49, 0x06, 0x86, 0x03, 0x10, 0x8A, 0xE1, 0x5A, 0x18, 0x94, 0x01, 0x05, 0x5A, 0xAB, 0x20, 0xB4, 0x03, 0x03, 0x54, 0x43, 0xFD, 0xFF, 0xE7, 0xCF, 0x9F, 0x3D, 0xFB, 0xF5, 0xAB, 0x01, 0x2C, 0x8C, 0x0D, 0x48, 0x4A, 0x4A, 0x49, 0xB1, 0xB1, 0x35, 0x30, 0x30, 0x41, 0xF9, 0x0C, 0x52, 0x40, 0xC0, 0xC6, 0xC6, 0xC8, 0xC8, 0xC1, 0x31, 0x67, 0xCE, 0x97, 0x2F, 0x61, 0x61, 0x30, 0x1A, 0x26, 0x0E, 0x55, 0xC6, 0x00, 0x66, 0xFC, 0x07, 0x02, 0x30, 0x8F, 0x20, 0x60, 0x60, 0x00, 0x00, 0x6D, 0xBB, 0x1D, 0xDE, 0xBD, 0x08, 0x32, 0x2C,
355 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
356 };
357 BYTE trueColorWithAlpha1x1WithPalette[] = {
358 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
359 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x06, 0x00, 0x00, 0x01, 0x38, 0x82, 0x28, 0x5C,
360 /* PLTE */ 0x00, 0x00, 0x00, 0x18, 'P', 'L', 'T', 'E', 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE6, 0xE6, 0xFA, 0xF5, 0xF5, 0xDC, 0xFF, 0xFF, 0xFF, 0x9A, 0xCD, 0x32, 0xEE, 0x82, 0xEE, 0xBD, 0xEB, 0xF4, 0x2B,
361 /* IDAT */ 0x00, 0x00, 0x00, 0x10, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xFF, 0x9F, 0x01, 0x08, 0xEA, 0xFF, 0x03, 0x00, 0x10, 0xF7, 0x03, 0x7D, 0xF1, 0xE9, 0x90, 0xF9,
362 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
363 };
364
365 // FIXME: GDI+ converts grayscale 16bpp images to 32bpp.
366 #if defined(USE_WINDOWS_GDIPLUS)
367 PixelFormat expectedGrayscalePixelFormat = PixelFormat32bppARGB;
368 PixelFormat expectedTrueColorPixelFormat = PixelFormat32bppARGB;
369 #else
370 PixelFormat expectedGrayscalePixelFormat = PixelFormat8bppIndexed ;
371 PixelFormat expectedTrueColorPixelFormat = PixelFormat24bppRGB ;
372 #endif
373
374 createFileSuccess (grayscale1x1Interlaced, expectedGrayscalePixelFormat, 1, 1, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
375 createFileSuccess (grayscale6x4NotInterlaced, expectedGrayscalePixelFormat, 6, 4, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
376 createFileSuccess (grayscale1x1WithPalette, expectedGrayscalePixelFormat, 1, 1, ImageFlagsColorSpaceGRAY | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
377 createFileSuccess (trueColor1x1Interlaced, expectedTrueColorPixelFormat, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
378 createFileSuccess (trueColor6x4NotInterlaced, expectedTrueColorPixelFormat, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
379 createFileSuccess (trueColor1x1WithPalette, expectedTrueColorPixelFormat, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
380 createFileSuccess (trueColorWithAlpha1x1Interlaced, PixelFormat32bppARGB, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
381 createFileSuccess (trueColorWithAlpha6x4NotInterlaced, PixelFormat32bppARGB, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
382 createFileSuccess (trueColorWithAlpha1x1WithPalette, PixelFormat32bppARGB, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasAlpha | ImageFlagsReadOnly, 3);
383 }
384
test_valid()385 static void test_valid ()
386 {
387 #if defined(USE_WINDOWS_GDIPLUS)
388 BYTE longIhdrLength[] = {
389 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
390 /* IHDR */ 0x00, 0x00, 0x00, 0x0E, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
391 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
392 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
393 };
394 #endif
395 #if defined(USE_WINDOWS_GDIPLUS)
396 BYTE multipleIhdrs[] = {
397 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
398 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
399 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x69, 0xC9, 0xB2,
400 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
401 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
402 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
403 };
404 #endif
405 #if defined(USE_WINDOWS_GDIPLUS)
406 BYTE multipleIdats[] = {
407 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
408 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x69, 0xC9, 0xB2,
409 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
410 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
411 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x98, 0x63, 0x6C, 0xD7,
412 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
413 };
414 #endif
415 #if defined(USE_WINDOWS_GDIPLUS)
416 BYTE oneEmptyIdat[] = {
417 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
418 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
419 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
420 /* IDAT */ 0x00, 0x00, 0x00, 0x00, 'I', 'D', 'A', 'T', 0x00, 0x00, 0x00, 0x00,
421 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
422 };
423 #endif
424 #if defined(USE_WINDOWS_GDIPLUS)
425 BYTE multiplePalettes[] = {
426 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
427 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
428 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
429 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
430 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
431 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
432 };
433 #endif
434 BYTE noIend[] = {
435 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
436 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x69, 0xC9, 0xB2,
437 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x98, 0x63, 0x6C, 0xD7,
438 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
439 };
440 #if defined(USE_WINDOWS_GDIPLUS)
441 BYTE invalidCrc[] = {
442 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
443 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
444 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
445 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
446 };
447 #endif
448 #if defined(USE_WINDOWS_GDIPLUS)
449 BYTE invalidCompression[] = {
450 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
451 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
452 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
453 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
454 };
455 #endif
456 BYTE metersPhysicalDimensionsChunk[] = {
457 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
458 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
459 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
460 /* pHYs */ 0x00, 0x00, 0x00, 0x09, 'p', 'H', 'Y', 's', 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, 0x6F, 0xA8, 0x64,
461 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
462 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
463 };
464 BYTE zeroDpiXPhysicalDimensionsChunk[] = {
465 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
466 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
467 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
468 /* pHYs */ 0x00, 0x00, 0x00, 0x09, 'p', 'H', 'Y', 's', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, 0x6F, 0xA8, 0x64,
469 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
470 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
471 };
472 BYTE zeroDpiYPhysicalDimensionsChunk[] = {
473 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
474 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
475 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
476 /* pHYs */ 0x00, 0x00, 0x00, 0x09, 'p', 'H', 'Y', 's', 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC7, 0x6F, 0xA8, 0x64,
477 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
478 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
479 };
480 BYTE unknownPhysicalDimensionsChunk[] = {
481 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
482 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
483 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
484 /* pHYs */ 0x00, 0x00, 0x00, 0x09, 'p', 'H', 'Y', 's', 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0xC7, 0x6F, 0xA8, 0x64,
485 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
486 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
487 };
488 BYTE invalidPhysicalDimensionsChunk[] = {
489 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
490 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
491 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
492 /* pHYs */ 0x00, 0x00, 0x00, 0x09, 'p', 'H', 'Y', 's', 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x02, 0xC7, 0x6F, 0xA8, 0x64,
493 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
494 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
495 };
496 BYTE gamaChunkBeforeColors[] = {
497 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
498 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
499 /* gAMA */ 0x00, 0x00, 0x00, 0x04, 'g', 'A', 'M', 'A', 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05,
500 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
501 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
502 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
503 };
504 BYTE gamaChunkAfterColors[] = {
505 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
506 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
507 /* gAMA */ 0x00, 0x00, 0x00, 0x04, 'g', 'A', 'M', 'A', 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05,
508 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
509 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
510 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
511 };
512 BYTE srgbChunk[] = {
513 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
514 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
515 /* sRGB */ 0x00, 0x00, 0x00, 0x01, 's', 'R', 'G', 'B', 0x00, 0xAE, 0xCE, 0x1C, 0xE9,
516 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
517 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
518 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
519 };
520 #if defined(USE_WINDOWS_GDIPLUS)
521 BYTE unknownChunk[] = {
522 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
523 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
524 /* UNKNOWN */ 0x00, 0x00, 0x00, 0x02, 'U', 'N', 'K', 'N', 0xFE, 0xEF, 0xAE, 0xCE, 0x1C, 0xE9,
525 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
526 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
527 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
528 };
529 #endif
530 BYTE invalidSrgbChunk[] = {
531 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
532 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x28, 0x2D, 0x63, 0xE6,
533 /* sRGB */ 0x00, 0x00, 0x00, 0x01, 's', 'R', 'G', 'B', 0xFF, 0xAE, 0xCE, 0x1C, 0xE9,
534 /* PLTE */ 0x00, 0x00, 0x00, 0x0C, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xC1, 0x7F, 0x62, 0xD1,
535 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0xC0, 0x06, 0x18, 0x18, 0x00, 0x00, 0x17, 0x00, 0x01, 0x47, 0xB7, 0x91, 0x37,
536 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
537 };
538 #if defined(USE_WINDOWS_GDIPLUS)
539 BYTE iendWithLength[] = {
540 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
541 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x69, 0xC9, 0xB2,
542 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x98, 0x63, 0x6C, 0xD7,
543 /* IEND */ 0x00, 0x00, 0x00, 0x01, 'I', 'E', 'N', 'D', 0x00, 0xAE, 0x42, 0x60, 0x82,
544 /* sRGB */ 0x00, 0x00, 0x00, 0x01, 's', 'R', 'G', 'B', 0xFF, 0xAE, 0xCE, 0x1C, 0xE9
545 };
546 #endif
547 BYTE iendWithTrailingData[] = {
548 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
549 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x69, 0xC9, 0xB2,
550 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x98, 0x63, 0x6C, 0xD7,
551 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82,
552 /* sRGB */ 0x00, 0x00, 0x00, 0x01, 's', 'R', 'G', 'B', 0xFF, 0xAE, 0xCE, 0x1C, 0xE9
553 };
554
555 // FIXME: GDI+ allows long IHDR lengths.
556 #if defined(USE_WINDOWS_GDIPLUS)
557 createFileSuccess (longIhdrLength, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
558 #endif
559 // FIXME: GDI+ allows multiple IHDRs.
560 #if defined(USE_WINDOWS_GDIPLUS)
561 createFileSuccess (multipleIhdrs, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
562 #endif
563 //FIXME: GDI+ allows multiple IDATs.
564 #if defined(USE_WINDOWS_GDIPLUS)
565 createFileSuccess (multipleIdats, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
566 #endif
567 // FIXME: GDI+ allows empty IDATs.
568 #if defined(USE_WINDOWS_GDIPLUS)
569 createFileSuccess (oneEmptyIdat, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
570 #endif
571 // FIXME: GDI+ allows multiple palettes
572 #if defined(USE_WINDOWS_GDIPLUS)
573 createFileSuccess (multiplePalettes, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
574 #endif
575 createFileSuccess (noIend, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
576 // FIXME: GDI+ does not validate the CRC.
577 #if defined(USE_WINDOWS_GDIPLUS)
578 createFileSuccess (invalidCrc, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
579 #endif
580 // FIXME: GDI+ does not validate the compression.
581 #if defined(USE_WINDOWS_GDIPLUS)
582 createFileSuccess (invalidCompression, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
583 #endif
584 createFileSuccess (metersPhysicalDimensionsChunk, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsHasRealDPI | ImageFlagsReadOnly, 3);
585 createFileSuccess (zeroDpiXPhysicalDimensionsChunk, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
586 createFileSuccess (zeroDpiYPhysicalDimensionsChunk, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
587 createFileSuccess (unknownPhysicalDimensionsChunk, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
588 createFileSuccess (invalidPhysicalDimensionsChunk, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
589 createFileSuccess (gamaChunkBeforeColors, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 4);
590 createFileSuccess (gamaChunkAfterColors, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 4);
591 createFileSuccess (srgbChunk, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 5);
592 // FIXME: GDI+ does not validate the CRC.
593 #if defined(USE_WINDOWS_GDIPLUS)
594 createFileSuccess (unknownChunk, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
595 #endif
596 createFileSuccess (invalidSrgbChunk, PixelFormat4bppIndexed, 6, 4, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 5);
597 // FIXME: GDI+ does not validate the CRC.
598 #if defined(USE_WINDOWS_GDIPLUS)
599 createFileSuccess (iendWithLength, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
600 #endif
601 createFileSuccess (iendWithTrailingData, PixelFormat1bppIndexed, 1, 1, ImageFlagsColorSpaceRGB | ImageFlagsHasRealPixelSize | ImageFlagsReadOnly, 3);
602 }
603
test_invalidHeader()604 static void test_invalidHeader ()
605 {
606 BYTE noP[] = {0x89};
607 BYTE noN[] = {0x89, 0x50};
608 BYTE noG[] = {0x89, 0x50, 0x4E};
609 BYTE noCLRF[] = {0x89, 0x50, 0x4E, 0x47};
610 BYTE shortCLRF[] = {0x89, 0x50, 0x4E, 0x47, 0x0D};
611 BYTE noEOF[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A};
612
613 createFile (noP, OutOfMemory);
614 createFile (noN, OutOfMemory);
615 createFile (noG, OutOfMemory);
616 createFile (noCLRF, OutOfMemory);
617 createFile (shortCLRF, OutOfMemory);
618 createFile (noEOF, OutOfMemory);
619 }
620
test_invalidHeaderChunk()621 static void test_invalidHeaderChunk()
622 {
623 BYTE noDataLength[] = {
624 /*Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A
625 };
626 BYTE shortDataLength[] = {
627 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
628 /* IHDR */ 0x00, 0x00, 0x00
629 };
630 BYTE noDataType[] = {
631 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
632 /* IHDR */ 0x00, 0x00, 0x00, 0x0D
633 };
634 BYTE shortDataType[] = {
635 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
636 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D'
637 };
638 BYTE noWidth[] = {
639 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
640 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R'
641 };
642 BYTE shortWidth[] = {
643 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
644 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00
645 };
646 BYTE noHeight[] = {
647 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
648 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01
649 };
650 BYTE shortHeight[] = {
651 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
652 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
653 };
654 BYTE noBitDepth[] = {
655 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
656 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01
657 };
658 BYTE noColorType[] = {
659 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
660 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01
661 };
662 BYTE noCompression[] = {
663 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
664 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00
665 };
666 BYTE noFilter[] = {
667 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
668 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00
669 };
670 BYTE noInterlace[] = {
671 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
672 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00
673 };
674 BYTE noCrc[] = {
675 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
676 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00
677 };
678 BYTE noIDAT[] = {
679 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
680 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x37, 0x6E, 0xF9, 0x24
681 };
682
683 createFile (noDataLength, OutOfMemory);
684 createFile (shortDataLength, OutOfMemory);
685 createFile (noDataType, OutOfMemory);
686 createFile (shortDataType, OutOfMemory);
687 createFile (noWidth, OutOfMemory);
688 createFile (shortWidth, OutOfMemory);
689 createFile (noHeight, OutOfMemory);
690 createFile (shortHeight, OutOfMemory);
691 createFile (noBitDepth, OutOfMemory);
692 createFile (noColorType, OutOfMemory);
693 createFile (noCompression, OutOfMemory);
694 createFile (noFilter, OutOfMemory);
695 createFile (noInterlace, OutOfMemory);
696 createFile (noCrc, OutOfMemory);
697 createFile (noIDAT, OutOfMemory);
698 }
699
test_invalidImageData()700 static void test_invalidImageData()
701 {
702 BYTE lowerCaseHeaders[] = {
703 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
704 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'i', 'h', 'd', 'r', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
705 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'i', 'd', 'a', 't', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
706 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'i', 'e', 'n', 'd', 0x00, 0x00, 0x00, 0x00
707 };
708 BYTE shortIhdrLength[] = {
709 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
710 /* IHDR */ 0x00, 0x00, 0x00, 0x0C, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
711 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
712 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
713 };
714 BYTE prematureIend[] = {
715 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
716 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82,
717 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x69, 0xC9, 0xB2,
718 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x98, 0x63, 0x6C, 0xD7
719 };
720 BYTE idatFirst[] = {
721 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
722 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
723 /* IHDR */ 0x00, 0x00, 0x00, 0x0C, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
724 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
725 };
726 BYTE zeroWidth[] = {
727 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
728 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
729 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
730 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
731 };
732 BYTE zeroHeight[] = {
733 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
734 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
735 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
736 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
737 };
738 BYTE invalidInterlace[] = {
739 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
740 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
741 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
742 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
743 };
744
745 BYTE invalidBitDepths[] = {0x00, 0x03, 0x05, 0x06, 0x07, 0x09, 0x0F, 0x11};
746 for (int i = 0; i < sizeof (invalidBitDepths); i++)
747 {
748 BYTE invalidBitDepth[] = {
749 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
750 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, invalidBitDepths[i], 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
751 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
752 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
753 };
754 createFile (invalidBitDepth, OutOfMemory);
755 }
756
757 BYTE invalidColorTypes[] = {0x01, 0x05, 0x07};
758 for (int i = 0; i < sizeof (invalidColorTypes); i++)
759 {
760 BYTE invalidColorType[] = {
761 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
762 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, invalidColorTypes[i], 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
763 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
764 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
765 };
766 createFile (invalidColorType, OutOfMemory);
767 }
768 BYTE noIdat[] = {
769 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
770 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 0xDB, 0x56, 0xCA,
771 /* PLTE */ 0x00, 0x00, 0x00, 0x06, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xA5, 0xD9, 0x9F, 0xDD,
772 /* IEND*/ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
773 };
774 BYTE onlyEmptyIdat[] = {
775 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
776 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
777 /* IDAT */ 0x00, 0x00, 0x00, 0x00, 'I', 'D', 'A', 'T', 0x00, 0x00, 0x00, 0x00,
778 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0x00, 0x00, 0x00, 0x00
779 };
780
781 createFile (lowerCaseHeaders, OutOfMemory);
782 createFile (shortIhdrLength, OutOfMemory);
783 createFile (prematureIend, OutOfMemory);
784 createFile (idatFirst, OutOfMemory);
785 createFile (zeroWidth, OutOfMemory);
786 createFile (zeroHeight, OutOfMemory);
787 createFile (invalidInterlace, OutOfMemory);
788 createFile (noIdat, OutOfMemory);
789 createFile (onlyEmptyIdat, OutOfMemory);
790 }
791
test_invalidImageFormat()792 static void test_invalidImageFormat()
793 {
794 BYTE indexedNoPalette[] = {
795 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
796 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x25, 0xDB, 0x56, 0xCA,
797 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x68, 0x00, 0x00, 0x00, 0x82, 0x00, 0x81, 0xA7, 0x01, 0xBA, 0x10,
798 /* IEND*/ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
799 };
800 BYTE indexed16bpp[] = {
801 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
802 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x03, 0x00, 0x00, 0x00, 0x25, 0xDB, 0x56, 0xCA,
803 /* PLTE */ 0x00, 0x00, 0x00, 0x06, 'P', 'L', 'T', 'E', 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xA5, 0xD9, 0x9F, 0xDD,
804 /* IDAT */ 0x00, 0x00, 0x00, 0x0A, 'I', 'D', 'A', 'T', 0x18, 0xD3, 0x63, 0x68, 0x00, 0x00, 0x00, 0x82, 0x00, 0x81, 0xA7, 0x01, 0xBA, 0x10,
805 /* IEND*/ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
806 };
807
808 BYTE invalidBitsPerPixel[] = {0x01, 0x02, 0x04};
809 for (int i = 0; i < sizeof (invalidBitsPerPixel); i++)
810 {
811 BYTE trueColorInvalidBpp[] = {
812 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
813 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, invalidBitsPerPixel[i], 0x02, 0x00, 0x00, 0x01, 0xE7, 0x70, 0x63, 0x48,
814 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xCF, 0xC0, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x63, 0x24, 0x55, 0xD3,
815 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
816 };
817 BYTE grayscaleWithAlphaInvalidBpp[] = {
818 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
819 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, invalidBitsPerPixel[i], 0x04, 0x00, 0x00, 0x01, 0xE7, 0x70, 0x63, 0x48,
820 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xCF, 0xC0, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x63, 0x24, 0x55, 0xD3,
821 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
822 };
823 BYTE trueColorWithAlphaInvalidBpp[] = {
824 /* Signature */ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
825 /* IHDR */ 0x00, 0x00, 0x00, 0x0D, 'I', 'H', 'D', 'R', 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, invalidBitsPerPixel[i], 0x06, 0x00, 0x00, 0x01, 0xE7, 0x70, 0x63, 0x48,
826 /* IDAT */ 0x00, 0x00, 0x00, 0x0C, 'I', 'D', 'A', 'T', 0x18, 0x57, 0x63, 0xF8, 0xCF, 0xC0, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x63, 0x24, 0x55, 0xD3,
827 /* IEND */ 0x00, 0x00, 0x00, 0x00, 'I', 'E', 'N', 'D', 0xAE, 0x42, 0x60, 0x82
828 };
829
830 createFile (trueColorInvalidBpp, OutOfMemory);
831 createFile (grayscaleWithAlphaInvalidBpp, OutOfMemory);
832 createFile (trueColorWithAlphaInvalidBpp, OutOfMemory);
833 }
834
835 createFile (indexedNoPalette, OutOfMemory);
836 createFile (indexed16bpp, OutOfMemory);
837 }
838
839 int
main(int argc,char ** argv)840 main (int argc, char**argv)
841 {
842 STARTUP;
843
844 test_valid1bpp ();
845 test_valid2bpp ();
846 test_valid4bpp ();
847 test_valid8bpp ();
848 test_valid16bpp ();
849 test_valid ();
850 test_invalidHeader ();
851 test_invalidHeaderChunk ();
852 test_invalidImageData ();
853 test_invalidImageFormat ();
854
855 deleteFile (file);
856
857 SHUTDOWN;
858 return 0;
859 }
860