png++
0.2.9
|
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_INFO_HPP_INCLUDED 00032 #define PNGPP_INFO_HPP_INCLUDED 00033 00034 #include <cassert> 00035 #include "info_base.hpp" 00036 #include "image_info.hpp" 00037 00038 namespace png 00039 { 00040 00045 class info 00046 : public info_base, 00047 public image_info 00048 { 00049 public: 00050 info(io_base& io, png_struct* png) 00051 : info_base(io, png) 00052 { 00053 } 00054 00055 void read() 00056 { 00057 assert(m_png); 00058 assert(m_info); 00059 00060 png_read_info(m_png, m_info); 00061 png_get_IHDR(m_png, 00062 m_info, 00063 & m_width, 00064 & m_height, 00065 reinterpret_cast< int* >(& m_bit_depth), 00066 reinterpret_cast< int* >(& m_color_type), 00067 reinterpret_cast< int* >(& m_interlace_type), 00068 reinterpret_cast< int* >(& m_compression_type), 00069 reinterpret_cast< int* >(& m_filter_type)); 00070 00071 if (png_get_valid(m_png, m_info, chunk_PLTE) == chunk_PLTE) 00072 { 00073 png_color* colors = 0; 00074 int count = 0; 00075 png_get_PLTE(m_png, m_info, & colors, & count); 00076 m_palette.assign(colors, colors + count); 00077 } 00078 00079 #ifdef PNG_tRNS_SUPPORTED 00080 if (png_get_valid(m_png, m_info, chunk_tRNS) == chunk_tRNS) 00081 { 00082 if (m_color_type == color_type_palette) 00083 { 00084 int count; 00085 byte* values; 00086 if (png_get_tRNS(m_png, m_info, & values, & count, NULL) 00087 != PNG_INFO_tRNS) 00088 { 00089 throw error("png_get_tRNS() failed"); 00090 } 00091 m_tRNS.assign(values, values + count); 00092 } 00093 } 00094 #endif 00095 00096 #ifdef PNG_gAMA_SUPPORTED 00097 if (png_get_valid(m_png, m_info, chunk_gAMA) == chunk_gAMA) 00098 { 00099 #ifdef PNG_FLOATING_POINT_SUPPORTED 00100 if (png_get_gAMA(m_png, m_info, &m_gamma) != PNG_INFO_gAMA) 00101 { 00102 throw error("png_get_gAMA() failed"); 00103 } 00104 #else 00105 png_fixed_point gamma = 0; 00106 if (png_get_gAMA_fixed(m_png, m_info, &gamma) != PNG_INFO_gAMA) 00107 { 00108 throw error("png_get_gAMA_fixed() failed"); 00109 } 00110 m_gamma = gamma / 100000.0; 00111 #endif 00112 } 00113 #endif 00114 } 00115 00116 void write() const 00117 { 00118 assert(m_png); 00119 assert(m_info); 00120 00121 sync_ihdr(); 00122 if (m_color_type == color_type_palette) 00123 { 00124 if (! m_palette.empty()) 00125 { 00126 png_set_PLTE(m_png, m_info, 00127 const_cast< color* >(& m_palette[0]), 00128 (int) m_palette.size()); 00129 } 00130 if (! m_tRNS.empty()) 00131 { 00132 #ifdef PNG_tRNS_SUPPORTED 00133 png_set_tRNS(m_png, m_info, 00134 const_cast< byte* >(& m_tRNS[0]), 00135 m_tRNS.size(), 00136 NULL); 00137 #else 00138 throw error("attempted to write tRNS chunk; recompile with PNG_tRNS_SUPPORTED"); 00139 #endif 00140 } 00141 } 00142 00143 if (m_gamma > 0) 00144 { 00145 #ifdef PNG_gAMA_SUPPORTED 00146 #ifdef PNG_FLOATING_POINT_SUPPORTED 00147 png_set_gAMA(m_png, m_info, m_gamma); 00148 #else 00149 png_set_gAMA_fixed(m_png, m_info, 00150 (png_fixed_point)(m_gamma * 100000)); 00151 #endif 00152 #else 00153 throw error("attempted to write gAMA chunk; recompile with PNG_gAMA_SUPPORTED"); 00154 #endif 00155 } 00156 00157 png_write_info(m_png, m_info); 00158 } 00159 00160 void update() 00161 { 00162 assert(m_png); 00163 assert(m_info); 00164 00165 sync_ihdr(); 00166 png_read_update_info(m_png, m_info); 00167 } 00168 00169 protected: 00170 void sync_ihdr(void) const 00171 { 00172 png_set_IHDR(m_png, 00173 m_info, 00174 m_width, 00175 m_height, 00176 m_bit_depth, 00177 m_color_type, 00178 m_interlace_type, 00179 m_compression_type, 00180 m_filter_type); 00181 } 00182 }; 00183 00184 } // namespace png 00185 00186 #endif // PNGPP_INFO_HPP_INCLUDED