]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/png/pngloader.cpp
Use nullptr in place of 0 or NULL
[libs/gui.git] / source / graphics / png / pngloader.cpp
index 35e6a971de3981bbd7b3deb501b5359bea3199fb..9c2e1ae339213c2f3cc5a2ad5965ecebb759bf33 100644 (file)
@@ -1,5 +1,5 @@
-#include <png.h>
 #include "pngloader.h"
+#include <png.h>
 
 using namespace std;
 
@@ -26,17 +26,17 @@ namespace Graphics {
 
 struct PngLoader::Private
 {
-       std::string message;
-       png_struct *png;
-       png_info *info;
+       string message;
+       png_struct *png = nullptr;
+       png_info *info = nullptr;
+       int interlace = PNG_INTERLACE_NONE;
 };
 
-ImageLoader::Register<PngLoader> PngLoader::reg;
 
 PngLoader::PngLoader(IO::Base &io, unsigned sig_bytes):
        priv(new Private)
 {
-       priv->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, &priv->message, error, 0);
+       priv->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, &priv->message, error, nullptr);
        priv->info = png_create_info_struct(priv->png);
 
        // These probably won't give any errors
@@ -46,26 +46,28 @@ PngLoader::PngLoader(IO::Base &io, unsigned sig_bytes):
 
 PngLoader::~PngLoader()
 {
-       png_destroy_read_struct(&priv->png, &priv->info, 0);
+       png_destroy_read_struct(&priv->png, &priv->info, nullptr);
        delete priv;
 }
 
-bool PngLoader::detect(const std::string &sig)
+bool PngLoader::detect(const string &sig)
 {
        return !png_sig_cmp(reinterpret_cast<png_byte *>(const_cast<char*>(sig.data())), 0, sig.size());
 }
 
-void PngLoader::load(Image::Data &data)
+void PngLoader::load_headers_(Image::Data &data)
 {
        if(setjmp(png_jmpbuf(priv->png)))
+       {
                throw bad_image_data(priv->message);
+       }
 
        png_read_info(priv->png, priv->info);
        png_uint_32 width;
        png_uint_32 height;
        int depth;
        int color;
-       png_get_IHDR(priv->png, priv->info, &width, &height, &depth, &color, 0, 0, 0);
+       png_get_IHDR(priv->png, priv->info, &width, &height, &depth, &color, &priv->interlace, nullptr, nullptr);
        unsigned nchans = png_get_channels(priv->png, priv->info);
 
        if(depth!=8)
@@ -84,12 +86,38 @@ void PngLoader::load(Image::Data &data)
        case PNG_COLOR_TYPE_RGB_ALPHA:  data.fmt = RGBA; break;
        default: throw unsupported_image_format("unknown color type");
        }
+}
+
+void PngLoader::load_pixels_(Image::Data &data)
+{
+       png_byte **rows = nullptr;
+
+       if(setjmp(png_jmpbuf(priv->png)))
+       {
+               delete[] rows;
+               throw bad_image_data(priv->message);
+       }
+
+       if(priv->interlace==PNG_INTERLACE_ADAM7)
+       {
+               // ADAM7 requires all rows to be loaded at once
+               unsigned n_passes = png_set_interlace_handling(priv->png);
+               rows = new png_byte *[data.height];
+               for(unsigned y=0; y<data.height; ++y)
+                       rows[y] = reinterpret_cast<png_byte *>(data.pixels+data.stride*(data.height-1-y));
 
-       data.data = new char[data.stride*data.height];
-       for(unsigned y=0; y<data.height; ++y)
-               png_read_row(priv->png, reinterpret_cast<png_byte *>(data.data+data.stride*(data.height-1-y)), 0);
+               for(unsigned i=0; i<n_passes; ++i)
+                       png_read_rows(priv->png, rows, nullptr, data.height);
+
+               delete[] rows;
+       }
+       else
+       {
+               for(unsigned y=0; y<data.height; ++y)
+                       png_read_row(priv->png, reinterpret_cast<png_byte *>(data.pixels+data.stride*(data.height-1-y)), nullptr);
+       }
 
-       png_read_end(priv->png, 0);
+       png_read_end(priv->png, nullptr);
 }
 
 } // namespace Graphics