void CqTiffDirHandle::fillHeaderRequiredAttrs(CqTexFileHeader& header) const { // Fill header with general metadata which won't affect the details of the // pixel memory layout. header.setWidth(tiffTagValue<uint32>(TIFFTAG_IMAGEWIDTH)); header.setHeight(tiffTagValue<uint32>(TIFFTAG_IMAGELENGTH)); if(TIFFIsTiled(tiffPtr())) { header.set<Attr::TileInfo>( SqTileInfo( tiffTagValue<uint32>(TIFFTAG_TILEWIDTH), tiffTagValue<uint32>(TIFFTAG_TILELENGTH)) ); } // Get the compression type. header.set<Attr::Compression>( tiffCompressionNameFromTag(tiffTagValue<uint16>(TIFFTAG_COMPRESSION)) ); // Compute pixel aspect ratio TqFloat xRes = 0; TqFloat yRes = 0; if(TIFFGetField(tiffPtr(), TIFFTAG_XRESOLUTION, &xRes) && TIFFGetField(tiffPtr(), TIFFTAG_YRESOLUTION, &yRes)) { // yRes/xRes should be the correct quantity corresponding to the // pixelAspectRatio used in OpenEXR. header.set<Attr::PixelAspectRatio>(yRes/xRes); } else { header.set<Attr::PixelAspectRatio>(1.0f); } }
void CqImage::saveToFile(const std::string& fileName) const { boost::mutex::scoped_lock lock(mutex()); CqTexFileHeader header; // Required attributes header.setWidth(m_realData->width()); header.setHeight(m_realData->height()); header.channelList() = m_realData->channelList(); // Informational strings header.set<Attr::Software>( (boost::format("Aqsis %s (%s %s)") % AQSIS_VERSION_STR % __DATE__ % __TIME__).str()); header.set<Attr::DisplayWindow>(SqImageRegion(m_frameWidth, m_frameHeight, m_originX, m_originY)); header.set<Attr::PixelAspectRatio>(1.0); // Set some default compression scheme for now - later we can accept user // input for this. header.set<Attr::Compression>("lzw"); // \todo: Attributes which might be good to add: // Host computer // Image description // Transformation matrices try { // Now create the image, and output the pixel data. boost::shared_ptr<IqTexOutputFile> outFile = IqTexOutputFile::open(fileName, ImageFile_Tiff, header); // Write all pixels out at once. outFile->writePixels(*m_realData); } catch(XqInternal& e) { Aqsis::log() << error << "Could not save image \"" << fileName << "\": " << e.what() << "\n"; return; } }
/** \brief Convert an OpenEXR header to our own header representation. * * \param exrHeader - input header * \param header - output header */ void convertHeader(const Imf::Header& exrHeader, CqTexFileHeader& header) { // Set width, height const Imath::Box2i& dataBox = exrHeader.dataWindow(); header.setWidth(dataBox.max.x - dataBox.min.x+1); header.setHeight(dataBox.max.y - dataBox.min.y+1); // display window const Imath::Box2i& displayBox = exrHeader.displayWindow(); header.set<Attr::DisplayWindow>( SqImageRegion( displayBox.max.x - displayBox.min.x, displayBox.max.y - displayBox.min.y, displayBox.min.x - dataBox.min.x, displayBox.min.y - dataBox.min.y) ); // Set tiling information ? // Aspect ratio header.set<Attr::PixelAspectRatio>(exrHeader.pixelAspectRatio()); TqChannelNameMap channelNameMap; // Convert channel representation const Imf::ChannelList& exrChannels = exrHeader.channels(); CqChannelList& channels = header.channelList(); for(Imf::ChannelList::ConstIterator i = exrChannels.begin(); i != exrChannels.end(); ++i) { // use lower case names for channels; OpenEXR uses upper case. std::string chanName = i.name(); std::transform(chanName.begin(), chanName.end(), chanName.begin(), ::tolower); channelNameMap[chanName] = i.name(); channels.addChannel( SqChannelInfo(chanName, channelTypeFromExr(i.channel().type)) ); } header.set<Attr::ExrChannelNameMap>(channelNameMap); channels.reorderChannels(); // Set compresssion type header.set<Attr::Compression>(exrCompressionToString(exrHeader.compression())); }
void CqZInputFile::readHeader(std::istream& inStream, CqTexFileHeader& header) { const char zFileMagicNum[] = "Aqsis ZFile"; const TqInt magicNumSize = sizeof(zFileMagicNum)-1; const TqInt versionNumSize = sizeof(AQSIS_VERSION_STR)-1; std::vector<char> buf(max(magicNumSize, versionNumSize)); // Read in magic number inStream.read(&buf[0], magicNumSize); if(!std::equal(buf.begin(), buf.begin() + magicNumSize, zFileMagicNum) || inStream.gcount() != magicNumSize) { AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile, "Magic number missmatch in zfile"); } // Read in Aqsis version. We require this to match the current aqsis version. inStream.read(&buf[0], versionNumSize); if(!std::equal(buf.begin(), buf.begin() + versionNumSize, AQSIS_VERSION_STR) || inStream.gcount() != versionNumSize) { AQSIS_THROW_XQERROR(XqBadTexture, EqE_Version, "zfile was created with a different aqsis version"); } // Read in map width TqUint width = 0; inStream.read(reinterpret_cast<char*>(&width), sizeof(width)); if(inStream.gcount() != sizeof(width)) AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile, "cannot read width from aqsis z-file"); // Read in map height TqUint height = 0; inStream.read(reinterpret_cast<char*>(&height), sizeof(height)); if(inStream.gcount() != sizeof(height)) AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile, "cannot read height from aqsis z-file"); // Read world to camera transformation matrix CqMatrix worldToCamera; worldToCamera.SetfIdentity(false); inStream.read(reinterpret_cast<char*>(worldToCamera.pElements()), 16*sizeof(TqFloat)); if(inStream.gcount() != 16*sizeof(TqFloat)) AQSIS_THROW_XQERROR(XqBadTexture,EqE_BadFile, "could not read world to camera matrix from aqsis z-file"); // Read world to screen transformation matrix CqMatrix worldToScreen; worldToScreen.SetfIdentity(false); inStream.read(reinterpret_cast<char*>(worldToScreen.pElements()), 16*sizeof(TqFloat)); if(inStream.gcount() != 16*sizeof(TqFloat)) AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile, "could not read world to screen matrix from aqsis z-file"); // Save the read header attributes into the file header. header.setWidth(width); header.setHeight(height); header.set<Attr::WorldToScreenMatrix>(worldToScreen); header.set<Attr::WorldToCameraMatrix>(worldToCamera); // Complete the header with some other attributes implied by the file format header.set<Attr::TextureFormat>(TextureFormat_Shadow); header.channelList().addChannel(SqChannelInfo("z", Channel_Float32)); }