From b6b9b5084fc482df71b020897453e63f55ec2726 Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Thu, 5 Nov 2015 20:53:11 +0000 Subject: Add a PNG loader --- Makefile | 2 +- loader.c | 10 +++++++--- png.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 png.c diff --git a/Makefile b/Makefile index 87b2fb1..7c23259 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: clean CFLAGS = -g -W -Wall -std=c11 `sdl2-config --cflags` -LDFLAGS = `sdl2-config --libs` +LDFLAGS = `sdl2-config --libs` -lpng TARGET = imv SOURCES = $(wildcard *.c) diff --git a/loader.c b/loader.c index 0a94cf9..9f62d24 100644 --- a/loader.c +++ b/loader.c @@ -1,13 +1,14 @@ #include #include +extern SDL_Texture* imv_load_png(SDL_Renderer *r, const char* path); + SDL_Texture* imv_load_image(SDL_Renderer *r, const char* path) { if(!path) return NULL; const char* ext = strrchr(path, '.'); - SDL_Texture *img = NULL; if(ext == NULL) { fprintf(stderr, "Could not determine filetype of '%s' from its extension.\n", @@ -15,7 +16,7 @@ SDL_Texture* imv_load_image(SDL_Renderer *r, const char* path) } else if(strcasecmp(ext, ".test") == 0) { const int width = 1280; const int height = 720; - img = SDL_CreateTexture(r, + SDL_Texture *img = SDL_CreateTexture(r, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STATIC, width, height); void *pixels = malloc(width*height*3); @@ -23,7 +24,10 @@ SDL_Texture* imv_load_image(SDL_Renderer *r, const char* path) SDL_Rect area = {0,0,width,height}; SDL_UpdateTexture(img, &area, pixels, width * 3); free(pixels); + return img; + } else if(strcasecmp(ext, ".png") == 0) { + return imv_load_png(r, path); } - return img; + return NULL; } diff --git a/png.c b/png.c new file mode 100644 index 0000000..02b951a --- /dev/null +++ b/png.c @@ -0,0 +1,50 @@ +#include +#include +#include + +SDL_Texture* imv_load_png(SDL_Renderer *r, const char* path) +{ + FILE *fp = fopen(path, "rb"); + + if(!fp) { + return NULL; + } + + png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png) { + fclose(fp); + return NULL; + } + + png_infop info = png_create_info_struct(png); + if(!info) { + fclose(fp); + png_destroy_read_struct(&png, NULL, NULL); + return NULL; + } + + png_init_io(png, fp); + png_read_png(png, info, + PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, + NULL); + png_uint_32 width, height; + png_get_IHDR(png, info, &width, &height, NULL, NULL, NULL, NULL, NULL); + unsigned int bytes_per_row = png_get_rowbytes(png, info); + png_bytepp row_ptrs = png_get_rows(png, info); + + char* pixels = (char*)malloc(bytes_per_row*height); + for (unsigned int i = 0; i < height; i++) { + memcpy(pixels + bytes_per_row * i, row_ptrs[i], bytes_per_row); + } + png_destroy_read_struct(&png, &info, NULL); + fclose(fp); + + SDL_Texture *img = SDL_CreateTexture(r, + SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STATIC, + width, height); + + SDL_Rect area = {0,0,width,height}; + SDL_UpdateTexture(img, &area, pixels, bytes_per_row); + free(pixels); + return img; +} -- cgit v1.2.3