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