Skip to content

Commit 97f8571

Browse files
committed
Address issues with small exr files and header parse
If we know the file size, we should truncate the header parse to only read the file at most. Otherwise, if the file size is unknown (stream) then be conservative (and slower) and read 1 byte at a time for the header parse. Once we know the file, that should be free to read chunks Signed-off-by: Kimball Thurston <[email protected]>
1 parent 1982b6f commit 97f8571

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

src/lib/OpenEXR/ImfContextInit.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,27 @@ istream_nonparallel_read (
118118
}
119119
}
120120

121+
int64_t stream_sz = s->size ();
122+
int64_t nend = nread + (int64_t)sz;
123+
if (stream_sz > 0 && nend > stream_sz)
124+
{
125+
sz = stream_sz - nend;
126+
}
127+
121128
try
122129
{
123-
s->read (static_cast<char*> (buffer), static_cast<int> (sz));
130+
if (s->isMemoryMapped ())
131+
{
132+
char* data = s->readMemoryMapped (static_cast<int> (sz));
133+
// TODO: in a future release, pass this through to
134+
// core directly
135+
if (data)
136+
memcpy (buffer, data, sz);
137+
}
138+
else
139+
{
140+
s->read (static_cast<char*> (buffer), static_cast<int> (sz));
141+
}
124142
}
125143
catch (...)
126144
{

src/lib/OpenEXRCore/parse_header.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ scratch_seq_read (struct _internal_exr_seq_scratch* scr, void* buf, uint64_t sz)
103103
outbuf += nCopy;
104104
nCopied += nCopy;
105105
}
106-
else if (notdone > SCRATCH_BUFFER_SIZE)
106+
else if (notdone >= SCRATCH_BUFFER_SIZE)
107107
{
108108
uint64_t nPages = notdone / SCRATCH_BUFFER_SIZE;
109109
int64_t nread = 0;
@@ -126,10 +126,28 @@ scratch_seq_read (struct _internal_exr_seq_scratch* scr, void* buf, uint64_t sz)
126126
else
127127
{
128128
int64_t nread = 0;
129-
rv = scr->ctxt->do_read (
129+
uint64_t toread = SCRATCH_BUFFER_SIZE;
130+
131+
if (scr->ctxt->file_size > 0)
132+
{
133+
if ((scr->fileoff + SCRATCH_BUFFER_SIZE) > scr->ctxt->file_size)
134+
{
135+
toread = scr->ctxt->file_size - scr->fileoff;
136+
}
137+
}
138+
else
139+
{
140+
/*
141+
* hrm, stream only with no known size, just read 1 byte at a
142+
* time to be safer
143+
*/
144+
toread = 1;
145+
}
146+
147+
rv = scr->ctxt->do_read (
130148
scr->ctxt,
131149
scr->scratch,
132-
SCRATCH_BUFFER_SIZE,
150+
toread,
133151
&(scr->fileoff),
134152
&nread,
135153
EXR_ALLOW_SHORT_READ);

src/lib/OpenEXRUtil/ImfCheckFile.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,8 @@ class PtrIStream : public IStream
975975

976976
virtual bool isMemoryMapped () const { return false; }
977977

978+
virtual int64_t size () { return end - base; }
979+
978980
virtual char* readMemoryMapped (int n)
979981
{
980982

0 commit comments

Comments
 (0)