Commit 0e83b127 authored by Martin Blanchard's avatar Martin Blanchard
Browse files

datastream: Add new LibRaw_proxy_datastream

The purpose of this new datastream type is to let the caller handle IO
operations, using the C API, by implementing a series of simples callbacks.
Caller must provide 7 procedures in order to get a complete datastream:
read_proc, seek_proc, size_proc, eof_proc, close_proc, fname_proc and
open_proc (for substream). get_char(), gets() and scanf() are build
around provided read_proc.
parent f75c1b86
......@@ -51,6 +51,7 @@ DllDef const char *libraw_strerror(int errorcode);
DllDef const char *libraw_strprogress(enum LibRaw_progress);
/* LibRaw C API */
DllDef libraw_data_t *libraw_init(unsigned int flags);
DllDef int libraw_open_proxy(libraw_data_t*, void*, read_proc, seek_proc, size_proc, eof_proc, close_proc, fname_proc, open_proc);
DllDef int libraw_open_file(libraw_data_t*, const char *);
DllDef int libraw_open_file_ex(libraw_data_t*, const char *, INT64 max_buff_sz);
#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
......@@ -124,6 +125,7 @@ class DllDef LibRaw
LibRaw(unsigned int flags = LIBRAW_OPTIONS_NONE);
libraw_output_params_t* output_params_ptr() { return &imgdata.params;}
int open_proxy(void*, read_proc, seek_proc, size_proc, eof_proc, close_proc, fname_proc, open_proc);
int open_file(const char *fname, INT64 max_buffered_sz=LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE);
#if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) && (_MSC_VER > 1310)
int open_file(const wchar_t *fname, INT64 max_buffered_sz=LIBRAW_USE_STREAMS_DATASTREAM_MAXSIZE);
......
......@@ -110,6 +110,44 @@ class DllDef LibRaw_abstract_datastream
template class DllDef std::auto_ptr<std::streambuf>;
#endif
class DllDef LibRaw_proxy_datastream: public LibRaw_abstract_datastream
{
public:
LibRaw_proxy_datastream(void*, read_proc, seek_proc, size_proc, eof_proc, close_proc, fname_proc, open_proc);
virtual ~LibRaw_proxy_datastream();
virtual int valid() { return (read_cb) ? 1 : 0; };
virtual int read(void *,size_t, size_t);
virtual int seek(INT64, int);
virtual INT64 tell();
virtual INT64 size();
virtual int get_char();
virtual char* gets(char *, int);
virtual int scanf_one(const char *, void *);
virtual int eof() { return eof_cb ? eof_cb(udata) : -1; };
/* Not supported */
virtual void * make_jas_stream() { return NULL; };
virtual int jpeg_src(void *) { return -1; };
virtual const char* fname() { return fname_cb ? fname_cb(udata) : NULL; };
virtual int subfile_open(const char*);
virtual void subfile_close();
private:
read_proc read_cb;
seek_proc seek_cb;
size_proc size_cb;
eof_proc eof_cb;
close_proc close_cb;
fname_proc fname_cb;
open_proc open_cb;
void* udata;
};
class DllDef LibRaw_file_datastream: public LibRaw_abstract_datastream
{
protected:
......
......@@ -110,6 +110,17 @@ typedef struct
} libraw_internal_output_params_t;
typedef int (*read_proc)(void*, void*,size_t);
typedef INT64 (*seek_proc)(void*, INT64, int);
typedef INT64 (*size_proc)(void*);
typedef int (*eof_proc)(void*);
typedef void (*close_proc)(void*, int);
typedef const char* (*fname_proc)(void*);
typedef int (*open_proc)(void*, const char*);
typedef void (* memory_callback)(void * data, const char *file, const char *where);
typedef void (*exif_parser_callback) (void *context, int tag, int type, int len,unsigned int ord, void *ifp);
......
......@@ -62,6 +62,14 @@ extern "C"
ip->subtract_black();
}
int libraw_open_proxy(libraw_data_t* lr, void* data, read_proc read_cb,
seek_proc seek_cb, size_proc size_cb, eof_proc eof_cb,
close_proc close_cb, fname_proc fname_cb, open_proc open_cb)
{
if(!lr) return EINVAL;
LibRaw *ip = (LibRaw*) lr->parent_class;
return ip->open_proxy(data, read_cb, seek_cb, size_cb, eof_cb, close_cb, fname_cb, open_cb);
}
int libraw_open_file(libraw_data_t* lr, const char *file)
{
......
......@@ -879,7 +879,41 @@ void LibRaw:: merror (void *ptr, const char *where)
throw LIBRAW_EXCEPTION_ALLOC;
}
int LibRaw::open_proxy(void* udata, read_proc read_cb, seek_proc seek_cb,
size_proc size_cb, eof_proc eof_cb, close_proc close_cb,
fname_proc fname_cb, open_proc open_cb)
{
LibRaw_abstract_datastream *stream;
try {
stream = new LibRaw_proxy_datastream(udata, read_cb, seek_cb,
size_cb, eof_cb, close_cb,
fname_cb, open_cb);
}
catch (std::bad_alloc)
{
recycle();
return LIBRAW_UNSUFFICIENT_MEMORY;
}
if(!stream->valid())
{
delete stream;
return LIBRAW_IO_ERROR;
}
ID.input_internal = 0; // preserve from deletion on error
int ret = open_datastream(stream);
if (ret == LIBRAW_SUCCESS)
{
ID.input_internal =1 ; // flag to delete datastream on recycle
}
else
{
delete stream;
ID.input_internal = 0;
}
return ret;
}
int LibRaw::open_file(const char *fname, INT64 max_buf_size)
{
......
......@@ -55,6 +55,116 @@ void LibRaw_abstract_datastream::tempbuffer_close()
substream = NULL;
}
// == LibRaw_proxy_datastream ==
LibRaw_proxy_datastream::LibRaw_proxy_datastream(void *u, read_proc read, seek_proc seek,
size_proc size, eof_proc eof, close_proc close,
fname_proc fname, open_proc open) : udata(u)
{
if (read) read_cb = read; else read_cb = NULL;
if (seek) seek_cb = seek; else seek_cb = NULL;
if (size) size_cb = size; else size_cb = NULL;
if (eof) eof_cb = eof; else eof_cb = NULL;
if (close) close_cb = close; else close_cb = NULL;
if (fname) fname_cb = fname; else fname_cb = NULL;
if (open) open_cb = open; else open_cb = NULL;
}
LibRaw_proxy_datastream::~LibRaw_proxy_datastream()
{
if (close_cb) close_cb(udata, 0);
}
int LibRaw_proxy_datastream::read(void* ptr,size_t sz, size_t nmemb)
{
if (!read_cb) return -1;
size_t to_read = sz * nmemb;
if (to_read < 1)
return 0;
return read_cb(udata, ptr, to_read);
}
int LibRaw_proxy_datastream::seek(INT64 o, int whence)
{
if (!seek_cb) return -1;
return (int)seek_cb(udata, o, whence);
}
INT64 LibRaw_proxy_datastream::tell()
{
if (!seek_cb) return -1;
return seek_cb(udata, 0, SEEK_CUR);
}
INT64 LibRaw_proxy_datastream::size()
{
if (!size_cb) return -1;
return size_cb(udata);
}
int LibRaw_proxy_datastream::get_char()
{
if (!read_cb) return -1;
char b[sizeof(char)];
if (read_cb(udata, (void*)b, sizeof(b))) return -1;
return (int)b[0];
}
char* LibRaw_proxy_datastream::gets(char *str, int sz)
{
if (!read_cb) return NULL;
char b[sizeof(char)],*pdest;
pdest = str;
while (int(pdest-str) < sz)
{
if(read_cb(udata, (void*)b, sizeof(b))) return NULL;
*pdest = (char)b[0];
if(b[0] == '\0' || b[0] == '\n')
break;
pdest++;
}
if((pdest-str) < sz)
*(++pdest)=0;
return str;
}
int LibRaw_proxy_datastream::scanf_one(const char *fmt, void* val)
{
if (!read_cb) return -1;
/* HUGE ASSUMPTION: *fmt is either "%d" or "%f" */
if (strcmp(fmt, "%d") == 0) {
char b[sizeof(int)];
if (read_cb(udata, b, sizeof(b))) return -1;
*(static_cast<int*>(val)) = b[0];
} else {
char b[sizeof(float)];
if (read_cb(udata, b, sizeof(b))) return -1;
*(static_cast<float*>(val)) = b[0];
}
return 1;
}
int LibRaw_proxy_datastream::subfile_open(const char *fn)
{
if (!open_cb) return -1;
return open_cb(udata, fn);
}
void LibRaw_proxy_datastream::subfile_close()
{
if (close_cb) close_cb(udata, 1);
}
// == LibRaw_file_datastream ==
LibRaw_file_datastream::~LibRaw_file_datastream()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment