1 module gfm.freeimage.freeimage; 2 3 import std.conv, 4 std.string; 5 6 import derelict.freeimage.freeimage, 7 derelict.util.exception; 8 9 /// The one exception type thrown in this wrapper. 10 /// A failing FreeImage function should <b>always</b> throw an FreeImageException. 11 class FreeImageException : Exception 12 { 13 public 14 { 15 @safe pure nothrow this(string message, string file =__FILE__, size_t line = __LINE__, Throwable next = null) 16 { 17 super(message, file, line, next); 18 } 19 } 20 } 21 22 /// FreeImage library wrapper. 23 final class FreeImage 24 { 25 public 26 { 27 /// Loads the FreeImage library and logs some information. 28 /// Throws: FreeImageException on error. 29 this(bool useExternalPlugins = false) 30 { 31 try 32 { 33 DerelictFI.load(); 34 } 35 catch(DerelictException e) 36 { 37 throw new FreeImageException(e.msg); 38 } 39 40 //FreeImage_Initialise(useExternalPlugins ? TRUE : FALSE); // documentation says it's useless 41 _libInitialized = true; 42 } 43 44 ~this() 45 { 46 if (_libInitialized) 47 { 48 debug ensureNotInGC("FreeImage"); 49 //FreeImage_DeInitialise(); // documentation says it's useless 50 _libInitialized = false; 51 } 52 } 53 54 const(char)[] getVersion() 55 { 56 const(char)* versionZ = FreeImage_GetVersion(); 57 return fromStringz(versionZ); 58 } 59 60 const(char)[] getCopyrightMessage() 61 { 62 const(char)* copyrightZ = FreeImage_GetCopyrightMessage(); 63 return fromStringz(copyrightZ); 64 } 65 } 66 67 private 68 { 69 bool _libInitialized; 70 } 71 } 72 73 /// Crash if the GC is running. 74 /// Useful in destructors to avoid reliance GC resource release. 75 package void ensureNotInGC(string resourceName) nothrow 76 { 77 import core.exception; 78 try 79 { 80 import core.memory; 81 cast(void) GC.malloc(1); // not ideal since it allocates 82 return; 83 } 84 catch(InvalidMemoryOperationError e) 85 { 86 87 import core.stdc.stdio; 88 fprintf(stderr, "Error: clean-up of %s incorrectly depends on destructors called by the GC.\n", resourceName.ptr); 89 assert(false); 90 } 91 }