1 // Copyright (C) 2008 Davis E. King (davis@dlib.net), Nils Labugt 2 // License: Boost Software License See LICENSE.txt for the full license. 3 #ifndef DLIB_PNG_IMPORT 4 #define DLIB_PNG_IMPORT 5 6 #include <memory> 7 8 #include "png_loader_abstract.h" 9 #include "image_loader.h" 10 #include "../pixel.h" 11 #include "../dir_nav.h" 12 #include "../test_for_odr_violations.h" 13 14 namespace dlib 15 { 16 17 struct LibpngData; 18 struct PngBufferReaderState; 19 struct FileInfo; 20 class png_loader : noncopyable 21 { 22 public: 23 24 png_loader( const char* filename ); 25 png_loader( const std::string& filename ); 26 png_loader( const dlib::file& f ); 27 png_loader( const unsigned char* image_buffer, size_t buffer_size ); 28 ~png_loader(); 29 30 bool is_gray() const; 31 bool is_graya() const; 32 bool is_rgb() const; 33 bool is_rgba() const; 34 bit_depth()35 unsigned int bit_depth () const { return bit_depth_; } 36 37 template<typename T> get_image(T & t_)38 void get_image( T& t_) const 39 { 40 #ifndef DLIB_PNG_SUPPORT 41 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 42 You are getting this error because you are trying to use the png_loader 43 object but you haven't defined DLIB_PNG_SUPPORT. You must do so to use 44 this object. You must also make sure you set your build environment 45 to link against the libpng library. 46 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 47 COMPILE_TIME_ASSERT(sizeof(T) == 0); 48 #endif 49 50 typedef typename image_traits<T>::pixel_type pixel_type; 51 image_view<T> t(t_); 52 t.set_size( height_, width_ ); 53 54 55 if (is_gray() && bit_depth_ == 8) 56 { 57 for ( unsigned n = 0; n < height_;n++ ) 58 { 59 const unsigned char* v = get_row( n ); 60 for ( unsigned m = 0; m < width_;m++ ) 61 { 62 unsigned char p = v[m]; 63 assign_pixel( t[n][m], p ); 64 } 65 } 66 } 67 else if (is_gray() && bit_depth_ == 16) 68 { 69 for ( unsigned n = 0; n < height_;n++ ) 70 { 71 const uint16* v = (uint16*)get_row( n ); 72 for ( unsigned m = 0; m < width_;m++ ) 73 { 74 dlib::uint16 p = v[m]; 75 assign_pixel( t[n][m], p ); 76 } 77 } 78 } 79 else if (is_graya() && bit_depth_ == 8) 80 { 81 for ( unsigned n = 0; n < height_;n++ ) 82 { 83 const unsigned char* v = get_row( n ); 84 for ( unsigned m = 0; m < width_; m++ ) 85 { 86 unsigned char p = v[m*2]; 87 if (!pixel_traits<pixel_type>::has_alpha) 88 { 89 assign_pixel( t[n][m], p ); 90 } 91 else 92 { 93 unsigned char pa = v[m*2+1]; 94 rgb_alpha_pixel pix; 95 assign_pixel(pix, p); 96 assign_pixel(pix.alpha, pa); 97 assign_pixel(t[n][m], pix); 98 } 99 } 100 } 101 } 102 else if (is_graya() && bit_depth_ == 16) 103 { 104 for ( unsigned n = 0; n < height_;n++ ) 105 { 106 const uint16* v = (uint16*)get_row( n ); 107 for ( unsigned m = 0; m < width_; m++ ) 108 { 109 dlib::uint16 p = v[m*2]; 110 if (!pixel_traits<pixel_type>::has_alpha) 111 { 112 assign_pixel( t[n][m], p ); 113 } 114 else 115 { 116 dlib::uint16 pa = v[m*2+1]; 117 rgb_alpha_pixel pix; 118 assign_pixel(pix, p); 119 assign_pixel(pix.alpha, pa); 120 assign_pixel(t[n][m], pix); 121 } 122 } 123 } 124 } 125 else if (is_rgb() && bit_depth_ == 8) 126 { 127 for ( unsigned n = 0; n < height_;n++ ) 128 { 129 const unsigned char* v = get_row( n ); 130 for ( unsigned m = 0; m < width_;m++ ) 131 { 132 rgb_pixel p; 133 p.red = v[m*3]; 134 p.green = v[m*3+1]; 135 p.blue = v[m*3+2]; 136 assign_pixel( t[n][m], p ); 137 } 138 } 139 } 140 else if (is_rgb() && bit_depth_ == 16) 141 { 142 for ( unsigned n = 0; n < height_;n++ ) 143 { 144 const uint16* v = (uint16*)get_row( n ); 145 for ( unsigned m = 0; m < width_;m++ ) 146 { 147 rgb_pixel p; 148 p.red = static_cast<uint8>(v[m*3]); 149 p.green = static_cast<uint8>(v[m*3+1]); 150 p.blue = static_cast<uint8>(v[m*3+2]); 151 assign_pixel( t[n][m], p ); 152 } 153 } 154 } 155 else if (is_rgba() && bit_depth_ == 8) 156 { 157 if (!pixel_traits<pixel_type>::has_alpha) 158 assign_all_pixels(t,0); 159 160 for ( unsigned n = 0; n < height_;n++ ) 161 { 162 const unsigned char* v = get_row( n ); 163 for ( unsigned m = 0; m < width_;m++ ) 164 { 165 rgb_alpha_pixel p; 166 p.red = v[m*4]; 167 p.green = v[m*4+1]; 168 p.blue = v[m*4+2]; 169 p.alpha = v[m*4+3]; 170 assign_pixel( t[n][m], p ); 171 } 172 } 173 } 174 else if (is_rgba() && bit_depth_ == 16) 175 { 176 if (!pixel_traits<pixel_type>::has_alpha) 177 assign_all_pixels(t,0); 178 179 for ( unsigned n = 0; n < height_;n++ ) 180 { 181 const uint16* v = (uint16*)get_row( n ); 182 for ( unsigned m = 0; m < width_;m++ ) 183 { 184 rgb_alpha_pixel p; 185 p.red = static_cast<uint8>(v[m*4]); 186 p.green = static_cast<uint8>(v[m*4+1]); 187 p.blue = static_cast<uint8>(v[m*4+2]); 188 p.alpha = static_cast<uint8>(v[m*4+3]); 189 assign_pixel( t[n][m], p ); 190 } 191 } 192 } 193 } 194 195 private: 196 const unsigned char* get_row( unsigned i ) const; 197 std::unique_ptr<FileInfo> check_file( const char* filename ); 198 void read_image( std::unique_ptr<FileInfo> file_info ); 199 unsigned height_, width_; 200 unsigned bit_depth_; 201 int color_type_; 202 std::unique_ptr<LibpngData> ld_; 203 std::unique_ptr<PngBufferReaderState> buffer_reader_state_; 204 }; 205 206 // ---------------------------------------------------------------------------------------- 207 208 template < 209 typename image_type 210 > load_png(image_type & image,const std::string & file_name)211 void load_png ( 212 image_type& image, 213 const std::string& file_name 214 ) 215 { 216 png_loader(file_name).get_image(image); 217 } 218 219 template < 220 typename image_type 221 > load_png(image_type & image,const unsigned char * image_buffer,size_t buffer_size)222 void load_png ( 223 image_type& image, 224 const unsigned char* image_buffer, 225 size_t buffer_size 226 ) 227 { 228 png_loader(image_buffer, buffer_size).get_image(image); 229 } 230 231 template < 232 typename image_type 233 > load_png(image_type & image,const char * image_buffer,size_t buffer_size)234 void load_png ( 235 image_type& image, 236 const char* image_buffer, 237 size_t buffer_size 238 ) 239 { 240 png_loader(reinterpret_cast<const unsigned char*>(image_buffer), buffer_size).get_image(image); 241 } 242 243 244 // ---------------------------------------------------------------------------------------- 245 246 } 247 248 #ifdef NO_MAKEFILE 249 #include "png_loader.cpp" 250 #endif 251 252 #endif // DLIB_PNG_IMPORT 253 254