diff --git a/include/boost/gil/extension/io/formats/targa/read.hpp b/include/boost/gil/extension/io/formats/targa/read.hpp index e8a3f39c1..e3d9f5ff2 100644 --- a/include/boost/gil/extension/io/formats/targa/read.hpp +++ b/include/boost/gil/extension/io/formats/targa/read.hpp @@ -127,7 +127,7 @@ public: { this->_scanline_length = this->_info._width * ( this->_info._bits_per_pixel / 8 ); - if( this->_info._descriptor & 0x20 ) + if( this->_info._screen_origin_bit ) { read_data< bgr8_view_t >( flipped_up_down_view( dst_view ) ); } @@ -142,7 +142,7 @@ public: { this->_scanline_length = this->_info._width * ( this->_info._bits_per_pixel / 8 ); - if( this->_info._descriptor & 0x20 ) + if( this->_info._screen_origin_bit ) { read_data< bgra8_view_t >( flipped_up_down_view( dst_view ) ); } @@ -178,7 +178,7 @@ public: { case 24: { - if( this->_info._descriptor & 0x20 ) + if( this->_info._screen_origin_bit ) { read_rle_data< bgr8_view_t >( flipped_up_down_view( dst_view ) ); } @@ -190,7 +190,7 @@ public: } case 32: { - if( this->_info._descriptor & 0x20 ) + if( this->_info._screen_origin_bit ) { read_rle_data< bgra8_view_t >( flipped_up_down_view( dst_view ) ); } diff --git a/include/boost/gil/extension/io/formats/targa/reader_backend.hpp b/include/boost/gil/extension/io/formats/targa/reader_backend.hpp index 750bc1455..251c90d92 100644 --- a/include/boost/gil/extension/io/formats/targa/reader_backend.hpp +++ b/include/boost/gil/extension/io/formats/targa/reader_backend.hpp @@ -94,7 +94,6 @@ public: } _info._descriptor = _io_dev.read_uint8(); - targa_descriptor::type pixel_type = _info._descriptor & 0xdf; // According to TGA specs, http://www.gamers.org/dEngine/quake3/TGA.txt, // the image descriptor byte is: @@ -104,7 +103,7 @@ public: { io_error("Unsupported descriptor for targa file"); } - else if (_info._bits_per_pixel == 24 && pixel_type != 0) + else if (_info._bits_per_pixel == 24) { // Bits 3-0 - For the Targa 24, it should be 0. if ((_info._descriptor & 0x0FU) != 0) @@ -112,24 +111,23 @@ public: io_error("Unsupported descriptor for targa file"); } } - else if (_info._bits_per_pixel == 32 && pixel_type != 0) + else if (_info._bits_per_pixel == 32) { // Bits 3-0 - For Targa 32, it should be 8. if (_info._descriptor != 8 && _info._descriptor != 40) { io_error("Unsupported descriptor for targa file"); } - - if (_info._descriptor & 32) - { - _info._screen_origin_bit = true; - } } else { io_error("Unsupported descriptor for targa file"); } + if (_info._descriptor & 32) + { + _info._screen_origin_bit = true; + } _info._valid = true; } diff --git a/include/boost/gil/extension/io/formats/targa/scanline_read.hpp b/include/boost/gil/extension/io/formats/targa/scanline_read.hpp index 78426e017..014c46b2e 100644 --- a/include/boost/gil/extension/io/formats/targa/scanline_read.hpp +++ b/include/boost/gil/extension/io/formats/targa/scanline_read.hpp @@ -120,6 +120,11 @@ private: { io_error( "Non-indexed targa files containing a palette are not supported." ); } + + if( this->_info._screen_origin_bit ) + { + io_error( "scanline reader cannot read targa files which have screen origin bit set." ); + } switch( this->_info._bits_per_pixel ) { diff --git a/io/test/targa_read_test.cpp b/io/test/targa_read_test.cpp index 02dc44592..e8386432b 100644 --- a/io/test/targa_read_test.cpp +++ b/io/test/targa_read_test.cpp @@ -75,10 +75,17 @@ BOOST_AUTO_TEST_CASE( read_reference_images_test ) // 24BPP_compressed.tga { rgb8_image_t img; - read_image( targa_in + "24BPP_compressed.tga", img, tag_t() ); - BOOST_CHECK_EQUAL( view( img ).width() , 124 ); - BOOST_CHECK_EQUAL( view( img ).height(), 124 ); + + typename rgb8_image_t::x_coord_t width = view( img ).width(); + typename rgb8_image_t::y_coord_t height = view( img ).height(); + + BOOST_CHECK_EQUAL( width , 124 ); + BOOST_CHECK_EQUAL( height, 124 ); + BOOST_CHECK( view( img )(0, 0) == rgb8_pixel_t(248, 0, 248) ); + BOOST_CHECK( view( img )(width-1, 0) == rgb8_pixel_t(0, 0, 248) ); + BOOST_CHECK( view( img )(0, height-1) == rgb8_pixel_t(248, 0, 0) ); + BOOST_CHECK( view( img )(width-1, height-1) == rgb8_pixel_t(248, 0, 248) ); write( img, "24BPP_compressed_out.tga" ); } @@ -86,10 +93,17 @@ BOOST_AUTO_TEST_CASE( read_reference_images_test ) // 24BPP_uncompressed.tga { rgb8_image_t img; - read_image( targa_in + "24BPP_uncompressed.tga", img, tag_t() ); - BOOST_CHECK_EQUAL( view( img ).width() , 124 ); - BOOST_CHECK_EQUAL( view( img ).height(), 124 ); + + typename rgb8_image_t::x_coord_t width = view( img ).width(); + typename rgb8_image_t::y_coord_t height = view( img ).height(); + + BOOST_CHECK_EQUAL( width , 124 ); + BOOST_CHECK_EQUAL( height, 124 ); + BOOST_CHECK( view( img )(0, 0) == rgb8_pixel_t(248, 0, 248) ); + BOOST_CHECK( view( img )(width-1, 0) == rgb8_pixel_t(0, 0, 248) ); + BOOST_CHECK( view( img )(0, height-1) == rgb8_pixel_t(248, 0, 0) ); + BOOST_CHECK( view( img )(width-1, height-1) == rgb8_pixel_t(248, 0, 248) ); write( img, "24BPP_uncompressed_out.tga" ); @@ -99,10 +113,17 @@ BOOST_AUTO_TEST_CASE( read_reference_images_test ) // 32BPP_compressed.tga { rgba8_image_t img; - read_image( targa_in + "32BPP_compressed.tga", img, tag_t() ); - BOOST_CHECK_EQUAL( view( img ).width() , 124 ); - BOOST_CHECK_EQUAL( view( img ).height(), 124 ); + + typename rgba8_image_t::x_coord_t width = view( img ).width(); + typename rgba8_image_t::y_coord_t height = view( img ).height(); + + BOOST_CHECK_EQUAL( width , 124 ); + BOOST_CHECK_EQUAL( height, 124 ); + BOOST_CHECK( view( img )(0, 0) == rgba8_pixel_t(248, 0, 248, 255) ); + BOOST_CHECK( view( img )(width-1, 0) == rgba8_pixel_t(0, 0, 248, 255) ); + BOOST_CHECK( view( img )(0, height-1) == rgba8_pixel_t(0, 0, 0, 0) ); + BOOST_CHECK( view( img )(width-1, height-1) == rgba8_pixel_t(248, 0, 248, 255) ); write( img, "32BPP_compressed_out.tga" ); } @@ -110,15 +131,94 @@ BOOST_AUTO_TEST_CASE( read_reference_images_test ) // 32BPP_uncompressed.tga { rgba8_image_t img; - read_image( targa_in + "32BPP_uncompressed.tga", img, tag_t() ); - BOOST_CHECK_EQUAL( view( img ).width() , 124 ); - BOOST_CHECK_EQUAL( view( img ).height(), 124 ); + + typename rgba8_image_t::x_coord_t width = view( img ).width(); + typename rgba8_image_t::y_coord_t height = view( img ).height(); + + BOOST_CHECK_EQUAL( width , 124 ); + BOOST_CHECK_EQUAL( height, 124 ); + BOOST_CHECK( view( img )(0, 0) == rgba8_pixel_t(248, 0, 248, 255) ); + BOOST_CHECK( view( img )(width-1, 0) == rgba8_pixel_t(0, 0, 248, 255) ); + BOOST_CHECK( view( img )(0, height-1) == rgba8_pixel_t(0, 0, 0, 0) ); + BOOST_CHECK( view( img )(width-1, height-1) == rgba8_pixel_t(248, 0, 248, 255) ); write( img, "32BPP_uncompressed_out.tga" ); test_targa_scanline_reader< bgra8_image_t >( "32BPP_uncompressed.tga" ); } + + // 24BPP_compressed_ul_origin.tga + { + rgb8_image_t img; + read_image( targa_in + "24BPP_compressed_ul_origin.tga", img, tag_t() ); + + typename rgb8_image_t::x_coord_t width = view( img ).width(); + typename rgb8_image_t::y_coord_t height = view( img ).height(); + + BOOST_CHECK_EQUAL( width , 124 ); + BOOST_CHECK_EQUAL( height, 124 ); + BOOST_CHECK( view( img )(0, 0) == rgb8_pixel_t(248, 0, 248) ); + BOOST_CHECK( view( img )(width-1, 0) == rgb8_pixel_t(0, 0, 248) ); + BOOST_CHECK( view( img )(0, height-1) == rgb8_pixel_t(248, 0, 0) ); + BOOST_CHECK( view( img )(width-1, height-1) == rgb8_pixel_t(248, 0, 248) ); + + write( img, "24BPP_compressed_ul_origin_out.tga" ); + } + + // 24BPP_uncompressed_ul_origin.tga + { + rgb8_image_t img; + read_image( targa_in + "24BPP_uncompressed_ul_origin.tga", img, tag_t() ); + + typename rgb8_image_t::x_coord_t width = view( img ).width(); + typename rgb8_image_t::y_coord_t height = view( img ).height(); + + BOOST_CHECK_EQUAL( width , 124 ); + BOOST_CHECK_EQUAL( height, 124 ); + BOOST_CHECK( view( img )(0, 0) == rgb8_pixel_t(248, 0, 248) ); + BOOST_CHECK( view( img )(width-1, 0) == rgb8_pixel_t(0, 0, 248) ); + BOOST_CHECK( view( img )(0, height-1) == rgb8_pixel_t(248, 0, 0) ); + BOOST_CHECK( view( img )(width-1, height-1) == rgb8_pixel_t(248, 0, 248) ); + + write( img, "24BPP_uncompressed_ul_origin_out.tga" ); + } + + // 32BPP_compressed_ul_origin.tga + { + rgba8_image_t img; + read_image( targa_in + "32BPP_compressed_ul_origin.tga", img, tag_t() ); + + typename rgba8_image_t::x_coord_t width = view( img ).width(); + typename rgba8_image_t::y_coord_t height = view( img ).height(); + + BOOST_CHECK_EQUAL( width , 124 ); + BOOST_CHECK_EQUAL( height, 124 ); + BOOST_CHECK( view( img )(0, 0) == rgba8_pixel_t(248, 0, 248, 255) ); + BOOST_CHECK( view( img )(width-1, 0) == rgba8_pixel_t(0, 0, 248, 255) ); + BOOST_CHECK( view( img )(0, height-1) == rgba8_pixel_t(0, 0, 0, 0) ); + BOOST_CHECK( view( img )(width-1, height-1) == rgba8_pixel_t(248, 0, 248, 255) ); + + write( img, "32BPP_compressed_ul_origin_out.tga" ); + } + + // 32BPP_uncompressed_ul_origin.tga + { + rgba8_image_t img; + read_image( targa_in + "32BPP_uncompressed_ul_origin.tga", img, tag_t() ); + + typename rgba8_image_t::x_coord_t width = view( img ).width(); + typename rgba8_image_t::y_coord_t height = view( img ).height(); + + BOOST_CHECK_EQUAL( width , 124 ); + BOOST_CHECK_EQUAL( height, 124 ); + BOOST_CHECK( view( img )(0, 0) == rgba8_pixel_t(248, 0, 248, 255) ); + BOOST_CHECK( view( img )(width-1, 0) == rgba8_pixel_t(0, 0, 248, 255) ); + BOOST_CHECK( view( img )(0, height-1) == rgba8_pixel_t(0, 0, 0, 0) ); + BOOST_CHECK( view( img )(width-1, height-1) == rgba8_pixel_t(248, 0, 248, 255) ); + + write( img, "32BPP_uncompressed_ul_origin_out.tga" ); + } } BOOST_AUTO_TEST_CASE( partial_image_test ) diff --git a/io/test_images/targa/24BPP_compressed_ul_origin.tga b/io/test_images/targa/24BPP_compressed_ul_origin.tga new file mode 100644 index 000000000..98988a751 Binary files /dev/null and b/io/test_images/targa/24BPP_compressed_ul_origin.tga differ diff --git a/io/test_images/targa/24BPP_uncompressed_ul_origin.tga b/io/test_images/targa/24BPP_uncompressed_ul_origin.tga new file mode 100644 index 000000000..e5cab05c0 Binary files /dev/null and b/io/test_images/targa/24BPP_uncompressed_ul_origin.tga differ diff --git a/io/test_images/targa/32BPP_compressed_ul_origin.tga b/io/test_images/targa/32BPP_compressed_ul_origin.tga new file mode 100644 index 000000000..1fa4c636e Binary files /dev/null and b/io/test_images/targa/32BPP_compressed_ul_origin.tga differ diff --git a/io/test_images/targa/32BPP_uncompressed_ul_origin.tga b/io/test_images/targa/32BPP_uncompressed_ul_origin.tga new file mode 100644 index 000000000..65e807408 Binary files /dev/null and b/io/test_images/targa/32BPP_uncompressed_ul_origin.tga differ