Use single Resource type for loading file or memory, JPEG file load improvements

This commit is contained in:
Joshua Granick
2014-07-27 16:32:13 -07:00
parent d0163f24e0
commit df3ba5992f
6 changed files with 192 additions and 27 deletions

View File

@@ -2,23 +2,25 @@
#define LIME_GRAPHICS_JPEG_H
#include <graphics/Image.h>
#include <io/Resource.h>
namespace lime {
class Image;
class JPEG {
public:
static bool Decode (const char *path, Image *image);
static bool Decode (Resource *resource, Image *image);
};
}
#endif
#endif

View File

@@ -2,17 +2,19 @@
#define LIME_GRAPHICS_PNG_H
#include <graphics/Image.h>
#include <io/Resource.h>
namespace lime {
class Image;
class PNG {
public:
static bool Decode (const char *path, Image *image);
static bool Decode (Resource *resource, Image *image);
};

View File

@@ -0,0 +1,25 @@
#ifndef LIME_IO_RESOURCE_H
#define LIME_IO_RESOURCE_H
#include <utils/ByteArray.h>
namespace lime {
struct Resource {
Resource (const char* path) { this->path = path; }
Resource (ByteArray *data) { this->data = data; }
ByteArray *data;
const char* path;
};
}
#endif

View File

@@ -57,10 +57,10 @@ namespace lime {
value lime_image_load (value path) {
Image image;
const char *filePath = val_string (path);
Resource resource = Resource (val_string (path));
#ifdef LIME_PNG
if (PNG::Decode (filePath, &image)) {
if (PNG::Decode (&resource, &image)) {
return image.Value ();
@@ -68,7 +68,7 @@ namespace lime {
#endif
#ifdef LIME_JPEG
if (JPEG::Decode (filePath, &image)) {
if (JPEG::Decode (&resource, &image)) {
return image.Value ();

View File

@@ -6,7 +6,7 @@ extern "C" {
}
#include <graphics/Image.h>
#include <setjmp.h>
#include <graphics/JPEG.h>
#include <utils/FileIO.h>
@@ -14,19 +14,155 @@ extern "C" {
namespace lime {
bool JPEG::Decode (const char *path, Image *image) {
struct ErrorData {
struct jpeg_error_mgr base;
jmp_buf on_error;
};
static void OnOutput (j_common_ptr cinfo) {}
static void OnError (j_common_ptr cinfo) {
ErrorData * err = (ErrorData *)cinfo->err;
longjmp (err->on_error, 1);
}
struct MySrcManager {
MySrcManager (const JOCTET *inData, int inLen) : mData (inData), mLen (inLen) {
pub.init_source = my_init_source;
pub.fill_input_buffer = my_fill_input_buffer;
pub.skip_input_data = my_skip_input_data;
pub.resync_to_restart = my_resync_to_restart;
pub.term_source = my_term_source;
pub.next_input_byte = 0;
pub.bytes_in_buffer = 0;
mUsed = false;
mEOI[0] = 0xff;
mEOI[1] = JPEG_EOI;
}
struct jpeg_source_mgr pub; /* public fields */
const JOCTET * mData;
size_t mLen;
bool mUsed;
unsigned char mEOI[2];
static void my_init_source (j_decompress_ptr cinfo) {
MySrcManager *man = (MySrcManager *)cinfo->src;
man->mUsed = false;
}
static boolean my_fill_input_buffer (j_decompress_ptr cinfo) {
MySrcManager *man = (MySrcManager *)cinfo->src;
if (man->mUsed) {
man->pub.next_input_byte = man->mEOI;
man->pub.bytes_in_buffer = 2;
} else {
man->pub.next_input_byte = man->mData;
man->pub.bytes_in_buffer = man->mLen;
man->mUsed = true;
}
return true;
}
static void my_skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
MySrcManager *man = (MySrcManager *)cinfo->src;
man->pub.next_input_byte += num_bytes;
man->pub.bytes_in_buffer -= num_bytes;
// was < 0 and was always false PJK 16JUN12
if (man->pub.bytes_in_buffer == 0) {
man->pub.next_input_byte = man->mEOI;
man->pub.bytes_in_buffer = 2;
}
}
static boolean my_resync_to_restart (j_decompress_ptr cinfo, int desired) {
MySrcManager *man = (MySrcManager *)cinfo->src;
man->mUsed = false;
return true;
}
static void my_term_source (j_decompress_ptr cinfo) {}
};
bool JPEG::Decode (Resource *resource, Image* image) {
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *file = lime::fopen (path, "rb");
//struct jpeg_error_mgr jerr;
//cinfo.err = jpeg_std_error (&jerr);
struct ErrorData jpegError;
jpegError.base.error_exit = OnError;
jpegError.base.output_message = OnOutput;
cinfo.err = jpeg_std_error (&jpegError.base);
FILE *file;
if (setjmp (jpegError.on_error)) {
if (file)
lime::fclose (file);
jpeg_destroy_decompress (&cinfo);
return false;
}
cinfo.err = jpeg_std_error (&jerr);
jpeg_create_decompress (&cinfo);
jpeg_stdio_src (&cinfo, file);
if (resource->path) {
file = lime::fopen (resource->path, "rb");
jpeg_stdio_src (&cinfo, file);
} else {
MySrcManager manager (resource->data->Bytes (), resource->data->Size ());
cinfo.src = &manager.pub;
}
bool decoded = false;
if (jpeg_read_header (&cinfo, TRUE) == JPEG_HEADER_OK) {
cinfo.out_color_space = JCS_RGB;
jpeg_start_decompress (&cinfo);
int components = cinfo.num_components;
image->Resize (cinfo.output_width, cinfo.output_height);
@@ -56,13 +192,14 @@ namespace lime {
delete[] scanline;
jpeg_finish_decompress (&cinfo);
decoded = true;
}
lime::fclose (file);
jpeg_destroy_decompress (&cinfo);
return true;
return decoded;
}

View File

@@ -5,7 +5,6 @@ extern "C" {
}
#include <graphics/Image.h>
#include <graphics/PNG.h>
#include <utils/FileIO.h>
@@ -13,7 +12,7 @@ extern "C" {
namespace lime {
bool PNG::Decode (const char *path, Image *image) {
bool PNG::Decode (Resource *resource, Image *image) {
unsigned char png_sig[PNG_SIG_SIZE];
png_structp png_ptr;
@@ -21,7 +20,7 @@ namespace lime {
png_uint_32 width, height;
int bit_depth, color_type;
FILE *file = lime::fopen (path, "rb");
FILE *file = lime::fopen (resource->path, "rb");
if (!file) return false;
// verify the PNG signature