Coverage Report

Created: 2026-04-01 07:24

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