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
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;
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))
{
}
}
-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;
;
#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
{