6464#include < ImfChannelList.h>
6565#include < Iex.h>
6666
67+ void exr_read_standard_attributes (Imf::InputFile *file, format_t *format)
68+ {
69+ format->exr_standard_attributes .dataWindow = file->header ().dataWindow ();
70+ format->exr_standard_attributes .displayWindow = file->header ().displayWindow ();
71+ format->exr_standard_attributes .pixelAspectRatio = file->header ().pixelAspectRatio ();
72+ format->exr_standard_attributes .screenWindowCenter = file->header ().screenWindowCenter ();
73+ format->exr_standard_attributes .screenWindowWidth = file->header ().screenWindowWidth ();
74+ format->exr_standard_attributes .lineOrder = file->header ().lineOrder ();
75+ format->exr_standard_attributes .compression = file->header ().compression ();
76+
77+ format->is_exr_standard_attributes_set = true ;
78+ return ;
79+ }
80+
6781bool exr_read (const char *name, float scale, ctl::dpx::fb<float > *pixels,
6882 format_t *format) {
6983 std::ifstream ins;
@@ -92,7 +106,9 @@ bool exr_read(const char *name, float scale, ctl::dpx::fb<float> *pixels,
92106 // ////////////////////////
93107
94108 Imf::InputFile file (name);
95- Imath::Box2i dw = file.header ().dataWindow ();
109+ // read the exr standard attributes for potential later use in exr_write()
110+ exr_read_standard_attributes (&file, format);
111+ Imath::Box2i dw = format->exr_standard_attributes .dataWindow ;
96112
97113 if (file.header ().channels ().begin ().channel ().type == Imf::HALF)
98114 format->src_bps =16 ;
@@ -112,30 +128,34 @@ bool exr_read(const char *name, float scale, ctl::dpx::fb<float> *pixels,
112128
113129 Imf::FrameBuffer frameBuffer;
114130 frameBuffer.insert (" R" ,
115- Imf::Slice (pixelType,
131+ Imf::Slice::Make (pixelType,
116132 (char *) pixels->ptr (),
133+ dw,
117134 xstride, ystride,
118135 1 , 1 ,
119136 0.0 ));
120137
121138 frameBuffer.insert (" G" ,
122- Imf::Slice (pixelType,
139+ Imf::Slice::Make (pixelType,
123140 (char *) (pixels->ptr ()+1 ),
141+ dw,
124142 xstride, ystride,
125143 1 , 1 ,
126144 0.0 ));
127145
128146 frameBuffer.insert (" B" ,
129- Imf::Slice (pixelType,
147+ Imf::Slice::Make (pixelType,
130148 (char *) (pixels->ptr ()+2 ),
149+ dw,
131150 xstride, ystride,
132151 1 , 1 ,
133152 0.0 ));
134153
135154 if (has_alpha){
136155 frameBuffer.insert (" A" ,
137- Imf::Slice (pixelType,
156+ Imf::Slice::Make (pixelType,
138157 (char *) (pixels->ptr ()+3 ),
158+ dw,
139159 xstride, ystride,
140160 1 , 1 ,
141161 1.0 ));
@@ -166,8 +186,8 @@ void exr_write(const char *name, float scale, const ctl::dpx::fb<float> &pixels,
166186 bool is_half = format->bps == 16 ? true : false ;
167187
168188 int depth = pixels.depth ();
169- float width = pixels.width ();
170- float height = pixels.height ();
189+ int width = pixels.width ();
190+ int height = pixels.height ();
171191 float const * pixelPtr = pixels.ptr ();
172192
173193 // Do any scaling on a full float buffer
@@ -189,13 +209,33 @@ void exr_write(const char *name, float scale, const ctl::dpx::fb<float> &pixels,
189209 Imf::PixelType pixelType = is_half ? Imf::HALF : Imf::FLOAT;
190210
191211 Imf::Header header (width, height);
192- header.compression () = (Imf::Compression)compression->exrCompressionScheme ;
212+
213+ if (format->is_exr_standard_attributes_set ) {
214+ header.dataWindow () = format->exr_standard_attributes .dataWindow ;
215+ header.displayWindow () = format->exr_standard_attributes .displayWindow ;
216+ header.pixelAspectRatio () = format->exr_standard_attributes .pixelAspectRatio ;
217+ header.screenWindowCenter () = format->exr_standard_attributes .screenWindowCenter ;
218+ header.screenWindowWidth () = format->exr_standard_attributes .screenWindowWidth ;
219+ header.lineOrder () = format->exr_standard_attributes .lineOrder ;
220+ if (true == format->is_compression_set ) {
221+ // the user specified a specific compression type
222+ header.compression () = (Imf::Compression)compression->exrCompressionScheme ;
223+ }
224+ else {
225+ header.compression () = format->exr_standard_attributes .compression ;
226+ }
227+ }
228+ else {
229+ header.compression () = (Imf::Compression)compression->exrCompressionScheme ;
230+ }
231+ Imath::Box2i dataWindow = header.dataWindow ();
193232
194233 header.channels ().insert (" R" , Imf::Channel (pixelType));
195234 header.channels ().insert (" G" , Imf::Channel (pixelType));
196235 header.channels ().insert (" B" , Imf::Channel (pixelType));
197- if (depth == 4 )
198- header.channels ().insert (" A" , Imf::Channel (pixelType));
236+ if (depth == 4 ) {
237+ header.channels ().insert (" A" , Imf::Channel (pixelType));
238+ }
199239
200240 Imf::OutputFile file (name, header);
201241 Imf::FrameBuffer frameBuffer;
@@ -219,27 +259,32 @@ void exr_write(const char *name, float scale, const ctl::dpx::fb<float> &pixels,
219259 int ystride = sizeof (*halfPixelPtr) * depth * width;
220260
221261 // Insert the half buffer into the framebuffer
222- frameBuffer.insert (" R" , Imf::Slice (pixelType, (char *)halfPixelPtr, xstride, ystride));
223- frameBuffer.insert (" G" , Imf::Slice (pixelType, (char *)(halfPixelPtr + 1 ), xstride, ystride));
224- frameBuffer.insert (" B" , Imf::Slice (pixelType, (char *)(halfPixelPtr + 2 ), xstride, ystride));
225- if (depth == 4 )
226- frameBuffer.insert (" A" , Imf::Slice (pixelType, (char *)(halfPixelPtr + 3 ), xstride, ystride));
262+ frameBuffer.insert (" R" , Imf::Slice::Make (pixelType, (char *)(halfPixelPtr + 0 ), dataWindow, xstride, ystride));
263+ frameBuffer.insert (" G" , Imf::Slice::Make (pixelType, (char *)(halfPixelPtr + 1 ), dataWindow, xstride, ystride));
264+ frameBuffer.insert (" B" , Imf::Slice::Make (pixelType, (char *)(halfPixelPtr + 2 ), dataWindow, xstride, ystride));
265+ if (depth == 4 ) {
266+ frameBuffer.insert (" A" , Imf::Slice::Make (pixelType, (char *)(halfPixelPtr + 3 ), dataWindow, xstride, ystride));
267+ }
268+
227269 }
228270 else {
229271 // No conversion needed so insert the float buffer into the frambuffer
230272 int xstride = sizeof (*pixelPtr) * depth;
231273 int ystride = sizeof (*pixelPtr) * depth * width;
232274
233- frameBuffer.insert (" R" , Imf::Slice (pixelType, (char *)pixelPtr, xstride, ystride));
234- frameBuffer.insert (" G" , Imf::Slice (pixelType, (char *)(pixelPtr + 1 ), xstride, ystride));
235- frameBuffer.insert (" B" , Imf::Slice (pixelType, (char *)(pixelPtr + 2 ), xstride, ystride));
236- if (depth == 4 )
237- frameBuffer.insert (" A" , Imf::Slice (pixelType, (char *)(pixelPtr + 3 ), xstride, ystride));
275+ frameBuffer.insert (" R" , Imf::Slice::Make (pixelType, (char *)(pixelPtr + 0 ), dataWindow, xstride, ystride));
276+ frameBuffer.insert (" G" , Imf::Slice::Make (pixelType, (char *)(pixelPtr + 1 ), dataWindow, xstride, ystride));
277+ frameBuffer.insert (" B" , Imf::Slice::Make (pixelType, (char *)(pixelPtr + 2 ), dataWindow, xstride, ystride));
278+ if (depth == 4 ) {
279+ frameBuffer.insert (" A" , Imf::Slice::Make (pixelType, (char *)(pixelPtr + 3 ), dataWindow, xstride, ystride));
280+ }
281+
238282 }
239283
240284 file.setFrameBuffer (frameBuffer);
241- file.writePixels (height );
285+ file.writePixels (dataWindow. max . y - dataWindow. min . y + 1 );
242286
287+ return ;
243288}
244289
245290#else
0 commit comments