Use single Resource type for loading file or memory, JPEG file load improvements
This commit is contained in:
@@ -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
|
||||
@@ -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);
|
||||
|
||||
|
||||
};
|
||||
|
||||
25
project/include/io/Resource.h
Normal file
25
project/include/io/Resource.h
Normal 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
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user