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

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/3rdparty/openexr/IlmImf/ImfTiledRgbaFile.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 TiledRgbaOutputFile
 
38
//      class TiledRgbaInputFile
 
39
//
 
40
//-----------------------------------------------------------------------------
 
41
 
 
42
#include <ImfTiledRgbaFile.h>
 
43
#include <ImfRgbaFile.h>
 
44
#include <ImfTiledOutputFile.h>
 
45
#include <ImfTiledInputFile.h>
 
46
#include <ImfChannelList.h>
 
47
#include <ImfTileDescriptionAttribute.h>
 
48
#include <ImfStandardAttributes.h>
 
49
#include <ImfRgbaYca.h>
 
50
#include <ImfArray.h>
 
51
#include "IlmThreadMutex.h"
 
52
#include "Iex.h"
 
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,
 
66
        RgbaChannels rgbaChannels,
 
67
        const char fileName[])
 
68
{
 
69
    ChannelList ch;
 
70
 
 
71
    if (rgbaChannels & (WRITE_Y | WRITE_C))
 
72
    {
 
73
    if (rgbaChannels & WRITE_Y)
 
74
    {
 
75
        ch.insert ("Y", Channel (HALF, 1, 1));
 
76
    }
 
77
 
 
78
    if (rgbaChannels & WRITE_C)
 
79
    {
 
80
        THROW (Iex::ArgExc, "Cannot open file \"" << fileName << "\" "
 
81
                "for writing.  Tiled image files do not "
 
82
                "support subsampled chroma channels.");
 
83
    }
 
84
    }
 
85
    else
 
86
    {
 
87
    if (rgbaChannels & WRITE_R)
 
88
        ch.insert ("R", Channel (HALF, 1, 1));
 
89
 
 
90
    if (rgbaChannels & WRITE_G)
 
91
        ch.insert ("G", Channel (HALF, 1, 1));
 
92
 
 
93
    if (rgbaChannels & WRITE_B)
 
94
        ch.insert ("B", Channel (HALF, 1, 1));
 
95
    }
 
96
 
 
97
    if (rgbaChannels & WRITE_A)
 
98
    ch.insert ("A", Channel (HALF, 1, 1));
 
99
 
 
100
    header.channels() = ch;
 
101
}
 
102
 
 
103
 
 
104
RgbaChannels
 
105
rgbaChannels (const ChannelList &ch, const string &channelNamePrefix = "")
 
106
{
 
107
    int i = 0;
 
108
 
 
109
    if (ch.findChannel (channelNamePrefix + "R"))
 
110
    i |= WRITE_R;
 
111
 
 
112
    if (ch.findChannel (channelNamePrefix + "G"))
 
113
    i |= WRITE_G;
 
114
 
 
115
    if (ch.findChannel (channelNamePrefix + "B"))
 
116
    i |= WRITE_B;
 
117
 
 
118
    if (ch.findChannel (channelNamePrefix + "A"))
 
119
    i |= WRITE_A;
 
120
 
 
121
    if (ch.findChannel (channelNamePrefix + "Y"))
 
122
    i |= WRITE_Y;
 
123
 
 
124
    return RgbaChannels (i);
 
125
}
 
126
 
 
127
 
 
128
string
 
129
prefixFromLayerName (const string &layerName, const Header &header)
 
130
{
 
131
    if (layerName.empty())
 
132
    return "";
 
133
 
 
134
    if (hasMultiView (header) && multiView(header)[0] == layerName)
 
135
    return "";
 
136
 
 
137
    return layerName + ".";
 
138
}
 
139
 
 
140
 
 
141
V3f
 
142
ywFromHeader (const Header &header)
 
143
{
 
144
    Chromaticities cr;
 
145
 
 
146
    if (hasChromaticities (header))
 
147
    cr = chromaticities (header);
 
148
 
 
149
    return computeYw (cr);
 
150
}
 
151
 
 
152
} // namespace
 
153
 
 
154
 
 
155
class TiledRgbaOutputFile::ToYa: public Mutex
 
156
{
 
157
  public:
 
158
 
 
159
     ToYa (TiledOutputFile &outputFile, RgbaChannels rgbaChannels);
 
160
 
 
161
     void       setFrameBuffer (const Rgba *base,
 
162
                size_t xStride,
 
163
                size_t yStride);
 
164
 
 
165
     void       writeTile (int dx, int dy, int lx, int ly);
 
166
 
 
167
  private:
 
168
 
 
169
     TiledOutputFile &  _outputFile;
 
170
     bool               _writeA;
 
171
     unsigned int       _tileXSize;
 
172
     unsigned int       _tileYSize;
 
173
     V3f                _yw;
 
174
     Array2D <Rgba>     _buf;
 
175
     const Rgba *       _fbBase;
 
176
     size_t             _fbXStride;
 
177
     size_t             _fbYStride;
 
178
};
 
179
 
 
180
 
 
181
TiledRgbaOutputFile::ToYa::ToYa (TiledOutputFile &outputFile,
 
182
                 RgbaChannels rgbaChannels)
 
183
:
 
184
    _outputFile (outputFile)
 
185
{
 
186
    _writeA = (rgbaChannels & WRITE_A)? true: false;
 
187
 
 
188
    const TileDescription &td = outputFile.header().tileDescription();
 
189
 
 
190
    _tileXSize = td.xSize;
 
191
    _tileYSize = td.ySize;
 
192
    _yw = ywFromHeader (_outputFile.header());
 
193
    _buf.resizeErase (_tileYSize, _tileXSize);
 
194
    _fbBase = 0;
 
195
    _fbXStride = 0;
 
196
    _fbYStride = 0;
 
197
}
 
198
 
 
199
 
 
200
void
 
201
TiledRgbaOutputFile::ToYa::setFrameBuffer (const Rgba *base,
 
202
                       size_t xStride,
 
203
                       size_t yStride)
 
204
{
 
205
    _fbBase = base;
 
206
    _fbXStride = xStride;
 
207
    _fbYStride = yStride;
 
208
}
 
209
 
 
210
 
 
211
void
 
212
TiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly)
 
213
{
 
214
    if (_fbBase == 0)
 
215
    {
 
216
    THROW (Iex::ArgExc, "No frame buffer was specified as the "
 
217
                "pixel data source for image file "
 
218
                "\"" << _outputFile.fileName() << "\".");
 
219
    }
 
220
 
 
221
    //
 
222
    // Copy the tile's RGBA pixels into _buf and convert
 
223
    // them to luminance/alpha format
 
224
    //
 
225
 
 
226
    Box2i dw = _outputFile.dataWindowForTile (dx, dy, lx, ly);
 
227
    int width = dw.max.x - dw.min.x + 1;
 
228
 
 
229
    for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1)
 
230
    {
 
231
    for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1)
 
232
        _buf[y1][x1] = _fbBase[x * _fbXStride + y * _fbYStride];
 
233
 
 
234
    RGBAtoYCA (_yw, width, _writeA, _buf[y1], _buf[y1]);
 
235
    }
 
236
 
 
237
    //
 
238
    // Store the contents of _buf in the output file
 
239
    //
 
240
 
 
241
    FrameBuffer fb;
 
242
 
 
243
    fb.insert ("Y", Slice (HALF,                                   // type
 
244
               (char *) &_buf[-dw.min.y][-dw.min.x].g, // base
 
245
               sizeof (Rgba),                      // xStride
 
246
               sizeof (Rgba) * _tileXSize));       // yStride
 
247
 
 
248
    fb.insert ("A", Slice (HALF,                                   // type
 
249
               (char *) &_buf[-dw.min.y][-dw.min.x].a, // base
 
250
               sizeof (Rgba),                      // xStride
 
251
               sizeof (Rgba) * _tileXSize));       // yStride
 
252
 
 
253
    _outputFile.setFrameBuffer (fb);
 
254
    _outputFile.writeTile (dx, dy, lx, ly);
 
255
}
 
256
 
 
257
 
 
258
TiledRgbaOutputFile::TiledRgbaOutputFile
 
259
    (const char name[],
 
260
     const Header &header,
 
261
     RgbaChannels rgbaChannels,
 
262
     int tileXSize,
 
263
     int tileYSize,
 
264
     LevelMode mode,
 
265
     LevelRoundingMode rmode,
 
266
     int numThreads)
 
267
:
 
268
    _outputFile (0),
 
269
    _toYa (0)
 
270
{
 
271
    Header hd (header);
 
272
    insertChannels (hd, rgbaChannels, name);
 
273
    hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
 
274
    _outputFile = new TiledOutputFile (name, hd, numThreads);
 
275
 
 
276
    if (rgbaChannels & WRITE_Y)
 
277
    _toYa = new ToYa (*_outputFile, rgbaChannels);
 
278
}
 
279
 
 
280
 
 
281
 
 
282
TiledRgbaOutputFile::TiledRgbaOutputFile
 
283
    (OStream &os,
 
284
     const Header &header,
 
285
     RgbaChannels rgbaChannels,
 
286
     int tileXSize,
 
287
     int tileYSize,
 
288
     LevelMode mode,
 
289
     LevelRoundingMode rmode,
 
290
     int numThreads)
 
291
:
 
292
    _outputFile (0),
 
293
    _toYa (0)
 
294
{
 
295
    Header hd (header);
 
296
    insertChannels (hd, rgbaChannels, os.fileName());
 
297
    hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
 
298
    _outputFile = new TiledOutputFile (os, hd, numThreads);
 
299
 
 
300
    if (rgbaChannels & WRITE_Y)
 
301
    _toYa = new ToYa (*_outputFile, rgbaChannels);
 
302
}
 
303
 
 
304
 
 
305
 
 
306
TiledRgbaOutputFile::TiledRgbaOutputFile
 
307
    (const char name[],
 
308
     int tileXSize,
 
309
     int tileYSize,
 
310
     LevelMode mode,
 
311
     LevelRoundingMode rmode,
 
312
     const Imath::Box2i &displayWindow,
 
313
     const Imath::Box2i &dataWindow,
 
314
     RgbaChannels rgbaChannels,
 
315
     float pixelAspectRatio,
 
316
     const Imath::V2f screenWindowCenter,
 
317
     float screenWindowWidth,
 
318
     LineOrder lineOrder,
 
319
     Compression compression,
 
320
     int numThreads)
 
321
:
 
322
    _outputFile (0),
 
323
    _toYa (0)
 
324
{
 
325
    Header hd (displayWindow,
 
326
           dataWindow.isEmpty()? displayWindow: dataWindow,
 
327
           pixelAspectRatio,
 
328
           screenWindowCenter,
 
329
           screenWindowWidth,
 
330
           lineOrder,
 
331
           compression);
 
332
 
 
333
    insertChannels (hd, rgbaChannels, name);
 
334
    hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
 
335
    _outputFile = new TiledOutputFile (name, hd, numThreads);
 
336
 
 
337
    if (rgbaChannels & WRITE_Y)
 
338
    _toYa = new ToYa (*_outputFile, rgbaChannels);
 
339
}
 
340
 
 
341
 
 
342
TiledRgbaOutputFile::TiledRgbaOutputFile
 
343
    (const char name[],
 
344
     int width,
 
345
     int height,
 
346
     int tileXSize,
 
347
     int tileYSize,
 
348
     LevelMode mode,
 
349
     LevelRoundingMode rmode,
 
350
     RgbaChannels rgbaChannels,
 
351
     float pixelAspectRatio,
 
352
     const Imath::V2f screenWindowCenter,
 
353
     float screenWindowWidth,
 
354
     LineOrder lineOrder,
 
355
     Compression compression,
 
356
     int numThreads)
 
357
:
 
358
    _outputFile (0),
 
359
    _toYa (0)
 
360
{
 
361
    Header hd (width,
 
362
           height,
 
363
           pixelAspectRatio,
 
364
           screenWindowCenter,
 
365
           screenWindowWidth,
 
366
           lineOrder,
 
367
           compression);
 
368
 
 
369
    insertChannels (hd, rgbaChannels, name);
 
370
    hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
 
371
    _outputFile = new TiledOutputFile (name, hd, numThreads);
 
372
 
 
373
    if (rgbaChannels & WRITE_Y)
 
374
    _toYa = new ToYa (*_outputFile, rgbaChannels);
 
375
}
 
376
 
 
377
 
 
378
TiledRgbaOutputFile::~TiledRgbaOutputFile ()
 
379
{
 
380
    delete _outputFile;
 
381
    delete _toYa;
 
382
}
 
383
 
 
384
 
 
385
void
 
386
TiledRgbaOutputFile::setFrameBuffer (const Rgba *base,
 
387
                     size_t xStride,
 
388
                     size_t yStride)
 
389
{
 
390
    if (_toYa)
 
391
    {
 
392
    Lock lock (*_toYa);
 
393
    _toYa->setFrameBuffer (base, xStride, yStride);
 
394
    }
 
395
    else
 
396
    {
 
397
    size_t xs = xStride * sizeof (Rgba);
 
398
    size_t ys = yStride * sizeof (Rgba);
 
399
 
 
400
    FrameBuffer fb;
 
401
 
 
402
    fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys));
 
403
    fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys));
 
404
    fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys));
 
405
    fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys));
 
406
 
 
407
    _outputFile->setFrameBuffer (fb);
 
408
    }
 
409
}
 
410
 
 
411
 
 
412
const Header &
 
413
TiledRgbaOutputFile::header () const
 
414
{
 
415
    return _outputFile->header();
 
416
}
 
417
 
 
418
 
 
419
const FrameBuffer &
 
420
TiledRgbaOutputFile::frameBuffer () const
 
421
{
 
422
    return _outputFile->frameBuffer();
 
423
}
 
424
 
 
425
 
 
426
const Imath::Box2i &
 
427
TiledRgbaOutputFile::displayWindow () const
 
428
{
 
429
    return _outputFile->header().displayWindow();
 
430
}
 
431
 
 
432
 
 
433
const Imath::Box2i &
 
434
TiledRgbaOutputFile::dataWindow () const
 
435
{
 
436
    return _outputFile->header().dataWindow();
 
437
}
 
438
 
 
439
 
 
440
float
 
441
TiledRgbaOutputFile::pixelAspectRatio () const
 
442
{
 
443
    return _outputFile->header().pixelAspectRatio();
 
444
}
 
445
 
 
446
 
 
447
const Imath::V2f
 
448
TiledRgbaOutputFile::screenWindowCenter () const
 
449
{
 
450
    return _outputFile->header().screenWindowCenter();
 
451
}
 
452
 
 
453
 
 
454
float
 
455
TiledRgbaOutputFile::screenWindowWidth () const
 
456
{
 
457
    return _outputFile->header().screenWindowWidth();
 
458
}
 
459
 
 
460
 
 
461
LineOrder
 
462
TiledRgbaOutputFile::lineOrder () const
 
463
{
 
464
    return _outputFile->header().lineOrder();
 
465
}
 
466
 
 
467
 
 
468
Compression
 
469
TiledRgbaOutputFile::compression () const
 
470
{
 
471
    return _outputFile->header().compression();
 
472
}
 
473
 
 
474
 
 
475
RgbaChannels
 
476
TiledRgbaOutputFile::channels () const
 
477
{
 
478
    return rgbaChannels (_outputFile->header().channels());
 
479
}
 
480
 
 
481
 
 
482
unsigned int
 
483
TiledRgbaOutputFile::tileXSize () const
 
484
{
 
485
     return _outputFile->tileXSize();
 
486
}
 
487
 
 
488
 
 
489
unsigned int
 
490
TiledRgbaOutputFile::tileYSize () const
 
491
{
 
492
     return _outputFile->tileYSize();
 
493
}
 
494
 
 
495
 
 
496
LevelMode
 
497
TiledRgbaOutputFile::levelMode () const
 
498
{
 
499
     return _outputFile->levelMode();
 
500
}
 
501
 
 
502
 
 
503
LevelRoundingMode
 
504
TiledRgbaOutputFile::levelRoundingMode () const
 
505
{
 
506
     return _outputFile->levelRoundingMode();
 
507
}
 
508
 
 
509
 
 
510
int
 
511
TiledRgbaOutputFile::numLevels () const
 
512
{
 
513
     return _outputFile->numLevels();
 
514
}
 
515
 
 
516
 
 
517
int
 
518
TiledRgbaOutputFile::numXLevels () const
 
519
{
 
520
     return _outputFile->numXLevels();
 
521
}
 
522
 
 
523
 
 
524
int
 
525
TiledRgbaOutputFile::numYLevels () const
 
526
{
 
527
     return _outputFile->numYLevels();
 
528
}
 
529
 
 
530
 
 
531
bool
 
532
TiledRgbaOutputFile::isValidLevel (int lx, int ly) const
 
533
{
 
534
    return _outputFile->isValidLevel (lx, ly);
 
535
}
 
536
 
 
537
 
 
538
int
 
539
TiledRgbaOutputFile::levelWidth (int lx) const
 
540
{
 
541
     return _outputFile->levelWidth (lx);
 
542
}
 
543
 
 
544
 
 
545
int
 
546
TiledRgbaOutputFile::levelHeight (int ly) const
 
547
{
 
548
     return _outputFile->levelHeight (ly);
 
549
}
 
550
 
 
551
 
 
552
int
 
553
TiledRgbaOutputFile::numXTiles (int lx) const
 
554
{
 
555
     return _outputFile->numXTiles (lx);
 
556
}
 
557
 
 
558
 
 
559
int
 
560
TiledRgbaOutputFile::numYTiles (int ly) const
 
561
{
 
562
     return _outputFile->numYTiles (ly);
 
563
}
 
564
 
 
565
 
 
566
Imath::Box2i
 
567
TiledRgbaOutputFile::dataWindowForLevel (int l) const
 
568
{
 
569
     return _outputFile->dataWindowForLevel (l);
 
570
}
 
571
 
 
572
 
 
573
Imath::Box2i
 
574
TiledRgbaOutputFile::dataWindowForLevel (int lx, int ly) const
 
575
{
 
576
     return _outputFile->dataWindowForLevel (lx, ly);
 
577
}
 
578
 
 
579
 
 
580
Imath::Box2i
 
581
TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int l) const
 
582
{
 
583
     return _outputFile->dataWindowForTile (dx, dy, l);
 
584
}
 
585
 
 
586
 
 
587
Imath::Box2i
 
588
TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
 
589
{
 
590
     return _outputFile->dataWindowForTile (dx, dy, lx, ly);
 
591
}
 
592
 
 
593
 
 
594
void
 
595
TiledRgbaOutputFile::writeTile (int dx, int dy, int l)
 
596
{
 
597
    if (_toYa)
 
598
    {
 
599
    Lock lock (*_toYa);
 
600
    _toYa->writeTile (dx, dy, l, l);
 
601
    }
 
602
    else
 
603
    {
 
604
     _outputFile->writeTile (dx, dy, l);
 
605
    }
 
606
}
 
607
 
 
608
 
 
609
void
 
610
TiledRgbaOutputFile::writeTile (int dx, int dy, int lx, int ly)
 
611
{
 
612
    if (_toYa)
 
613
    {
 
614
    Lock lock (*_toYa);
 
615
    _toYa->writeTile (dx, dy, lx, ly);
 
616
    }
 
617
    else
 
618
    {
 
619
     _outputFile->writeTile (dx, dy, lx, ly);
 
620
    }
 
621
}
 
622
 
 
623
 
 
624
void
 
625
TiledRgbaOutputFile::writeTiles
 
626
    (int dxMin, int dxMax, int dyMin, int dyMax, int lx, int ly)
 
627
{
 
628
    if (_toYa)
 
629
    {
 
630
    Lock lock (*_toYa);
 
631
 
 
632
        for (int dy = dyMin; dy <= dyMax; dy++)
 
633
            for (int dx = dxMin; dx <= dxMax; dx++)
 
634
            _toYa->writeTile (dx, dy, lx, ly);
 
635
    }
 
636
    else
 
637
    {
 
638
        _outputFile->writeTiles (dxMin, dxMax, dyMin, dyMax, lx, ly);
 
639
    }
 
640
}
 
641
 
 
642
void
 
643
TiledRgbaOutputFile::writeTiles
 
644
    (int dxMin, int dxMax, int dyMin, int dyMax, int l)
 
645
{
 
646
    writeTiles (dxMin, dxMax, dyMin, dyMax, l, l);
 
647
}
 
648
 
 
649
 
 
650
class TiledRgbaInputFile::FromYa: public Mutex
 
651
{
 
652
  public:
 
653
 
 
654
     FromYa (TiledInputFile &inputFile);
 
655
 
 
656
     void       setFrameBuffer (Rgba *base,
 
657
                size_t xStride,
 
658
                size_t yStride,
 
659
                const string &channelNamePrefix);
 
660
 
 
661
     void       readTile (int dx, int dy, int lx, int ly);
 
662
 
 
663
  private:
 
664
 
 
665
     TiledInputFile &   _inputFile;
 
666
     unsigned int       _tileXSize;
 
667
     unsigned int       _tileYSize;
 
668
     V3f                _yw;
 
669
     Array2D <Rgba>     _buf;
 
670
     Rgba *             _fbBase;
 
671
     size_t             _fbXStride;
 
672
     size_t             _fbYStride;
 
673
};
 
674
 
 
675
 
 
676
TiledRgbaInputFile::FromYa::FromYa (TiledInputFile &inputFile)
 
677
:
 
678
    _inputFile (inputFile)
 
679
{
 
680
    const TileDescription &td = inputFile.header().tileDescription();
 
681
 
 
682
    _tileXSize = td.xSize;
 
683
    _tileYSize = td.ySize;
 
684
    _yw = ywFromHeader (_inputFile.header());
 
685
    _buf.resizeErase (_tileYSize, _tileXSize);
 
686
    _fbBase = 0;
 
687
    _fbXStride = 0;
 
688
    _fbYStride = 0;
 
689
}
 
690
 
 
691
 
 
692
void
 
693
TiledRgbaInputFile::FromYa::setFrameBuffer (Rgba *base,
 
694
                        size_t xStride,
 
695
                        size_t yStride,
 
696
                        const string &channelNamePrefix)
 
697
{
 
698
    if (_fbBase == 0)
 
699
{
 
700
    FrameBuffer fb;
 
701
 
 
702
    fb.insert (channelNamePrefix + "Y",
 
703
           Slice (HALF,                         // type
 
704
              (char *) &_buf[0][0].g,   // base
 
705
              sizeof (Rgba),            // xStride
 
706
              sizeof (Rgba) * _tileXSize,       // yStride
 
707
              1, 1,                             // sampling
 
708
              0.0,                              // fillValue
 
709
              true, true));                     // tileCoordinates
 
710
 
 
711
    fb.insert (channelNamePrefix + "A",
 
712
           Slice (HALF,                         // type
 
713
              (char *) &_buf[0][0].a,   // base
 
714
              sizeof (Rgba),            // xStride
 
715
              sizeof (Rgba) * _tileXSize,       // yStride
 
716
              1, 1,                             // sampling
 
717
              1.0,                              // fillValue
 
718
              true, true));                     // tileCoordinates
 
719
 
 
720
    _inputFile.setFrameBuffer (fb);
 
721
    }
 
722
 
 
723
    _fbBase = base;
 
724
    _fbXStride = xStride;
 
725
    _fbYStride = yStride;
 
726
}
 
727
 
 
728
 
 
729
void
 
730
TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly)
 
731
{
 
732
    if (_fbBase == 0)
 
733
    {
 
734
    THROW (Iex::ArgExc, "No frame buffer was specified as the "
 
735
                "pixel data destination for image file "
 
736
                "\"" << _inputFile.fileName() << "\".");
 
737
    }
 
738
 
 
739
    //
 
740
    // Read the tile requested by the caller into _buf.
 
741
    //
 
742
 
 
743
    _inputFile.readTile (dx, dy, lx, ly);
 
744
 
 
745
    //
 
746
    // Convert the luminance/alpha pixels to RGBA
 
747
    // and copy them into the caller's frame buffer.
 
748
    //
 
749
 
 
750
    Box2i dw = _inputFile.dataWindowForTile (dx, dy, lx, ly);
 
751
    int width = dw.max.x - dw.min.x + 1;
 
752
 
 
753
    for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1)
 
754
    {
 
755
    for (int x1 = 0; x1 < width; ++x1)
 
756
    {
 
757
        _buf[y1][x1].r = 0;
 
758
        _buf[y1][x1].b = 0;
 
759
    }
 
760
 
 
761
    YCAtoRGBA (_yw, width, _buf[y1], _buf[y1]);
 
762
 
 
763
    for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1)
 
764
    {
 
765
        _fbBase[x * _fbXStride + y * _fbYStride] = _buf[y1][x1];
 
766
    }
 
767
    }
 
768
}
 
769
 
 
770
 
 
771
TiledRgbaInputFile::TiledRgbaInputFile (const char name[], int numThreads):
 
772
    _inputFile (new TiledInputFile (name, numThreads)),
 
773
    _fromYa (0),
 
774
    _channelNamePrefix ("")
 
775
{
 
776
    if (channels() & WRITE_Y)
 
777
    _fromYa = new FromYa (*_inputFile);
 
778
}
 
779
 
 
780
 
 
781
TiledRgbaInputFile::TiledRgbaInputFile (IStream &is, int numThreads):
 
782
    _inputFile (new TiledInputFile (is, numThreads)),
 
783
    _fromYa (0),
 
784
    _channelNamePrefix ("")
 
785
{
 
786
    if (channels() & WRITE_Y)
 
787
    _fromYa = new FromYa (*_inputFile);
 
788
}
 
789
 
 
790
 
 
791
TiledRgbaInputFile::TiledRgbaInputFile (const char name[],
 
792
                    const string &layerName,
 
793
                    int numThreads)
 
794
:
 
795
    _inputFile (new TiledInputFile (name, numThreads)),
 
796
    _fromYa (0),
 
797
    _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
 
798
{
 
799
    if (channels() & WRITE_Y)
 
800
    _fromYa = new FromYa (*_inputFile);
 
801
}
 
802
 
 
803
 
 
804
TiledRgbaInputFile::TiledRgbaInputFile (IStream &is,
 
805
                    const string &layerName,
 
806
                    int numThreads)
 
807
:
 
808
    _inputFile (new TiledInputFile (is, numThreads)),
 
809
    _fromYa (0),
 
810
    _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
 
811
{
 
812
    if (channels() & WRITE_Y)
 
813
    _fromYa = new FromYa (*_inputFile);
 
814
}
 
815
 
 
816
 
 
817
TiledRgbaInputFile::~TiledRgbaInputFile ()
 
818
{
 
819
    delete _inputFile;
 
820
    delete _fromYa;
 
821
}
 
822
 
 
823
 
 
824
void
 
825
TiledRgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
 
826
{
 
827
    if (_fromYa)
 
828
    {
 
829
    Lock lock (*_fromYa);
 
830
    _fromYa->setFrameBuffer (base, xStride, yStride, _channelNamePrefix);
 
831
    }
 
832
    else
 
833
    {
 
834
    size_t xs = xStride * sizeof (Rgba);
 
835
    size_t ys = yStride * sizeof (Rgba);
 
836
 
 
837
    FrameBuffer fb;
 
838
 
 
839
    fb.insert (_channelNamePrefix + "R",
 
840
           Slice (HALF,
 
841
                   (char *) &base[0].r,
 
842
                   xs, ys,
 
843
                   1, 1,        // xSampling, ySampling
 
844
                   0.0));       // fillValue
 
845
 
 
846
    fb.insert (_channelNamePrefix + "G",
 
847
           Slice (HALF,
 
848
                   (char *) &base[0].g,
 
849
                   xs, ys,
 
850
                   1, 1,        // xSampling, ySampling
 
851
                   0.0));       // fillValue
 
852
 
 
853
    fb.insert (_channelNamePrefix + "B",
 
854
           Slice (HALF,
 
855
                   (char *) &base[0].b,
 
856
                   xs, ys,
 
857
                   1, 1,        // xSampling, ySampling
 
858
                   0.0));       // fillValue
 
859
 
 
860
    fb.insert (_channelNamePrefix + "A",
 
861
           Slice (HALF,
 
862
                   (char *) &base[0].a,
 
863
                   xs, ys,
 
864
                   1, 1,        // xSampling, ySampling
 
865
                   1.0));       // fillValue
 
866
 
 
867
    _inputFile->setFrameBuffer (fb);
 
868
    }
 
869
}
 
870
 
 
871
 
 
872
void
 
873
TiledRgbaInputFile::setLayerName (const std::string &layerName)
 
874
{
 
875
    delete _fromYa;
 
876
    _fromYa = 0;
 
877
 
 
878
    _channelNamePrefix = prefixFromLayerName (layerName, _inputFile->header());
 
879
 
 
880
    if (channels() & WRITE_Y)
 
881
    _fromYa = new FromYa (*_inputFile);
 
882
 
 
883
    FrameBuffer fb;
 
884
    _inputFile->setFrameBuffer (fb);
 
885
}
 
886
 
 
887
 
 
888
const Header &
 
889
TiledRgbaInputFile::header () const
 
890
{
 
891
    return _inputFile->header();
 
892
}
 
893
 
 
894
 
 
895
const char *
 
896
TiledRgbaInputFile::fileName () const
 
897
{
 
898
    return _inputFile->fileName();
 
899
}
 
900
 
 
901
 
 
902
const FrameBuffer &
 
903
TiledRgbaInputFile::frameBuffer () const
 
904
{
 
905
    return _inputFile->frameBuffer();
 
906
}
 
907
 
 
908
 
 
909
const Imath::Box2i &
 
910
TiledRgbaInputFile::displayWindow () const
 
911
{
 
912
    return _inputFile->header().displayWindow();
 
913
}
 
914
 
 
915
 
 
916
const Imath::Box2i &
 
917
TiledRgbaInputFile::dataWindow () const
 
918
{
 
919
    return _inputFile->header().dataWindow();
 
920
}
 
921
 
 
922
 
 
923
float
 
924
TiledRgbaInputFile::pixelAspectRatio () const
 
925
{
 
926
    return _inputFile->header().pixelAspectRatio();
 
927
}
 
928
 
 
929
 
 
930
const Imath::V2f
 
931
TiledRgbaInputFile::screenWindowCenter () const
 
932
{
 
933
    return _inputFile->header().screenWindowCenter();
 
934
}
 
935
 
 
936
 
 
937
float
 
938
TiledRgbaInputFile::screenWindowWidth () const
 
939
{
 
940
    return _inputFile->header().screenWindowWidth();
 
941
}
 
942
 
 
943
 
 
944
LineOrder
 
945
TiledRgbaInputFile::lineOrder () const
 
946
{
 
947
    return _inputFile->header().lineOrder();
 
948
}
 
949
 
 
950
 
 
951
Compression
 
952
TiledRgbaInputFile::compression () const
 
953
{
 
954
    return _inputFile->header().compression();
 
955
}
 
956
 
 
957
 
 
958
RgbaChannels
 
959
TiledRgbaInputFile::channels () const
 
960
{
 
961
    return rgbaChannels (_inputFile->header().channels(), _channelNamePrefix);
 
962
}
 
963
 
 
964
 
 
965
int
 
966
TiledRgbaInputFile::version () const
 
967
{
 
968
    return _inputFile->version();
 
969
}
 
970
 
 
971
 
 
972
bool
 
973
TiledRgbaInputFile::isComplete () const
 
974
{
 
975
    return _inputFile->isComplete();
 
976
}
 
977
 
 
978
 
 
979
unsigned int
 
980
TiledRgbaInputFile::tileXSize () const
 
981
{
 
982
     return _inputFile->tileXSize();
 
983
}
 
984
 
 
985
 
 
986
unsigned int
 
987
TiledRgbaInputFile::tileYSize () const
 
988
{
 
989
     return _inputFile->tileYSize();
 
990
}
 
991
 
 
992
 
 
993
LevelMode
 
994
TiledRgbaInputFile::levelMode () const
 
995
{
 
996
     return _inputFile->levelMode();
 
997
}
 
998
 
 
999
 
 
1000
LevelRoundingMode
 
1001
TiledRgbaInputFile::levelRoundingMode () const
 
1002
{
 
1003
     return _inputFile->levelRoundingMode();
 
1004
}
 
1005
 
 
1006
 
 
1007
int
 
1008
TiledRgbaInputFile::numLevels () const
 
1009
{
 
1010
     return _inputFile->numLevels();
 
1011
}
 
1012
 
 
1013
 
 
1014
int
 
1015
TiledRgbaInputFile::numXLevels () const
 
1016
{
 
1017
     return _inputFile->numXLevels();
 
1018
}
 
1019
 
 
1020
 
 
1021
int
 
1022
TiledRgbaInputFile::numYLevels () const
 
1023
{
 
1024
     return _inputFile->numYLevels();
 
1025
}
 
1026
 
 
1027
 
 
1028
bool
 
1029
TiledRgbaInputFile::isValidLevel (int lx, int ly) const
 
1030
{
 
1031
    return _inputFile->isValidLevel (lx, ly);
 
1032
}
 
1033
 
 
1034
 
 
1035
int
 
1036
TiledRgbaInputFile::levelWidth (int lx) const
 
1037
{
 
1038
     return _inputFile->levelWidth (lx);
 
1039
}
 
1040
 
 
1041
 
 
1042
int
 
1043
TiledRgbaInputFile::levelHeight (int ly) const
 
1044
{
 
1045
     return _inputFile->levelHeight (ly);
 
1046
}
 
1047
 
 
1048
 
 
1049
int
 
1050
TiledRgbaInputFile::numXTiles (int lx) const
 
1051
{
 
1052
     return _inputFile->numXTiles(lx);
 
1053
}
 
1054
 
 
1055
 
 
1056
int
 
1057
TiledRgbaInputFile::numYTiles (int ly) const
 
1058
{
 
1059
     return _inputFile->numYTiles(ly);
 
1060
}
 
1061
 
 
1062
 
 
1063
Imath::Box2i
 
1064
TiledRgbaInputFile::dataWindowForLevel (int l) const
 
1065
{
 
1066
     return _inputFile->dataWindowForLevel (l);
 
1067
}
 
1068
 
 
1069
 
 
1070
Imath::Box2i
 
1071
TiledRgbaInputFile::dataWindowForLevel (int lx, int ly) const
 
1072
{
 
1073
     return _inputFile->dataWindowForLevel (lx, ly);
 
1074
}
 
1075
 
 
1076
 
 
1077
Imath::Box2i
 
1078
TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int l) const
 
1079
{
 
1080
     return _inputFile->dataWindowForTile (dx, dy, l);
 
1081
}
 
1082
 
 
1083
 
 
1084
Imath::Box2i
 
1085
TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
 
1086
{
 
1087
     return _inputFile->dataWindowForTile (dx, dy, lx, ly);
 
1088
}
 
1089
 
 
1090
 
 
1091
void
 
1092
TiledRgbaInputFile::readTile (int dx, int dy, int l)
 
1093
{
 
1094
    if (_fromYa)
 
1095
    {
 
1096
    Lock lock (*_fromYa);
 
1097
    _fromYa->readTile (dx, dy, l, l);
 
1098
    }
 
1099
    else
 
1100
    {
 
1101
     _inputFile->readTile (dx, dy, l);
 
1102
    }
 
1103
}
 
1104
 
 
1105
 
 
1106
void
 
1107
TiledRgbaInputFile::readTile (int dx, int dy, int lx, int ly)
 
1108
{
 
1109
    if (_fromYa)
 
1110
    {
 
1111
    Lock lock (*_fromYa);
 
1112
    _fromYa->readTile (dx, dy, lx, ly);
 
1113
    }
 
1114
    else
 
1115
    {
 
1116
     _inputFile->readTile (dx, dy, lx, ly);
 
1117
    }
 
1118
}
 
1119
 
 
1120
 
 
1121
void
 
1122
TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax,
 
1123
                               int lx, int ly)
 
1124
{
 
1125
    if (_fromYa)
 
1126
    {
 
1127
    Lock lock (*_fromYa);
 
1128
 
 
1129
        for (int dy = dyMin; dy <= dyMax; dy++)
 
1130
            for (int dx = dxMin; dx <= dxMax; dx++)
 
1131
            _fromYa->readTile (dx, dy, lx, ly);
 
1132
    }
 
1133
    else
 
1134
    {
 
1135
        _inputFile->readTiles (dxMin, dxMax, dyMin, dyMax, lx, ly);
 
1136
    }
 
1137
}
 
1138
 
 
1139
void
 
1140
TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax,
 
1141
                               int l)
 
1142
{
 
1143
    readTiles (dxMin, dxMax, dyMin, dyMax, l, l);
 
1144
}
 
1145
 
 
1146
 
 
1147
void
 
1148
TiledRgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 
1149
{
 
1150
    _outputFile->updatePreviewImage (newPixels);
 
1151
}
 
1152
 
 
1153
 
 
1154
void
 
1155
TiledRgbaOutputFile::breakTile  (int dx, int dy, int lx, int ly,
 
1156
                 int offset, int length, char c)
 
1157
{
 
1158
    _outputFile->breakTile (dx, dy, lx, ly, offset, length, c);
 
1159
}
 
1160
 
 
1161
 
 
1162
} // namespace Imf