From: Mikko Rasa Date: Mon, 7 Oct 2013 11:08:19 +0000 (+0300) Subject: Change the ImageLoader API to use IO::Seekable X-Git-Url: http://git.tdb.fi/?p=libs%2Fgui.git;a=commitdiff_plain;h=8e403dbbcde6efee1862f6d501ce30a3e7ba81c4 Change the ImageLoader API to use IO::Seekable Trying to operate on purely streamed I/O turns out to be more headache than it's worth. I'll implement a generic adaptor in the IO namespace if it's needed at a later point. --- diff --git a/source/graphics/devil/devilloader.cpp b/source/graphics/devil/devilloader.cpp index 23b04b3..392bde8 100644 --- a/source/graphics/devil/devilloader.cpp +++ b/source/graphics/devil/devilloader.cpp @@ -6,90 +6,51 @@ using namespace std; namespace { -struct IOContext -{ - Msp::IO::Base *io; - char *buffer; - unsigned buf_fill; - unsigned buf_max; - unsigned position; -}; - unsigned char eof(void *handle) { - return reinterpret_cast(handle)->io->eof(); + return reinterpret_cast(handle)->eof(); } int get(void *handle) { - IOContext *ctx = reinterpret_cast(handle); - if(ctx->positionbuf_fill) - return ctx->buffer[ctx->position++]; - else - { - char c = ctx->io->get(); - if(ctx->positionbuf_max) - ctx->buffer[ctx->position] = c; - ++ctx->position; - return c; - } + return reinterpret_cast(handle)->get(); } int read(void *buf, unsigned size, unsigned count, void *handle) { - IOContext *ctx = reinterpret_cast(handle); + Msp::IO::Seekable *io = reinterpret_cast(handle); char *cbuf = reinterpret_cast(buf); - unsigned len = size*count; - unsigned ret = 0; - - if(ctx->positionbuf_fill) + unsigned i = 0; + for(; ibuf_fill-ctx->position, len); - copy(ctx->buffer+ctx->position, ctx->buffer+ctx->position+copy_len, cbuf); - ctx->position += copy_len; - ret += copy_len; - cbuf += copy_len; - len -= copy_len; + unsigned len = io->read(cbuf, size); + cbuf += size; + if(lenio->read(cbuf, len); - if(ctx->positionbuf_max) - { - unsigned copy_len = min(ctx->buf_max-ctx->position, read_len); - copy(cbuf, cbuf+copy_len, ctx->buffer+ctx->position); - ctx->buf_fill += copy_len; - } - ret += read_len; - ctx->position += read_len; - } - - return ret; + return i; } -int seek(void *handle, int offset, int type) +int seek(void *handle, int offset, int il_type) { - IOContext *ctx = reinterpret_cast(handle); - - unsigned new_pos = ctx->position; - if(type==IL_SEEK_SET) - new_pos = offset; - else if(type==IL_SEEK_CUR) - new_pos += offset; + Msp::IO::SeekType type; + if(il_type==IL_SEEK_SET) + type = Msp::IO::S_BEG; + else if(il_type==IL_SEEK_CUR) + type = Msp::IO::S_CUR; + else if(il_type==IL_SEEK_END) + type = Msp::IO::S_END; else return -1; - if(new_pos>ctx->buf_fill) - new_pos = ctx->buf_fill; - ctx->position = new_pos; + reinterpret_cast(handle)->seek(offset, type); return 0; } int tell(void *handle) { - return reinterpret_cast(handle)->position; + return reinterpret_cast(handle)->tell(); } } // namespace @@ -98,9 +59,8 @@ int tell(void *handle) namespace Msp { namespace Graphics { -DevilLoader::DevilLoader(IO::Base &i, const string &s): - io(i), - signature(s) +DevilLoader::DevilLoader(IO::Seekable &i): + io(i) { static bool il_init_done = false; @@ -128,18 +88,9 @@ bool DevilLoader::detect(const string &sig) void DevilLoader::load(Image::Data &data) { - IOContext ctx; - ctx.io = &io; - char buffer[4096]; - ctx.buffer = buffer; - ctx.buf_max = sizeof(buffer); - copy(signature.begin(), signature.end(), buffer); - ctx.buf_fill = signature.size(); - ctx.position = 0; - ilSetRead(0, 0, eof, get, read, seek, tell); ilBindImage(id); - ilLoadF(IL_TYPE_UNKNOWN, &ctx); + ilLoadF(IL_TYPE_UNKNOWN, &io); switch(ilGetInteger(IL_IMAGE_FORMAT)) { diff --git a/source/graphics/devil/devilloader.h b/source/graphics/devil/devilloader.h index 3791bb2..3b933ae 100644 --- a/source/graphics/devil/devilloader.h +++ b/source/graphics/devil/devilloader.h @@ -10,11 +10,10 @@ class DevilLoader: public ImageLoader { private: IO::Base &io; - std::string signature; unsigned id; public: - DevilLoader(IO::Base &, const std::string &); + DevilLoader(IO::Seekable &); virtual ~DevilLoader(); static bool detect(const std::string &); diff --git a/source/graphics/image.cpp b/source/graphics/image.cpp index 3e1124f..b22be19 100644 --- a/source/graphics/image.cpp +++ b/source/graphics/image.cpp @@ -29,7 +29,7 @@ void Image::load_file(const string &fn) load(*loader); } -void Image::load_io(IO::Base &io) +void Image::load_io(IO::Seekable &io) { RefPtr loader = ImageLoader::open_io(io); load(*loader); diff --git a/source/graphics/image.h b/source/graphics/image.h index bfaeef8..6905461 100644 --- a/source/graphics/image.h +++ b/source/graphics/image.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include "pixelformat.h" namespace Msp { @@ -30,7 +30,7 @@ private: public: void load_file(const std::string &); - void load_io(IO::Base &); + void load_io(IO::Seekable &); void load(ImageLoader &); PixelFormat get_format() const { return data.fmt; } diff --git a/source/graphics/imageloader.cpp b/source/graphics/imageloader.cpp index 679f797..daedab6 100644 --- a/source/graphics/imageloader.cpp +++ b/source/graphics/imageloader.cpp @@ -38,11 +38,12 @@ ImageLoader *ImageLoader::open_file(const string &fn) } } -ImageLoader *ImageLoader::open_io(IO::Base &io) +ImageLoader *ImageLoader::open_io(IO::Seekable &io) { char sig_buf[8]; unsigned sig_len = io.read(sig_buf, sizeof(sig_buf)); string sig(sig_buf, sig_len); + io.seek(0, IO::S_BEG); // TODO register loader classes automatically ImageLoader *loader = 0; @@ -50,11 +51,11 @@ ImageLoader *ImageLoader::open_io(IO::Base &io) ; #ifdef WITH_LIBPNG else if(PngLoader::detect(sig)) - loader = new PngLoader(io, sig); + loader = new PngLoader(io); #endif #ifdef WITH_DEVIL else if(DevilLoader::detect(sig)) - loader = new DevilLoader(io, sig); + loader = new DevilLoader(io); #endif else { diff --git a/source/graphics/imageloader.h b/source/graphics/imageloader.h index 0653275..f953990 100644 --- a/source/graphics/imageloader.h +++ b/source/graphics/imageloader.h @@ -32,7 +32,7 @@ public: virtual ~ImageLoader(); static ImageLoader *open_file(const std::string &); - static ImageLoader *open_io(IO::Base &); + static ImageLoader *open_io(IO::Seekable &); virtual void load(Image::Data &) = 0; }; diff --git a/source/graphics/png/pngloader.cpp b/source/graphics/png/pngloader.cpp index 8553065..3f2f959 100644 --- a/source/graphics/png/pngloader.cpp +++ b/source/graphics/png/pngloader.cpp @@ -31,7 +31,7 @@ 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 +39,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() diff --git a/source/graphics/png/pngloader.h b/source/graphics/png/pngloader.h index 0bb5fd7..a81c34c 100644 --- a/source/graphics/png/pngloader.h +++ b/source/graphics/png/pngloader.h @@ -14,7 +14,7 @@ private: Private *priv; public: - PngLoader(IO::Base &, const std::string &); + PngLoader(IO::Base &, unsigned = 0); virtual ~PngLoader(); static bool detect(const std::string &);