X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fdevil%2Fdevilloader.cpp;h=423b108a5bf6ad13d960099c03070cfe2e30b96b;hb=2ebdf45974a0a7649b3488f9da4b8cf90a1db584;hp=23b04b32d64819bd839bc317ad3c81995c866d53;hpb=cfd3548464e6424fc9decf0539d6cd04b031ba10;p=libs%2Fgui.git diff --git a/source/graphics/devil/devilloader.cpp b/source/graphics/devil/devilloader.cpp index 23b04b3..423b108 100644 --- a/source/graphics/devil/devilloader.cpp +++ b/source/graphics/devil/devilloader.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "devilloader.h" @@ -6,90 +7,65 @@ 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 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; - } - - if(len) + unsigned i = 0; + for(; iio->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; + unsigned len = io->read(cbuf, size); + cbuf += size; + if(len(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(); +} + +std::string error_string(ILenum err) +{ + switch(err) + { + case IL_FORMAT_NOT_SUPPORTED: return "Format not supported"; + case IL_INTERNAL_ERROR: return "DevIL internal error"; + case IL_INVALID_FILE_HEADER: return "Invalid file header"; + case IL_FILE_READ_ERROR: return "File read error"; + case IL_LIB_PNG_ERROR: return "LibPNG error"; + case IL_LIB_JPEG_ERROR: return "LibJPEG error"; + default: return Msp::format("Unknown error (%04X)", err); + } } } // namespace @@ -98,9 +74,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; @@ -126,20 +101,14 @@ bool DevilLoader::detect(const string &sig) return type!=IL_TYPE_UNKNOWN; } -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); - ilLoadF(IL_TYPE_UNKNOWN, &ctx); + + ilGetError(); + if(!ilLoadF(IL_TYPE_UNKNOWN, &io)) + throw bad_image_data(error_string(ilGetError())); switch(ilGetInteger(IL_IMAGE_FORMAT)) { @@ -155,10 +124,11 @@ void DevilLoader::load(Image::Data &data) data.width = ilGetInteger(IL_IMAGE_WIDTH); data.height = ilGetInteger(IL_IMAGE_HEIGHT); - unsigned data_size = data.width*data.height*ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); - data.data = new char[data_size]; + data.stride = data.width*ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); + unsigned data_size = data.stride*data.height; + data.pixels = new char[data_size]; ILubyte *il_data = ilGetData(); - copy(il_data, il_data+data_size, data.data); + copy(il_data, il_data+data_size, data.pixels); ilBindImage(0); ilResetRead();