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_TARGA_FILEFORMAT_TEST_SUITE_IMAGES Run tests using the targa file format test images suite. See _TARGA_TEST_FILES 365BOOST_GIL_IO_USE_TIFF_LIBTIFF_TEST_SUITE_IMAGES Run tests using the targa file format test images suite. See _TIFF_LIB_TIFF_TEST_FILES 366BOOST_GIL_IO_USE_TIFF_GRAPHICSMAGICK_TEST_SUITE_IMAGES Run tests using the targa file format test images suite. See _TIFF_GRAPHICSMAGICK_TEST_FILES 367======================================================== ======================================================== 368 369Supported Image Formats 370~~~~~~~~~~~~~~~~~~~~~~~ 371 372BMP 373+++ 374 375For a general overview of the BMP image file format go to the 376following BMP_Wiki_. 377 378Please note, the code has not been tested on X Windows System variations 379of the BMP format which are usually referred to XBM and XPM formats. 380 381Here, only the MS Windows and OS/2 format is relevant. 382 383Currently the code is able to read and write the following image types: 384 385:Read: ``gray1_image_t``, ``gray4_image_t``, ``gray8_image_t``, ``rgb8_image_t`` and, ``rgba8_image_t`` 386:Write: ``rgb8_image_t`` and, ``rgba8_image_t`` 387 388The lack of having an indexed image type in gil restricts the current 389interface to only write out non-indexed images. 390This is subject to change soon. 391 392JPEG 393++++ 394 395For a general overview of the JPEG image file format go to the 396following JPEG_Wiki_. 397 398This jpeg extension is based on the libjpeg library which can be 399found here, JPEG_Lib_. 400 401All versions starting from 8x are supported. 402 403The user has to make sure this library is properly installed. 404I strongly recommend the user to build the library yourself. 405It could potentially save you a lot of trouble. 406 407Currently the code is able to read and write the following image types: 408 409:Read: ``gray8_image_t``, ``rgb8_image_t``, ``cmyk8_image_t`` 410:Write: ``gray8_image_t``, ``rgb8_image_t``, ``cmyk8_image_t`` 411 412Reading YCbCr or YCCK images is possible but might result in inaccuracies since 413both color spaces aren't available yet for gil. 414For now these color space are read as rgb images. 415This is subject to change soon. 416 417PNG 418+++ 419 420For a general overview of the PNG image file format go to the 421following PNG_Wiki_. 422 423This png extension is based on the libpng, which can be found 424here, PNG_Lib_. 425 426All versions starting from 1.5.x are supported. 427 428The user has to make sure this library is properly installed. 429I strongly recommend the user to build the library yourself. 430It could potentially save you a lot of trouble. 431 432Currently the code is able to read and write the following image types: 433 434:Read: gray1, gray2, gray4, gray8, gray16, gray_alpha_8, gray_alpha_16, rgb8, rgb16, rgba8, rgba16 435:Write: gray1, gray2, gray4, gray8, gray16, gray_alpha_8, gray_alpha_16, rgb8, rgb16, rgba8, rgba16 436 437For reading gray_alpha images the user has to compile application with ``BOOST_GIL_IO_ENABLE_GRAY_ALPHA`` 438macro defined. This color space is defined in the toolbox by using ``gray_alpha.hpp``. 439 440PNM 441+++ 442 443For a general overview of the PNM image file format go to the 444following PNM_Wiki_. No external library is needed for the pnm format. 445 446The extension can read images in both flavours of the formats, ASCII and binary, 447that is types from P1 through P6; can write only binary formats. 448 449Currently the code is able to read and write the following image types: 450 451:Read: gray1, gray8, rgb8 452:Write: gray1, gray8, rgb8 453 454When reading a mono text image the data is read as a gray8 image. 455 456RAW 457+++ 458 459For a general overview see RAW_Wiki_. 460 461Currently the extension is only able to read rgb8 images. 462 463TARGA 464+++++ 465 466For a general overview of the BMP image file format go to the 467following TARGA_Wiki_. 468 469Currently the code is able to read and write the following image types: 470 471:Read: rgb8_image_t and rgba8_image_t 472:Write: rgb8_image_t and rgba8_image_t 473 474The lack of having an indexed image type in gil restricts the current 475interface to only write out non-indexed images. 476This is subject to change soon. 477 478TIFF 479++++ 480 481For a general overview of the TIFF image file format go to the 482following TIFF_Wiki_. 483 484This tiff extension is based on the libtiff, which can be found, TIFF_Lib_. 485 486All versions starting from 3.9.x are supported. 487 488The user has to make sure this library is properly installed. I strongly 489recommend the user to build the library yourself. It could potentially 490save you a lot of trouble. 491 492TIFF images can virtually encode all kinds of channel sizes representing 493various color spaces. Even planar images are possible. 494For instance, ``rbg323`` or ``gray7``. The channels also can have specific 495formats, like integer values or floating point values. 496 497For a complete set of options please consult the following websites: 498 499* TIFF_Base_Tags_ 500* TIFF_Extension_Tags_ 501 502The author of this extension is not claiming all tiff formats are supported. 503This extension is likely to be a moving target adding new features with each 504new milestone. Here is an incomplete lists: 505 506* Multi-page TIFF - read only 507* Strip TIFF - read and write support 508* Tiled TIFF - read and write support with user defined tiled sizes 509* Bit images TIFF - fully supported, like ``gray1_image_t`` (minisblack) 510* Planar TIFF - fully supported 511* Floating-point TIFF - fully supported 512* Palette TIFF - supported but no indexed image type is available as of now 513 514This gil extension uses two different test image suites to test read and 515write capabilities. See ``test_image`` folder. 516It's advisable to use ImageMagick test viewer to display images. 517 518 519Extending GIL::IO with new Formats 520~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 522Extending the gil::io with new formats is meant to be simple and 523straightforward. Before adding I would recommend to have a look at existing 524implementations and then trying to follow a couple of guidelines: 525 526* Create the following files for your new xxx format 527 * ``xxx_read.hpp`` - Only includes read code 528 * ``xxx_write.hpp`` - Only includes write code 529 * ``xxx_all.hpp`` - includes xxx_read.hpp and xxx_write.hpp 530* Add the code to the ``boost::gil::detail`` namespace 531* Create a tag type for the new format. Like this:: 532 533 struct xxx_tag : format_tag {}; 534 535* Create the image_read_info for the new format. It contains all the 536 information that are necessary to read an image. It should be filled 537 and returned by the ``get_info`` member of the reader class. See below:: 538 539 template<> struct image_read_info< xxx_tag > {}; 540 541* Create the image_write_info for the new format. It contains all the 542 information that are necessary to write an image:: 543 544 template<> struct image_write_info< xxx_tag > {}; 545 546* Use the following reader skeleton as a start:: 547 548 template< typename Device 549 , typename ConversionPolicy 550 > 551 class reader< Device 552 , xxx_tag 553 , ConversionPolicy 554 > 555 : public reader_base< xxx_tag 556 , ConversionPolicy 557 > 558 { 559 private: 560 561 typedef typename ConversionPolicy::color_converter_type cc_t; 562 563 public: 564 565 reader( Device& device ) 566 : _io_dev( device ) 567 {} 568 569 reader( Device& device 570 , const cc_t& cc 571 ) 572 : _io_dev( device ) 573 , reader_base< xxx_tag 574 , ConversionPolicy 575 >( cc ) 576 {} 577 578 image_read_info< xxx_tag > get_info() 579 { 580 // your implementation here 581 } 582 583 template< typename View > 584 void apply( const View& dst_view ) 585 { 586 // your implementation here 587 } 588 }; 589 590* The writer skeleton:: 591 592 template< typename Device > 593 class writer< Device 594 , xxx_tag 595 > 596 { 597 public: 598 599 writer( Device & file ) 600 : out(file) 601 {} 602 603 template<typename View> 604 void apply( const View& view ) 605 { 606 // your implementation here 607 } 608 609 template<typename View> 610 void apply( const View& view 611 , const image_write_info< xxx_tag >& info ) 612 { 613 // your implementation here 614 } 615 }; 616 617Running gil::io tests 618--------------------- 619 620gil::io comes with a large suite of test cases which reads and writes various 621file formats. It uses some test image suites which can be found online or 622which can be demanded from me by sending me an email. 623 624There are some test images created by me in the test folder. 625To enable unit tests which make use of them set the following compiler options 626``BOOST_GIL_IO_TEST_ALLOW_READING_IMAGES`` and 627``BOOST_GIL_IO_TEST_ALLOW_WRITING_IMAGES``. 628 629The following list provides all links to the image suites the compiler symbol 630to enable the tests: 631 632:BMP: BMP_TEST_FILES_ -- BOOST_GIL_IO_USE_BMP_TEST_SUITE_IMAGES 633:PNG: PNG_TEST_FILES_ -- BOOST_GIL_IO_USE_PNG_TEST_SUITE_IMAGES 634:PNM: request files from me -- BOOST_GIL_IO_USE_PNM_TEST_SUITE_IMAGES 635:TARGA: TARGA_TEST_FILES_ -- BOOST_GIL_IO_USE_TARGA_FILEFORMAT_TEST_SUITE_IMAGES 636:TIFF: TIFF_LIB_TIFF_TEST_FILES_ -- BOOST_GIL_IO_USE_TIFF_LIBTIFF_TEST_SUITE_IMAGES 637:TIFF: TIFF_GRAPHICSMAGICK_TEST_FILES_ -- BOOST_GIL_IO_USE_TIFF_GRAPHICSMAGICK_TEST_SUITE_IMAGES 638 639 640.. _BMP_Wiki: http://en.wikipedia.org/wiki/BMP_file_format 641.. _JPEG_Wiki: http://en.wikipedia.org/wiki/JPEG 642.. _JPEG_lib: http://www.ijg.org/ 643.. _PNG_Wiki: http://en.wikipedia.org/wiki/Portable_Network_Graphics 644.. _PNG_Lib: http://libpng.org/pub/png/libpng.html 645.. _PNM_Wiki: http://en.wikipedia.org/wiki/Portable_anymap 646.. _RAW_Wiki: http://en.wikipedia.org/wiki/Raw_image_format 647.. _TARGA_Wiki: http://en.wikipedia.org/wiki/Truevision_TGA 648.. _RAW_lib: http://www.libraw.org/ 649.. _RAW_Wiki: http://en.wikipedia.org/wiki/Raw_image_format 650.. _TIFF_Wiki: http://en.wikipedia.org/wiki/Tagged_Image_File_Format 651.. _TIFF_Lib: http://www.remotesensing.org/libtiff/ 652.. _TIFF_Base_Tags: http://www.awaresystems.be/imaging/tiff/tifftags/baseline.html 653.. _TIFF_Extension_Tags: http://www.awaresystems.be/imaging/tiff/tifftags/extension.html 654.. _BMP_TEST_FILES: http://entropymine.com/jason/bmpsuite/ 655.. _PNG_TEST_FILES: http://www.schaik.com/pngsuite/pngsuite.html 656.. _TARGA_TEST_FILES: http://www.fileformat.info/format/tga/sample/index.htm 657.. _TIFF_LIB_TIFF_TEST_FILES: http://www.remotesensing.org/libtiff/images.html 658.. _TIFF_GRAPHICSMAGICK_TEST_FILES: ftp://ftp.graphicsmagick.org/pub/tiff-samples/tiff-sample-images-be.tar.gz 659