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.
-struct IOContext
-{
- Msp::IO::Base *io;
- char *buffer;
- unsigned buf_fill;
- unsigned buf_max;
- unsigned position;
-};
-
unsigned char eof(void *handle)
{
unsigned char eof(void *handle)
{
- return reinterpret_cast<IOContext *>(handle)->io->eof();
+ return reinterpret_cast<Msp::IO::Seekable *>(handle)->eof();
}
int get(void *handle)
{
}
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)
{
}
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);
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;
-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;
- 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 0;
}
int tell(void *handle)
{
- return reinterpret_cast<IOContext *>(handle)->position;
+ return reinterpret_cast<Msp::IO::Seekable *>(handle)->tell();
namespace Msp {
namespace Graphics {
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;
{
static bool il_init_done = false;
void DevilLoader::load(Image::Data &data)
{
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);
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))
{
switch(ilGetInteger(IL_IMAGE_FORMAT))
{
- DevilLoader(IO::Base &, const std::string &);
+ DevilLoader(IO::Seekable &);
virtual ~DevilLoader();
static bool detect(const std::string &);
virtual ~DevilLoader();
static bool detect(const std::string &);
-void Image::load_io(IO::Base &io)
+void Image::load_io(IO::Seekable &io)
{
RefPtr<ImageLoader> loader = ImageLoader::open_io(io);
load(*loader);
{
RefPtr<ImageLoader> loader = ImageLoader::open_io(io);
load(*loader);
#include <stdexcept>
#include <string>
#include <stdexcept>
#include <string>
-#include <msp/io/base.h>
+#include <msp/io/seekable.h>
#include "pixelformat.h"
namespace Msp {
#include "pixelformat.h"
namespace Msp {
public:
void load_file(const std::string &);
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; }
void load(ImageLoader &);
PixelFormat get_format() const { return data.fmt; }
-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);
{
char sig_buf[8];
unsigned sig_len = io.read(sig_buf, sizeof(sig_buf));
string sig(sig_buf, sig_len);
// TODO register loader classes automatically
ImageLoader *loader = 0;
// TODO register loader classes automatically
ImageLoader *loader = 0;
;
#ifdef WITH_LIBPNG
else if(PngLoader::detect(sig))
;
#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))
#endif
#ifdef WITH_DEVIL
else if(DevilLoader::detect(sig))
- loader = new DevilLoader(io, sig);
+ loader = new DevilLoader(io);
virtual ~ImageLoader();
static ImageLoader *open_file(const std::string &);
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;
};
virtual void load(Image::Data &) = 0;
};
-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);
priv(new Private)
{
priv->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, &priv->message, error, 0);
// These probably won't give any errors
png_set_read_fn(priv->png, &io, read);
// 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()
}
PngLoader::~PngLoader()
- PngLoader(IO::Base &, const std::string &);
+ PngLoader(IO::Base &, unsigned = 0);
virtual ~PngLoader();
static bool detect(const std::string &);
virtual ~PngLoader();
static bool detect(const std::string &);