1 //
2 // Copyright 2013 Christian Henning
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 #define BOOST_GIL_IO_ADD_FS_PATH_SUPPORT
9 #define BOOST_GIL_IO_ENABLE_GRAY_ALPHA
10 #define BOOST_FILESYSTEM_VERSION 3
11 #include <boost/gil.hpp>
12 #include <boost/gil/extension/io/png.hpp>
13
14 #include <boost/core/lightweight_test.hpp>
15
16 #include <cstdint>
17 #include <iostream>
18 #include <sstream>
19 #include <string>
20
21 #include "paths.hpp"
22 #include "scanline_read_test.hpp"
23 #include "test_utility_output_stream.hpp"
24
25 namespace gil = boost::gil;
26 namespace fs = boost::filesystem;
27
28 using gray_alpha8_pixel_t = gil::pixel<std::uint8_t, gil::gray_alpha_layout_t>;
29 using gray_alpha8c_pixel_t = gil::pixel<std::uint8_t, gil::gray_alpha_layout_t> const;
30 using gray_alpha8_image_t= gil::image<gray_alpha8_pixel_t, false>;
31
32 using gray_alpha16_pixel_t = gil::pixel<std::uint16_t, gil::gray_alpha_layout_t>;
33 using gray_alpha16c_pixel_t = gil::pixel<std::uint16_t, gil::gray_alpha_layout_t> const;
34 using gray_alpha16_image_t = gil::image<gray_alpha16_pixel_t, false>;
35
36 template <typename Image>
test_file(std::string filename)37 void test_file(std::string filename)
38 {
39 Image src, dst;
40
41 gil::image_read_settings<gil::png_tag> settings;
42 settings._read_file_gamma = true;
43 settings._read_transparency_data = true;
44
45 using backend_t = gil::get_reader_backend<std::string const, gil::png_tag>::type;
46 backend_t backend = gil::read_image_info(png_in + filename, settings);
47
48 gil::read_image(png_in + filename, src, settings);
49
50 #ifdef BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES
51 gil::image_write_info<gil::png_tag> write_info;
52 write_info._file_gamma = backend._info._file_gamma;
53
54 gil::write_view(png_out + filename, view(src), write_info);
55 gil::read_image(png_out + filename, dst, settings);
56
57 BOOST_TEST(gil::equal_pixels(gil::const_view(src), gil::const_view(dst)));
58 #endif // BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES
59 }
60
61 template <typename Image>
test_png_scanline_reader(std::string filename)62 void test_png_scanline_reader(std::string filename)
63 {
64 test_scanline_reader<Image, gil::png_tag>(std::string(png_in + filename).c_str());
65 }
66
67 #ifdef BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES
test_read_header()68 void test_read_header()
69 {
70 using backend_t = gil::get_reader_backend<std::string const, gil::png_tag>::type;
71 backend_t backend = gil::read_image_info(png_filename, gil::png_tag());
72
73 BOOST_TEST_EQ(backend._info._width, 1000u);
74 BOOST_TEST_EQ(backend._info._height, 600u);
75
76 BOOST_TEST_EQ(backend._info._num_channels, 4);
77 BOOST_TEST_EQ(backend._info._bit_depth, 8);
78 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_RGBA);
79
80 BOOST_TEST_EQ(backend._info._interlace_method, PNG_INTERLACE_NONE);
81 BOOST_TEST_EQ(backend._info._compression_method, PNG_COMPRESSION_TYPE_BASE);
82 BOOST_TEST_EQ(backend._info._filter_method, PNG_FILTER_TYPE_BASE);
83
84 BOOST_TEST_EQ(backend._info._file_gamma, 1);
85 }
86
test_read_pixel_per_meter()87 void test_read_pixel_per_meter()
88 {
89 gil::image_read_settings<gil::png_tag> settings;
90 settings.set_read_members_true();
91
92 using backend_t = gil::get_reader_backend<std::string const, gil::png_tag>::type;
93 backend_t backend = gil::read_image_info(png_base_in + "EddDawson/36dpi.png", settings);
94
95 BOOST_TEST_EQ(backend._info._pixels_per_meter, png_uint_32(1417));
96 }
97
test_read_with_trns_chunk_color_type_0()98 void test_read_with_trns_chunk_color_type_0()
99 {
100 // PNG 1.2: For color type 0 (grayscale), the tRNS chunk contains a single gray level value,
101 // stored in the format:
102 //
103 // Gray: 2 bytes, range 0 .. (2^bitdepth)-1
104 {
105 auto const png_path = png_in + "tbbn0g04.png";
106 gil::image_read_settings<gil::png_tag> settings;
107 settings.set_read_members_true();
108 auto backend = gil::read_image_info(png_path, settings);
109 BOOST_TEST_EQ(backend._info._width, 32u);
110 BOOST_TEST_EQ(backend._info._height, 32u);
111 BOOST_TEST_EQ(backend._info._bit_depth, 4);
112 BOOST_TEST_EQ(backend._info._num_channels, 1u);
113 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_GRAY);
114
115 gray_alpha8_image_t img;
116 read_image(png_path, img, settings);
117 BOOST_TEST_EQ(backend._info._width, 32u);
118 BOOST_TEST_EQ(backend._info._height, 32u);
119 BOOST_TEST_EQ(const_view(img).front(), gray_alpha8c_pixel_t(255, 0));
120 BOOST_TEST_EQ(const_view(img)[78], gray_alpha8c_pixel_t(221, 255));
121 BOOST_TEST_EQ(const_view(img)[79], gray_alpha8c_pixel_t(204, 255));
122 BOOST_TEST_EQ(const_view(img)[975], gray_alpha8c_pixel_t(238, 255));
123 BOOST_TEST_EQ(const_view(img)[976], gray_alpha8c_pixel_t(221, 255));
124 BOOST_TEST_EQ(const_view(img).back(), gray_alpha8c_pixel_t(255, 0));
125 }
126 {
127 auto const png_path = png_in + "tbwn0g16.png";
128 gil::image_read_settings<gil::png_tag> settings;
129 settings.set_read_members_true();
130 auto backend = gil::read_image_info(png_path, settings);
131 BOOST_TEST_EQ(backend._info._width, 32u);
132 BOOST_TEST_EQ(backend._info._height, 32u);
133 BOOST_TEST_EQ(backend._info._bit_depth, 16);
134 BOOST_TEST_EQ(backend._info._num_channels, 1u);
135 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_GRAY);
136
137 gray_alpha16_image_t img;
138 read_image(png_path, img, settings);
139 BOOST_TEST_EQ(backend._info._width, 32u);
140 BOOST_TEST_EQ(backend._info._height, 32u);
141 BOOST_TEST_EQ(const_view(img).front(), gray_alpha16c_pixel_t(65535, 0));
142 BOOST_TEST_EQ(const_view(img)[78], gray_alpha16c_pixel_t(58339, 65535));
143 BOOST_TEST_EQ(const_view(img)[79], gray_alpha16c_pixel_t(51657, 65535));
144 BOOST_TEST_EQ(const_view(img)[975], gray_alpha16c_pixel_t(62965, 65535));
145 BOOST_TEST_EQ(const_view(img)[976], gray_alpha16c_pixel_t(58339, 65535));
146 BOOST_TEST_EQ(const_view(img).back(), gray_alpha16c_pixel_t(65535, 0));
147 }
148 }
149
test_read_with_trns_chunk_color_type_2()150 void test_read_with_trns_chunk_color_type_2()
151 {
152 // PNG 1.2: For color type 2 (truecolor), the tRNS chunk contains a single RGB color value,
153 // stored in the format:
154 //
155 // Red: 2 bytes, range 0 .. (2^bitdepth)-1
156 // Green: 2 bytes, range 0 .. (2^bitdepth)-1
157 // Blue: 2 bytes, range 0 .. (2^bitdepth)-1
158 {
159 auto const png_path = png_in + "tbbn2c16.png";
160 gil::image_read_settings<gil::png_tag> settings;
161 settings.set_read_members_true();
162 auto backend = gil::read_image_info(png_path, settings);
163 BOOST_TEST_EQ(backend._info._width, 32u);
164 BOOST_TEST_EQ(backend._info._height, 32u);
165 BOOST_TEST_EQ(backend._info._bit_depth, 16);
166 BOOST_TEST_EQ(backend._info._num_channels, 3u);
167 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_RGB);
168
169 gil::rgba16_image_t img;
170 read_image(png_path, img, settings);
171 BOOST_TEST_EQ(backend._info._width, 32u);
172 BOOST_TEST_EQ(backend._info._height, 32u);
173 BOOST_TEST_EQ(const_view(img).front(), gil::rgba16c_pixel_t(65535, 65535, 65535, 0));
174 BOOST_TEST_EQ(const_view(img)[78], gil::rgba16c_pixel_t(58339, 58339, 58339, 65535));
175 BOOST_TEST_EQ(const_view(img)[79], gil::rgba16c_pixel_t(51657, 51657, 51657, 65535));
176 BOOST_TEST_EQ(const_view(img)[975], gil::rgba16c_pixel_t(62965, 62965, 62965, 65535));
177 BOOST_TEST_EQ(const_view(img)[976], gil::rgba16c_pixel_t(58339, 58339, 58339, 65535));
178 BOOST_TEST_EQ(const_view(img).back(), gil::rgba16c_pixel_t(65535, 65535, 65535, 0));
179 }
180 {
181 auto const png_path = png_in + "tbgn2c16.png";
182 gil::image_read_settings<gil::png_tag> settings;
183 settings.set_read_members_true();
184 auto backend = gil::read_image_info(png_path, settings);
185 BOOST_TEST_EQ(backend._info._width, 32u);
186 BOOST_TEST_EQ(backend._info._height, 32u);
187 BOOST_TEST_EQ(backend._info._bit_depth, 16);
188 BOOST_TEST_EQ(backend._info._num_channels, 3u);
189 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_RGB);
190
191 gil::rgba16_image_t img;
192 read_image(png_path, img, settings);
193 BOOST_TEST_EQ(backend._info._width, 32u);
194 BOOST_TEST_EQ(backend._info._height, 32u);
195 BOOST_TEST_EQ(const_view(img).front(), gil::rgba16c_pixel_t(65535, 65535, 65535, 0));
196 BOOST_TEST_EQ(const_view(img)[78], gil::rgba16c_pixel_t(58339, 58339, 58339, 65535));
197 BOOST_TEST_EQ(const_view(img)[79], gil::rgba16c_pixel_t(51657, 51657, 51657, 65535));
198 BOOST_TEST_EQ(const_view(img)[975], gil::rgba16c_pixel_t(62965, 62965, 62965, 65535));
199 BOOST_TEST_EQ(const_view(img)[976], gil::rgba16c_pixel_t(58339, 58339, 58339, 65535));
200 BOOST_TEST_EQ(const_view(img).back(), gil::rgba16c_pixel_t(65535, 65535, 65535, 0));
201 }
202 {
203 auto const png_path = png_in + "tbrn2c08.png";
204 gil::image_read_settings<gil::png_tag> settings;
205 settings.set_read_members_true();
206 auto backend = gil::read_image_info(png_path, settings);
207 BOOST_TEST_EQ(backend._info._width, 32u);
208 BOOST_TEST_EQ(backend._info._height, 32u);
209 BOOST_TEST_EQ(backend._info._bit_depth, 8);
210 BOOST_TEST_EQ(backend._info._num_channels, 3u);
211 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_RGB);
212
213 gil::rgba8_image_t img;
214 read_image(png_path, img, settings);
215 BOOST_TEST_EQ(backend._info._width, 32u);
216 BOOST_TEST_EQ(backend._info._height, 32u);
217 BOOST_TEST_EQ(const_view(img).front(), gil::rgba8c_pixel_t(255, 255, 255, 0));
218 BOOST_TEST_EQ(const_view(img)[78], gil::rgba8c_pixel_t(227, 227, 227, 255));
219 BOOST_TEST_EQ(const_view(img)[79], gil::rgba8c_pixel_t(201, 201, 201, 255));
220 BOOST_TEST_EQ(const_view(img)[975], gil::rgba8c_pixel_t(245, 245, 245, 255));
221 BOOST_TEST_EQ(const_view(img)[976], gil::rgba8c_pixel_t(227, 227, 227, 255));
222 BOOST_TEST_EQ(const_view(img).back(), gil::rgba8c_pixel_t(255, 255, 255, 0));
223 }
224 }
225
test_read_with_trns_chunk_color_type_3()226 void test_read_with_trns_chunk_color_type_3()
227 {
228 // PNG 1.2: For color type 3 (indexed color), the tRNS chunk contains a series of one-byte
229 // alpha values, corresponding to entries in the PLTE chunk:
230 //
231 // Alpha for palette index 0: 1 byte
232 // Alpha for palette index 1: 1 byte
233 // ...etc...
234 {
235 auto const png_path = png_in + "tbbn3p08.png";
236 gil::image_read_settings<gil::png_tag> settings;
237 settings.set_read_members_true();
238 auto backend = gil::read_image_info(png_path, settings);
239 BOOST_TEST_EQ(backend._info._width, 32u);
240 BOOST_TEST_EQ(backend._info._height, 32u);
241 BOOST_TEST_EQ(backend._info._bit_depth, 8);
242 BOOST_TEST_EQ(backend._info._num_channels, 1u);
243 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_PALETTE);
244
245 gil::rgba8_image_t img;
246 read_image(png_path, img, settings);
247 BOOST_TEST_EQ(backend._info._width, 32u);
248 BOOST_TEST_EQ(backend._info._height, 32u);
249 BOOST_TEST_EQ(const_view(img).front(), gil::rgba8c_pixel_t(255, 255, 255, 0));
250 BOOST_TEST_EQ(const_view(img)[78], gil::rgba8c_pixel_t(227, 227, 227, 255));
251 BOOST_TEST_EQ(const_view(img)[79], gil::rgba8c_pixel_t(201, 201, 201, 255));
252 BOOST_TEST_EQ(const_view(img)[975], gil::rgba8c_pixel_t(246, 246, 246, 255));
253 BOOST_TEST_EQ(const_view(img)[976], gil::rgba8c_pixel_t(227, 227, 227, 255));
254 BOOST_TEST_EQ(const_view(img).back(), gil::rgba8c_pixel_t(255, 255, 255, 0));
255 }
256 {
257 auto const png_path = png_in + "tbgn3p08.png";
258 gil::image_read_settings<gil::png_tag> settings;
259 settings.set_read_members_true();
260 auto backend = gil::read_image_info(png_path, settings);
261 BOOST_TEST_EQ(backend._info._width, 32u);
262 BOOST_TEST_EQ(backend._info._height, 32u);
263 BOOST_TEST_EQ(backend._info._bit_depth, 8);
264 BOOST_TEST_EQ(backend._info._num_channels, 1u);
265 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_PALETTE);
266
267 gil::rgba8_image_t img;
268 read_image(png_path, img, settings);
269 BOOST_TEST_EQ(backend._info._width, 32u);
270 BOOST_TEST_EQ(backend._info._height, 32u);
271 BOOST_TEST_EQ(const_view(img).front(), gil::rgba8c_pixel_t(255, 255, 255, 0));
272 BOOST_TEST_EQ(const_view(img)[78], gil::rgba8c_pixel_t(227, 227, 227, 255));
273 BOOST_TEST_EQ(const_view(img)[79], gil::rgba8c_pixel_t(201, 201, 201, 255));
274 BOOST_TEST_EQ(const_view(img)[975], gil::rgba8c_pixel_t(246, 246, 246, 255));
275 BOOST_TEST_EQ(const_view(img)[976], gil::rgba8c_pixel_t(227, 227, 227, 255));
276 BOOST_TEST_EQ(const_view(img).back(), gil::rgba8c_pixel_t(255, 255, 255, 0));
277 }
278 {
279 auto const png_path = png_in + "tp1n3p08.png";
280 gil::image_read_settings<gil::png_tag> settings;
281 settings.set_read_members_true();
282 auto backend = gil::read_image_info(png_path, settings);
283 BOOST_TEST_EQ(backend._info._width, 32u);
284 BOOST_TEST_EQ(backend._info._height, 32u);
285 BOOST_TEST_EQ(backend._info._bit_depth, 8);
286 BOOST_TEST_EQ(backend._info._num_channels, 1u);
287 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_PALETTE);
288
289 gil::rgba8_image_t img;
290 read_image(png_path, img, settings);
291 BOOST_TEST_EQ(backend._info._width, 32u);
292 BOOST_TEST_EQ(backend._info._height, 32u);
293 BOOST_TEST_EQ(const_view(img).front(), gil::rgba8c_pixel_t(255, 255, 255, 0));
294 BOOST_TEST_EQ(const_view(img)[78], gil::rgba8c_pixel_t(227, 227, 227, 255));
295 BOOST_TEST_EQ(const_view(img)[79], gil::rgba8c_pixel_t(201, 201, 201, 255));
296 BOOST_TEST_EQ(const_view(img)[975], gil::rgba8c_pixel_t(246, 246, 246, 255));
297 BOOST_TEST_EQ(const_view(img)[976], gil::rgba8c_pixel_t(227, 227, 227, 255));
298 BOOST_TEST_EQ(const_view(img).back(), gil::rgba8c_pixel_t(255, 255, 255, 0));
299 }
300 {
301 auto const png_path = png_in + "tm3n3p02.png";
302 gil::image_read_settings<gil::png_tag> settings;
303 settings.set_read_members_true();
304 auto backend = gil::read_image_info(png_path, settings);
305 BOOST_TEST_EQ(backend._info._width, 32u);
306 BOOST_TEST_EQ(backend._info._height, 32u);
307 BOOST_TEST_EQ(backend._info._bit_depth, 2);
308 BOOST_TEST_EQ(backend._info._num_channels, 1u);
309 BOOST_TEST_EQ(backend._info._color_type, PNG_COLOR_TYPE_PALETTE);
310
311 gil::rgba8_image_t img;
312 read_image(png_path, img, settings);
313 BOOST_TEST_EQ(backend._info._width, 32u);
314 BOOST_TEST_EQ(backend._info._height, 32u);
315 BOOST_TEST_EQ(const_view(img).front(), gil::rgba8c_pixel_t(0, 0, 255, 0));
316 BOOST_TEST_EQ(const_view(img)[16], gil::rgba8c_pixel_t(0, 0, 255, 85));
317 BOOST_TEST_EQ(const_view(img)[511], gil::rgba8c_pixel_t(0, 0, 255, 85));
318 BOOST_TEST_EQ(const_view(img)[1007], gil::rgba8c_pixel_t(0, 0, 255, 170));
319 BOOST_TEST_EQ(const_view(img).back(), gil::rgba8c_pixel_t(0, 0, 255, 255));
320 }
321 }
322 #endif // BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES
323
324 #ifdef BOOST_GIL_IO_USE_PNG_TEST_SUITE_IMAGES
test_basic_format()325 void test_basic_format()
326 {
327 // Basic format test files (non-interlaced)
328
329 // BASN0g01 - black & white
330 test_file<gil::gray1_image_t>("BASN0G01.PNG");
331 test_png_scanline_reader<gil::gray1_image_t>("BASN0G01.PNG");
332
333 // BASN0g02 - 2 bit (4 level) grayscale
334 test_file<gil::gray2_image_t>("BASN0G02.PNG");
335 test_png_scanline_reader<gil::gray2_image_t>("BASN0G02.PNG");
336
337 // BASN0g04 - 4 bit (16 level) grayscale
338 test_file<gil::gray4_image_t>("BASN0G04.PNG");
339 test_png_scanline_reader<gil::gray4_image_t>("BASN0G04.PNG");
340
341 // BASN0g08 - 8 bit (256 level) grayscale
342 test_file<gil::gray8_image_t>("BASN0G08.PNG");
343 test_png_scanline_reader<gil::gray8_image_t>("BASN0G08.PNG");
344
345 // BASN0g16 - 16 bit (64k level) grayscale
346 test_file<gil::gray16_image_t>("BASN0G16.PNG");
347 test_png_scanline_reader<gil::gray16_image_t>("BASN0G16.PNG");
348
349 // BASN2c08 - 3x8 bits gil::rgb color
350 test_file<gil::rgb8_image_t>("BASN2C08.PNG");
351 test_png_scanline_reader<gil::rgb8_image_t>("BASN2C08.PNG");
352
353 // BASN2c16 - 3x16 bits gil::rgb color
354 test_file<gil::rgb16_image_t>("BASN2C16.PNG");
355 test_png_scanline_reader<gil::rgb16_image_t>("BASN2C16.PNG");
356
357 // BASN3p01 - 1 bit (2 color) paletted
358 test_file<gil::rgb8_image_t>("BASN3P01.PNG");
359 test_png_scanline_reader<gil::rgb8_image_t>("BASN3P01.PNG");
360
361 // BASN3p02 - 2 bit (4 color) paletted
362 test_file<gil::rgb8_image_t>("BASN3P02.PNG");
363 test_png_scanline_reader<gil::rgb8_image_t>("BASN3P02.PNG");
364
365 // BASN3p04 - 4 bit (16 color) paletted
366 test_file<gil::rgb8_image_t>("BASN3P04.PNG");
367 test_png_scanline_reader<gil::rgb8_image_t>("BASN3P04.PNG");
368
369 // BASN3p08 - 8 bit (256 color) paletted
370 test_file<gil::rgb8_image_t>("BASN3P08.PNG");
371 test_png_scanline_reader<gil::rgb8_image_t>("BASN3P08.PNG");
372
373 // BASN4a08 - 8 bit grayscale + 8 bit alpha-channel
374 test_file<gil::gray_alpha8_image_t>("BASN4A08.PNG");
375 test_png_scanline_reader<gil::gray_alpha8_image_t>("BASN4A08.PNG");
376
377 // BASN4a16 - 16 bit grayscale + 16 bit alpha-channel
378 test_file<gil::gray_alpha16_image_t>("BASN4A16.PNG");
379 test_png_scanline_reader<gil::gray_alpha16_image_t>("BASN4A16.PNG");
380
381 // BASN6a08 - 3x8 bits gil::rgb color + 8 bit alpha-channel
382 test_file<gil::rgba8_image_t>("BASN6A08.PNG");
383 test_png_scanline_reader<gil::rgba8_image_t>("BASN6A08.PNG");
384
385 // BASN6a16 - 3x16 bits gil::rgb color + 16 bit alpha-channel
386 test_file<gil::rgba16_image_t>("BASN6A16.PNG");
387 test_png_scanline_reader<gil::rgba16_image_t>("BASN6A16.PNG");
388 }
389
test_basic_format_interlaced()390 void test_basic_format_interlaced()
391 {
392 // Basic format test files (Adam-7 interlaced)
393
394 // BASI0g01 - black & white
395 test_file<gil::gray1_image_t>("BASI0G01.PNG");
396
397 // BASI0g02 - 2 bit (4 level) grayscale
398 test_file<gil::gray2_image_t>("BASI0G02.PNG");
399
400 // BASI0g04 - 4 bit (16 level) grayscale
401 test_file<gil::gray4_image_t>("BASI0G04.PNG");
402
403 // BASI0g08 - 8 bit (256 level) grayscale
404 test_file<gil::gray8_image_t>("BASI0G08.PNG");
405
406 // BASI0g16 - 16 bit (64k level) grayscale
407 test_file<gil::gray16_image_t>("BASI0G16.PNG");
408
409 // BASI2c08 - 3x8 bits gil::rgb color
410 test_file<gil::rgb8_image_t>("BASI2C08.PNG");
411
412 // BASI2c16 - 3x16 bits gil::rgb color
413 test_file<gil::rgb16_image_t>("BASI2C16.PNG");
414
415 // BASI3p01 - 1 bit (2 color) paletted
416 test_file<gil::rgb8_image_t>("BASI3P01.PNG");
417
418 // BASI3p02 - 2 bit (4 color) paletted
419 test_file<gil::rgb8_image_t>("BASI3P02.PNG");
420
421 // BASI3p04 - 4 bit (16 color) paletted
422 test_file<gil::rgb8_image_t>("BASI3P04.PNG");
423
424 // BASI3p08 - 8 bit (256 color) paletted
425 test_file<gil::rgb8_image_t>("BASI3P08.PNG");
426
427 // BASI4a08 - 8 bit grayscale + 8 bit alpha-channel
428 test_file<gil::gray_alpha8_image_t>("BASI4A08.PNG");
429
430 // BASI4a16 - 16 bit grayscale + 16 bit alpha-channel
431 test_file<gil::gray_alpha16_image_t>("BASI4A16.PNG");
432
433 // BASI6a08 - 3x8 bits gil::rgb color + 8 bit alpha-channel
434 test_file<gil::rgba8_image_t>("BASI6A08.PNG");
435
436 // BASI6a16 - 3x16 bits gil::rgb color + 16 bit alpha-channel
437 test_file<gil::rgba16_image_t>("BASI6A16.PNG");
438 }
439
test_odd_sizes()440 void test_odd_sizes()
441 {
442 // S01I3P01 - 1x1 paletted file, interlaced
443 test_file<gil::rgb8_image_t>("S01I3P01.PNG");
444
445 // S01N3P01 - 1x1 paletted file, no interlacing
446 test_file<gil::rgb8_image_t>("S01N3P01.PNG");
447 test_png_scanline_reader<gil::rgb8_image_t>("S01N3P01.PNG");
448
449 // S02I3P01 - 2x2 paletted file, interlaced
450 test_file<gil::rgb8_image_t>("S02I3P01.PNG");
451
452 // S02N3P01 - 2x2 paletted file, no interlacing
453 test_file<gil::rgb8_image_t>("S02N3P01.PNG");
454 test_png_scanline_reader<gil::rgb8_image_t>("S02N3P01.PNG");
455
456 // S03I3P01 - 3x3 paletted file, interlaced
457 test_file<gil::rgb8_image_t>("S03I3P01.PNG");
458
459 // S03N3P01 - 3x3 paletted file, no interlacing
460 test_file<gil::rgb8_image_t>("S03N3P01.PNG");
461 test_png_scanline_reader<gil::rgb8_image_t>("S03N3P01.PNG");
462
463 // S04I3P01 - 4x4 paletted file, interlaced
464 test_file<gil::rgb8_image_t>("S04I3P01.PNG");
465
466 // S04N3P01 - 4x4 paletted file, no interlacing
467 test_file<gil::rgb8_image_t>("S04N3P01.PNG");
468 test_png_scanline_reader<gil::rgb8_image_t>("S04N3P01.PNG");
469
470 // S05I3P02 - 5x5 paletted file, interlaced
471 test_file<gil::rgb8_image_t>("S05I3P02.PNG");
472
473 // S05N3P02 - 5x5 paletted file, no interlacing
474 test_file<gil::rgb8_image_t>("S05N3P02.PNG");
475 test_png_scanline_reader<gil::rgb8_image_t>("S05N3P02.PNG");
476
477 // S06I3P02 - 6x6 paletted file, interlaced
478 test_file<gil::rgb8_image_t>("S06I3P02.PNG");
479
480 // S06N3P02 - 6x6 paletted file, no interlacing
481 test_file<gil::rgb8_image_t>("S06N3P02.PNG");
482 test_png_scanline_reader<gil::rgb8_image_t>("S06N3P02.PNG");
483
484 // S07I3P02 - 7x7 paletted file, interlaced
485 test_file<gil::rgb8_image_t>("S07I3P02.PNG");
486
487 // S07N3P02 - 7x7 paletted file, no interlacing
488 test_file<gil::rgb8_image_t>("S07N3P02.PNG");
489 test_png_scanline_reader<gil::rgb8_image_t>("S07N3P02.PNG");
490
491 // S08I3P02 - 8x8 paletted file, interlaced
492 test_file<gil::rgb8_image_t>("S08I3P02.PNG");
493
494 // S08N3P02 - 8x8 paletted file, no interlacing
495 test_file<gil::rgb8_image_t>("S08N3P02.PNG");
496 test_png_scanline_reader<gil::rgb8_image_t>("S08N3P02.PNG");
497
498 // S09I3P02 - 9x9 paletted file, interlaced
499 test_file<gil::rgb8_image_t>("S09I3P02.PNG");
500
501 // S09N3P02 - 9x9 paletted file, no interlacing
502 test_file<gil::rgb8_image_t>("S09N3P02.PNG");
503 test_png_scanline_reader<gil::rgb8_image_t>("S09N3P02.PNG");
504
505 // S32I3P04 - 32x32 paletted file, interlaced
506 test_file<gil::rgb8_image_t>("S32I3P04.PNG");
507
508 // S32N3P04 - 32x32 paletted file, no interlacing
509 test_file<gil::rgb8_image_t>("S32N3P04.PNG");
510 test_png_scanline_reader<gil::rgb8_image_t>("S32N3P04.PNG");
511
512 // S33I3P04 - 33x33 paletted file, interlaced
513 test_file<gil::rgb8_image_t>("S33I3P04.PNG");
514
515 // S33N3P04 - 33x33 paletted file, no interlacing
516 test_file<gil::rgb8_image_t>("S33N3P04.PNG");
517 test_png_scanline_reader<gil::rgb8_image_t>("S33N3P04.PNG");
518
519 // S34I3P04 - 34x34 paletted file, interlaced
520 test_file<gil::rgb8_image_t>("S34I3P04.PNG");
521
522 // S34N3P04 - 34x34 paletted file, no interlacing
523 test_file<gil::rgb8_image_t>("S34N3P04.PNG");
524 test_png_scanline_reader<gil::rgb8_image_t>("S34N3P04.PNG");
525
526 // S35I3P04 - 35x35 paletted file, interlaced
527 test_file<gil::rgb8_image_t>("S35I3P04.PNG");
528
529 // S35N3P04 - 35x35 paletted file, no interlacing
530 test_file<gil::rgb8_image_t>("S35N3P04.PNG");
531 test_png_scanline_reader<gil::rgb8_image_t>("S35N3P04.PNG");
532
533 // S36I3P04 - 36x36 paletted file, interlaced
534 test_file<gil::rgb8_image_t>("S36I3P04.PNG");
535
536 // S36N3P04 - 36x36 paletted file, no interlacing
537 test_file<gil::rgb8_image_t>("S36N3P04.PNG");
538 test_png_scanline_reader<gil::rgb8_image_t>("S36N3P04.PNG");
539
540 // S37I3P04 - 37x37 paletted file, interlaced
541 test_file<gil::rgb8_image_t>("S37I3P04.PNG");
542
543 // S37N3P04 - 37x37 paletted file, no interlacing
544 test_file<gil::rgb8_image_t>("S37N3P04.PNG");
545 test_png_scanline_reader<gil::rgb8_image_t>("S37N3P04.PNG");
546
547 // S38I3P04 - 38x38 paletted file, interlaced
548 test_file<gil::rgb8_image_t>("S38I3P04.PNG");
549
550 // S38N3P04 - 38x38 paletted file, no interlacing
551 test_file<gil::rgb8_image_t>("S38N3P04.PNG");
552 test_png_scanline_reader<gil::rgb8_image_t>("S38N3P04.PNG");
553
554 // S39I3P04 - 39x39 paletted file, interlaced
555 test_file<gil::rgb8_image_t>("S39I3P04.PNG");
556
557 // S39N3P04 - 39x39 paletted file, no interlacing
558 test_file<gil::rgb8_image_t>("S39N3P04.PNG");
559 test_png_scanline_reader<gil::rgb8_image_t>("S39N3P04.PNG");
560
561 // S40I3P04 - 40x40 paletted file, interlaced
562 test_file<gil::rgb8_image_t>("S40I3P04.PNG");
563
564 // S40N3P04 - 40x40 paletted file, no interlacing
565 test_file<gil::rgb8_image_t>("S40N3P04.PNG");
566 test_png_scanline_reader<gil::rgb8_image_t>("S40N3P04.PNG");
567 }
568
test_background()569 void test_background()
570 {
571 // BGAI4A08 - 8 bit grayscale, alpha, no background chunk, interlaced
572 test_file<gil::gray_alpha8_image_t>("BGAI4A08.PNG");
573
574 // BGAI4A16 - 16 bit grayscale, alpha, no background chunk, interlaced
575 test_file<gil::gray_alpha16_image_t>("BGAI4A16.PNG");
576
577 // BGAN6A08 - 3x8 bits gil::rgb color, alpha, no background chunk
578 test_file<gil::rgba8_image_t>("BGAN6A08.PNG");
579
580 // BGAN6A16 - 3x16 bits gil::rgb color, alpha, no background chunk
581 test_file<gil::rgba16_image_t>("BGAN6A16.PNG");
582
583 // BGBN4A08 - 8 bit grayscale, alpha, black background chunk
584 test_file<gil::gray_alpha8_image_t>("BGBN4A08.PNG");
585
586 // BGGN4A16 - 16 bit grayscale, alpha, gray background chunk
587 test_file<gil::gray_alpha16_image_t>("BGGN4A16.PNG");
588
589 // BGWN6A08 - 3x8 bits gil::rgb color, alpha, white background chunk
590 test_file<gil::rgba8_image_t>("BGWN6A08.PNG");
591
592 // BGYN6A16 - 3x16 bits gil::rgb color, alpha, yellow background chunk
593 test_file<gil::rgba16_image_t>("BGYN6A16.PNG");
594 }
595
test_transparency()596 void test_transparency()
597 {
598 // TBBN1G04 - transparent, black background chunk
599 // file missing
600 //test_file<gil::gray_alpha8_image_t>("TBBN1G04.PNG" );
601
602 // TBBN2C16 - transparent, blue background chunk
603 test_file<gil::rgba16_image_t>("TBBN2C16.PNG");
604
605 // TBBN3P08 - transparent, black background chunk
606 test_file<gil::rgba8_image_t>("TBBN3P08.PNG");
607
608 // TBGN2C16 - transparent, green background chunk
609 test_file<gil::rgba16_image_t>("TBGN2C16.PNG");
610
611 // TBGN3P08 - transparent, light-gray background chunk
612 test_file<gil::rgba8_image_t>("TBGN3P08.PNG");
613
614 // TBRN2C08 - transparent, red background chunk
615 test_file<gil::rgba8_image_t>("TBRN2C08.PNG");
616
617 // TBWN1G16 - transparent, white background chunk
618 test_file<gil::gray_alpha16_image_t>("TBWN0G16.PNG");
619
620 // TBWN3P08 - transparent, white background chunk
621 test_file<gil::rgba8_image_t>("TBWN3P08.PNG");
622
623 // TBYN3P08 - transparent, yellow background chunk
624 test_file<gil::rgba8_image_t>("TBYN3P08.PNG");
625
626 // TP0N1G08 - not transparent for reference (logo on gray)
627 test_file<gil::gray8_image_t>("TP0N0G08.PNG");
628
629 // TP0N2C08 - not transparent for reference (logo on gray)
630 test_file<gil::rgb8_image_t>("TP0N2C08.PNG");
631
632 // TP0N3P08 - not transparent for reference (logo on gray)
633 test_file<gil::rgb8_image_t>("TP0N3P08.PNG");
634
635 // TP1N3P08 - transparent, but no background chunk
636 test_file<gil::rgba8_image_t>("TP1N3P08.PNG");
637 }
638
test_gamma()639 void test_gamma()
640 {
641 // G03N0G16 - grayscale, file-gamma = 0.35
642 test_file<gil::gray16_image_t>("G03N0G16.PNG");
643
644 // G03N2C08 - color, file-gamma = 0.35
645 test_file<gil::rgb8_image_t>("G03N2C08.PNG");
646
647 // G03N3P04 - paletted, file-gamma = 0.35
648 test_file<gil::rgb8_image_t>("G03N3P04.PNG");
649
650 // G04N0G16 - grayscale, file-gamma = 0.45
651 test_file<gil::gray16_image_t>("G04N0G16.PNG");
652
653 // G04N2C08 - color, file-gamma = 0.45
654 test_file<gil::rgb8_image_t>("G04N2C08.PNG");
655
656 // G04N3P04 - paletted, file-gamma = 0.45
657 test_file<gil::rgb8_image_t>("G04N3P04.PNG");
658
659 // G05N0G16 - grayscale, file-gamma = 0.55
660 test_file<gil::gray16_image_t>("G05N0G16.PNG");
661
662 // G05N2C08 - color, file-gamma = 0.55
663 test_file<gil::rgb8_image_t>("G05N2C08.PNG");
664
665 // G05N3P04 - paletted, file-gamma = 0.55
666 test_file<gil::rgb8_image_t>("G05N3P04.PNG");
667
668 // G07N0G16 - grayscale, file-gamma = 0.70
669 test_file<gil::gray16_image_t>("G07N0G16.PNG");
670
671 // G07N2C08 - color, file-gamma = 0.70
672 test_file<gil::rgb8_image_t>("G07N2C08.PNG");
673
674 // G07N3P04 - paletted, file-gamma = 0.70
675 test_file<gil::rgb8_image_t>("G07N3P04.PNG");
676
677 // G10N0G16 - grayscale, file-gamma = 1.00
678 test_file<gil::gray16_image_t>("G10N0G16.PNG");
679
680 // G10N2C08 - color, file-gamma = 1.00
681 test_file<gil::rgb8_image_t>("G10N2C08.PNG");
682
683 // G10N3P04 - paletted, file-gamma = 1.00
684 test_file<gil::rgb8_image_t>("G10N3P04.PNG");
685
686 // G25N0G16 - grayscale, file-gamma = 2.50
687 test_file<gil::gray16_image_t>("G25N0G16.PNG");
688
689 // G25N2C08 - color, file-gamma = 2.50
690 test_file<gil::rgb8_image_t>("G25N2C08.PNG");
691
692 // G25N3P04 - paletted, file-gamma = 2.50
693 test_file<gil::rgb8_image_t>("G25N3P04.PNG");
694 }
695 #endif // BOOST_GIL_IO_USE_PNG_TEST_SUITE_IMAGES
696
test_corrupted_png_read()697 void test_corrupted_png_read()
698 {
699 // taken from https://github.com/boostorg/gil/issues/401#issue-518615480
700 // author: https://github.com/misos1
701
702 std::initializer_list<unsigned char> corrupt_png = {
703 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A,
704 0x00, 0x00, 0x00, 0x0D,
705 'I', 'H', 'D', 'R',
706 0x00, 0x00, 0x04, 0x00,
707 0x00, 0x00, 0x05, 0xA9,
708 0x08, 0x02, 0x00, 0x00, 0x00,
709 0x68, 0x1B, 0xF7, 0x46,
710 0x00, 0x00, 0x00, 0x00,
711 'I', 'D', 'A', 'T',
712 0x35, 0xAF, 0x06, 0x1E,
713 0x00, 0x00, 0x00, 0x00,
714 'I', 'E', 'N', 'D',
715 0xAE, 0x42, 0x60, 0x82
716 };
717
718 std::stringstream ss(
719 std::string(corrupt_png.begin(), corrupt_png.end()),
720 std::ios_base::in | std::ios_base::binary);
721 boost::gil::rgb8_image_t img;
722
723 // TODO: Replace with BOOST_ERROR below with BOOST_TEST_THROWS
724 try
725 {
726 boost::gil::read_image(ss, img, boost::gil::png_tag{});
727 }
728 catch (std::ios_base::failure& exception)
729 {
730 // the exception message is "png is invalid: iostream error"
731 // is the error portable throughout stdlib implementations,
732 // or is it native to this one?
733 // the description passd is "png_is_invalid"
734 // the exact error message is thus not checked
735 return;
736 }
737
738 BOOST_ERROR("no exception was thrown, which is an error");
739 }
740
main()741 int main()
742 {
743 test_read_header();
744 test_corrupted_png_read();
745
746 #ifdef BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES
747 test_read_pixel_per_meter();
748 test_read_with_trns_chunk_color_type_0();
749 test_read_with_trns_chunk_color_type_2();
750 test_read_with_trns_chunk_color_type_3();
751 #endif // BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES
752
753 #ifdef BOOST_GIL_IO_USE_PNG_TEST_SUITE_IMAGES
754 test_basic_format();
755 test_basic_format_interlaced();
756 test_odd_sizes();
757 test_background();
758 test_transparency();
759 test_gamma();
760 #endif
761
762 return boost::report_errors();
763 }
764
765