+#ifdef WITH_DEVIL
+#include <IL/il.h>
+#include "image_devil.h"
+#include "image_private.h"
+
+using namespace std;
+
+namespace {
+
+using namespace Msp::Graphics;
+
+void init_load(Image::Private &priv)
+{
+ static bool il_init_done = false;
+
+ if(!il_init_done)
+ {
+ ilInit();
+ ilEnable(IL_ORIGIN_SET);
+ ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
+ il_init_done = true;
+ }
+
+ if(!priv.id)
+ ilGenImages(1, &priv.id);
+ ilBindImage(priv.id);
+}
+
+void finish_load(Image::Private &priv)
+{
+ switch(ilGetInteger(IL_IMAGE_FORMAT))
+ {
+ case IL_COLOR_INDEX: priv.fmt = COLOR_INDEX; break;
+ case IL_LUMINANCE: priv.fmt = LUMINANCE; break;
+ case IL_LUMINANCE_ALPHA: priv.fmt = LUMINANCE_ALPHA; break;
+ case IL_RGB: priv.fmt = RGB; break;
+ case IL_RGBA: priv.fmt = RGBA; break;
+ case IL_BGR: priv.fmt = BGR; break;
+ case IL_BGRA: priv.fmt = BGRA; break;
+ default: throw unsupported_image_format("unknown pixel format");
+ }
+
+ priv.width = ilGetInteger(IL_IMAGE_WIDTH);
+ priv.height = ilGetInteger(IL_IMAGE_HEIGHT);
+ priv.data = reinterpret_cast<char *>(ilGetData());
+
+ ilBindImage(0);
+}
+
+}
+
+
+namespace Msp {
+namespace Graphics {
+
+void load_devil_file(const string &fn, Image::Private &priv)
+{
+ init_load(priv);
+ if(!ilLoadImage(const_cast<char *>(fn.c_str())))
+ throw bad_image_data("IL error");
+ finish_load(priv);
+}
+
+void load_devil_mem(const void *data, unsigned size, Image::Private &priv)
+{
+ init_load(priv);
+ if(!ilLoadL(IL_TYPE_UNKNOWN, const_cast<void *>(data), size))
+ throw bad_image_data("IL error");
+ finish_load(priv);
+}
+
+} // namespace Graphics
+} // namespace Msp
+
+#endif