Skip to content

Commit 5620115

Browse files
committed
Added IMG_Save() and IMG_SaveTyped_IO()
1 parent c1fbaec commit 5620115

File tree

4 files changed

+214
-14
lines changed

4 files changed

+214
-14
lines changed

examples/showimage.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -176,20 +176,7 @@ int main(int argc, char *argv[])
176176
if (saveFile) {
177177
SDL_Surface *surface = IMG_Load(argv[i]);
178178
if (surface) {
179-
const char *ext = SDL_strrchr(saveFile, '.');
180-
bool saved = false;
181-
if (ext && SDL_strcasecmp(ext, ".avif") == 0) {
182-
saved = IMG_SaveAVIF(surface, saveFile, 90);
183-
} else if (ext && SDL_strcasecmp(ext, ".bmp") == 0) {
184-
saved = IMG_SaveBMP(surface, saveFile);
185-
} else if (ext && SDL_strcasecmp(ext, ".jpg") == 0) {
186-
saved = IMG_SaveJPG(surface, saveFile, 90);
187-
} else if (ext && SDL_strcasecmp(ext, ".png") == 0) {
188-
saved = IMG_SavePNG(surface, saveFile);
189-
} else {
190-
SDL_SetError("Unknown save file type");
191-
}
192-
if (!saved) {
179+
if (!IMG_Save(surface, saveFile)) {
193180
SDL_Log("Couldn't save %s: %s\n", saveFile, SDL_GetError());
194181
result = 3;
195182
}

include/SDL3_image/SDL_image.h

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,6 +1848,63 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL IMG_ReadXPMFromArray(char **xpm);
18481848
*/
18491849
extern SDL_DECLSPEC SDL_Surface * SDLCALL IMG_ReadXPMFromArrayToRGB888(char **xpm);
18501850

1851+
/**
1852+
* Save an SDL_Surface into an image file.
1853+
*
1854+
* If the file already exists, it will be overwritten.
1855+
*
1856+
* For formats that accept a quality, a default quality of 75 will be used.
1857+
*
1858+
* \param surface the SDL surface to save.
1859+
* \param file path on the filesystem to write new file to.
1860+
* \returns true on success or false on failure; call SDL_GetError() for more
1861+
* information.
1862+
*
1863+
* \since This function is available since SDL_image 3.0.0.
1864+
*
1865+
* \sa IMG_SaveTyped_IO
1866+
* \sa IMG_SaveAVIF
1867+
* \sa IMG_SaveBMP
1868+
* \sa IMG_SaveGIF
1869+
* \sa IMG_SaveJPG
1870+
* \sa IMG_SavePNG
1871+
* \sa IMG_SaveTGA
1872+
* \sa IMG_SaveWEBP
1873+
*/
1874+
extern SDL_DECLSPEC bool SDLCALL IMG_Save(SDL_Surface *surface, const char *file);
1875+
1876+
/**
1877+
* Save an SDL_Surface into formatted image data, via an SDL_IOStream.
1878+
*
1879+
* If you just want to save to a filename, you can use IMG_Save() instead.
1880+
*
1881+
* If `closeio` is true, `dst` will be closed before returning, whether this
1882+
* function succeeds or not.
1883+
*
1884+
* For formats that accept a quality, a default quality of 75 will be used.
1885+
*
1886+
* \param surface the SDL surface to save.
1887+
* \param dst the SDL_IOStream to save the image data to.
1888+
* \param closeio true to close/free the SDL_IOStream before returning, false
1889+
* to leave it open.
1890+
* \param type a filename extension that represent this data ("BMP", "GIF",
1891+
* "PNG", etc).
1892+
* \returns true on success or false on failure; call SDL_GetError() for more
1893+
* information.
1894+
*
1895+
* \since This function is available since SDL_image 3.0.0.
1896+
*
1897+
* \sa IMG_Save
1898+
* \sa IMG_SaveAVIF_IO
1899+
* \sa IMG_SaveBMP_IO
1900+
* \sa IMG_SaveGIF_IO
1901+
* \sa IMG_SaveJPG_IO
1902+
* \sa IMG_SavePNG_IO
1903+
* \sa IMG_SaveTGA_IO
1904+
* \sa IMG_SaveWEBP_IO
1905+
*/
1906+
extern SDL_DECLSPEC bool SDLCALL IMG_SaveTyped_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio, const char *type);
1907+
18511908
/**
18521909
* Save an SDL_Surface into a AVIF image file.
18531910
*
@@ -1863,6 +1920,12 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL IMG_ReadXPMFromArrayToRGB888(char **xp
18631920
* \since This function is available since SDL_image 3.0.0.
18641921
*
18651922
* \sa IMG_SaveAVIF_IO
1923+
* \sa IMG_SaveBMP
1924+
* \sa IMG_SaveGIF
1925+
* \sa IMG_SaveJPG
1926+
* \sa IMG_SavePNG
1927+
* \sa IMG_SaveTGA
1928+
* \sa IMG_SaveWEBP
18661929
*/
18671930
extern SDL_DECLSPEC bool SDLCALL IMG_SaveAVIF(SDL_Surface *surface, const char *file, int quality);
18681931

@@ -1886,6 +1949,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveAVIF(SDL_Surface *surface, const char *
18861949
* \since This function is available since SDL_image 3.0.0.
18871950
*
18881951
* \sa IMG_SaveAVIF
1952+
* \sa IMG_SaveBMP_IO
1953+
* \sa IMG_SaveGIF_IO
1954+
* \sa IMG_SaveJPG_IO
1955+
* \sa IMG_SavePNG_IO
1956+
* \sa IMG_SaveTGA_IO
1957+
* \sa IMG_SaveWEBP_IO
18891958
*/
18901959
extern SDL_DECLSPEC bool SDLCALL IMG_SaveAVIF_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio, int quality);
18911960

@@ -1902,6 +1971,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveAVIF_IO(SDL_Surface *surface, SDL_IOStr
19021971
* \since This function is available since SDL_image 3.4.0.
19031972
*
19041973
* \sa IMG_SaveBMP_IO
1974+
* \sa IMG_SaveAVIF
1975+
* \sa IMG_SaveGIF
1976+
* \sa IMG_SaveJPG
1977+
* \sa IMG_SavePNG
1978+
* \sa IMG_SaveTGA
1979+
* \sa IMG_SaveWEBP
19051980
*/
19061981
extern SDL_DECLSPEC bool SDLCALL IMG_SaveBMP(SDL_Surface *surface, const char *file);
19071982

@@ -1923,6 +1998,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveBMP(SDL_Surface *surface, const char *f
19231998
* \since This function is available since SDL_image 3.4.0.
19241999
*
19252000
* \sa IMG_SaveBMP
2001+
* \sa IMG_SaveAVIF_IO
2002+
* \sa IMG_SaveGIF_IO
2003+
* \sa IMG_SaveJPG_IO
2004+
* \sa IMG_SavePNG_IO
2005+
* \sa IMG_SaveTGA_IO
2006+
* \sa IMG_SaveWEBP_IO
19262007
*/
19272008
extern SDL_DECLSPEC bool SDLCALL IMG_SaveBMP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio);
19282009

@@ -1939,6 +2020,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveBMP_IO(SDL_Surface *surface, SDL_IOStre
19392020
* \since This function is available since SDL_image 3.4.0.
19402021
*
19412022
* \sa IMG_SaveGIF_IO
2023+
* \sa IMG_SaveAVIF
2024+
* \sa IMG_SaveBMP
2025+
* \sa IMG_SaveJPG
2026+
* \sa IMG_SavePNG
2027+
* \sa IMG_SaveTGA
2028+
* \sa IMG_SaveWEBP
19422029
*/
19432030
extern SDL_DECLSPEC bool SDLCALL IMG_SaveGIF(SDL_Surface *surface, const char *file);
19442031

@@ -1960,6 +2047,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveGIF(SDL_Surface *surface, const char *f
19602047
* \since This function is available since SDL_image 3.4.0.
19612048
*
19622049
* \sa IMG_SaveGIF
2050+
* \sa IMG_SaveAVIF_IO
2051+
* \sa IMG_SaveBMP_IO
2052+
* \sa IMG_SaveJPG_IO
2053+
* \sa IMG_SavePNG_IO
2054+
* \sa IMG_SaveTGA_IO
2055+
* \sa IMG_SaveWEBP_IO
19632056
*/
19642057
extern SDL_DECLSPEC bool SDLCALL IMG_SaveGIF_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio);
19652058

@@ -1978,6 +2071,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveGIF_IO(SDL_Surface *surface, SDL_IOStre
19782071
* \since This function is available since SDL_image 3.0.0.
19792072
*
19802073
* \sa IMG_SaveJPG_IO
2074+
* \sa IMG_SaveAVIF
2075+
* \sa IMG_SaveBMP
2076+
* \sa IMG_SaveGIF
2077+
* \sa IMG_SavePNG
2078+
* \sa IMG_SaveTGA
2079+
* \sa IMG_SaveWEBP
19812080
*/
19822081
extern SDL_DECLSPEC bool SDLCALL IMG_SaveJPG(SDL_Surface *surface, const char *file, int quality);
19832082

@@ -2001,6 +2100,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveJPG(SDL_Surface *surface, const char *f
20012100
* \since This function is available since SDL_image 3.0.0.
20022101
*
20032102
* \sa IMG_SaveJPG
2103+
* \sa IMG_SaveAVIF_IO
2104+
* \sa IMG_SaveBMP_IO
2105+
* \sa IMG_SaveGIF_IO
2106+
* \sa IMG_SavePNG_IO
2107+
* \sa IMG_SaveTGA_IO
2108+
* \sa IMG_SaveWEBP_IO
20042109
*/
20052110
extern SDL_DECLSPEC bool SDLCALL IMG_SaveJPG_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio, int quality);
20062111

@@ -2017,6 +2122,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveJPG_IO(SDL_Surface *surface, SDL_IOStre
20172122
* \since This function is available since SDL_image 3.0.0.
20182123
*
20192124
* \sa IMG_SavePNG_IO
2125+
* \sa IMG_SaveAVIF
2126+
* \sa IMG_SaveBMP
2127+
* \sa IMG_SaveGIF
2128+
* \sa IMG_SaveJPG
2129+
* \sa IMG_SaveTGA
2130+
* \sa IMG_SaveWEBP
20202131
*/
20212132
extern SDL_DECLSPEC bool SDLCALL IMG_SavePNG(SDL_Surface *surface, const char *file);
20222133

@@ -2038,6 +2149,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SavePNG(SDL_Surface *surface, const char *f
20382149
* \since This function is available since SDL_image 3.0.0.
20392150
*
20402151
* \sa IMG_SavePNG
2152+
* \sa IMG_SaveAVIF_IO
2153+
* \sa IMG_SaveBMP_IO
2154+
* \sa IMG_SaveGIF_IO
2155+
* \sa IMG_SaveJPG_IO
2156+
* \sa IMG_SaveTGA_IO
2157+
* \sa IMG_SaveWEBP_IO
20412158
*/
20422159
extern SDL_DECLSPEC bool SDLCALL IMG_SavePNG_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio);
20432160

@@ -2054,6 +2171,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SavePNG_IO(SDL_Surface *surface, SDL_IOStre
20542171
* \since This function is available since SDL_image 3.4.0.
20552172
*
20562173
* \sa IMG_SaveTGA_IO
2174+
* \sa IMG_SaveAVIF
2175+
* \sa IMG_SaveBMP
2176+
* \sa IMG_SaveGIF
2177+
* \sa IMG_SaveJPG
2178+
* \sa IMG_SavePNG
2179+
* \sa IMG_SaveWEBP
20572180
*/
20582181
extern SDL_DECLSPEC bool SDLCALL IMG_SaveTGA(SDL_Surface *surface, const char *file);
20592182

@@ -2075,6 +2198,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveTGA(SDL_Surface *surface, const char *f
20752198
* \since This function is available since SDL_image 3.4.0.
20762199
*
20772200
* \sa IMG_SaveTGA
2201+
* \sa IMG_SaveAVIF_IO
2202+
* \sa IMG_SaveBMP_IO
2203+
* \sa IMG_SaveGIF_IO
2204+
* \sa IMG_SaveJPG_IO
2205+
* \sa IMG_SavePNG_IO
2206+
* \sa IMG_SaveWEBP_IO
20782207
*/
20792208
extern SDL_DECLSPEC bool SDLCALL IMG_SaveTGA_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio);
20802209

@@ -2095,6 +2224,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveTGA_IO(SDL_Surface *surface, SDL_IOStre
20952224
* \since This function is available since SDL_image 3.4.0.
20962225
*
20972226
* \sa IMG_SaveWEBP_IO
2227+
* \sa IMG_SaveAVIF
2228+
* \sa IMG_SaveBMP
2229+
* \sa IMG_SaveGIF
2230+
* \sa IMG_SaveJPG
2231+
* \sa IMG_SavePNG
2232+
* \sa IMG_SaveTGA
20982233
*/
20992234
extern SDL_DECLSPEC bool SDLCALL IMG_SaveWEBP(SDL_Surface *surface, const char *file, float quality);
21002235

@@ -2120,6 +2255,12 @@ extern SDL_DECLSPEC bool SDLCALL IMG_SaveWEBP(SDL_Surface *surface, const char *
21202255
* \since This function is available since SDL_image 3.4.0.
21212256
*
21222257
* \sa IMG_SaveWEBP
2258+
* \sa IMG_SaveAVIF_IO
2259+
* \sa IMG_SaveBMP_IO
2260+
* \sa IMG_SaveGIF_IO
2261+
* \sa IMG_SaveJPG_IO
2262+
* \sa IMG_SavePNG_IO
2263+
* \sa IMG_SaveTGA_IO
21232264
*/
21242265
extern SDL_DECLSPEC bool SDLCALL IMG_SaveWEBP_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio, float quality);
21252266

src/IMG.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,73 @@ void IMG_FreeAnimation(IMG_Animation *anim)
340340
}
341341
}
342342

343+
bool IMG_Save(SDL_Surface *surface, const char *file)
344+
{
345+
if (!surface) {
346+
return SDL_InvalidParamError("surface");
347+
}
348+
349+
if (!file || !*file) {
350+
return SDL_InvalidParamError("file");
351+
}
352+
353+
const char *type = SDL_strrchr(file, '.');
354+
if (type) {
355+
// Skip the '.' in the file extension
356+
++type;
357+
} else {
358+
return SDL_SetError("Couldn't determine file type");
359+
}
360+
361+
SDL_IOStream *dst = SDL_IOFromFile(file, "wb");
362+
if (!dst) {
363+
return false;
364+
}
365+
366+
return IMG_SaveTyped_IO(surface, dst, true, type);
367+
}
368+
369+
bool IMG_SaveTyped_IO(SDL_Surface *surface, SDL_IOStream *dst, bool closeio, const char *type)
370+
{
371+
bool result = false;
372+
373+
if (!surface) {
374+
SDL_InvalidParamError("surface");
375+
goto done;
376+
}
377+
378+
if (!dst) {
379+
SDL_InvalidParamError("dst");
380+
goto done;
381+
}
382+
383+
if (!type || !*type) {
384+
SDL_InvalidParamError("type");
385+
goto done;
386+
}
387+
388+
if (SDL_strcasecmp(type, "avif") == 0) {
389+
result = IMG_SaveAVIF_IO(surface, dst, false, 75);
390+
} else if (SDL_strcasecmp(type, "bmp") == 0) {
391+
result = IMG_SaveBMP_IO(surface, dst, false);
392+
} else if (SDL_strcasecmp(type, "gif") == 0) {
393+
result = IMG_SaveGIF_IO(surface, dst, false);
394+
} else if (SDL_strcasecmp(type, "jpg") == 0 ||
395+
SDL_strcasecmp(type, "jpeg") == 0) {
396+
result = IMG_SaveJPG_IO(surface, dst, false, 75);
397+
} else if (SDL_strcasecmp(type, "png") == 0) {
398+
result = IMG_SavePNG_IO(surface, dst, false);
399+
} else if (SDL_strcasecmp(type, "tga") == 0) {
400+
result = IMG_SaveTGA_IO(surface, dst, false);
401+
} else if (SDL_strcasecmp(type, "webp") == 0) {
402+
result = IMG_SaveWEBP_IO(surface, dst, false, 75.0f);
403+
} else {
404+
result = SDL_SetError("Unsupported image format");
405+
}
406+
407+
done:
408+
if (dst && closeio) {
409+
SDL_CloseIO(dst);
410+
}
411+
return result;
412+
}

src/SDL_image.sym

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,7 @@ SDL3_image_0.0.0 {
7272
IMG_LoadAVIFAnimation_IO;
7373
IMG_SaveBMP;
7474
IMG_SaveBMP_IO;
75+
IMG_Save;
76+
IMG_SaveTyped_IO;
7577
local: *;
7678
};

0 commit comments

Comments
 (0)