void FExrImageWrapper::CompressRaw(const sourcetype* SrcData, bool bIgnoreAlpha) { uint32 NumWriteComponents = GetNumChannelsFromFormat(RawFormat); if (bIgnoreAlpha && NumWriteComponents == 4) { NumWriteComponents = 3; } Imf::Header Header(Width, Height); for (uint32 Channel = 0; Channel < NumWriteComponents; Channel++) { Header.channels().insert(GetRawChannelName(Channel), Imf::Channel(OutputFormat)); } FMemFileOut MemFile(""); Imf::FrameBuffer ImfFrameBuffer; TArray<uint8> ChannelOutputBuffers[4]; for (uint32 Channel = 0; Channel < NumWriteComponents; Channel++) { WriteFrameBufferChannel<OutputFormat>(ImfFrameBuffer, GetRawChannelName(Channel), SrcData + Channel, ChannelOutputBuffers[Channel]); } Imf::OutputFile ImfFile(MemFile, Header); ImfFile.setFrameBuffer(ImfFrameBuffer); ImfFile.writePixels(Height); CompressedData = MemFile.Data; }
void FExrImageWrapper::WriteFrameBufferChannel(Imf::FrameBuffer& ImfFrameBuffer, const char* ChannelName, const sourcetype* SrcData, TArray<uint8>& ChannelBuffer) { const int32 OutputPixelSize = ((OutputFormat == Imf::HALF) ? 2 : 4); ChannelBuffer.AddUninitialized(Width*Height*OutputPixelSize); uint32 SrcChannels = GetNumChannelsFromFormat(RawFormat); ExtractAndConvertChannel(SrcData, SrcChannels, Width, Height, (typename TExrImageOutputChannelType<OutputFormat>::Type*)&ChannelBuffer[0]); Imf::Slice FrameChannel = Imf::Slice(OutputFormat, (char*)&ChannelBuffer[0], OutputPixelSize, Width*OutputPixelSize); ImfFrameBuffer.insert(ChannelName, FrameChannel); }
void FExrImageWrapper::CompressRaw(const sourcetype* SrcData, bool bIgnoreAlpha) { const double StartTime = FPlatformTime::Seconds(); uint32 NumWriteComponents = GetNumChannelsFromFormat(RawFormat); if (bIgnoreAlpha && NumWriteComponents == 4) { NumWriteComponents = 3; } Imf::Compression Comp = bUseCompression ? Imf::Compression::ZIP_COMPRESSION : Imf::Compression::NO_COMPRESSION; Imf::Header Header(Width, Height, 1, Imath::V2f(0, 0), 1, Imf::LineOrder::INCREASING_Y, Comp); for (uint32 Channel = 0; Channel < NumWriteComponents; Channel++) { Header.channels().insert(GetRawChannelName(Channel), Imf::Channel(OutputFormat)); } FMemFileOut MemFile(""); const int32 OutputPixelSize = ((OutputFormat == Imf::HALF && bUseCompression) ? 2 : 4); MemFile.Data.AddUninitialized(Width * Height * NumWriteComponents * OutputPixelSize); Imf::FrameBuffer ImfFrameBuffer; TArray<uint8> ChannelOutputBuffers[4]; for (uint32 Channel = 0; Channel < NumWriteComponents; Channel++) { WriteFrameBufferChannel<OutputFormat>(ImfFrameBuffer, GetRawChannelName(Channel), SrcData + Channel, ChannelOutputBuffers[Channel]); } Imf::OutputFile ImfFile(MemFile, Header); ImfFile.setFrameBuffer(ImfFrameBuffer); ImfFile.writePixels(Height); CompressedData.AddUninitialized(MemFile.tellp()); FMemory::Memcpy(CompressedData.GetData(), MemFile.Data.GetData(), MemFile.tellp()); const double DeltaTime = FPlatformTime::Seconds() - StartTime; UE_LOG(LogImageWrapper, Verbose, TEXT("Compressed image in %.3f seconds"), DeltaTime); }