1IO extensions
2=============
3
4Overview
5--------
6
7This extension to boost::gil provides an easy to use interface for reading and
8writing various image formats. It also includes a framework for adding
9new formats.
10
11Please see section 3.3 for all supported image formats. A basic tutorial is
12provided in section [link gil.io.tutorial Tutorial].
13Also, this extension requires Boost version 1.42 and up.
14Furthermore the GIL extension Toolbox is used.
15
16For adding new image formats please refer to section
17[link gil.io.using_io.extending_gil__io_with_new_formats Extending GIL::IO with new Formats].
18
19Supported Platforms
20-------------------
21
22All platforms supported by Boost which have a decent C++ compiler.
23Depending on the image format one or more of the following image
24libraries might be needed:
25
26* libtiff
27* libjpeg
28* libpng
29* libraw
30* zlib
31
32The library is designed to support as many formats as required by the user.
33For instance, if the user only needs bmp support none of the above mentioned
34dependencies are required.
35
36There are more details available in this documentation on the image format
37dependencies. Please see section
38[link gil.io.using_io.supported_image_formats Supported Image Formats].
39
40Tutorial
41--------
42
43Thanks to modern C++ programming techniques the interface for this library
44is rather small and easy to use. In this tutorial I'll give you a short
45walk-around on how to use this boost::gil extension.
46For more details please refer to section 3.
47
48For each supported IO format a single top-level header file is provided.
49For instance, include `boost/gil/extension/io/tiff.hpp` to be able
50to read or write TIFF files.
51
52Reading An Image
53~~~~~~~~~~~~~~~~
54
55Probably the most common case to read a tiff image can be done as follows::
56
57    std::string filename( "image.tif" );
58    rgb8_image_t img;
59    read_image( filename, img, tiff_tag() );
60
61The code would be same for all other image formats. The only thing that needs
62to change is the tag type ( tiff_tag ) in the read_image call.
63The read_image() expects the supplied image type to be compatible with the
64image stored in the file. If the user doesn't know what format an image has she
65can use read_and_convert_image().
66Another important fact is that read_image() will allocate the appropriate
67memory needed for the read operation. There are ``read_view`` or
68``read_and_convert_view`` counterparts, if the memory is already allocated.
69
70Sometimes the user only wants to read a sub-part of an image,
71then the above call would look as follows::
72
73    read_image( filename
74              , img
75              , image_read_settings< tiff_tag >( point_t( 0, 0 ), point_t( 50, 50 ) )
76              );
77
78The image_read_settings class will provide the user with image format
79independent reading setting but can also serves as a pointer for format
80dependent settings.
81Please see the specific image format sections
82[link gil.io.using_io.supported_image_formats Supported Image Formats]
83for more details.
84
85Writing An Image
86~~~~~~~~~~~~~~~~
87
88Besides reading the information also writing is the second part of this
89Boost.GIL extension. Writing is a lot simpler than reading since an existing
90image view contains all the information.
91
92For instance writing an image can be done as follows::
93
94    std::string filename( "image.tif" );
95    rgb8_image_t img( 640, 480 );
96
97    // write data into image
98
99    write_view( filename
100              , view( img )
101              , tiff_tag()
102              );
103
104
105The interface is similar to reading an image. To add image format specific
106parameter the user can use ``image_write_info`` class.
107For instance, a user can specify the JPEG quality when writing like this::
108
109    std::string filename( "image.jpg" );
110    rgb8_image_t img( 640, 480 );
111
112    // write data into image
113
114    write_view( filename
115              , view( img )
116              , image_write_info< jpeg_tag >( 95 )
117              );
118
119
120The above example will write an image where the jpeg quality is
121set to 95 percent.
122
123Reading And Writing In-Memory Buffers
124~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
125
126Reading and writing in-memory buffers are supported as well. See as follows::
127
128    // 1. Read an image.
129    ifstream in( "test.tif", ios::binary );
130
131    rgb8_image_t img;
132    read_image( in, img, tiff_tag() );
133
134    // 2. Write image to in-memory buffer.
135    stringstream out_buffer( ios_base::out | ios_base::binary );
136
137    rgb8_image_t src;
138    write_view( out_buffer, view( src ), tiff_tag() );
139
140    // 3. Copy in-memory buffer to another.
141    stringstream in_buffer( ios_base::in | ios_base::binary );
142    in_buffer << out_buffer.rdbuf();
143
144    // 4. Read in-memory buffer to gil image
145    rgb8_image_t dst;
146    read_image( in_buffer, dst, tag_t() );
147
148    // 5. Write out image.
149    string filename( "out.tif" );
150    ofstream out( filename.c_str(), ios_base::binary );
151    write_view( out, view( dst ), tiff_tag() );
152
153In case the user is using his own stream classes he has to make sure it
154has the common interface read, write, seek, close, etc. Interface.
155
156Using IO
157--------
158
159General Overview
160~~~~~~~~~~~~~~~~
161
162The tutorial pointed out some use cases for reading and writing images in
163various image formats. This section will provide a more thorough overview.
164
165The next sections will introduce the Read and Write interface. But it might be
166worth pointing out that by using some advanced metaprogramming techniques the
167interface is rather small and hopefully easy to understand.
168
169Besides the general interface the user also has the ability to interface
170directly with the underlying image format. For that each reader or writer
171provides access to the so-called backend.
172
173For instance::
174
175    typedef get_reader_backend< const std::string
176                              , tag_t
177                              >::type backend_t;
178
179    backend_t backend = read_image_info( bmp_filename
180                                       , tag_t()
181                                       );
182
183    BOOST_CHECK_EQUAL( backend._info._width , 127 );
184    BOOST_CHECK_EQUAL( backend._info._height, 64 );
185
186Of course, the typedef can be removed when using c++11's auto feature.
187
188Read Interface
189~~~~~~~~~~~~~~
190
191As the Tutorial demonstrated there are a few ways to read images.
192Here is an enumeration of all read functions with a short description:
193
194* ``read_image`` - read into a gil image with no conversion.
195  Memory is allocated.
196* ``read_view`` - read into a gil view with no conversion.
197* ``read_and_convert_image`` - read and convert into a gil image.
198  Memory is allocated.
199* ``read_and_convert_view`` - read and convert into a gil view.
200* ``read_image_info`` - read the image header.
201
202Conversion in this context is necessary if the source (file) has an
203incompatible color space with the destination (gil image type).
204If that's the case the user has to use the xxx_and_convert_xxx variants.
205
206All functions take the filename or a device as the first parameter.
207The filename can be anything from a C-string, ``std::string``,
208``std::wstring`` and ``boost::filesystem`` path. When using the path
209object the user needs to define the ADD_FS_PATH_SUPPORT compiler symbol to
210include the boost::filesystem dependency.
211Devices could be a ``FILE*``, ``std::ifstream``, and ``TIFF*`` for TIFF images.
212
213The second parameter is either an image or view type depending on the
214``read_xxx`` function.
215The third and last parameter is either an instance of the
216``image_read_settings<FormatTag>`` or just the ``FormatTag``.
217The settings can be various depending on the format which is being read.
218But the all share settings for reading a partial image area.
219The first point describes the top left image coordinate whereas the second
220are the dimensions in x and y directions.
221
222Here an example of setting up partial read::
223
224    read_image( filename
225              , img
226              , image_read_settings< tiff_tag >( point_t( 0, 0 ), point_t( 50, 50 ) )
227              );
228
229Each format supports reading just the header information,
230using ``read_image_info``. Please refer to the format specific sections
231under 3.3. A basic example follows::
232
233    image_read_info< tiff_t > info = read_image_info( filename
234                                                    , tiff_t()
235                                                    );
236
237GIL also comes with a dynamic image extension.
238In the context of GIL.IO a user can define an ``any_image`` type based on
239several image types. The IO extension would then pick the matching image type
240to the current image file.
241The following example shows this feature::
242
243    typedef mpl::vector< gray8_image_t
244                       , gray16_image_t
245                       , rgb8_image_t
246                       , rgba_image_t
247                       > my_img_types;
248
249    any_image< my_img_types > runtime_image;
250
251    read_image( filename
252              , runtime_image
253              , tiff_tag()
254              );
255
256During the review it became clear that there is a need to read big images
257scanline by scanline. To support such use case a ``scanline_reader`` is
258implemented for all supported image formats.
259The ``scanline_read_iterators`` will then allow to traverse through the image.
260The following code sample shows the usage::
261
262    typedef tiff_tag tag_t;
263
264    typedef scanline_reader< typename get_read_device< const char*
265                                                     , tag_t
266                                                     >::type
267                            , tag_t
268                            > reader_t;
269
270    reader_t reader = make_scanline_reader( "C:/boost/libs/gil/test/extension/io/images/tiff/test.tif", tag_t() );
271
272    typedef rgba8_image_t image_t;
273
274    image_t dst( reader._info._width, reader._info._height );
275    fill_pixels( view(dst), image_t::value_type() );
276
277    typedef reader_t::iterator_t iterator_t;
278
279    iterator_t it  = reader.begin();
280    iterator_t end = reader.end();
281
282    for( int row = 0; it != end; ++it, ++row )
283    {
284        copy_pixels( interleaved_view( reader._info._width
285                                        , 1
286                                        , ( image_t::view_t::x_iterator ) *it
287                                        , reader._scanline_length
288                                        )
289                    , subimage_view( view( dst )
290                                    , 0
291                                    , row
292                                    , reader._info._width
293                                    , 1
294                                    )
295                    );
296    }
297
298There are many ways to traverse an image but for as of now only by
299scanline is supported.
300
301
302Write Interface
303~~~~~~~~~~~~~~~
304
305There is only one function for writing out images, write_view.
306Similar to reading the first parameter is either a filename or a device.
307The filename can be anything from a C-string, ``std::string``,
308``std::wstring``, and ``boost::filesystem`` path. When using the path object
309the user needs to define the ``ADD_FS_PATH_SUPPORT`` compiler symbol to
310include the ``boost::filesystem`` dependency.
311Devices could be ``FILE*``, ``std::ifstream``, and ``TIFF*`` for TIFF images.
312
313The second parameter is an view object to image being written.
314The third and last parameter is either a tag or an
315``image_write_info<FormatTag>`` object containing more settings.
316One example for instance is the JPEG quality.
317Refer to the format specific sections under 3.3. to have a list of all
318the possible settings.
319
320Writing an any_image<...> is supported. See the following example::
321
322    typedef mpl::vector< gray8_image_t
323                       , gray16_image_t
324                       , rgb8_image_t
325                       , rgba_image_t
326                       > my_img_types;
327
328
329    any_image< my_img_types > runtime_image;
330
331    // fill any_image
332
333    write_view( filename
334              , view( runtime_image )
335              , tiff_tag()
336              );
337
338Compiler Symbols
339~~~~~~~~~~~~~~~~
340
341The following table gives an overview of all supported compiler symbols
342that can be set by the user:
343
344.. comment [table Compiler Symbols
345
346======================================================== ========================================================
347   Symbol                                                   Description
348======================================================== ========================================================
349BOOST_GIL_IO_ENABLE_GRAY_ALPHA                           Enable the color space "gray_alpha".
350BOOST_GIL_IO_ADD_FS_PATH_SUPPORT                         Enable boost::filesystem 3.0 library.
351BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED                Use libpng in floating point mode. This symbol is incompatible with BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED.
352BOOST_GIL_IO_PNG_FIXED_POINT_SUPPORTED                   Use libpng in integer mode. This symbol is incompatible with BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED.
353BOOST_GIL_IO_PNG_DITHERING_SUPPORTED                     Look up "dithering" in libpng manual for explanation.
354BOOST_GIL_IO_PNG_1_4_OR_LOWER                            Allow compiling with libpng 1.4 or lower.
355BOOST_GIL_EXTENSION_IO_JPEG_C_LIB_COMPILED_AS_CPLUSPLUS  libjpeg is compiled as c++ lib.
356BOOST_GIL_EXTENSION_IO_PNG_C_LIB_COMPILED_AS_CPLUSPLUS   libpng is compiled as c++ lib.
357BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS  libtiff is compiled as c++ lib.
358BOOST_GIL_EXTENSION_IO_ZLIB_C_LIB_COMPILED_AS_CPLUSPLUS  zlib is compiled as c++ lib.
359BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES                   Allow basic test images to be read from local hard drive. The paths can be set in paths.hpp
360BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES                   Allow images to be written to the local hard drive. The paths can be set in paths.hpp
361BOOST_GIL_IO_USE_BMP_TEST_SUITE_IMAGES                   Run tests using the bmp test images suite. See _BMP_TEST_FILES
362BOOST_GIL_IO_USE_PNG_TEST_SUITE_IMAGES                   Run tests using the png test images suite. See _PNG_TEST_FILES
363BOOST_GIL_IO_USE_PNM_TEST_SUITE_IMAGES                   Run tests using the pnm test images suite. Send me an email for accessing the files.
364BOOST_GIL_IO_USE_TIFF_LIBTIFF_TEST_SUITE_IMAGES          Run tests using the targa file format test images suite. See _TIFF_LIB_TIFF_TEST_FILES
365BOOST_GIL_IO_USE_TIFF_GRAPHICSMAGICK_TEST_SUITE_IMAGES   Run tests using the targa file format test images suite. See _TIFF_GRAPHICSMAGICK_TEST_FILES
366======================================================== ========================================================
367
368Supported Image Formats
369~~~~~~~~~~~~~~~~~~~~~~~
370
371BMP
372+++
373
374For a general overview of the BMP image file format go to the
375following BMP_Wiki_.
376
377Please note, the code has not been tested on X Windows System variations
378of the BMP format which are usually referred to XBM and XPM formats.
379
380Here, only the MS Windows and OS/2 format is relevant.
381
382Currently the code is able to read and write the following image types:
383
384:Read: ``gray1_image_t``, ``gray4_image_t``, ``gray8_image_t``, ``rgb8_image_t`` and, ``rgba8_image_t``
385:Write: ``rgb8_image_t`` and, ``rgba8_image_t``
386
387The lack of having an indexed image type in gil restricts the current
388interface to only write out non-indexed images.
389This is subject to change soon.
390
391JPEG
392++++
393
394For a general overview of the JPEG image file format go to the
395following JPEG_Wiki_.
396
397This jpeg extension is based on the libjpeg library which can be
398found here, JPEG_Lib_.
399
400All versions starting from 8x are supported.
401
402The user has to make sure this library is properly installed.
403I strongly recommend the user to build the library yourself.
404It could potentially save you a lot of trouble.
405
406Currently the code is able to read and write the following image types:
407
408:Read: ``gray8_image_t``, ``rgb8_image_t``, ``cmyk8_image_t``
409:Write: ``gray8_image_t``, ``rgb8_image_t``, ``cmyk8_image_t``
410
411Reading YCbCr or YCCK images is possible but might result in inaccuracies since
412both color spaces aren't available yet for gil.
413For now these color space are read as rgb images.
414This is subject to change soon.
415
416PNG
417+++
418
419For a general overview of the PNG image file format go to the
420following PNG_Wiki_.
421
422This png extension is based on the libpng, which can be found
423here, PNG_Lib_.
424
425All versions starting from 1.5.x are supported.
426
427The user has to make sure this library is properly installed.
428I strongly recommend the user to build the library yourself.
429It could potentially save you a lot of trouble.
430
431Currently the code is able to read and write the following image types:
432
433:Read: gray1, gray2, gray4, gray8, gray16, gray_alpha_8, gray_alpha_16, rgb8, rgb16, rgba8, rgba16
434:Write: gray1, gray2, gray4, gray8, gray16, gray_alpha_8, gray_alpha_16, rgb8, rgb16, rgba8, rgba16
435
436For reading gray_alpha images the user has to compile application with ``BOOST_GIL_IO_ENABLE_GRAY_ALPHA``
437macro  defined. This color space is defined in the toolbox by using ``gray_alpha.hpp``.
438
439PNM
440+++
441
442For a general overview of the PNM image file format go to the
443following PNM_Wiki_. No external library is needed for the pnm format.
444
445The extension can read images in both flavours of the formats, ASCII and binary,
446that is types from P1 through P6; can write only binary formats.
447
448Currently the code is able to read and write the following image types:
449
450:Read: gray1, gray8, rgb8
451:Write: gray1, gray8, rgb8
452
453When reading a mono text image the data is read as a gray8 image.
454
455RAW
456+++
457
458For a general overview see RAW_Wiki_.
459
460Currently the extension is only able to read rgb8 images.
461
462TARGA
463+++++
464
465For a general overview of the BMP image file format go to the
466following TARGA_Wiki_.
467
468Currently the code is able to read and write the following image types:
469
470:Read: rgb8_image_t and rgba8_image_t
471:Write: rgb8_image_t and rgba8_image_t
472
473The lack of having an indexed image type in gil restricts the current
474interface to only write out non-indexed images.
475This is subject to change soon.
476
477TIFF
478++++
479
480For a general overview of the TIFF image file format go to the
481following TIFF_Wiki_.
482
483This tiff extension is based on the libtiff, which can be found, TIFF_Lib_.
484
485All versions starting from 3.9.x are supported.
486
487The user has to make sure this library is properly installed. I strongly
488recommend the user to build the library yourself. It could potentially
489save you a lot of trouble.
490
491TIFF images can virtually encode all kinds of channel sizes representing
492various color spaces. Even planar images are possible.
493For instance, ``rbg323`` or ``gray7``. The channels also can have specific
494formats, like integer values or floating point values.
495
496For a complete set of options please consult the following websites:
497
498* TIFF_Base_Tags_
499* TIFF_Extension_Tags_
500
501The author of this extension is not claiming all tiff formats are supported.
502This extension is likely to be a moving target adding new features with each
503new milestone. Here is an incomplete lists:
504
505* Multi-page TIFF - read only
506* Strip TIFF - read and write support
507* Tiled TIFF - read and write support with user defined tiled sizes
508* Bit images TIFF - fully supported, like ``gray1_image_t`` (minisblack)
509* Planar TIFF - fully supported
510* Floating-point TIFF - fully supported
511* Palette TIFF - supported but no indexed image type is available as of now
512
513This gil extension uses two different test image suites to test read and
514write capabilities. See ``test_image`` folder.
515It's advisable to use ImageMagick test viewer to display images.
516
517
518Extending GIL::IO with new Formats
519~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
520
521Extending the gil::io with new formats is meant to be simple and
522straightforward. Before adding I would recommend to have a look at existing
523implementations and then trying to follow a couple of guidelines:
524
525* Create the following files for your new xxx format
526    * ``xxx_read.hpp`` - Only includes read code
527    * ``xxx_write.hpp`` - Only includes write code
528    * ``xxx_all.hpp`` - includes xxx_read.hpp and xxx_write.hpp
529* Add the code to the ``boost::gil::detail`` namespace
530* Create a tag type for the new format. Like this::
531
532    struct xxx_tag : format_tag {};
533
534* Create the image_read_info for the new format. It contains all the
535  information that are necessary to read an image. It should be filled
536  and returned by the ``get_info`` member of the reader class. See below::
537
538    template<> struct image_read_info< xxx_tag > {};
539
540* Create the image_write_info for the new format. It contains all the
541  information that are necessary to write an image::
542
543    template<> struct image_write_info< xxx_tag > {};
544
545* Use the following reader skeleton as a start::
546
547    template< typename Device
548            , typename ConversionPolicy
549            >
550    class reader< Device
551                , xxx_tag
552                , ConversionPolicy
553                >
554                : public reader_base< xxx_tag
555                                    , ConversionPolicy
556                                    >
557    {
558    private:
559
560        typedef typename ConversionPolicy::color_converter_type cc_t;
561
562    public:
563
564        reader( Device& device )
565        : _io_dev( device )
566        {}
567
568        reader( Device&     device
569              , const cc_t& cc
570              )
571        : _io_dev( device )
572        , reader_base< xxx_tag
573                     , ConversionPolicy
574                     >( cc )
575        {}
576
577        image_read_info< xxx_tag > get_info()
578        {
579            // your implementation here
580        }
581
582        template< typename View >
583        void apply( const View& dst_view )
584        {
585            // your implementation here
586        }
587    };
588
589* The writer skeleton::
590
591    template< typename Device >
592    class writer< Device
593                , xxx_tag
594                >
595    {
596    public:
597
598        writer( Device & file )
599        : out(file)
600        {}
601
602        template<typename View>
603        void apply( const View& view )
604        {
605            // your implementation here
606        }
607
608        template<typename View>
609        void apply( const View&                        view
610                  , const image_write_info< xxx_tag >& info )
611        {
612            // your implementation here
613        }
614    };
615
616Running gil::io tests
617---------------------
618
619gil::io comes with a large suite of test cases which reads and writes various
620file formats. It uses some test image suites which can be found online or
621which can be demanded from me by sending me an email.
622
623There are some test images created by me in the test folder.
624To enable unit tests which make use of them set the following compiler options
625``BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES`` and
626``BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES``.
627
628The following list provides all links to the image suites the compiler symbol
629to enable the tests:
630
631:BMP:   BMP_TEST_FILES_                 -- BOOST_GIL_IO_USE_BMP_TEST_SUITE_IMAGES
632:PNG:   PNG_TEST_FILES_                 -- BOOST_GIL_IO_USE_PNG_TEST_SUITE_IMAGES
633:PNM:   request files from me           -- BOOST_GIL_IO_USE_PNM_TEST_SUITE_IMAGES
634:TIFF:  TIFF_LIB_TIFF_TEST_FILES_       -- BOOST_GIL_IO_USE_TIFF_LIBTIFF_TEST_SUITE_IMAGES
635:TIFF:  TIFF_GRAPHICSMAGICK_TEST_FILES_ -- BOOST_GIL_IO_USE_TIFF_GRAPHICSMAGICK_TEST_SUITE_IMAGES
636
637
638.. _BMP_Wiki: http://en.wikipedia.org/wiki/BMP_file_format
639.. _JPEG_Wiki: http://en.wikipedia.org/wiki/JPEG
640.. _JPEG_lib: http://www.ijg.org/
641.. _PNG_Wiki: http://en.wikipedia.org/wiki/Portable_Network_Graphics
642.. _PNG_Lib: http://libpng.org/pub/png/libpng.html
643.. _PNM_Wiki: http://en.wikipedia.org/wiki/Portable_anymap
644.. _RAW_Wiki: http://en.wikipedia.org/wiki/Raw_image_format
645.. _TARGA_Wiki: http://en.wikipedia.org/wiki/Truevision_TGA
646.. _RAW_lib: http://www.libraw.org/
647.. _RAW_Wiki: http://en.wikipedia.org/wiki/Raw_image_format
648.. _TIFF_Wiki: http://en.wikipedia.org/wiki/Tagged_Image_File_Format
649.. _TIFF_Lib: http://www.remotesensing.org/libtiff/
650.. _TIFF_Base_Tags: http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html
651.. _TIFF_Extension_Tags: http://www.awaresystems.be/imaging/tiff/tifftags/extension.html
652.. _BMP_TEST_FILES: http://entropymine.com/jason/bmpsuite/
653.. _PNG_TEST_FILES: http://www.schaik.com/pngsuite/pngsuite.html
654.. _TARGA_TEST_FILES: http://www.fileformat.info/format/tga/sample/index.htm
655.. _TIFF_LIB_TIFF_TEST_FILES: http://www.remotesensing.org/libtiff/images.html
656.. _TIFF_GRAPHICSMAGICK_TEST_FILES: ftp://ftp.graphicsmagick.org/pub/tiff-samples/tiff-sample-images-be.tar.gz
657