1 module des.il.io; 2 3 import des.math.linear.vector; 4 5 import derelict.devil.il; 6 import derelict.devil.ilu; 7 8 public import des.il; 9 import des.util.stdext..string; 10 11 import std..string; 12 13 import std.conv : to; 14 15 /// 16 Image imLoad( string fname, bool flip=true ) 17 { 18 loadIL(); 19 20 ILuint im; 21 ilGenImages( 1, &im ); 22 scope(exit) ilDeleteImages( 1, &im ); 23 ilBindImage( im ); 24 25 if( ilLoadImage( fname.toStringz ) == false ) 26 throw new ImageException( "'ilLoadImage' fails with '" ~ fname ~ "': " ~ 27 toDString( iluErrorString( ilGetError() ) ) ); 28 29 int w = ilGetInteger( IL_IMAGE_WIDTH ); 30 int h = ilGetInteger( IL_IMAGE_HEIGHT ); 31 int c = ilGetInteger( IL_IMAGE_BYTES_PER_PIXEL ); 32 33 if( flip ) iluFlipImage(); 34 35 ubyte* raw = ilGetData(); 36 37 return Image( ivec2(w,h), cast(ubyte)(c), DataType.UBYTE, raw[0..w*h*c] ); 38 } 39 40 /// 41 void imSave( in Image img, string fname ) 42 { 43 loadIL(); 44 45 ILenum format, type; 46 47 switch( img.info.comp ) 48 { 49 case 1: format = IL_COLOUR_INDEX; break; 50 case 3: format = IL_RGB; break; 51 case 4: format = IL_RGBA; break; 52 default: throw new ImageException( "Bad image channels count for saving" ); 53 } 54 55 switch( img.info.type ) 56 { 57 case DataType.BYTE: type = IL_BYTE; break; 58 case DataType.UBYTE: type = IL_UNSIGNED_BYTE; break; 59 case DataType.SHORT: type = IL_SHORT; break; 60 case DataType.USHORT: type = IL_UNSIGNED_SHORT; break; 61 case DataType.INT: type = IL_INT; break; 62 case DataType.UINT: type = IL_UNSIGNED_INT; break; 63 case DataType.FLOAT: type = IL_FLOAT; break; 64 case DataType.DOUBLE: type = IL_DOUBLE; break; 65 default: 66 throw new ImageException( "Bad image type for saving (" ~ 67 to!string(img.info.comp) ~ 68 "), please retype image" ); 69 } 70 71 ILuint im; 72 ilGenImages( 1, &im ); 73 scope(exit) ilDeleteImages( 1, &im ); 74 ilBindImage( im ); 75 76 auto size = uivec2( redimSize( 2, img.size ) ); 77 78 if( IL_TRUE != ilTexImage( size.w, size.h, 1, cast(ubyte)(img.info.comp), format, type, cast(void*)img.data.ptr ) ) 79 throw new ImageException( "ilTexImage fails: " ~ toDString( iluErrorString(ilGetError()) ) ); 80 81 iluFlipImage(); 82 83 import std..string; 84 if( IL_TRUE != ilSaveImage( fname.toStringz ) ) 85 throw new ImageException( "ilSaveImage fails: " ~ toDString( iluErrorString(ilGetError()) ) ); 86 } 87 88 private void loadIL() 89 { 90 if( DerelictIL.isLoaded ) return; 91 92 DerelictIL.load(); 93 DerelictILU.load(); 94 ilInit(); 95 iluInit(); 96 ilEnable( IL_FILE_OVERWRITE ); 97 }