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