Imported Upstream version 1.71.0
[platform/upstream/boost.git] / libs / gil / io / test / bmp_read_test.cpp
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_TEST_MODULE bmp_read_test_module
9 #include <boost/gil.hpp>
10 #include <boost/gil/extension/io/bmp.hpp>
11
12 #include <boost/test/unit_test.hpp>
13 #include <boost/type_traits/is_same.hpp>
14
15 #include "paths.hpp"
16 #include "scanline_read_test.hpp"
17
18 using namespace std;
19 using namespace boost::gil;
20
21 using tag_t = bmp_tag;
22
23 BOOST_AUTO_TEST_SUITE( gil_io_bmp_tests )
24
25 #ifdef BOOST_GIL_IO_USE_BMP_TEST_SUITE_IMAGES
26
27 template< typename Image >
28 void write( Image&        img
29           , const string& file_name
30           )
31 {
32 #ifdef BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES
33     write_view( bmp_out + file_name
34               , view( img )
35               , tag_t()
36               );
37 #endif // BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES
38 }
39
40 BOOST_AUTO_TEST_CASE( read_header_test )
41 {
42     {
43         using backend_t = get_reader_backend<std::string const, tag_t>::type;
44
45         backend_t backend = read_image_info( bmp_filename
46                                            , tag_t()
47                                            );
48
49         BOOST_CHECK_EQUAL( backend._info._offset               ,      54u );
50         BOOST_CHECK_EQUAL( backend._info._header_size          ,      40u );
51         BOOST_CHECK_EQUAL( backend._info._width                ,     1000 );
52         BOOST_CHECK_EQUAL( backend._info._height               ,      600 );
53         BOOST_CHECK_EQUAL( backend._info._bits_per_pixel       ,       24 );
54         BOOST_CHECK_EQUAL( backend._info._compression          ,       0u );
55         BOOST_CHECK_EQUAL( backend._info._image_size           , 1800000u );
56         BOOST_CHECK_EQUAL( backend._info._horizontal_resolution,        0 );
57         BOOST_CHECK_EQUAL( backend._info._vertical_resolution  ,        0 );
58         BOOST_CHECK_EQUAL( backend._info._num_colors           ,       0u );
59         BOOST_CHECK_EQUAL( backend._info._num_important_colors ,       0u );
60         BOOST_CHECK_EQUAL( backend._info._valid                ,     true );
61     }
62 }
63
64 BOOST_AUTO_TEST_CASE( read_reference_images_test )
65 {
66     // comments are taken from http://entropymine.com/jason/bmpsuite/reference/reference.html
67
68     // g01bw.bmp - black and white palette (#000000,#FFFFFF)
69     {
70         rgba8_image_t img;
71         read_image( bmp_in + "g01bw.bmp", img, tag_t() );
72     }
73
74     // g01wb.bmp - white and black palette (#FFFFFF,#000000).
75     // Should look the same as g01bw, not inverted.
76     {
77         rgba8_image_t img;
78
79         read_image( bmp_in + "g01wb.bmp", img, tag_t() );
80         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
81         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
82
83         write( img, "g01wb.bmp" );
84     }
85
86     // g01bg.bmp - blue and green palette (#4040FF,#40FF40)
87     {
88         rgba8_image_t img;
89
90         read_image( bmp_in + "g01bg.bmp", img, tag_t() );
91         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
92         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
93
94         write( img, "g01bg.bmp" );
95     }
96
97     // g01p1.bmp - 1-color (blue) palette (#4040FF)
98     {
99         rgba8_image_t img;
100
101         read_image( bmp_in + "g01p1.bmp", img, tag_t() );
102         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
103         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
104
105         write( img, "g01p1.bmp" );
106     }
107
108     // g04.bmp - basic 4bpp (16 color) image
109     {
110         rgba8_image_t img;
111
112         read_image( bmp_in + "g04.bmp", img, tag_t() );
113         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
114         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
115
116         write( img, "g04.bmp" );
117     }
118
119     // g04rle.bmp - RLE compressed.
120     {
121         rgb8_image_t img;
122
123         read_image( bmp_in + "g04rle.bmp", img, tag_t() );
124         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
125         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
126
127         write( img, "g04rle.bmp" );
128     }
129
130     // g04p4.bmp - 4-color grayscale palette
131     {
132         rgba8_image_t img;
133
134         read_image( bmp_in + "g04p4.bmp", img, tag_t() );
135         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
136         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
137
138         write( img, "g04p4.bmp" );
139     }
140
141     // g08.bmp - basic 8bpp (256 color) image
142     {
143         rgba8_image_t img;
144
145         read_image( bmp_in + "g08.bmp", img, tag_t() );
146         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
147         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
148
149         write( img, "g08.bmp" );
150     }
151
152     // g08p256.bmp - biClrUsed=256, biClrImportant=0 [=256]
153     {
154         rgba8_image_t img;
155
156         read_image( bmp_in + "g08p256.bmp", img, tag_t() );
157         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
158         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
159
160         write( img, "g08p256.bmp" );
161     }
162
163     // g08pi256.bmp - biClrUsed=256, biClrImportant=256
164     {
165         rgba8_image_t img;
166
167         read_image( bmp_in + "g08pi256.bmp", img, tag_t() );
168         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
169         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
170
171         write( img, "g08pi256.bmp" );
172     }
173
174     // g08pi64.bmp - biClrUsed=256, biClrImportant=64. It's barely possible that some
175     // sophisticated viewers may display this image in grayscale, if there are a
176     // limited number of colors available.
177     {
178         rgba8_image_t img;
179
180         read_image( bmp_in + "g08pi64.bmp", img, tag_t() );
181         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
182         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
183
184         write( img, "g08pi64.bmp" );
185     }
186
187     // g08rle.bmp - RLE compressed.
188     {
189         rgb8_image_t img;
190
191         read_image( bmp_in + "g08rle.bmp", img, tag_t() );
192         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
193         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
194
195         write( img, "g08rle.bmp" );
196     }
197
198     // g08os2.bmp - OS/2-style bitmap. This is an obsolete variety of BMP
199     // that is still encountered sometimes. It has 3-byte palette
200     // entries (instead of 4), and 16-bit width/height fields (instead of 32).
201     {
202         rgb8_image_t img;
203
204         read_image( bmp_in + "g08os2.bmp", img, tag_t() );
205         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
206         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
207
208         write( img, "g08os2.bmp" );
209     }
210
211     // g08res22.bmp - resolution 7874x7874 pixels/meter (200x200 dpi)
212     {
213         rgba8_image_t img;
214
215         read_image( bmp_in + "g08res22.bmp", img, tag_t() );
216         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
217         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
218
219         write( img, "g08res22.bmp" );
220     }
221
222     // g08res11.bmp - resolution 3937x3937 pixels/meter (100x100 dpi)
223     {
224         rgba8_image_t img;
225
226         read_image( bmp_in + "g08res11.bmp", img, tag_t() );
227         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
228         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
229
230         write( img, "g08res11.bmp" );
231     }
232
233     // g08res21.bmp resolution 7874x3937 pixels/meter (200x100 dpi).
234     // Some programs (e.g. Imaging for Windows) may display this image
235     // stretched vertically, which is the optimal thing to do if the
236     // program is primarily a viewer, rather than an editor.
237     {
238         rgba8_image_t img;
239
240         read_image( bmp_in + "g08res21.bmp", img, tag_t() );
241         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
242         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
243
244         write( img, "g08res21.bmp" );
245     }
246
247     // g08s0.bmp - bits size not given (set to 0). This is legal for uncompressed bitmaps.
248     {
249         rgba8_image_t img;
250
251         read_image( bmp_in + "g08s0.bmp", img, tag_t() );
252         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
253         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
254
255         write( img, "g08s0.bmp" );
256     }
257
258     // g08offs.bmp - bfOffBits in header not set to the usual value.
259     // There are 100 extra unused bytes between palette and bits.
260     {
261         rgba8_image_t img;
262
263         read_image( bmp_in + "g08offs.bmp", img, tag_t() );
264         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
265         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
266
267         write( img, "g08offs.bmp" );
268     }
269
270     // g08w126.bmp - size 126x63 (right and bottom slightly clipped)
271     {
272         rgba8_image_t img;
273
274         read_image( bmp_in + "g08w126.bmp", img, tag_t() );
275         BOOST_CHECK_EQUAL( view( img ).width() , 126u );
276         BOOST_CHECK_EQUAL( view( img ).height(),  63u );
277
278         write( img, "g08w126.bmp" );
279     }
280
281     // g08w125.bmp - size 125x62
282     {
283         rgba8_image_t img;
284
285         read_image( bmp_in + "g08w125.bmp", img, tag_t() );
286         BOOST_CHECK_EQUAL( view( img ).width() , 125u );
287         BOOST_CHECK_EQUAL( view( img ).height(),  62u );
288
289         write( img, "g08w125.bmp" );
290     }
291
292     // g08w124.bmp - size 124x61
293     {
294         rgba8_image_t img;
295
296         read_image( bmp_in + "g08w124.bmp", img, tag_t() );
297         BOOST_CHECK_EQUAL( view( img ).width() , 124u );
298         BOOST_CHECK_EQUAL( view( img ).height(),  61u );
299
300         write( img, "g08w124.bmp" );
301     }
302
303     // g08p64.bmp - 64-color grayscale palette
304     {
305         rgba8_image_t img;
306
307         read_image( bmp_in + "g08p64.bmp", img, tag_t() );
308         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
309         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
310
311         write( img, "g08p64.bmp" );
312     }
313
314     // g16def555.bmp - 15-bit color (1 bit wasted), biCompression=BI_RGB (no bitfields, defaults to 5-5-5)
315     {
316         rgb8_image_t img;
317
318         read_image( bmp_in + "g16def555.bmp", img, tag_t() );
319         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
320         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
321
322         write( img, "g16def555.bmp" );
323     }
324
325     // g16bf555.bmp - 15-bit color, biCompression=BI_BITFIELDS (bitfields indicate 5-5-5)
326     {
327         rgb8_image_t img;
328
329         read_image( bmp_in + "g16bf555.bmp", img, tag_t() );
330         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
331         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
332
333         write( img, "g16bf555.bmp" );
334     }
335
336     // g16bf565.bmp - 16-bit color, biCompression=BI_BITFIELDS (bitfields indicate 5-6-5)
337     {
338         rgb8_image_t img;
339
340         read_image( bmp_in + "g16bf565.bmp", img, tag_t() );
341         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
342         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
343
344         write( img, "g16bf565.bmp" );
345     }
346
347     // g24.bmp - 24-bit color (BGR)
348     {
349         rgb8_image_t img;
350
351         read_image( bmp_in + "g24.bmp", img, tag_t() );
352         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
353         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
354
355         write( img, "g24.bmp" );
356     }
357
358     // g32def.bmp - 24-bit color (8 bits wasted), biCompression=BI_RGB (no bitfields, defaults to BGRx)
359     {
360         rgba8_image_t img;
361
362         read_image( bmp_in + "g32def.bmp", img, tag_t() );
363         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
364         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
365
366         write( img, "g32def.bmp" );
367     }
368
369     // g32bf.bmp - 24-bit color (8 bits wasted), biCompression=BI_BITFIELDS (bitfields indicate BGRx)
370     {
371         rgba8_image_t img;
372
373         read_image( bmp_in + "g32bf.bmp", img, tag_t() );
374         BOOST_CHECK_EQUAL( view( img ).width() , 127u );
375         BOOST_CHECK_EQUAL( view( img ).height(),  64u );
376
377         write( img, "g32bf.bmp" );
378     }
379 }
380
381
382 BOOST_AUTO_TEST_CASE( read_reference_images_image_iterator_test )
383 {
384     // comments are taken from http://entropymine.com/jason/bmpsuite/reference/reference.html
385
386     // g01bw.bmp - black and white palette (#000000,#FFFFFF)
387     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g01bw.bmp" ).c_str() );
388
389     // g01wb.bmp - white and black palette (#FFFFFF,#000000).
390     // Should look the same as g01bw, not inverted.
391     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g01wb.bmp" ).c_str() );
392
393     // g01bg.bmp - blue and green palette (#4040FF,#40FF40)
394     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g01bg.bmp" ).c_str() );
395
396     // g01p1.bmp - 1-color (blue) palette (#4040FF)
397     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g01p1.bmp" ).c_str() );
398
399     // g04.bmp - basic 4bpp (16 color) image
400     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g04.bmp" ).c_str() );
401
402     // not supported
403     // g04rle.bmp - RLE compressed.
404     //test_scanline_reader< bgra8_image_t, bmp_tag >( string( bmp_in + "g01bg.bmp" ).c_str() );
405
406     // g04p4.bmp - 4-color grayscale palette
407     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g04p4.bmp" ).c_str() );
408
409     // g08.bmp - basic 8bpp (256 color) image
410     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08.bmp" ).c_str() );
411
412     // g08p256.bmp - biClrUsed=256, biClrImportant=0 [=256]
413     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08p256.bmp" ).c_str() );
414
415     // g08pi256.bmp - biClrUsed=256, biClrImportant=256
416     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08pi256.bmp" ).c_str() );
417
418     // g08pi64.bmp - biClrUsed=256, biClrImportant=64. It's barely possible that some
419     // sophisticated viewers may display this image in grayscale, if there are a
420     // limited number of colors available.
421     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08pi64.bmp" ).c_str() );
422
423     // not supported
424     // g08rle.bmp - RLE compressed.
425
426     // g08os2.bmp - OS/2-style bitmap. This is an obsolete variety of BMP
427     // that is still encountered sometimes. It has 3-byte palette
428     // entries (instead of 4), and 16-bit width/height fields (instead of 32).
429     test_scanline_reader< rgb8_image_t, bmp_tag >( string( bmp_in + "g08os2.bmp" ).c_str() );
430
431     // g08res22.bmp - resolution 7874x7874 pixels/meter (200x200 dpi)
432     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08res22.bmp" ).c_str() );
433
434     // g08res11.bmp - resolution 3937x3937 pixels/meter (100x100 dpi)
435     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08res11.bmp" ).c_str() );
436
437     // g08res21.bmp resolution 7874x3937 pixels/meter (200x100 dpi).
438     // Some programs (e.g. Imaging for Windows) may display this image
439     // stretched vertically, which is the optimal thing to do if the
440     // program is primarily a viewer, rather than an editor.
441     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08res21.bmp" ).c_str() );
442
443     // g08s0.bmp - bits size not given (set to 0). This is legal for uncompressed bitmaps.
444     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08s0.bmp" ).c_str() );
445
446     // g08offs.bmp - bfOffBits in header not set to the usual value.
447     // There are 100 extra unused bytes between palette and bits.
448     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08offs.bmp" ).c_str() );
449
450     // g08w126.bmp - size 126x63 (right and bottom slightly clipped)
451     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08w126.bmp" ).c_str() );
452
453     // g08w125.bmp - size 125x62
454     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08w125.bmp" ).c_str() );
455
456     // g08w124.bmp - size 124x61
457     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08w124.bmp" ).c_str() );
458
459     // g08p64.bmp - 64-color grayscale palette
460     test_scanline_reader< rgba8_image_t, bmp_tag >( string( bmp_in + "g08p64.bmp" ).c_str() );
461
462     // g16def555.bmp - 15-bit color (1 bit wasted), biCompression=BI_RGB (no bitfields, defaults to 5-5-5)
463     test_scanline_reader< rgb8_image_t, bmp_tag >( string( bmp_in + "g16def555.bmp" ).c_str() );
464
465     // g16bf555.bmp - 15-bit color, biCompression=BI_BITFIELDS (bitfields indicate 5-5-5)
466     test_scanline_reader< rgb8_image_t, bmp_tag >( string( bmp_in + "g16bf555.bmp" ).c_str() );
467
468     // g16bf565.bmp - 16-bit color, biCompression=BI_BITFIELDS (bitfields indicate 5-6-5)
469     test_scanline_reader< rgb8_image_t, bmp_tag >( string( bmp_in + "g16bf565.bmp" ).c_str() );
470
471     // g24.bmp - 24-bit color (BGR)
472     test_scanline_reader< bgr8_image_t, bmp_tag >( string( bmp_in + "g24.bmp" ).c_str() );
473
474     // g32def.bmp - 24-bit color (8 bits wasted), biCompression=BI_RGB (no bitfields, defaults to BGRx)
475     test_scanline_reader< bgra8_image_t, bmp_tag >( string( bmp_in + "g32def.bmp" ).c_str() );
476
477     // g32bf.bmp - 24-bit color (8 bits wasted), biCompression=BI_BITFIELDS (bitfields indicate BGRx)
478     test_scanline_reader< bgra8_image_t, bmp_tag >( string( bmp_in + "g32bf.bmp" ).c_str() );
479 }
480
481 BOOST_AUTO_TEST_CASE( partial_image_test )
482 {
483     const std::string filename( bmp_in + "rgb.bmp" );
484
485     {
486         rgb8_image_t img;
487         read_image( filename
488                   , img
489                   , image_read_settings< bmp_tag >( point_t( 0, 0 ), point_t( 50, 50 ) )
490                   );
491
492 #ifdef BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES
493         write_view( bmp_out + "rgb_partial.bmp"
494                   , view( img )
495                   , tag_t()
496                   );
497 #endif // BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES
498     }
499 }
500
501 #endif // BOOST_GIL_IO_USE_BMP_TEST_SUITE_IMAGES
502
503 BOOST_AUTO_TEST_SUITE_END()