📄 imfheader.cpp
字号:
}const PreviewImage &Header::previewImage () const{ return typedAttribute <PreviewImageAttribute> ("preview").value();}bool Header::hasPreviewImage () const{ return findTypedAttribute <PreviewImageAttribute> ("preview") != 0;}void Header::sanityCheck (bool isTiled) const{ // // The display window and the data window must each // contain at least one pixel. In addition, the // coordinates of the window corners must be small // enough to keep expressions like max-min+1 or // max+min from overflowing. // const Box2i &displayWindow = this->displayWindow(); if (displayWindow.min.x > displayWindow.max.x || displayWindow.min.y > displayWindow.max.y || displayWindow.min.x <= -(INT_MAX / 2) || displayWindow.min.y <= -(INT_MAX / 2) || displayWindow.max.x >= (INT_MAX / 2) || displayWindow.max.y >= (INT_MAX / 2)) { throw Iex::ArgExc ("Invalid display window in image header."); } const Box2i &dataWindow = this->dataWindow(); if (dataWindow.min.x > dataWindow.max.x || dataWindow.min.y > dataWindow.max.y || dataWindow.min.x <= -(INT_MAX / 2) || dataWindow.min.y <= -(INT_MAX / 2) || dataWindow.max.x >= (INT_MAX / 2) || dataWindow.max.y >= (INT_MAX / 2)) { throw Iex::ArgExc ("Invalid data window in image header."); } if (maxImageWidth > 0 && maxImageWidth < dataWindow.max.x - dataWindow.min.x + 1) { THROW (Iex::ArgExc, "The width of the data window exceeds the " "maximum width of " << maxImageWidth << "pixels."); } if (maxImageHeight > 0 && maxImageHeight < dataWindow.max.y - dataWindow.min.y + 1) { THROW (Iex::ArgExc, "The width of the data window exceeds the " "maximum width of " << maxImageHeight << "pixels."); } // // The pixel aspect ratio must be greater than 0. // In applications, numbers like the the display or // data window dimensions are likely to be multiplied // or divided by the pixel aspect ratio; to avoid // arithmetic exceptions, we limit the pixel aspect // ratio to a range that is smaller than theoretically // possible (real aspect ratios are likely to be close // to 1.0 anyway). // float pixelAspectRatio = this->pixelAspectRatio(); const float MIN_PIXEL_ASPECT_RATIO = 1e-6; const float MAX_PIXEL_ASPECT_RATIO = 1e+6; if (pixelAspectRatio < MIN_PIXEL_ASPECT_RATIO || pixelAspectRatio > MAX_PIXEL_ASPECT_RATIO) { throw Iex::ArgExc ("Invalid pixel aspect ratio in image header."); } // // The screen window width must not be less than 0. // The size of the screen window can vary over a wide // range (fish-eye lens to astronomical telescope), // so we can't limit the screen window width to a // small range. // float screenWindowWidth = this->screenWindowWidth(); if (screenWindowWidth < 0) throw Iex::ArgExc ("Invalid screen window width in image header."); // // If the file is tiled, verify that the tile description has resonable // values and check to see if the lineOrder is one of the predefined 3. // If the file is not tiled, then the lineOrder can only be INCREASING_Y // or DECREASING_Y. // LineOrder lineOrder = this->lineOrder(); if (isTiled) { if (!hasTileDescription()) { throw Iex::ArgExc ("Tiled image has no tile " "description attribute."); } const TileDescription &tileDesc = tileDescription(); if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0) throw Iex::ArgExc ("Invalid tile size in image header."); if (maxTileWidth > 0 && maxTileWidth < tileDesc.xSize) { THROW (Iex::ArgExc, "The width of the tiles exceeds the maximum " "width of " << maxTileWidth << "pixels."); } if (maxTileHeight > 0 && maxTileHeight < tileDesc.ySize) { THROW (Iex::ArgExc, "The width of the tiles exceeds the maximum " "width of " << maxTileHeight << "pixels."); } if (tileDesc.mode != ONE_LEVEL && tileDesc.mode != MIPMAP_LEVELS && tileDesc.mode != RIPMAP_LEVELS) throw Iex::ArgExc ("Invalid level mode in image header."); if (tileDesc.roundingMode != ROUND_UP && tileDesc.roundingMode != ROUND_DOWN) throw Iex::ArgExc ("Invalid level rounding mode in image header."); if (lineOrder != INCREASING_Y && lineOrder != DECREASING_Y && lineOrder != RANDOM_Y) throw Iex::ArgExc ("Invalid line order in image header."); } else { if (lineOrder != INCREASING_Y && lineOrder != DECREASING_Y) throw Iex::ArgExc ("Invalid line order in image header."); } // // The compression method must be one of the predefined values. // if (!isValidCompression (this->compression())) throw Iex::ArgExc ("Unknown compression type in image header."); // // Check the channel list: // // If the file is tiled then for each channel, the type must be one of the // predefined values, and the x and y sampling must both be 1. // // If the file is not tiled then for each channel, the type must be one // of the predefined values, the x and y coordinates of the data window's // upper left corner must be divisible by the x and y subsampling factors, // and the width and height of the data window must be divisible by the // x and y subsampling factors. // const ChannelList &channels = this->channels(); if (isTiled) { for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { if (i.channel().type != UINT && i.channel().type != HALF && i.channel().type != FLOAT) { THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" " "image channel is invalid."); } if (i.channel().xSampling != 1) { THROW (Iex::ArgExc, "The x subsampling factor for the " "\"" << i.name() << "\" channel " "is not 1."); } if (i.channel().ySampling != 1) { THROW (Iex::ArgExc, "The y subsampling factor for the " "\"" << i.name() << "\" channel " "is not 1."); } } } else { for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { if (i.channel().type != UINT && i.channel().type != HALF && i.channel().type != FLOAT) { THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" " "image channel is invalid."); } if (i.channel().xSampling < 1) { THROW (Iex::ArgExc, "The x subsampling factor for the " "\"" << i.name() << "\" channel " "is invalid."); } if (i.channel().ySampling < 1) { THROW (Iex::ArgExc, "The y subsampling factor for the " "\"" << i.name() << "\" channel " "is invalid."); } if (dataWindow.min.x % i.channel().xSampling) { THROW (Iex::ArgExc, "The minimum x coordinate of the " "image's data window is not a multiple " "of the x subsampling factor of " "the \"" << i.name() << "\" channel."); } if (dataWindow.min.y % i.channel().ySampling) { THROW (Iex::ArgExc, "The minimum y coordinate of the " "image's data window is not a multiple " "of the y subsampling factor of " "the \"" << i.name() << "\" channel."); } if ((dataWindow.max.x - dataWindow.min.x + 1) % i.channel().xSampling) { THROW (Iex::ArgExc, "Number of pixels per row in the " "image's data window is not a multiple " "of the x subsampling factor of " "the \"" << i.name() << "\" channel."); } if ((dataWindow.max.y - dataWindow.min.y + 1) % i.channel().ySampling) { THROW (Iex::ArgExc, "Number of pixels per column in the " "image's data window is not a multiple " "of the y subsampling factor of " "the \"" << i.name() << "\" channel."); } } }}void Header::setMaxImageSize (int maxWidth, int maxHeight){ maxImageWidth = maxWidth; maxImageHeight = maxHeight;}void Header::setMaxTileSize (int maxWidth, int maxHeight){ maxTileWidth = maxWidth; maxTileHeight = maxHeight;}Int64Header::writeTo (OStream &os, bool isTiled) const{ // // Write a "magic number" to identify the file as an image file. // Write the current file format version number. // Xdr::write <StreamIO> (os, MAGIC); int version = isTiled ? makeTiled (EXR_VERSION) : EXR_VERSION; Xdr::write <StreamIO> (os, version); // // Write all attributes. If we have a preview image attribute, // keep track of its position in the file. // Int64 previewPosition = 0; const Attribute *preview = findTypedAttribute <PreviewImageAttribute> ("preview"); for (ConstIterator i = begin(); i != end(); ++i) { // // Write the attribute's name and type. // Xdr::write <StreamIO> (os, i.name()); Xdr::write <StreamIO> (os, i.attribute().typeName()); // // Write the size of the attribute value, // and the value itself. // StdOSStream oss; i.attribute().writeValueTo (oss, version); std::string s = oss.str(); Xdr::write <StreamIO> (os, (int) s.length()); if (&i.attribute() == preview) previewPosition = os.tellp(); os.write (s.data(), s.length()); } // // Write zero-length attribute name to mark the end of the header. // Xdr::write <StreamIO> (os, ""); return previewPosition;}voidHeader::readFrom (IStream &is, int &version){ // // Read the magic number and the file format version number. // Then check if we can read the rest of this file. // int magic; Xdr::read <StreamIO> (is, magic); Xdr::read <StreamIO> (is, version); if (magic != MAGIC) { throw Iex::InputExc ("File is not an image file."); } if (getVersion (version) != EXR_VERSION) { THROW (Iex::InputExc, "Cannot read " "version " << getVersion (version) << " " "image files. Current file format version " "is " << EXR_VERSION << "."); } if (!supportsFlags (getFlags (version))) { THROW (Iex::InputExc, "The file format version number's flag field " "contains unrecognized flags."); } // // Read all attributes. // while (true) { // // Read the name of the attribute. // A zero-length attribute name indicates the end of the header. // char name[100]; Xdr::read <StreamIO> (is, sizeof (name), name); if (name[0] == 0) break; // // Read the attribute type and the size of the attribute value. // char typeName[100]; int size; Xdr::read <StreamIO> (is, sizeof (typeName), typeName); Xdr::read <StreamIO> (is, size); AttributeMap::iterator i = _map.find (name); if (i != _map.end()) { // // The attribute already exists (for example, // because it is a predefined attribute). // Read the attribute's new value from the file. // if (strncmp (i->second->typeName(), typeName, sizeof (typeName))) THROW (Iex::InputExc, "Unexpected type for image attribute " "\"" << name << "\"."); i->second->readValueFrom (is, size, version); } else { // // The new attribute does not exist yet. // If the attribute type is of a known type, // read the attribute value. If the attribute // is of an unknown type, read its value and // store it as an OpaqueAttribute. // Attribute *attr; if (Attribute::knownType (typeName)) attr = Attribute::newAttribute (typeName); else attr = new OpaqueAttribute (typeName); try { attr->readValueFrom (is, size, version); _map[name] = attr; } catch (...) { delete attr; throw; } } }}voidstaticInitialize (){ static Mutex criticalSection; Lock lock (criticalSection); static bool initialized = false; if (!initialized) { // // One-time initialization -- register // some predefined attribute types. // Box2fAttribute::registerAttributeType(); Box2iAttribute::registerAttributeType(); ChannelListAttribute::registerAttributeType(); CompressionAttribute::registerAttributeType(); ChromaticitiesAttribute::registerAttributeType(); DoubleAttribute::registerAttributeType(); EnvmapAttribute::registerAttributeType(); FloatAttribute::registerAttributeType(); IntAttribute::registerAttributeType(); KeyCodeAttribute::registerAttributeType(); LineOrderAttribute::registerAttributeType(); M33fAttribute::registerAttributeType(); M44fAttribute::registerAttributeType(); PreviewImageAttribute::registerAttributeType(); RationalAttribute::registerAttributeType(); StringAttribute::registerAttributeType(); TileDescriptionAttribute::registerAttributeType(); TimeCodeAttribute::registerAttributeType(); V2fAttribute::registerAttributeType(); V2iAttribute::registerAttributeType(); V3fAttribute::registerAttributeType(); V3iAttribute::registerAttributeType(); initialized = true; }}} // namespace Imf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -