openexr-devel
[Top][All Lists]
Advanced

[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);
    }
}






reply via email to

[Prev in Thread] Current Thread [Next in Thread]