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