Permalink
Browse files

implemented from memory loader

  • Loading branch information...
1 parent 3ac8786 commit af96ba8f506871fe5d7c978406ff61f256c55fd8 @crowriot committed Jan 26, 2013
Showing with 121 additions and 19 deletions.
  1. +10 −2 imagelib/imagelib.h
  2. +60 −8 imagelib/loadjpeg.c
  3. +51 −9 imagelib/loadpng.c
View
@@ -3,6 +3,8 @@
/// image lib, (c) crow_riot 2013
+#include <stddef.h>
+
typedef struct {
unsigned char* data;
@@ -26,11 +28,17 @@ typedef struct {
/// load png from disk
-image_t* loadpng(const char *filename, const imageloadersettings_t settings);
+image_t* loadpng_disk(const char *filename, const imageloadersettings_t settings);
+
+/// load png from memory
+image_t* loadpng_mem(char* buf, size_t size, const imageloadersettings_t settings);
/// load jpeg from disk
/// please not that only rgb jpeg images are suported by the loader, no color indexed ones!
-image_t* loadjpeg(const char *filename, const imageloadersettings_t settings);
+image_t* loadjpeg_disk(const char *filename, const imageloadersettings_t settings);
+
+/// load jpeg from memory
+image_t* loadjpeg_mem(char* buf, size_t size, const imageloadersettings_t settings);
#endif
View
@@ -7,15 +7,51 @@
#include <stdlib.h>
#include <stdio.h>
#include <jpeglib.h>
+#include <jerror.h>
+/// stackoverflow <3
+/// http://stackoverflow.com/questions/5280756/libjpeg-ver-6b-jpeg-stdio-src-vs-jpeg-mem-src
-image_t *loadjpeg(const char *filename, const imageloadersettings_t settings)
+/* Read JPEG image from a memory segment */
+static void init_source (j_decompress_ptr cinfo) {}
+static boolean fill_input_buffer (j_decompress_ptr cinfo)
{
- FILE *fp = fopen(filename,"rb");
- if (!fp)
- return NULL;
+ ERREXIT(cinfo, JERR_INPUT_EMPTY);
+ return TRUE;
+}
+static void skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+ struct jpeg_source_mgr* src = (struct jpeg_source_mgr*) cinfo->src;
+
+ if (num_bytes > 0) {
+ src->next_input_byte += (size_t) num_bytes;
+ src->bytes_in_buffer -= (size_t) num_bytes;
+ }
+}
+static void term_source (j_decompress_ptr cinfo) {}
+static void jpeg_mem_src (j_decompress_ptr cinfo, void* buffer, long nbytes)
+{
+ struct jpeg_source_mgr* src;
+
+ if (cinfo->src == NULL) { /* first time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ sizeof(struct jpeg_source_mgr));
+ }
+
+ src = (struct jpeg_source_mgr*) cinfo->src;
+ src->init_source = init_source;
+ src->fill_input_buffer = fill_input_buffer;
+ src->skip_input_data = skip_input_data;
+ src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ src->term_source = term_source;
+ src->bytes_in_buffer = nbytes;
+ src->next_input_byte = (JOCTET*)buffer;
+}
+image_t* loadjpeg_mem(char* buf, size_t size, const imageloadersettings_t settings)
+{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPLE *buffer;
@@ -25,20 +61,18 @@ image_t *loadjpeg(const char *filename, const imageloadersettings_t settings)
jpeg_create_decompress(&cinfo);
- jpeg_stdio_src(&cinfo,fp);
+ //jpeg_stdio_src(&cinfo,fp);
+ jpeg_mem_src(&cinfo,buf,size);
if (jpeg_read_header(&cinfo,1)!=JPEG_HEADER_OK) {
- fclose(fp);
return NULL;
}
if(!jpeg_start_decompress(&cinfo)) {
- fclose(fp);
return NULL;
}
if (cinfo.output_components!=3) {
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
- fclose(fp);
return NULL;
}
int stride = cinfo.output_width * cinfo.output_components;
@@ -93,3 +127,21 @@ image_t *loadjpeg(const char *filename, const imageloadersettings_t settings)
return image;
}
+
+
+image_t* loadjpeg_disk(const char *filename, const imageloadersettings_t settings)
+{
+ FILE *fp = fopen(filename,"rb");
+ if (!fp)
+ return NULL;
+
+ fseek(fp,0,SEEK_END);
+ size_t size = ftell(fp);
+ fseek(fp,0,SEEK_SET);
+
+ char* buf = malloc(sizeof(char)*size);
+ fread(buf,size,1,fp);
+ fclose(fp);
+
+ return loadjpeg_mem(buf,size,settings);
+}
View
@@ -5,33 +5,56 @@
#include <stdlib.h>
#include "imagelib.h"
+typedef struct
+{
+ char* data;
+ size_t size;
+ size_t offset;
+} png_memory_buffer;
+
-image_t* loadpng( const char *filepath, const imageloadersettings_t settings)
+static void png_read_data(png_structp png_ptr, png_bytep outbuffer, png_size_t bytes_to_read)
{
- FILE *fp = fopen(filepath,"rb");
- if (!fp)
- return NULL;
+ if(png_ptr->io_ptr==NULL)
+ return;
+
+ png_memory_buffer* readbuffer = (png_memory_buffer*)png_ptr->io_ptr;
+
+ if (readbuffer->offset+bytes_to_read>readbuffer->size)
+ return;
+ memcpy(outbuffer,readbuffer->data+readbuffer->offset,bytes_to_read);
+
+ readbuffer->offset += bytes_to_read;
+}
+
+
+image_t* loadpng_mem( char* buffer, size_t size, const imageloadersettings_t settings )
+{
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
if ( !png_ptr ) {
- fclose(fp);
return NULL;
}
png_infop info = png_create_info_struct(png_ptr);
if ( !info ) {
png_destroy_read_struct(&png_ptr, NULL, NULL);
- fclose(fp);
return NULL;
}
if ( setjmp(png_jmpbuf(png_ptr)) ) {
png_destroy_read_struct(&png_ptr, &info, NULL);
- fclose(fp);
return NULL;
}
- png_init_io(png_ptr,fp);
+ png_memory_buffer membuffer = {
+ .data = buffer,
+ .size = size,
+ .offset = 0
+ };
+
+ //png_init_io(png_ptr,fp);
+ png_set_read_fn(png_ptr,&membuffer,png_read_data);
png_set_sig_bytes(png_ptr,0);
@@ -60,7 +83,6 @@ image_t* loadpng( const char *filepath, const imageloadersettings_t settings)
}
if ( bytepp==0 ) {
- fclose(fp);
png_destroy_read_struct(&png_ptr, &info, NULL);
return NULL;
}
@@ -139,8 +161,28 @@ image_t* loadpng( const char *filepath, const imageloadersettings_t settings)
}
png_destroy_read_struct(&png_ptr, &info, NULL);
+
+ return image;
+}
+
+
+image_t* loadpng_disk( const char *filepath, const imageloadersettings_t settings)
+{
+ FILE *fp = fopen(filepath,"rb");
+ if (!fp)
+ return NULL;
+
+ fseek(fp,0,SEEK_END);
+ size_t size = ftell(fp);
+ fseek(fp,0,SEEK_SET);
+
+ char* buf = malloc(sizeof(char)*size);
+ fread(buf,size,1,fp);
fclose(fp);
+ image_t *image = loadpng_mem(buf,size,settings);
+ free(buf);
+
return image;
}

0 comments on commit af96ba8

Please sign in to comment.