1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
6
// All rights reserved.
8
// Redistribution and use in source and binary forms, with or without
9
// modification, are permitted provided that the following conditions are
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
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.
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.
33
///////////////////////////////////////////////////////////////////////////
35
//-----------------------------------------------------------------------------
37
// class RgbaOutputFile
38
// class RgbaInputFile
40
//-----------------------------------------------------------------------------
42
#include <ImfRgbaFile.h>
43
#include <ImfOutputFile.h>
44
#include <ImfInputFile.h>
45
#include <ImfChannelList.h>
46
#include <ImfRgbaYca.h>
47
#include <ImfStandardAttributes.h>
49
#include <IlmThreadMutex.h>
58
using namespace Imath;
59
using namespace RgbaYca;
60
using namespace IlmThread;
65
insertChannels (Header &header, RgbaChannels rgbaChannels)
69
if (rgbaChannels & (WRITE_Y | WRITE_C))
71
if (rgbaChannels & WRITE_Y)
73
ch.insert ("Y", Channel (HALF, 1, 1));
76
if (rgbaChannels & WRITE_C)
78
ch.insert ("RY", Channel (HALF, 2, 2, true));
79
ch.insert ("BY", Channel (HALF, 2, 2, true));
84
if (rgbaChannels & WRITE_R)
85
ch.insert ("R", Channel (HALF, 1, 1));
87
if (rgbaChannels & WRITE_G)
88
ch.insert ("G", Channel (HALF, 1, 1));
90
if (rgbaChannels & WRITE_B)
91
ch.insert ("B", Channel (HALF, 1, 1));
94
if (rgbaChannels & WRITE_A)
95
ch.insert ("A", Channel (HALF, 1, 1));
97
header.channels() = ch;
102
rgbaChannels (const ChannelList &ch, const string &channelNamePrefix = "")
106
if (ch.findChannel (channelNamePrefix + "R"))
109
if (ch.findChannel (channelNamePrefix + "G"))
112
if (ch.findChannel (channelNamePrefix + "B"))
115
if (ch.findChannel (channelNamePrefix + "A"))
118
if (ch.findChannel (channelNamePrefix + "Y"))
121
if (ch.findChannel (channelNamePrefix + "RY") ||
122
ch.findChannel (channelNamePrefix + "BY"))
125
return RgbaChannels (i);
130
prefixFromLayerName (const string &layerName, const Header &header)
132
if (layerName.empty())
135
if (hasMultiView (header) && multiView(header)[0] == layerName)
138
return layerName + ".";
143
ywFromHeader (const Header &header)
147
if (hasChromaticities (header))
148
cr = chromaticities (header);
150
return computeYw (cr);
155
cachePadding (ptrdiff_t size)
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.
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.)
170
static int LOG2_CACHE_LINE_SIZE = 8;
171
static const ptrdiff_t CACHE_LINE_SIZE = (1 << LOG2_CACHE_LINE_SIZE);
173
int i = LOG2_CACHE_LINE_SIZE + 2;
175
while ((size >> i) > 1)
178
if (size > (1 << (i + 1)) - 64)
179
return 64 + ((1 << (i + 1)) - size);
181
if (size < (1 << i) + 64)
182
return 64 + ((1 << i) - size);
190
class RgbaOutputFile::ToYca: public Mutex
194
ToYca (OutputFile &outputFile, RgbaChannels rgbaChannels);
197
void setYCRounding (unsigned int roundY,
198
unsigned int roundC);
200
void setFrameBuffer (const Rgba *base,
204
void writePixels (int numScanLines);
205
int currentScanLine () const;
210
void rotateBuffers ();
211
void duplicateLastBuffer ();
212
void duplicateSecondToLastBuffer ();
213
void decimateChromaVertAndWriteScanLine ();
215
OutputFile & _outputFile;
223
LineOrder _lineOrder;
224
int _currentScanLine;
229
const Rgba * _fbBase;
237
RgbaOutputFile::ToYca::ToYca (OutputFile &outputFile,
238
RgbaChannels rgbaChannels)
240
_outputFile (outputFile)
242
_writeY = (rgbaChannels & WRITE_Y)? true: false;
243
_writeC = (rgbaChannels & WRITE_C)? true: false;
244
_writeA = (rgbaChannels & WRITE_A)? true: false;
246
const Box2i dw = _outputFile.header().dataWindow();
249
_width = dw.max.x - dw.min.x + 1;
250
_height = dw.max.y - dw.min.y + 1;
253
_lineOrder = _outputFile.header().lineOrder();
255
if (_lineOrder == INCREASING_Y)
256
_currentScanLine = dw.min.y;
258
_currentScanLine = dw.max.y;
260
_yw = ywFromHeader (_outputFile.header());
262
ptrdiff_t pad = cachePadding (_width * sizeof (Rgba)) / sizeof (Rgba);
264
_bufBase = new Rgba[(_width + pad) * N];
266
for (int i = 0; i < N; ++i)
267
_buf[i] = _bufBase + (i * (_width + pad));
269
_tmpBuf = new Rgba[_width + N - 1];
280
RgbaOutputFile::ToYca::~ToYca ()
288
RgbaOutputFile::ToYca::setYCRounding (unsigned int roundY,
297
RgbaOutputFile::ToYca::setFrameBuffer (const Rgba *base,
309
(char *) &_tmpBuf[-_xMin].g, // base
310
sizeof (Rgba), // xStride
320
(char *) &_tmpBuf[-_xMin].r, // base
321
sizeof (Rgba) * 2, // xStride
328
(char *) &_tmpBuf[-_xMin].b, // base
329
sizeof (Rgba) * 2, // xStride
339
(char *) &_tmpBuf[-_xMin].a, // base
340
sizeof (Rgba), // xStride
346
_outputFile.setFrameBuffer (fb);
350
_fbXStride = xStride;
351
_fbYStride = yStride;
356
RgbaOutputFile::ToYca::writePixels (int numScanLines)
360
THROW (Iex::ArgExc, "No frame buffer was specified as the "
361
"pixel data source for image file "
362
"\"" << _outputFile.fileName() << "\".");
365
if (_writeY && !_writeC)
368
// We are writing only luminance; filtering
369
// and subsampling are not necessary.
372
for (int i = 0; i < numScanLines; ++i)
375
// Copy the next scan line from the caller's
376
// frame buffer into _tmpBuf.
379
for (int j = 0; j < _width; ++j)
381
_tmpBuf[j] = _fbBase[_fbYStride * _currentScanLine +
382
_fbXStride * (j + _xMin)];
386
// Convert the scan line from RGB to luminance/chroma,
387
// and store the result in the output file.
390
RGBAtoYCA (_yw, _width, _writeA, _tmpBuf, _tmpBuf);
391
_outputFile.writePixels (1);
395
if (_lineOrder == INCREASING_Y)
404
// We are writing chroma; the pixels must be filtered and subsampled.
407
for (int i = 0; i < numScanLines; ++i)
410
// Copy the next scan line from the caller's
411
// frame buffer into _tmpBuf.
414
for (int j = 0; j < _width; ++j)
416
_tmpBuf[j + N2] = _fbBase[_fbYStride * _currentScanLine +
417
_fbXStride * (j + _xMin)];
421
// Convert the scan line from RGB to luminance/chroma.
424
RGBAtoYCA (_yw, _width, _writeA, _tmpBuf + N2, _tmpBuf + N2);
427
// Append N2 copies of the first and last pixel to the
428
// beginning and end of the scan line.
434
// Filter and subsample the scan line's chroma channels
435
// horizontally; store the result in _buf.
439
decimateChromaHoriz (_width, _tmpBuf, _buf[N - 1]);
442
// If this is the first scan line in the image,
443
// store N2 more copies of the scan line in _buf.
446
if (_linesConverted == 0)
448
for (int j = 0; j < N2; ++j)
449
duplicateLastBuffer();
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
461
if (_linesConverted > N2)
462
decimateChromaVertAndWriteScanLine();
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.
470
if (_linesConverted >= _height)
472
for (int j = 0; j < N2 - _height; ++j)
473
duplicateLastBuffer();
475
duplicateSecondToLastBuffer();
477
decimateChromaVertAndWriteScanLine();
479
for (int j = 1; j < min (_height, N2); ++j)
481
duplicateLastBuffer();
483
decimateChromaVertAndWriteScanLine();
487
if (_lineOrder == INCREASING_Y)
497
RgbaOutputFile::ToYca::currentScanLine () const
499
return _currentScanLine;
504
RgbaOutputFile::ToYca::padTmpBuf ()
506
for (int i = 0; i < N2; ++i)
508
_tmpBuf[i] = _tmpBuf[N2];
509
_tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
515
RgbaOutputFile::ToYca::rotateBuffers ()
519
for (int i = 0; i < N - 1; ++i)
520
_buf[i] = _buf[i + 1];
527
RgbaOutputFile::ToYca::duplicateLastBuffer ()
530
memcpy (_buf[N - 1], _buf[N - 2], _width * sizeof (Rgba));
535
RgbaOutputFile::ToYca::duplicateSecondToLastBuffer ()
538
memcpy (_buf[N - 1], _buf[N - 3], _width * sizeof (Rgba));
543
RgbaOutputFile::ToYca::decimateChromaVertAndWriteScanLine ()
545
if (_linesConverted & 1)
546
memcpy (_tmpBuf, _buf[N2], _width * sizeof (Rgba));
548
decimateChromaVert (_width, _buf, _tmpBuf);
550
if (_writeY && _writeC)
551
roundYCA (_width, _roundY, _roundC, _tmpBuf, _tmpBuf);
553
_outputFile.writePixels (1);
557
RgbaOutputFile::RgbaOutputFile (const char name[],
558
const Header &header,
559
RgbaChannels rgbaChannels,
565
insertChannels (hd, rgbaChannels);
566
_outputFile = new OutputFile (name, hd, numThreads);
568
if (rgbaChannels & (WRITE_Y | WRITE_C))
569
_toYca = new ToYca (*_outputFile, rgbaChannels);
573
RgbaOutputFile::RgbaOutputFile (OStream &os,
574
const Header &header,
575
RgbaChannels rgbaChannels,
581
insertChannels (hd, rgbaChannels);
582
_outputFile = new OutputFile (os, hd, numThreads);
584
if (rgbaChannels & (WRITE_Y | WRITE_C))
585
_toYca = new ToYca (*_outputFile, rgbaChannels);
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,
597
Compression compression,
602
Header hd (displayWindow,
603
dataWindow.isEmpty()? displayWindow: dataWindow,
610
insertChannels (hd, rgbaChannels);
611
_outputFile = new OutputFile (name, hd, numThreads);
613
if (rgbaChannels & (WRITE_Y | WRITE_C))
614
_toYca = new ToYca (*_outputFile, rgbaChannels);
618
RgbaOutputFile::RgbaOutputFile (const char name[],
621
RgbaChannels rgbaChannels,
622
float pixelAspectRatio,
623
const Imath::V2f screenWindowCenter,
624
float screenWindowWidth,
626
Compression compression,
639
insertChannels (hd, rgbaChannels);
640
_outputFile = new OutputFile (name, hd, numThreads);
642
if (rgbaChannels & (WRITE_Y | WRITE_C))
643
_toYca = new ToYca (*_outputFile, rgbaChannels);
647
RgbaOutputFile::~RgbaOutputFile ()
655
RgbaOutputFile::setFrameBuffer (const Rgba *base,
662
_toYca->setFrameBuffer (base, xStride, yStride);
666
size_t xs = xStride * sizeof (Rgba);
667
size_t ys = yStride * sizeof (Rgba);
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));
676
_outputFile->setFrameBuffer (fb);
682
RgbaOutputFile::writePixels (int numScanLines)
687
_toYca->writePixels (numScanLines);
691
_outputFile->writePixels (numScanLines);
697
RgbaOutputFile::currentScanLine () const
702
return _toYca->currentScanLine();
706
return _outputFile->currentScanLine();
712
RgbaOutputFile::header () const
714
return _outputFile->header();
719
RgbaOutputFile::frameBuffer () const
721
return _outputFile->frameBuffer();
726
RgbaOutputFile::displayWindow () const
728
return _outputFile->header().displayWindow();
733
RgbaOutputFile::dataWindow () const
735
return _outputFile->header().dataWindow();
740
RgbaOutputFile::pixelAspectRatio () const
742
return _outputFile->header().pixelAspectRatio();
747
RgbaOutputFile::screenWindowCenter () const
749
return _outputFile->header().screenWindowCenter();
754
RgbaOutputFile::screenWindowWidth () const
756
return _outputFile->header().screenWindowWidth();
761
RgbaOutputFile::lineOrder () const
763
return _outputFile->header().lineOrder();
768
RgbaOutputFile::compression () const
770
return _outputFile->header().compression();
775
RgbaOutputFile::channels () const
777
return rgbaChannels (_outputFile->header().channels());
782
RgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
784
_outputFile->updatePreviewImage (newPixels);
789
RgbaOutputFile::setYCRounding (unsigned int roundY, unsigned int roundC)
794
_toYca->setYCRounding (roundY, roundC);
800
RgbaOutputFile::breakScanLine (int y, int offset, int length, char c)
802
_outputFile->breakScanLine (y, offset, length, c);
806
class RgbaInputFile::FromYca: public Mutex
810
FromYca (InputFile &inputFile, RgbaChannels rgbaChannels);
813
void setFrameBuffer (Rgba *base,
816
const string &channelNamePrefix);
818
void readPixels (int scanLine1, int scanLine2);
822
void readPixels (int scanLine);
823
void rotateBuf1 (int d);
824
void rotateBuf2 (int d);
825
void readYCAScanLine (int y, Rgba buf[]);
828
InputFile & _inputFile;
835
int _currentScanLine;
836
LineOrder _lineOrder;
848
RgbaInputFile::FromYca::FromYca (InputFile &inputFile,
849
RgbaChannels rgbaChannels)
851
_inputFile (inputFile)
853
_readC = (rgbaChannels & WRITE_C)? true: false;
855
const Box2i dw = _inputFile.header().dataWindow();
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());
866
ptrdiff_t pad = cachePadding (_width * sizeof (Rgba)) / sizeof (Rgba);
868
_bufBase = new Rgba[(_width + pad) * (N + 2 + 3)];
870
for (int i = 0; i < N + 2; ++i)
871
_buf1[i] = _bufBase + (i * (_width + pad));
873
for (int i = 0; i < 3; ++i)
874
_buf2[i] = _bufBase + ((i + N + 2) * (_width + pad));
876
_tmpBuf = new Rgba[_width + N - 1];
884
RgbaInputFile::FromYca::~FromYca ()
892
RgbaInputFile::FromYca::setFrameBuffer (Rgba *base,
895
const string &channelNamePrefix)
901
fb.insert (channelNamePrefix + "Y",
903
(char *) &_tmpBuf[N2 - _xMin].g, // base
904
sizeof (Rgba), // xStride
912
fb.insert (channelNamePrefix + "RY",
914
(char *) &_tmpBuf[N2 - _xMin].r, // base
915
sizeof (Rgba) * 2, // xStride
921
fb.insert (channelNamePrefix + "BY",
923
(char *) &_tmpBuf[N2 - _xMin].b, // base
924
sizeof (Rgba) * 2, // xStride
931
fb.insert (channelNamePrefix + "A",
933
(char *) &_tmpBuf[N2 - _xMin].a, // base
934
sizeof (Rgba), // xStride
940
_inputFile.setFrameBuffer (fb);
944
_fbXStride = xStride;
945
_fbYStride = yStride;
950
RgbaInputFile::FromYca::readPixels (int scanLine1, int scanLine2)
952
int minY = min (scanLine1, scanLine2);
953
int maxY = max (scanLine1, scanLine2);
955
if (_lineOrder == INCREASING_Y)
957
for (int y = minY; y <= maxY; ++y)
962
for (int y = maxY; y >= minY; --y)
969
RgbaInputFile::FromYca::readPixels (int scanLine)
973
THROW (Iex::ArgExc, "No frame buffer was specified as the "
974
"pixel data destination for image file "
975
"\"" << _inputFile.fileName() << "\".");
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.
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:
987
// _currentScanLine holds the y coordinate of the scan line
988
// that was most recently read.
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.
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.
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.
1007
int dy = scanLine - _currentScanLine;
1009
if (abs (dy) < N + 2)
1018
int n = min (-dy, N + 2);
1019
int yMin = scanLine - N2 - 1;
1021
for (int i = n - 1; i >= 0; --i)
1022
readYCAScanLine (yMin + i, _buf1[i]);
1026
int n = min (-dy, 3);
1028
for (int i = 0; i < n; ++i)
1030
if ((scanLine + i) & 1)
1032
YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
1036
reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
1037
YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
1045
int n = min (dy, N + 2);
1046
int yMax = scanLine + N2 + 1;
1048
for (int i = n - 1; i >= 0; --i)
1049
readYCAScanLine (yMax - i, _buf1[N + 1 - i]);
1053
int n = min (dy, 3);
1055
for (int i = 2; i > 2 - n; --i)
1057
if ((scanLine + i) & 1)
1059
YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
1063
reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
1064
YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
1070
fixSaturation (_yw, _width, _buf2, _tmpBuf);
1072
for (int i = 0; i < _width; ++i)
1073
_fbBase[_fbYStride * scanLine + _fbXStride * (i + _xMin)] = _tmpBuf[i];
1075
_currentScanLine = scanLine;
1080
RgbaInputFile::FromYca::rotateBuf1 (int d)
1082
d = modp (d, N + 2);
1086
for (int i = 0; i < N + 2; ++i)
1089
for (int i = 0; i < N + 2; ++i)
1090
_buf1[i] = tmp[(i + d) % (N + 2)];
1095
RgbaInputFile::FromYca::rotateBuf2 (int d)
1101
for (int i = 0; i < 3; ++i)
1104
for (int i = 0; i < 3; ++i)
1105
_buf2[i] = tmp[(i + d) % 3];
1110
RgbaInputFile::FromYca::readYCAScanLine (int y, Rgba *buf)
1122
// Read scan line y into _tmpBuf.
1125
_inputFile.readPixels (y);
1128
// Reconstruct missing chroma samples and copy
1129
// the scan line into buf.
1134
for (int i = 0; i < _width; ++i)
1136
_tmpBuf[i + N2].r = 0;
1137
_tmpBuf[i + N2].b = 0;
1143
memcpy (buf, _tmpBuf + N2, _width * sizeof (Rgba));
1148
reconstructChromaHoriz (_width, _tmpBuf, buf);
1154
RgbaInputFile::FromYca::padTmpBuf ()
1156
for (int i = 0; i < N2; ++i)
1158
_tmpBuf[i] = _tmpBuf[N2];
1159
_tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
1164
RgbaInputFile::RgbaInputFile (const char name[], int numThreads):
1165
_inputFile (new InputFile (name, numThreads)),
1167
_channelNamePrefix ("")
1169
RgbaChannels rgbaChannels = channels();
1171
if (rgbaChannels & (WRITE_Y | WRITE_C))
1172
_fromYca = new FromYca (*_inputFile, rgbaChannels);
1176
RgbaInputFile::RgbaInputFile (IStream &is, int numThreads):
1177
_inputFile (new InputFile (is, numThreads)),
1179
_channelNamePrefix ("")
1181
RgbaChannels rgbaChannels = channels();
1183
if (rgbaChannels & (WRITE_Y | WRITE_C))
1184
_fromYca = new FromYca (*_inputFile, rgbaChannels);
1188
RgbaInputFile::RgbaInputFile (const char name[],
1189
const string &layerName,
1192
_inputFile (new InputFile (name, numThreads)),
1194
_channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
1196
RgbaChannels rgbaChannels = channels();
1198
if (rgbaChannels & (WRITE_Y | WRITE_C))
1199
_fromYca = new FromYca (*_inputFile, rgbaChannels);
1203
RgbaInputFile::RgbaInputFile (IStream &is,
1204
const string &layerName,
1207
_inputFile (new InputFile (is, numThreads)),
1209
_channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
1211
RgbaChannels rgbaChannels = channels();
1213
if (rgbaChannels & (WRITE_Y | WRITE_C))
1214
_fromYca = new FromYca (*_inputFile, rgbaChannels);
1218
RgbaInputFile::~RgbaInputFile ()
1226
RgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
1230
Lock lock (*_fromYca);
1231
_fromYca->setFrameBuffer (base, xStride, yStride, _channelNamePrefix);
1235
size_t xs = xStride * sizeof (Rgba);
1236
size_t ys = yStride * sizeof (Rgba);
1240
fb.insert (_channelNamePrefix + "R",
1242
(char *) &base[0].r,
1244
1, 1, // xSampling, ySampling
1247
fb.insert (_channelNamePrefix + "G",
1249
(char *) &base[0].g,
1251
1, 1, // xSampling, ySampling
1254
fb.insert (_channelNamePrefix + "B",
1256
(char *) &base[0].b,
1258
1, 1, // xSampling, ySampling
1261
fb.insert (_channelNamePrefix + "A",
1263
(char *) &base[0].a,
1265
1, 1, // xSampling, ySampling
1268
_inputFile->setFrameBuffer (fb);
1274
RgbaInputFile::setLayerName (const string &layerName)
1279
_channelNamePrefix = prefixFromLayerName (layerName, _inputFile->header());
1281
RgbaChannels rgbaChannels = channels();
1283
if (rgbaChannels & (WRITE_Y | WRITE_C))
1284
_fromYca = new FromYca (*_inputFile, rgbaChannels);
1287
_inputFile->setFrameBuffer (fb);
1292
RgbaInputFile::readPixels (int scanLine1, int scanLine2)
1296
Lock lock (*_fromYca);
1297
_fromYca->readPixels (scanLine1, scanLine2);
1301
_inputFile->readPixels (scanLine1, scanLine2);
1307
RgbaInputFile::readPixels (int scanLine)
1309
readPixels (scanLine, scanLine);
1314
RgbaInputFile::isComplete () const
1316
return _inputFile->isComplete();
1321
RgbaInputFile::header () const
1323
return _inputFile->header();
1328
RgbaInputFile::fileName () const
1330
return _inputFile->fileName();
1335
RgbaInputFile::frameBuffer () const
1337
return _inputFile->frameBuffer();
1341
const Imath::Box2i &
1342
RgbaInputFile::displayWindow () const
1344
return _inputFile->header().displayWindow();
1348
const Imath::Box2i &
1349
RgbaInputFile::dataWindow () const
1351
return _inputFile->header().dataWindow();
1356
RgbaInputFile::pixelAspectRatio () const
1358
return _inputFile->header().pixelAspectRatio();
1363
RgbaInputFile::screenWindowCenter () const
1365
return _inputFile->header().screenWindowCenter();
1370
RgbaInputFile::screenWindowWidth () const
1372
return _inputFile->header().screenWindowWidth();
1377
RgbaInputFile::lineOrder () const
1379
return _inputFile->header().lineOrder();
1384
RgbaInputFile::compression () const
1386
return _inputFile->header().compression();
1391
RgbaInputFile::channels () const
1393
return rgbaChannels (_inputFile->header().channels(), _channelNamePrefix);
1398
RgbaInputFile::version () const
1400
return _inputFile->version();