~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/3rdparty/openexr/IlmImf/ImfRgbaFile.cpp

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 
4
// Digital Ltd. LLC
 
5
//
 
6
// All rights reserved.
 
7
//
 
8
// Redistribution and use in source and binary forms, with or without
 
9
// modification, are permitted provided that the following conditions are
 
10
// met:
 
11
// *       Redistributions of source code must retain the above copyright
 
12
// notice, this list of conditions and the following disclaimer.
 
13
// *       Redistributions in binary form must reproduce the above
 
14
// copyright notice, this list of conditions and the following disclaimer
 
15
// in the documentation and/or other materials provided with the
 
16
// distribution.
 
17
// *       Neither the name of Industrial Light & Magic nor the names of
 
18
// its contributors may be used to endorse or promote products derived
 
19
// from this software without specific prior written permission.
 
20
//
 
21
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
22
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
23
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
24
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
25
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
26
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
27
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
28
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
29
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
30
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
31
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
32
//
 
33
///////////////////////////////////////////////////////////////////////////
 
34
 
 
35
//-----------------------------------------------------------------------------
 
36
//
 
37
//      class RgbaOutputFile
 
38
//      class RgbaInputFile
 
39
//
 
40
//-----------------------------------------------------------------------------
 
41
 
 
42
#include <ImfRgbaFile.h>
 
43
#include <ImfOutputFile.h>
 
44
#include <ImfInputFile.h>
 
45
#include <ImfChannelList.h>
 
46
#include <ImfRgbaYca.h>
 
47
#include <ImfStandardAttributes.h>
 
48
#include <ImathFun.h>
 
49
#include <IlmThreadMutex.h>
 
50
#include <Iex.h>
 
51
#include <string.h>
 
52
#include <algorithm>
 
53
 
 
54
 
 
55
namespace Imf {
 
56
 
 
57
using namespace std;
 
58
using namespace Imath;
 
59
using namespace RgbaYca;
 
60
using namespace IlmThread;
 
61
 
 
62
namespace {
 
63
 
 
64
void
 
65
insertChannels (Header &header, RgbaChannels rgbaChannels)
 
66
{
 
67
    ChannelList ch;
 
68
 
 
69
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
70
    {
 
71
    if (rgbaChannels & WRITE_Y)
 
72
    {
 
73
        ch.insert ("Y", Channel (HALF, 1, 1));
 
74
    }
 
75
 
 
76
    if (rgbaChannels & WRITE_C)
 
77
    {
 
78
        ch.insert ("RY", Channel (HALF, 2, 2, true));
 
79
        ch.insert ("BY", Channel (HALF, 2, 2, true));
 
80
    }
 
81
    }
 
82
    else
 
83
    {
 
84
    if (rgbaChannels & WRITE_R)
 
85
        ch.insert ("R", Channel (HALF, 1, 1));
 
86
 
 
87
    if (rgbaChannels & WRITE_G)
 
88
        ch.insert ("G", Channel (HALF, 1, 1));
 
89
 
 
90
    if (rgbaChannels & WRITE_B)
 
91
        ch.insert ("B", Channel (HALF, 1, 1));
 
92
    }
 
93
 
 
94
    if (rgbaChannels & WRITE_A)
 
95
    ch.insert ("A", Channel (HALF, 1, 1));
 
96
 
 
97
    header.channels() = ch;
 
98
}
 
99
 
 
100
 
 
101
RgbaChannels
 
102
rgbaChannels (const ChannelList &ch, const string &channelNamePrefix = "")
 
103
{
 
104
    int i = 0;
 
105
 
 
106
    if (ch.findChannel (channelNamePrefix + "R"))
 
107
    i |= WRITE_R;
 
108
 
 
109
    if (ch.findChannel (channelNamePrefix + "G"))
 
110
    i |= WRITE_G;
 
111
 
 
112
    if (ch.findChannel (channelNamePrefix + "B"))
 
113
    i |= WRITE_B;
 
114
 
 
115
    if (ch.findChannel (channelNamePrefix + "A"))
 
116
    i |= WRITE_A;
 
117
 
 
118
    if (ch.findChannel (channelNamePrefix + "Y"))
 
119
    i |= WRITE_Y;
 
120
 
 
121
    if (ch.findChannel (channelNamePrefix + "RY") ||
 
122
    ch.findChannel (channelNamePrefix + "BY"))
 
123
    i |= WRITE_C;
 
124
 
 
125
    return RgbaChannels (i);
 
126
}
 
127
 
 
128
 
 
129
string
 
130
prefixFromLayerName (const string &layerName, const Header &header)
 
131
{
 
132
    if (layerName.empty())
 
133
    return "";
 
134
 
 
135
    if (hasMultiView (header) && multiView(header)[0] == layerName)
 
136
    return "";
 
137
 
 
138
    return layerName + ".";
 
139
}
 
140
 
 
141
 
 
142
V3f
 
143
ywFromHeader (const Header &header)
 
144
{
 
145
    Chromaticities cr;
 
146
 
 
147
    if (hasChromaticities (header))
 
148
    cr = chromaticities (header);
 
149
 
 
150
    return computeYw (cr);
 
151
}
 
152
 
 
153
 
 
154
ptrdiff_t
 
155
cachePadding (ptrdiff_t size)
 
156
{
 
157
    //
 
158
    // Some of the buffers that are allocated by classes ToYca and
 
159
    // FromYca, below, may need to be padded to avoid cache thrashing.
 
160
    // If the difference between the buffer size and the nearest power
 
161
    // of two is less than CACHE_LINE_SIZE, then we add an appropriate
 
162
    // amount of padding.
 
163
    //
 
164
    // CACHE_LINE_SIZE must be a power of two, and it must be at
 
165
    // least as big as the true size of a cache line on the machine
 
166
    // we are running on.  (It is ok if CACHE_LINE_SIZE is larger
 
167
    // than a real cache line.)
 
168
    //
 
169
 
 
170
    static int LOG2_CACHE_LINE_SIZE = 8;
 
171
    static const ptrdiff_t CACHE_LINE_SIZE = (1 << LOG2_CACHE_LINE_SIZE);
 
172
 
 
173
    int i = LOG2_CACHE_LINE_SIZE + 2;
 
174
 
 
175
    while ((size >> i) > 1)
 
176
    ++i;
 
177
 
 
178
    if (size > (1 << (i + 1)) - 64)
 
179
    return 64 + ((1 << (i + 1)) - size);
 
180
 
 
181
    if (size < (1 << i) + 64)
 
182
    return 64 + ((1 << i) - size);
 
183
 
 
184
    return 0;
 
185
}
 
186
 
 
187
} // namespace
 
188
 
 
189
 
 
190
class RgbaOutputFile::ToYca: public Mutex
 
191
{
 
192
  public:
 
193
 
 
194
     ToYca (OutputFile &outputFile, RgbaChannels rgbaChannels);
 
195
    ~ToYca ();
 
196
 
 
197
    void                setYCRounding (unsigned int roundY,
 
198
                           unsigned int roundC);
 
199
 
 
200
    void                setFrameBuffer (const Rgba *base,
 
201
                    size_t xStride,
 
202
                    size_t yStride);
 
203
 
 
204
    void                writePixels (int numScanLines);
 
205
    int                 currentScanLine () const;
 
206
 
 
207
  private:
 
208
 
 
209
    void                padTmpBuf ();
 
210
    void                rotateBuffers ();
 
211
    void                duplicateLastBuffer ();
 
212
    void                duplicateSecondToLastBuffer ();
 
213
    void                decimateChromaVertAndWriteScanLine ();
 
214
 
 
215
    OutputFile &        _outputFile;
 
216
    bool                _writeY;
 
217
    bool                _writeC;
 
218
    bool                _writeA;
 
219
    int                 _xMin;
 
220
    int                 _width;
 
221
    int                 _height;
 
222
    int                 _linesConverted;
 
223
    LineOrder           _lineOrder;
 
224
    int                 _currentScanLine;
 
225
    V3f                 _yw;
 
226
    Rgba *              _bufBase;
 
227
    Rgba *              _buf[N];
 
228
    Rgba *              _tmpBuf;
 
229
    const Rgba *        _fbBase;
 
230
    size_t              _fbXStride;
 
231
    size_t              _fbYStride;
 
232
    int                 _roundY;
 
233
    int                 _roundC;
 
234
};
 
235
 
 
236
 
 
237
RgbaOutputFile::ToYca::ToYca (OutputFile &outputFile,
 
238
                  RgbaChannels rgbaChannels)
 
239
:
 
240
    _outputFile (outputFile)
 
241
{
 
242
    _writeY = (rgbaChannels & WRITE_Y)? true: false;
 
243
    _writeC = (rgbaChannels & WRITE_C)? true: false;
 
244
    _writeA = (rgbaChannels & WRITE_A)? true: false;
 
245
 
 
246
    const Box2i dw = _outputFile.header().dataWindow();
 
247
 
 
248
    _xMin = dw.min.x;
 
249
    _width  = dw.max.x - dw.min.x + 1;
 
250
    _height = dw.max.y - dw.min.y + 1;
 
251
 
 
252
    _linesConverted = 0;
 
253
    _lineOrder = _outputFile.header().lineOrder();
 
254
 
 
255
    if (_lineOrder == INCREASING_Y)
 
256
    _currentScanLine = dw.min.y;
 
257
    else
 
258
    _currentScanLine = dw.max.y;
 
259
 
 
260
    _yw = ywFromHeader (_outputFile.header());
 
261
 
 
262
    ptrdiff_t pad = cachePadding (_width * sizeof (Rgba)) / sizeof (Rgba);
 
263
 
 
264
    _bufBase = new Rgba[(_width + pad) * N];
 
265
 
 
266
    for (int i = 0; i < N; ++i)
 
267
    _buf[i] = _bufBase + (i * (_width + pad));
 
268
 
 
269
    _tmpBuf = new Rgba[_width + N - 1];
 
270
 
 
271
    _fbBase = 0;
 
272
    _fbXStride = 0;
 
273
    _fbYStride = 0;
 
274
 
 
275
    _roundY = 7;
 
276
    _roundC = 5;
 
277
}
 
278
 
 
279
 
 
280
RgbaOutputFile::ToYca::~ToYca ()
 
281
{
 
282
    delete [] _bufBase;
 
283
    delete [] _tmpBuf;
 
284
}
 
285
 
 
286
 
 
287
void
 
288
RgbaOutputFile::ToYca::setYCRounding (unsigned int roundY,
 
289
                      unsigned int roundC)
 
290
{
 
291
    _roundY = roundY;
 
292
    _roundC = roundC;
 
293
}
 
294
 
 
295
 
 
296
void
 
297
RgbaOutputFile::ToYca::setFrameBuffer (const Rgba *base,
 
298
                       size_t xStride,
 
299
                       size_t yStride)
 
300
{
 
301
    if (_fbBase == 0)
 
302
    {
 
303
    FrameBuffer fb;
 
304
 
 
305
    if (_writeY)
 
306
    {
 
307
        fb.insert ("Y",
 
308
               Slice (HALF,                             // type
 
309
                  (char *) &_tmpBuf[-_xMin].g,  // base
 
310
                  sizeof (Rgba),                        // xStride
 
311
                  0,                            // yStride
 
312
                  1,                            // xSampling
 
313
                  1));                          // ySampling
 
314
    }
 
315
 
 
316
    if (_writeC)
 
317
    {
 
318
        fb.insert ("RY",
 
319
               Slice (HALF,                             // type
 
320
                  (char *) &_tmpBuf[-_xMin].r,  // base
 
321
                  sizeof (Rgba) * 2,            // xStride
 
322
                  0,                            // yStride
 
323
                  2,                            // xSampling
 
324
                  2));                          // ySampling
 
325
 
 
326
        fb.insert ("BY",
 
327
               Slice (HALF,                             // type
 
328
                  (char *) &_tmpBuf[-_xMin].b,  // base
 
329
                  sizeof (Rgba) * 2,            // xStride
 
330
                  0,                            // yStride
 
331
                  2,                            // xSampling
 
332
                  2));                          // ySampling
 
333
    }
 
334
 
 
335
    if (_writeA)
 
336
    {
 
337
        fb.insert ("A",
 
338
               Slice (HALF,                             // type
 
339
                  (char *) &_tmpBuf[-_xMin].a,  // base
 
340
                  sizeof (Rgba),                        // xStride
 
341
                  0,                            // yStride
 
342
                  1,                            // xSampling
 
343
                  1));                          // ySampling
 
344
    }
 
345
 
 
346
    _outputFile.setFrameBuffer (fb);
 
347
    }
 
348
 
 
349
    _fbBase = base;
 
350
    _fbXStride = xStride;
 
351
    _fbYStride = yStride;
 
352
}
 
353
 
 
354
 
 
355
void
 
356
RgbaOutputFile::ToYca::writePixels (int numScanLines)
 
357
{
 
358
    if (_fbBase == 0)
 
359
    {
 
360
    THROW (Iex::ArgExc, "No frame buffer was specified as the "
 
361
                "pixel data source for image file "
 
362
                "\"" << _outputFile.fileName() << "\".");
 
363
    }
 
364
 
 
365
    if (_writeY && !_writeC)
 
366
    {
 
367
    //
 
368
    // We are writing only luminance; filtering
 
369
    // and subsampling are not necessary.
 
370
    //
 
371
 
 
372
    for (int i = 0; i < numScanLines; ++i)
 
373
    {
 
374
        //
 
375
        // Copy the next scan line from the caller's
 
376
        // frame buffer into _tmpBuf.
 
377
        //
 
378
 
 
379
        for (int j = 0; j < _width; ++j)
 
380
        {
 
381
        _tmpBuf[j] = _fbBase[_fbYStride * _currentScanLine +
 
382
                     _fbXStride * (j + _xMin)];
 
383
        }
 
384
 
 
385
        //
 
386
        // Convert the scan line from RGB to luminance/chroma,
 
387
        // and store the result in the output file.
 
388
        //
 
389
 
 
390
        RGBAtoYCA (_yw, _width, _writeA, _tmpBuf, _tmpBuf);
 
391
        _outputFile.writePixels (1);
 
392
 
 
393
        ++_linesConverted;
 
394
 
 
395
        if (_lineOrder == INCREASING_Y)
 
396
        ++_currentScanLine;
 
397
        else
 
398
        --_currentScanLine;
 
399
    }
 
400
    }
 
401
    else
 
402
    {
 
403
    //
 
404
    // We are writing chroma; the pixels must be filtered and subsampled.
 
405
    //
 
406
 
 
407
    for (int i = 0; i < numScanLines; ++i)
 
408
    {
 
409
        //
 
410
        // Copy the next scan line from the caller's
 
411
        // frame buffer into _tmpBuf.
 
412
        //
 
413
 
 
414
        for (int j = 0; j < _width; ++j)
 
415
        {
 
416
        _tmpBuf[j + N2] = _fbBase[_fbYStride * _currentScanLine +
 
417
                      _fbXStride * (j + _xMin)];
 
418
        }
 
419
 
 
420
        //
 
421
        // Convert the scan line from RGB to luminance/chroma.
 
422
        //
 
423
 
 
424
        RGBAtoYCA (_yw, _width, _writeA, _tmpBuf + N2, _tmpBuf + N2);
 
425
 
 
426
        //
 
427
        // Append N2 copies of the first and last pixel to the
 
428
        // beginning and end of the scan line.
 
429
        //
 
430
 
 
431
        padTmpBuf ();
 
432
 
 
433
        //
 
434
        // Filter and subsample the scan line's chroma channels
 
435
        // horizontally; store the result in _buf.
 
436
        //
 
437
 
 
438
        rotateBuffers();
 
439
        decimateChromaHoriz (_width, _tmpBuf, _buf[N - 1]);
 
440
 
 
441
        //
 
442
        // If this is the first scan line in the image,
 
443
        // store N2 more copies of the scan line in _buf.
 
444
        //
 
445
 
 
446
        if (_linesConverted == 0)
 
447
        {
 
448
        for (int j = 0; j < N2; ++j)
 
449
            duplicateLastBuffer();
 
450
        }
 
451
 
 
452
        ++_linesConverted;
 
453
 
 
454
        //
 
455
        // If we have have converted at least N2 scan lines from
 
456
        // RGBA to luminance/chroma, then we can start to filter
 
457
        // and subsample vertically, and store pixels in the
 
458
        // output file.
 
459
        //
 
460
 
 
461
        if (_linesConverted > N2)
 
462
        decimateChromaVertAndWriteScanLine();
 
463
 
 
464
        //
 
465
        // If we have already converted the last scan line in
 
466
        // the image to luminance/chroma, filter, subsample and
 
467
        // store the remaining scan lines in _buf.
 
468
        //
 
469
 
 
470
        if (_linesConverted >= _height)
 
471
        {
 
472
        for (int j = 0; j < N2 - _height; ++j)
 
473
            duplicateLastBuffer();
 
474
 
 
475
        duplicateSecondToLastBuffer();
 
476
        ++_linesConverted;
 
477
        decimateChromaVertAndWriteScanLine();
 
478
 
 
479
        for (int j = 1; j < min (_height, N2); ++j)
 
480
        {
 
481
            duplicateLastBuffer();
 
482
            ++_linesConverted;
 
483
            decimateChromaVertAndWriteScanLine();
 
484
        }
 
485
        }
 
486
 
 
487
        if (_lineOrder == INCREASING_Y)
 
488
        ++_currentScanLine;
 
489
        else
 
490
        --_currentScanLine;
 
491
    }
 
492
    }
 
493
}
 
494
 
 
495
 
 
496
int
 
497
RgbaOutputFile::ToYca::currentScanLine () const
 
498
{
 
499
    return _currentScanLine;
 
500
}
 
501
 
 
502
 
 
503
void
 
504
RgbaOutputFile::ToYca::padTmpBuf ()
 
505
{
 
506
    for (int i = 0; i < N2; ++i)
 
507
    {
 
508
    _tmpBuf[i] = _tmpBuf[N2];
 
509
    _tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
 
510
    }
 
511
}
 
512
 
 
513
 
 
514
void
 
515
RgbaOutputFile::ToYca::rotateBuffers ()
 
516
{
 
517
    Rgba *tmp = _buf[0];
 
518
 
 
519
    for (int i = 0; i < N - 1; ++i)
 
520
    _buf[i] = _buf[i + 1];
 
521
 
 
522
    _buf[N - 1] = tmp;
 
523
}
 
524
 
 
525
 
 
526
void
 
527
RgbaOutputFile::ToYca::duplicateLastBuffer ()
 
528
{
 
529
    rotateBuffers();
 
530
    memcpy (_buf[N - 1], _buf[N - 2], _width * sizeof (Rgba));
 
531
}
 
532
 
 
533
 
 
534
void
 
535
RgbaOutputFile::ToYca::duplicateSecondToLastBuffer ()
 
536
{
 
537
    rotateBuffers();
 
538
    memcpy (_buf[N - 1], _buf[N - 3], _width * sizeof (Rgba));
 
539
}
 
540
 
 
541
 
 
542
void
 
543
RgbaOutputFile::ToYca::decimateChromaVertAndWriteScanLine ()
 
544
{
 
545
    if (_linesConverted & 1)
 
546
    memcpy (_tmpBuf, _buf[N2], _width * sizeof (Rgba));
 
547
    else
 
548
    decimateChromaVert (_width, _buf, _tmpBuf);
 
549
 
 
550
    if (_writeY && _writeC)
 
551
    roundYCA (_width, _roundY, _roundC, _tmpBuf, _tmpBuf);
 
552
 
 
553
    _outputFile.writePixels (1);
 
554
}
 
555
 
 
556
 
 
557
RgbaOutputFile::RgbaOutputFile (const char name[],
 
558
                const Header &header,
 
559
                RgbaChannels rgbaChannels,
 
560
                                int numThreads):
 
561
    _outputFile (0),
 
562
    _toYca (0)
 
563
{
 
564
    Header hd (header);
 
565
    insertChannels (hd, rgbaChannels);
 
566
    _outputFile = new OutputFile (name, hd, numThreads);
 
567
 
 
568
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
569
    _toYca = new ToYca (*_outputFile, rgbaChannels);
 
570
}
 
571
 
 
572
 
 
573
RgbaOutputFile::RgbaOutputFile (OStream &os,
 
574
                const Header &header,
 
575
                RgbaChannels rgbaChannels,
 
576
                                int numThreads):
 
577
    _outputFile (0),
 
578
    _toYca (0)
 
579
{
 
580
    Header hd (header);
 
581
    insertChannels (hd, rgbaChannels);
 
582
    _outputFile = new OutputFile (os, hd, numThreads);
 
583
 
 
584
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
585
    _toYca = new ToYca (*_outputFile, rgbaChannels);
 
586
}
 
587
 
 
588
 
 
589
RgbaOutputFile::RgbaOutputFile (const char name[],
 
590
                const Imath::Box2i &displayWindow,
 
591
                const Imath::Box2i &dataWindow,
 
592
                RgbaChannels rgbaChannels,
 
593
                float pixelAspectRatio,
 
594
                const Imath::V2f screenWindowCenter,
 
595
                float screenWindowWidth,
 
596
                LineOrder lineOrder,
 
597
                Compression compression,
 
598
                                int numThreads):
 
599
    _outputFile (0),
 
600
    _toYca (0)
 
601
{
 
602
    Header hd (displayWindow,
 
603
           dataWindow.isEmpty()? displayWindow: dataWindow,
 
604
           pixelAspectRatio,
 
605
           screenWindowCenter,
 
606
           screenWindowWidth,
 
607
           lineOrder,
 
608
           compression);
 
609
 
 
610
    insertChannels (hd, rgbaChannels);
 
611
    _outputFile = new OutputFile (name, hd, numThreads);
 
612
 
 
613
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
614
    _toYca = new ToYca (*_outputFile, rgbaChannels);
 
615
}
 
616
 
 
617
 
 
618
RgbaOutputFile::RgbaOutputFile (const char name[],
 
619
                int width,
 
620
                int height,
 
621
                RgbaChannels rgbaChannels,
 
622
                float pixelAspectRatio,
 
623
                const Imath::V2f screenWindowCenter,
 
624
                float screenWindowWidth,
 
625
                LineOrder lineOrder,
 
626
                Compression compression,
 
627
                                int numThreads):
 
628
    _outputFile (0),
 
629
    _toYca (0)
 
630
{
 
631
    Header hd (width,
 
632
           height,
 
633
           pixelAspectRatio,
 
634
           screenWindowCenter,
 
635
           screenWindowWidth,
 
636
           lineOrder,
 
637
           compression);
 
638
 
 
639
    insertChannels (hd, rgbaChannels);
 
640
    _outputFile = new OutputFile (name, hd, numThreads);
 
641
 
 
642
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
643
    _toYca = new ToYca (*_outputFile, rgbaChannels);
 
644
}
 
645
 
 
646
 
 
647
RgbaOutputFile::~RgbaOutputFile ()
 
648
{
 
649
    delete _toYca;
 
650
    delete _outputFile;
 
651
}
 
652
 
 
653
 
 
654
void
 
655
RgbaOutputFile::setFrameBuffer (const Rgba *base,
 
656
                size_t xStride,
 
657
                size_t yStride)
 
658
{
 
659
    if (_toYca)
 
660
    {
 
661
    Lock lock (*_toYca);
 
662
    _toYca->setFrameBuffer (base, xStride, yStride);
 
663
    }
 
664
    else
 
665
    {
 
666
    size_t xs = xStride * sizeof (Rgba);
 
667
    size_t ys = yStride * sizeof (Rgba);
 
668
 
 
669
    FrameBuffer fb;
 
670
 
 
671
    fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys));
 
672
    fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys));
 
673
    fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys));
 
674
    fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys));
 
675
 
 
676
    _outputFile->setFrameBuffer (fb);
 
677
    }
 
678
}
 
679
 
 
680
 
 
681
void
 
682
RgbaOutputFile::writePixels (int numScanLines)
 
683
{
 
684
    if (_toYca)
 
685
    {
 
686
    Lock lock (*_toYca);
 
687
    _toYca->writePixels (numScanLines);
 
688
    }
 
689
    else
 
690
    {
 
691
    _outputFile->writePixels (numScanLines);
 
692
    }
 
693
}
 
694
 
 
695
 
 
696
int
 
697
RgbaOutputFile::currentScanLine () const
 
698
{
 
699
    if (_toYca)
 
700
    {
 
701
    Lock lock (*_toYca);
 
702
    return _toYca->currentScanLine();
 
703
    }
 
704
    else
 
705
    {
 
706
    return _outputFile->currentScanLine();
 
707
    }
 
708
}
 
709
 
 
710
 
 
711
const Header &
 
712
RgbaOutputFile::header () const
 
713
{
 
714
    return _outputFile->header();
 
715
}
 
716
 
 
717
 
 
718
const FrameBuffer &
 
719
RgbaOutputFile::frameBuffer () const
 
720
{
 
721
    return _outputFile->frameBuffer();
 
722
}
 
723
 
 
724
 
 
725
const Imath::Box2i &
 
726
RgbaOutputFile::displayWindow () const
 
727
{
 
728
    return _outputFile->header().displayWindow();
 
729
}
 
730
 
 
731
 
 
732
const Imath::Box2i &
 
733
RgbaOutputFile::dataWindow () const
 
734
{
 
735
    return _outputFile->header().dataWindow();
 
736
}
 
737
 
 
738
 
 
739
float
 
740
RgbaOutputFile::pixelAspectRatio () const
 
741
{
 
742
    return _outputFile->header().pixelAspectRatio();
 
743
}
 
744
 
 
745
 
 
746
const Imath::V2f
 
747
RgbaOutputFile::screenWindowCenter () const
 
748
{
 
749
    return _outputFile->header().screenWindowCenter();
 
750
}
 
751
 
 
752
 
 
753
float
 
754
RgbaOutputFile::screenWindowWidth () const
 
755
{
 
756
    return _outputFile->header().screenWindowWidth();
 
757
}
 
758
 
 
759
 
 
760
LineOrder
 
761
RgbaOutputFile::lineOrder () const
 
762
{
 
763
    return _outputFile->header().lineOrder();
 
764
}
 
765
 
 
766
 
 
767
Compression
 
768
RgbaOutputFile::compression () const
 
769
{
 
770
    return _outputFile->header().compression();
 
771
}
 
772
 
 
773
 
 
774
RgbaChannels
 
775
RgbaOutputFile::channels () const
 
776
{
 
777
    return rgbaChannels (_outputFile->header().channels());
 
778
}
 
779
 
 
780
 
 
781
void
 
782
RgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 
783
{
 
784
    _outputFile->updatePreviewImage (newPixels);
 
785
}
 
786
 
 
787
 
 
788
void
 
789
RgbaOutputFile::setYCRounding (unsigned int roundY, unsigned int roundC)
 
790
{
 
791
    if (_toYca)
 
792
    {
 
793
    Lock lock (*_toYca);
 
794
    _toYca->setYCRounding (roundY, roundC);
 
795
    }
 
796
}
 
797
 
 
798
 
 
799
void
 
800
RgbaOutputFile::breakScanLine  (int y, int offset, int length, char c)
 
801
{
 
802
    _outputFile->breakScanLine (y, offset, length, c);
 
803
}
 
804
 
 
805
 
 
806
class RgbaInputFile::FromYca: public Mutex
 
807
{
 
808
  public:
 
809
 
 
810
     FromYca (InputFile &inputFile, RgbaChannels rgbaChannels);
 
811
    ~FromYca ();
 
812
 
 
813
    void                setFrameBuffer (Rgba *base,
 
814
                    size_t xStride,
 
815
                    size_t yStride,
 
816
                    const string &channelNamePrefix);
 
817
 
 
818
    void                readPixels (int scanLine1, int scanLine2);
 
819
 
 
820
  private:
 
821
 
 
822
    void                readPixels (int scanLine);
 
823
    void                rotateBuf1 (int d);
 
824
    void                rotateBuf2 (int d);
 
825
    void                readYCAScanLine (int y, Rgba buf[]);
 
826
    void                padTmpBuf ();
 
827
 
 
828
    InputFile &         _inputFile;
 
829
    bool                _readC;
 
830
    int                 _xMin;
 
831
    int                 _yMin;
 
832
    int                 _yMax;
 
833
    int                 _width;
 
834
    int                 _height;
 
835
    int                 _currentScanLine;
 
836
    LineOrder           _lineOrder;
 
837
    V3f                 _yw;
 
838
    Rgba *              _bufBase;
 
839
    Rgba *              _buf1[N + 2];
 
840
    Rgba *              _buf2[3];
 
841
    Rgba *              _tmpBuf;
 
842
    Rgba *              _fbBase;
 
843
    size_t              _fbXStride;
 
844
    size_t              _fbYStride;
 
845
};
 
846
 
 
847
 
 
848
RgbaInputFile::FromYca::FromYca (InputFile &inputFile,
 
849
                 RgbaChannels rgbaChannels)
 
850
:
 
851
    _inputFile (inputFile)
 
852
{
 
853
    _readC = (rgbaChannels & WRITE_C)? true: false;
 
854
 
 
855
    const Box2i dw = _inputFile.header().dataWindow();
 
856
 
 
857
    _xMin = dw.min.x;
 
858
    _yMin = dw.min.y;
 
859
    _yMax = dw.max.y;
 
860
    _width  = dw.max.x - dw.min.x + 1;
 
861
    _height = dw.max.y - dw.min.y + 1;
 
862
    _currentScanLine = dw.min.y - N - 2;
 
863
    _lineOrder = _inputFile.header().lineOrder();
 
864
    _yw = ywFromHeader (_inputFile.header());
 
865
 
 
866
    ptrdiff_t pad = cachePadding (_width * sizeof (Rgba)) / sizeof (Rgba);
 
867
 
 
868
    _bufBase = new Rgba[(_width + pad) * (N + 2 + 3)];
 
869
 
 
870
    for (int i = 0; i < N + 2; ++i)
 
871
    _buf1[i] = _bufBase + (i * (_width + pad));
 
872
 
 
873
    for (int i = 0; i < 3; ++i)
 
874
    _buf2[i] = _bufBase + ((i + N + 2) * (_width + pad));
 
875
 
 
876
    _tmpBuf = new Rgba[_width + N - 1];
 
877
 
 
878
    _fbBase = 0;
 
879
    _fbXStride = 0;
 
880
    _fbYStride = 0;
 
881
}
 
882
 
 
883
 
 
884
RgbaInputFile::FromYca::~FromYca ()
 
885
{
 
886
    delete [] _bufBase;
 
887
    delete [] _tmpBuf;
 
888
}
 
889
 
 
890
 
 
891
void
 
892
RgbaInputFile::FromYca::setFrameBuffer (Rgba *base,
 
893
                    size_t xStride,
 
894
                    size_t yStride,
 
895
                    const string &channelNamePrefix)
 
896
{
 
897
    if (_fbBase == 0)
 
898
    {
 
899
    FrameBuffer fb;
 
900
 
 
901
    fb.insert (channelNamePrefix + "Y",
 
902
           Slice (HALF,                                 // type
 
903
              (char *) &_tmpBuf[N2 - _xMin].g,  // base
 
904
              sizeof (Rgba),                    // xStride
 
905
              0,                                        // yStride
 
906
              1,                                        // xSampling
 
907
              1,                                        // ySampling
 
908
              0.5));                            // fillValue
 
909
 
 
910
    if (_readC)
 
911
    {
 
912
        fb.insert (channelNamePrefix + "RY",
 
913
               Slice (HALF,                             // type
 
914
                  (char *) &_tmpBuf[N2 - _xMin].r,      // base
 
915
                  sizeof (Rgba) * 2,            // xStride
 
916
                  0,                            // yStride
 
917
                  2,                            // xSampling
 
918
                  2,                            // ySampling
 
919
                  0.0));                                // fillValue
 
920
 
 
921
        fb.insert (channelNamePrefix + "BY",
 
922
               Slice (HALF,                             // type
 
923
                  (char *) &_tmpBuf[N2 - _xMin].b,      // base
 
924
                  sizeof (Rgba) * 2,            // xStride
 
925
                  0,                            // yStride
 
926
                  2,                            // xSampling
 
927
                  2,                            // ySampling
 
928
                  0.0));                                // fillValue
 
929
    }
 
930
 
 
931
    fb.insert (channelNamePrefix + "A",
 
932
           Slice (HALF,                                 // type
 
933
              (char *) &_tmpBuf[N2 - _xMin].a,  // base
 
934
              sizeof (Rgba),                    // xStride
 
935
              0,                                        // yStride
 
936
              1,                                        // xSampling
 
937
              1,                                        // ySampling
 
938
              1.0));                            // fillValue
 
939
 
 
940
    _inputFile.setFrameBuffer (fb);
 
941
    }
 
942
 
 
943
    _fbBase = base;
 
944
    _fbXStride = xStride;
 
945
    _fbYStride = yStride;
 
946
}
 
947
 
 
948
 
 
949
void
 
950
RgbaInputFile::FromYca::readPixels (int scanLine1, int scanLine2)
 
951
{
 
952
    int minY = min (scanLine1, scanLine2);
 
953
    int maxY = max (scanLine1, scanLine2);
 
954
 
 
955
    if (_lineOrder == INCREASING_Y)
 
956
    {
 
957
    for (int y = minY; y <= maxY; ++y)
 
958
        readPixels (y);
 
959
    }
 
960
    else
 
961
    {
 
962
    for (int y = maxY; y >= minY; --y)
 
963
        readPixels (y);
 
964
    }
 
965
}
 
966
 
 
967
 
 
968
void
 
969
RgbaInputFile::FromYca::readPixels (int scanLine)
 
970
{
 
971
    if (_fbBase == 0)
 
972
    {
 
973
    THROW (Iex::ArgExc, "No frame buffer was specified as the "
 
974
                "pixel data destination for image file "
 
975
                "\"" << _inputFile.fileName() << "\".");
 
976
    }
 
977
 
 
978
    //
 
979
    // In order to convert one scan line to RGB format, we need that
 
980
    // scan line plus N2+1 extra scan lines above and N2+1 scan lines
 
981
    // below in luminance/chroma format.
 
982
    //
 
983
    // We allow random access to scan lines, but we buffer partially
 
984
    // processed luminance/chroma data in order to make reading pixels
 
985
    // in increasing y or decreasing y order reasonably efficient:
 
986
    //
 
987
    //  _currentScanLine        holds the y coordinate of the scan line
 
988
    //                          that was most recently read.
 
989
    //
 
990
    //  _buf1                   contains scan lines _currentScanLine-N2-1
 
991
    //                          through _currentScanLine+N2+1 in
 
992
    //                          luminance/chroma format.  Odd-numbered
 
993
    //                          lines contain no chroma data.  Even-numbered
 
994
    //                          lines have valid chroma data for all pixels.
 
995
    //
 
996
    //  _buf2                   contains scan lines _currentScanLine-1
 
997
    //                          through _currentScanLine+1, in RGB format.
 
998
    //                          Super-saturated pixels (see ImfRgbaYca.h)
 
999
    //                          have not yet been eliminated.
 
1000
    //
 
1001
    // If the scan line we are trying to read now is close enough to
 
1002
    // _currentScanLine, we don't have to recompute the contents of _buf1
 
1003
    // and _buf2 from scratch.  We can rotate _buf1 and _buf2, and fill
 
1004
    // in the missing data.
 
1005
    //
 
1006
 
 
1007
    int dy = scanLine - _currentScanLine;
 
1008
 
 
1009
    if (abs (dy) < N + 2)
 
1010
    rotateBuf1 (dy);
 
1011
 
 
1012
    if (abs (dy) < 3)
 
1013
    rotateBuf2 (dy);
 
1014
 
 
1015
    if (dy < 0)
 
1016
    {
 
1017
    {
 
1018
        int n = min (-dy, N + 2);
 
1019
        int yMin = scanLine - N2 - 1;
 
1020
 
 
1021
        for (int i = n - 1; i >= 0; --i)
 
1022
        readYCAScanLine (yMin + i, _buf1[i]);
 
1023
    }
 
1024
 
 
1025
    {
 
1026
        int n = min (-dy, 3);
 
1027
 
 
1028
        for (int i = 0; i < n; ++i)
 
1029
        {
 
1030
        if ((scanLine + i) & 1)
 
1031
        {
 
1032
            YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
 
1033
        }
 
1034
        else
 
1035
        {
 
1036
            reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
 
1037
            YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
 
1038
        }
 
1039
        }
 
1040
    }
 
1041
    }
 
1042
    else
 
1043
    {
 
1044
    {
 
1045
        int n = min (dy, N + 2);
 
1046
        int yMax = scanLine + N2 + 1;
 
1047
 
 
1048
        for (int i = n - 1; i >= 0; --i)
 
1049
        readYCAScanLine (yMax - i, _buf1[N + 1 - i]);
 
1050
    }
 
1051
 
 
1052
    {
 
1053
        int n = min (dy, 3);
 
1054
 
 
1055
        for (int i = 2; i > 2 - n; --i)
 
1056
        {
 
1057
        if ((scanLine + i) & 1)
 
1058
        {
 
1059
            YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
 
1060
        }
 
1061
        else
 
1062
        {
 
1063
            reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
 
1064
            YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
 
1065
        }
 
1066
        }
 
1067
    }
 
1068
    }
 
1069
 
 
1070
    fixSaturation (_yw, _width, _buf2, _tmpBuf);
 
1071
 
 
1072
    for (int i = 0; i < _width; ++i)
 
1073
    _fbBase[_fbYStride * scanLine + _fbXStride * (i + _xMin)] = _tmpBuf[i];
 
1074
 
 
1075
    _currentScanLine = scanLine;
 
1076
}
 
1077
 
 
1078
 
 
1079
void
 
1080
RgbaInputFile::FromYca::rotateBuf1 (int d)
 
1081
{
 
1082
    d = modp (d, N + 2);
 
1083
 
 
1084
    Rgba *tmp[N + 2];
 
1085
 
 
1086
    for (int i = 0; i < N + 2; ++i)
 
1087
    tmp[i] = _buf1[i];
 
1088
 
 
1089
    for (int i = 0; i < N + 2; ++i)
 
1090
    _buf1[i] = tmp[(i + d) % (N + 2)];
 
1091
}
 
1092
 
 
1093
 
 
1094
void
 
1095
RgbaInputFile::FromYca::rotateBuf2 (int d)
 
1096
{
 
1097
    d = modp (d, 3);
 
1098
 
 
1099
    Rgba *tmp[3];
 
1100
 
 
1101
    for (int i = 0; i < 3; ++i)
 
1102
    tmp[i] = _buf2[i];
 
1103
 
 
1104
    for (int i = 0; i < 3; ++i)
 
1105
    _buf2[i] = tmp[(i + d) % 3];
 
1106
}
 
1107
 
 
1108
 
 
1109
void
 
1110
RgbaInputFile::FromYca::readYCAScanLine (int y, Rgba *buf)
 
1111
{
 
1112
    //
 
1113
    // Clamp y.
 
1114
    //
 
1115
 
 
1116
    if (y < _yMin)
 
1117
    y = _yMin;
 
1118
    else if (y > _yMax)
 
1119
    y = _yMax - 1;
 
1120
 
 
1121
    //
 
1122
    // Read scan line y into _tmpBuf.
 
1123
    //
 
1124
 
 
1125
    _inputFile.readPixels (y);
 
1126
 
 
1127
    //
 
1128
    // Reconstruct missing chroma samples and copy
 
1129
    // the scan line into buf.
 
1130
    //
 
1131
 
 
1132
    if (!_readC)
 
1133
    {
 
1134
    for (int i = 0; i < _width; ++i)
 
1135
    {
 
1136
        _tmpBuf[i + N2].r = 0;
 
1137
        _tmpBuf[i + N2].b = 0;
 
1138
    }
 
1139
    }
 
1140
 
 
1141
    if (y & 1)
 
1142
    {
 
1143
    memcpy (buf, _tmpBuf + N2, _width * sizeof (Rgba));
 
1144
    }
 
1145
    else
 
1146
    {
 
1147
    padTmpBuf();
 
1148
    reconstructChromaHoriz (_width, _tmpBuf, buf);
 
1149
    }
 
1150
}
 
1151
 
 
1152
 
 
1153
void
 
1154
RgbaInputFile::FromYca::padTmpBuf ()
 
1155
{
 
1156
    for (int i = 0; i < N2; ++i)
 
1157
    {
 
1158
    _tmpBuf[i] = _tmpBuf[N2];
 
1159
    _tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
 
1160
    }
 
1161
}
 
1162
 
 
1163
 
 
1164
RgbaInputFile::RgbaInputFile (const char name[], int numThreads):
 
1165
    _inputFile (new InputFile (name, numThreads)),
 
1166
    _fromYca (0),
 
1167
    _channelNamePrefix ("")
 
1168
{
 
1169
    RgbaChannels rgbaChannels = channels();
 
1170
 
 
1171
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
1172
    _fromYca = new FromYca (*_inputFile, rgbaChannels);
 
1173
}
 
1174
 
 
1175
 
 
1176
RgbaInputFile::RgbaInputFile (IStream &is, int numThreads):
 
1177
    _inputFile (new InputFile (is, numThreads)),
 
1178
    _fromYca (0),
 
1179
    _channelNamePrefix ("")
 
1180
{
 
1181
    RgbaChannels rgbaChannels = channels();
 
1182
 
 
1183
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
1184
    _fromYca = new FromYca (*_inputFile, rgbaChannels);
 
1185
}
 
1186
 
 
1187
 
 
1188
RgbaInputFile::RgbaInputFile (const char name[],
 
1189
                  const string &layerName,
 
1190
                  int numThreads)
 
1191
:
 
1192
    _inputFile (new InputFile (name, numThreads)),
 
1193
    _fromYca (0),
 
1194
    _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
 
1195
{
 
1196
    RgbaChannels rgbaChannels = channels();
 
1197
 
 
1198
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
1199
    _fromYca = new FromYca (*_inputFile, rgbaChannels);
 
1200
}
 
1201
 
 
1202
 
 
1203
RgbaInputFile::RgbaInputFile (IStream &is,
 
1204
                  const string &layerName,
 
1205
                  int numThreads)
 
1206
:
 
1207
    _inputFile (new InputFile (is, numThreads)),
 
1208
    _fromYca (0),
 
1209
    _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
 
1210
{
 
1211
    RgbaChannels rgbaChannels = channels();
 
1212
 
 
1213
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
1214
    _fromYca = new FromYca (*_inputFile, rgbaChannels);
 
1215
}
 
1216
 
 
1217
 
 
1218
RgbaInputFile::~RgbaInputFile ()
 
1219
{
 
1220
    delete _inputFile;
 
1221
    delete _fromYca;
 
1222
}
 
1223
 
 
1224
 
 
1225
void
 
1226
RgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
 
1227
{
 
1228
    if (_fromYca)
 
1229
    {
 
1230
    Lock lock (*_fromYca);
 
1231
    _fromYca->setFrameBuffer (base, xStride, yStride, _channelNamePrefix);
 
1232
    }
 
1233
    else
 
1234
    {
 
1235
    size_t xs = xStride * sizeof (Rgba);
 
1236
    size_t ys = yStride * sizeof (Rgba);
 
1237
 
 
1238
    FrameBuffer fb;
 
1239
 
 
1240
    fb.insert (_channelNamePrefix + "R",
 
1241
           Slice (HALF,
 
1242
              (char *) &base[0].r,
 
1243
              xs, ys,
 
1244
              1, 1,             // xSampling, ySampling
 
1245
              0.0));    // fillValue
 
1246
 
 
1247
    fb.insert (_channelNamePrefix + "G",
 
1248
           Slice (HALF,
 
1249
              (char *) &base[0].g,
 
1250
              xs, ys,
 
1251
              1, 1,             // xSampling, ySampling
 
1252
              0.0));    // fillValue
 
1253
 
 
1254
    fb.insert (_channelNamePrefix + "B",
 
1255
           Slice (HALF,
 
1256
              (char *) &base[0].b,
 
1257
              xs, ys,
 
1258
              1, 1,             // xSampling, ySampling
 
1259
              0.0));    // fillValue
 
1260
 
 
1261
    fb.insert (_channelNamePrefix + "A",
 
1262
           Slice (HALF,
 
1263
              (char *) &base[0].a,
 
1264
              xs, ys,
 
1265
              1, 1,             // xSampling, ySampling
 
1266
              1.0));    // fillValue
 
1267
 
 
1268
    _inputFile->setFrameBuffer (fb);
 
1269
    }
 
1270
}
 
1271
 
 
1272
 
 
1273
void
 
1274
RgbaInputFile::setLayerName (const string &layerName)
 
1275
{
 
1276
    delete _fromYca;
 
1277
    _fromYca = 0;
 
1278
 
 
1279
    _channelNamePrefix = prefixFromLayerName (layerName, _inputFile->header());
 
1280
 
 
1281
    RgbaChannels rgbaChannels = channels();
 
1282
 
 
1283
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
1284
    _fromYca = new FromYca (*_inputFile, rgbaChannels);
 
1285
 
 
1286
    FrameBuffer fb;
 
1287
    _inputFile->setFrameBuffer (fb);
 
1288
}
 
1289
 
 
1290
 
 
1291
void
 
1292
RgbaInputFile::readPixels (int scanLine1, int scanLine2)
 
1293
{
 
1294
    if (_fromYca)
 
1295
    {
 
1296
    Lock lock (*_fromYca);
 
1297
    _fromYca->readPixels (scanLine1, scanLine2);
 
1298
    }
 
1299
    else
 
1300
    {
 
1301
    _inputFile->readPixels (scanLine1, scanLine2);
 
1302
    }
 
1303
}
 
1304
 
 
1305
 
 
1306
void
 
1307
RgbaInputFile::readPixels (int scanLine)
 
1308
{
 
1309
    readPixels (scanLine, scanLine);
 
1310
}
 
1311
 
 
1312
 
 
1313
bool
 
1314
RgbaInputFile::isComplete () const
 
1315
{
 
1316
    return _inputFile->isComplete();
 
1317
}
 
1318
 
 
1319
 
 
1320
const Header &
 
1321
RgbaInputFile::header () const
 
1322
{
 
1323
    return _inputFile->header();
 
1324
}
 
1325
 
 
1326
 
 
1327
const char *
 
1328
RgbaInputFile::fileName () const
 
1329
{
 
1330
    return _inputFile->fileName();
 
1331
}
 
1332
 
 
1333
 
 
1334
const FrameBuffer &
 
1335
RgbaInputFile::frameBuffer () const
 
1336
{
 
1337
    return _inputFile->frameBuffer();
 
1338
}
 
1339
 
 
1340
 
 
1341
const Imath::Box2i &
 
1342
RgbaInputFile::displayWindow () const
 
1343
{
 
1344
    return _inputFile->header().displayWindow();
 
1345
}
 
1346
 
 
1347
 
 
1348
const Imath::Box2i &
 
1349
RgbaInputFile::dataWindow () const
 
1350
{
 
1351
    return _inputFile->header().dataWindow();
 
1352
}
 
1353
 
 
1354
 
 
1355
float
 
1356
RgbaInputFile::pixelAspectRatio () const
 
1357
{
 
1358
    return _inputFile->header().pixelAspectRatio();
 
1359
}
 
1360
 
 
1361
 
 
1362
const Imath::V2f
 
1363
RgbaInputFile::screenWindowCenter () const
 
1364
{
 
1365
    return _inputFile->header().screenWindowCenter();
 
1366
}
 
1367
 
 
1368
 
 
1369
float
 
1370
RgbaInputFile::screenWindowWidth () const
 
1371
{
 
1372
    return _inputFile->header().screenWindowWidth();
 
1373
}
 
1374
 
 
1375
 
 
1376
LineOrder
 
1377
RgbaInputFile::lineOrder () const
 
1378
{
 
1379
    return _inputFile->header().lineOrder();
 
1380
}
 
1381
 
 
1382
 
 
1383
Compression
 
1384
RgbaInputFile::compression () const
 
1385
{
 
1386
    return _inputFile->header().compression();
 
1387
}
 
1388
 
 
1389
 
 
1390
RgbaChannels
 
1391
RgbaInputFile::channels () const
 
1392
{
 
1393
    return rgbaChannels (_inputFile->header().channels(), _channelNamePrefix);
 
1394
}
 
1395
 
 
1396
 
 
1397
int
 
1398
RgbaInputFile::version () const
 
1399
{
 
1400
    return _inputFile->version();
 
1401
}
 
1402
 
 
1403
 
 
1404
} // namespace Imf