- 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