[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Openexr-devel] Read OpenEXR from memory data source ?
From: |
Florian Kainz |
Subject: |
Re: [Openexr-devel] Read OpenEXR from memory data source ? |
Date: |
Mon, 07 Mar 2005 11:48:45 -0800 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3) Gecko/20030314 |
Gernot,
your Mem_IStream::read() contains two bugs:
if (n + _exrpos < _exrsize)
should read
if (n + _exrpos <= _exrsize)
and
memcpy(c, (void *)(_exrbuf[_exrpos]), n);
should read
memcpy(c, (void *)(_exrbuf + _exrpos), n);
After fixing those bugs, class Mem_IStream works
as expected (at least in my test case, see below).
The IStream base class merely stores the file name
for later use in error messages; IStream does not
check if the name is valid. Also, you should never
have to deal with endian-ness issues; those are
handled for you by the IlmImf library
By the way, to avoid unnecessary type casts, you may
want to change the type of exrbuf from "unsigned char"
to "char".
Florian
---------
class Mem_IStream: public IStream
{
public:
Mem_IStream (char *exrbuf, int exrsize):
IStream("dummy"), _exrpos (0), _exrsize(exrsize) { _exrbuf = exrbuf; }
virtual bool read (char c[], int n);
virtual Int64 tellg ();
virtual void seekg (Int64 pos);
virtual void clear ();
private:
Int64 _exrpos;
Int64 _exrsize;
char *_exrbuf;
};
bool Mem_IStream::read (char c[], int n)
{
if (n + _exrpos <= _exrsize)
{
memcpy(c, (void *)(_exrbuf + _exrpos), n);
_exrpos += n;
return true;
}
else
return false;
}
Int64 Mem_IStream::tellg ()
{
return _exrpos;
}
void Mem_IStream::seekg (Int64 pos)
{
_exrpos = pos;
}
void Mem_IStream::clear ()
{
}
void
readFile (const char inFileName[])
{
Array <char> buffer;
int n = 0;
{
ifstream is (inFileName, ios_base::binary);
is.seekg (0, ios_base::end); // error checking omitted!
n = is.tellg();
buffer.resizeErase (n);
is.seekg (0, ios_base::beg);
is.read (buffer, n);
}
Mem_IStream mis (buffer, n);
{
RgbaInputFile in (mis);
const Box2i &dw = in.dataWindow();
int w = dw.max.x - dw.min.x + 1;
int h = dw.max.y - dw.min.y + 1;
Array2D <Rgba> pixels (h, w);
in.setFrameBuffer (&pixels[-dw.min.y][-dw.min.x], 1, w);
in.readPixels (dw.min.y, dw.max.y);
}
}