1 2 // Copyright Michael D. Parker 2018. 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE_1_0.txt or copy at 5 // http://www.boost.org/LICENSE_1_0.txt) 6 7 module bindbc.sdl.image; 8 9 version(BindSDL_Image): 10 11 import bindbc.sdl.bind.sdlerror : SDL_GetError, SDL_SetError; 12 import bindbc.sdl.bind.sdlrender : SDL_Renderer, SDL_Texture; 13 import bindbc.sdl.bind.sdlrwops : SDL_RWops; 14 import bindbc.sdl.bind.sdlsurface : SDL_Surface; 15 import bindbc.sdl.bind.sdlversion : SDL_version, SDL_VERSIONNUM; 16 17 alias IMG_SetError = SDL_SetError; 18 alias IMG_GetError = SDL_GetError; 19 20 enum SDLImageSupport { 21 noLibrary, 22 badLibrary, 23 sdlImage200 = 200, 24 sdlImage201, 25 sdlImage202, 26 } 27 28 enum ubyte SDL_IMAGE_MAJOR_VERSION = 2; 29 enum ubyte SDL_IMAGE_MINOR_VERSION = 0; 30 31 version(SDL_Image_202) { 32 enum sdlImageSupport = SDLImageSupport.sdlImage202; 33 enum ubyte SDL_IMAGE_PATCHLEVEL = 2; 34 } 35 else version(SDL_Image_201) { 36 enum sdlImageSupport = SDLImageSupport.sdlImage201; 37 enum ubyte SDL_IMAGE_PATCHLEVEL = 1; 38 } 39 else { 40 enum sdlImageSupport = SDLImageSupport.sdlImage200; 41 enum ubyte SDL_IMAGE_PATCHLEVEL = 0; 42 } 43 44 @nogc nothrow void SDL_IMAGE_VERSION(SDL_version* X) 45 { 46 X.major = SDL_IMAGE_MAJOR_VERSION; 47 X.minor = SDL_IMAGE_MINOR_VERSION; 48 X.patch = SDL_IMAGE_PATCHLEVEL; 49 } 50 51 // These were implemented in SDL_image 2.0.2, but are fine for all versions. 52 enum SDL_IMAGE_COMPILEDVERSION = SDL_VERSIONNUM!(SDL_IMAGE_MAJOR_VERSION, SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL); 53 enum SDL_IMAGE_VERSION_ATLEAST(ubyte X, ubyte Y, ubyte Z) = SDL_IMAGE_COMPILEDVERSION >= SDL_VERSIONNUM!(X, Y, Z); 54 55 enum { 56 IMG_INIT_JPG = 0x00000001, 57 IMG_INIT_PNG = 0x00000002, 58 IMG_INIT_TIF = 0x00000004, 59 IMG_INIT_WEBP = 0x00000008, 60 } 61 62 version(BindSDL_Static) { 63 extern(C) @nogc nothrow { 64 int IMG_Init(int); 65 int IMG_Quit(); 66 const(SDL_version)* IMG_Linked_Version(); 67 SDL_Surface* IMG_LoadTyped_RW(SDL_RWops*,int,const(char)*); 68 SDL_Surface* IMG_Load(const(char)*); 69 SDL_Surface* IMG_Load_RW(SDL_RWops*,int); 70 71 SDL_Texture* IMG_LoadTexture(SDL_Renderer*,const(char)*); 72 SDL_Texture* IMG_LoadTexture_RW(SDL_Renderer*,SDL_RWops*,int); 73 SDL_Texture* IMG_LoadTextureTyped_RW(SDL_Renderer*,SDL_RWops*,int,const(char)*); 74 75 int IMG_isICO(SDL_RWops*); 76 int IMG_isCUR(SDL_RWops*); 77 int IMG_isBMP(SDL_RWops*); 78 int IMG_isGIF(SDL_RWops*); 79 int IMG_isJPG(SDL_RWops*); 80 int IMG_isLBM(SDL_RWops*); 81 int IMG_isPCX(SDL_RWops*); 82 int IMG_isPNG(SDL_RWops*); 83 int IMG_isPNM(SDL_RWops*); 84 int IMG_isTIF(SDL_RWops*); 85 int IMG_isXCF(SDL_RWops*); 86 int IMG_isXPM(SDL_RWops*); 87 int IMG_isXV(SDL_RWops*); 88 int IMG_isWEBP(SDL_RWops*); 89 90 SDL_Surface* IMG_LoadICO_RW(SDL_RWops*); 91 SDL_Surface* IMG_LoadCUR_RW(SDL_RWops*); 92 SDL_Surface* IMG_LoadBMP_RW(SDL_RWops*); 93 SDL_Surface* IMG_LoadGIF_RW(SDL_RWops*); 94 SDL_Surface* IMG_LoadJPG_RW(SDL_RWops*); 95 SDL_Surface* IMG_LoadLBM_RW(SDL_RWops*); 96 SDL_Surface* IMG_LoadPCX_RW(SDL_RWops*); 97 SDL_Surface* IMG_LoadPNG_RW(SDL_RWops*); 98 SDL_Surface* IMG_LoadPNM_RW(SDL_RWops*); 99 SDL_Surface* IMG_LoadTGA_RW(SDL_RWops*); 100 SDL_Surface* IMG_LoadTIF_RW(SDL_RWops*); 101 SDL_Surface* IMG_LoadXCF_RW(SDL_RWops*); 102 SDL_Surface* IMG_LoadXPM_RW(SDL_RWops*); 103 SDL_Surface* IMG_LoadXV_RW(SDL_RWops*); 104 SDL_Surface* IMG_LoadWEBP_RW(SDL_RWops*); 105 106 SDL_Surface* IMG_ReadXPMFromArray(char**); 107 108 int IMG_SavePNG(SDL_Surface*,const(char)*); 109 int IMG_SavePNG_RW(SDL_Surface*,SDL_RWops*,int); 110 111 static if(sdlImageSupport >= SDLImageSupport.sdlImage202) { 112 int IMG_isSVG(SDL_RWops*); 113 SDL_Surface* IMG_LoadSVG(SDL_RWops*); 114 int IMG_SaveJPG(SDL_Surface*,const(char)*,int); 115 int IMG_SaveJPG_RW(SDL_Surface*,SDL_RWops*,int,int); 116 } 117 } 118 } 119 else { 120 import bindbc.loader; 121 122 extern(C) @nogc nothrow { 123 alias pIMG_Init = int function(int); 124 alias pIMG_Quit = int function(); 125 alias pIMG_Linked_Version = const(SDL_version)* function(); 126 alias pIMG_LoadTyped_RW = SDL_Surface* function(SDL_RWops*,int,const(char)*); 127 alias pIMG_Load = SDL_Surface* function(const(char)*); 128 alias pIMG_Load_RW = SDL_Surface* function(SDL_RWops*,int); 129 130 alias pIMG_LoadTexture = SDL_Texture* function(SDL_Renderer*,const(char)*); 131 alias pIMG_LoadTexture_RW = SDL_Texture* function(SDL_Renderer*,SDL_RWops*,int); 132 alias pIMG_LoadTextureTyped_RW = SDL_Texture* function(SDL_Renderer*,SDL_RWops*,int,const(char)*); 133 134 alias pIMG_isICO = int function(SDL_RWops*); 135 alias pIMG_isCUR = int function(SDL_RWops*); 136 alias pIMG_isBMP = int function(SDL_RWops*); 137 alias pIMG_isGIF = int function(SDL_RWops*); 138 alias pIMG_isJPG = int function(SDL_RWops*); 139 alias pIMG_isLBM = int function(SDL_RWops*); 140 alias pIMG_isPCX = int function(SDL_RWops*); 141 alias pIMG_isPNG = int function(SDL_RWops*); 142 alias pIMG_isPNM = int function(SDL_RWops*); 143 alias pIMG_isTIF = int function(SDL_RWops*); 144 alias pIMG_isXCF = int function(SDL_RWops*); 145 alias pIMG_isXPM = int function(SDL_RWops*); 146 alias pIMG_isXV = int function(SDL_RWops*); 147 alias pIMG_isWEBP = int function(SDL_RWops*); 148 149 alias pIMG_LoadICO_RW = SDL_Surface* function(SDL_RWops*); 150 alias pIMG_LoadCUR_RW = SDL_Surface* function(SDL_RWops*); 151 alias pIMG_LoadBMP_RW = SDL_Surface* function(SDL_RWops*); 152 alias pIMG_LoadGIF_RW = SDL_Surface* function(SDL_RWops*); 153 alias pIMG_LoadJPG_RW = SDL_Surface* function(SDL_RWops*); 154 alias pIMG_LoadLBM_RW = SDL_Surface* function(SDL_RWops*); 155 alias pIMG_LoadPCX_RW = SDL_Surface* function(SDL_RWops*); 156 alias pIMG_LoadPNG_RW = SDL_Surface* function(SDL_RWops*); 157 alias pIMG_LoadPNM_RW = SDL_Surface* function(SDL_RWops*); 158 alias pIMG_LoadTGA_RW = SDL_Surface* function(SDL_RWops*); 159 alias pIMG_LoadTIF_RW = SDL_Surface* function(SDL_RWops*); 160 alias pIMG_LoadXCF_RW = SDL_Surface* function(SDL_RWops*); 161 alias pIMG_LoadXPM_RW = SDL_Surface* function(SDL_RWops*); 162 alias pIMG_LoadXV_RW = SDL_Surface* function(SDL_RWops*); 163 alias pIMG_LoadWEBP_RW = SDL_Surface* function(SDL_RWops*); 164 165 alias pIMG_ReadXPMFromArray = SDL_Surface* function(char**); 166 167 alias pIMG_SavePNG = int function(SDL_Surface*,const(char)*); 168 alias pIMG_SavePNG_RW = int function(SDL_Surface*,SDL_RWops*,int); 169 } 170 171 __gshared { 172 pIMG_Init IMG_Init; 173 pIMG_Quit IMG_Quit; 174 pIMG_Linked_Version IMG_Linked_Version; 175 pIMG_LoadTyped_RW IMG_LoadTyped_RW; 176 pIMG_Load IMG_Load; 177 pIMG_Load_RW IMG_Load_RW; 178 pIMG_LoadTexture IMG_LoadTexture; 179 pIMG_LoadTexture_RW IMG_LoadTexture_RW; 180 pIMG_LoadTextureTyped_RW IMG_LoadTextureTyped_RW; 181 pIMG_isICO IMG_isICO; 182 pIMG_isCUR IMG_isCUR; 183 pIMG_isBMP IMG_isBMP; 184 pIMG_isGIF IMG_isGIF; 185 pIMG_isJPG IMG_isJPG; 186 pIMG_isLBM IMG_isLBM; 187 pIMG_isPCX IMG_isPCX; 188 pIMG_isPNG IMG_isPNG; 189 pIMG_isPNM IMG_isPNM; 190 pIMG_isTIF IMG_isTIF; 191 pIMG_isXCF IMG_isXCF; 192 pIMG_isXPM IMG_isXPM; 193 pIMG_isXV IMG_isXV; 194 pIMG_isWEBP IMG_isWEBP; 195 pIMG_LoadICO_RW IMG_LoadICO_RW; 196 pIMG_LoadCUR_RW IMG_LoadCUR_RW; 197 pIMG_LoadBMP_RW IMG_LoadBMP_RW; 198 pIMG_LoadGIF_RW IMG_LoadGIF_RW; 199 pIMG_LoadJPG_RW IMG_LoadJPG_RW; 200 pIMG_LoadLBM_RW IMG_LoadLBM_RW; 201 pIMG_LoadPCX_RW IMG_LoadPCX_RW; 202 pIMG_LoadPNG_RW IMG_LoadPNG_RW; 203 pIMG_LoadPNM_RW IMG_LoadPNM_RW; 204 pIMG_LoadTGA_RW IMG_LoadTGA_RW; 205 pIMG_LoadTIF_RW IMG_LoadTIF_RW; 206 pIMG_LoadXCF_RW IMG_LoadXCF_RW; 207 pIMG_LoadXPM_RW IMG_LoadXPM_RW; 208 pIMG_LoadXV_RW IMG_LoadXV_RW; 209 pIMG_LoadWEBP_RW IMG_LoadWEBP_RW; 210 pIMG_ReadXPMFromArray IMG_ReadXPMFromArray; 211 pIMG_SavePNG IMG_SavePNG; 212 pIMG_SavePNG_RW IMG_SavePNG_RW; 213 } 214 215 static if(sdlImageSupport >= SDLImageSupport.sdlImage202) { 216 extern(C) @nogc nothrow { 217 alias pIMG_isSVG = int function(SDL_RWops*); 218 alias pIMG_LoadSVG_RW = SDL_Surface* function(SDL_RWops*); 219 alias pIMG_SaveJPG = int function(SDL_Surface*,const(char)*,int); 220 alias pIMG_SaveJPG_RW = int function(SDL_Surface*,SDL_RWops*,int,int); 221 } 222 223 __gshared { 224 pIMG_isSVG IMG_isSVG; 225 pIMG_LoadSVG_RW IMG_LoadSVG; 226 pIMG_SaveJPG IMG_SaveJPG; 227 pIMG_SaveJPG_RW IMG_SaveJPG_RW; 228 } 229 } 230 231 private { 232 __gshared SharedLib lib; 233 __gshared SDLImageSupport loadedVersion; 234 } 235 236 void unloadSDLImage() 237 { 238 if(lib != invalidHandle) { 239 lib.unload(); 240 } 241 } 242 243 SDLImageSupport loadedSDLImageVersion() { return loadedVersion; } 244 245 bool isSDLImageLoaded() 246 { 247 return lib != invalidHandle; 248 } 249 250 251 SDLImageSupport loadSDLImage() 252 { 253 version(Windows) { 254 const(char)[][1] libNames = ["SDL2_image.dll"]; 255 } 256 else version(OSX) { 257 const(char)[][6] libNames = [ 258 "libSDL2_image.dylib", 259 "/usr/local/lib/libSDL2_image.dylib", 260 "../Frameworks/SDL2_image.framework/SDL2_image", 261 "/Library/Frameworks/SDL2_image.framework/SDL2_image", 262 "/System/Library/Frameworks/SDL2_image.framework/SDL2_image", 263 "/opt/local/lib/libSDL2_image.dylib" 264 ]; 265 } 266 else version(Posix) { 267 const(char)[][6] libNames = [ 268 "libSDL2_image.so", 269 "/usr/local/lib/libSDL2_image.so", 270 "libSDL2_image-2.0.so", 271 "/usr/local/lib/libSDL2_image-2.0.so", 272 "libSDL2_image-2.0.so.0", 273 "/usr/local/lib/libSDL2_image-2.0.so.0" 274 ]; 275 } 276 else static assert(0, "bindbc-sdl is not yet supported on this platform."); 277 278 SDLImageSupport ret; 279 foreach(name; libNames) { 280 ret = loadSDLImage(name.ptr); 281 if(ret != SDLImageSupport.noLibrary) break; 282 } 283 return ret; 284 } 285 286 SDLImageSupport loadSDLImage(const(char)* libName) 287 { 288 lib = load(libName); 289 if(lib == invalidHandle) { 290 return SDLImageSupport.noLibrary; 291 } 292 293 auto errCount = errorCount(); 294 loadedVersion = SDLImageSupport.badLibrary; 295 296 lib.bindSymbol(cast(void**)&IMG_Init,"IMG_Init"); 297 lib.bindSymbol(cast(void**)&IMG_Quit,"IMG_Quit"); 298 lib.bindSymbol(cast(void**)&IMG_Linked_Version,"IMG_Linked_Version"); 299 lib.bindSymbol(cast(void**)&IMG_LoadTyped_RW,"IMG_LoadTyped_RW"); 300 lib.bindSymbol(cast(void**)&IMG_Load,"IMG_Load"); 301 lib.bindSymbol(cast(void**)&IMG_Load_RW,"IMG_Load_RW"); 302 lib.bindSymbol(cast(void**)&IMG_LoadTexture,"IMG_LoadTexture"); 303 lib.bindSymbol(cast(void**)&IMG_LoadTexture_RW,"IMG_LoadTexture_RW"); 304 lib.bindSymbol(cast(void**)&IMG_LoadTextureTyped_RW,"IMG_LoadTextureTyped_RW"); 305 lib.bindSymbol(cast(void**)&IMG_isICO,"IMG_isICO"); 306 lib.bindSymbol(cast(void**)&IMG_isCUR,"IMG_isCUR"); 307 lib.bindSymbol(cast(void**)&IMG_isBMP,"IMG_isBMP"); 308 lib.bindSymbol(cast(void**)&IMG_isGIF,"IMG_isGIF"); 309 lib.bindSymbol(cast(void**)&IMG_isJPG,"IMG_isJPG"); 310 lib.bindSymbol(cast(void**)&IMG_isLBM,"IMG_isLBM"); 311 lib.bindSymbol(cast(void**)&IMG_isPCX,"IMG_isPCX"); 312 lib.bindSymbol(cast(void**)&IMG_isPNG,"IMG_isPNG"); 313 lib.bindSymbol(cast(void**)&IMG_isPNM,"IMG_isPNM"); 314 lib.bindSymbol(cast(void**)&IMG_isTIF,"IMG_isTIF"); 315 lib.bindSymbol(cast(void**)&IMG_isXCF,"IMG_isXCF"); 316 lib.bindSymbol(cast(void**)&IMG_isXPM,"IMG_isXPM"); 317 lib.bindSymbol(cast(void**)&IMG_isXV,"IMG_isXV"); 318 lib.bindSymbol(cast(void**)&IMG_isWEBP,"IMG_isWEBP"); 319 lib.bindSymbol(cast(void**)&IMG_LoadICO_RW,"IMG_LoadICO_RW"); 320 lib.bindSymbol(cast(void**)&IMG_LoadCUR_RW,"IMG_LoadCUR_RW"); 321 lib.bindSymbol(cast(void**)&IMG_LoadBMP_RW,"IMG_LoadBMP_RW"); 322 lib.bindSymbol(cast(void**)&IMG_LoadGIF_RW,"IMG_LoadGIF_RW"); 323 lib.bindSymbol(cast(void**)&IMG_LoadJPG_RW,"IMG_LoadJPG_RW"); 324 lib.bindSymbol(cast(void**)&IMG_LoadLBM_RW,"IMG_LoadLBM_RW"); 325 lib.bindSymbol(cast(void**)&IMG_LoadPCX_RW,"IMG_LoadPCX_RW"); 326 lib.bindSymbol(cast(void**)&IMG_LoadPNG_RW,"IMG_LoadPNG_RW"); 327 lib.bindSymbol(cast(void**)&IMG_LoadPNM_RW,"IMG_LoadPNM_RW"); 328 lib.bindSymbol(cast(void**)&IMG_LoadTGA_RW,"IMG_LoadTGA_RW"); 329 lib.bindSymbol(cast(void**)&IMG_LoadTIF_RW,"IMG_LoadTIF_RW"); 330 lib.bindSymbol(cast(void**)&IMG_LoadXCF_RW,"IMG_LoadXCF_RW"); 331 lib.bindSymbol(cast(void**)&IMG_LoadXPM_RW,"IMG_LoadXPM_RW"); 332 lib.bindSymbol(cast(void**)&IMG_LoadXV_RW,"IMG_LoadXV_RW"); 333 lib.bindSymbol(cast(void**)&IMG_isXV,"IMG_isXV"); 334 lib.bindSymbol(cast(void**)&IMG_LoadWEBP_RW,"IMG_LoadWEBP_RW"); 335 lib.bindSymbol(cast(void**)&IMG_SavePNG,"IMG_SavePNG"); 336 lib.bindSymbol(cast(void**)&IMG_SavePNG_RW,"IMG_SavePNG_RW"); 337 338 if(errorCount() != errCount) return SDLImageSupport.badLibrary; 339 else loadedVersion = SDLImageSupport.sdlImage200; 340 341 static if(sdlImageSupport >= SDLImageSupport.sdlImage202) { 342 lib.bindSymbol(cast(void**)&IMG_isSVG,"IMG_isSVG"); 343 lib.bindSymbol(cast(void**)&IMG_LoadSVG,"IMG_LoadSVG_RW"); 344 lib.bindSymbol(cast(void**)&IMG_SaveJPG,"IMG_SaveJPG"); 345 lib.bindSymbol(cast(void**)&IMG_SaveJPG_RW,"IMG_SaveJPG_RW"); 346 347 if(errorCount() != errCount) return SDLImageSupport.badLibrary; 348 else loadedVersion = SDLImageSupport.sdlImage202; 349 } 350 351 return loadedVersion; 352 } 353 }