- Main Page
- Namespaces
- Classes
- Files

- File List

# writer.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_WRITER_HPP_INCLUDED
    00032 #define PNGPP_WRITER_HPP_INCLUDED
    00033
    00034 #include <cassert>
    00035 #include "io_base.hpp"
    00036
    00037 namespace png
    00038 {
    00039
    00065     template< class ostream >
    00066     class writer
    00067         : public io_base
    00068     {
    00069     public:
    00074         explicit writer(ostream& stream)
    00075             : io_base(png_create_write_struct(PNG_LIBPNG_VER_STRING,
    00076                                               static_cast< io_base* >(this),
    00077                                               raise_error,
    00078                                               0))
    00079         {
    00080             png_set_write_fn(m_png, & stream, write_data, flush_data);
    00081         }
    00082
    00083         ~writer()
    00084         {
    00085             m_end_info.destroy();
    00086             png_destroy_write_struct(& m_png, m_info.get_png_info_ptr());
    00087         }
    00088
    00089         void write_png() const
    00090         {
    00091             if (setjmp(png_jmpbuf(m_png)))
    00092             {
    00093                 throw error(m_error);
    00094             }
    00095             png_write_png(m_png,
    00096                           m_info.get_png_info(),
    00097                           /* transforms = */ 0,
    00098                           /* params = */ 0);
    00099         }
    00100
    00104         void write_info() const
    00105         {
    00106             if (setjmp(png_jmpbuf(m_png)))
    00107             {
    00108                 throw error(m_error);
    00109             }
    00110             m_info.write();
    00111         }
    00112
    00116         void write_row(byte* bytes)
    00117         {
    00118             if (setjmp(png_jmpbuf(m_png)))
    00119             {
    00120                 throw error(m_error);
    00121             }
    00122             png_write_row(m_png, bytes);
    00123         }
    00124
    00128         void write_end_info() const
    00129         {
    00130             if (setjmp(png_jmpbuf(m_png)))
    00131             {
    00132                 throw error(m_error);
    00133             }
    00134             m_end_info.write();
    00135         }
    00136
    00137     private:
    00138         static void write_data(png_struct* png, byte* data, size_t length)
    00139         {
    00140             io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
    00141             writer* wr = static_cast< writer* >(io);
    00142             wr->reset_error();
    00143             ostream* stream = reinterpret_cast< ostream* >(png_get_io_ptr(png));
    00144             try
    00145             {
    00146                 stream->write(reinterpret_cast< char* >(data), length);
    00147                 if (!stream->good())
    00148                 {
    00149                     wr->set_error("ostream::write() failed");
    00150                 }
    00151             }
    00152             catch (std::exception const& error)
    00153             {
    00154                 wr->set_error(error.what());
    00155             }
    00156             catch (...)
    00157             {
    00158                 assert(!"caught something wrong");
    00159                 wr->set_error("write_data: caught something wrong");
    00160             }
    00161             if (wr->is_error())
    00162             {
    00163                 wr->raise_error();
    00164             }
    00165         }
    00166
    00167         static void flush_data(png_struct* png)
    00168         {
    00169             io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
    00170             writer* wr = static_cast< writer* >(io);
    00171             wr->reset_error();
    00172             ostream* stream = reinterpret_cast< ostream* >(png_get_io_ptr(png));
    00173             try
    00174             {
    00175                 stream->flush();
    00176                 if (!stream->good())
    00177                 {
    00178                     wr->set_error("ostream::flush() failed");
    00179                 }
    00180             }
    00181             catch (std::exception const& error)
    00182             {
    00183                 wr->set_error(error.what());
    00184             }
    00185             catch (...)
    00186             {
    00187                 assert(!"caught something wrong");
    00188                 wr->set_error("flush_data: caught something wrong");
    00189             }
    00190             if (wr->is_error())
    00191             {
    00192                 wr->raise_error();
    00193             }
    00194         }
    00195     };
    00196
    00197 } // namespace png
    00198
    00199 #endif // PNGPP_WRITER_HPP_INCLUDED