PageRenderTime 39ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/src/3rdparty/openexr-1.7.0/ImfTiledRgbaFile.cpp

https://bitbucket.org/melbyruarus/pbrt
C++ | 1162 lines | 852 code | 257 blank | 53 comment | 49 complexity | de0d2bc225205dc30471caf6e96d8110 MD5 | raw file
  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. // class TiledRgbaOutputFile
  37. // class TiledRgbaInputFile
  38. //
  39. //-----------------------------------------------------------------------------
  40. #include <ImfTiledRgbaFile.h>
  41. #include <ImfRgbaFile.h>
  42. #include <ImfTiledOutputFile.h>
  43. #include <ImfTiledInputFile.h>
  44. #include <ImfChannelList.h>
  45. #include <ImfTileDescriptionAttribute.h>
  46. #include <ImfStandardAttributes.h>
  47. #include <ImfRgbaYca.h>
  48. #include <ImfArray.h>
  49. #include "IlmThreadMutex.h"
  50. #include "Iex.h"
  51. namespace Imf {
  52. using namespace std;
  53. using namespace Imath;
  54. using namespace RgbaYca;
  55. using namespace IlmThread;
  56. namespace {
  57. void
  58. insertChannels (Header &header,
  59. RgbaChannels rgbaChannels,
  60. const char fileName[])
  61. {
  62. ChannelList ch;
  63. if (rgbaChannels & (WRITE_Y | WRITE_C))
  64. {
  65. if (rgbaChannels & WRITE_Y)
  66. {
  67. ch.insert ("Y", Channel (HALF, 1, 1));
  68. }
  69. if (rgbaChannels & WRITE_C)
  70. {
  71. THROW (Iex::ArgExc, "Cannot open file \"" << fileName << "\" "
  72. "for writing. Tiled image files do not "
  73. "support subsampled chroma channels.");
  74. }
  75. }
  76. else
  77. {
  78. if (rgbaChannels & WRITE_R)
  79. ch.insert ("R", Channel (HALF, 1, 1));
  80. if (rgbaChannels & WRITE_G)
  81. ch.insert ("G", Channel (HALF, 1, 1));
  82. if (rgbaChannels & WRITE_B)
  83. ch.insert ("B", Channel (HALF, 1, 1));
  84. }
  85. if (rgbaChannels & WRITE_A)
  86. ch.insert ("A", Channel (HALF, 1, 1));
  87. header.channels() = ch;
  88. }
  89. RgbaChannels
  90. rgbaChannels (const ChannelList &ch, const string &channelNamePrefix = "")
  91. {
  92. int i = 0;
  93. if (ch.findChannel (channelNamePrefix + "R"))
  94. i |= WRITE_R;
  95. if (ch.findChannel (channelNamePrefix + "G"))
  96. i |= WRITE_G;
  97. if (ch.findChannel (channelNamePrefix + "B"))
  98. i |= WRITE_B;
  99. if (ch.findChannel (channelNamePrefix + "A"))
  100. i |= WRITE_A;
  101. if (ch.findChannel (channelNamePrefix + "Y"))
  102. i |= WRITE_Y;
  103. return RgbaChannels (i);
  104. }
  105. string
  106. prefixFromLayerName (const string &layerName, const Header &header)
  107. {
  108. if (layerName.empty())
  109. return "";
  110. if (hasMultiView (header) && multiView(header)[0] == layerName)
  111. return "";
  112. return layerName + ".";
  113. }
  114. V3f
  115. ywFromHeader (const Header &header)
  116. {
  117. Chromaticities cr;
  118. if (hasChromaticities (header))
  119. cr = chromaticities (header);
  120. return computeYw (cr);
  121. }
  122. } // namespace
  123. class TiledRgbaOutputFile::ToYa: public Mutex
  124. {
  125. public:
  126. ToYa (TiledOutputFile &outputFile, RgbaChannels rgbaChannels);
  127. void setFrameBuffer (const Rgba *base,
  128. size_t xStride,
  129. size_t yStride);
  130. void writeTile (int dx, int dy, int lx, int ly);
  131. private:
  132. TiledOutputFile & _outputFile;
  133. bool _writeA;
  134. unsigned int _tileXSize;
  135. unsigned int _tileYSize;
  136. V3f _yw;
  137. Array2D <Rgba> _buf;
  138. const Rgba * _fbBase;
  139. size_t _fbXStride;
  140. size_t _fbYStride;
  141. };
  142. TiledRgbaOutputFile::ToYa::ToYa (TiledOutputFile &outputFile,
  143. RgbaChannels rgbaChannels)
  144. :
  145. _outputFile (outputFile)
  146. {
  147. _writeA = (rgbaChannels & WRITE_A)? true: false;
  148. const TileDescription &td = outputFile.header().tileDescription();
  149. _tileXSize = td.xSize;
  150. _tileYSize = td.ySize;
  151. _yw = ywFromHeader (_outputFile.header());
  152. _buf.resizeErase (_tileYSize, _tileXSize);
  153. _fbBase = 0;
  154. _fbXStride = 0;
  155. _fbYStride = 0;
  156. }
  157. void
  158. TiledRgbaOutputFile::ToYa::setFrameBuffer (const Rgba *base,
  159. size_t xStride,
  160. size_t yStride)
  161. {
  162. _fbBase = base;
  163. _fbXStride = xStride;
  164. _fbYStride = yStride;
  165. }
  166. void
  167. TiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly)
  168. {
  169. if (_fbBase == 0)
  170. {
  171. THROW (Iex::ArgExc, "No frame buffer was specified as the "
  172. "pixel data source for image file "
  173. "\"" << _outputFile.fileName() << "\".");
  174. }
  175. //
  176. // Copy the tile's RGBA pixels into _buf and convert
  177. // them to luminance/alpha format
  178. //
  179. Box2i dw = _outputFile.dataWindowForTile (dx, dy, lx, ly);
  180. int width = dw.max.x - dw.min.x + 1;
  181. for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1)
  182. {
  183. for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1)
  184. _buf[y1][x1] = _fbBase[x * _fbXStride + y * _fbYStride];
  185. RGBAtoYCA (_yw, width, _writeA, _buf[y1], _buf[y1]);
  186. }
  187. //
  188. // Store the contents of _buf in the output file
  189. //
  190. FrameBuffer fb;
  191. fb.insert ("Y", Slice (HALF, // type
  192. (char *) &_buf[-dw.min.y][-dw.min.x].g, // base
  193. sizeof (Rgba), // xStride
  194. sizeof (Rgba) * _tileXSize)); // yStride
  195. fb.insert ("A", Slice (HALF, // type
  196. (char *) &_buf[-dw.min.y][-dw.min.x].a, // base
  197. sizeof (Rgba), // xStride
  198. sizeof (Rgba) * _tileXSize)); // yStride
  199. _outputFile.setFrameBuffer (fb);
  200. _outputFile.writeTile (dx, dy, lx, ly);
  201. }
  202. TiledRgbaOutputFile::TiledRgbaOutputFile
  203. (const char name[],
  204. const Header &header,
  205. RgbaChannels rgbaChannels,
  206. int tileXSize,
  207. int tileYSize,
  208. LevelMode mode,
  209. LevelRoundingMode rmode,
  210. int numThreads)
  211. :
  212. _outputFile (0),
  213. _toYa (0)
  214. {
  215. Header hd (header);
  216. insertChannels (hd, rgbaChannels, name);
  217. hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
  218. _outputFile = new TiledOutputFile (name, hd, numThreads);
  219. if (rgbaChannels & WRITE_Y)
  220. _toYa = new ToYa (*_outputFile, rgbaChannels);
  221. }
  222. TiledRgbaOutputFile::TiledRgbaOutputFile
  223. (OStream &os,
  224. const Header &header,
  225. RgbaChannels rgbaChannels,
  226. int tileXSize,
  227. int tileYSize,
  228. LevelMode mode,
  229. LevelRoundingMode rmode,
  230. int numThreads)
  231. :
  232. _outputFile (0),
  233. _toYa (0)
  234. {
  235. Header hd (header);
  236. insertChannels (hd, rgbaChannels, os.fileName());
  237. hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
  238. _outputFile = new TiledOutputFile (os, hd, numThreads);
  239. if (rgbaChannels & WRITE_Y)
  240. _toYa = new ToYa (*_outputFile, rgbaChannels);
  241. }
  242. TiledRgbaOutputFile::TiledRgbaOutputFile
  243. (const char name[],
  244. int tileXSize,
  245. int tileYSize,
  246. LevelMode mode,
  247. LevelRoundingMode rmode,
  248. const Imath::Box2i &displayWindow,
  249. const Imath::Box2i &dataWindow,
  250. RgbaChannels rgbaChannels,
  251. float pixelAspectRatio,
  252. const Imath::V2f screenWindowCenter,
  253. float screenWindowWidth,
  254. LineOrder lineOrder,
  255. Compression compression,
  256. int numThreads)
  257. :
  258. _outputFile (0),
  259. _toYa (0)
  260. {
  261. Header hd (displayWindow,
  262. dataWindow.isEmpty()? displayWindow: dataWindow,
  263. pixelAspectRatio,
  264. screenWindowCenter,
  265. screenWindowWidth,
  266. lineOrder,
  267. compression);
  268. insertChannels (hd, rgbaChannels, name);
  269. hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
  270. _outputFile = new TiledOutputFile (name, hd, numThreads);
  271. if (rgbaChannels & WRITE_Y)
  272. _toYa = new ToYa (*_outputFile, rgbaChannels);
  273. }
  274. TiledRgbaOutputFile::TiledRgbaOutputFile
  275. (const char name[],
  276. int width,
  277. int height,
  278. int tileXSize,
  279. int tileYSize,
  280. LevelMode mode,
  281. LevelRoundingMode rmode,
  282. RgbaChannels rgbaChannels,
  283. float pixelAspectRatio,
  284. const Imath::V2f screenWindowCenter,
  285. float screenWindowWidth,
  286. LineOrder lineOrder,
  287. Compression compression,
  288. int numThreads)
  289. :
  290. _outputFile (0),
  291. _toYa (0)
  292. {
  293. Header hd (width,
  294. height,
  295. pixelAspectRatio,
  296. screenWindowCenter,
  297. screenWindowWidth,
  298. lineOrder,
  299. compression);
  300. insertChannels (hd, rgbaChannels, name);
  301. hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
  302. _outputFile = new TiledOutputFile (name, hd, numThreads);
  303. if (rgbaChannels & WRITE_Y)
  304. _toYa = new ToYa (*_outputFile, rgbaChannels);
  305. }
  306. TiledRgbaOutputFile::~TiledRgbaOutputFile ()
  307. {
  308. delete _outputFile;
  309. delete _toYa;
  310. }
  311. void
  312. TiledRgbaOutputFile::setFrameBuffer (const Rgba *base,
  313. size_t xStride,
  314. size_t yStride)
  315. {
  316. if (_toYa)
  317. {
  318. Lock lock (*_toYa);
  319. _toYa->setFrameBuffer (base, xStride, yStride);
  320. }
  321. else
  322. {
  323. size_t xs = xStride * sizeof (Rgba);
  324. size_t ys = yStride * sizeof (Rgba);
  325. FrameBuffer fb;
  326. fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys));
  327. fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys));
  328. fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys));
  329. fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys));
  330. _outputFile->setFrameBuffer (fb);
  331. }
  332. }
  333. const Header &
  334. TiledRgbaOutputFile::header () const
  335. {
  336. return _outputFile->header();
  337. }
  338. const FrameBuffer &
  339. TiledRgbaOutputFile::frameBuffer () const
  340. {
  341. return _outputFile->frameBuffer();
  342. }
  343. const Imath::Box2i &
  344. TiledRgbaOutputFile::displayWindow () const
  345. {
  346. return _outputFile->header().displayWindow();
  347. }
  348. const Imath::Box2i &
  349. TiledRgbaOutputFile::dataWindow () const
  350. {
  351. return _outputFile->header().dataWindow();
  352. }
  353. float
  354. TiledRgbaOutputFile::pixelAspectRatio () const
  355. {
  356. return _outputFile->header().pixelAspectRatio();
  357. }
  358. const Imath::V2f
  359. TiledRgbaOutputFile::screenWindowCenter () const
  360. {
  361. return _outputFile->header().screenWindowCenter();
  362. }
  363. float
  364. TiledRgbaOutputFile::screenWindowWidth () const
  365. {
  366. return _outputFile->header().screenWindowWidth();
  367. }
  368. LineOrder
  369. TiledRgbaOutputFile::lineOrder () const
  370. {
  371. return _outputFile->header().lineOrder();
  372. }
  373. Compression
  374. TiledRgbaOutputFile::compression () const
  375. {
  376. return _outputFile->header().compression();
  377. }
  378. RgbaChannels
  379. TiledRgbaOutputFile::channels () const
  380. {
  381. return rgbaChannels (_outputFile->header().channels());
  382. }
  383. unsigned int
  384. TiledRgbaOutputFile::tileXSize () const
  385. {
  386. return _outputFile->tileXSize();
  387. }
  388. unsigned int
  389. TiledRgbaOutputFile::tileYSize () const
  390. {
  391. return _outputFile->tileYSize();
  392. }
  393. LevelMode
  394. TiledRgbaOutputFile::levelMode () const
  395. {
  396. return _outputFile->levelMode();
  397. }
  398. LevelRoundingMode
  399. TiledRgbaOutputFile::levelRoundingMode () const
  400. {
  401. return _outputFile->levelRoundingMode();
  402. }
  403. int
  404. TiledRgbaOutputFile::numLevels () const
  405. {
  406. return _outputFile->numLevels();
  407. }
  408. int
  409. TiledRgbaOutputFile::numXLevels () const
  410. {
  411. return _outputFile->numXLevels();
  412. }
  413. int
  414. TiledRgbaOutputFile::numYLevels () const
  415. {
  416. return _outputFile->numYLevels();
  417. }
  418. bool
  419. TiledRgbaOutputFile::isValidLevel (int lx, int ly) const
  420. {
  421. return _outputFile->isValidLevel (lx, ly);
  422. }
  423. int
  424. TiledRgbaOutputFile::levelWidth (int lx) const
  425. {
  426. return _outputFile->levelWidth (lx);
  427. }
  428. int
  429. TiledRgbaOutputFile::levelHeight (int ly) const
  430. {
  431. return _outputFile->levelHeight (ly);
  432. }
  433. int
  434. TiledRgbaOutputFile::numXTiles (int lx) const
  435. {
  436. return _outputFile->numXTiles (lx);
  437. }
  438. int
  439. TiledRgbaOutputFile::numYTiles (int ly) const
  440. {
  441. return _outputFile->numYTiles (ly);
  442. }
  443. Imath::Box2i
  444. TiledRgbaOutputFile::dataWindowForLevel (int l) const
  445. {
  446. return _outputFile->dataWindowForLevel (l);
  447. }
  448. Imath::Box2i
  449. TiledRgbaOutputFile::dataWindowForLevel (int lx, int ly) const
  450. {
  451. return _outputFile->dataWindowForLevel (lx, ly);
  452. }
  453. Imath::Box2i
  454. TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int l) const
  455. {
  456. return _outputFile->dataWindowForTile (dx, dy, l);
  457. }
  458. Imath::Box2i
  459. TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
  460. {
  461. return _outputFile->dataWindowForTile (dx, dy, lx, ly);
  462. }
  463. void
  464. TiledRgbaOutputFile::writeTile (int dx, int dy, int l)
  465. {
  466. if (_toYa)
  467. {
  468. Lock lock (*_toYa);
  469. _toYa->writeTile (dx, dy, l, l);
  470. }
  471. else
  472. {
  473. _outputFile->writeTile (dx, dy, l);
  474. }
  475. }
  476. void
  477. TiledRgbaOutputFile::writeTile (int dx, int dy, int lx, int ly)
  478. {
  479. if (_toYa)
  480. {
  481. Lock lock (*_toYa);
  482. _toYa->writeTile (dx, dy, lx, ly);
  483. }
  484. else
  485. {
  486. _outputFile->writeTile (dx, dy, lx, ly);
  487. }
  488. }
  489. void
  490. TiledRgbaOutputFile::writeTiles
  491. (int dxMin, int dxMax, int dyMin, int dyMax, int lx, int ly)
  492. {
  493. if (_toYa)
  494. {
  495. Lock lock (*_toYa);
  496. for (int dy = dyMin; dy <= dyMax; dy++)
  497. for (int dx = dxMin; dx <= dxMax; dx++)
  498. _toYa->writeTile (dx, dy, lx, ly);
  499. }
  500. else
  501. {
  502. _outputFile->writeTiles (dxMin, dxMax, dyMin, dyMax, lx, ly);
  503. }
  504. }
  505. void
  506. TiledRgbaOutputFile::writeTiles
  507. (int dxMin, int dxMax, int dyMin, int dyMax, int l)
  508. {
  509. writeTiles (dxMin, dxMax, dyMin, dyMax, l, l);
  510. }
  511. class TiledRgbaInputFile::FromYa: public Mutex
  512. {
  513. public:
  514. FromYa (TiledInputFile &inputFile);
  515. void setFrameBuffer (Rgba *base,
  516. size_t xStride,
  517. size_t yStride,
  518. const string &channelNamePrefix);
  519. void readTile (int dx, int dy, int lx, int ly);
  520. private:
  521. TiledInputFile & _inputFile;
  522. unsigned int _tileXSize;
  523. unsigned int _tileYSize;
  524. V3f _yw;
  525. Array2D <Rgba> _buf;
  526. Rgba * _fbBase;
  527. size_t _fbXStride;
  528. size_t _fbYStride;
  529. };
  530. TiledRgbaInputFile::FromYa::FromYa (TiledInputFile &inputFile)
  531. :
  532. _inputFile (inputFile)
  533. {
  534. const TileDescription &td = inputFile.header().tileDescription();
  535. _tileXSize = td.xSize;
  536. _tileYSize = td.ySize;
  537. _yw = ywFromHeader (_inputFile.header());
  538. _buf.resizeErase (_tileYSize, _tileXSize);
  539. _fbBase = 0;
  540. _fbXStride = 0;
  541. _fbYStride = 0;
  542. }
  543. void
  544. TiledRgbaInputFile::FromYa::setFrameBuffer (Rgba *base,
  545. size_t xStride,
  546. size_t yStride,
  547. const string &channelNamePrefix)
  548. {
  549. if (_fbBase == 0)
  550. {
  551. FrameBuffer fb;
  552. fb.insert (channelNamePrefix + "Y",
  553. Slice (HALF, // type
  554. (char *) &_buf[0][0].g, // base
  555. sizeof (Rgba), // xStride
  556. sizeof (Rgba) * _tileXSize, // yStride
  557. 1, 1, // sampling
  558. 0.0, // fillValue
  559. true, true)); // tileCoordinates
  560. fb.insert (channelNamePrefix + "A",
  561. Slice (HALF, // type
  562. (char *) &_buf[0][0].a, // base
  563. sizeof (Rgba), // xStride
  564. sizeof (Rgba) * _tileXSize, // yStride
  565. 1, 1, // sampling
  566. 1.0, // fillValue
  567. true, true)); // tileCoordinates
  568. _inputFile.setFrameBuffer (fb);
  569. }
  570. _fbBase = base;
  571. _fbXStride = xStride;
  572. _fbYStride = yStride;
  573. }
  574. void
  575. TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly)
  576. {
  577. if (_fbBase == 0)
  578. {
  579. THROW (Iex::ArgExc, "No frame buffer was specified as the "
  580. "pixel data destination for image file "
  581. "\"" << _inputFile.fileName() << "\".");
  582. }
  583. //
  584. // Read the tile requested by the caller into _buf.
  585. //
  586. _inputFile.readTile (dx, dy, lx, ly);
  587. //
  588. // Convert the luminance/alpha pixels to RGBA
  589. // and copy them into the caller's frame buffer.
  590. //
  591. Box2i dw = _inputFile.dataWindowForTile (dx, dy, lx, ly);
  592. int width = dw.max.x - dw.min.x + 1;
  593. for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1)
  594. {
  595. for (int x1 = 0; x1 < width; ++x1)
  596. {
  597. _buf[y1][x1].r = 0;
  598. _buf[y1][x1].b = 0;
  599. }
  600. YCAtoRGBA (_yw, width, _buf[y1], _buf[y1]);
  601. for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1)
  602. {
  603. _fbBase[x * _fbXStride + y * _fbYStride] = _buf[y1][x1];
  604. }
  605. }
  606. }
  607. TiledRgbaInputFile::TiledRgbaInputFile (const char name[], int numThreads):
  608. _inputFile (new TiledInputFile (name, numThreads)),
  609. _fromYa (0),
  610. _channelNamePrefix ("")
  611. {
  612. if (channels() & WRITE_Y)
  613. _fromYa = new FromYa (*_inputFile);
  614. }
  615. TiledRgbaInputFile::TiledRgbaInputFile (IStream &is, int numThreads):
  616. _inputFile (new TiledInputFile (is, numThreads)),
  617. _fromYa (0),
  618. _channelNamePrefix ("")
  619. {
  620. if (channels() & WRITE_Y)
  621. _fromYa = new FromYa (*_inputFile);
  622. }
  623. TiledRgbaInputFile::TiledRgbaInputFile (const char name[],
  624. const string &layerName,
  625. int numThreads)
  626. :
  627. _inputFile (new TiledInputFile (name, numThreads)),
  628. _fromYa (0),
  629. _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
  630. {
  631. if (channels() & WRITE_Y)
  632. _fromYa = new FromYa (*_inputFile);
  633. }
  634. TiledRgbaInputFile::TiledRgbaInputFile (IStream &is,
  635. const string &layerName,
  636. int numThreads)
  637. :
  638. _inputFile (new TiledInputFile (is, numThreads)),
  639. _fromYa (0),
  640. _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
  641. {
  642. if (channels() & WRITE_Y)
  643. _fromYa = new FromYa (*_inputFile);
  644. }
  645. TiledRgbaInputFile::~TiledRgbaInputFile ()
  646. {
  647. delete _inputFile;
  648. delete _fromYa;
  649. }
  650. void
  651. TiledRgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
  652. {
  653. if (_fromYa)
  654. {
  655. Lock lock (*_fromYa);
  656. _fromYa->setFrameBuffer (base, xStride, yStride, _channelNamePrefix);
  657. }
  658. else
  659. {
  660. size_t xs = xStride * sizeof (Rgba);
  661. size_t ys = yStride * sizeof (Rgba);
  662. FrameBuffer fb;
  663. fb.insert (_channelNamePrefix + "R",
  664. Slice (HALF,
  665. (char *) &base[0].r,
  666. xs, ys,
  667. 1, 1, // xSampling, ySampling
  668. 0.0)); // fillValue
  669. fb.insert (_channelNamePrefix + "G",
  670. Slice (HALF,
  671. (char *) &base[0].g,
  672. xs, ys,
  673. 1, 1, // xSampling, ySampling
  674. 0.0)); // fillValue
  675. fb.insert (_channelNamePrefix + "B",
  676. Slice (HALF,
  677. (char *) &base[0].b,
  678. xs, ys,
  679. 1, 1, // xSampling, ySampling
  680. 0.0)); // fillValue
  681. fb.insert (_channelNamePrefix + "A",
  682. Slice (HALF,
  683. (char *) &base[0].a,
  684. xs, ys,
  685. 1, 1, // xSampling, ySampling
  686. 1.0)); // fillValue
  687. _inputFile->setFrameBuffer (fb);
  688. }
  689. }
  690. void
  691. TiledRgbaInputFile::setLayerName (const std::string &layerName)
  692. {
  693. delete _fromYa;
  694. _fromYa = 0;
  695. _channelNamePrefix = prefixFromLayerName (layerName, _inputFile->header());
  696. if (channels() & WRITE_Y)
  697. _fromYa = new FromYa (*_inputFile);
  698. FrameBuffer fb;
  699. _inputFile->setFrameBuffer (fb);
  700. }
  701. const Header &
  702. TiledRgbaInputFile::header () const
  703. {
  704. return _inputFile->header();
  705. }
  706. const char *
  707. TiledRgbaInputFile::fileName () const
  708. {
  709. return _inputFile->fileName();
  710. }
  711. const FrameBuffer &
  712. TiledRgbaInputFile::frameBuffer () const
  713. {
  714. return _inputFile->frameBuffer();
  715. }
  716. const Imath::Box2i &
  717. TiledRgbaInputFile::displayWindow () const
  718. {
  719. return _inputFile->header().displayWindow();
  720. }
  721. const Imath::Box2i &
  722. TiledRgbaInputFile::dataWindow () const
  723. {
  724. return _inputFile->header().dataWindow();
  725. }
  726. float
  727. TiledRgbaInputFile::pixelAspectRatio () const
  728. {
  729. return _inputFile->header().pixelAspectRatio();
  730. }
  731. const Imath::V2f
  732. TiledRgbaInputFile::screenWindowCenter () const
  733. {
  734. return _inputFile->header().screenWindowCenter();
  735. }
  736. float
  737. TiledRgbaInputFile::screenWindowWidth () const
  738. {
  739. return _inputFile->header().screenWindowWidth();
  740. }
  741. LineOrder
  742. TiledRgbaInputFile::lineOrder () const
  743. {
  744. return _inputFile->header().lineOrder();
  745. }
  746. Compression
  747. TiledRgbaInputFile::compression () const
  748. {
  749. return _inputFile->header().compression();
  750. }
  751. RgbaChannels
  752. TiledRgbaInputFile::channels () const
  753. {
  754. return rgbaChannels (_inputFile->header().channels(), _channelNamePrefix);
  755. }
  756. int
  757. TiledRgbaInputFile::version () const
  758. {
  759. return _inputFile->version();
  760. }
  761. bool
  762. TiledRgbaInputFile::isComplete () const
  763. {
  764. return _inputFile->isComplete();
  765. }
  766. unsigned int
  767. TiledRgbaInputFile::tileXSize () const
  768. {
  769. return _inputFile->tileXSize();
  770. }
  771. unsigned int
  772. TiledRgbaInputFile::tileYSize () const
  773. {
  774. return _inputFile->tileYSize();
  775. }
  776. LevelMode
  777. TiledRgbaInputFile::levelMode () const
  778. {
  779. return _inputFile->levelMode();
  780. }
  781. LevelRoundingMode
  782. TiledRgbaInputFile::levelRoundingMode () const
  783. {
  784. return _inputFile->levelRoundingMode();
  785. }
  786. int
  787. TiledRgbaInputFile::numLevels () const
  788. {
  789. return _inputFile->numLevels();
  790. }
  791. int
  792. TiledRgbaInputFile::numXLevels () const
  793. {
  794. return _inputFile->numXLevels();
  795. }
  796. int
  797. TiledRgbaInputFile::numYLevels () const
  798. {
  799. return _inputFile->numYLevels();
  800. }
  801. bool
  802. TiledRgbaInputFile::isValidLevel (int lx, int ly) const
  803. {
  804. return _inputFile->isValidLevel (lx, ly);
  805. }
  806. int
  807. TiledRgbaInputFile::levelWidth (int lx) const
  808. {
  809. return _inputFile->levelWidth (lx);
  810. }
  811. int
  812. TiledRgbaInputFile::levelHeight (int ly) const
  813. {
  814. return _inputFile->levelHeight (ly);
  815. }
  816. int
  817. TiledRgbaInputFile::numXTiles (int lx) const
  818. {
  819. return _inputFile->numXTiles(lx);
  820. }
  821. int
  822. TiledRgbaInputFile::numYTiles (int ly) const
  823. {
  824. return _inputFile->numYTiles(ly);
  825. }
  826. Imath::Box2i
  827. TiledRgbaInputFile::dataWindowForLevel (int l) const
  828. {
  829. return _inputFile->dataWindowForLevel (l);
  830. }
  831. Imath::Box2i
  832. TiledRgbaInputFile::dataWindowForLevel (int lx, int ly) const
  833. {
  834. return _inputFile->dataWindowForLevel (lx, ly);
  835. }
  836. Imath::Box2i
  837. TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int l) const
  838. {
  839. return _inputFile->dataWindowForTile (dx, dy, l);
  840. }
  841. Imath::Box2i
  842. TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
  843. {
  844. return _inputFile->dataWindowForTile (dx, dy, lx, ly);
  845. }
  846. void
  847. TiledRgbaInputFile::readTile (int dx, int dy, int l)
  848. {
  849. if (_fromYa)
  850. {
  851. Lock lock (*_fromYa);
  852. _fromYa->readTile (dx, dy, l, l);
  853. }
  854. else
  855. {
  856. _inputFile->readTile (dx, dy, l);
  857. }
  858. }
  859. void
  860. TiledRgbaInputFile::readTile (int dx, int dy, int lx, int ly)
  861. {
  862. if (_fromYa)
  863. {
  864. Lock lock (*_fromYa);
  865. _fromYa->readTile (dx, dy, lx, ly);
  866. }
  867. else
  868. {
  869. _inputFile->readTile (dx, dy, lx, ly);
  870. }
  871. }
  872. void
  873. TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax,
  874. int lx, int ly)
  875. {
  876. if (_fromYa)
  877. {
  878. Lock lock (*_fromYa);
  879. for (int dy = dyMin; dy <= dyMax; dy++)
  880. for (int dx = dxMin; dx <= dxMax; dx++)
  881. _fromYa->readTile (dx, dy, lx, ly);
  882. }
  883. else
  884. {
  885. _inputFile->readTiles (dxMin, dxMax, dyMin, dyMax, lx, ly);
  886. }
  887. }
  888. void
  889. TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax,
  890. int l)
  891. {
  892. readTiles (dxMin, dxMax, dyMin, dyMax, l, l);
  893. }
  894. void
  895. TiledRgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
  896. {
  897. _outputFile->updatePreviewImage (newPixels);
  898. }
  899. void
  900. TiledRgbaOutputFile::breakTile (int dx, int dy, int lx, int ly,
  901. int offset, int length, char c)
  902. {
  903. _outputFile->breakTile (dx, dy, lx, ly, offset, length, c);
  904. }
  905. } // namespace Imf