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_READER_HPP_INCLUDED 00032 #define PNGPP_READER_HPP_INCLUDED 00033 00034 #include <cassert> 00035 #include "io_base.hpp" 00036 00037 namespace png 00038 { 00039 00064 template< class istream > 00065 class reader 00066 : public io_base 00067 { 00068 public: 00073 explicit reader(istream& stream) 00074 : io_base(png_create_read_struct(PNG_LIBPNG_VER_STRING, 00075 static_cast< io_base* >(this), 00076 raise_error, 00077 0)) 00078 { 00079 png_set_read_fn(m_png, & stream, read_data); 00080 } 00081 00082 ~reader() 00083 { 00084 png_destroy_read_struct(& m_png, 00085 m_info.get_png_info_ptr(), 00086 m_end_info.get_png_info_ptr()); 00087 } 00088 00093 void read_png() 00094 { 00095 if (setjmp(png_jmpbuf(m_png))) 00096 { 00097 throw error(m_error); 00098 } 00099 png_read_png(m_png, 00100 m_info.get_png_info(), 00101 /* transforms = */ 0, 00102 /* params = */ 0); 00103 } 00104 00108 void read_info() 00109 { 00110 if (setjmp(png_jmpbuf(m_png))) 00111 { 00112 throw error(m_error); 00113 } 00114 m_info.read(); 00115 } 00116 00120 void read_row(byte* bytes) 00121 { 00122 if (setjmp(png_jmpbuf(m_png))) 00123 { 00124 throw error(m_error); 00125 } 00126 png_read_row(m_png, bytes, 0); 00127 } 00128 00132 void read_end_info() 00133 { 00134 if (setjmp(png_jmpbuf(m_png))) 00135 { 00136 throw error(m_error); 00137 } 00138 m_end_info.read(); 00139 } 00140 00141 void update_info() 00142 { 00143 m_info.update(); 00144 } 00145 00146 private: 00147 static void read_data(png_struct* png, byte* data, png_size_t length) 00148 { 00149 io_base* io = static_cast< io_base* >(png_get_error_ptr(png)); 00150 reader* rd = static_cast< reader* >(io); 00151 rd->reset_error(); 00152 istream* stream = reinterpret_cast< istream* >(png_get_io_ptr(png)); 00153 try 00154 { 00155 stream->read(reinterpret_cast< char* >(data), length); 00156 if (!stream->good()) 00157 { 00158 rd->set_error("istream::read() failed"); 00159 } 00160 } 00161 catch (std::exception const& error) 00162 { 00163 rd->set_error(error.what()); 00164 } 00165 catch (...) 00166 { 00167 assert(!"read_data: caught something wrong"); 00168 rd->set_error("read_data: caught something wrong"); 00169 } 00170 if (rd->is_error()) 00171 { 00172 rd->raise_error(); 00173 } 00174 } 00175 }; 00176 00177 } // namespace png 00178 00179 #endif // PNGPP_READER_HPP_INCLUDED