1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
4 // Digital Ltd. LLC
5 //
6 // All rights reserved.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
10 // met:
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // * Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 ///////////////////////////////////////////////////////////////////////////
34
35
36
37 //-----------------------------------------------------------------------------
38 //
39 // Miscellaneous helper functions for OpenEXR image file I/O
40 //
41 //-----------------------------------------------------------------------------
42
43 #include <ImfMisc.h>
44 #include <ImfHeader.h>
45 #include <ImfAttribute.h>
46 #include <ImfCompressor.h>
47 #include <ImfChannelList.h>
48 #include <ImfXdr.h>
49 #include <ImathFun.h>
50 #include <Iex.h>
51 #include <ImfStdIO.h>
52 #include <ImfConvert.h>
53 #include <ImfPartType.h>
54 #include <ImfTileDescription.h>
55 #include "ImfNamespace.h"
56
57 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
58
59 using IMATH_NAMESPACE::Box2i;
60 using IMATH_NAMESPACE::divp;
61 using IMATH_NAMESPACE::modp;
62 using std::vector;
63
64 int
pixelTypeSize(PixelType type)65 pixelTypeSize (PixelType type)
66 {
67 int size;
68
69 switch (type)
70 {
71 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
72
73 size = Xdr::size <unsigned int> ();
74 break;
75
76 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
77
78 size = Xdr::size <half> ();
79 break;
80
81 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
82
83 size = Xdr::size <float> ();
84 break;
85
86 default:
87
88 throw IEX_NAMESPACE::ArgExc ("Unknown pixel type.");
89 }
90
91 return size;
92 }
93
94
95 int
numSamples(int s,int a,int b)96 numSamples (int s, int a, int b)
97 {
98 int a1 = divp (a, s);
99 int b1 = divp (b, s);
100 return b1 - a1 + ((a1 * s < a)? 0: 1);
101 }
102
103
104 size_t
bytesPerLineTable(const Header & header,vector<size_t> & bytesPerLine)105 bytesPerLineTable (const Header &header,
106 vector<size_t> &bytesPerLine)
107 {
108 const Box2i &dataWindow = header.dataWindow();
109 const ChannelList &channels = header.channels();
110
111 bytesPerLine.resize (dataWindow.max.y - dataWindow.min.y + 1);
112
113 for (ChannelList::ConstIterator c = channels.begin();
114 c != channels.end();
115 ++c)
116 {
117 int nBytes = pixelTypeSize (c.channel().type) *
118 (dataWindow.max.x - dataWindow.min.x + 1) /
119 c.channel().xSampling;
120
121 for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
122 if (modp (y, c.channel().ySampling) == 0)
123 bytesPerLine[i] += nBytes;
124 }
125
126 size_t maxBytesPerLine = 0;
127
128 for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
129 if (maxBytesPerLine < bytesPerLine[i])
130 maxBytesPerLine = bytesPerLine[i];
131
132 return maxBytesPerLine;
133 }
134
135
136 const int&
sampleCount(const char * base,int xStride,int yStride,int x,int y)137 sampleCount(const char* base, int xStride, int yStride, int x, int y)
138 {
139 const char* ptr = base + y * yStride + x * xStride;
140 int* intPtr = (int*) ptr;
141
142 return *intPtr;
143 }
144
145 int&
sampleCount(char * base,int xStride,int yStride,int x,int y)146 sampleCount(char* base, int xStride, int yStride, int x, int y)
147 {
148 char* ptr = base + y * yStride + x * xStride;
149 int* intPtr = (int*) ptr;
150
151 return *intPtr;
152 }
153
154
155 size_t
bytesPerDeepLineTable(const Header & header,int minY,int maxY,const char * base,int xStride,int yStride,vector<size_t> & bytesPerLine)156 bytesPerDeepLineTable (const Header &header,
157 int minY, int maxY,
158 const char* base,
159 int xStride,
160 int yStride,
161 vector<size_t> &bytesPerLine)
162 {
163 const Box2i &dataWindow = header.dataWindow();
164 const ChannelList &channels = header.channels();
165
166 for (ChannelList::ConstIterator c = channels.begin();
167 c != channels.end();
168 ++c)
169 {
170 for (int y = minY; y <= maxY; ++y)
171 if (modp (y, c.channel().ySampling) == 0)
172 {
173 int nBytes = 0;
174 for (int x = dataWindow.min.x; x <= dataWindow.max.x; x++)
175 {
176 if (modp (x, c.channel().xSampling) == 0)
177 nBytes += pixelTypeSize (c.channel().type) *
178 sampleCount(base, xStride, yStride, x, y);
179 }
180 bytesPerLine[y - dataWindow.min.y] += nBytes;
181 }
182 }
183
184 size_t maxBytesPerLine = 0;
185
186 for (int y = minY; y <= maxY; ++y)
187 if (maxBytesPerLine < bytesPerLine[y - dataWindow.min.y])
188 maxBytesPerLine = bytesPerLine[y - dataWindow.min.y];
189
190 return maxBytesPerLine;
191 }
192
193
194 size_t
bytesPerDeepLineTable(const Header & header,char * base,int xStride,int yStride,vector<size_t> & bytesPerLine)195 bytesPerDeepLineTable (const Header &header,
196 char* base,
197 int xStride,
198 int yStride,
199 vector<size_t> &bytesPerLine)
200 {
201 return bytesPerDeepLineTable(header,
202 header.dataWindow().min.y,
203 header.dataWindow().max.y,
204 base,
205 xStride,
206 yStride,
207 bytesPerLine);
208 }
209
210
211 void
offsetInLineBufferTable(const vector<size_t> & bytesPerLine,int scanline1,int scanline2,int linesInLineBuffer,vector<size_t> & offsetInLineBuffer)212 offsetInLineBufferTable (const vector<size_t> &bytesPerLine,
213 int scanline1, int scanline2,
214 int linesInLineBuffer,
215 vector<size_t> &offsetInLineBuffer)
216 {
217 offsetInLineBuffer.resize (bytesPerLine.size());
218
219 size_t offset = 0;
220
221 for (int i = scanline1; i <= scanline2; ++i)
222 {
223 if (i % linesInLineBuffer == 0)
224 offset = 0;
225
226 offsetInLineBuffer[i] = offset;
227 offset += bytesPerLine[i];
228 }
229 }
230
231
232 void
offsetInLineBufferTable(const vector<size_t> & bytesPerLine,int linesInLineBuffer,vector<size_t> & offsetInLineBuffer)233 offsetInLineBufferTable (const vector<size_t> &bytesPerLine,
234 int linesInLineBuffer,
235 vector<size_t> &offsetInLineBuffer)
236 {
237 offsetInLineBufferTable (bytesPerLine,
238 0, bytesPerLine.size() - 1,
239 linesInLineBuffer,
240 offsetInLineBuffer);
241 }
242
243
244 int
lineBufferMinY(int y,int minY,int linesInLineBuffer)245 lineBufferMinY (int y, int minY, int linesInLineBuffer)
246 {
247 return ((y - minY) / linesInLineBuffer) * linesInLineBuffer + minY;
248 }
249
250
251 int
lineBufferMaxY(int y,int minY,int linesInLineBuffer)252 lineBufferMaxY (int y, int minY, int linesInLineBuffer)
253 {
254 return lineBufferMinY (y, minY, linesInLineBuffer) + linesInLineBuffer - 1;
255 }
256
257
258 Compressor::Format
defaultFormat(Compressor * compressor)259 defaultFormat (Compressor * compressor)
260 {
261 return compressor? compressor->format(): Compressor::XDR;
262 }
263
264
265 int
numLinesInBuffer(Compressor * compressor)266 numLinesInBuffer (Compressor * compressor)
267 {
268 return compressor? compressor->numScanLines(): 1;
269 }
270
271
272 void
copyIntoFrameBuffer(const char * & readPtr,char * writePtr,char * endPtr,size_t xStride,bool fill,double fillValue,Compressor::Format format,PixelType typeInFrameBuffer,PixelType typeInFile)273 copyIntoFrameBuffer (const char *& readPtr,
274 char * writePtr,
275 char * endPtr,
276 size_t xStride,
277 bool fill,
278 double fillValue,
279 Compressor::Format format,
280 PixelType typeInFrameBuffer,
281 PixelType typeInFile)
282 {
283 //
284 // Copy a horizontal row of pixels from an input
285 // file's line or tile buffer to a frame buffer.
286 //
287
288 if (fill)
289 {
290 //
291 // The file contains no data for this channel.
292 // Store a default value in the frame buffer.
293 //
294
295 switch (typeInFrameBuffer)
296 {
297 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
298
299 {
300 unsigned int fillVal = (unsigned int) (fillValue);
301
302 while (writePtr <= endPtr)
303 {
304 *(unsigned int *) writePtr = fillVal;
305 writePtr += xStride;
306 }
307 }
308 break;
309
310 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
311
312 {
313 half fillVal = half (fillValue);
314
315 while (writePtr <= endPtr)
316 {
317 *(half *) writePtr = fillVal;
318 writePtr += xStride;
319 }
320 }
321 break;
322
323 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
324
325 {
326 float fillVal = float (fillValue);
327
328 while (writePtr <= endPtr)
329 {
330 *(float *) writePtr = fillVal;
331 writePtr += xStride;
332 }
333 }
334 break;
335
336 default:
337
338 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
339 }
340 }
341 else if (format == Compressor::XDR)
342 {
343 //
344 // The the line or tile buffer is in XDR format.
345 //
346 // Convert the pixels from the file's machine-
347 // independent representation, and store the
348 // results in the frame buffer.
349 //
350
351 switch (typeInFrameBuffer)
352 {
353 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
354
355 switch (typeInFile)
356 {
357 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
358
359 while (writePtr <= endPtr)
360 {
361 Xdr::read <CharPtrIO> (readPtr, *(unsigned int *) writePtr);
362 writePtr += xStride;
363 }
364 break;
365
366 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
367
368 while (writePtr <= endPtr)
369 {
370 half h;
371 Xdr::read <CharPtrIO> (readPtr, h);
372 *(unsigned int *) writePtr = halfToUint (h);
373 writePtr += xStride;
374 }
375 break;
376
377 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
378
379 while (writePtr <= endPtr)
380 {
381 float f;
382 Xdr::read <CharPtrIO> (readPtr, f);
383 *(unsigned int *)writePtr = floatToUint (f);
384 writePtr += xStride;
385 }
386 break;
387
388 default:
389 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
390 }
391 break;
392
393 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
394
395 switch (typeInFile)
396 {
397 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
398
399 while (writePtr <= endPtr)
400 {
401 unsigned int ui;
402 Xdr::read <CharPtrIO> (readPtr, ui);
403 *(half *) writePtr = uintToHalf (ui);
404 writePtr += xStride;
405 }
406 break;
407
408 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
409
410 while (writePtr <= endPtr)
411 {
412 Xdr::read <CharPtrIO> (readPtr, *(half *) writePtr);
413 writePtr += xStride;
414 }
415 break;
416
417 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
418
419 while (writePtr <= endPtr)
420 {
421 float f;
422 Xdr::read <CharPtrIO> (readPtr, f);
423 *(half *) writePtr = floatToHalf (f);
424 writePtr += xStride;
425 }
426 break;
427 default:
428
429 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
430 }
431 break;
432
433 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
434
435 switch (typeInFile)
436 {
437 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
438
439 while (writePtr <= endPtr)
440 {
441 unsigned int ui;
442 Xdr::read <CharPtrIO> (readPtr, ui);
443 *(float *) writePtr = float (ui);
444 writePtr += xStride;
445 }
446 break;
447
448 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
449
450 while (writePtr <= endPtr)
451 {
452 half h;
453 Xdr::read <CharPtrIO> (readPtr, h);
454 *(float *) writePtr = float (h);
455 writePtr += xStride;
456 }
457 break;
458
459 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
460
461 while (writePtr <= endPtr)
462 {
463 Xdr::read <CharPtrIO> (readPtr, *(float *) writePtr);
464 writePtr += xStride;
465 }
466 break;
467 default:
468
469 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
470 }
471 break;
472
473 default:
474
475 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
476 }
477 }
478 else
479 {
480 //
481 // The the line or tile buffer is in NATIVE format.
482 // Copy the results into the frame buffer.
483 //
484
485 switch (typeInFrameBuffer)
486 {
487 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
488
489 switch (typeInFile)
490 {
491 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
492
493 while (writePtr <= endPtr)
494 {
495 for (size_t i = 0; i < sizeof (unsigned int); ++i)
496 writePtr[i] = readPtr[i];
497
498 readPtr += sizeof (unsigned int);
499 writePtr += xStride;
500 }
501 break;
502
503 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
504
505 while (writePtr <= endPtr)
506 {
507 half h = *(half *) readPtr;
508 *(unsigned int *) writePtr = halfToUint (h);
509 readPtr += sizeof (half);
510 writePtr += xStride;
511 }
512 break;
513
514 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
515
516 while (writePtr <= endPtr)
517 {
518 float f;
519
520 for (size_t i = 0; i < sizeof (float); ++i)
521 ((char *)&f)[i] = readPtr[i];
522
523 *(unsigned int *)writePtr = floatToUint (f);
524 readPtr += sizeof (float);
525 writePtr += xStride;
526 }
527 break;
528
529 default:
530
531 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
532 }
533 break;
534
535 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
536
537 switch (typeInFile)
538 {
539 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
540
541 while (writePtr <= endPtr)
542 {
543 unsigned int ui;
544
545 for (size_t i = 0; i < sizeof (unsigned int); ++i)
546 ((char *)&ui)[i] = readPtr[i];
547
548 *(half *) writePtr = uintToHalf (ui);
549 readPtr += sizeof (unsigned int);
550 writePtr += xStride;
551 }
552 break;
553
554 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
555
556 // If we're tightly packed, just memcpy
557 if (xStride == sizeof(half)) {
558 int numBytes = endPtr-writePtr+sizeof(half);
559 memcpy(writePtr, readPtr, numBytes);
560 readPtr += numBytes;
561 writePtr += numBytes;
562 } else {
563 while (writePtr <= endPtr)
564 {
565 *(half *) writePtr = *(half *)readPtr;
566 readPtr += sizeof (half);
567 writePtr += xStride;
568 }
569 }
570 break;
571
572 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
573
574 while (writePtr <= endPtr)
575 {
576 float f;
577
578 for (size_t i = 0; i < sizeof (float); ++i)
579 ((char *)&f)[i] = readPtr[i];
580
581 *(half *) writePtr = floatToHalf (f);
582 readPtr += sizeof (float);
583 writePtr += xStride;
584 }
585 break;
586 default:
587
588 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
589 }
590 break;
591
592 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
593
594 switch (typeInFile)
595 {
596 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
597
598 while (writePtr <= endPtr)
599 {
600 unsigned int ui;
601
602 for (size_t i = 0; i < sizeof (unsigned int); ++i)
603 ((char *)&ui)[i] = readPtr[i];
604
605 *(float *) writePtr = float (ui);
606 readPtr += sizeof (unsigned int);
607 writePtr += xStride;
608 }
609 break;
610
611 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
612
613 while (writePtr <= endPtr)
614 {
615 half h = *(half *) readPtr;
616 *(float *) writePtr = float (h);
617 readPtr += sizeof (half);
618 writePtr += xStride;
619 }
620 break;
621
622 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
623
624 while (writePtr <= endPtr)
625 {
626 for (size_t i = 0; i < sizeof (float); ++i)
627 writePtr[i] = readPtr[i];
628
629 readPtr += sizeof (float);
630 writePtr += xStride;
631 }
632 break;
633 default:
634
635 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
636 }
637 break;
638
639 default:
640
641 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
642 }
643 }
644 }
645
646 void
copyIntoDeepFrameBuffer(const char * & readPtr,char * base,const char * sampleCountBase,ptrdiff_t sampleCountXStride,ptrdiff_t sampleCountYStride,int y,int minX,int maxX,int xOffsetForSampleCount,int yOffsetForSampleCount,int xOffsetForData,int yOffsetForData,ptrdiff_t sampleStride,ptrdiff_t xPointerStride,ptrdiff_t yPointerStride,bool fill,double fillValue,Compressor::Format format,PixelType typeInFrameBuffer,PixelType typeInFile)647 copyIntoDeepFrameBuffer (const char *& readPtr,
648 char * base,
649 const char* sampleCountBase,
650 ptrdiff_t sampleCountXStride,
651 ptrdiff_t sampleCountYStride,
652 int y, int minX, int maxX,
653 int xOffsetForSampleCount,
654 int yOffsetForSampleCount,
655 int xOffsetForData,
656 int yOffsetForData,
657 ptrdiff_t sampleStride,
658 ptrdiff_t xPointerStride,
659 ptrdiff_t yPointerStride,
660 bool fill,
661 double fillValue,
662 Compressor::Format format,
663 PixelType typeInFrameBuffer,
664 PixelType typeInFile)
665 {
666 //
667 // Copy a horizontal row of pixels from an input
668 // file's line or tile buffer to a frame buffer.
669 //
670
671 if (fill)
672 {
673 //
674 // The file contains no data for this channel.
675 // Store a default value in the frame buffer.
676 //
677
678 switch (typeInFrameBuffer)
679 {
680 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
681
682 {
683 unsigned int fillVal = (unsigned int) (fillValue);
684
685 for (int x = minX; x <= maxX; x++)
686 {
687 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
688 if(writePtr)
689 {
690 int count = sampleCount(sampleCountBase,
691 sampleCountXStride,
692 sampleCountYStride,
693 x - xOffsetForSampleCount,
694 y - yOffsetForSampleCount);
695 for (int i = 0; i < count; i++)
696 {
697 *(unsigned int *) writePtr = fillVal;
698 writePtr += sampleStride;
699 }
700 }
701 }
702 }
703 break;
704
705 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
706
707 {
708 half fillVal = half (fillValue);
709
710 for (int x = minX; x <= maxX; x++)
711 {
712 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
713
714 if(writePtr)
715 {
716 int count = sampleCount(sampleCountBase,
717 sampleCountXStride,
718 sampleCountYStride,
719 x - xOffsetForSampleCount,
720 y - yOffsetForSampleCount);
721 for (int i = 0; i < count; i++)
722 {
723 *(half *) writePtr = fillVal;
724 writePtr += sampleStride;
725 }
726 }
727 }
728 }
729 break;
730
731 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
732
733 {
734 float fillVal = float (fillValue);
735
736 for (int x = minX; x <= maxX; x++)
737 {
738 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
739
740 if(writePtr)
741 {
742 int count = sampleCount(sampleCountBase,
743 sampleCountXStride,
744 sampleCountYStride,
745 x - xOffsetForSampleCount,
746 y - yOffsetForSampleCount);
747 for (int i = 0; i < count; i++)
748 {
749 *(float *) writePtr = fillVal;
750 writePtr += sampleStride;
751 }
752 }
753 }
754 }
755 break;
756
757 default:
758
759 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
760 }
761 }
762 else if (format == Compressor::XDR)
763 {
764 //
765 // The the line or tile buffer is in XDR format.
766 //
767 // Convert the pixels from the file's machine-
768 // independent representation, and store the
769 // results in the frame buffer.
770 //
771
772 switch (typeInFrameBuffer)
773 {
774 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
775
776 switch (typeInFile)
777 {
778 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
779
780 for (int x = minX; x <= maxX; x++)
781 {
782 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
783
784 int count = sampleCount(sampleCountBase,
785 sampleCountXStride,
786 sampleCountYStride,
787 x - xOffsetForSampleCount,
788 y - yOffsetForSampleCount);
789 if(writePtr)
790 {
791
792 for (int i = 0; i < count; i++)
793 {
794 Xdr::read <CharPtrIO> (readPtr, *(unsigned int *) writePtr);
795 writePtr += sampleStride;
796 }
797 }else{
798 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
799 }
800 }
801 break;
802
803 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
804
805 for (int x = minX; x <= maxX; x++)
806 {
807 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
808
809 int count = sampleCount(sampleCountBase,
810 sampleCountXStride,
811 sampleCountYStride,
812 x - xOffsetForSampleCount,
813 y - yOffsetForSampleCount);
814 if(writePtr)
815 {
816
817 for (int i = 0; i < count; i++)
818 {
819 half h;
820 Xdr::read <CharPtrIO> (readPtr, h);
821 *(unsigned int *) writePtr = halfToUint (h);
822 writePtr += sampleStride;
823 }
824 }else{
825 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
826 }
827 }
828 break;
829
830 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
831
832 for (int x = minX; x <= maxX; x++)
833 {
834 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
835
836 int count = sampleCount(sampleCountBase,
837 sampleCountXStride,
838 sampleCountYStride,
839 x - xOffsetForSampleCount,
840 y - yOffsetForSampleCount);
841
842 if(writePtr)
843 {
844 for (int i = 0; i < count; i++)
845 {
846 float f;
847 Xdr::read <CharPtrIO> (readPtr, f);
848 *(unsigned int *)writePtr = floatToUint (f);
849 writePtr += sampleStride;
850 }
851 }else{
852 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
853 }
854
855 }
856 break;
857 default:
858 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
859 }
860 break;
861
862 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
863
864 switch (typeInFile)
865 {
866 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
867
868 for (int x = minX; x <= maxX; x++)
869 {
870 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
871
872 int count = sampleCount(sampleCountBase,
873 sampleCountXStride,
874 sampleCountYStride,
875 x - xOffsetForSampleCount,
876 y - yOffsetForSampleCount);
877 if(writePtr)
878 {
879
880 for (int i = 0; i < count; i++)
881 {
882 unsigned int ui;
883 Xdr::read <CharPtrIO> (readPtr, ui);
884 *(half *) writePtr = uintToHalf (ui);
885 writePtr += sampleStride;
886 }
887 }else{
888 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
889 }
890 }
891 break;
892
893 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
894
895 for (int x = minX; x <= maxX; x++)
896 {
897 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
898
899 int count = sampleCount(sampleCountBase,
900 sampleCountXStride,
901 sampleCountYStride,
902 x - xOffsetForSampleCount,
903 y - yOffsetForSampleCount);
904 if(writePtr)
905 {
906
907 for (int i = 0; i < count; i++)
908 {
909 Xdr::read <CharPtrIO> (readPtr, *(half *) writePtr);
910 writePtr += sampleStride;
911 }
912 }else{
913 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
914 }
915 }
916 break;
917
918 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
919
920 for (int x = minX; x <= maxX; x++)
921 {
922 char* writePtr = *(char **) (base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
923
924 int count = sampleCount(sampleCountBase,
925 sampleCountXStride,
926 sampleCountYStride,
927 x - xOffsetForSampleCount,
928 y - yOffsetForSampleCount);
929 if(writePtr)
930 {
931 for (int i = 0; i < count; i++)
932 {
933 float f;
934 Xdr::read <CharPtrIO> (readPtr, f);
935 *(half *) writePtr = floatToHalf (f);
936 writePtr += sampleStride;
937 }
938 }else{
939 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
940 }
941 }
942 break;
943 default:
944
945 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
946 }
947 break;
948
949 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
950
951 switch (typeInFile)
952 {
953 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
954
955 for (int x = minX; x <= maxX; x++)
956 {
957 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
958
959 int count = sampleCount(sampleCountBase,
960 sampleCountXStride,
961 sampleCountYStride,
962 x - xOffsetForSampleCount,
963 y - yOffsetForSampleCount);
964 if(writePtr)
965 {
966 for (int i = 0; i < count; i++)
967 {
968 unsigned int ui;
969 Xdr::read <CharPtrIO> (readPtr, ui);
970 *(float *) writePtr = float (ui);
971 writePtr += sampleStride;
972 }
973 }else{
974 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
975 }
976 }
977 break;
978
979 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
980
981 for (int x = minX; x <= maxX; x++)
982 {
983 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
984
985 int count = sampleCount(sampleCountBase,
986 sampleCountXStride,
987 sampleCountYStride,
988 x - xOffsetForSampleCount,
989 y - yOffsetForSampleCount);
990 if(writePtr)
991 {
992
993 for (int i = 0; i < count; i++)
994 {
995 half h;
996 Xdr::read <CharPtrIO> (readPtr, h);
997 *(float *) writePtr = float (h);
998 writePtr += sampleStride;
999 }
1000
1001 }else{
1002 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
1003 }
1004 }
1005 break;
1006
1007 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1008
1009 for (int x = minX; x <= maxX; x++)
1010 {
1011 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1012
1013 int count = sampleCount(sampleCountBase,
1014 sampleCountXStride,
1015 sampleCountYStride,
1016 x - xOffsetForSampleCount,
1017 y - yOffsetForSampleCount);
1018 if(writePtr)
1019 {
1020
1021 for (int i = 0; i < count; i++)
1022 {
1023 Xdr::read <CharPtrIO> (readPtr, *(float *) writePtr);
1024 writePtr += sampleStride;
1025 }
1026 } else{
1027 Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
1028 }
1029
1030 }
1031 break;
1032 default:
1033
1034 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1035 }
1036 break;
1037
1038 default:
1039
1040 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1041 }
1042 }
1043 else
1044 {
1045 //
1046 // The the line or tile buffer is in NATIVE format.
1047 // Copy the results into the frame buffer.
1048 //
1049
1050 switch (typeInFrameBuffer)
1051 {
1052 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1053
1054 switch (typeInFile)
1055 {
1056 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1057
1058 for (int x = minX; x <= maxX; x++)
1059 {
1060 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1061
1062 int count = sampleCount(sampleCountBase,
1063 sampleCountXStride,
1064 sampleCountYStride,
1065 x - xOffsetForSampleCount,
1066 y - yOffsetForSampleCount);
1067
1068 if(writePtr)
1069 {
1070 for (int i = 0; i < count; i++)
1071 {
1072 for (size_t i = 0; i < sizeof (unsigned int); ++i)
1073 writePtr[i] = readPtr[i];
1074
1075 readPtr += sizeof (unsigned int);
1076 writePtr += sampleStride;
1077 }
1078 }else{
1079 readPtr+=sizeof(unsigned int)*count;
1080 }
1081 }
1082 break;
1083
1084 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1085
1086 for (int x = minX; x <= maxX; x++)
1087 {
1088 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1089
1090 int count = sampleCount(sampleCountBase,
1091 sampleCountXStride,
1092 sampleCountYStride,
1093 x - xOffsetForSampleCount,
1094 y - yOffsetForSampleCount);
1095
1096 if(writePtr)
1097 {
1098 for (int i = 0; i < count; i++)
1099 {
1100 half h = *(half *) readPtr;
1101 *(unsigned int *) writePtr = halfToUint (h);
1102 readPtr += sizeof (half);
1103 writePtr += sampleStride;
1104 }
1105 }else{
1106 readPtr+=sizeof(half)*count;
1107 }
1108 }
1109 break;
1110
1111 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1112
1113 for (int x = minX; x <= maxX; x++)
1114 {
1115 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1116
1117 int count = sampleCount(sampleCountBase,
1118 sampleCountXStride,
1119 sampleCountYStride,
1120 x - xOffsetForSampleCount,
1121 y - yOffsetForSampleCount);
1122
1123 if(writePtr)
1124 {
1125
1126 for (int i = 0; i < count; i++)
1127 {
1128 float f;
1129
1130 for (size_t i = 0; i < sizeof (float); ++i)
1131 ((char *)&f)[i] = readPtr[i];
1132
1133 *(unsigned int *)writePtr = floatToUint (f);
1134 readPtr += sizeof (float);
1135 writePtr += sampleStride;
1136 }
1137 }else{
1138 readPtr+=sizeof(float)*count;
1139 }
1140 }
1141 break;
1142 default:
1143
1144 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1145 }
1146 break;
1147
1148 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1149
1150 switch (typeInFile)
1151 {
1152 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1153
1154 for (int x = minX; x <= maxX; x++)
1155 {
1156 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1157
1158 int count = sampleCount(sampleCountBase,
1159 sampleCountXStride,
1160 sampleCountYStride,
1161 x - xOffsetForSampleCount,
1162 y - yOffsetForSampleCount);
1163
1164 if(writePtr)
1165 {
1166 for (int i = 0; i < count; i++)
1167 {
1168 unsigned int ui;
1169
1170 for (size_t i = 0; i < sizeof (unsigned int); ++i)
1171 ((char *)&ui)[i] = readPtr[i];
1172
1173 *(half *) writePtr = uintToHalf (ui);
1174 readPtr += sizeof (unsigned int);
1175 writePtr += sampleStride;
1176 }
1177 }else{
1178 readPtr+=sizeof(unsigned int)*count;
1179 }
1180 }
1181 break;
1182
1183 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1184
1185 for (int x = minX; x <= maxX; x++)
1186 {
1187 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1188
1189 int count = sampleCount(sampleCountBase,
1190 sampleCountXStride,
1191 sampleCountYStride,
1192 x - xOffsetForSampleCount,
1193 y - yOffsetForSampleCount);
1194
1195 if(writePtr)
1196 {
1197 for (int i = 0; i < count; i++)
1198 {
1199 *(half *) writePtr = *(half *)readPtr;
1200 readPtr += sizeof (half);
1201 writePtr += sampleStride;
1202 }
1203 }else{
1204 readPtr+=sizeof(half)*count;
1205 }
1206 }
1207 break;
1208
1209 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1210
1211 for (int x = minX; x <= maxX; x++)
1212 {
1213 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1214
1215 int count = sampleCount(sampleCountBase,
1216 sampleCountXStride,
1217 sampleCountYStride,
1218 x - xOffsetForSampleCount,
1219 y - yOffsetForSampleCount);
1220
1221 if(writePtr)
1222 {
1223 for (int i = 0; i < count; i++)
1224 {
1225 float f;
1226
1227 for (size_t i = 0; i < sizeof (float); ++i)
1228 ((char *)&f)[i] = readPtr[i];
1229
1230 *(half *) writePtr = floatToHalf (f);
1231 readPtr += sizeof (float);
1232 writePtr += sampleStride;
1233 }
1234 }else{
1235 readPtr+=sizeof(float)*count;
1236 }
1237 }
1238 break;
1239 default:
1240
1241 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1242 }
1243 break;
1244
1245 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1246
1247 switch (typeInFile)
1248 {
1249 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1250
1251 for (int x = minX; x <= maxX; x++)
1252 {
1253 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1254
1255 int count = sampleCount(sampleCountBase,
1256 sampleCountXStride,
1257 sampleCountYStride,
1258 x - xOffsetForSampleCount,
1259 y - yOffsetForSampleCount);
1260
1261 if(writePtr)
1262 {
1263 for (int i = 0; i < count; i++)
1264 {
1265 unsigned int ui;
1266
1267 for (size_t i = 0; i < sizeof (unsigned int); ++i)
1268 ((char *)&ui)[i] = readPtr[i];
1269
1270 *(float *) writePtr = float (ui);
1271 readPtr += sizeof (unsigned int);
1272 writePtr += sampleStride;
1273 }
1274 }else{
1275 readPtr+=sizeof(unsigned int)*count;
1276 }
1277 }
1278 break;
1279
1280 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1281
1282 for (int x = minX; x <= maxX; x++)
1283 {
1284 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1285
1286 int count = sampleCount(sampleCountBase,
1287 sampleCountXStride,
1288 sampleCountYStride,
1289 x - xOffsetForSampleCount,
1290 y - yOffsetForSampleCount);
1291
1292 if(writePtr)
1293 {
1294 for (int i = 0; i < count; i++)
1295 {
1296 half h = *(half *) readPtr;
1297 *(float *) writePtr = float (h);
1298 readPtr += sizeof (half);
1299 writePtr += sampleStride;
1300 }
1301 }else{
1302 readPtr+=sizeof(half)*count;
1303 }
1304 }
1305 break;
1306
1307 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1308
1309 for (int x = minX; x <= maxX; x++)
1310 {
1311 char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
1312
1313 int count = sampleCount(sampleCountBase,
1314 sampleCountXStride,
1315 sampleCountYStride,
1316 x - xOffsetForSampleCount,
1317 y - yOffsetForSampleCount);
1318
1319 if(writePtr)
1320 {
1321 for (int i = 0; i < count; i++)
1322 {
1323 for (size_t i = 0; i < sizeof (float); ++i)
1324 writePtr[i] = readPtr[i];
1325
1326 readPtr += sizeof (float);
1327 writePtr += sampleStride;
1328 }
1329 }else{
1330 readPtr+=sizeof(float)*count;
1331 }
1332 }
1333 break;
1334 default:
1335
1336 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1337 }
1338 break;
1339
1340 default:
1341
1342 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1343 }
1344 }
1345 }
1346
1347
1348 void
skipChannel(const char * & readPtr,PixelType typeInFile,size_t xSize)1349 skipChannel (const char *& readPtr,
1350 PixelType typeInFile,
1351 size_t xSize)
1352 {
1353 switch (typeInFile)
1354 {
1355 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1356
1357 Xdr::skip <CharPtrIO> (readPtr, Xdr::size <unsigned int> () * xSize);
1358 break;
1359
1360 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1361
1362 Xdr::skip <CharPtrIO> (readPtr, Xdr::size <half> () * xSize);
1363 break;
1364
1365 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1366
1367 Xdr::skip <CharPtrIO> (readPtr, Xdr::size <float> () * xSize);
1368 break;
1369
1370 default:
1371
1372 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1373 }
1374 }
1375
1376
1377 void
convertInPlace(char * & writePtr,const char * & readPtr,PixelType type,size_t numPixels)1378 convertInPlace (char *& writePtr,
1379 const char *& readPtr,
1380 PixelType type,
1381 size_t numPixels)
1382 {
1383 switch (type)
1384 {
1385 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1386
1387 for (size_t j = 0; j < numPixels; ++j)
1388 {
1389 Xdr::write <CharPtrIO> (writePtr, *(const unsigned int *) readPtr);
1390 readPtr += sizeof(unsigned int);
1391 }
1392 break;
1393
1394 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1395
1396 for (size_t j = 0; j < numPixels; ++j)
1397 {
1398 Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
1399 readPtr += sizeof(half);
1400 }
1401 break;
1402
1403 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1404
1405 for (size_t j = 0; j < numPixels; ++j)
1406 {
1407 Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
1408 readPtr += sizeof(float);
1409 }
1410 break;
1411
1412 default:
1413
1414 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1415 }
1416 }
1417
1418
1419 void
copyFromFrameBuffer(char * & writePtr,const char * & readPtr,const char * endPtr,size_t xStride,Compressor::Format format,PixelType type)1420 copyFromFrameBuffer (char *& writePtr,
1421 const char *& readPtr,
1422 const char * endPtr,
1423 size_t xStride,
1424 Compressor::Format format,
1425 PixelType type)
1426 {
1427 //
1428 // Copy a horizontal row of pixels from a frame
1429 // buffer to an output file's line or tile buffer.
1430 //
1431
1432 if (format == Compressor::XDR)
1433 {
1434 //
1435 // The the line or tile buffer is in XDR format.
1436 //
1437
1438 switch (type)
1439 {
1440 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1441
1442 while (readPtr <= endPtr)
1443 {
1444 Xdr::write <CharPtrIO> (writePtr,
1445 *(const unsigned int *) readPtr);
1446 readPtr += xStride;
1447 }
1448 break;
1449
1450 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1451
1452 while (readPtr <= endPtr)
1453 {
1454 Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
1455 readPtr += xStride;
1456 }
1457 break;
1458
1459 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1460
1461 while (readPtr <= endPtr)
1462 {
1463 Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
1464 readPtr += xStride;
1465 }
1466 break;
1467
1468 default:
1469
1470 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1471 }
1472 }
1473 else
1474 {
1475 //
1476 // The the line or tile buffer is in NATIVE format.
1477 //
1478
1479 switch (type)
1480 {
1481 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1482
1483 while (readPtr <= endPtr)
1484 {
1485 for (size_t i = 0; i < sizeof (unsigned int); ++i)
1486 *writePtr++ = readPtr[i];
1487
1488 readPtr += xStride;
1489 }
1490 break;
1491
1492 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1493
1494 while (readPtr <= endPtr)
1495 {
1496 *(half *) writePtr = *(const half *) readPtr;
1497 writePtr += sizeof (half);
1498 readPtr += xStride;
1499 }
1500 break;
1501
1502 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1503
1504 while (readPtr <= endPtr)
1505 {
1506 for (size_t i = 0; i < sizeof (float); ++i)
1507 *writePtr++ = readPtr[i];
1508
1509 readPtr += xStride;
1510 }
1511 break;
1512
1513 default:
1514
1515 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1516 }
1517 }
1518 }
1519
1520 void
copyFromDeepFrameBuffer(char * & writePtr,const char * base,char * sampleCountBase,ptrdiff_t sampleCountXStride,ptrdiff_t sampleCountYStride,int y,int xMin,int xMax,int xOffsetForSampleCount,int yOffsetForSampleCount,int xOffsetForData,int yOffsetForData,ptrdiff_t sampleStride,ptrdiff_t dataXStride,ptrdiff_t dataYStride,Compressor::Format format,PixelType type)1521 copyFromDeepFrameBuffer (char *& writePtr,
1522 const char * base,
1523 char* sampleCountBase,
1524 ptrdiff_t sampleCountXStride,
1525 ptrdiff_t sampleCountYStride,
1526 int y, int xMin, int xMax,
1527 int xOffsetForSampleCount,
1528 int yOffsetForSampleCount,
1529 int xOffsetForData,
1530 int yOffsetForData,
1531 ptrdiff_t sampleStride,
1532 ptrdiff_t dataXStride,
1533 ptrdiff_t dataYStride,
1534 Compressor::Format format,
1535 PixelType type)
1536 {
1537 //
1538 // Copy a horizontal row of pixels from a frame
1539 // buffer to an output file's line or tile buffer.
1540 //
1541
1542 if (format == Compressor::XDR)
1543 {
1544 //
1545 // The the line or tile buffer is in XDR format.
1546 //
1547
1548 switch (type)
1549 {
1550 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1551
1552 for (int x = xMin; x <= xMax; x++)
1553 {
1554 unsigned int count =
1555 sampleCount(sampleCountBase,
1556 sampleCountXStride,
1557 sampleCountYStride,
1558 x - xOffsetForSampleCount,
1559 y - yOffsetForSampleCount);
1560 const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
1561 const char* readPtr = ((const char**) ptr)[0];
1562 for (unsigned int i = 0; i < count; i++)
1563 {
1564 Xdr::write <CharPtrIO> (writePtr,
1565 *(const unsigned int *) readPtr);
1566 readPtr += sampleStride;
1567 }
1568 }
1569 break;
1570
1571 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1572
1573 for (int x = xMin; x <= xMax; x++)
1574 {
1575 unsigned int count =
1576 sampleCount(sampleCountBase,
1577 sampleCountXStride,
1578 sampleCountYStride,
1579 x - xOffsetForSampleCount,
1580 y - yOffsetForSampleCount);
1581 const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
1582 const char* readPtr = ((const char**) ptr)[0];
1583 for (unsigned int i = 0; i < count; i++)
1584 {
1585 Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
1586 readPtr += sampleStride;
1587 }
1588 }
1589 break;
1590
1591 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1592
1593 for (int x = xMin; x <= xMax; x++)
1594 {
1595 unsigned int count =
1596 sampleCount(sampleCountBase,
1597 sampleCountXStride,
1598 sampleCountYStride,
1599 x - xOffsetForSampleCount,
1600 y - yOffsetForSampleCount);
1601 const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
1602
1603 const char* readPtr = ((const char**) ptr)[0];
1604 for (unsigned int i = 0; i < count; i++)
1605 {
1606 Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
1607 readPtr += sampleStride;
1608 }
1609 }
1610 break;
1611
1612 default:
1613
1614 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1615 }
1616 }
1617 else
1618 {
1619 //
1620 // The the line or tile buffer is in NATIVE format.
1621 //
1622
1623 switch (type)
1624 {
1625 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1626
1627 for (int x = xMin; x <= xMax; x++)
1628 {
1629 unsigned int count =
1630 sampleCount(sampleCountBase,
1631 sampleCountXStride,
1632 sampleCountYStride,
1633 x - xOffsetForSampleCount,
1634 y - yOffsetForSampleCount);
1635
1636 const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
1637 const char* readPtr = ((const char**) ptr)[0];
1638 for (unsigned int i = 0; i < count; i++)
1639 {
1640 for (size_t j = 0; j < sizeof (unsigned int); ++j)
1641 *writePtr++ = readPtr[j];
1642
1643 readPtr += sampleStride;
1644 }
1645 }
1646 break;
1647
1648 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1649
1650 for (int x = xMin; x <= xMax; x++)
1651 {
1652 unsigned int count =
1653 sampleCount(sampleCountBase,
1654 sampleCountXStride,
1655 sampleCountYStride,
1656 x - xOffsetForSampleCount,
1657 y - yOffsetForSampleCount);
1658 const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
1659 const char* readPtr = ((const char**) ptr)[0];
1660 for (unsigned int i = 0; i < count; i++)
1661 {
1662 *(half *) writePtr = *(const half *) readPtr;
1663 writePtr += sizeof (half);
1664 readPtr += sampleStride;
1665 }
1666 }
1667 break;
1668
1669 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1670
1671 for (int x = xMin; x <= xMax; x++)
1672 {
1673 unsigned int count =
1674 sampleCount(sampleCountBase,
1675 sampleCountXStride,
1676 sampleCountYStride,
1677 x - xOffsetForSampleCount,
1678 y - yOffsetForSampleCount);
1679
1680 const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
1681 const char* readPtr = ((const char**) ptr)[0];
1682 for (unsigned int i = 0; i < count; i++)
1683 {
1684 for (size_t j = 0; j < sizeof (float); ++j)
1685 *writePtr++ = readPtr[j];
1686
1687 readPtr += sampleStride;
1688 }
1689 }
1690 break;
1691
1692 default:
1693
1694 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1695 }
1696 }
1697 }
1698
1699
1700 void
fillChannelWithZeroes(char * & writePtr,Compressor::Format format,PixelType type,size_t xSize)1701 fillChannelWithZeroes (char *& writePtr,
1702 Compressor::Format format,
1703 PixelType type,
1704 size_t xSize)
1705 {
1706 if (format == Compressor::XDR)
1707 {
1708 //
1709 // Fill with data in XDR format.
1710 //
1711
1712 switch (type)
1713 {
1714 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1715
1716 for (size_t j = 0; j < xSize; ++j)
1717 Xdr::write <CharPtrIO> (writePtr, (unsigned int) 0);
1718
1719 break;
1720
1721 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1722
1723 for (size_t j = 0; j < xSize; ++j)
1724 Xdr::write <CharPtrIO> (writePtr, (half) 0);
1725
1726 break;
1727
1728 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1729
1730 for (size_t j = 0; j < xSize; ++j)
1731 Xdr::write <CharPtrIO> (writePtr, (float) 0);
1732
1733 break;
1734
1735 default:
1736
1737 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1738 }
1739 }
1740 else
1741 {
1742 //
1743 // Fill with data in NATIVE format.
1744 //
1745
1746 switch (type)
1747 {
1748 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
1749
1750 for (size_t j = 0; j < xSize; ++j)
1751 {
1752 static const unsigned int ui = 0;
1753
1754 for (size_t i = 0; i < sizeof (ui); ++i)
1755 *writePtr++ = ((char *) &ui)[i];
1756 }
1757 break;
1758
1759 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
1760
1761 for (size_t j = 0; j < xSize; ++j)
1762 {
1763 *(half *) writePtr = half (0);
1764 writePtr += sizeof (half);
1765 }
1766 break;
1767
1768 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
1769
1770 for (size_t j = 0; j < xSize; ++j)
1771 {
1772 static const float f = 0;
1773
1774 for (size_t i = 0; i < sizeof (f); ++i)
1775 *writePtr++ = ((char *) &f)[i];
1776 }
1777 break;
1778
1779 default:
1780
1781 throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
1782 }
1783 }
1784 }
1785
1786 bool
usesLongNames(const Header & header)1787 usesLongNames (const Header &header)
1788 {
1789 //
1790 // If an OpenEXR file contains any attribute names, attribute type names
1791 // or channel names longer than 31 characters, then the file cannot be
1792 // read by older versions of the IlmImf library (up to OpenEXR 1.6.1).
1793 // Before writing the file header, we check if the header contains
1794 // any names longer than 31 characters; if it does, then we set the
1795 // LONG_NAMES_FLAG in the file version number. Older versions of the
1796 // IlmImf library will refuse to read files that have the LONG_NAMES_FLAG
1797 // set. Without the flag, older versions of the library would mis-
1798 // interpret the file as broken.
1799 //
1800
1801 for (Header::ConstIterator i = header.begin();
1802 i != header.end();
1803 ++i)
1804 {
1805 if (strlen (i.name()) >= 32 || strlen (i.attribute().typeName()) >= 32)
1806 return true;
1807 }
1808
1809 const ChannelList &channels = header.channels();
1810
1811 for (ChannelList::ConstIterator i = channels.begin();
1812 i != channels.end();
1813 ++i)
1814 {
1815 if (strlen (i.name()) >= 32)
1816 return true;
1817 }
1818
1819 return false;
1820 }
1821
1822 int
getScanlineChunkOffsetTableSize(const Header & header)1823 getScanlineChunkOffsetTableSize(const Header& header)
1824 {
1825 const Box2i &dataWindow = header.dataWindow();
1826
1827 vector<size_t> bytesPerLine;
1828 size_t maxBytesPerLine = bytesPerLineTable (header,
1829 bytesPerLine);
1830
1831 Compressor* compressor = newCompressor(header.compression(),
1832 maxBytesPerLine,
1833 header);
1834
1835 int linesInBuffer = numLinesInBuffer (compressor);
1836
1837 int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
1838 linesInBuffer) / linesInBuffer;
1839
1840 delete compressor;
1841
1842 return lineOffsetSize;
1843 }
1844
1845 //
1846 // Located in ImfTiledMisc.cpp
1847 //
1848 int
1849 getTiledChunkOffsetTableSize(const Header& header);
1850
1851 int
getChunkOffsetTableSize(const Header & header,bool ignore_attribute)1852 getChunkOffsetTableSize(const Header& header,bool ignore_attribute)
1853 {
1854 if(!ignore_attribute && header.hasChunkCount())
1855 {
1856 return header.chunkCount();
1857 }
1858
1859 if(header.hasType() && !isSupportedType(header.type()))
1860 {
1861 throw IEX_NAMESPACE::ArgExc ("unsupported header type to "
1862 "get chunk offset table size");
1863 }
1864 if (isTiled(header.type()) == false)
1865 return getScanlineChunkOffsetTableSize(header);
1866 else
1867 return getTiledChunkOffsetTableSize(header);
1868
1869 }
1870
1871
1872 OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
1873