~ubuntu-branches/ubuntu/saucy/openexr/saucy

« back to all changes in this revision

Viewing changes to IlmImf/ImfMisc.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adeodato Simó
  • Date: 2008-03-24 23:00:21 UTC
  • mfrom: (3.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20080324230021-gnofz9mnvcj1xlv3
Tags: 1.6.1-3
Disable (hopefully temporarily) the test suite on arm and ia64.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 
37
37
//-----------------------------------------------------------------------------
38
38
//
39
 
//      Miscellaneous image file related stuff
 
39
//      Miscellaneous helper functions for OpenEXR image file I/O
40
40
//
41
41
//-----------------------------------------------------------------------------
42
42
 
43
43
#include <ImfMisc.h>
44
44
#include <ImfHeader.h>
 
45
#include <ImfCompressor.h>
45
46
#include <ImfChannelList.h>
46
47
#include <ImfXdr.h>
47
48
#include <ImathFun.h>
48
49
#include <Iex.h>
 
50
#include <ImfStdIO.h>
 
51
#include <ImfConvert.h>
49
52
 
50
53
namespace Imf {
51
54
 
52
55
using Imath::Box2i;
 
56
using Imath::divp;
53
57
using Imath::modp;
54
58
using std::vector;
55
59
 
56
 
 
57
60
int
58
61
pixelTypeSize (PixelType type)
59
62
{
85
88
}
86
89
 
87
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
 
88
100
size_t
89
101
bytesPerLineTable (const Header &header,
90
102
                   vector<size_t> &bytesPerLine)
151
163
}
152
164
 
153
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
 
154
787
} // namespace Imf