• Main Page
  • Namespaces
  • Classes
  • Files
  • File List

io_base.hpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007,2008   Alex Shulgin
00003  *
00004  * This file is part of png++ the C++ wrapper for libpng.  PNG++ is free
00005  * software; the exact copying conditions are as follows:
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright notice,
00011  * this list of conditions and the following disclaimer.
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  * notice, this list of conditions and the following disclaimer in the
00015  * documentation and/or other materials provided with the distribution.
00016  *
00017  * 3. The name of the author may not be used to endorse or promote products
00018  * derived from this software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00021  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00022  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00023  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00025  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  */
00031 #ifndef PNGPP_IO_BASE_HPP_INCLUDED
00032 #define PNGPP_IO_BASE_HPP_INCLUDED
00033 
00034 #include <cassert>
00035 #include <cstdio>
00036 #include <cstdarg>
00037 #include "error.hpp"
00038 #include "info.hpp"
00039 #include "end_info.hpp"
00040 
00041 static void
00042 trace_io_transform(char const* fmt, ...)
00043 {
00044 #ifdef DEBUG_IO_TRANSFORM
00045     va_list va;
00046     va_start(va, fmt);
00047     fprintf(stderr, "TRANSFORM_IO: ");
00048     vfprintf(stderr, fmt, va);
00049     va_end(va);
00050 #endif
00051 }
00052 #define TRACE_IO_TRANSFORM trace_io_transform
00053 
00054 namespace png
00055 {
00056 
00062     class io_base
00063     {
00064         io_base(io_base const&);
00065         io_base& operator=(io_base const&);
00066 
00067     public:
00068         explicit io_base(png_struct* png)
00069             : m_png(png),
00070               m_info(*this, m_png),
00071               m_end_info(*this, m_png)
00072         {
00073         }
00074 
00075         ~io_base()
00076         {
00077             assert(! m_png);
00078             assert(! m_info.get_png_info());
00079             assert(! m_end_info.get_png_info());
00080         }
00081 
00082         png_struct* get_png_struct() const
00083         {
00084             return m_png;
00085         }
00086 
00087         info& get_info()
00088         {
00089             return m_info;
00090         }
00091 
00092         info const& get_info() const
00093         {
00094             return m_info;
00095         }
00096 
00097         image_info const& get_image_info() const
00098         {
00099             return m_info;
00100         }
00101 
00102         void set_image_info(image_info const& info)
00103         {
00104             static_cast< image_info& >(m_info) = info; // slice it
00105         }
00106 
00107         end_info& get_end_info()
00108         {
00109             return m_end_info;
00110         }
00111 
00112         end_info const& get_end_info() const
00113         {
00114             return m_end_info;
00115         }
00116 
00118         // info accessors
00119         //
00120         size_t get_width() const
00121         {
00122             return m_info.get_width();
00123         }
00124 
00125         void set_width(size_t width)
00126         {
00127             m_info.set_width(width);
00128         }
00129 
00130         size_t get_height() const
00131         {
00132             return m_info.get_height();
00133         }
00134 
00135         void set_height(size_t height)
00136         {
00137             m_info.set_height(height);
00138         }
00139 
00140         color_type get_color_type() const
00141         {
00142             return m_info.get_color_type();
00143         }
00144 
00145         void set_color_type(color_type color_space)
00146         {
00147             m_info.set_color_type(color_space);
00148         }
00149 
00150         size_t get_bit_depth() const
00151         {
00152             return m_info.get_bit_depth();
00153         }
00154 
00155         void set_bit_depth(size_t bit_depth)
00156         {
00157             m_info.set_bit_depth(bit_depth);
00158         }
00159 
00160         interlace_type get_interlace_type() const
00161         {
00162             return m_info.get_interlace_type();
00163         }
00164 
00165         void set_interlace_type(interlace_type interlace)
00166         {
00167             m_info.set_interlace_type(interlace);
00168         }
00169 
00170         compression_type get_compression_type() const
00171         {
00172             return m_info.get_compression_type();
00173         }
00174 
00175         void set_compression_type(compression_type compression)
00176         {
00177             m_info.set_compression_type(compression);
00178         }
00179 
00180         filter_type get_filter_type() const
00181         {
00182             return m_info.get_filter_type();
00183         }
00184 
00185         void set_filter_type(filter_type filter)
00186         {
00187             m_info.set_filter_type(filter);
00188         }
00189 
00191 
00192         bool has_chunk(chunk id)
00193         {
00194             return png_get_valid(m_png,
00195                                  m_info.get_png_info(),
00196                                  uint_32(id)) == uint_32(id);
00197         }
00198 
00199 #if defined(PNG_READ_EXPAND_SUPPORTED)
00200         void set_gray_1_2_4_to_8() const
00201         {
00202             TRACE_IO_TRANSFORM("png_set_expand_gray_1_2_4_to_8\n");
00203             png_set_expand_gray_1_2_4_to_8(m_png);
00204         }
00205 
00206         void set_palette_to_rgb() const
00207         {
00208             TRACE_IO_TRANSFORM("png_set_palette_to_rgb\n");
00209             png_set_palette_to_rgb(m_png);
00210         }
00211 
00212         void set_tRNS_to_alpha() const
00213         {
00214             TRACE_IO_TRANSFORM("png_set_tRNS_to_alpha\n");
00215             png_set_tRNS_to_alpha(m_png);
00216         }
00217 #endif // defined(PNG_READ_EXPAND_SUPPORTED)
00218 
00219 #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
00220         void set_bgr() const
00221         {
00222             TRACE_IO_TRANSFORM("png_set_bgr\n");
00223             png_set_bgr(m_png);
00224         }
00225 #endif
00226 
00227 #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
00228         void set_gray_to_rgb() const
00229         {
00230             TRACE_IO_TRANSFORM("png_set_gray_to_rgb\n");
00231             png_set_gray_to_rgb(m_png);
00232         }
00233 #endif
00234 
00235 #ifdef PNG_FLOATING_POINT_SUPPORTED
00236         void set_rgb_to_gray(rgb_to_gray_error_action error_action
00237                              = rgb_to_gray_silent,
00238                              double red_weight   = -1.0,
00239                              double green_weight = -1.0) const
00240         {
00241             TRACE_IO_TRANSFORM("png_set_rgb_to_gray: error_action=%d,"
00242                                " red_weight=%lf, green_weight=%lf\n",
00243                                error_action, red_weight, green_weight);
00244 
00245             png_set_rgb_to_gray(m_png, error_action, red_weight, green_weight);
00246         }
00247 #else
00248         void set_rgb_to_gray(rgb_to_gray_error_action error_action
00249                              = rgb_to_gray_silent,
00250                              fixed_point red_weight   = -1,
00251                              fixed_point green_weight = -1) const
00252         {
00253             TRACE_IO_TRANSFORM("png_set_rgb_to_gray_fixed: error_action=%d,"
00254                                " red_weight=%d, green_weight=%d\n",
00255                                error_action, red_weight, green_weight);
00256 
00257             png_set_rgb_to_gray_fixed(m_png, error_action,
00258                                       red_weight, green_weight);
00259         }
00260 #endif // PNG_FLOATING_POINT_SUPPORTED
00261 
00263         // alpha channel transformations
00264         //
00265 #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
00266         void set_strip_alpha() const
00267         {
00268             TRACE_IO_TRANSFORM("png_set_strip_alpha\n");
00269             png_set_strip_alpha(m_png);
00270         }
00271 #endif
00272 
00273 #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) \
00274     || defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
00275         void set_swap_alpha() const
00276         {
00277             TRACE_IO_TRANSFORM("png_set_swap_alpha\n");
00278             png_set_swap_alpha(m_png);
00279         }
00280 #endif
00281 
00282 #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) \
00283     || defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
00284         void set_invert_alpha() const
00285         {
00286             TRACE_IO_TRANSFORM("png_set_invert_alpha\n");
00287             png_set_invert_alpha(m_png);
00288         }
00289 #endif
00290 
00291 #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
00292         void set_filler(uint_32 filler, filler_type type) const
00293         {
00294             TRACE_IO_TRANSFORM("png_set_filler: filler=%08x, type=%d\n",
00295                                filler, type);
00296 
00297             png_set_filler(m_png, filler, type);
00298         }
00299 
00300 #if !defined(PNG_1_0_X)
00301         void set_add_alpha(uint_32 filler, filler_type type) const
00302         {
00303             TRACE_IO_TRANSFORM("png_set_add_alpha: filler=%08x, type=%d\n",
00304                                filler, type);
00305 
00306             png_set_add_alpha(m_png, filler, type);
00307         }
00308 #endif
00309 #endif // PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED
00310 
00311 #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
00312         void set_swap() const
00313         {
00314             TRACE_IO_TRANSFORM("png_set_swap\n");
00315             png_set_swap(m_png);
00316         }
00317 #endif
00318 
00319 #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
00320         void set_packing() const
00321         {
00322             TRACE_IO_TRANSFORM("png_set_packing\n");
00323             png_set_packing(m_png);
00324         }
00325 #endif
00326 
00327 #if defined(PNG_READ_PACKSWAP_SUPPORTED) \
00328     || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
00329         void set_packswap() const
00330         {
00331             TRACE_IO_TRANSFORM("png_set_packswap\n");
00332             png_set_packswap(m_png);
00333         }
00334 #endif
00335 
00336 #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
00337         void set_shift(byte red_bits, byte green_bits, byte blue_bits,
00338                        byte alpha_bits = 0) const
00339         {
00340             TRACE_IO_TRANSFORM("png_set_shift: red_bits=%d, green_bits=%d,"
00341                                " blue_bits=%d, alpha_bits=%d\n",
00342                                red_bits, green_bits, blue_bits, alpha_bits);
00343 
00344             if (get_color_type() != color_type_rgb
00345                 || get_color_type() != color_type_rgb_alpha)
00346             {
00347                 throw error("set_shift: expected RGB or RGBA color type");
00348             }
00349             color_info bits;
00350             bits.red = red_bits;
00351             bits.green = green_bits;
00352             bits.blue = blue_bits;
00353             bits.alpha = alpha_bits;
00354             png_set_shift(m_png, & bits);
00355         }
00356 
00357         void set_shift(byte gray_bits, byte alpha_bits = 0) const
00358         {
00359             TRACE_IO_TRANSFORM("png_set_shift: gray_bits=%d, alpha_bits=%d\n",
00360                                gray_bits, alpha_bits);
00361 
00362             if (get_color_type() != color_type_gray
00363                 || get_color_type() != color_type_gray_alpha)
00364             {
00365                 throw error("set_shift: expected Gray or Gray+Alpha"
00366                             " color type");
00367             }
00368             color_info bits;
00369             bits.gray = gray_bits;
00370             bits.alpha = alpha_bits;
00371             png_set_shift(m_png, & bits);
00372         }
00373 #endif // PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED
00374 
00375 #if defined(PNG_READ_INTERLACING_SUPPORTED) \
00376     || defined(PNG_WRITE_INTERLACING_SUPPORTED)
00377         int set_interlace_handling() const
00378         {
00379             TRACE_IO_TRANSFORM("png_set_interlace_handling\n");
00380             return png_set_interlace_handling(m_png);
00381         }
00382 #endif
00383 
00384 #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
00385         void set_invert_mono() const
00386         {
00387             TRACE_IO_TRANSFORM("png_set_invert_mono\n");
00388             png_set_invert_mono(m_png);
00389         }
00390 #endif
00391 
00392 #if defined(PNG_READ_16_TO_8_SUPPORTED)
00393         void set_strip_16() const
00394         {
00395             TRACE_IO_TRANSFORM("png_set_strip_16\n");
00396             png_set_strip_16(m_png);
00397         }
00398 #endif
00399 
00400 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
00401         void set_read_user_transform(png_user_transform_ptr transform_fn)
00402         {
00403             TRACE_IO_TRANSFORM("png_set_read_user_transform_fn\n");
00404             png_set_read_user_transform_fn(m_png, transform_fn);
00405         }
00406 #endif
00407 
00408 #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) \
00409     || defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
00410         void set_user_transform_info(void* info, int bit_depth, int channels)
00411         {
00412             TRACE_IO_TRANSFORM("png_set_user_transform_info: bit_depth=%d,"
00413                                " channels=%d\n", bit_depth, channels);
00414 
00415             png_set_user_transform_info(m_png, info, bit_depth, channels);
00416         }
00417 #endif
00418 
00419     protected:
00420         void* get_io_ptr() const
00421         {
00422             return png_get_io_ptr(m_png);
00423         }
00424 
00425         void set_error(char const* message)
00426         {
00427             assert(message);
00428             m_error = message;
00429         }
00430 
00431         void reset_error()
00432         {
00433             m_error.clear();
00434         }
00435 
00436 /*
00437         std::string const& get_error() const
00438         {
00439             return m_error;
00440         }
00441 */
00442 
00443         bool is_error() const
00444         {
00445             return !m_error.empty();
00446         }
00447 
00448         void raise_error()
00449         {
00450             longjmp(png_jmpbuf(m_png), -1);
00451         }
00452 
00453         static void raise_error(png_struct* png, char const* message)
00454         {
00455             io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
00456             io->set_error(message);
00457             io->raise_error();
00458         }
00459 
00460         png_struct* m_png;
00461         info m_info;
00462         end_info m_end_info;
00463         std::string m_error;
00464     };
00465 
00466 } // namespace png
00467 
00468 #endif // PNGPP_IO_BASE_HPP_INCLUDED

Generated on Wed Dec 15 2010 12:52:57 for png++ by  doxygen 1.7.1