~cosme/ubuntu/precise/freeimage/freeimage-3.15.1

« back to all changes in this revision

Viewing changes to Source/OpenEXR/IlmImf/ImfMisc.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-07-20 13:42:15 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100720134215-xt1454zaedv3b604
Tags: 3.13.1-0ubuntu1
* New upstream release. Closes: (LP: #607800)
 - Updated debian/freeimage-get-orig-source script.
 - Removing no longer necessary debian/patches/* and
   the patch system in debian/rules.
 - Updated debian/rules to work with the new Makefiles.
 - Drop from -O3 to -O2 and use lzma compression saves
   ~10 MB of free space. 
* lintian stuff
 - fixed debhelper-but-no-misc-depends
 - fixed ldconfig-symlink-missing-for-shlib

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 <ImfCompressor.h>
46
 
#include <ImfChannelList.h>
47
 
#include <ImfXdr.h>
48
 
#include <ImathFun.h>
49
 
#include <Iex.h>
50
 
#include <ImfStdIO.h>
51
 
#include <ImfConvert.h>
52
 
 
53
 
namespace Imf {
54
 
 
55
 
using Imath::Box2i;
56
 
using Imath::divp;
57
 
using Imath::modp;
58
 
using std::vector;
59
 
 
60
 
int
61
 
pixelTypeSize (PixelType type)
62
 
{
63
 
    int size;
64
 
 
65
 
    switch (type)
66
 
    {
67
 
      case UINT:
68
 
        
69
 
        size = Xdr::size <unsigned int> ();
70
 
        break;
71
 
 
72
 
      case HALF:
73
 
 
74
 
        size = Xdr::size <half> ();
75
 
        break;
76
 
 
77
 
      case FLOAT:
78
 
 
79
 
        size = Xdr::size <float> ();
80
 
        break;
81
 
 
82
 
      default:
83
 
 
84
 
        throw Iex::ArgExc ("Unknown pixel type.");
85
 
    }
86
 
 
87
 
    return size;
88
 
}
89
 
 
90
 
 
91
 
int
92
 
numSamples (int s, int a, int b)
93
 
{
94
 
    int a1 = divp (a, s);
95
 
    int b1 = divp (b, s);
96
 
    return  b1 - a1 + ((a1 * s < a)? 0: 1);
97
 
}
98
 
 
99
 
 
100
 
size_t
101
 
bytesPerLineTable (const Header &header,
102
 
                   vector<size_t> &bytesPerLine)
103
 
{
104
 
    const Box2i &dataWindow = header.dataWindow();
105
 
    const ChannelList &channels = header.channels();
106
 
 
107
 
    bytesPerLine.resize (dataWindow.max.y - dataWindow.min.y + 1);
108
 
 
109
 
    for (ChannelList::ConstIterator c = channels.begin();
110
 
         c != channels.end();
111
 
         ++c)
112
 
    {
113
 
        int nBytes = pixelTypeSize (c.channel().type) *
114
 
                     (dataWindow.max.x - dataWindow.min.x + 1) /
115
 
                     c.channel().xSampling;
116
 
 
117
 
        for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
118
 
            if (modp (y, c.channel().ySampling) == 0)
119
 
                bytesPerLine[i] += nBytes;
120
 
    }
121
 
 
122
 
    size_t maxBytesPerLine = 0;
123
 
 
124
 
    for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
125
 
        if (maxBytesPerLine < bytesPerLine[i])
126
 
            maxBytesPerLine = bytesPerLine[i];
127
 
 
128
 
    return maxBytesPerLine;
129
 
}
130
 
 
131
 
 
132
 
void
133
 
offsetInLineBufferTable (const vector<size_t> &bytesPerLine,
134
 
                         int linesInLineBuffer,
135
 
                         vector<size_t> &offsetInLineBuffer)
136
 
{
137
 
    offsetInLineBuffer.resize (bytesPerLine.size());
138
 
 
139
 
    size_t offset = 0;
140
 
 
141
 
    for (int i = 0; i < bytesPerLine.size(); ++i)
142
 
    {
143
 
        if (i % linesInLineBuffer == 0)
144
 
            offset = 0;
145
 
 
146
 
        offsetInLineBuffer[i] = offset;
147
 
        offset += bytesPerLine[i];
148
 
    }
149
 
}
150
 
 
151
 
 
152
 
int
153
 
lineBufferMinY (int y, int minY, int linesInLineBuffer)
154
 
{
155
 
    return ((y - minY) / linesInLineBuffer) * linesInLineBuffer + minY;
156
 
}
157
 
 
158
 
 
159
 
int
160
 
lineBufferMaxY (int y, int minY, int linesInLineBuffer)
161
 
{
162
 
    return lineBufferMinY (y, minY, linesInLineBuffer) + linesInLineBuffer - 1;
163
 
}
164
 
 
165
 
 
166
 
Compressor::Format
167
 
defaultFormat (Compressor * compressor)
168
 
{
169
 
    return compressor? compressor->format(): Compressor::XDR;
170
 
}
171
 
 
172
 
 
173
 
int
174
 
numLinesInBuffer (Compressor * compressor)
175
 
{
176
 
    return compressor? compressor->numScanLines(): 1;
177
 
}
178
 
 
179
 
 
180
 
void
181
 
copyIntoFrameBuffer (const char *& readPtr,
182
 
                     char * writePtr,
183
 
                     char * endPtr,
184
 
                     size_t xStride,
185
 
                     bool fill,
186
 
                     double fillValue,
187
 
                     Compressor::Format format,
188
 
                     PixelType typeInFrameBuffer,
189
 
                     PixelType typeInFile)
190
 
{
191
 
    //
192
 
    // Copy a horizontal row of pixels from an input
193
 
    // file's line or tile buffer to a frame buffer.
194
 
    //
195
 
 
196
 
    if (fill)
197
 
    {
198
 
        //
199
 
        // The file contains no data for this channel.
200
 
        // Store a default value in the frame buffer.
201
 
        //
202
 
 
203
 
        switch (typeInFrameBuffer)
204
 
        {
205
 
          case UINT:
206
 
            
207
 
            {
208
 
                unsigned int fillVal = (unsigned int) (fillValue);
209
 
 
210
 
                while (writePtr <= endPtr)
211
 
                {
212
 
                    *(unsigned int *) writePtr = fillVal;
213
 
                    writePtr += xStride;
214
 
                }
215
 
            }
216
 
            break;
217
 
 
218
 
          case HALF:
219
 
 
220
 
            {
221
 
                half fillVal = half (fillValue);
222
 
 
223
 
                while (writePtr <= endPtr)
224
 
                {
225
 
                    *(half *) writePtr = fillVal;
226
 
                    writePtr += xStride;
227
 
                }
228
 
            }
229
 
            break;
230
 
 
231
 
          case FLOAT:
232
 
 
233
 
            {
234
 
                float fillVal = float (fillValue);
235
 
 
236
 
                while (writePtr <= endPtr)
237
 
                {
238
 
                    *(float *) writePtr = fillVal;
239
 
                    writePtr += xStride;
240
 
                }
241
 
            }
242
 
            break;
243
 
 
244
 
          default:
245
 
 
246
 
            throw Iex::ArgExc ("Unknown pixel data type.");
247
 
        }
248
 
    }
249
 
    else if (format == Compressor::XDR)
250
 
    {
251
 
        //
252
 
        // The the line or tile buffer is in XDR format.
253
 
        //
254
 
        // Convert the pixels from the file's machine-
255
 
        // independent representation, and store the
256
 
        // results in the frame buffer.
257
 
        //
258
 
 
259
 
        switch (typeInFrameBuffer)
260
 
        {
261
 
          case UINT:
262
 
    
263
 
            switch (typeInFile)
264
 
            {
265
 
              case UINT:
266
 
 
267
 
                while (writePtr <= endPtr)
268
 
                {
269
 
                    Xdr::read <CharPtrIO> (readPtr, *(unsigned int *) writePtr);
270
 
                    writePtr += xStride;
271
 
                }
272
 
                break;
273
 
 
274
 
              case HALF:
275
 
 
276
 
                while (writePtr <= endPtr)
277
 
                {
278
 
                    half h;
279
 
                    Xdr::read <CharPtrIO> (readPtr, h);
280
 
                    *(unsigned int *) writePtr = halfToUint (h);
281
 
                    writePtr += xStride;
282
 
                }
283
 
                break;
284
 
 
285
 
              case FLOAT:
286
 
 
287
 
                while (writePtr <= endPtr)
288
 
                {
289
 
                    float f;
290
 
                    Xdr::read <CharPtrIO> (readPtr, f);
291
 
                    *(unsigned int *)writePtr = floatToUint (f);
292
 
                    writePtr += xStride;
293
 
                }
294
 
                break;
295
 
            }
296
 
            break;
297
 
 
298
 
          case HALF:
299
 
 
300
 
            switch (typeInFile)
301
 
            {
302
 
              case UINT:
303
 
 
304
 
                while (writePtr <= endPtr)
305
 
                {
306
 
                    unsigned int ui;
307
 
                    Xdr::read <CharPtrIO> (readPtr, ui);
308
 
                    *(half *) writePtr = uintToHalf (ui);
309
 
                    writePtr += xStride;
310
 
                }
311
 
                break;
312
 
                
313
 
              case HALF:
314
 
 
315
 
                while (writePtr <= endPtr)
316
 
                {
317
 
                    Xdr::read <CharPtrIO> (readPtr, *(half *) writePtr);
318
 
                    writePtr += xStride;
319
 
                }
320
 
                break;
321
 
 
322
 
              case FLOAT:
323
 
 
324
 
                while (writePtr <= endPtr)
325
 
                {
326
 
                    float f;
327
 
                    Xdr::read <CharPtrIO> (readPtr, f);
328
 
                    *(half *) writePtr = floatToHalf (f);
329
 
                    writePtr += xStride;
330
 
                }
331
 
                break;
332
 
            }
333
 
            break;
334
 
 
335
 
          case FLOAT:
336
 
 
337
 
            switch (typeInFile)
338
 
            {
339
 
              case UINT:
340
 
 
341
 
                while (writePtr <= endPtr)
342
 
                {
343
 
                    unsigned int ui;
344
 
                    Xdr::read <CharPtrIO> (readPtr, ui);
345
 
                    *(float *) writePtr = float (ui);
346
 
                    writePtr += xStride;
347
 
                }
348
 
                break;
349
 
 
350
 
              case HALF:
351
 
 
352
 
                while (writePtr <= endPtr)
353
 
                {
354
 
                    half h;
355
 
                    Xdr::read <CharPtrIO> (readPtr, h);
356
 
                    *(float *) writePtr = float (h);
357
 
                    writePtr += xStride;
358
 
                }
359
 
                break;
360
 
 
361
 
              case FLOAT:
362
 
 
363
 
                while (writePtr <= endPtr)
364
 
                {
365
 
                    Xdr::read <CharPtrIO> (readPtr, *(float *) writePtr);
366
 
                    writePtr += xStride;
367
 
                }
368
 
                break;
369
 
            }
370
 
            break;
371
 
 
372
 
          default:
373
 
 
374
 
            throw Iex::ArgExc ("Unknown pixel data type.");
375
 
        }
376
 
    }
377
 
    else
378
 
    {
379
 
        //
380
 
        // The the line or tile buffer is in NATIVE format.
381
 
        // Copy the results into the frame buffer.
382
 
        //
383
 
 
384
 
        switch (typeInFrameBuffer)
385
 
        {
386
 
          case UINT:
387
 
    
388
 
            switch (typeInFile)
389
 
            {
390
 
              case UINT:
391
 
 
392
 
                while (writePtr <= endPtr)
393
 
                {
394
 
                    for (size_t i = 0; i < sizeof (unsigned int); ++i)
395
 
                        writePtr[i] = readPtr[i];
396
 
 
397
 
                    readPtr += sizeof (unsigned int);
398
 
                    writePtr += xStride;
399
 
                }
400
 
                break;
401
 
 
402
 
              case HALF:
403
 
 
404
 
                while (writePtr <= endPtr)
405
 
                {
406
 
                    half h = *(half *) readPtr;
407
 
                    *(unsigned int *) writePtr = halfToUint (h);
408
 
                    readPtr += sizeof (half);
409
 
                    writePtr += xStride;
410
 
                }
411
 
                break;
412
 
 
413
 
              case FLOAT:
414
 
 
415
 
                while (writePtr <= endPtr)
416
 
                {
417
 
                    float f;
418
 
 
419
 
                    for (size_t i = 0; i < sizeof (float); ++i)
420
 
                        ((char *)&f)[i] = readPtr[i];
421
 
 
422
 
                    *(unsigned int *)writePtr = floatToUint (f);
423
 
                    readPtr += sizeof (float);
424
 
                    writePtr += xStride;
425
 
                }
426
 
                break;
427
 
            }
428
 
            break;
429
 
 
430
 
          case HALF:
431
 
 
432
 
            switch (typeInFile)
433
 
            {
434
 
              case UINT:
435
 
 
436
 
                while (writePtr <= endPtr)
437
 
                {
438
 
                    unsigned int ui;
439
 
 
440
 
                    for (size_t i = 0; i < sizeof (unsigned int); ++i)
441
 
                        ((char *)&ui)[i] = readPtr[i];
442
 
 
443
 
                    *(half *) writePtr = uintToHalf (ui);
444
 
                    readPtr += sizeof (unsigned int);
445
 
                    writePtr += xStride;
446
 
                }
447
 
                break;
448
 
 
449
 
              case HALF:
450
 
 
451
 
                while (writePtr <= endPtr)
452
 
                {
453
 
                    *(half *) writePtr = *(half *)readPtr;
454
 
                    readPtr += sizeof (half);
455
 
                    writePtr += xStride;
456
 
                }
457
 
                break;
458
 
 
459
 
              case FLOAT:
460
 
 
461
 
                while (writePtr <= endPtr)
462
 
                {
463
 
                    float f;
464
 
 
465
 
                    for (size_t i = 0; i < sizeof (float); ++i)
466
 
                        ((char *)&f)[i] = readPtr[i];
467
 
 
468
 
                    *(half *) writePtr = floatToHalf (f);
469
 
                    readPtr += sizeof (float);
470
 
                    writePtr += xStride;
471
 
                }
472
 
                break;
473
 
            }
474
 
            break;
475
 
 
476
 
          case FLOAT:
477
 
 
478
 
            switch (typeInFile)
479
 
            {
480
 
              case UINT:
481
 
 
482
 
                while (writePtr <= endPtr)
483
 
                {
484
 
                    unsigned int ui;
485
 
 
486
 
                    for (size_t i = 0; i < sizeof (unsigned int); ++i)
487
 
                        ((char *)&ui)[i] = readPtr[i];
488
 
 
489
 
                    *(float *) writePtr = float (ui);
490
 
                    readPtr += sizeof (unsigned int);
491
 
                    writePtr += xStride;
492
 
                }
493
 
                break;
494
 
 
495
 
              case HALF:
496
 
 
497
 
                while (writePtr <= endPtr)
498
 
                {
499
 
                    half h = *(half *) readPtr;
500
 
                    *(float *) writePtr = float (h);
501
 
                    readPtr += sizeof (half);
502
 
                    writePtr += xStride;
503
 
                }
504
 
                break;
505
 
 
506
 
              case FLOAT:
507
 
 
508
 
                while (writePtr <= endPtr)
509
 
                {
510
 
                    for (size_t i = 0; i < sizeof (float); ++i)
511
 
                        writePtr[i] = readPtr[i];
512
 
 
513
 
                    readPtr += sizeof (float);
514
 
                    writePtr += xStride;
515
 
                }
516
 
                break;
517
 
            }
518
 
            break;
519
 
 
520
 
          default:
521
 
 
522
 
            throw Iex::ArgExc ("Unknown pixel data type.");
523
 
        }
524
 
    }
525
 
}
526
 
 
527
 
 
528
 
void
529
 
skipChannel (const char *& readPtr,
530
 
             PixelType typeInFile,
531
 
             size_t xSize)
532
 
{
533
 
    switch (typeInFile)
534
 
    {
535
 
      case UINT:
536
 
        
537
 
        Xdr::skip <CharPtrIO> (readPtr, Xdr::size <unsigned int> () * xSize);
538
 
        break;
539
 
 
540
 
      case HALF:
541
 
 
542
 
        Xdr::skip <CharPtrIO> (readPtr, Xdr::size <half> () * xSize);
543
 
        break;
544
 
 
545
 
      case FLOAT:
546
 
 
547
 
        Xdr::skip <CharPtrIO> (readPtr, Xdr::size <float> () * xSize);
548
 
        break;
549
 
 
550
 
      default:
551
 
 
552
 
        throw Iex::ArgExc ("Unknown pixel data type.");
553
 
    }
554
 
}
555
 
 
556
 
 
557
 
void
558
 
convertInPlace (char *& writePtr,
559
 
                const char *& readPtr,
560
 
                PixelType type,
561
 
                size_t numPixels)
562
 
{
563
 
    switch (type)
564
 
    {
565
 
      case UINT:
566
 
    
567
 
        for (int j = 0; j < numPixels; ++j)
568
 
        {
569
 
            Xdr::write <CharPtrIO> (writePtr, *(const unsigned int *) readPtr);
570
 
            readPtr += sizeof(unsigned int);
571
 
        }
572
 
        break;
573
 
    
574
 
      case HALF:
575
 
    
576
 
        for (int j = 0; j < numPixels; ++j)
577
 
        {               
578
 
            Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
579
 
            readPtr += sizeof(half);
580
 
        }
581
 
        break;
582
 
    
583
 
      case FLOAT:
584
 
    
585
 
        for (int j = 0; j < numPixels; ++j)
586
 
        {
587
 
            Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
588
 
            readPtr += sizeof(float);
589
 
        }
590
 
        break;
591
 
    
592
 
      default:
593
 
    
594
 
        throw Iex::ArgExc ("Unknown pixel data type.");
595
 
    }
596
 
}
597
 
 
598
 
 
599
 
void
600
 
copyFromFrameBuffer (char *& writePtr,
601
 
                     const char *& readPtr,
602
 
                     const char * endPtr,
603
 
                     size_t xStride,
604
 
                     Compressor::Format format,
605
 
                     PixelType type)
606
 
{
607
 
    //
608
 
    // Copy a horizontal row of pixels from a frame
609
 
    // buffer to an output file's line or tile buffer.
610
 
    //
611
 
 
612
 
    if (format == Compressor::XDR)
613
 
    {
614
 
        //
615
 
        // The the line or tile buffer is in XDR format.
616
 
        //
617
 
 
618
 
        switch (type)
619
 
        {
620
 
          case UINT:
621
 
 
622
 
            while (readPtr <= endPtr)
623
 
            {
624
 
                Xdr::write <CharPtrIO> (writePtr,
625
 
                                        *(const unsigned int *) readPtr);
626
 
                readPtr += xStride;
627
 
            }
628
 
            break;
629
 
 
630
 
          case HALF:
631
 
 
632
 
            while (readPtr <= endPtr)
633
 
            {
634
 
                Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
635
 
                readPtr += xStride;
636
 
            }
637
 
            break;
638
 
 
639
 
          case FLOAT:
640
 
 
641
 
            while (readPtr <= endPtr)
642
 
            {
643
 
                Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
644
 
                readPtr += xStride;
645
 
            }
646
 
            break;
647
 
 
648
 
          default:
649
 
 
650
 
            throw Iex::ArgExc ("Unknown pixel data type.");
651
 
        }
652
 
    }
653
 
    else
654
 
    {
655
 
        //
656
 
        // The the line or tile buffer is in NATIVE format.
657
 
        //
658
 
 
659
 
        switch (type)
660
 
        {
661
 
          case UINT:
662
 
 
663
 
            while (readPtr <= endPtr)
664
 
            {
665
 
                for (size_t i = 0; i < sizeof (unsigned int); ++i)
666
 
                    *writePtr++ = readPtr[i];
667
 
 
668
 
                readPtr += xStride;
669
 
            }
670
 
            break;
671
 
 
672
 
          case HALF:
673
 
 
674
 
            while (readPtr <= endPtr)
675
 
            {
676
 
                *(half *) writePtr = *(const half *) readPtr;
677
 
                writePtr += sizeof (half);
678
 
                readPtr += xStride;
679
 
            }
680
 
            break;
681
 
 
682
 
          case FLOAT:
683
 
 
684
 
            while (readPtr <= endPtr)
685
 
            {
686
 
                for (size_t i = 0; i < sizeof (float); ++i)
687
 
                    *writePtr++ = readPtr[i];
688
 
 
689
 
                readPtr += xStride;
690
 
            }
691
 
            break;
692
 
            
693
 
          default:
694
 
 
695
 
            throw Iex::ArgExc ("Unknown pixel data type.");
696
 
        }
697
 
    }
698
 
}
699
 
 
700
 
 
701
 
void
702
 
fillChannelWithZeroes (char *& writePtr,
703
 
                       Compressor::Format format,
704
 
                       PixelType type,
705
 
                       size_t xSize)
706
 
{
707
 
    if (format == Compressor::XDR)
708
 
    {
709
 
        //
710
 
        // Fill with data in XDR format.
711
 
        //
712
 
 
713
 
        switch (type)
714
 
        {
715
 
          case UINT:
716
 
 
717
 
            for (int j = 0; j < xSize; ++j)
718
 
                Xdr::write <CharPtrIO> (writePtr, (unsigned int) 0);
719
 
 
720
 
            break;
721
 
 
722
 
          case HALF:
723
 
 
724
 
            for (int j = 0; j < xSize; ++j)
725
 
                Xdr::write <CharPtrIO> (writePtr, (half) 0);
726
 
 
727
 
            break;
728
 
 
729
 
          case FLOAT:
730
 
 
731
 
            for (int j = 0; j < xSize; ++j)
732
 
                Xdr::write <CharPtrIO> (writePtr, (float) 0);
733
 
 
734
 
            break;
735
 
            
736
 
          default:
737
 
 
738
 
            throw Iex::ArgExc ("Unknown pixel data type.");
739
 
        }
740
 
    }
741
 
    else
742
 
    {
743
 
        //
744
 
        // Fill with data in NATIVE format.
745
 
        //
746
 
 
747
 
        switch (type)
748
 
        {
749
 
          case UINT:
750
 
 
751
 
            for (int j = 0; j < xSize; ++j)
752
 
            {
753
 
                static const unsigned int ui = 0;
754
 
 
755
 
                for (size_t i = 0; i < sizeof (ui); ++i)
756
 
                    *writePtr++ = ((char *) &ui)[i];
757
 
            }
758
 
            break;
759
 
 
760
 
          case HALF:
761
 
 
762
 
            for (int j = 0; j < xSize; ++j)
763
 
            {
764
 
                *(half *) writePtr = half (0);
765
 
                writePtr += sizeof (half);
766
 
            }
767
 
            break;
768
 
 
769
 
          case FLOAT:
770
 
 
771
 
            for (int j = 0; j < xSize; ++j)
772
 
            {
773
 
                static const float f = 0;
774
 
 
775
 
                for (size_t i = 0; i < sizeof (f); ++i)
776
 
                    *writePtr++ = ((char *) &f)[i];
777
 
            }
778
 
            break;
779
 
            
780
 
          default:
781
 
 
782
 
            throw Iex::ArgExc ("Unknown pixel data type.");
783
 
        }
784
 
    }
785
 
}
786
 
 
787
 
} // namespace Imf
 
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 <ImfCompressor.h>
 
46
#include <ImfChannelList.h>
 
47
#include <ImfXdr.h>
 
48
#include <ImathFun.h>
 
49
#include <Iex.h>
 
50
#include <ImfStdIO.h>
 
51
#include <ImfConvert.h>
 
52
 
 
53
namespace Imf {
 
54
 
 
55
using Imath::Box2i;
 
56
using Imath::divp;
 
57
using Imath::modp;
 
58
using std::vector;
 
59
 
 
60
int
 
61
pixelTypeSize (PixelType type)
 
62
{
 
63
    int size;
 
64
 
 
65
    switch (type)
 
66
    {
 
67
      case UINT:
 
68
        
 
69
        size = Xdr::size <unsigned int> ();
 
70
        break;
 
71
 
 
72
      case HALF:
 
73
 
 
74
        size = Xdr::size <half> ();
 
75
        break;
 
76
 
 
77
      case FLOAT:
 
78
 
 
79
        size = Xdr::size <float> ();
 
80
        break;
 
81
 
 
82
      default:
 
83
 
 
84
        throw Iex::ArgExc ("Unknown pixel type.");
 
85
    }
 
86
 
 
87
    return size;
 
88
}
 
89
 
 
90
 
 
91
int
 
92
numSamples (int s, int a, int b)
 
93
{
 
94
    int a1 = divp (a, s);
 
95
    int b1 = divp (b, s);
 
96
    return  b1 - a1 + ((a1 * s < a)? 0: 1);
 
97
}
 
98
 
 
99
 
 
100
size_t
 
101
bytesPerLineTable (const Header &header,
 
102
                   vector<size_t> &bytesPerLine)
 
103
{
 
104
    const Box2i &dataWindow = header.dataWindow();
 
105
    const ChannelList &channels = header.channels();
 
106
 
 
107
    bytesPerLine.resize (dataWindow.max.y - dataWindow.min.y + 1);
 
108
 
 
109
    for (ChannelList::ConstIterator c = channels.begin();
 
110
         c != channels.end();
 
111
         ++c)
 
112
    {
 
113
        int nBytes = pixelTypeSize (c.channel().type) *
 
114
                     (dataWindow.max.x - dataWindow.min.x + 1) /
 
115
                     c.channel().xSampling;
 
116
 
 
117
        for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
 
118
            if (modp (y, c.channel().ySampling) == 0)
 
119
                bytesPerLine[i] += nBytes;
 
120
    }
 
121
 
 
122
    size_t maxBytesPerLine = 0;
 
123
 
 
124
    for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
 
125
        if (maxBytesPerLine < bytesPerLine[i])
 
126
            maxBytesPerLine = bytesPerLine[i];
 
127
 
 
128
    return maxBytesPerLine;
 
129
}
 
130
 
 
131
 
 
132
void
 
133
offsetInLineBufferTable (const vector<size_t> &bytesPerLine,
 
134
                         int linesInLineBuffer,
 
135
                         vector<size_t> &offsetInLineBuffer)
 
136
{
 
137
    offsetInLineBuffer.resize (bytesPerLine.size());
 
138
 
 
139
    size_t offset = 0;
 
140
 
 
141
    for (int i = 0; i < bytesPerLine.size(); ++i)
 
142
    {
 
143
        if (i % linesInLineBuffer == 0)
 
144
            offset = 0;
 
145
 
 
146
        offsetInLineBuffer[i] = offset;
 
147
        offset += bytesPerLine[i];
 
148
    }
 
149
}
 
150
 
 
151
 
 
152
int
 
153
lineBufferMinY (int y, int minY, int linesInLineBuffer)
 
154
{
 
155
    return ((y - minY) / linesInLineBuffer) * linesInLineBuffer + minY;
 
156
}
 
157
 
 
158
 
 
159
int
 
160
lineBufferMaxY (int y, int minY, int linesInLineBuffer)
 
161
{
 
162
    return lineBufferMinY (y, minY, linesInLineBuffer) + linesInLineBuffer - 1;
 
163
}
 
164
 
 
165
 
 
166
Compressor::Format
 
167
defaultFormat (Compressor * compressor)
 
168
{
 
169
    return compressor? compressor->format(): Compressor::XDR;
 
170
}
 
171
 
 
172
 
 
173
int
 
174
numLinesInBuffer (Compressor * compressor)
 
175
{
 
176
    return compressor? compressor->numScanLines(): 1;
 
177
}
 
178
 
 
179
 
 
180
void
 
181
copyIntoFrameBuffer (const char *& readPtr,
 
182
                     char * writePtr,
 
183
                     char * endPtr,
 
184
                     size_t xStride,
 
185
                     bool fill,
 
186
                     double fillValue,
 
187
                     Compressor::Format format,
 
188
                     PixelType typeInFrameBuffer,
 
189
                     PixelType typeInFile)
 
190
{
 
191
    //
 
192
    // Copy a horizontal row of pixels from an input
 
193
    // file's line or tile buffer to a frame buffer.
 
194
    //
 
195
 
 
196
    if (fill)
 
197
    {
 
198
        //
 
199
        // The file contains no data for this channel.
 
200
        // Store a default value in the frame buffer.
 
201
        //
 
202
 
 
203
        switch (typeInFrameBuffer)
 
204
        {
 
205
          case UINT:
 
206
            
 
207
            {
 
208
                unsigned int fillVal = (unsigned int) (fillValue);
 
209
 
 
210
                while (writePtr <= endPtr)
 
211
                {
 
212
                    *(unsigned int *) writePtr = fillVal;
 
213
                    writePtr += xStride;
 
214
                }
 
215
            }
 
216
            break;
 
217
 
 
218
          case HALF:
 
219
 
 
220
            {
 
221
                half fillVal = half (fillValue);
 
222
 
 
223
                while (writePtr <= endPtr)
 
224
                {
 
225
                    *(half *) writePtr = fillVal;
 
226
                    writePtr += xStride;
 
227
                }
 
228
            }
 
229
            break;
 
230
 
 
231
          case FLOAT:
 
232
 
 
233
            {
 
234
                float fillVal = float (fillValue);
 
235
 
 
236
                while (writePtr <= endPtr)
 
237
                {
 
238
                    *(float *) writePtr = fillVal;
 
239
                    writePtr += xStride;
 
240
                }
 
241
            }
 
242
            break;
 
243
 
 
244
          default:
 
245
 
 
246
            throw Iex::ArgExc ("Unknown pixel data type.");
 
247
        }
 
248
    }
 
249
    else if (format == Compressor::XDR)
 
250
    {
 
251
        //
 
252
        // The the line or tile buffer is in XDR format.
 
253
        //
 
254
        // Convert the pixels from the file's machine-
 
255
        // independent representation, and store the
 
256
        // results in the frame buffer.
 
257
        //
 
258
 
 
259
        switch (typeInFrameBuffer)
 
260
        {
 
261
          case UINT:
 
262
    
 
263
            switch (typeInFile)
 
264
            {
 
265
              case UINT:
 
266
 
 
267
                while (writePtr <= endPtr)
 
268
                {
 
269
                    Xdr::read <CharPtrIO> (readPtr, *(unsigned int *) writePtr);
 
270
                    writePtr += xStride;
 
271
                }
 
272
                break;
 
273
 
 
274
              case HALF:
 
275
 
 
276
                while (writePtr <= endPtr)
 
277
                {
 
278
                    half h;
 
279
                    Xdr::read <CharPtrIO> (readPtr, h);
 
280
                    *(unsigned int *) writePtr = halfToUint (h);
 
281
                    writePtr += xStride;
 
282
                }
 
283
                break;
 
284
 
 
285
              case FLOAT:
 
286
 
 
287
                while (writePtr <= endPtr)
 
288
                {
 
289
                    float f;
 
290
                    Xdr::read <CharPtrIO> (readPtr, f);
 
291
                    *(unsigned int *)writePtr = floatToUint (f);
 
292
                    writePtr += xStride;
 
293
                }
 
294
                break;
 
295
            }
 
296
            break;
 
297
 
 
298
          case HALF:
 
299
 
 
300
            switch (typeInFile)
 
301
            {
 
302
              case UINT:
 
303
 
 
304
                while (writePtr <= endPtr)
 
305
                {
 
306
                    unsigned int ui;
 
307
                    Xdr::read <CharPtrIO> (readPtr, ui);
 
308
                    *(half *) writePtr = uintToHalf (ui);
 
309
                    writePtr += xStride;
 
310
                }
 
311
                break;
 
312
                
 
313
              case HALF:
 
314
 
 
315
                while (writePtr <= endPtr)
 
316
                {
 
317
                    Xdr::read <CharPtrIO> (readPtr, *(half *) writePtr);
 
318
                    writePtr += xStride;
 
319
                }
 
320
                break;
 
321
 
 
322
              case FLOAT:
 
323
 
 
324
                while (writePtr <= endPtr)
 
325
                {
 
326
                    float f;
 
327
                    Xdr::read <CharPtrIO> (readPtr, f);
 
328
                    *(half *) writePtr = floatToHalf (f);
 
329
                    writePtr += xStride;
 
330
                }
 
331
                break;
 
332
            }
 
333
            break;
 
334
 
 
335
          case FLOAT:
 
336
 
 
337
            switch (typeInFile)
 
338
            {
 
339
              case UINT:
 
340
 
 
341
                while (writePtr <= endPtr)
 
342
                {
 
343
                    unsigned int ui;
 
344
                    Xdr::read <CharPtrIO> (readPtr, ui);
 
345
                    *(float *) writePtr = float (ui);
 
346
                    writePtr += xStride;
 
347
                }
 
348
                break;
 
349
 
 
350
              case HALF:
 
351
 
 
352
                while (writePtr <= endPtr)
 
353
                {
 
354
                    half h;
 
355
                    Xdr::read <CharPtrIO> (readPtr, h);
 
356
                    *(float *) writePtr = float (h);
 
357
                    writePtr += xStride;
 
358
                }
 
359
                break;
 
360
 
 
361
              case FLOAT:
 
362
 
 
363
                while (writePtr <= endPtr)
 
364
                {
 
365
                    Xdr::read <CharPtrIO> (readPtr, *(float *) writePtr);
 
366
                    writePtr += xStride;
 
367
                }
 
368
                break;
 
369
            }
 
370
            break;
 
371
 
 
372
          default:
 
373
 
 
374
            throw Iex::ArgExc ("Unknown pixel data type.");
 
375
        }
 
376
    }
 
377
    else
 
378
    {
 
379
        //
 
380
        // The the line or tile buffer is in NATIVE format.
 
381
        // Copy the results into the frame buffer.
 
382
        //
 
383
 
 
384
        switch (typeInFrameBuffer)
 
385
        {
 
386
          case UINT:
 
387
    
 
388
            switch (typeInFile)
 
389
            {
 
390
              case UINT:
 
391
 
 
392
                while (writePtr <= endPtr)
 
393
                {
 
394
                    for (size_t i = 0; i < sizeof (unsigned int); ++i)
 
395
                        writePtr[i] = readPtr[i];
 
396
 
 
397
                    readPtr += sizeof (unsigned int);
 
398
                    writePtr += xStride;
 
399
                }
 
400
                break;
 
401
 
 
402
              case HALF:
 
403
 
 
404
                while (writePtr <= endPtr)
 
405
                {
 
406
                    half h = *(half *) readPtr;
 
407
                    *(unsigned int *) writePtr = halfToUint (h);
 
408
                    readPtr += sizeof (half);
 
409
                    writePtr += xStride;
 
410
                }
 
411
                break;
 
412
 
 
413
              case FLOAT:
 
414
 
 
415
                while (writePtr <= endPtr)
 
416
                {
 
417
                    float f;
 
418
 
 
419
                    for (size_t i = 0; i < sizeof (float); ++i)
 
420
                        ((char *)&f)[i] = readPtr[i];
 
421
 
 
422
                    *(unsigned int *)writePtr = floatToUint (f);
 
423
                    readPtr += sizeof (float);
 
424
                    writePtr += xStride;
 
425
                }
 
426
                break;
 
427
            }
 
428
            break;
 
429
 
 
430
          case HALF:
 
431
 
 
432
            switch (typeInFile)
 
433
            {
 
434
              case UINT:
 
435
 
 
436
                while (writePtr <= endPtr)
 
437
                {
 
438
                    unsigned int ui;
 
439
 
 
440
                    for (size_t i = 0; i < sizeof (unsigned int); ++i)
 
441
                        ((char *)&ui)[i] = readPtr[i];
 
442
 
 
443
                    *(half *) writePtr = uintToHalf (ui);
 
444
                    readPtr += sizeof (unsigned int);
 
445
                    writePtr += xStride;
 
446
                }
 
447
                break;
 
448
 
 
449
              case HALF:
 
450
 
 
451
                while (writePtr <= endPtr)
 
452
                {
 
453
                    *(half *) writePtr = *(half *)readPtr;
 
454
                    readPtr += sizeof (half);
 
455
                    writePtr += xStride;
 
456
                }
 
457
                break;
 
458
 
 
459
              case FLOAT:
 
460
 
 
461
                while (writePtr <= endPtr)
 
462
                {
 
463
                    float f;
 
464
 
 
465
                    for (size_t i = 0; i < sizeof (float); ++i)
 
466
                        ((char *)&f)[i] = readPtr[i];
 
467
 
 
468
                    *(half *) writePtr = floatToHalf (f);
 
469
                    readPtr += sizeof (float);
 
470
                    writePtr += xStride;
 
471
                }
 
472
                break;
 
473
            }
 
474
            break;
 
475
 
 
476
          case FLOAT:
 
477
 
 
478
            switch (typeInFile)
 
479
            {
 
480
              case UINT:
 
481
 
 
482
                while (writePtr <= endPtr)
 
483
                {
 
484
                    unsigned int ui;
 
485
 
 
486
                    for (size_t i = 0; i < sizeof (unsigned int); ++i)
 
487
                        ((char *)&ui)[i] = readPtr[i];
 
488
 
 
489
                    *(float *) writePtr = float (ui);
 
490
                    readPtr += sizeof (unsigned int);
 
491
                    writePtr += xStride;
 
492
                }
 
493
                break;
 
494
 
 
495
              case HALF:
 
496
 
 
497
                while (writePtr <= endPtr)
 
498
                {
 
499
                    half h = *(half *) readPtr;
 
500
                    *(float *) writePtr = float (h);
 
501
                    readPtr += sizeof (half);
 
502
                    writePtr += xStride;
 
503
                }
 
504
                break;
 
505
 
 
506
              case FLOAT:
 
507
 
 
508
                while (writePtr <= endPtr)
 
509
                {
 
510
                    for (size_t i = 0; i < sizeof (float); ++i)
 
511
                        writePtr[i] = readPtr[i];
 
512
 
 
513
                    readPtr += sizeof (float);
 
514
                    writePtr += xStride;
 
515
                }
 
516
                break;
 
517
            }
 
518
            break;
 
519
 
 
520
          default:
 
521
 
 
522
            throw Iex::ArgExc ("Unknown pixel data type.");
 
523
        }
 
524
    }
 
525
}
 
526
 
 
527
 
 
528
void
 
529
skipChannel (const char *& readPtr,
 
530
             PixelType typeInFile,
 
531
             size_t xSize)
 
532
{
 
533
    switch (typeInFile)
 
534
    {
 
535
      case UINT:
 
536
        
 
537
        Xdr::skip <CharPtrIO> (readPtr, Xdr::size <unsigned int> () * xSize);
 
538
        break;
 
539
 
 
540
      case HALF:
 
541
 
 
542
        Xdr::skip <CharPtrIO> (readPtr, Xdr::size <half> () * xSize);
 
543
        break;
 
544
 
 
545
      case FLOAT:
 
546
 
 
547
        Xdr::skip <CharPtrIO> (readPtr, Xdr::size <float> () * xSize);
 
548
        break;
 
549
 
 
550
      default:
 
551
 
 
552
        throw Iex::ArgExc ("Unknown pixel data type.");
 
553
    }
 
554
}
 
555
 
 
556
 
 
557
void
 
558
convertInPlace (char *& writePtr,
 
559
                const char *& readPtr,
 
560
                PixelType type,
 
561
                size_t numPixels)
 
562
{
 
563
    switch (type)
 
564
    {
 
565
      case UINT:
 
566
    
 
567
        for (int j = 0; j < numPixels; ++j)
 
568
        {
 
569
            Xdr::write <CharPtrIO> (writePtr, *(const unsigned int *) readPtr);
 
570
            readPtr += sizeof(unsigned int);
 
571
        }
 
572
        break;
 
573
    
 
574
      case HALF:
 
575
    
 
576
        for (int j = 0; j < numPixels; ++j)
 
577
        {               
 
578
            Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
 
579
            readPtr += sizeof(half);
 
580
        }
 
581
        break;
 
582
    
 
583
      case FLOAT:
 
584
    
 
585
        for (int j = 0; j < numPixels; ++j)
 
586
        {
 
587
            Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
 
588
            readPtr += sizeof(float);
 
589
        }
 
590
        break;
 
591
    
 
592
      default:
 
593
    
 
594
        throw Iex::ArgExc ("Unknown pixel data type.");
 
595
    }
 
596
}
 
597
 
 
598
 
 
599
void
 
600
copyFromFrameBuffer (char *& writePtr,
 
601
                     const char *& readPtr,
 
602
                     const char * endPtr,
 
603
                     size_t xStride,
 
604
                     Compressor::Format format,
 
605
                     PixelType type)
 
606
{
 
607
    //
 
608
    // Copy a horizontal row of pixels from a frame
 
609
    // buffer to an output file's line or tile buffer.
 
610
    //
 
611
 
 
612
    if (format == Compressor::XDR)
 
613
    {
 
614
        //
 
615
        // The the line or tile buffer is in XDR format.
 
616
        //
 
617
 
 
618
        switch (type)
 
619
        {
 
620
          case UINT:
 
621
 
 
622
            while (readPtr <= endPtr)
 
623
            {
 
624
                Xdr::write <CharPtrIO> (writePtr,
 
625
                                        *(const unsigned int *) readPtr);
 
626
                readPtr += xStride;
 
627
            }
 
628
            break;
 
629
 
 
630
          case HALF:
 
631
 
 
632
            while (readPtr <= endPtr)
 
633
            {
 
634
                Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
 
635
                readPtr += xStride;
 
636
            }
 
637
            break;
 
638
 
 
639
          case FLOAT:
 
640
 
 
641
            while (readPtr <= endPtr)
 
642
            {
 
643
                Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
 
644
                readPtr += xStride;
 
645
            }
 
646
            break;
 
647
 
 
648
          default:
 
649
 
 
650
            throw Iex::ArgExc ("Unknown pixel data type.");
 
651
        }
 
652
    }
 
653
    else
 
654
    {
 
655
        //
 
656
        // The the line or tile buffer is in NATIVE format.
 
657
        //
 
658
 
 
659
        switch (type)
 
660
        {
 
661
          case UINT:
 
662
 
 
663
            while (readPtr <= endPtr)
 
664
            {
 
665
                for (size_t i = 0; i < sizeof (unsigned int); ++i)
 
666
                    *writePtr++ = readPtr[i];
 
667
 
 
668
                readPtr += xStride;
 
669
            }
 
670
            break;
 
671
 
 
672
          case HALF:
 
673
 
 
674
            while (readPtr <= endPtr)
 
675
            {
 
676
                *(half *) writePtr = *(const half *) readPtr;
 
677
                writePtr += sizeof (half);
 
678
                readPtr += xStride;
 
679
            }
 
680
            break;
 
681
 
 
682
          case FLOAT:
 
683
 
 
684
            while (readPtr <= endPtr)
 
685
            {
 
686
                for (size_t i = 0; i < sizeof (float); ++i)
 
687
                    *writePtr++ = readPtr[i];
 
688
 
 
689
                readPtr += xStride;
 
690
            }
 
691
            break;
 
692
            
 
693
          default:
 
694
 
 
695
            throw Iex::ArgExc ("Unknown pixel data type.");
 
696
        }
 
697
    }
 
698
}
 
699
 
 
700
 
 
701
void
 
702
fillChannelWithZeroes (char *& writePtr,
 
703
                       Compressor::Format format,
 
704
                       PixelType type,
 
705
                       size_t xSize)
 
706
{
 
707
    if (format == Compressor::XDR)
 
708
    {
 
709
        //
 
710
        // Fill with data in XDR format.
 
711
        //
 
712
 
 
713
        switch (type)
 
714
        {
 
715
          case UINT:
 
716
 
 
717
            for (int j = 0; j < xSize; ++j)
 
718
                Xdr::write <CharPtrIO> (writePtr, (unsigned int) 0);
 
719
 
 
720
            break;
 
721
 
 
722
          case HALF:
 
723
 
 
724
            for (int j = 0; j < xSize; ++j)
 
725
                Xdr::write <CharPtrIO> (writePtr, (half) 0);
 
726
 
 
727
            break;
 
728
 
 
729
          case FLOAT:
 
730
 
 
731
            for (int j = 0; j < xSize; ++j)
 
732
                Xdr::write <CharPtrIO> (writePtr, (float) 0);
 
733
 
 
734
            break;
 
735
            
 
736
          default:
 
737
 
 
738
            throw Iex::ArgExc ("Unknown pixel data type.");
 
739
        }
 
740
    }
 
741
    else
 
742
    {
 
743
        //
 
744
        // Fill with data in NATIVE format.
 
745
        //
 
746
 
 
747
        switch (type)
 
748
        {
 
749
          case UINT:
 
750
 
 
751
            for (int j = 0; j < xSize; ++j)
 
752
            {
 
753
                static const unsigned int ui = 0;
 
754
 
 
755
                for (size_t i = 0; i < sizeof (ui); ++i)
 
756
                    *writePtr++ = ((char *) &ui)[i];
 
757
            }
 
758
            break;
 
759
 
 
760
          case HALF:
 
761
 
 
762
            for (int j = 0; j < xSize; ++j)
 
763
            {
 
764
                *(half *) writePtr = half (0);
 
765
                writePtr += sizeof (half);
 
766
            }
 
767
            break;
 
768
 
 
769
          case FLOAT:
 
770
 
 
771
            for (int j = 0; j < xSize; ++j)
 
772
            {
 
773
                static const float f = 0;
 
774
 
 
775
                for (size_t i = 0; i < sizeof (f); ++i)
 
776
                    *writePtr++ = ((char *) &f)[i];
 
777
            }
 
778
            break;
 
779
            
 
780
          default:
 
781
 
 
782
            throw Iex::ArgExc ("Unknown pixel data type.");
 
783
        }
 
784
    }
 
785
}
 
786
 
 
787
} // namespace Imf