00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef PNGPP_IO_BASE_HPP_INCLUDED
00032 #define PNGPP_IO_BASE_HPP_INCLUDED
00033
00034 #include <cassert>
00035 #include <cstdio>
00036 #include "error.hpp"
00037 #include "info.hpp"
00038 #include "end_info.hpp"
00039
00040 namespace png
00041 {
00042
00048 class io_base
00049 {
00050 io_base(io_base const&);
00051 io_base& operator=(io_base const&);
00052
00053 public:
00054 explicit io_base(png_struct* png)
00055 : m_png(png),
00056 m_info(*this, m_png),
00057 m_end_info(*this, m_png)
00058 {
00059 }
00060
00061 ~io_base()
00062 {
00063 assert(! m_png);
00064 assert(! m_info.get_png_info());
00065 assert(! m_end_info.get_png_info());
00066 }
00067
00068 png_struct* get_png_struct() const
00069 {
00070 return m_png;
00071 }
00072
00073 info& get_info()
00074 {
00075 return m_info;
00076 }
00077
00078 info const& get_info() const
00079 {
00080 return m_info;
00081 }
00082
00083 image_info const& get_image_info() const
00084 {
00085 return m_info;
00086 }
00087
00088 void set_image_info(image_info const& info)
00089 {
00090 static_cast< image_info& >(m_info) = info;
00091 }
00092
00093 end_info& get_end_info()
00094 {
00095 return m_end_info;
00096 }
00097
00098 end_info const& get_end_info() const
00099 {
00100 return m_end_info;
00101 }
00102
00104
00105
00106 size_t get_width() const
00107 {
00108 return m_info.get_width();
00109 }
00110
00111 void set_width(size_t width)
00112 {
00113 m_info.set_width(width);
00114 }
00115
00116 size_t get_height() const
00117 {
00118 return m_info.get_height();
00119 }
00120
00121 void set_height(size_t height)
00122 {
00123 m_info.set_height(height);
00124 }
00125
00126 color_type get_color_type() const
00127 {
00128 return m_info.get_color_type();
00129 }
00130
00131 void set_color_type(color_type color_space)
00132 {
00133 m_info.set_color_type(color_space);
00134 }
00135
00136 size_t get_bit_depth() const
00137 {
00138 return m_info.get_bit_depth();
00139 }
00140
00141 void set_bit_depth(size_t bit_depth)
00142 {
00143 m_info.set_bit_depth(bit_depth);
00144 }
00145
00146 interlace_type get_interlace_type() const
00147 {
00148 return m_info.get_interlace_type();
00149 }
00150
00151 void set_interlace_type(interlace_type interlace)
00152 {
00153 m_info.set_interlace_type(interlace);
00154 }
00155
00156 compression_type get_compression_type() const
00157 {
00158 return m_info.get_compression_type();
00159 }
00160
00161 void set_compression_type(compression_type compression)
00162 {
00163 m_info.set_compression_type(compression);
00164 }
00165
00166 filter_type get_filter_type() const
00167 {
00168 return m_info.get_filter_type();
00169 }
00170
00171 void set_filter_type(filter_type filter)
00172 {
00173 m_info.set_filter_type(filter);
00174 }
00175
00177
00178 bool has_chunk(chunk id)
00179 {
00180 return png_get_valid(m_png,
00181 m_info.get_png_info(),
00182 uint_32(id)) == uint_32(id);
00183 }
00184
00185 #if defined(PNG_READ_EXPAND_SUPPORTED)
00186 void set_gray_1_2_4_to_8() const
00187 {
00188 png_set_gray_1_2_4_to_8(m_png);
00189 }
00190
00191 void set_palette_to_rgb() const
00192 {
00193 png_set_palette_to_rgb(m_png);
00194 }
00195
00196 void set_tRNS_to_alpha() const
00197 {
00198 png_set_tRNS_to_alpha(m_png);
00199 }
00200 #endif // defined(PNG_READ_EXPAND_SUPPORTED)
00201
00202 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
00203 void set_bgr() const
00204 {
00205 png_set_bgr(m_png);
00206 }
00207 #endif
00208
00209 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
00210 void set_gray_to_rgb() const
00211 {
00212 png_set_gray_to_rgb(m_png);
00213 }
00214 #endif
00215
00216 #ifdef PNG_FLOATING_POINT_SUPPORTED
00217 void set_rgb_to_gray(rgb_to_gray_error_action error_action
00218 = rgb_to_gray_silent,
00219 double red_weight = -1.0,
00220 double green_weight = -1.0) const
00221 {
00222 png_set_rgb_to_gray(m_png, error_action, red_weight, green_weight);
00223 }
00224 #else
00225 void set_rgb_to_gray(rgb_to_gray_error_action error_action
00226 = rgb_to_gray_silent,
00227 fixed_point red_weight = -1,
00228 fixed_point green_weight = -1) const
00229 {
00230 png_set_rgb_to_gray_fixed(m_png, error_action,
00231 red_weight, green_weight);
00232 }
00233 #endif // PNG_FLOATING_POINT_SUPPORTED
00234
00236
00237
00238 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
00239 void set_strip_alpha() const
00240 {
00241 png_set_strip_alpha(m_png);
00242 }
00243 #endif
00244
00245 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) \
00246 || defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
00247 void set_swap_alpha() const
00248 {
00249 png_set_swap_alpha(m_png);
00250 }
00251 #endif
00252
00253 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) \
00254 || defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
00255 void set_invert_alpha() const
00256 {
00257 png_set_invert_alpha(m_png);
00258 }
00259 #endif
00260
00261 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
00262 void set_filler(uint_32 filler, filler_type type) const
00263 {
00264 png_set_filler(m_png, filler, type);
00265 }
00266
00267 #if !defined(PNG_1_0_X)
00268 void set_add_alpha(uint_32 filler, filler_type type) const
00269 {
00270 png_set_add_alpha(m_png, filler, type);
00271 }
00272 #endif
00273 #endif // PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED
00274
00275 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
00276 void set_swap() const
00277 {
00278 png_set_swap(m_png);
00279 }
00280 #endif
00281
00282 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
00283 void set_packing() const
00284 {
00285 png_set_packing(m_png);
00286 }
00287 #endif
00288
00289 #if defined(PNG_READ_PACKSWAP_SUPPORTED) \
00290 || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
00291 void set_packswap() const
00292 {
00293 png_set_packswap(m_png);
00294 }
00295 #endif
00296
00297 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
00298 void set_shift(byte red_bits, byte green_bits, byte blue_bits,
00299 byte alpha_bits = 0) const
00300 {
00301 if (get_color_type() != color_type_rgb
00302 || get_color_type() != color_type_rgb_alpha)
00303 {
00304 throw error("set_shift: expected RGB or RGBA color type");
00305 }
00306 color_info bits;
00307 bits.red = red_bits;
00308 bits.green = green_bits;
00309 bits.blue = blue_bits;
00310 bits.alpha = alpha_bits;
00311 png_set_shift(m_png, & bits);
00312 }
00313
00314 void set_shift(byte gray_bits, byte alpha_bits = 0) const
00315 {
00316 if (get_color_type() != color_type_gray
00317 || get_color_type() != color_type_gray_alpha)
00318 {
00319 throw error("set_shift: expected Gray or Gray+Alpha"
00320 " color type");
00321 }
00322 color_info bits;
00323 bits.gray = gray_bits;
00324 bits.alpha = alpha_bits;
00325 png_set_shift(m_png, & bits);
00326 }
00327 #endif // PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED
00328
00329 #if defined(PNG_READ_INTERLACING_SUPPORTED) \
00330 || defined(PNG_WRITE_INTERLACING_SUPPORTED)
00331 int set_interlace_handling() const
00332 {
00333 return png_set_interlace_handling(m_png);
00334 }
00335 #endif
00336
00337 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
00338 void set_invert_mono() const
00339 {
00340 png_set_invert_mono(m_png);
00341 }
00342 #endif
00343
00344 #if defined(PNG_READ_16_TO_8_SUPPORTED)
00345 void set_strip_16() const
00346 {
00347 png_set_strip_16(m_png);
00348 }
00349 #endif
00350
00351 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
00352 void set_read_user_transform(png_user_transform_ptr transform_fn)
00353 {
00354 png_set_read_user_transform_fn(m_png, transform_fn);
00355 }
00356 #endif
00357
00358 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) \
00359 || defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
00360 void set_user_transform_info(void* info, int bit_depth, int channels)
00361 {
00362 png_set_user_transform_info(m_png, info, bit_depth, channels);
00363 }
00364 #endif
00365
00366 protected:
00367 void* get_io_ptr() const
00368 {
00369 return png_get_io_ptr(m_png);
00370 }
00371
00372 void set_error(char const* message)
00373 {
00374 assert(message);
00375 m_error = message;
00376 }
00377
00378 void reset_error()
00379 {
00380 m_error.clear();
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390 bool is_error() const
00391 {
00392 return !m_error.empty();
00393 }
00394
00395 void raise_error()
00396 {
00397 longjmp(m_png->jmpbuf, -1);
00398 }
00399
00400 static void raise_error(png_struct* png, char const* message)
00401 {
00402 io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
00403 io->set_error(message);
00404 longjmp(png->jmpbuf, -1);
00405 }
00406
00407 png_struct* m_png;
00408 info m_info;
00409 end_info m_end_info;
00410 std::string m_error;
00411 };
00412
00413 }
00414
00415 #endif // PNGPP_IO_BASE_HPP_INCLUDED