PBRT
|
00001 00002 // 00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 00036 #ifndef INCLUDED_IMF_TILED_RGBA_FILE_H 00037 #define INCLUDED_IMF_TILED_RGBA_FILE_H 00038 00039 //----------------------------------------------------------------------------- 00040 // 00041 // Simplified RGBA image I/O for tiled files 00042 // 00043 // class TiledRgbaOutputFile 00044 // class TiledRgbaInputFile 00045 // 00046 //----------------------------------------------------------------------------- 00047 00048 #include <ImfHeader.h> 00049 #include <ImfFrameBuffer.h> 00050 #include "ImathVec.h" 00051 #include "ImathBox.h" 00052 #include "half.h" 00053 #include <ImfTileDescription.h> 00054 #include <ImfRgba.h> 00055 #include <ImfThreading.h> 00056 #include <string> 00057 00058 namespace Imf { 00059 00060 class TiledOutputFile; 00061 class TiledInputFile; 00062 struct PreviewRgba; 00063 00064 00065 // 00066 // Tiled RGBA output file. 00067 // 00068 00069 class TiledRgbaOutputFile 00070 { 00071 public: 00072 00073 //--------------------------------------------------- 00074 // Constructor -- rgbaChannels, tileXSize, tileYSize, 00075 // levelMode, and levelRoundingMode overwrite the 00076 // channel list and tile description attribute in the 00077 // header that is passed as an argument to the 00078 // constructor. 00079 //--------------------------------------------------- 00080 00081 TiledRgbaOutputFile (const char name[], 00082 const Header &header, 00083 RgbaChannels rgbaChannels, 00084 int tileXSize, 00085 int tileYSize, 00086 LevelMode mode, 00087 LevelRoundingMode rmode = ROUND_DOWN, 00088 int numThreads = globalThreadCount ()); 00089 00090 00091 //--------------------------------------------------- 00092 // Constructor -- like the previous one, but the new 00093 // TiledRgbaOutputFile is attached to a file that has 00094 // already been opened by the caller. Destroying 00095 // TiledRgbaOutputFileObjects constructed with this 00096 // constructor does not automatically close the 00097 // corresponding files. 00098 //--------------------------------------------------- 00099 00100 TiledRgbaOutputFile (OStream &os, 00101 const Header &header, 00102 RgbaChannels rgbaChannels, 00103 int tileXSize, 00104 int tileYSize, 00105 LevelMode mode, 00106 LevelRoundingMode rmode = ROUND_DOWN, 00107 int numThreads = globalThreadCount ()); 00108 00109 00110 //------------------------------------------------------ 00111 // Constructor -- header data are explicitly specified 00112 // as function call arguments (an empty dataWindow means 00113 // "same as displayWindow") 00114 //------------------------------------------------------ 00115 00116 TiledRgbaOutputFile (const char name[], 00117 int tileXSize, 00118 int tileYSize, 00119 LevelMode mode, 00120 LevelRoundingMode rmode, 00121 const Imath::Box2i &displayWindow, 00122 const Imath::Box2i &dataWindow = Imath::Box2i(), 00123 RgbaChannels rgbaChannels = WRITE_RGBA, 00124 float pixelAspectRatio = 1, 00125 const Imath::V2f screenWindowCenter = 00126 Imath::V2f (0, 0), 00127 float screenWindowWidth = 1, 00128 LineOrder lineOrder = INCREASING_Y, 00129 Compression compression = ZIP_COMPRESSION, 00130 int numThreads = globalThreadCount ()); 00131 00132 00133 //----------------------------------------------- 00134 // Constructor -- like the previous one, but both 00135 // the display window and the data window are 00136 // Box2i (V2i (0, 0), V2i (width - 1, height -1)) 00137 //----------------------------------------------- 00138 00139 TiledRgbaOutputFile (const char name[], 00140 int width, 00141 int height, 00142 int tileXSize, 00143 int tileYSize, 00144 LevelMode mode, 00145 LevelRoundingMode rmode = ROUND_DOWN, 00146 RgbaChannels rgbaChannels = WRITE_RGBA, 00147 float pixelAspectRatio = 1, 00148 const Imath::V2f screenWindowCenter = 00149 Imath::V2f (0, 0), 00150 float screenWindowWidth = 1, 00151 LineOrder lineOrder = INCREASING_Y, 00152 Compression compression = ZIP_COMPRESSION, 00153 int numThreads = globalThreadCount ()); 00154 00155 00156 virtual ~TiledRgbaOutputFile (); 00157 00158 00159 //------------------------------------------------ 00160 // Define a frame buffer as the pixel data source: 00161 // Pixel (x, y) is at address 00162 // 00163 // base + x * xStride + y * yStride 00164 // 00165 //------------------------------------------------ 00166 00167 void setFrameBuffer (const Rgba *base, 00168 size_t xStride, 00169 size_t yStride); 00170 00171 //-------------------------- 00172 // Access to the file header 00173 //-------------------------- 00174 00175 const Header & header () const; 00176 const FrameBuffer & frameBuffer () const; 00177 const Imath::Box2i & displayWindow () const; 00178 const Imath::Box2i & dataWindow () const; 00179 float pixelAspectRatio () const; 00180 const Imath::V2f screenWindowCenter () const; 00181 float screenWindowWidth () const; 00182 LineOrder lineOrder () const; 00183 Compression compression () const; 00184 RgbaChannels channels () const; 00185 00186 00187 //---------------------------------------------------- 00188 // Utility functions (same as in Imf::TiledOutputFile) 00189 //---------------------------------------------------- 00190 00191 unsigned int tileXSize () const; 00192 unsigned int tileYSize () const; 00193 LevelMode levelMode () const; 00194 LevelRoundingMode levelRoundingMode () const; 00195 00196 int numLevels () const; 00197 int numXLevels () const; 00198 int numYLevels () const; 00199 bool isValidLevel (int lx, int ly) const; 00200 00201 int levelWidth (int lx) const; 00202 int levelHeight (int ly) const; 00203 00204 int numXTiles (int lx = 0) const; 00205 int numYTiles (int ly = 0) const; 00206 00207 Imath::Box2i dataWindowForLevel (int l = 0) const; 00208 Imath::Box2i dataWindowForLevel (int lx, int ly) const; 00209 00210 Imath::Box2i dataWindowForTile (int dx, int dy, 00211 int l = 0) const; 00212 00213 Imath::Box2i dataWindowForTile (int dx, int dy, 00214 int lx, int ly) const; 00215 00216 //------------------------------------------------------------------ 00217 // Write pixel data: 00218 // 00219 // writeTile(dx, dy, lx, ly) writes the tile with tile 00220 // coordinates (dx, dy), and level number (lx, ly) to 00221 // the file. 00222 // 00223 // dx must lie in the interval [0, numXTiles(lx)-1] 00224 // dy must lie in the interval [0, numYTiles(ly)-1] 00225 // 00226 // lx must lie in the interval [0, numXLevels()-1] 00227 // ly must lie in the inverval [0, numYLevels()-1] 00228 // 00229 // writeTile(dx, dy, level) is a convenience function 00230 // used for ONE_LEVEL and MIPMAP_LEVEL files. It calls 00231 // writeTile(dx, dy, level, level). 00232 // 00233 // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow 00234 // writing multiple tiles at once. If multi-threading is used 00235 // multiple tiles are written concurrently. 00236 // 00237 // Pixels that are outside the pixel coordinate range for the tile's 00238 // level, are never accessed by writeTile(). 00239 // 00240 // Each tile in the file must be written exactly once. 00241 // 00242 //------------------------------------------------------------------ 00243 00244 void writeTile (int dx, int dy, int l = 0); 00245 void writeTile (int dx, int dy, int lx, int ly); 00246 00247 void writeTiles (int dxMin, int dxMax, int dyMin, int dyMax, 00248 int lx, int ly); 00249 00250 void writeTiles (int dxMin, int dxMax, int dyMin, int dyMax, 00251 int l = 0); 00252 00253 00254 // ------------------------------------------------------------------------- 00255 // Update the preview image (see Imf::TiledOutputFile::updatePreviewImage()) 00256 // ------------------------------------------------------------------------- 00257 00258 void updatePreviewImage (const PreviewRgba[]); 00259 00260 00261 //------------------------------------------------ 00262 // Break a tile -- for testing and debugging only 00263 // (see Imf::TiledOutputFile::breakTile()) 00264 // 00265 // Warning: Calling this function usually results 00266 // in a broken image file. The file or parts of 00267 // it may not be readable, or the file may contain 00268 // bad data. 00269 // 00270 //------------------------------------------------ 00271 00272 void breakTile (int dx, int dy, 00273 int lx, int ly, 00274 int offset, 00275 int length, 00276 char c); 00277 private: 00278 00279 // 00280 // Copy constructor and assignment are not implemented 00281 // 00282 00283 TiledRgbaOutputFile (const TiledRgbaOutputFile &); 00284 TiledRgbaOutputFile & operator = (const TiledRgbaOutputFile &); 00285 00286 class ToYa; 00287 00288 TiledOutputFile * _outputFile; 00289 ToYa * _toYa; 00290 }; 00291 00292 00293 00294 // 00295 // Tiled RGBA input file 00296 // 00297 00298 class TiledRgbaInputFile 00299 { 00300 public: 00301 00302 //-------------------------------------------------------- 00303 // Constructor -- opens the file with the specified name. 00304 // Destroying TiledRgbaInputFile objects constructed with 00305 // this constructor automatically closes the corresponding 00306 // files. 00307 //-------------------------------------------------------- 00308 00309 TiledRgbaInputFile (const char name[], 00310 int numThreads = globalThreadCount ()); 00311 00312 00313 //------------------------------------------------------- 00314 // Constructor -- attaches the new TiledRgbaInputFile 00315 // object to a file that has already been opened by the 00316 // caller. 00317 // Destroying TiledRgbaInputFile objects constructed with 00318 // this constructor does not automatically close the 00319 // corresponding files. 00320 //------------------------------------------------------- 00321 00322 TiledRgbaInputFile (IStream &is, int numThreads = globalThreadCount ()); 00323 00324 00325 //------------------------------------------------------------ 00326 // Constructors -- the same as the previous two, but the names 00327 // of the red, green, blue, alpha, and luminance channels are 00328 // expected to be layerName.R, layerName.G, etc. 00329 //------------------------------------------------------------ 00330 00331 TiledRgbaInputFile (const char name[], 00332 const std::string &layerName, 00333 int numThreads = globalThreadCount()); 00334 00335 TiledRgbaInputFile (IStream &is, 00336 const std::string &layerName, 00337 int numThreads = globalThreadCount()); 00338 00339 //----------- 00340 // Destructor 00341 //----------- 00342 00343 virtual ~TiledRgbaInputFile (); 00344 00345 00346 //----------------------------------------------------- 00347 // Define a frame buffer as the pixel data destination: 00348 // Pixel (x, y) is at address 00349 // 00350 // base + x * xStride + y * yStride 00351 // 00352 //----------------------------------------------------- 00353 00354 void setFrameBuffer (Rgba *base, 00355 size_t xStride, 00356 size_t yStride); 00357 00358 //------------------------------------------------------------------- 00359 // Switch to a different layer -- subsequent calls to readTile() 00360 // and readTiles() will read channels layerName.R, layerName.G, etc. 00361 // After each call to setLayerName(), setFrameBuffer() must be called 00362 // at least once before the next call to readTile() or readTiles(). 00363 //------------------------------------------------------------------- 00364 00365 void setLayerName (const std::string &layerName); 00366 00367 00368 //-------------------------- 00369 // Access to the file header 00370 //-------------------------- 00371 00372 const Header & header () const; 00373 const FrameBuffer & frameBuffer () const; 00374 const Imath::Box2i & displayWindow () const; 00375 const Imath::Box2i & dataWindow () const; 00376 float pixelAspectRatio () const; 00377 const Imath::V2f screenWindowCenter () const; 00378 float screenWindowWidth () const; 00379 LineOrder lineOrder () const; 00380 Compression compression () const; 00381 RgbaChannels channels () const; 00382 const char * fileName () const; 00383 bool isComplete () const; 00384 00385 //---------------------------------- 00386 // Access to the file format version 00387 //---------------------------------- 00388 00389 int version () const; 00390 00391 00392 //--------------------------------------------------- 00393 // Utility functions (same as in Imf::TiledInputFile) 00394 //--------------------------------------------------- 00395 00396 unsigned int tileXSize () const; 00397 unsigned int tileYSize () const; 00398 LevelMode levelMode () const; 00399 LevelRoundingMode levelRoundingMode () const; 00400 00401 int numLevels () const; 00402 int numXLevels () const; 00403 int numYLevels () const; 00404 bool isValidLevel (int lx, int ly) const; 00405 00406 int levelWidth (int lx) const; 00407 int levelHeight (int ly) const; 00408 00409 int numXTiles (int lx = 0) const; 00410 int numYTiles (int ly = 0) const; 00411 00412 Imath::Box2i dataWindowForLevel (int l = 0) const; 00413 Imath::Box2i dataWindowForLevel (int lx, int ly) const; 00414 00415 Imath::Box2i dataWindowForTile (int dx, int dy, 00416 int l = 0) const; 00417 00418 Imath::Box2i dataWindowForTile (int dx, int dy, 00419 int lx, int ly) const; 00420 00421 00422 //---------------------------------------------------------------- 00423 // Read pixel data: 00424 // 00425 // readTile(dx, dy, lx, ly) reads the tile with tile 00426 // coordinates (dx, dy), and level number (lx, ly), 00427 // and stores it in the current frame buffer. 00428 // 00429 // dx must lie in the interval [0, numXTiles(lx)-1] 00430 // dy must lie in the interval [0, numYTiles(ly)-1] 00431 // 00432 // lx must lie in the interval [0, numXLevels()-1] 00433 // ly must lie in the inverval [0, numYLevels()-1] 00434 // 00435 // readTile(dx, dy, level) is a convenience function used 00436 // for ONE_LEVEL and MIPMAP_LEVELS files. It calls 00437 // readTile(dx, dy, level, level). 00438 // 00439 // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow 00440 // reading multiple tiles at once. If multi-threading is used 00441 // multiple tiles are read concurrently. 00442 // 00443 // Pixels that are outside the pixel coordinate range for the 00444 // tile's level, are never accessed by readTile(). 00445 // 00446 // Attempting to access a tile that is not present in the file 00447 // throws an InputExc exception. 00448 // 00449 //---------------------------------------------------------------- 00450 00451 void readTile (int dx, int dy, int l = 0); 00452 void readTile (int dx, int dy, int lx, int ly); 00453 00454 void readTiles (int dxMin, int dxMax, 00455 int dyMin, int dyMax, int lx, int ly); 00456 00457 void readTiles (int dxMin, int dxMax, 00458 int dyMin, int dyMax, int l = 0); 00459 00460 private: 00461 00462 // 00463 // Copy constructor and assignment are not implemented 00464 // 00465 00466 TiledRgbaInputFile (const TiledRgbaInputFile &); 00467 TiledRgbaInputFile & operator = (const TiledRgbaInputFile &); 00468 00469 class FromYa; 00470 00471 TiledInputFile * _inputFile; 00472 FromYa * _fromYa; 00473 std::string _channelNamePrefix; 00474 }; 00475 00476 00477 } // namespace Imf 00478 00479 #endif