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_READER_HPP_INCLUDED
00032 #define PNGPP_READER_HPP_INCLUDED
00033
00034 #include <cassert>
00035 #include <iostream>
00036 #include "io_base.hpp"
00037
00038 namespace png
00039 {
00040
00048 class reader
00049 : public io_base
00050 {
00051 public:
00056 explicit reader(std::istream& stream)
00057 : io_base(png_create_read_struct(PNG_LIBPNG_VER_STRING,
00058 static_cast< io_base* >(this),
00059 raise_error,
00060 0))
00061 {
00062 png_set_read_fn(m_png, & stream, read_data);
00063 }
00064
00065 ~reader()
00066 {
00067 png_destroy_read_struct(& m_png,
00068 m_info.get_png_info_ptr(),
00069 m_end_info.get_png_info_ptr());
00070 }
00071
00076 void read_png()
00077 {
00078 if (setjmp(m_png->jmpbuf))
00079 {
00080 throw error(m_error);
00081 }
00082 png_read_png(m_png,
00083 m_info.get_png_info(),
00084 0,
00085 0);
00086 }
00087
00091 void read_info()
00092 {
00093 if (setjmp(m_png->jmpbuf))
00094 {
00095 throw error(m_error);
00096 }
00097 m_info.read();
00098 }
00099
00103 void read_row(byte* bytes)
00104 {
00105 if (setjmp(m_png->jmpbuf))
00106 {
00107 throw error(m_error);
00108 }
00109 png_read_row(m_png, bytes, 0);
00110 }
00111
00115 void read_end_info()
00116 {
00117 if (setjmp(m_png->jmpbuf))
00118 {
00119 throw error(m_error);
00120 }
00121 m_end_info.read();
00122 }
00123
00124 void update_info()
00125 {
00126 m_info.update();
00127 }
00128
00129 private:
00130 static void read_data(png_struct* png, byte* data, size_t length)
00131 {
00132 io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
00133 reader* rd = static_cast< reader* >(io);
00134 rd->reset_error();
00135 std::istream* stream
00136 = reinterpret_cast< std::istream* >(png_get_io_ptr(png));
00137 try
00138 {
00139 stream->read(reinterpret_cast< char* >(data), length);
00140 if (!stream->good())
00141 {
00142 rd->set_error("std::istream::read() failed");
00143 }
00144 }
00145 catch (std::exception const& error)
00146 {
00147 rd->set_error(error.what());
00148 }
00149 catch (...)
00150 {
00151 assert(!"read_data: caught something wrong");
00152 rd->set_error("read_data: caught something wrong");
00153 }
00154 if (rd->is_error())
00155 {
00156 rd->raise_error();
00157 }
00158 }
00159 };
00160
00161 }
00162
00163 #endif // PNGPP_READER_HPP_INCLUDED