1 module gfm.sdl2.sdlimage; 2 3 import std..string; 4 5 import bindbc.sdl, 6 bindbc.sdl.image; 7 8 import std.experimental.logger; 9 10 import gfm.sdl2.sdl, 11 gfm.sdl2.surface; 12 13 /// Load images using SDL_image, a SDL companion library able to load various image formats. 14 final class SDLImage 15 { 16 public 17 { 18 /// Loads the SDL_image library. 19 /// SDL must be already initialized. 20 /// Throws: $(D SDL2Exception) on error. 21 this(SDL2 sdl2, int flags = IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | IMG_INIT_WEBP) 22 { 23 _sdl2 = sdl2; // force loading of SDL first 24 _logger = sdl2._logger; 25 _SDLImageInitialized = false; 26 27 const ret = loadSDLImage(); 28 if(ret < sdlImageSupport) 29 { 30 if(ret == SDLImageSupport.noLibrary) 31 throwSDL2ImageException("SDL Image shared library failed to load"); 32 else if(SDLImageSupport.badLibrary) 33 // One or more symbols failed to load. The likely cause is that the 34 // shared library is for a lower version than bindbc-sdl was configured 35 // to load (via SDL_201, SDL_202, etc.) 36 throwSDL2ImageException("One or more symbols of SDL Image shared library failed to load"); 37 throwSDL2ImageException("The version of the SDL Image library on your system is too low. Please upgrade."); 38 } 39 40 int inited = IMG_Init(flags); 41 _SDLImageInitialized = true; 42 } 43 44 /// Releases the SDL resource. 45 ~this() 46 { 47 if (_SDLImageInitialized) 48 { 49 debug ensureNotInGC("SDLImage"); 50 _SDLImageInitialized = false; 51 IMG_Quit(); 52 } 53 } 54 55 /// Load an image. 56 /// Returns: A SDL surface with loaded content. 57 /// Throws: $(D SDL2Exception) on error. 58 SDL2Surface load(string path) 59 { 60 immutable(char)* pathz = toStringz(path); 61 SDL_Surface* surface = IMG_Load(pathz); 62 if (surface is null) 63 throwSDL2ImageException("IMG_Load"); 64 65 return new SDL2Surface(_sdl2, surface, SDL2Surface.Owned.YES); 66 } 67 } 68 69 private 70 { 71 Logger _logger; 72 SDL2 _sdl2; 73 bool _SDLImageInitialized; 74 75 void throwSDL2ImageException(string callThatFailed) 76 { 77 string message = format("%s failed: %s", callThatFailed, getErrorString()); 78 throw new SDL2Exception(message); 79 } 80 81 const(char)[] getErrorString() 82 { 83 return fromStringz(IMG_GetError()); 84 } 85 } 86 }