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 #ifndef INCLUDED_IMF_TILED_RGBA_FILE_H 37 #define INCLUDED_IMF_TILED_RGBA_FILE_H 38 39 //----------------------------------------------------------------------------- 40 // 41 // Simplified RGBA image I/O for tiled files 42 // 43 // class TiledRgbaOutputFile 44 // class TiledRgbaInputFile 45 // 46 //----------------------------------------------------------------------------- 47 48 #include <ImfHeader.h> 49 #include <ImfFrameBuffer.h> 50 #include "ImathVec.h" 51 #include "ImathBox.h" 52 #include "half.h" 53 #include <ImfTileDescription.h> 54 #include <ImfRgba.h> 55 #include <ImfThreading.h> 56 #include <string> 57 58 namespace Imf { 59 60 class TiledOutputFile; 61 class TiledInputFile; 62 struct PreviewRgba; 63 64 65 // 66 // Tiled RGBA output file. 67 // 68 69 class TiledRgbaOutputFile 70 { 71 public: 72 73 //--------------------------------------------------- 74 // Constructor -- rgbaChannels, tileXSize, tileYSize, 75 // levelMode, and levelRoundingMode overwrite the 76 // channel list and tile description attribute in the 77 // header that is passed as an argument to the 78 // constructor. 79 //--------------------------------------------------- 80 81 TiledRgbaOutputFile (const char name[], 82 const Header &header, 83 RgbaChannels rgbaChannels, 84 int tileXSize, 85 int tileYSize, 86 LevelMode mode, 87 LevelRoundingMode rmode = ROUND_DOWN, 88 int numThreads = globalThreadCount ()); 89 90 91 //--------------------------------------------------- 92 // Constructor -- like the previous one, but the new 93 // TiledRgbaOutputFile is attached to a file that has 94 // already been opened by the caller. Destroying 95 // TiledRgbaOutputFileObjects constructed with this 96 // constructor does not automatically close the 97 // corresponding files. 98 //--------------------------------------------------- 99 100 TiledRgbaOutputFile (OStream &os, 101 const Header &header, 102 RgbaChannels rgbaChannels, 103 int tileXSize, 104 int tileYSize, 105 LevelMode mode, 106 LevelRoundingMode rmode = ROUND_DOWN, 107 int numThreads = globalThreadCount ()); 108 109 110 //------------------------------------------------------ 111 // Constructor -- header data are explicitly specified 112 // as function call arguments (an empty dataWindow means 113 // "same as displayWindow") 114 //------------------------------------------------------ 115 116 TiledRgbaOutputFile (const char name[], 117 int tileXSize, 118 int tileYSize, 119 LevelMode mode, 120 LevelRoundingMode rmode, 121 const Imath::Box2i &displayWindow, 122 const Imath::Box2i &dataWindow = Imath::Box2i(), 123 RgbaChannels rgbaChannels = WRITE_RGBA, 124 float pixelAspectRatio = 1, 125 const Imath::V2f screenWindowCenter = 126 Imath::V2f (0, 0), 127 float screenWindowWidth = 1, 128 LineOrder lineOrder = INCREASING_Y, 129 Compression compression = ZIP_COMPRESSION, 130 int numThreads = globalThreadCount ()); 131 132 133 //----------------------------------------------- 134 // Constructor -- like the previous one, but both 135 // the display window and the data window are 136 // Box2i (V2i (0, 0), V2i (width - 1, height -1)) 137 //----------------------------------------------- 138 139 TiledRgbaOutputFile (const char name[], 140 int width, 141 int height, 142 int tileXSize, 143 int tileYSize, 144 LevelMode mode, 145 LevelRoundingMode rmode = ROUND_DOWN, 146 RgbaChannels rgbaChannels = WRITE_RGBA, 147 float pixelAspectRatio = 1, 148 const Imath::V2f screenWindowCenter = 149 Imath::V2f (0, 0), 150 float screenWindowWidth = 1, 151 LineOrder lineOrder = INCREASING_Y, 152 Compression compression = ZIP_COMPRESSION, 153 int numThreads = globalThreadCount ()); 154 155 156 virtual ~TiledRgbaOutputFile (); 157 158 159 //------------------------------------------------ 160 // Define a frame buffer as the pixel data source: 161 // Pixel (x, y) is at address 162 // 163 // base + x * xStride + y * yStride 164 // 165 //------------------------------------------------ 166 167 void setFrameBuffer (const Rgba *base, 168 size_t xStride, 169 size_t yStride); 170 171 //-------------------------- 172 // Access to the file header 173 //-------------------------- 174 175 const Header & header () const; 176 const FrameBuffer & frameBuffer () const; 177 const Imath::Box2i & displayWindow () const; 178 const Imath::Box2i & dataWindow () const; 179 float pixelAspectRatio () const; 180 const Imath::V2f screenWindowCenter () const; 181 float screenWindowWidth () const; 182 LineOrder lineOrder () const; 183 Compression compression () const; 184 RgbaChannels channels () const; 185 186 187 //---------------------------------------------------- 188 // Utility functions (same as in Imf::TiledOutputFile) 189 //---------------------------------------------------- 190 191 unsigned int tileXSize () const; 192 unsigned int tileYSize () const; 193 LevelMode levelMode () const; 194 LevelRoundingMode levelRoundingMode () const; 195 196 int numLevels () const; 197 int numXLevels () const; 198 int numYLevels () const; 199 bool isValidLevel (int lx, int ly) const; 200 201 int levelWidth (int lx) const; 202 int levelHeight (int ly) const; 203 204 int numXTiles (int lx = 0) const; 205 int numYTiles (int ly = 0) const; 206 207 Imath::Box2i dataWindowForLevel (int l = 0) const; 208 Imath::Box2i dataWindowForLevel (int lx, int ly) const; 209 210 Imath::Box2i dataWindowForTile (int dx, int dy, 211 int l = 0) const; 212 213 Imath::Box2i dataWindowForTile (int dx, int dy, 214 int lx, int ly) const; 215 216 //------------------------------------------------------------------ 217 // Write pixel data: 218 // 219 // writeTile(dx, dy, lx, ly) writes the tile with tile 220 // coordinates (dx, dy), and level number (lx, ly) to 221 // the file. 222 // 223 // dx must lie in the interval [0, numXTiles(lx)-1] 224 // dy must lie in the interval [0, numYTiles(ly)-1] 225 // 226 // lx must lie in the interval [0, numXLevels()-1] 227 // ly must lie in the inverval [0, numYLevels()-1] 228 // 229 // writeTile(dx, dy, level) is a convenience function 230 // used for ONE_LEVEL and MIPMAP_LEVEL files. It calls 231 // writeTile(dx, dy, level, level). 232 // 233 // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow 234 // writing multiple tiles at once. If multi-threading is used 235 // multiple tiles are written concurrently. 236 // 237 // Pixels that are outside the pixel coordinate range for the tile's 238 // level, are never accessed by writeTile(). 239 // 240 // Each tile in the file must be written exactly once. 241 // 242 //------------------------------------------------------------------ 243 244 void writeTile (int dx, int dy, int l = 0); 245 void writeTile (int dx, int dy, int lx, int ly); 246 247 void writeTiles (int dxMin, int dxMax, int dyMin, int dyMax, 248 int lx, int ly); 249 250 void writeTiles (int dxMin, int dxMax, int dyMin, int dyMax, 251 int l = 0); 252 253 254 // ------------------------------------------------------------------------- 255 // Update the preview image (see Imf::TiledOutputFile::updatePreviewImage()) 256 // ------------------------------------------------------------------------- 257 258 void updatePreviewImage (const PreviewRgba[]); 259 260 261 //------------------------------------------------ 262 // Break a tile -- for testing and debugging only 263 // (see Imf::TiledOutputFile::breakTile()) 264 // 265 // Warning: Calling this function usually results 266 // in a broken image file. The file or parts of 267 // it may not be readable, or the file may contain 268 // bad data. 269 // 270 //------------------------------------------------ 271 272 void breakTile (int dx, int dy, 273 int lx, int ly, 274 int offset, 275 int length, 276 char c); 277 private: 278 279 // 280 // Copy constructor and assignment are not implemented 281 // 282 283 TiledRgbaOutputFile (const TiledRgbaOutputFile &); 284 TiledRgbaOutputFile & operator = (const TiledRgbaOutputFile &); 285 286 class ToYa; 287 288 TiledOutputFile * _outputFile; 289 ToYa * _toYa; 290 }; 291 292 293 294 // 295 // Tiled RGBA input file 296 // 297 298 class TiledRgbaInputFile 299 { 300 public: 301 302 //-------------------------------------------------------- 303 // Constructor -- opens the file with the specified name. 304 // Destroying TiledRgbaInputFile objects constructed with 305 // this constructor automatically closes the corresponding 306 // files. 307 //-------------------------------------------------------- 308 309 TiledRgbaInputFile (const char name[], 310 int numThreads = globalThreadCount ()); 311 312 313 //------------------------------------------------------- 314 // Constructor -- attaches the new TiledRgbaInputFile 315 // object to a file that has already been opened by the 316 // caller. 317 // Destroying TiledRgbaInputFile objects constructed with 318 // this constructor does not automatically close the 319 // corresponding files. 320 //------------------------------------------------------- 321 322 TiledRgbaInputFile (IStream &is, int numThreads = globalThreadCount ()); 323 324 325 //------------------------------------------------------------ 326 // Constructors -- the same as the previous two, but the names 327 // of the red, green, blue, alpha, and luminance channels are 328 // expected to be layerName.R, layerName.G, etc. 329 //------------------------------------------------------------ 330 331 TiledRgbaInputFile (const char name[], 332 const std::string &layerName, 333 int numThreads = globalThreadCount()); 334 335 TiledRgbaInputFile (IStream &is, 336 const std::string &layerName, 337 int numThreads = globalThreadCount()); 338 339 //----------- 340 // Destructor 341 //----------- 342 343 virtual ~TiledRgbaInputFile (); 344 345 346 //----------------------------------------------------- 347 // Define a frame buffer as the pixel data destination: 348 // Pixel (x, y) is at address 349 // 350 // base + x * xStride + y * yStride 351 // 352 //----------------------------------------------------- 353 354 void setFrameBuffer (Rgba *base, 355 size_t xStride, 356 size_t yStride); 357 358 //------------------------------------------------------------------- 359 // Switch to a different layer -- subsequent calls to readTile() 360 // and readTiles() will read channels layerName.R, layerName.G, etc. 361 // After each call to setLayerName(), setFrameBuffer() must be called 362 // at least once before the next call to readTile() or readTiles(). 363 //------------------------------------------------------------------- 364 365 void setLayerName (const std::string &layerName); 366 367 368 //-------------------------- 369 // Access to the file header 370 //-------------------------- 371 372 const Header & header () const; 373 const FrameBuffer & frameBuffer () const; 374 const Imath::Box2i & displayWindow () const; 375 const Imath::Box2i & dataWindow () const; 376 float pixelAspectRatio () const; 377 const Imath::V2f screenWindowCenter () const; 378 float screenWindowWidth () const; 379 LineOrder lineOrder () const; 380 Compression compression () const; 381 RgbaChannels channels () const; 382 const char * fileName () const; 383 bool isComplete () const; 384 385 //---------------------------------- 386 // Access to the file format version 387 //---------------------------------- 388 389 int version () const; 390 391 392 //--------------------------------------------------- 393 // Utility functions (same as in Imf::TiledInputFile) 394 //--------------------------------------------------- 395 396 unsigned int tileXSize () const; 397 unsigned int tileYSize () const; 398 LevelMode levelMode () const; 399 LevelRoundingMode levelRoundingMode () const; 400 401 int numLevels () const; 402 int numXLevels () const; 403 int numYLevels () const; 404 bool isValidLevel (int lx, int ly) const; 405 406 int levelWidth (int lx) const; 407 int levelHeight (int ly) const; 408 409 int numXTiles (int lx = 0) const; 410 int numYTiles (int ly = 0) const; 411 412 Imath::Box2i dataWindowForLevel (int l = 0) const; 413 Imath::Box2i dataWindowForLevel (int lx, int ly) const; 414 415 Imath::Box2i dataWindowForTile (int dx, int dy, 416 int l = 0) const; 417 418 Imath::Box2i dataWindowForTile (int dx, int dy, 419 int lx, int ly) const; 420 421 422 //---------------------------------------------------------------- 423 // Read pixel data: 424 // 425 // readTile(dx, dy, lx, ly) reads the tile with tile 426 // coordinates (dx, dy), and level number (lx, ly), 427 // and stores it in the current frame buffer. 428 // 429 // dx must lie in the interval [0, numXTiles(lx)-1] 430 // dy must lie in the interval [0, numYTiles(ly)-1] 431 // 432 // lx must lie in the interval [0, numXLevels()-1] 433 // ly must lie in the inverval [0, numYLevels()-1] 434 // 435 // readTile(dx, dy, level) is a convenience function used 436 // for ONE_LEVEL and MIPMAP_LEVELS files. It calls 437 // readTile(dx, dy, level, level). 438 // 439 // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow 440 // reading multiple tiles at once. If multi-threading is used 441 // multiple tiles are read concurrently. 442 // 443 // Pixels that are outside the pixel coordinate range for the 444 // tile's level, are never accessed by readTile(). 445 // 446 // Attempting to access a tile that is not present in the file 447 // throws an InputExc exception. 448 // 449 //---------------------------------------------------------------- 450 451 void readTile (int dx, int dy, int l = 0); 452 void readTile (int dx, int dy, int lx, int ly); 453 454 void readTiles (int dxMin, int dxMax, 455 int dyMin, int dyMax, int lx, int ly); 456 457 void readTiles (int dxMin, int dxMax, 458 int dyMin, int dyMax, int l = 0); 459 460 private: 461 462 // 463 // Copy constructor and assignment are not implemented 464 // 465 466 TiledRgbaInputFile (const TiledRgbaInputFile &); 467 TiledRgbaInputFile & operator = (const TiledRgbaInputFile &); 468 469 class FromYa; 470 471 TiledInputFile * _inputFile; 472 FromYa * _fromYa; 473 std::string _channelNamePrefix; 474 }; 475 476 477 } // namespace Imf 478 479 #endif 480