1 /+
2 +            Copyright 2022 – 2023 Aya Partridge
3 +          Copyright 2018 - 2022 Michael D. Parker
4 + Distributed under the Boost Software License, Version 1.0.
5 +     (See accompanying file LICENSE_1_0.txt or copy at
6 +           http://www.boost.org/LICENSE_1_0.txt)
7 +/
8 module sdl_image;
9 
10 import bindbc.sdl.config;
11 static if(bindSDLImage):
12 import bindbc.sdl.codegen;
13 
14 import sdl.error: SDL_GetError, SDL_SetError;
15 import sdl.render: SDL_Renderer, SDL_Texture;
16 import sdl.rwops: SDL_RWops;
17 import sdl.surface: SDL_Surface;
18 import sdl.version_: SDL_version;
19 
20 enum SDLImageSupport: SDL_version{
21 	noLibrary   = SDL_version(0,0,0),
22 	badLibrary  = SDL_version(0,0,255),
23 	v2_0_0      = SDL_version(2,0,0),
24 	v2_0_1      = SDL_version(2,0,1),
25 	v2_0_2      = SDL_version(2,0,2),
26 	v2_0_3      = SDL_version(2,0,3),
27 	v2_0_4      = SDL_version(2,0,4),
28 	v2_0_5      = SDL_version(2,0,5),
29 	v2_6        = SDL_version(2,6,0),
30 	
31 	deprecated("Please use `v2_0_0` instead") sdlImage200 = SDL_version(2,0,0),
32 	deprecated("Please use `v2_0_1` instead") sdlImage201 = SDL_version(2,0,1),
33 	deprecated("Please use `v2_0_2` instead") sdlImage202 = SDL_version(2,0,2),
34 	deprecated("Please use `v2_0_3` instead") sdlImage203 = SDL_version(2,0,3),
35 	deprecated("Please use `v2_0_4` instead") sdlImage204 = SDL_version(2,0,4),
36 	deprecated("Please use `v2_0_5` instead") sdlImage205 = SDL_version(2,0,5),
37 }
38 
39 enum sdlImageSupport = (){
40 	version(SDL_Image_2_6)      return SDLImageSupport.v2_6;
41 	else version(SDL_Image_205) return SDLImageSupport.v2_0_5;
42 	else version(SDL_Image_204) return SDLImageSupport.v2_0_4;
43 	else version(SDL_Image_203) return SDLImageSupport.v2_0_3;
44 	else version(SDL_Image_202) return SDLImageSupport.v2_0_2;
45 	else version(SDL_Image_201) return SDLImageSupport.v2_0_1;
46 	else                        return SDLImageSupport.v2_0_0;
47 }();
48 
49 enum SDL_IMAGE_MAJOR_VERSION = sdlImageSupport.major;
50 enum SDL_IMAGE_MINOR_VERSION = sdlImageSupport.minor;
51 enum SDL_IMAGE_PATCHLEVEL    = sdlImageSupport.patch;
52 
53 pragma(inline, true) void SDL_IMAGE_VERSION(SDL_version* X) @nogc nothrow pure @safe{
54 	X.major = SDL_IMAGE_MAJOR_VERSION;
55 	X.minor = SDL_IMAGE_MINOR_VERSION;
56 	X.patch = SDL_IMAGE_PATCHLEVEL;
57 }
58 
59 deprecated("Please use SDL_IMAGE_VERSION_ATLEAST or SDL_IMAGE_VERSION instead")
60 	enum SDL_IMAGE_COMPILEDVERSION = SDL_version(SDL_IMAGE_MAJOR_VERSION, SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL);
61 
62 pragma(inline, true) @nogc nothrow{
63 	bool SDL_IMAGE_VERSION_ATLEAST(ubyte X, ubyte Y, ubyte Z){ return SDL_version(SDL_IMAGE_MAJOR_VERSION, SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL) >= SDL_version(X, Y, Z); }
64 }
65 deprecated("Please use the non-template variant instead"){
66 	enum SDL_IMAGE_VERSION_ATLEAST(ubyte X, ubyte Y, ubyte Z) = SDL_version(SDL_IMAGE_MAJOR_VERSION, SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL) >= SDL_version(X, Y, Z);
67 }
68 
69 alias IMG_InitFlags = int;
70 enum: IMG_InitFlags{
71 	IMG_INIT_JPG   = 0x0000_0001,
72 	IMG_INIT_PNG   = 0x0000_0002,
73 	IMG_INIT_TIF   = 0x0000_0004,
74 	IMG_INIT_WEBP  = 0x0000_0008,
75 }
76 static if(sdlImageSupport >= SDLImageSupport.v2_6)
77 enum: IMG_InitFlags{
78 	IMG_INIT_JXL   = 0x0000_0010,
79 	IMG_INIT_AVIF  = 0x0000_0020,
80 }
81 
82 static if(sdlImageSupport >= SDLImageSupport.v2_6){
83 	struct IMG_Animation{
84 		int w, h;
85 		int count;
86 		SDL_Surface** frames;
87 		int* delays;
88 	}
89 }
90 
91 alias IMG_SetError = SDL_SetError;
92 
93 alias IMG_GetError = SDL_GetError;
94 
95 mixin(joinFnBinds((){
96 	string[][] ret;
97 	ret ~= makeFnBinds([
98 		[q{int}, q{IMG_Init}, q{int flags}],
99 		[q{int}, q{IMG_Quit}, q{}],
100 		[q{const(SDL_version)*}, q{IMG_Linked_Version}, q{}],
101 		[q{SDL_Surface*}, q{IMG_LoadTyped_RW}, q{SDL_RWops* src, int freesrc, const(char)* type}],
102 		[q{SDL_Surface*}, q{IMG_Load}, q{const(char)* file}],
103 		[q{SDL_Surface*}, q{IMG_Load_RW}, q{SDL_RWops* src, int freesrc}],
104 		
105 		[q{SDL_Texture*}, q{IMG_LoadTexture}, q{SDL_Renderer* renderer, const(char)* file}],
106 		[q{SDL_Texture*}, q{IMG_LoadTexture_RW}, q{SDL_Renderer* renderer, SDL_RWops* src, int freesrc}],
107 		[q{SDL_Texture*}, q{IMG_LoadTextureTyped_RW}, q{SDL_Renderer* renderer, SDL_RWops* src, int freesrc, const(char)* type}],
108 		
109 		[q{int}, q{IMG_isICO}, q{SDL_RWops* src}],
110 		[q{int}, q{IMG_isCUR}, q{SDL_RWops* src}],
111 		[q{int}, q{IMG_isBMP}, q{SDL_RWops* src}],
112 		[q{int}, q{IMG_isGIF}, q{SDL_RWops* src}],
113 		[q{int}, q{IMG_isJPG}, q{SDL_RWops* src}],
114 		[q{int}, q{IMG_isLBM}, q{SDL_RWops* src}],
115 		[q{int}, q{IMG_isPCX}, q{SDL_RWops* src}],
116 		[q{int}, q{IMG_isPNG}, q{SDL_RWops* src}],
117 		[q{int}, q{IMG_isPNM}, q{SDL_RWops* src}],
118 		[q{int}, q{IMG_isTIF}, q{SDL_RWops* src}],
119 		[q{int}, q{IMG_isXCF}, q{SDL_RWops* src}],
120 		[q{int}, q{IMG_isXPM}, q{SDL_RWops* src}],
121 		[q{int}, q{IMG_isXV}, q{SDL_RWops* src}],
122 		[q{int}, q{IMG_isWEBP}, q{SDL_RWops* src}],
123 		
124 		[q{SDL_Surface*}, q{IMG_LoadICO_RW}, q{SDL_RWops* src}],
125 		[q{SDL_Surface*}, q{IMG_LoadCUR_RW}, q{SDL_RWops* src}],
126 		[q{SDL_Surface*}, q{IMG_LoadBMP_RW}, q{SDL_RWops* src}],
127 		[q{SDL_Surface*}, q{IMG_LoadGIF_RW}, q{SDL_RWops* src}],
128 		[q{SDL_Surface*}, q{IMG_LoadJPG_RW}, q{SDL_RWops* src}],
129 		[q{SDL_Surface*}, q{IMG_LoadLBM_RW}, q{SDL_RWops* src}],
130 		[q{SDL_Surface*}, q{IMG_LoadPCX_RW}, q{SDL_RWops* src}],
131 		[q{SDL_Surface*}, q{IMG_LoadPNG_RW}, q{SDL_RWops* src}],
132 		[q{SDL_Surface*}, q{IMG_LoadPNM_RW}, q{SDL_RWops* src}],
133 		[q{SDL_Surface*}, q{IMG_LoadTGA_RW}, q{SDL_RWops* src}],
134 		[q{SDL_Surface*}, q{IMG_LoadTIF_RW}, q{SDL_RWops* src}],
135 		[q{SDL_Surface*}, q{IMG_LoadXCF_RW}, q{SDL_RWops* src}],
136 		[q{SDL_Surface*}, q{IMG_LoadXPM_RW}, q{SDL_RWops* src}],
137 		[q{SDL_Surface*}, q{IMG_LoadXV_RW}, q{SDL_RWops* src}],
138 		[q{SDL_Surface*}, q{IMG_LoadWEBP_RW}, q{SDL_RWops* src}],
139 		
140 		[q{SDL_Surface*}, q{IMG_ReadXPMFromArray}, q{char** xpm}],
141 		
142 		[q{int}, q{IMG_SavePNG}, q{SDL_Surface* surface, const(char)* file}],
143 		[q{int}, q{IMG_SavePNG_RW}, q{SDL_Surface* surface, SDL_RWops* dst, int freedst}],
144 	]);
145 	static if(sdlImageSupport >= SDLImageSupport.v2_0_2){
146 		ret ~= makeFnBinds([
147 			[q{int}, q{IMG_isSVG}, q{SDL_RWops* src}],
148 			[q{SDL_Surface*}, q{IMG_LoadSVG}, q{SDL_RWops* src}],
149 			[q{int}, q{IMG_SaveJPG}, q{SDL_Surface* surface, const(char)* file, int quality}],
150 			[q{int}, q{IMG_SaveJPG_RW}, q{SDL_Surface* surface, SDL_RWops* dst, int freedst, int quality}],
151 			[q{SDL_Surface*}, q{IMG_LoadSVG_RW}, q{SDL_RWops* src}],
152 		]);
153 	}
154 	static if(sdlImageSupport >= SDLImageSupport.v2_6){
155 		ret ~= makeFnBinds([
156 			[q{int}, q{IMG_isAVIF}, q{SDL_RWops* src}],
157 			[q{int}, q{IMG_isJXL}, q{SDL_RWops* src}],
158 			[q{int}, q{IMG_isQOI}, q{SDL_RWops* src}],
159 			
160 			[q{SDL_Surface*}, q{IMG_LoadAVIF_RW}, q{SDL_RWops* src}],
161 			[q{SDL_Surface*}, q{IMG_LoadJXL_RW}, q{SDL_RWops* src}],
162 			[q{SDL_Surface*}, q{IMG_LoadQOI_RW}, q{SDL_RWops* src}],
163 			
164 			[q{SDL_Surface*}, q{IMG_LoadSizedSVG_RW}, q{SDL_RWops* src, int width, int height}],
165 			[q{SDL_Surface*}, q{IMG_ReadXPMFromArrayToRGB888}, q{char** xpm}],
166 			[q{IMG_Animation*}, q{IMG_LoadAnimation}, q{const(char)* file}],
167 			[q{IMG_Animation*}, q{IMG_LoadAnimation_RW}, q{SDL_RWops* src, int freesrc}],
168 			[q{IMG_Animation*}, q{IMG_LoadAnimationTyped_RW}, q{SDL_RWops* src, int freesrc, const(char)* type}],
169 			[q{void}, q{IMG_FreeAnimation}, q{IMG_Animation* anim}],
170 			[q{IMG_Animation*}, q{IMG_LoadGIFAnimation_RW}, q{SDL_RWops* src}],
171 		]);
172 	}
173 	return ret;
174 }()));
175 
176 static if(!staticBinding):
177 import bindbc.loader;
178 
179 private{
180 	SharedLib lib;
181 	SDLImageSupport loadedVersion;
182 	enum libNamesCT = (){
183 		version(Windows){
184 			return [
185 				`SDL2_image.dll`,
186 			];
187 		}else version(OSX){
188 			return [
189 				`libSDL2_image.dylib`,
190 				`/opt/homebrew/lib/libSDL2_image.dylib`,
191 				`SDL2_image`,
192 				`/Library/Frameworks/SDL2_image.framework/SDL2_image`,
193 				`/System/Library/Frameworks/SDL2_image.framework/SDL2_image`,
194 			];
195 		}else version(Posix){
196 			return [
197 				`libSDL2_image.so`,
198 				`libSDL2_image-2.0.so`,
199 				`libSDL2_image-2.0.so.0`,
200 			];
201 		}else static assert(0, "BindBC-SDL_image does not have library search paths set up for this platform");
202 	}();
203 }
204 
205 @nogc nothrow:
206 deprecated("Please use `IMG_Linked_Version` instead")
207 	SDLImageSupport loadedSDLImageVersion(){ return loadedVersion; }
208 
209 mixin(bindbc.sdl.codegen.makeDynloadFns("Image", [__MODULE__]));