twn_textures.c: stream-based texture load
This commit is contained in:
parent
1430a13832
commit
65425f5b2e
@ -14,27 +14,55 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SDL_RWops *rwops;
|
||||||
|
size_t size;
|
||||||
|
size_t position;
|
||||||
|
} TextureLoadingContext;
|
||||||
|
|
||||||
|
|
||||||
|
static int load_read_callback(void *user, char *data, int size) {
|
||||||
|
TextureLoadingContext *context = user;
|
||||||
|
int read = (int)SDL_RWread(context->rwops, data, 1, size);
|
||||||
|
context->position += read;
|
||||||
|
if (read == 0)
|
||||||
|
CRY_SDL( "Error in streamed texture load.");
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_skip_callback(void *user, int n) {
|
||||||
|
TextureLoadingContext *context = user;
|
||||||
|
context->position += n;
|
||||||
|
Sint64 result = SDL_RWseek(context->rwops, n, RW_SEEK_CUR);
|
||||||
|
SDL_assert_always(result != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int load_eof_callback(void *user) {
|
||||||
|
TextureLoadingContext *context = user;
|
||||||
|
return context->position == context->size;
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_Surface *image_to_surface(const char *path) {
|
static SDL_Surface *image_to_surface(const char *path) {
|
||||||
SDL_RWops *handle = PHYSFSRWOPS_openRead(path);
|
SDL_RWops *handle = PHYSFSRWOPS_openRead(path);
|
||||||
if (handle == NULL)
|
if (handle == NULL)
|
||||||
goto ERR_CANNOT_OPEN_FILE;
|
goto ERR_CANNOT_OPEN_FILE;
|
||||||
|
|
||||||
/* TODO: try using callbacks so that no loading of whole files is needed */
|
TextureLoadingContext context = {
|
||||||
size_t file_size;
|
.rwops = handle,
|
||||||
void *file_mem = SDL_LoadFile_RW(handle, &file_size, 0);
|
.size = SDL_RWsize(handle),
|
||||||
SDL_FreeRW(handle);
|
};
|
||||||
|
|
||||||
if (!file_mem)
|
stbi_io_callbacks callbacks = {
|
||||||
goto ERR_CANNOT_ALLOCATE_MEM;
|
.read = load_read_callback,
|
||||||
|
.skip = load_skip_callback,
|
||||||
|
.eof = load_eof_callback,
|
||||||
|
};
|
||||||
|
|
||||||
int width, height, channels;
|
int width, height, channels;
|
||||||
void *image_mem = stbi_load_from_memory(file_mem, (int)file_size, &width, &height, &channels, 0);
|
void *image_mem = stbi_load_from_callbacks(&callbacks, &context, &width, &height, &channels, 0);
|
||||||
if (!image_mem)
|
if (!image_mem)
|
||||||
goto ERR_CANNOT_READ_IMAGE;
|
goto ERR_CANNOT_READ_IMAGE;
|
||||||
|
|
||||||
SDL_free(file_mem);
|
|
||||||
|
|
||||||
Uint32 rmask, gmask, bmask, amask;
|
Uint32 rmask, gmask, bmask, amask;
|
||||||
|
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||||
@ -65,9 +93,6 @@ ERR_CANNOT_CREATE_SURFACE:
|
|||||||
stbi_image_free(image_mem);
|
stbi_image_free(image_mem);
|
||||||
|
|
||||||
ERR_CANNOT_READ_IMAGE:
|
ERR_CANNOT_READ_IMAGE:
|
||||||
SDL_free(file_mem);
|
|
||||||
|
|
||||||
ERR_CANNOT_ALLOCATE_MEM:
|
|
||||||
ERR_CANNOT_OPEN_FILE:
|
ERR_CANNOT_OPEN_FILE:
|
||||||
CRY(path, "Failed to load image. Aborting...");
|
CRY(path, "Failed to load image. Aborting...");
|
||||||
die_abruptly();
|
die_abruptly();
|
||||||
|
Loading…
Reference in New Issue
Block a user