mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-30 21:37:43 +08:00
Add SDL_LoadSurface and SDL_LoadSurface_IO (#14374)
This commit is contained in:
@@ -502,6 +502,46 @@ extern SDL_DECLSPEC bool SDLCALL SDL_LockSurface(SDL_Surface *surface);
|
|||||||
*/
|
*/
|
||||||
extern SDL_DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface);
|
extern SDL_DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a BMP or PNG image from a seekable SDL data stream.
|
||||||
|
*
|
||||||
|
* The new surface should be freed with SDL_DestroySurface(). Not doing so
|
||||||
|
* will result in a memory leak.
|
||||||
|
*
|
||||||
|
* \param src the data stream for the surface.
|
||||||
|
* \param closeio if true, calls SDL_CloseIO() on `src` before returning, even
|
||||||
|
* in the case of an error.
|
||||||
|
* \returns a pointer to a new SDL_Surface structure or NULL on failure; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.4.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_DestroySurface
|
||||||
|
* \sa SDL_LoadSurface
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_LoadSurface_IO(SDL_IOStream *src, bool closeio);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a BMP or PNG image from a file.
|
||||||
|
*
|
||||||
|
* The new surface should be freed with SDL_DestroySurface(). Not doing so
|
||||||
|
* will result in a memory leak.
|
||||||
|
*
|
||||||
|
* \param file the file to load.
|
||||||
|
* \returns a pointer to a new SDL_Surface structure or NULL on failure; call
|
||||||
|
* SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.4.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_DestroySurface
|
||||||
|
* \sa SDL_LoadSurface_IO
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC SDL_Surface * SDLCALL SDL_LoadSurface(const char *file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a BMP image from a seekable SDL data stream.
|
* Load a BMP image from a seekable SDL data stream.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1268,6 +1268,8 @@ SDL3_0.0.0 {
|
|||||||
SDL_GetPenDeviceType;
|
SDL_GetPenDeviceType;
|
||||||
SDL_CreateAnimatedCursor;
|
SDL_CreateAnimatedCursor;
|
||||||
SDL_RotateSurface;
|
SDL_RotateSurface;
|
||||||
|
SDL_LoadSurface_IO;
|
||||||
|
SDL_LoadSurface;
|
||||||
# extra symbols go here (don't modify this line)
|
# extra symbols go here (don't modify this line)
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1294,3 +1294,5 @@
|
|||||||
#define SDL_GetPenDeviceType SDL_GetPenDeviceType_REAL
|
#define SDL_GetPenDeviceType SDL_GetPenDeviceType_REAL
|
||||||
#define SDL_CreateAnimatedCursor SDL_CreateAnimatedCursor_REAL
|
#define SDL_CreateAnimatedCursor SDL_CreateAnimatedCursor_REAL
|
||||||
#define SDL_RotateSurface SDL_RotateSurface_REAL
|
#define SDL_RotateSurface SDL_RotateSurface_REAL
|
||||||
|
#define SDL_LoadSurface_IO SDL_LoadSurface_IO_REAL
|
||||||
|
#define SDL_LoadSurface SDL_LoadSurface_REAL
|
||||||
|
|||||||
@@ -1302,3 +1302,5 @@ SDL_DYNAPI_PROC(int,SDL_GetSystemPageSize,(void),(),return)
|
|||||||
SDL_DYNAPI_PROC(SDL_PenDeviceType,SDL_GetPenDeviceType,(SDL_PenID a),(a),return)
|
SDL_DYNAPI_PROC(SDL_PenDeviceType,SDL_GetPenDeviceType,(SDL_PenID a),(a),return)
|
||||||
SDL_DYNAPI_PROC(SDL_Cursor*,SDL_CreateAnimatedCursor,(SDL_CursorFrameInfo *a,int b,int c,int d),(a,b,c,d),return)
|
SDL_DYNAPI_PROC(SDL_Cursor*,SDL_CreateAnimatedCursor,(SDL_CursorFrameInfo *a,int b,int c,int d),(a,b,c,d),return)
|
||||||
SDL_DYNAPI_PROC(SDL_Surface*,SDL_RotateSurface,(SDL_Surface *a,float b),(a,b),return)
|
SDL_DYNAPI_PROC(SDL_Surface*,SDL_RotateSurface,(SDL_Surface *a,float b),(a,b),return)
|
||||||
|
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadSurface_IO,(SDL_IOStream *a,bool b),(a,b),return)
|
||||||
|
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadSurface,(const char *a),(a),return)
|
||||||
|
|||||||
+24
-6
@@ -177,6 +177,26 @@ static void CorrectAlphaChannel(SDL_Surface *surface)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SDL_IsBMP(SDL_IOStream *src)
|
||||||
|
{
|
||||||
|
Sint64 start;
|
||||||
|
Uint8 magic[2];
|
||||||
|
bool is_BMP;
|
||||||
|
|
||||||
|
is_BMP = false;
|
||||||
|
start = SDL_TellIO(src);
|
||||||
|
if (start >= 0) {
|
||||||
|
if (SDL_ReadIO(src, magic, sizeof(magic)) == sizeof(magic)) {
|
||||||
|
if (magic[0] == 'B' && magic[1] == 'M') {
|
||||||
|
is_BMP = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_SeekIO(src, start, SDL_IO_SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_BMP;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Surface *SDL_LoadBMP_IO(SDL_IOStream *src, bool closeio)
|
SDL_Surface *SDL_LoadBMP_IO(SDL_IOStream *src, bool closeio)
|
||||||
{
|
{
|
||||||
bool was_error = true;
|
bool was_error = true;
|
||||||
@@ -195,7 +215,7 @@ SDL_Surface *SDL_LoadBMP_IO(SDL_IOStream *src, bool closeio)
|
|||||||
bool correctAlpha = false;
|
bool correctAlpha = false;
|
||||||
|
|
||||||
// The Win32 BMP file header (14 bytes)
|
// The Win32 BMP file header (14 bytes)
|
||||||
char magic[2];
|
// char magic[2];
|
||||||
// Uint32 bfSize;
|
// Uint32 bfSize;
|
||||||
// Uint16 bfReserved1;
|
// Uint16 bfReserved1;
|
||||||
// Uint16 bfReserved2;
|
// Uint16 bfReserved2;
|
||||||
@@ -227,14 +247,12 @@ SDL_Surface *SDL_LoadBMP_IO(SDL_IOStream *src, bool closeio)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
SDL_ClearError();
|
SDL_ClearError();
|
||||||
if (SDL_ReadIO(src, magic, 2) != 2) {
|
if (!SDL_IsBMP(src)) {
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (SDL_strncmp(magic, "BM", 2) != 0) {
|
|
||||||
SDL_SetError("File is not a Windows BMP file");
|
SDL_SetError("File is not a Windows BMP file");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (!SDL_ReadU32LE(src, NULL /* bfSize */) ||
|
if (!SDL_ReadU16LE(src, NULL /* magic (already checked) */) ||
|
||||||
|
!SDL_ReadU32LE(src, NULL /* bfSize */) ||
|
||||||
!SDL_ReadU16LE(src, NULL /* bfReserved1 */) ||
|
!SDL_ReadU16LE(src, NULL /* bfReserved1 */) ||
|
||||||
!SDL_ReadU16LE(src, NULL /* bfReserved2 */) ||
|
!SDL_ReadU16LE(src, NULL /* bfReserved2 */) ||
|
||||||
!SDL_ReadU32LE(src, &bfOffBits)) {
|
!SDL_ReadU32LE(src, &bfOffBits)) {
|
||||||
|
|||||||
+22
-14
@@ -328,11 +328,31 @@ static SDL_Surface *SDL_LoadSTB_IO(SDL_IOStream *src)
|
|||||||
}
|
}
|
||||||
#endif // SDL_HAVE_STB
|
#endif // SDL_HAVE_STB
|
||||||
|
|
||||||
SDL_Surface *SDL_LoadPNG_IO(SDL_IOStream *src, bool closeio)
|
bool SDL_IsPNG(SDL_IOStream *src)
|
||||||
{
|
{
|
||||||
Sint64 start;
|
Sint64 start;
|
||||||
Uint8 magic[4];
|
Uint8 magic[4];
|
||||||
bool is_PNG;
|
bool is_PNG;
|
||||||
|
|
||||||
|
is_PNG = false;
|
||||||
|
start = SDL_TellIO(src);
|
||||||
|
if (start >= 0) {
|
||||||
|
if (SDL_ReadIO(src, magic, sizeof(magic)) == sizeof(magic)) {
|
||||||
|
if (magic[0] == 0x89 &&
|
||||||
|
magic[1] == 'P' &&
|
||||||
|
magic[2] == 'N' &&
|
||||||
|
magic[3] == 'G') {
|
||||||
|
is_PNG = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_SeekIO(src, start, SDL_IO_SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_PNG;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *SDL_LoadPNG_IO(SDL_IOStream *src, bool closeio)
|
||||||
|
{
|
||||||
SDL_Surface *surface = NULL;
|
SDL_Surface *surface = NULL;
|
||||||
|
|
||||||
CHECK_PARAM(!src) {
|
CHECK_PARAM(!src) {
|
||||||
@@ -340,19 +360,7 @@ SDL_Surface *SDL_LoadPNG_IO(SDL_IOStream *src, bool closeio)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
start = SDL_TellIO(src);
|
if (!SDL_IsPNG(src)) {
|
||||||
is_PNG = false;
|
|
||||||
if (SDL_ReadIO(src, magic, sizeof(magic)) == sizeof(magic)) {
|
|
||||||
if (magic[0] == 0x89 &&
|
|
||||||
magic[1] == 'P' &&
|
|
||||||
magic[2] == 'N' &&
|
|
||||||
magic[3] == 'G') {
|
|
||||||
is_PNG = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDL_SeekIO(src, start, SDL_IO_SEEK_SET);
|
|
||||||
|
|
||||||
if (!is_PNG) {
|
|
||||||
SDL_SetError("File is not a PNG file");
|
SDL_SetError("File is not a PNG file");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3083,3 +3083,28 @@ void SDL_DestroySurface(SDL_Surface *surface)
|
|||||||
SDL_free(surface);
|
SDL_free(surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_Surface *SDL_LoadSurface_IO(SDL_IOStream *src, bool closeio)
|
||||||
|
{
|
||||||
|
if (SDL_IsBMP(src)) {
|
||||||
|
return SDL_LoadBMP_IO(src, closeio);
|
||||||
|
} else if (SDL_IsPNG(src)) {
|
||||||
|
return SDL_LoadPNG_IO(src, closeio);
|
||||||
|
} else {
|
||||||
|
if (closeio) {
|
||||||
|
SDL_CloseIO(src);
|
||||||
|
}
|
||||||
|
SDL_SetError("Unsupported image format");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *SDL_LoadSurface(const char *file)
|
||||||
|
{
|
||||||
|
SDL_IOStream *stream = SDL_IOFromFile(file, "rb");
|
||||||
|
if (!stream) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SDL_LoadSurface_IO(stream, true);
|
||||||
|
}
|
||||||
|
|||||||
@@ -93,5 +93,7 @@ extern float SDL_GetDefaultHDRHeadroom(SDL_Colorspace colorspace);
|
|||||||
extern float SDL_GetSurfaceHDRHeadroom(SDL_Surface *surface, SDL_Colorspace colorspace);
|
extern float SDL_GetSurfaceHDRHeadroom(SDL_Surface *surface, SDL_Colorspace colorspace);
|
||||||
extern SDL_Surface *SDL_GetSurfaceImage(SDL_Surface *surface, float display_scale);
|
extern SDL_Surface *SDL_GetSurfaceImage(SDL_Surface *surface, float display_scale);
|
||||||
extern SDL_Surface *SDL_ConvertSurfaceRect(SDL_Surface *surface, const SDL_Rect *rect, SDL_PixelFormat format);
|
extern SDL_Surface *SDL_ConvertSurfaceRect(SDL_Surface *surface, const SDL_Rect *rect, SDL_PixelFormat format);
|
||||||
|
extern bool SDL_IsBMP(SDL_IOStream *src);
|
||||||
|
extern bool SDL_IsPNG(SDL_IOStream *src);
|
||||||
|
|
||||||
#endif // SDL_surface_c_h_
|
#endif // SDL_surface_c_h_
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ static const char *cross[] = {
|
|||||||
|
|
||||||
static SDL_Surface *load_image_file(const char *file)
|
static SDL_Surface *load_image_file(const char *file)
|
||||||
{
|
{
|
||||||
SDL_Surface *surface = SDL_strstr(file, ".png") ? SDL_LoadPNG(file) : SDL_LoadBMP(file);
|
SDL_Surface *surface = SDL_LoadSurface(file);
|
||||||
if (surface) {
|
if (surface) {
|
||||||
if (SDL_GetSurfacePalette(surface)) {
|
if (SDL_GetSurfacePalette(surface)) {
|
||||||
const Uint8 bpp = SDL_BITSPERPIXEL(surface->format);
|
const Uint8 bpp = SDL_BITSPERPIXEL(surface->format);
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (image_file) {
|
if (image_file) {
|
||||||
shape = SDL_strstr(image_file, ".png") ? SDL_LoadPNG(image_file) : SDL_LoadBMP(image_file);
|
shape = SDL_LoadSurface(image_file);
|
||||||
if (!shape) {
|
if (!shape) {
|
||||||
SDL_Log("Couldn't load %s: %s", image_file, SDL_GetError());
|
SDL_Log("Couldn't load %s: %s", image_file, SDL_GetError());
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|||||||
+1
-1
@@ -84,7 +84,7 @@ SDL_Texture *LoadTexture(SDL_Renderer *renderer, const char *file, bool transpar
|
|||||||
file = path;
|
file = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = SDL_strstr(file, ".png") ? SDL_LoadPNG(file) : SDL_LoadBMP(file);
|
temp = SDL_LoadSurface(file);
|
||||||
if (!temp) {
|
if (!temp) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user