1 /+
2 +            Copyright 2022 – 2024 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 
19 enum SDLImageSupport: SDL_version{
20 	noLibrary   = SDL_version(0,0,0),
21 	badLibrary  = SDL_version(0,0,255),
22 	v2_0_0      = SDL_version(2,0,0),
23 	v2_0_1      = SDL_version(2,0,1),
24 	v2_0_2      = SDL_version(2,0,2),
25 	v2_0_3      = SDL_version(2,0,3),
26 	v2_0_4      = SDL_version(2,0,4),
27 	v2_0_5      = SDL_version(2,0,5),
28 	v2_6        = SDL_version(2,6,0),
29 	v2_8        = SDL_version(2,8,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_8)      return SDLImageSupport.v2_8;
41 	else version(SDL_Image_2_6) return SDLImageSupport.v2_6;
42 	else version(SDL_Image_205) return SDLImageSupport.v2_0_5;
43 	else version(SDL_Image_204) return SDLImageSupport.v2_0_4;
44 	else version(SDL_Image_203) return SDLImageSupport.v2_0_3;
45 	else version(SDL_Image_202) return SDLImageSupport.v2_0_2;
46 	else version(SDL_Image_201) return SDLImageSupport.v2_0_1;
47 	else                        return SDLImageSupport.v2_0_0;
48 }();
49 
50 enum SDL_IMAGE_MAJOR_VERSION = sdlImageSupport.major;
51 enum SDL_IMAGE_MINOR_VERSION = sdlImageSupport.minor;
52 enum SDL_IMAGE_PATCHLEVEL    = sdlImageSupport.patch;
53 
54 pragma(inline, true) void SDL_IMAGE_VERSION(SDL_version* x) nothrow @nogc pure @safe{
55 	x.major = SDL_IMAGE_MAJOR_VERSION;
56 	x.minor = SDL_IMAGE_MINOR_VERSION;
57 	x.patch = SDL_IMAGE_PATCHLEVEL;
58 }
59 
60 deprecated("Please use SDL_IMAGE_VERSION_ATLEAST or SDL_IMAGE_VERSION instead")
61 	enum SDL_IMAGE_COMPILEDVERSION = SDL_version(SDL_IMAGE_MAJOR_VERSION, SDL_IMAGE_MINOR_VERSION, SDL_IMAGE_PATCHLEVEL);
62 
63 pragma(inline, true) nothrow @nogc{
64 	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); }
65 }
66 deprecated("Please use the non-template variant instead"){
67 	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);
68 }
69 
70 alias IMG_InitFlags = int;
71 enum: IMG_InitFlags{
72 	IMG_INIT_JPG   = 0x0000_0001,
73 	IMG_INIT_PNG   = 0x0000_0002,
74 	IMG_INIT_TIF   = 0x0000_0004,
75 	IMG_INIT_WEBP  = 0x0000_0008,
76 }
77 static if(sdlImageSupport >= SDLImageSupport.v2_6)
78 enum: IMG_InitFlags{
79 	IMG_INIT_JXL   = 0x0000_0010,
80 	IMG_INIT_AVIF  = 0x0000_0020,
81 }
82 
83 static if(sdlImageSupport >= SDLImageSupport.v2_6){
84 	struct IMG_Animation{
85 		int w, h;
86 		int count;
87 		SDL_Surface** frames;
88 		int* delays;
89 	}
90 }
91 
92 alias IMG_SetError = SDL_SetError;
93 alias IMG_GetError = SDL_GetError;
94 
95 mixin(joinFnBinds((){
96 	FnBind[] ret = [
97 		{q{int}, q{IMG_Init}, q{int flags}},
98 		{q{int}, q{IMG_Quit}, q{}},
99 		{q{const(SDL_version)*}, q{IMG_Linked_Version}, q{}},
100 		{q{SDL_Surface*}, q{IMG_LoadTyped_RW}, q{SDL_RWops* src, int freeSrc, const(char)* type}},
101 		{q{SDL_Surface*}, q{IMG_Load}, q{const(char)* file}},
102 		{q{SDL_Surface*}, q{IMG_Load_RW}, q{SDL_RWops* src, int freeSrc}},
103 		
104 		{q{SDL_Texture*}, q{IMG_LoadTexture}, q{SDL_Renderer* renderer, const(char)* file}},
105 		{q{SDL_Texture*}, q{IMG_LoadTexture_RW}, q{SDL_Renderer* renderer, SDL_RWops* src, int freeSrc}},
106 		{q{SDL_Texture*}, q{IMG_LoadTextureTyped_RW}, q{SDL_Renderer* renderer, SDL_RWops* src, int freeSrc, const(char)* type}},
107 		
108 		{q{int}, q{IMG_isICO}, q{SDL_RWops* src}},
109 		{q{int}, q{IMG_isCUR}, q{SDL_RWops* src}},
110 		{q{int}, q{IMG_isBMP}, q{SDL_RWops* src}},
111 		{q{int}, q{IMG_isGIF}, q{SDL_RWops* src}},
112 		{q{int}, q{IMG_isJPG}, q{SDL_RWops* src}},
113 		{q{int}, q{IMG_isLBM}, q{SDL_RWops* src}},
114 		{q{int}, q{IMG_isPCX}, q{SDL_RWops* src}},
115 		{q{int}, q{IMG_isPNG}, q{SDL_RWops* src}},
116 		{q{int}, q{IMG_isPNM}, q{SDL_RWops* src}},
117 		{q{int}, q{IMG_isTIF}, q{SDL_RWops* src}},
118 		{q{int}, q{IMG_isXCF}, q{SDL_RWops* src}},
119 		{q{int}, q{IMG_isXPM}, q{SDL_RWops* src}},
120 		{q{int}, q{IMG_isXV}, q{SDL_RWops* src}},
121 		{q{int}, q{IMG_isWEBP}, q{SDL_RWops* src}},
122 		
123 		{q{SDL_Surface*}, q{IMG_LoadICO_RW}, q{SDL_RWops* src}},
124 		{q{SDL_Surface*}, q{IMG_LoadCUR_RW}, q{SDL_RWops* src}},
125 		{q{SDL_Surface*}, q{IMG_LoadBMP_RW}, q{SDL_RWops* src}},
126 		{q{SDL_Surface*}, q{IMG_LoadGIF_RW}, q{SDL_RWops* src}},
127 		{q{SDL_Surface*}, q{IMG_LoadJPG_RW}, q{SDL_RWops* src}},
128 		{q{SDL_Surface*}, q{IMG_LoadLBM_RW}, q{SDL_RWops* src}},
129 		{q{SDL_Surface*}, q{IMG_LoadPCX_RW}, q{SDL_RWops* src}},
130 		{q{SDL_Surface*}, q{IMG_LoadPNG_RW}, q{SDL_RWops* src}},
131 		{q{SDL_Surface*}, q{IMG_LoadPNM_RW}, q{SDL_RWops* src}},
132 		{q{SDL_Surface*}, q{IMG_LoadTGA_RW}, q{SDL_RWops* src}},
133 		{q{SDL_Surface*}, q{IMG_LoadTIF_RW}, q{SDL_RWops* src}},
134 		{q{SDL_Surface*}, q{IMG_LoadXCF_RW}, q{SDL_RWops* src}},
135 		{q{SDL_Surface*}, q{IMG_LoadXPM_RW}, q{SDL_RWops* src}},
136 		{q{SDL_Surface*}, q{IMG_LoadXV_RW}, q{SDL_RWops* src}},
137 		{q{SDL_Surface*}, q{IMG_LoadWEBP_RW}, q{SDL_RWops* src}},
138 		
139 		{q{SDL_Surface*}, q{IMG_ReadXPMFromArray}, q{char** xpm}},
140 		
141 		{q{int}, q{IMG_SavePNG}, q{SDL_Surface* surface, const(char)* file}},
142 		{q{int}, q{IMG_SavePNG_RW}, q{SDL_Surface* surface, SDL_RWops* dst, int freeDst}},
143 	];
144 	if(sdlImageSupport >= SDLImageSupport.v2_0_2){
145 		FnBind[] add = [
146 			{q{int}, q{IMG_isSVG}, q{SDL_RWops* src}},
147 			{q{SDL_Surface*}, q{IMG_LoadSVG_RW}, q{SDL_RWops* src}},
148 			{q{int}, q{IMG_SaveJPG}, q{SDL_Surface* surface, const(char)* file, int quality}},
149 			{q{int}, q{IMG_SaveJPG_RW}, q{SDL_Surface* surface, SDL_RWops* dst, int freeDst, int quality}},
150 		];
151 		ret ~= add;
152 	}
153 	if(sdlImageSupport >= SDLImageSupport.v2_6){
154 		FnBind[] add = [
155 			{q{int}, q{IMG_isAVIF}, q{SDL_RWops* src}},
156 			{q{int}, q{IMG_isJXL}, q{SDL_RWops* src}},
157 			{q{int}, q{IMG_isQOI}, q{SDL_RWops* src}},
158 			
159 			{q{SDL_Surface*}, q{IMG_LoadAVIF_RW}, q{SDL_RWops* src}},
160 			{q{SDL_Surface*}, q{IMG_LoadJXL_RW}, q{SDL_RWops* src}},
161 			{q{SDL_Surface*}, q{IMG_LoadQOI_RW}, q{SDL_RWops* src}},
162 			
163 			{q{SDL_Surface*}, q{IMG_LoadSizedSVG_RW}, q{SDL_RWops* src, int width, int height}},
164 			{q{SDL_Surface*}, q{IMG_ReadXPMFromArrayToRGB888}, q{char** xpm}},
165 			{q{IMG_Animation*}, q{IMG_LoadAnimation}, q{const(char)* file}},
166 			{q{IMG_Animation*}, q{IMG_LoadAnimation_RW}, q{SDL_RWops* src, int freeSrc}},
167 			{q{IMG_Animation*}, q{IMG_LoadAnimationTyped_RW}, q{SDL_RWops* src, int freeSrc, const(char)* type}},
168 			{q{void}, q{IMG_FreeAnimation}, q{IMG_Animation* anim}},
169 			{q{IMG_Animation*}, q{IMG_LoadGIFAnimation_RW}, q{SDL_RWops* src}},
170 		];
171 		ret ~= add;
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 nothrow @nogc:
206 deprecated("Please use `IMG_Linked_Version` instead")
207 	SDLImageSupport loadedSDLImageVersion(){ return loadedVersion; }
208 
209 mixin(bindbc.sdl.codegen.makeDynloadFns("Image", [__MODULE__]));