* General Public License for more details.
*/
-#include <SDL.h>
#include <png.h>
#include <jpeglib.h>
+#include <stdlib.h>
+#include <assert.h>
#include "glext.h"
#include "base_config.h"
+#include "base_image.h"
+
+#include "fs.h"
+#include "fs_png.h"
+#include "fs_jpg.h"
/*---------------------------------------------------------------------------*/
int *height,
int *bytes)
{
- FILE *fp;
+ fs_file fh;
png_structp readp = NULL;
png_infop infop = NULL;
/* 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;
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);
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;
}
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;
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. */
{
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);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
- fclose(fp);
+ fs_close(fp);
}
return p;
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)
}
}
+/*
+ * 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;
+}
+
/*---------------------------------------------------------------------------*/