X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fimage.cpp;h=2903d499f75cfcb815a02f48de869b875bff54ef;hb=2ed9d7a0a96638bdf0614c1cf858719e7ced40d3;hp=56e7c1b01f59c54338e5cfb671f9961ba9502c8b;hpb=cc728fda1325c5358f3ec177d31621b5688371fe;p=libs%2Fgui.git diff --git a/source/graphics/image.cpp b/source/graphics/image.cpp index 56e7c1b..2903d49 100644 --- a/source/graphics/image.cpp +++ b/source/graphics/image.cpp @@ -1,194 +1,90 @@ -#ifdef WITH_DEVIL -#include -#endif +#include "image.h" +#include +#include #include #include -#include "image.h" -#include "image_png.h" -#include "image_private.h" +#include "imageloader.h" using namespace std; namespace Msp { namespace Graphics { -Image::Private::Private() +Image::Data::Data(): + fmt(RGB), + width(0), + height(0), + owned_pixels(0), + pixels(0) +{ } + +Image::Data::Data(const Data &other): + fmt(other.fmt), + width(other.width), + height(other.height), + stride(other.stride), + owned_pixels(other.pixels ? new char[stride*height] : 0), + pixels(owned_pixels) { -#ifdef WITH_DEVIL - id = 0; -#endif -#ifdef WITH_LIBPNG - fmt = RGB; - width = 0; - height = 0; - data = 0; -#endif + if(pixels) + copy(other.pixels, other.pixels+stride*height, pixels); } - -namespace { - -#ifdef WITH_DEVIL -void ensure_devil_image(unsigned &id) +Image::Data &Image::Data::operator=(const Data &other) { - static bool init_done = false; + delete[] owned_pixels; + pixels = owned_pixels = 0; - if(!init_done) + fmt = other.fmt; + width = other.width; + height = other.height; + stride = other.stride; + + if(other.pixels) { - ilInit(); - ilEnable(IL_ORIGIN_SET); - ilOriginFunc(IL_ORIGIN_LOWER_LEFT); - init_done = true; + pixels = owned_pixels = new char[stride*height]; + copy(other.pixels, other.pixels+stride*height, pixels); } - if(!id) - ilGenImages(1, &id); -} -#endif - + return *this; } - -Image::Image(): - priv(new Private) +Image::Data::~Data() { -#if !defined(WITH_DEVIL) && !defined(WITH_LIBPNG) - throw runtime_error("no image support"); -#endif + delete[] owned_pixels; } -Image::~Image() -{ -#ifdef WITH_DEVIL - if(priv->id) - ilDeleteImages(1, &priv->id); -#endif -#ifdef WITH_LIBPNG - delete[] priv->data; -#endif - delete priv; -} void Image::load_file(const string &fn) { -#ifdef WITH_LIBPNG - if(fn.size()>4 && !fn.compare(fn.size()-4, 4, ".png")) - { - IO::BufferedFile file(fn); - load_png(file, *priv); - } - else -#endif - { -#ifdef WITH_DEVIL - ensure_devil_image(priv->id); - ilBindImage(priv->id); - if(!ilLoadImage(const_cast(fn.c_str()))) - throw bad_image_data("IL error"); -#else - throw unsupported_image_format("DevIL needed for non-PNG images"); -#endif - } - (void)fn; + RefPtr loader = ImageLoader::open_file(fn); + load(*loader); } -void Image::load_memory(const void *data, unsigned size) +void Image::load_io(IO::Seekable &io) { -#ifdef WITH_LIBPNG - if(size>=8 && is_png(data, 8)) - { - IO::Memory mem(reinterpret_cast(data), size); - load_png(mem, *priv); - } - else -#endif - { -#ifdef WITH_DEVIL - ensure_devil_image(priv->id); - ilBindImage(priv->id); - if(!ilLoadL(IL_TYPE_UNKNOWN, const_cast(data), size)) - throw bad_image_data("IL error"); -#else - throw unsupported_image_format("DevIL needed for non-PNG images"); -#endif - } - (void)data; - (void)size; -} - -PixelFormat Image::get_format() const -{ -#ifdef WITH_LIBPNG - if(priv->data) - return priv->fmt; -#endif -#ifdef WITH_DEVIL - if(priv->id) - { - ilBindImage(priv->id); - switch(ilGetInteger(IL_IMAGE_FORMAT)) - { - case IL_COLOR_INDEX: return COLOR_INDEX; - case IL_LUMINANCE: return LUMINANCE; - case IL_LUMINANCE_ALPHA: return LUMINANCE_ALPHA; - case IL_RGB: return RGB; - case IL_RGBA: return RGBA; - case IL_BGR: return BGR; - case IL_BGRA: return BGRA; - // XXX bad, should throw when loading - default: throw invalid_argument("unknown pixel format in image"); - } - } -#endif - return RGB; + RefPtr loader = ImageLoader::open_io(io); + load(*loader); } -unsigned Image::get_width() const +void Image::load(ImageLoader &loader) { -#ifdef WITH_LIBPNG - if(priv->data) - return priv->width; -#endif -#ifdef WITH_DEVIL - if(priv->id) - { - ilBindImage(priv->id); - return ilGetInteger(IL_IMAGE_WIDTH); - } -#endif - return 0; + if(loader.get_state()==ImageLoader::INITIAL) + data = Data(); + loader.load(data); } -unsigned Image::get_height() const +void Image::load_into(ImageLoader &loader, void *buffer) { -#ifdef WITH_LIBPNG - if(priv->data) - return priv->height; -#endif -#ifdef WITH_DEVIL - if(priv->id) - { - ilBindImage(priv->id); - return ilGetInteger(IL_IMAGE_HEIGHT); - } -#endif - return 0; + data.pixels = reinterpret_cast(buffer); + load(loader); } -const void *Image::get_data() const +void Image::load_headers(ImageLoader &loader) { -#ifdef WITH_LIBPNG - if(priv->data) - return priv->data; -#endif -#ifdef WITH_DEVIL - if(priv->id) - { - ilBindImage(priv->id); - return ilGetData(); - } -#endif - return 0; + if(loader.get_state()==ImageLoader::INITIAL) + data = Data(); + loader.load_headers(data); } } // namespace Graphics