X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=share%2Fbase_image.c;h=b3c5808424772eafed4e61786942501274385061;hb=9a0d95f9e851a54f69f05552ca9bf4041c8c88e0;hp=01799857c8037abc9501c46a6304d6dd4670bbf4;hpb=437d96ba91cd831c91c6635d2a897a41a79ec0a6;p=neverball diff --git a/share/base_image.c b/share/base_image.c index 0179985..b3c5808 100644 --- a/share/base_image.c +++ b/share/base_image.c @@ -14,11 +14,17 @@ #include #include +#include +#include #include "glext.h" #include "base_config.h" #include "base_image.h" +#include "fs.h" +#include "fs_png.h" +#include "fs_jpg.h" + /*---------------------------------------------------------------------------*/ void image_size(int *W, int *H, int w, int h) @@ -38,7 +44,7 @@ static void *image_load_png(const char *filename, int *width, int *height, int *bytes) { - FILE *fp; + fs_file fh; png_structp readp = NULL; png_infop infop = NULL; @@ -47,12 +53,12 @@ static void *image_load_png(const char *filename, int *width, /* Initialize all PNG import data structures. */ - if (!(fp = fopen(filename, FMODE_RB))) + if (!(fh = fs_open(filename, "r"))) return NULL; if (!(readp = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) return NULL; - + if (!(infop = png_create_info_struct(readp))) return NULL; @@ -60,16 +66,19 @@ static void *image_load_png(const char *filename, int *width, if (setjmp(png_jmpbuf(readp)) == 0) { - int w, h, b, c, r, i; + int w, h, b, i; /* Read the PNG header. */ - png_init_io(readp, fp); - png_read_png(readp, infop, - PNG_TRANSFORM_EXPAND | - PNG_TRANSFORM_STRIP_16 | - PNG_TRANSFORM_PACKING, NULL); - + png_set_read_fn(readp, fh, fs_png_read); + png_read_info(readp, infop); + + png_set_expand(readp); + png_set_strip_16(readp); + png_set_packing(readp); + + png_read_update_info(readp, infop); + /* Extract and check image properties. */ w = (int) png_get_image_width (readp, infop); @@ -85,31 +94,32 @@ static void *image_load_png(const char *filename, int *width, default: longjmp(png_jmpbuf(readp), -1); } - /* Read the pixel data. */ - - if (!(bytep = png_get_rows(readp, infop))) + if (!(bytep = png_malloc(readp, h * png_sizeof(png_bytep)))) longjmp(png_jmpbuf(readp), -1); - /* Allocate the final pixel buffer and copy pixels there. */ + /* Allocate the final pixel buffer and read pixels there. */ if ((p = (unsigned char *) malloc(w * h * b))) { - for (r = 0; r < h; r++) - for (c = 0; c < w; c++) - for (i = 0; i < b; i++) - p[r*w*b+c*b+i] = (unsigned char) bytep[r][c*b+i]; + for (i = 0; i < h; i++) + bytep[i] = p + w * b * (h - i - 1); + + png_read_image(readp, bytep); + png_read_end(readp, NULL); if (width) *width = w; if (height) *height = h; if (bytes) *bytes = b; } + + png_free(readp, bytep); } else p = NULL; /* Free all resources. */ png_destroy_read_struct(&readp, &infop, NULL); - fclose(fp); + fs_close(fh); return p; } @@ -119,9 +129,9 @@ static void *image_load_jpg(const char *filename, int *width, int *bytes) { GLubyte *p = NULL; - FILE *fp; + fs_file fp; - if ((fp = fopen(filename, FMODE_RB))) + if ((fp = fs_open(filename, "r"))) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; @@ -132,7 +142,10 @@ static void *image_load_jpg(const char *filename, int *width, cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo, fp); + + /* Set up a VFS source manager. */ + + fs_jpg_src(&cinfo, fp); /* Grab the JPG header info. */ @@ -149,7 +162,7 @@ static void *image_load_jpg(const char *filename, int *width, { while (cinfo.output_scanline < cinfo.output_height) { - GLubyte *buffer = p + w * b * i; + GLubyte *buffer = p + w * b * (h - i - 1); i += jpeg_read_scanlines(&cinfo, &buffer, 1); } @@ -161,7 +174,7 @@ static void *image_load_jpg(const char *filename, int *width, jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); - fclose(fp); + fs_close(fp); } return p; @@ -172,7 +185,7 @@ void *image_load(const char *filename, int *width, int *bytes) { const char *ext = filename + strlen(filename) - 4; - + if (strcmp(ext, ".png") == 0 || strcmp(ext, ".PNG") == 0) return image_load_png(filename, width, height, bytes); else if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".JPG") == 0) @@ -287,4 +300,38 @@ void image_white(void *p, int w, int h, int b) } } +/* + * Allocate and return an image buffer of the given image flipped horizontally + * and/or vertically. + */ +void *image_flip(const void *p, int w, int h, int b, int hflip, int vflip) +{ + unsigned char *q; + + assert(hflip || vflip); + + if (!p) + return NULL; + + if ((q = malloc(w * b * h))) + { + int r, c, i; + + for (r = 0; r < h; r++) + for (c = 0; c < w; c++) + for (i = 0; i < b; i++) + { + int pr = vflip ? h - r - 1 : r; + int pc = hflip ? w - c - 1 : c; + + int qi = r * w * b + c * b + i; + int pi = pr * w * b + pc * b + i; + + q[qi] = ((const unsigned char *) p)[pi]; + } + return q; + } + return NULL; +} + /*---------------------------------------------------------------------------*/