]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/png/pngloader.cpp
Add a helper class for registering image loaders
[libs/gui.git] / source / graphics / png / pngloader.cpp
index 85530653afa8004cb6692fc2cd3fc6f1dcaf2f1b..ede91b0c37be3615ae7ca9e714d93c0d3aa10d67 100644 (file)
@@ -31,7 +31,8 @@ struct PngLoader::Private
        png_info *info;
 };
 
-PngLoader::PngLoader(IO::Base &io, const string &sig):
+
+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);
@@ -39,7 +40,7 @@ PngLoader::PngLoader(IO::Base &io, const string &sig):
 
        // These probably won't give any errors
        png_set_read_fn(priv->png, &io, read);
-       png_set_sig_bytes(priv->png, sig.size());
+       png_set_sig_bytes(priv->png, sig_bytes);
 }
 
 PngLoader::~PngLoader()
@@ -64,28 +65,28 @@ void PngLoader::load(Image::Data &data)
        int depth;
        int color;
        png_get_IHDR(priv->png, priv->info, &width, &height, &depth, &color, 0, 0, 0);
-       data.width = width;
-       data.height = height;
+       unsigned nchans = png_get_channels(priv->png, priv->info);
+
        if(depth!=8)
                throw unsupported_image_format("depth!=8");
+
+       data.width = width;
+       data.height = height;
+       data.stride = data.width*nchans;
+
        switch(color)
        {
        case PNG_COLOR_TYPE_PALETTE:    data.fmt = COLOR_INDEX; break;
        case PNG_COLOR_TYPE_GRAY:       data.fmt = LUMINANCE; break;
        case PNG_COLOR_TYPE_GRAY_ALPHA: data.fmt = LUMINANCE_ALPHA; break;
-       case PNG_COLOR_TYPE_RGB:        data.fmt = RGB; break;
+       case PNG_COLOR_TYPE_RGB:        data.fmt = (nchans==4 ? RGBX : RGB); break;
        case PNG_COLOR_TYPE_RGB_ALPHA:  data.fmt = RGBA; break;
        default: throw unsupported_image_format("unknown color type");
        }
 
-       unsigned nchans = png_get_channels(priv->png, priv->info);
-       if(nchans==4 && data.fmt==RGB)
-               png_set_strip_alpha(priv->png);
-
-       unsigned rowstride = data.width*nchans;
-       data.data = new char[rowstride*data.height];
+       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+rowstride*(data.height-1-y)), 0);
+               png_read_row(priv->png, reinterpret_cast<png_byte *>(data.data+data.stride*(data.height-1-y)), 0);
 
        png_read_end(priv->png, 0);
 }