• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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