]> git.tdb.fi Git - libs/gui.git/commitdiff
Change the ImageLoader API to use IO::Seekable
authorMikko Rasa <tdb@tdb.fi>
Mon, 7 Oct 2013 11:08:19 +0000 (14:08 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 7 Oct 2013 16:42:36 +0000 (19:42 +0300)
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.

source/graphics/devil/devilloader.cpp
source/graphics/devil/devilloader.h
source/graphics/image.cpp
source/graphics/image.h
source/graphics/imageloader.cpp
source/graphics/imageloader.h
source/graphics/png/pngloader.cpp
source/graphics/png/pngloader.h

index 23b04b32d64819bd839bc317ad3c81995c866d53..392bde8f8099b08422f359d19086abe695097039 100644 (file)
@@ -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<IOContext *>(handle)->io->eof();
+       return reinterpret_cast<Msp::IO::Seekable *>(handle)->eof();
 }
 
 int get(void *handle)
 {
-       IOContext *ctx = reinterpret_cast<IOContext *>(handle);
-       if(ctx->position<ctx->buf_fill)
-               return ctx->buffer[ctx->position++];
-       else
-       {
-               char c = ctx->io->get();
-               if(ctx->position<ctx->buf_max)
-                       ctx->buffer[ctx->position] = c;
-               ++ctx->position;
-               return c;
-       }
+       return reinterpret_cast<Msp::IO::Seekable *>(handle)->get();
 }
 
 int read(void *buf, unsigned size, unsigned count, void *handle)
 {
-       IOContext *ctx = reinterpret_cast<IOContext *>(handle);
+       Msp::IO::Seekable *io = reinterpret_cast<Msp::IO::Seekable *>(handle);
        char *cbuf = reinterpret_cast<char *>(buf);
-       unsigned len = size*count;
-       unsigned ret = 0;
-
-       if(ctx->position<ctx->buf_fill)
+       unsigned i = 0;
+       for(; i<count; ++i)
        {
-               unsigned copy_len = min(ctx->buf_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(len<size)
+                       break;
        }
-
-       if(len)
-       {
-               unsigned read_len = ctx->io->read(cbuf, len);
-               if(ctx->position<ctx->buf_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<IOContext *>(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<Msp::IO::Seekable *>(handle)->seek(offset, type);
 
        return 0;
 }
 
 int tell(void *handle)
 {
-       return reinterpret_cast<IOContext *>(handle)->position;
+       return reinterpret_cast<Msp::IO::Seekable *>(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))
        {
index 3791bb2c0a519f4dd85ffe045eeb48f2f8e4e355..3b933ae2ff0cc9c0e52de2a7161a91b2c277f8e1 100644 (file)
@@ -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 &);
index 3e1124faaf06800158413189c054529db2ca4060..b22be1969d057e161cd60af0be3d9785c320b438 100644 (file)
@@ -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<ImageLoader> loader = ImageLoader::open_io(io);
        load(*loader);
index bfaeef84a00fbf7b945dbac8cc51d0fc593673bd..6905461a49557ed64df428902e538d85a9d271fc 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <stdexcept>
 #include <string>
-#include <msp/io/base.h>
+#include <msp/io/seekable.h>
 #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; }
index 679f797adcc2bae5d7499c7cc41f6254ef3bb723..daedab6c5b57e80539c580602dcc5c07a3f923f5 100644 (file)
@@ -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
        {
index 06532753b3e535d152c84c6ad75abae80230167b..f953990c696458dffb587d0a3fd3889fe10b9975 100644 (file)
@@ -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;
 };
index 85530653afa8004cb6692fc2cd3fc6f1dcaf2f1b..3f2f95912da05dd068075064edca261b47f521ee 100644 (file)
@@ -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()
index 0bb5fd7a575c2d559939fcbab0a1cf7b71d58b11..a81c34c3c49811318ed4cd912b70a98a43c48780 100644 (file)
@@ -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 &);