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// 38// Utility program to print an image file's header 39// 40//----------------------------------------------------------------------------- 41 42#include "OpenEXRConfig.h" 43#include <ImfInputFile.h> 44#include <ImfBoxAttribute.h> 45#include <ImfChannelListAttribute.h> 46#include <ImfChromaticitiesAttribute.h> 47#include <ImfCompressionAttribute.h> 48#include <ImfDoubleAttribute.h> 49#include <ImfEnvmapAttribute.h> 50#include <ImfFloatAttribute.h> 51#include <ImfIntAttribute.h> 52#include <ImfKeyCodeAttribute.h> 53#include <ImfLineOrderAttribute.h> 54#include <ImfMatrixAttribute.h> 55#include <ImfPreviewImageAttribute.h> 56#include <ImfRationalAttribute.h> 57#include <ImfStringAttribute.h> 58#include <ImfTileDescriptionAttribute.h> 59#include <ImfTimeCodeAttribute.h> 60#include <ImfVecAttribute.h> 61#include <ImfVersion.h> 62#include <iostream> 63#include <iomanip> 64 65using namespace Imf; 66using namespace std; 67 68 69void 70printCompression (Compression c) 71{ 72 switch (c) 73 { 74 case NO_COMPRESSION: 75 cout << "none"; 76 break; 77 78 case RLE_COMPRESSION: 79 cout << "run-length encoding"; 80 break; 81 82 case ZIPS_COMPRESSION: 83 cout << "zip, individual scanlines"; 84 break; 85 86 case ZIP_COMPRESSION: 87 cout << "zip, multi-scanline blocks"; 88 break; 89 90 case PIZ_COMPRESSION: 91 cout << "piz"; 92 break; 93 94 case PXR24_COMPRESSION: 95 cout << "pxr24"; 96 break; 97 98 case B44_COMPRESSION: 99 cout << "b44"; 100 break; 101 102 case B44A_COMPRESSION: 103 cout << "b44a"; 104 break; 105 106 default: 107 cout << int (c); 108 break; 109 } 110} 111 112 113void 114printLineOrder (LineOrder lo) 115{ 116 switch (lo) 117 { 118 case INCREASING_Y: 119 cout << "increasing y"; 120 break; 121 122 case DECREASING_Y: 123 cout << "decreasing y"; 124 break; 125 126 case RANDOM_Y: 127 cout << "random y"; 128 break; 129 130 default: 131 cout << int (lo); 132 break; 133 }; 134} 135 136 137void 138printPixelType (PixelType pt) 139{ 140 switch (pt) 141 { 142 case UINT: 143 cout << "32-bit unsigned integer"; 144 break; 145 146 case HALF: 147 cout << "16-bit floating-point"; 148 break; 149 150 case FLOAT: 151 cout << "32-bit floating-point"; 152 break; 153 154 default: 155 cout << "type " << int (pt); 156 break; 157 } 158} 159 160 161void 162printLevelMode (LevelMode lm) 163{ 164 switch (lm) 165 { 166 case ONE_LEVEL: 167 cout << "single level"; 168 break; 169 170 case MIPMAP_LEVELS: 171 cout << "mip-map"; 172 break; 173 174 case RIPMAP_LEVELS: 175 cout << "rip-map"; 176 break; 177 178 default: 179 cout << "level mode " << int (lm); 180 break; 181 } 182} 183 184 185void 186printLevelRoundingMode (LevelRoundingMode lm) 187{ 188 switch (lm) 189 { 190 case ROUND_DOWN: 191 cout << "down"; 192 break; 193 194 case ROUND_UP: 195 cout << "up"; 196 break; 197 198 default: 199 cout << "mode " << int (lm); 200 break; 201 } 202} 203 204 205void 206printTimeCode (TimeCode tc) 207{ 208 cout << " " 209 "time " << 210 setfill ('0') << 211#ifndef HAVE_COMPLETE_IOMANIP 212 setw (2) << tc.hours() << ":" << 213 setw (2) << tc.minutes() << ":" << 214 setw (2) << tc.seconds() << ":" << 215 setw (2) << tc.frame() << "\n" << 216#else 217 setw (2) << right << tc.hours() << ":" << 218 setw (2) << right << tc.minutes() << ":" << 219 setw (2) << right << tc.seconds() << ":" << 220 setw (2) << right << tc.frame() << "\n" << 221#endif 222 setfill (' ') << 223 " " 224 "drop frame " << tc.dropFrame() << ", " 225 "color frame " << tc.colorFrame() << ", " 226 "field/phase " << tc.fieldPhase() << "\n" 227 " " 228 "bgf0 " << tc.bgf0() << ", " 229 "bgf1 " << tc.bgf1() << ", " 230 "bgf2 " << tc.bgf2() << "\n" 231 " " 232 "user data 0x" << hex << tc.userData() << dec; 233} 234 235 236void 237printEnvmap (Envmap e) 238{ 239 switch (e) 240 { 241 case ENVMAP_LATLONG: 242 cout << "latitude-longitude map"; 243 break; 244 245 case ENVMAP_CUBE: 246 cout << "cube-face map"; 247 break; 248 249 default: 250 cout << "map type " << int (e); 251 break; 252 } 253} 254 255 256void 257printChannelList (const ChannelList &cl) 258{ 259 for (ChannelList::ConstIterator i = cl.begin(); i != cl.end(); ++i) 260 { 261 cout << "\n " << i.name() << ", "; 262 263 printPixelType (i.channel().type); 264 265 cout << ", sampling " << 266 i.channel().xSampling << " " << 267 i.channel().ySampling; 268 269 if (i.channel().pLinear) 270 cout << ", plinear"; 271 } 272} 273 274 275void 276printInfo (const char fileName[]) 277{ 278 InputFile in (fileName); 279 const Header &h = in.header(); 280 281 cout << "\n" << fileName << 282 (in.isComplete()? "": " (incomplete file)") << 283 ":\n\n"; 284 285 cout << "file format version: " << 286 getVersion (in.version()) << ", " 287 "flags 0x" << 288 setbase (16) << getFlags (in.version()) << setbase (10) << "\n"; 289 290 for (Header::ConstIterator i = h.begin(); i != h.end(); ++i) 291 { 292 const Attribute *a = &i.attribute(); 293 cout << i.name() << " (type " << a->typeName() << ")"; 294 295 if (const Box2iAttribute *ta = 296 dynamic_cast <const Box2iAttribute *> (a)) 297 { 298 cout << ": " << ta->value().min << " - " << ta->value().max; 299 } 300 else if (const Box2fAttribute *ta = 301 dynamic_cast <const Box2fAttribute *> (a)) 302 { 303 cout << ": " << ta->value().min << " - " << ta->value().max; 304 } 305 else if (const ChannelListAttribute *ta = 306 dynamic_cast <const ChannelListAttribute *> (a)) 307 { 308 cout << ":"; 309 printChannelList (ta->value()); 310 } 311 else if (const ChromaticitiesAttribute *ta = 312 dynamic_cast <const ChromaticitiesAttribute *> (a)) 313 { 314 cout << ":\n" 315 " red " << ta->value().red << "\n" 316 " green " << ta->value().green << "\n" 317 " blue " << ta->value().blue << "\n" 318 " white " << ta->value().white; 319 } 320 else if (const CompressionAttribute *ta = 321 dynamic_cast <const CompressionAttribute *> (a)) 322 { 323 cout << ": "; 324 printCompression (ta->value()); 325 } 326 else if (const DoubleAttribute *ta = 327 dynamic_cast <const DoubleAttribute *> (a)) 328 { 329 cout << ": " << ta->value(); 330 } 331 else if (const EnvmapAttribute *ta = 332 dynamic_cast <const EnvmapAttribute *> (a)) 333 { 334 cout << ": "; 335 printEnvmap (ta->value()); 336 } 337 else if (const FloatAttribute *ta = 338 dynamic_cast <const FloatAttribute *> (a)) 339 { 340 cout << ": " << ta->value(); 341 } 342 else if (const IntAttribute *ta = 343 dynamic_cast <const IntAttribute *> (a)) 344 { 345 cout << ": " << ta->value(); 346 } 347 else if (const KeyCodeAttribute *ta = 348 dynamic_cast <const KeyCodeAttribute *> (a)) 349 { 350 cout << ":\n" 351 " film manufacturer code " << 352 ta->value().filmMfcCode() << "\n" 353 " film type code " << 354 ta->value().filmType() << "\n" 355 " prefix " << 356 ta->value().prefix() << "\n" 357 " count " << 358 ta->value().count() << "\n" 359 " perf offset " << 360 ta->value().perfOffset() << "\n" 361 " perfs per frame " << 362 ta->value().perfsPerFrame() << "\n" 363 " perfs per count " << 364 ta->value().perfsPerCount(); 365 } 366 else if (const LineOrderAttribute *ta = 367 dynamic_cast <const LineOrderAttribute *> (a)) 368 { 369 cout << ": "; 370 printLineOrder (ta->value()); 371 } 372 else if (const M33fAttribute *ta = 373 dynamic_cast <const M33fAttribute *> (a)) 374 { 375 cout << ":\n" 376 " (" << 377 ta->value()[0][0] << " " << 378 ta->value()[0][1] << " " << 379 ta->value()[0][2] << "\n " << 380 ta->value()[1][0] << " " << 381 ta->value()[1][1] << " " << 382 ta->value()[1][2] << "\n " << 383 ta->value()[2][0] << " " << 384 ta->value()[2][1] << " " << 385 ta->value()[2][2] << ")"; 386 } 387 else if (const M44fAttribute *ta = 388 dynamic_cast <const M44fAttribute *> (a)) 389 { 390 cout << ":\n" 391 " (" << 392 ta->value()[0][0] << " " << 393 ta->value()[0][1] << " " << 394 ta->value()[0][2] << " " << 395 ta->value()[0][3] << "\n " << 396 ta->value()[1][0] << " " << 397 ta->value()[1][1] << " " << 398 ta->value()[1][2] << " " << 399 ta->value()[1][3] << "\n " << 400 ta->value()[2][0] << " " << 401 ta->value()[2][1] << " " << 402 ta->value()[2][2] << " " << 403 ta->value()[2][3] << "\n " << 404 ta->value()[3][0] << " " << 405 ta->value()[3][1] << " " << 406 ta->value()[3][2] << " " << 407 ta->value()[3][3] << ")"; 408 } 409 else if (const PreviewImageAttribute *ta = 410 dynamic_cast <const PreviewImageAttribute *> (a)) 411 { 412 cout << ": " << 413 ta->value().width() << " by " << 414 ta->value().height() << " pixels"; 415 } 416 else if (const StringAttribute *ta = 417 dynamic_cast <const StringAttribute *> (a)) 418 { 419 cout << ": \"" << ta->value() << "\""; 420 } 421 else if (const RationalAttribute *ta = 422 dynamic_cast <const RationalAttribute *> (a)) 423 { 424 cout << ": " << ta->value().n << "/" << ta->value().d << 425 " (" << double (ta->value()) << ")"; 426 } 427 else if (const TileDescriptionAttribute *ta = 428 dynamic_cast <const TileDescriptionAttribute *> (a)) 429 { 430 cout << ":\n "; 431 432 printLevelMode (ta->value().mode); 433 434 cout << "\n tile size " << 435 ta->value().xSize << " by " << 436 ta->value().ySize << " pixels"; 437 438 if (ta->value().mode != ONE_LEVEL) 439 { 440 cout << "\n level sizes rounded "; 441 printLevelRoundingMode (ta->value().roundingMode); 442 } 443 } 444 else if (const TimeCodeAttribute *ta = 445 dynamic_cast <const TimeCodeAttribute *> (a)) 446 { 447 cout << ":\n"; 448 printTimeCode (ta->value()); 449 } 450 else if (const V2iAttribute *ta = 451 dynamic_cast <const V2iAttribute *> (a)) 452 { 453 cout << ": " << ta->value(); 454 } 455 else if (const V2fAttribute *ta = 456 dynamic_cast <const V2fAttribute *> (a)) 457 { 458 cout << ": " << ta->value(); 459 } 460 else if (const V3iAttribute *ta = 461 dynamic_cast <const V3iAttribute *> (a)) 462 { 463 cout << ": " << ta->value(); 464 } 465 else if (const V3fAttribute *ta = 466 dynamic_cast <const V3fAttribute *> (a)) 467 { 468 cout << ": " << ta->value(); 469 } 470 471 cout << '\n'; 472 } 473 474 cout << endl; 475} 476 477 478int 479main(int argc, char **argv) 480{ 481 if (argc < 2) 482 { 483 std::cerr << "usage: " << argv[0] << " imagefile [imagefile ...]\n"; 484 return 1; 485 } 486 else 487 { 488 try 489 { 490 for (int i = 1; i < argc; ++i) 491 printInfo (argv[i]); 492 493 return 0; 494 } 495 catch (const std::exception &e) 496 { 497 std::cerr << e.what() << std::endl; 498 return 1; 499 } 500 } 501} 502