use SDL_RWops to read png textures
This commit is contained in:
parent
a787f88cff
commit
4b132656a5
4 changed files with 36 additions and 25 deletions
|
@ -52,36 +52,30 @@ Texture* prefix_get_tex(const char *name, const char *prefix) {
|
|||
return tex;
|
||||
}
|
||||
|
||||
static SDL_Surface* load_png(const char *filename) {
|
||||
static SDL_Surface* load_png_p(const char *filename, SDL_RWops *rwops) {
|
||||
#define PNGFAIL(msg) { warnx("load_png(): couldn't load '%s': %s", filename, msg); return NULL; }
|
||||
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
|
||||
if(!fp) {
|
||||
PNGFAIL("fopen() failed")
|
||||
if(!rwops) {
|
||||
PNGFAIL(SDL_GetError())
|
||||
}
|
||||
|
||||
png_structp png_ptr;
|
||||
if(!(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) {
|
||||
fclose(fp);
|
||||
PNGFAIL("png_create_read_struct() failed")
|
||||
}
|
||||
|
||||
png_infop info_ptr;
|
||||
if(!(info_ptr = png_create_info_struct(png_ptr))) {
|
||||
fclose(fp);
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
PNGFAIL("png_create_info_struct() failed")
|
||||
}
|
||||
|
||||
png_infop end_info;
|
||||
if(!(end_info = png_create_info_struct(png_ptr))) {
|
||||
fclose(fp);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
PNGFAIL("png_create_info_struct() failed")
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, fp);
|
||||
png_init_rwops(png_ptr, rwops);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
int colortype = png_get_color_type(png_ptr,info_ptr);
|
||||
|
@ -95,19 +89,19 @@ static SDL_Surface* load_png(const char *filename) {
|
|||
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
|
||||
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
|
||||
int width = png_get_image_width(png_ptr, info_ptr);
|
||||
int height = png_get_image_height(png_ptr, info_ptr);
|
||||
int depth = png_get_bit_depth(png_ptr, info_ptr);
|
||||
|
||||
|
||||
|
||||
png_bytep row_pointers[height];
|
||||
|
||||
Uint32 *pixels = malloc(sizeof(Uint32)*width*height);
|
||||
|
||||
for(int i = 0; i < height; i++)
|
||||
row_pointers[i] = (png_bytep)(pixels+i*width);
|
||||
|
||||
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
png_read_end(png_ptr, end_info);
|
||||
|
||||
|
@ -129,17 +123,22 @@ static SDL_Surface* load_png(const char *filename) {
|
|||
SDL_Surface *res = SDL_CreateRGBSurfaceFrom(pixels, width, height, depth*4, 0, rmask, gmask, bmask, amask);
|
||||
|
||||
if(!res) {
|
||||
fclose(fp);
|
||||
PNGFAIL(SDL_GetError())
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
|
||||
|
||||
return res;
|
||||
#undef PNGFAIL
|
||||
}
|
||||
|
||||
static SDL_Surface* load_png(const char *filename) {
|
||||
SDL_RWops *rwops = SDL_RWFromFile(filename, "r");
|
||||
SDL_Surface *surf = load_png_p(filename, rwops);
|
||||
SDL_RWclose(rwops);
|
||||
return surf;
|
||||
}
|
||||
|
||||
void load_sdl_surf(SDL_Surface *surface, Texture *texture) {
|
||||
glGenTextures(1, &texture->gltex);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->gltex);
|
||||
|
|
19
src/util.c
19
src/util.c
|
@ -351,6 +351,25 @@ Hashtable* parse_keyvalue_file(const char *filename, size_t tablesize) {
|
|||
return ht;
|
||||
}
|
||||
|
||||
static void png_rwops_write_data(png_structp png_ptr, png_bytep data, png_size_t length) {
|
||||
SDL_RWops *out = png_get_io_ptr(png_ptr);
|
||||
SDL_RWwrite(out, data, length, 1);
|
||||
}
|
||||
|
||||
static void png_rwops_flush_data(png_structp png_ptr) {
|
||||
// no flush operation in SDL_RWops
|
||||
}
|
||||
|
||||
static void png_rwops_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
|
||||
SDL_RWops *out = png_get_io_ptr(png_ptr);
|
||||
SDL_RWread(out, data, length, 1);
|
||||
}
|
||||
|
||||
void png_init_rwops(png_structp png, SDL_RWops *rwops) {
|
||||
png_set_write_fn(png, rwops, png_rwops_write_data, png_rwops_flush_data);
|
||||
png_set_read_fn(png, rwops, png_rwops_read_data);
|
||||
}
|
||||
|
||||
//
|
||||
// misc utils
|
||||
//
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <zlib.h> // compiling under mingw may fail without this...
|
||||
#include <png.h>
|
||||
#include <SDL.h>
|
||||
#include "hashtable.h"
|
||||
|
||||
|
@ -96,6 +97,7 @@ bool parse_keyvalue_stream_cb(SDL_RWops *strm, KVCallback callback, void *data);
|
|||
bool parse_keyvalue_file_cb(const char *filename, KVCallback callback, void *data);
|
||||
Hashtable* parse_keyvalue_stream(SDL_RWops *strm, size_t tablesize);
|
||||
Hashtable* parse_keyvalue_file(const char *filename, size_t tablesize);
|
||||
void png_init_rwops(png_structp png, SDL_RWops *rwops);
|
||||
|
||||
//
|
||||
// misc utils
|
||||
|
|
11
src/video.c
11
src/video.c
|
@ -221,15 +221,6 @@ void video_setmode(int w, int h, bool fs, bool resizable) {
|
|||
_video_setmode(w, h, flags, false);
|
||||
}
|
||||
|
||||
static void png_rwops_write_data(png_structp png_ptr, png_bytep data, png_size_t length) {
|
||||
SDL_RWops *out = png_get_io_ptr(png_ptr);
|
||||
SDL_RWwrite(out, data, length, 1);
|
||||
}
|
||||
|
||||
static void png_rwops_flush_data(png_structp png_ptr) {
|
||||
// no flush operation in SDL_RWops
|
||||
}
|
||||
|
||||
void video_take_screenshot(void) {
|
||||
SDL_RWops *out;
|
||||
char *data;
|
||||
|
@ -282,7 +273,7 @@ void video_take_screenshot(void) {
|
|||
memcpy(row_pointers[y], data + rw*3*(h-1-y), w*3);
|
||||
}
|
||||
|
||||
png_set_write_fn(png_ptr, out, png_rwops_write_data, png_rwops_flush_data);
|
||||
png_init_rwops(png_ptr, out);
|
||||
png_set_rows(png_ptr, info_ptr, row_pointers);
|
||||
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
||||
|
||||
|
|
Loading…
Reference in a new issue