mirror of
https://github.com/Bithack/principia.git
synced 2026-06-24 02:04:08 +00:00
Use filename extensions for determining image format rather than magic
This commit is contained in:
parent
22c192b6d2
commit
d623a95857
8 changed files with 37 additions and 184 deletions
|
|
@ -19,34 +19,8 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* A simple library to load images of various formats as SDL surfaces */
|
||||
|
||||
#include <SDL_image.h>
|
||||
|
||||
SDL_Surface *IMG_LoadTyped_IO(SDL_IOStream *src, bool closeio, const char *type);
|
||||
|
||||
/* Load an image from a file */
|
||||
SDL_Surface *IMG_Load(const char *file)
|
||||
{
|
||||
SDL_IOStream *src = SDL_IOFromFile(file, "rb");
|
||||
if (!src) {
|
||||
/* The error message has been set in SDL_IOFromFile */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *ext = SDL_strrchr(file, '.');
|
||||
if (ext) {
|
||||
ext++;
|
||||
}
|
||||
return IMG_LoadTyped_IO(src, true, ext);
|
||||
}
|
||||
|
||||
/* Load an image from an SDL datasource (for compatibility) */
|
||||
SDL_Surface *IMG_Load_IO(SDL_IOStream *src, bool closeio)
|
||||
{
|
||||
return IMG_LoadTyped_IO(src, closeio, NULL);
|
||||
}
|
||||
|
||||
/* Load an image from an SDL datasource, optionally specifying the type */
|
||||
SDL_Surface *IMG_LoadTyped_IO(SDL_IOStream *src, bool closeio, const char *type)
|
||||
{
|
||||
|
|
@ -67,21 +41,21 @@ SDL_Surface *IMG_LoadTyped_IO(SDL_IOStream *src, bool closeio, const char *type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Detect the type of image being loaded */
|
||||
if (IMG_isJPG(src)) {
|
||||
image = IMG_LoadJPG_IO(src);
|
||||
if (closeio) {
|
||||
SDL_CloseIO(src);
|
||||
if (type) {
|
||||
if (SDL_strcasecmp(type, "JPEG") == 0 || SDL_strcasecmp(type, "JPG") == 0) {
|
||||
image = IMG_LoadJPG_IO(src);
|
||||
if (closeio) {
|
||||
SDL_CloseIO(src);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
if (IMG_isPNG(src)) {
|
||||
image = IMG_LoadPNG_IO(src);
|
||||
if (closeio) {
|
||||
SDL_CloseIO(src);
|
||||
if (SDL_strcasecmp(type, "PNG") == 0) {
|
||||
image = IMG_LoadPNG_IO(src);
|
||||
if (closeio) {
|
||||
SDL_CloseIO(src);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
if (closeio) {
|
||||
|
|
@ -90,3 +64,19 @@ SDL_Surface *IMG_LoadTyped_IO(SDL_IOStream *src, bool closeio, const char *type)
|
|||
SDL_SetError("Unsupported image format");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Load an image from a file */
|
||||
SDL_Surface *IMG_Load(const char *file)
|
||||
{
|
||||
SDL_IOStream *src = SDL_IOFromFile(file, "rb");
|
||||
if (!src) {
|
||||
/* The error message has been set in SDL_IOFromFile */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *ext = SDL_strrchr(file, '.');
|
||||
if (ext) {
|
||||
ext++;
|
||||
}
|
||||
return IMG_LoadTyped_IO(src, true, ext);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,73 +28,6 @@
|
|||
|
||||
#include <jpeglib.h>
|
||||
|
||||
/* Define this for fast loading and not as good image quality */
|
||||
/*#define FAST_JPEG*/
|
||||
|
||||
/* See if an image is contained in a data source */
|
||||
bool IMG_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 */
|
||||
/* Ok, I'm convinced. It is a JPEG. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_SeekIO(src, start, SDL_IO_SEEK_SET);
|
||||
return is_JPG;
|
||||
}
|
||||
|
||||
#define INPUT_BUFFER_SIZE 4096
|
||||
typedef struct {
|
||||
struct jpeg_source_mgr pub;
|
||||
|
|
@ -266,12 +199,6 @@ static bool LIBJPEG_LoadJPG_IO(SDL_IOStream *src, struct loadjpeg_vars *vars)
|
|||
/* Set 24-bit RGB output */
|
||||
vars->cinfo.out_color_space = JCS_RGB;
|
||||
vars->cinfo.quantize_colors = FALSE;
|
||||
#ifdef FAST_JPEG
|
||||
vars->cinfo.scale_num = 1;
|
||||
vars->cinfo.scale_denom = 1;
|
||||
vars->cinfo.dct_method = JDCT_FASTEST;
|
||||
vars->cinfo.do_fancy_upsampling = FALSE;
|
||||
#endif
|
||||
jpeg_calc_output_dimensions(&vars->cinfo);
|
||||
|
||||
/* Allocate an output surface to hold the image */
|
||||
|
|
|
|||
|
|
@ -24,46 +24,6 @@
|
|||
#include <SDL_image.h>
|
||||
#include <png.h>
|
||||
|
||||
extern bool IMG_InitPNG(void);
|
||||
extern SDL_Surface *IMG_LoadPNG_LIBPNG(SDL_IOStream *src);
|
||||
extern bool IMG_SavePNG_LIBPNG(SDL_Surface *surface, SDL_IOStream *dst, bool closeio);
|
||||
|
||||
/* See if an image is contained in a data source */
|
||||
bool IMG_isPNG(SDL_IOStream *src)
|
||||
{
|
||||
Sint64 start;
|
||||
bool is_PNG;
|
||||
Uint8 magic[4];
|
||||
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
start = SDL_TellIO(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);
|
||||
return is_PNG;
|
||||
}
|
||||
|
||||
typedef png_const_structrp png_noconst15_structrp;
|
||||
typedef png_const_inforp png_noconst15_inforp;
|
||||
typedef png_inforp png_noconst16_inforp;
|
||||
|
||||
#define libpng_get_uint_32(buf) \
|
||||
(((png_uint_32)( *(buf) ) << 24) + \
|
||||
((png_uint_32)(*((buf) + 1)) << 16) + \
|
||||
((png_uint_32)(*((buf) + 2)) << 8) + \
|
||||
((png_uint_32)(*((buf) + 3))))
|
||||
|
||||
|
||||
static void png_read_data(png_structp png_ptr, png_bytep area, png_size_t size)
|
||||
{
|
||||
SDL_IOStream *src = (SDL_IOStream *)png_get_io_ptr(png_ptr);
|
||||
|
|
|
|||
|
|
@ -38,17 +38,7 @@ extern SDL_DECLSPEC SDL_Surface * SDLCALL IMG_Load(const char *file);
|
|||
/**
|
||||
* Load an image from an SDL data source into a software surface.
|
||||
*/
|
||||
extern SDL_DECLSPEC SDL_Surface * SDLCALL IMG_Load_IO(SDL_IOStream *src, bool closeio);
|
||||
|
||||
/**
|
||||
* Detect JPG image data on a readable/seekable SDL_IOStream.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL IMG_isJPG(SDL_IOStream *src);
|
||||
|
||||
/**
|
||||
* Detect PNG image data on a readable/seekable SDL_IOStream.
|
||||
*/
|
||||
extern SDL_DECLSPEC bool SDLCALL IMG_isPNG(SDL_IOStream *src);
|
||||
extern SDL_DECLSPEC SDL_Surface * SDLCALL IMG_LoadTyped_IO(SDL_IOStream *src, bool closeio, const char *type);
|
||||
|
||||
/**
|
||||
* Load a JPG image directly.
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ _get_featured_levels(void *_num)
|
|||
lb.r_buf(thumb, thumb_len);
|
||||
|
||||
tms::texture *tex = new tms::texture();
|
||||
tex->load_mem2(thumb, thumb_len, 0);
|
||||
tex->load_mem2(thumb, thumb_len, 0, "jpg");
|
||||
tex->flip_y();
|
||||
tex->add_alpha(1.f);
|
||||
|
||||
|
|
|
|||
|
|
@ -145,13 +145,8 @@ tms_texture_load(struct tms_texture *tex, const char *filename)
|
|||
tex->gamma_corrected = 0;
|
||||
tex->width = s->w;
|
||||
tex->height = s->h;
|
||||
//tex->num_channels = 3 + s->format->Amask?1:0;
|
||||
tex->num_channels = SDL_GetPixelFormatDetails(s->format)->bytes_per_pixel;
|
||||
|
||||
//tms_infof("bpp %d", s->format->BytesPerPixel);
|
||||
|
||||
//tms_assertf(tex->num_channels == s->format->BytesPerPixel, "unsupported texture type BLAH");
|
||||
|
||||
tex->data = malloc(tex->width*tex->height*tex->num_channels);
|
||||
|
||||
for (int y=0; y<s->h; y++) {
|
||||
|
|
@ -163,7 +158,6 @@ tms_texture_load(struct tms_texture *tex, const char *filename)
|
|||
}
|
||||
|
||||
SDL_DestroySurface(s);
|
||||
//SDL_RWclose(rw);
|
||||
|
||||
return T_OK;
|
||||
}
|
||||
|
|
@ -207,7 +201,7 @@ tms_texture_load_mem(struct tms_texture *tex, const char *buf,
|
|||
* @relates tms_texture
|
||||
**/
|
||||
int
|
||||
tms_texture_load_mem2(struct tms_texture *tex, const char *buf, size_t size, int freesrc)
|
||||
tms_texture_load_mem2(struct tms_texture *tex, const char *buf, size_t size, int freesrc, const char *type)
|
||||
{
|
||||
int status;
|
||||
|
||||
|
|
@ -218,10 +212,10 @@ tms_texture_load_mem2(struct tms_texture *tex, const char *buf, size_t size, int
|
|||
return T_COULD_NOT_OPEN;
|
||||
}
|
||||
|
||||
SDL_Surface *s = IMG_Load_IO(rw, freesrc);
|
||||
SDL_Surface *s = IMG_LoadTyped_IO(rw, freesrc, type);
|
||||
|
||||
if (!s) {
|
||||
tms_errorf("Error calling IMG_Load_IO: %s", SDL_GetError());
|
||||
tms_errorf("Error loading image: %s", SDL_GetError());
|
||||
return T_COULD_NOT_OPEN;
|
||||
}
|
||||
|
||||
|
|
@ -230,15 +224,8 @@ tms_texture_load_mem2(struct tms_texture *tex, const char *buf, size_t size, int
|
|||
tex->gamma_corrected = 0;
|
||||
tex->width = s->w;
|
||||
tex->height = s->h;
|
||||
//tex->num_channels = 3 + s->format->Amask?1:0;
|
||||
// fix this for SDL3
|
||||
//tex->num_channels = s->format->BytesPerPixel;
|
||||
tex->num_channels = SDL_GetPixelFormatDetails(s->format)->bytes_per_pixel;
|
||||
|
||||
//tms_infof("bpp %d", s->format->BytesPerPixel);
|
||||
|
||||
//tms_assertf(tex->num_channels == s->format->BytesPerPixel, "unsupported texture type BLAH");
|
||||
|
||||
tex->data = malloc(tex->width*tex->height*tex->num_channels);
|
||||
|
||||
for (int y=0; y<s->h; y++) {
|
||||
|
|
@ -250,7 +237,6 @@ tms_texture_load_mem2(struct tms_texture *tex, const char *buf, size_t size, int
|
|||
}
|
||||
|
||||
SDL_DestroySurface(s);
|
||||
//SDL_RWclose(rw);
|
||||
|
||||
return T_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ int tms_texture_clear_buffer(struct tms_texture *tex, unsigned char clear_value)
|
|||
int tms_texture_free_buffer(struct tms_texture *tex);
|
||||
int tms_texture_load(struct tms_texture *tex, const char *filename);
|
||||
int tms_texture_load_mem(struct tms_texture *tex, const char *buf, int width, int height, int num_channels);
|
||||
int tms_texture_load_mem2(struct tms_texture *tex, const char *buf, size_t size, int freesrc);
|
||||
int tms_texture_load_mem2(struct tms_texture *tex, const char *buf, size_t size, int freesrc, const char *type);
|
||||
int tms_texture_upload(struct tms_texture *tex);
|
||||
int tms_texture_bind(struct tms_texture *tex);
|
||||
int tms_texture_flip_y(struct tms_texture *tex);
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ namespace tms {
|
|||
return tms_texture_load(this, filename);
|
||||
}
|
||||
|
||||
inline int load_mem2(const char *buf, size_t size, int freesrc) {
|
||||
return tms_texture_load_mem2(this, buf, size, freesrc);
|
||||
inline int load_mem2(const char *buf, size_t size, int freesrc, const char *type) {
|
||||
return tms_texture_load_mem2(this, buf, size, freesrc, type);
|
||||
}
|
||||
|
||||
inline int upload() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue