1 2 // Copyright 2018 - 2021 Michael D. Parker 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 flags); 82 int IMG_Quit(); 83 const(SDL_version)* IMG_Linked_Version(); 84 SDL_Surface* IMG_LoadTyped_RW(SDL_RWops* src, int freesrc, const(char)* type); 85 SDL_Surface* IMG_Load(const(char)* file); 86 SDL_Surface* IMG_Load_RW(SDL_RWops* src, int freesrc); 87 88 SDL_Texture* IMG_LoadTexture(SDL_Renderer* renderer, const(char)* file); 89 SDL_Texture* IMG_LoadTexture_RW(SDL_Renderer* renderer, SDL_RWops* src, int freesrc); 90 SDL_Texture* IMG_LoadTextureTyped_RW(SDL_Renderer* renderer, SDL_RWops* src, int freesrc, const(char)* type); 91 92 int IMG_isICO(SDL_RWops* src); 93 int IMG_isCUR(SDL_RWops* src); 94 int IMG_isBMP(SDL_RWops* src); 95 int IMG_isGIF(SDL_RWops* src); 96 int IMG_isJPG(SDL_RWops* src); 97 int IMG_isLBM(SDL_RWops* src); 98 int IMG_isPCX(SDL_RWops* src); 99 int IMG_isPNG(SDL_RWops* src); 100 int IMG_isPNM(SDL_RWops* src); 101 int IMG_isTIF(SDL_RWops* src); 102 int IMG_isXCF(SDL_RWops* src); 103 int IMG_isXPM(SDL_RWops* src); 104 int IMG_isXV(SDL_RWops* src); 105 int IMG_isWEBP(SDL_RWops* src); 106 107 SDL_Surface* IMG_LoadICO_RW(SDL_RWops* src); 108 SDL_Surface* IMG_LoadCUR_RW(SDL_RWops* src); 109 SDL_Surface* IMG_LoadBMP_RW(SDL_RWops* src); 110 SDL_Surface* IMG_LoadGIF_RW(SDL_RWops* src); 111 SDL_Surface* IMG_LoadJPG_RW(SDL_RWops* src); 112 SDL_Surface* IMG_LoadLBM_RW(SDL_RWops* src); 113 SDL_Surface* IMG_LoadPCX_RW(SDL_RWops* src); 114 SDL_Surface* IMG_LoadPNG_RW(SDL_RWops* src); 115 SDL_Surface* IMG_LoadPNM_RW(SDL_RWops* src); 116 SDL_Surface* IMG_LoadTGA_RW(SDL_RWops* src); 117 SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src); 118 SDL_Surface* IMG_LoadXCF_RW(SDL_RWops* src); 119 SDL_Surface* IMG_LoadXPM_RW(SDL_RWops* src); 120 SDL_Surface* IMG_LoadXV_RW(SDL_RWops* src); 121 SDL_Surface* IMG_LoadWEBP_RW(SDL_RWops* src); 122 123 SDL_Surface* IMG_ReadXPMFromArray(char** xpm); 124 125 int IMG_SavePNG(SDL_Surface* surface, const(char)* file); 126 int IMG_SavePNG_RW(SDL_Surface* surface, SDL_RWops* dst, int freedst); 127 128 static if(sdlImageSupport >= SDLImageSupport.sdlImage202) { 129 int IMG_isSVG(SDL_RWops* src); 130 SDL_Surface* IMG_LoadSVG(SDL_RWops* src); 131 int IMG_SaveJPG(SDL_Surface* surface, const(char)* file, int quality); 132 int IMG_SaveJPG_RW(SDL_Surface* surface, SDL_RWops* dst, int freedst, int quality); 133 } 134 } 135 } 136 else { 137 import bindbc.loader; 138 139 extern(C) @nogc nothrow { 140 alias pIMG_Init = int function(int flags); 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* src, int freesrc, const(char)* type); 144 alias pIMG_Load = SDL_Surface* function(const(char)* file); 145 alias pIMG_Load_RW = SDL_Surface* function(SDL_RWops* src, int freesrc); 146 147 alias pIMG_LoadTexture = SDL_Texture* function(SDL_Renderer* renderer, const(char)* file); 148 alias pIMG_LoadTexture_RW = SDL_Texture* function(SDL_Renderer* renderer, SDL_RWops* src, int freesrc); 149 alias pIMG_LoadTextureTyped_RW = SDL_Texture* function(SDL_Renderer* renderer, SDL_RWops* src, int freesrc, const(char)* type); 150 151 alias pIMG_isICO = int function(SDL_RWops* src); 152 alias pIMG_isCUR = int function(SDL_RWops* src); 153 alias pIMG_isBMP = int function(SDL_RWops* src); 154 alias pIMG_isGIF = int function(SDL_RWops* src); 155 alias pIMG_isJPG = int function(SDL_RWops* src); 156 alias pIMG_isLBM = int function(SDL_RWops* src); 157 alias pIMG_isPCX = int function(SDL_RWops* src); 158 alias pIMG_isPNG = int function(SDL_RWops* src); 159 alias pIMG_isPNM = int function(SDL_RWops* src); 160 alias pIMG_isTIF = int function(SDL_RWops* src); 161 alias pIMG_isXCF = int function(SDL_RWops* src); 162 alias pIMG_isXPM = int function(SDL_RWops* src); 163 alias pIMG_isXV = int function(SDL_RWops* src); 164 alias pIMG_isWEBP = int function(SDL_RWops* src); 165 166 alias pIMG_LoadICO_RW = SDL_Surface* function(SDL_RWops* src); 167 alias pIMG_LoadCUR_RW = SDL_Surface* function(SDL_RWops* src); 168 alias pIMG_LoadBMP_RW = SDL_Surface* function(SDL_RWops* src); 169 alias pIMG_LoadGIF_RW = SDL_Surface* function(SDL_RWops* src); 170 alias pIMG_LoadJPG_RW = SDL_Surface* function(SDL_RWops* src); 171 alias pIMG_LoadLBM_RW = SDL_Surface* function(SDL_RWops* src); 172 alias pIMG_LoadPCX_RW = SDL_Surface* function(SDL_RWops* src); 173 alias pIMG_LoadPNG_RW = SDL_Surface* function(SDL_RWops* src); 174 alias pIMG_LoadPNM_RW = SDL_Surface* function(SDL_RWops* src); 175 alias pIMG_LoadTGA_RW = SDL_Surface* function(SDL_RWops* src); 176 alias pIMG_LoadTIF_RW = SDL_Surface* function(SDL_RWops* src); 177 alias pIMG_LoadXCF_RW = SDL_Surface* function(SDL_RWops* src); 178 alias pIMG_LoadXPM_RW = SDL_Surface* function(SDL_RWops* src); 179 alias pIMG_LoadXV_RW = SDL_Surface* function(SDL_RWops* src); 180 alias pIMG_LoadWEBP_RW = SDL_Surface* function(SDL_RWops* src); 181 182 alias pIMG_ReadXPMFromArray = SDL_Surface* function(char** xpm); 183 184 alias pIMG_SavePNG = int function(SDL_Surface* surface, const(char)* file); 185 alias pIMG_SavePNG_RW = int function(SDL_Surface* surface, SDL_RWops* dst, int freedst); 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* src); 235 alias pIMG_LoadSVG_RW = SDL_Surface* function(SDL_RWops* src); 236 alias pIMG_SaveJPG = int function(SDL_Surface* surface, const(char)* file, int quality); 237 alias pIMG_SaveJPG_RW = int function(SDL_Surface* surface, SDL_RWops* dst, int freedst, int quality); 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 @nogc nothrow: 254 void unloadSDLImage() 255 { 256 if(lib != invalidHandle) { 257 lib.unload(); 258 } 259 } 260 261 SDLImageSupport loadedSDLImageVersion() { return loadedVersion; } 262 263 bool isSDLImageLoaded() 264 { 265 return lib != invalidHandle; 266 } 267 268 269 SDLImageSupport loadSDLImage() 270 { 271 version(Windows) { 272 const(char)[][1] libNames = ["SDL2_image.dll"]; 273 } 274 else version(OSX) { 275 const(char)[][6] libNames = [ 276 "libSDL2_image.dylib", 277 "/usr/local/lib/libSDL2_image.dylib", 278 "../Frameworks/SDL2_image.framework/SDL2_image", 279 "/Library/Frameworks/SDL2_image.framework/SDL2_image", 280 "/System/Library/Frameworks/SDL2_image.framework/SDL2_image", 281 "/opt/local/lib/libSDL2_image.dylib" 282 ]; 283 } 284 else version(Posix) { 285 const(char)[][6] libNames = [ 286 "libSDL2_image.so", 287 "/usr/local/lib/libSDL2_image.so", 288 "libSDL2_image-2.0.so", 289 "/usr/local/lib/libSDL2_image-2.0.so", 290 "libSDL2_image-2.0.so.0", 291 "/usr/local/lib/libSDL2_image-2.0.so.0" 292 ]; 293 } 294 else static assert(0, "bindbc-sdl is not yet supported on this platform."); 295 296 SDLImageSupport ret; 297 foreach(name; libNames) { 298 ret = loadSDLImage(name.ptr); 299 if(ret != SDLImageSupport.noLibrary) break; 300 } 301 return ret; 302 } 303 304 SDLImageSupport loadSDLImage(const(char)* libName) 305 { 306 lib = load(libName); 307 if(lib == invalidHandle) { 308 return SDLImageSupport.noLibrary; 309 } 310 311 auto errCount = errorCount(); 312 loadedVersion = SDLImageSupport.badLibrary; 313 314 lib.bindSymbol(cast(void**)&IMG_Init,"IMG_Init"); 315 lib.bindSymbol(cast(void**)&IMG_Quit,"IMG_Quit"); 316 lib.bindSymbol(cast(void**)&IMG_Linked_Version,"IMG_Linked_Version"); 317 lib.bindSymbol(cast(void**)&IMG_LoadTyped_RW,"IMG_LoadTyped_RW"); 318 lib.bindSymbol(cast(void**)&IMG_Load,"IMG_Load"); 319 lib.bindSymbol(cast(void**)&IMG_Load_RW,"IMG_Load_RW"); 320 lib.bindSymbol(cast(void**)&IMG_LoadTexture,"IMG_LoadTexture"); 321 lib.bindSymbol(cast(void**)&IMG_LoadTexture_RW,"IMG_LoadTexture_RW"); 322 lib.bindSymbol(cast(void**)&IMG_LoadTextureTyped_RW,"IMG_LoadTextureTyped_RW"); 323 lib.bindSymbol(cast(void**)&IMG_isICO,"IMG_isICO"); 324 lib.bindSymbol(cast(void**)&IMG_isCUR,"IMG_isCUR"); 325 lib.bindSymbol(cast(void**)&IMG_isBMP,"IMG_isBMP"); 326 lib.bindSymbol(cast(void**)&IMG_isGIF,"IMG_isGIF"); 327 lib.bindSymbol(cast(void**)&IMG_isJPG,"IMG_isJPG"); 328 lib.bindSymbol(cast(void**)&IMG_isLBM,"IMG_isLBM"); 329 lib.bindSymbol(cast(void**)&IMG_isPCX,"IMG_isPCX"); 330 lib.bindSymbol(cast(void**)&IMG_isPNG,"IMG_isPNG"); 331 lib.bindSymbol(cast(void**)&IMG_isPNM,"IMG_isPNM"); 332 lib.bindSymbol(cast(void**)&IMG_isTIF,"IMG_isTIF"); 333 lib.bindSymbol(cast(void**)&IMG_isXCF,"IMG_isXCF"); 334 lib.bindSymbol(cast(void**)&IMG_isXPM,"IMG_isXPM"); 335 lib.bindSymbol(cast(void**)&IMG_isXV,"IMG_isXV"); 336 lib.bindSymbol(cast(void**)&IMG_isWEBP,"IMG_isWEBP"); 337 lib.bindSymbol(cast(void**)&IMG_LoadICO_RW,"IMG_LoadICO_RW"); 338 lib.bindSymbol(cast(void**)&IMG_LoadCUR_RW,"IMG_LoadCUR_RW"); 339 lib.bindSymbol(cast(void**)&IMG_LoadBMP_RW,"IMG_LoadBMP_RW"); 340 lib.bindSymbol(cast(void**)&IMG_LoadGIF_RW,"IMG_LoadGIF_RW"); 341 lib.bindSymbol(cast(void**)&IMG_LoadJPG_RW,"IMG_LoadJPG_RW"); 342 lib.bindSymbol(cast(void**)&IMG_LoadLBM_RW,"IMG_LoadLBM_RW"); 343 lib.bindSymbol(cast(void**)&IMG_LoadPCX_RW,"IMG_LoadPCX_RW"); 344 lib.bindSymbol(cast(void**)&IMG_LoadPNG_RW,"IMG_LoadPNG_RW"); 345 lib.bindSymbol(cast(void**)&IMG_LoadPNM_RW,"IMG_LoadPNM_RW"); 346 lib.bindSymbol(cast(void**)&IMG_LoadTGA_RW,"IMG_LoadTGA_RW"); 347 lib.bindSymbol(cast(void**)&IMG_LoadTIF_RW,"IMG_LoadTIF_RW"); 348 lib.bindSymbol(cast(void**)&IMG_LoadXCF_RW,"IMG_LoadXCF_RW"); 349 lib.bindSymbol(cast(void**)&IMG_LoadXPM_RW,"IMG_LoadXPM_RW"); 350 lib.bindSymbol(cast(void**)&IMG_LoadXV_RW,"IMG_LoadXV_RW"); 351 lib.bindSymbol(cast(void**)&IMG_isXV,"IMG_isXV"); 352 lib.bindSymbol(cast(void**)&IMG_LoadWEBP_RW,"IMG_LoadWEBP_RW"); 353 lib.bindSymbol(cast(void**)&IMG_SavePNG,"IMG_SavePNG"); 354 lib.bindSymbol(cast(void**)&IMG_SavePNG_RW,"IMG_SavePNG_RW"); 355 356 if(errorCount() != errCount) return SDLImageSupport.badLibrary; 357 else loadedVersion = (sdlImageSupport >= SDLImageSupport.sdlImage201) ? SDLImageSupport.sdlImage201 : SDLImageSupport.sdlImage200; 358 359 static if(sdlImageSupport >= SDLImageSupport.sdlImage202) { 360 lib.bindSymbol(cast(void**)&IMG_isSVG,"IMG_isSVG"); 361 lib.bindSymbol(cast(void**)&IMG_LoadSVG,"IMG_LoadSVG_RW"); 362 lib.bindSymbol(cast(void**)&IMG_SaveJPG,"IMG_SaveJPG"); 363 lib.bindSymbol(cast(void**)&IMG_SaveJPG_RW,"IMG_SaveJPG_RW"); 364 365 if(errorCount() != errCount) return SDLImageSupport.badLibrary; 366 else { 367 loadedVersion = (sdlImageSupport >= SDLImageSupport.sdlImage205) ? SDLImageSupport.sdlImage205 : sdlImageSupport; 368 } 369 } 370 371 return loadedVersion; 372 } 373 }