mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-29 16:25:22 +00:00
Support loading JPEG images through SDL_LoadSurface()
This commit is contained in:
committed by
Sam Lantinga
parent
9672f5b68b
commit
c6b232f5d4
@@ -1285,3 +1285,5 @@ _SDL_SetGPURenderStateStorageBuffers
|
||||
_SDL_GDKSuspendRenderer
|
||||
_SDL_GDKResumeRenderer
|
||||
_SDL_IsPhone
|
||||
_SDL_LoadJPG_IO
|
||||
_SDL_LoadJPG
|
||||
|
||||
@@ -1286,6 +1286,8 @@ SDL3_0.0.0 {
|
||||
SDL_GDKSuspendRenderer;
|
||||
SDL_GDKResumeRenderer;
|
||||
SDL_IsPhone;
|
||||
SDL_LoadJPG_IO;
|
||||
SDL_LoadJPG;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
||||
@@ -1312,3 +1312,5 @@
|
||||
#define SDL_GDKSuspendRenderer SDL_GDKSuspendRenderer_REAL
|
||||
#define SDL_GDKResumeRenderer SDL_GDKResumeRenderer_REAL
|
||||
#define SDL_IsPhone SDL_IsPhone_REAL
|
||||
#define SDL_LoadJPG_IO SDL_LoadJPG_IO_REAL
|
||||
#define SDL_LoadJPG SDL_LoadJPG_REAL
|
||||
|
||||
@@ -1320,3 +1320,5 @@ SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateStorageBuffers,(SDL_GPURenderState *a,
|
||||
SDL_DYNAPI_PROC(void,SDL_GDKSuspendRenderer,(SDL_Renderer *a),(a),)
|
||||
SDL_DYNAPI_PROC(void,SDL_GDKResumeRenderer,(SDL_Renderer *a),(a),)
|
||||
SDL_DYNAPI_PROC(bool,SDL_IsPhone,(void),(),return)
|
||||
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG_IO,(SDL_IOStream *a,bool b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_Surface*,SDL_LoadJPG,(const char *a),(a),return)
|
||||
|
||||
@@ -363,6 +363,116 @@ static SDL_Surface *SDL_LoadSTB_IO(SDL_IOStream *src)
|
||||
}
|
||||
#endif // SDL_HAVE_STB
|
||||
|
||||
/* FIXME: This is a copypaste from JPEGLIB! Pull that out of the ifdefs */
|
||||
/* Define this for quicker (but less perfect) JPEG identification */
|
||||
#define FAST_IS_JPEG
|
||||
|
||||
/* See if an image is contained in a data source */
|
||||
bool SDL_IsJPG(SDL_IOStream *src)
|
||||
{
|
||||
Sint64 start;
|
||||
bool is_JPG;
|
||||
bool in_scan;
|
||||
Uint8 magic[4];
|
||||
|
||||
/* This detection code is by Steaphan Greene <stea@cs.binghamton.edu> */
|
||||
/* Blame me, not Sam, if this doesn't work right. */
|
||||
/* And don't forget to report the problem to the the sdl list too! */
|
||||
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
start = SDL_TellIO(src);
|
||||
is_JPG = false;
|
||||
in_scan = false;
|
||||
if (SDL_ReadIO(src, magic, 2) == 2) {
|
||||
if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) {
|
||||
is_JPG = true;
|
||||
while (is_JPG) {
|
||||
if (SDL_ReadIO(src, magic, 2) != 2) {
|
||||
is_JPG = false;
|
||||
} else if ( (magic[0] != 0xFF) && !in_scan ) {
|
||||
is_JPG = false;
|
||||
} else if ( (magic[0] != 0xFF) || (magic[1] == 0xFF) ) {
|
||||
/* Extra padding in JPEG (legal) */
|
||||
/* or this is data and we are scanning */
|
||||
SDL_SeekIO(src, -1, SDL_IO_SEEK_CUR);
|
||||
} else if (magic[1] == 0xD9) {
|
||||
/* Got to end of good JPEG */
|
||||
break;
|
||||
} else if ( in_scan && (magic[1] == 0x00) ) {
|
||||
/* This is an encoded 0xFF within the data */
|
||||
} else if ( (magic[1] >= 0xD0) && (magic[1] < 0xD9) ) {
|
||||
/* These have nothing else */
|
||||
} else if (SDL_ReadIO(src, magic+2, 2) != 2) {
|
||||
is_JPG = false;
|
||||
} else {
|
||||
/* Yes, it's big-endian */
|
||||
Sint64 innerStart;
|
||||
Uint32 size;
|
||||
Sint64 end;
|
||||
innerStart = SDL_TellIO(src);
|
||||
size = (magic[2] << 8) + magic[3];
|
||||
end = SDL_SeekIO(src, size-2, SDL_IO_SEEK_CUR);
|
||||
if ( end != innerStart + size - 2 ) {
|
||||
is_JPG = false;
|
||||
}
|
||||
if ( magic[1] == 0xDA ) {
|
||||
/* Now comes the actual JPEG meat */
|
||||
#ifdef FAST_IS_JPEG
|
||||
/* Ok, I'm convinced. It is a JPEG. */
|
||||
break;
|
||||
#else
|
||||
/* I'm not convinced. Prove it! */
|
||||
in_scan = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_SeekIO(src, start, SDL_IO_SEEK_SET);
|
||||
return is_JPG;
|
||||
}
|
||||
|
||||
SDL_Surface *SDL_LoadJPG_IO(SDL_IOStream *src, bool closeio)
|
||||
{
|
||||
SDL_Surface *surface = NULL;
|
||||
|
||||
CHECK_PARAM(!src) {
|
||||
SDL_InvalidParamError("src");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!SDL_IsJPG(src)) {
|
||||
SDL_SetError("File is not a JPEG file");
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef SDL_HAVE_STB
|
||||
surface = SDL_LoadSTB_IO(src);
|
||||
#else
|
||||
SDL_SetError("SDL not built with STB image support");
|
||||
#endif // SDL_HAVE_STB
|
||||
|
||||
done:
|
||||
if (src && closeio) {
|
||||
SDL_CloseIO(src);
|
||||
}
|
||||
return surface;
|
||||
}
|
||||
|
||||
SDL_Surface *SDL_LoadJPG(const char *file)
|
||||
{
|
||||
SDL_IOStream *stream = SDL_IOFromFile(file, "rb");
|
||||
if (!stream) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SDL_LoadJPG_IO(stream, true);
|
||||
}
|
||||
|
||||
bool SDL_IsPNG(SDL_IOStream *src)
|
||||
{
|
||||
Sint64 start;
|
||||
|
||||
@@ -3118,6 +3118,8 @@ SDL_Surface *SDL_LoadSurface_IO(SDL_IOStream *src, bool closeio)
|
||||
return SDL_LoadBMP_IO(src, closeio);
|
||||
} else if (SDL_IsPNG(src)) {
|
||||
return SDL_LoadPNG_IO(src, closeio);
|
||||
} else if (SDL_IsJPG(src)) {
|
||||
return SDL_LoadJPG_IO(src, closeio);
|
||||
} else {
|
||||
if (closeio) {
|
||||
SDL_CloseIO(src);
|
||||
|
||||
@@ -94,6 +94,7 @@ extern float SDL_GetSurfaceHDRHeadroom(SDL_Surface *surface, SDL_Colorspace colo
|
||||
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 bool SDL_IsBMP(SDL_IOStream *src);
|
||||
extern bool SDL_IsJPG(SDL_IOStream *src);
|
||||
extern bool SDL_IsPNG(SDL_IOStream *src);
|
||||
|
||||
#endif // SDL_surface_c_h_
|
||||
|
||||
Reference in New Issue
Block a user