void SaveTexture( const std::string& _filename, float* _data, int _w, int _h, bool _verbose) { int xRes = _w; int yRes = _h; int xOffset = 0; int yOffset = 0; int nChannels = 4; Imf::Header header(xRes, yRes); Imath::Box2i dataWindow(Imath::V2i(xOffset, yOffset), Imath::V2i(xOffset + xRes - 1, yOffset + yRes - 1)); header.dataWindow() = dataWindow; header.channels().insert("R", Imf::Channel (Imf::HALF)); header.channels().insert("G", Imf::Channel (Imf::HALF)); header.channels().insert("B", Imf::Channel (Imf::HALF)); header.channels().insert("A", Imf::Channel (Imf::HALF)); ::half *hchannels = new ::half[nChannels * xRes * yRes]; for (int y = 0; y < yRes; ++y) for (int x = 0; x < xRes; ++x) for (int c = 0; c < nChannels; ++c) { int iSrc = c + x*nChannels + (yRes-1-y)*xRes*nChannels; int iDst = c + x*nChannels + y*xRes*nChannels; hchannels[iDst] = _data[iSrc]; } Imf::FrameBuffer fb; fb.insert("R", Imf::Slice(Imf::HALF, (char *)hchannels, nChannels*sizeof(::half), nChannels*xRes*sizeof(::half))); fb.insert("G", Imf::Slice(Imf::HALF, (char *)hchannels+1*sizeof(::half), nChannels*sizeof(::half), nChannels*xRes*sizeof(::half))); fb.insert("B", Imf::Slice(Imf::HALF, (char *)hchannels+2*sizeof(::half), nChannels*sizeof(::half), nChannels*xRes*sizeof(::half))); fb.insert("A", Imf::Slice(Imf::HALF, (char *)hchannels+3*sizeof(::half), nChannels*sizeof(::half), nChannels*xRes*sizeof(::half))); Imf::OutputFile file(_filename.c_str(), header); file.setFrameBuffer(fb); try { file.writePixels(yRes); } catch (const std::exception &e) { Error("Unable to write image file \"%s\": %s", _filename.c_str(), e.what()); assert(false); } delete[] hchannels; }
//--------------------------------------------------------------------------- void File_Exr::Data_Parse() { if (CC4(Buffer+Buffer_Offset)==0x762F3101) //"v/1"+1 //Header Header(); else if (name=="comments" && type=="string") comments(); else if (name=="compression" && type=="compression" && Element_Size==1) compression(); else if (name=="dataWindow" && type=="box2i" && Element_Size==16) dataWindow(); else if (name=="displayWindow" && type=="box2i" && Element_Size==16) displayWindow(); else if (name=="pixelAspectRatio" && type=="float" && Element_Size==4) pixelAspectRatio(); else Skip_XX(Element_Size, "value"); }
//--------------------------------------------------------------------------- void File_Exr::Data_Parse() { if (name_End==0) ImageData(); else if (name=="channels" && type=="chlist") channels(); else if (name=="comments" && type=="string") comments(); else if (name=="compression" && type=="compression" && Element_Size==1) compression(); else if (name=="dataWindow" && type=="box2i" && Element_Size==16) dataWindow(); else if (name=="displayWindow" && type=="box2i" && Element_Size==16) displayWindow(); else if (name=="pixelAspectRatio" && type=="float" && Element_Size==4) pixelAspectRatio(); else Skip_XX(Element_Size, "value"); }
void DPXCodec::decompress(const DataChunk &data) { MemoryFile file(data); DPXCodec_InStream istream(file); dpx::Reader dpx; dpx.SetInStream(&istream); const bool header_read = dpx.ReadHeader(); if(header_read) { const int dpx_width = dpx.header.Width(); const int dpx_height = dpx.header.Height(); const int dpx_channels = dpx.header.ImageElementComponentCount(0); assert(dpx_width == _descriptor.getStoredWidth()); assert(dpx_height == _descriptor.getStoredHeight()); assert(dpx_channels == (_channels == DPX_RGBA ? 4 : 3)); const Box2i dataW = dataWindow(); if(dpx_width != (dataW.max.x - dataW.min.x + 1)) throw MoxMxf::InputExc("Stored data is wrong width"); if(dpx_height != (dataW.max.y - dataW.min.y + 1)) throw MoxMxf::InputExc("Stored data is wrong height"); const size_t pixsize = (_depth == DPX_8 ? sizeof(unsigned char) : sizeof(unsigned short)); const size_t rowbytes = dpx_width * pixsize * dpx_channels; const size_t buffer_size = rowbytes * dpx_height; DataChunkPtr frame_data = new DataChunk(buffer_size); char *origin = (char *)frame_data->Data; FrameBufferPtr frame_buffer = new FrameBuffer(dataW); const PixelType pixel_type = (_depth == DPX_8 ? MoxFiles::UINT8 : MoxFiles::UINT16); const size_t bytes_per_subpixel = PixelSize(pixel_type); const size_t bytes_per_pixel = bytes_per_subpixel * dpx_channels; frame_buffer->insert("R", Slice(pixel_type, origin + (bytes_per_subpixel * 0), bytes_per_pixel, rowbytes)); frame_buffer->insert("G", Slice(pixel_type, origin + (bytes_per_subpixel * 1), bytes_per_pixel, rowbytes)); frame_buffer->insert("B", Slice(pixel_type, origin + (bytes_per_subpixel * 2), bytes_per_pixel, rowbytes)); if(_channels == DPX_RGBA) frame_buffer->insert("A", Slice(pixel_type, origin + (bytes_per_subpixel * 3), bytes_per_pixel, rowbytes)); frame_buffer->attachData(frame_data); dpx::Block block(0, 0, dpx_width - 1, dpx_height - 1); const dpx::Descriptor dpx_desc = dpx.header.ImageDescriptor(0); const dpx::DataSize dpx_size = (_depth == DPX_8 ? dpx::kByte : dpx::kWord); const bool image_read = dpx.ReadBlock((void *)origin, dpx_size, block, dpx_desc); if(image_read) { storeFrame(frame_buffer); } else assert(false); } else assert(false); }
void DPXCodec::compress(const FrameBuffer &frame) { const PixelType pixel_type = (_depth == DPX_8 ? MoxFiles::UINT8 : MoxFiles::UINT16); const size_t bytes_per_subpixel = PixelSize(pixel_type); const int num_channels = (_channels == DPX_RGBA ? 4 : 3); const Box2i dataW = dataWindow(); const int width = (dataW.max.x - dataW.min.x + 1); const int height = (dataW.max.y - dataW.min.y + 1); const size_t bytes_per_pixel = bytes_per_subpixel * num_channels; const size_t rowbytes = bytes_per_pixel * width; const size_t buffer_size = rowbytes * height; DataChunk data(buffer_size); FrameBuffer frame_buffer(dataW); char *origin = (char *)data.Data; frame_buffer.insert("R", Slice(pixel_type, origin + (bytes_per_subpixel * 0), bytes_per_pixel, rowbytes)); frame_buffer.insert("G", Slice(pixel_type, origin + (bytes_per_subpixel * 1), bytes_per_pixel, rowbytes)); frame_buffer.insert("B", Slice(pixel_type, origin + (bytes_per_subpixel * 2), bytes_per_pixel, rowbytes)); if(_channels == DPX_RGBA) frame_buffer.insert("A", Slice(pixel_type, origin + (bytes_per_subpixel * 3), bytes_per_pixel, rowbytes)); frame_buffer.copyFromFrame(frame); MemoryFile file(buffer_size); DPXCodec_OutStream ostream(file); dpx::Writer dpx; dpx.SetOutStream(&ostream); dpx.SetFileInfo("MOX", // fileName NULL, // creation time (set by libdpx) "DPXcodec, part of MOX", // creator NULL, // project NULL, // copyright ~0, // encryption key (0xffffffff means no encryption) false); // don't swap byte order dpx.SetImageInfo(width, height); dpx.header.SetAspectRatio(0, _pixelAspectRatio.Numerator); dpx.header.SetAspectRatio(1, _pixelAspectRatio.Denominator); dpx.header.SetFrameRate((dpx::R32)_frameRate.Numerator / (dpx::R32)_frameRate.Denominator); //dpx.header.SetInterlace(info->field_label->type == FIEL_Type_FRAME_RENDERED ? 0 : 1); const unsigned int bit_depth = (_depth == DPX_8 ? 8 : _depth == DPX_10 ? 10 : _depth == DPX_12 ? 12 : _depth == DPX_16 ? 16 : 10); const dpx::Descriptor dpx_desc = (_channels == DPX_RGBA ? dpx::kRGBA : dpx::kRGB); const dpx::Packing packing = ((bit_depth == 8 || bit_depth == 16) ? dpx::kPacked : dpx::kFilledMethodA); const dpx::Characteristic transfer = dpx::kLogarithmic; const dpx::Characteristic colorimetric = dpx::kLogarithmic; dpx.SetElement(0, dpx_desc, bit_depth, transfer, colorimetric, packing); const bool wrote_header = dpx.WriteHeader(); if(!wrote_header) throw MoxMxf::ArgExc("Error writing header"); const dpx::DataSize size = (pixel_type == MoxFiles::UINT16 ? dpx::kWord : dpx::kByte); const bool wrote_element = dpx.WriteElement(0, data.Data, size); if(!wrote_element) throw MoxMxf::ArgExc("Error writing image"); const bool wrote_finish = dpx.Finish(); if(!wrote_finish) throw MoxMxf::ArgExc("Error writing finish"); storeData( file.getDataChunk() ); }
void JPEGLSCodec::decompress(const DataChunk &data) { ByteStreamInfo inStream = FromByteArray(data.Data, data.Size); struct JlsParameters info; JLS_ERROR err = JpegLsReadHeaderStream(inStream, &info); if(err == OK) { const int width = info.width; const int height = info.height; assert(info.components == (_channels == JPEGLS_RGBA ? 4 : 3)); assert(info.colorTransform == COLORXFORM_NONE); const PixelType pixType = (_depth == JPEGLS_8 ? UINT8 : _depth == JPEGLS_10 ? UINT10 : _depth == JPEGLS_12 ? UINT12 : _depth == JPEGLS_16 ? UINT16 : UINT8); const size_t pixSize = PixelSize(pixType); const unsigned int bitDepth = PixelBits(pixType); assert(info.bitspersample == bitDepth); const size_t pixelSize = (info.components * PixelSize(pixType)); const size_t rowBytes = (width * pixelSize); const size_t bufSize = (height * rowBytes); DataChunkPtr frameData = new DataChunk(bufSize); char *buf = (char *)frameData->Data; const Box2i dataW = dataWindow(); assert(width == (dataW.max.x - dataW.min.x + 1)); assert(height == (dataW.max.y - dataW.min.y + 1)); assert(dataW.min.x == 0); assert(dataW.min.y == 0); FrameBufferPtr frameBuffer = new FrameBuffer(dataW); frameBuffer->insert("R", Slice(pixType, &buf[0 * pixSize], pixelSize, rowBytes)); frameBuffer->insert("G", Slice(pixType, &buf[1 * pixSize], pixelSize, rowBytes)); frameBuffer->insert("B", Slice(pixType, &buf[2 * pixSize], pixelSize, rowBytes)); if(info.components >= 4) frameBuffer->insert("A", Slice(pixType, &buf[3 * pixSize], pixelSize, rowBytes)); frameBuffer->attachData(frameData); ByteStreamInfo outStream = FromByteArray(frameData->Data, frameData->Size); err = JpegLsDecodeStream(outStream, inStream, &info); if(err == OK) { storeFrame(frameBuffer); } } if(err != OK) throw MoxMxf::ArgExc("JPEG-LS decompression error"); }
void JPEGLSCodec::compress(const FrameBuffer &frame) { const Box2i dataW = dataWindow(); const int width = (dataW.max.x - dataW.min.x + 1); const int height = (dataW.max.y - dataW.min.y + 1); const PixelType pixType = (_depth == JPEGLS_8 ? UINT8 : _depth == JPEGLS_10 ? UINT10 : _depth == JPEGLS_12 ? UINT12 : _depth == JPEGLS_16 ? UINT16 : UINT8); const size_t pixSize = PixelSize(pixType); const unsigned int bitDepth = PixelBits(pixType); const int numChannels = (_channels == JPEGLS_RGBA ? 4 : 3); const size_t tempPixelSize = (numChannels * pixSize); const size_t tempRowbytes = (tempPixelSize * width); const size_t tempBufSize = (tempRowbytes * height); DataChunk dataChunk(tempBufSize); char *tempBuffer = (char *)dataChunk.Data; assert(dataW.min.x == 0 && dataW.min.y == 0); FrameBuffer tempFrameBuffer(dataW); tempFrameBuffer.insert("R", Slice(pixType, &tempBuffer[0 * pixSize], tempPixelSize, tempRowbytes)); tempFrameBuffer.insert("G", Slice(pixType, &tempBuffer[1 * pixSize], tempPixelSize, tempRowbytes)); tempFrameBuffer.insert("B", Slice(pixType, &tempBuffer[2 * pixSize], tempPixelSize, tempRowbytes)); if(_channels == JPEGLS_RGBA) tempFrameBuffer.insert("A", Slice(pixType, &tempBuffer[3 * pixSize], tempPixelSize, tempRowbytes)); tempFrameBuffer.copyFromFrame(frame); JlsParameters params = JlsParameters(); params.width = width; params.height = height; params.bitspersample = bitDepth; //params.bytesperline = (tempRowbytes / 3); params.components = numChannels; params.allowedlossyerror = 0; // always lossless params.ilv = ILV_SAMPLE; params.colorTransform = COLORXFORM_NONE; //params.outputBgr = 0; /* params.custom.MAXVAL = 255; params.custom.T1 = 0; params.custom.T2 = 0; params.custom.T3 = 0; params.custom.RESET = 1; params.jfif.Ver = 123; params.jfif.units = 0; params.jfif.XDensity = 72; params.jfif.YDensity = 72; params.jfif.Xthumb = 0; params.jfif.Ythumb = 0; params.jfif.pdataThumbnail = NULL; */ ByteStreamInfo inStream = FromByteArray(dataChunk.Data, dataChunk.Size); DataChunkPtr outDataChunk = new DataChunk(tempBufSize); size_t bytesWritten = 0; JLS_ERROR err = OK; do { ByteStreamInfo outStream = FromByteArray(outDataChunk->Data, outDataChunk->Size); err = JpegLsEncodeStream(outStream, &bytesWritten, inStream, ¶ms); if(err == CompressedBufferTooSmall) { outDataChunk->Resize(2 * outDataChunk->Size, false); } }while(err == CompressedBufferTooSmall); assert(err != TooMuchCompressedData); if(err == OK) { assert(bytesWritten > 0); outDataChunk->Resize(bytesWritten); storeData(outDataChunk); } else throw MoxMxf::ArgExc("JPEG-LS compression error"); }
bool DeepImageReader::loadFileFromPath( const std::string &filePath, std::string &errorMsg ) { try { // Perform an early-out if we have already loaded the desired file. if( m_currentPath == filePath && m_reader && m_currentPath != "" ) { return true; } IECore::ReaderPtr object( IECore::Reader::create( filePath ) ); m_reader = IECore::runTimeCast<IECore::DeepImageReader>( object ); if( m_reader ) { m_currentPath = filePath; std::vector< std::string > channelNames; m_reader->channelNames( channelNames ); m_channels = DD::Image::ChannelSet( DD::Image::Mask_DeepFront | DD::Image::Mask_DeepBack ); m_channelMap.clear(); for( std::vector< std::string >::const_iterator it( channelNames.begin() ); it != channelNames.end(); ++it ) { int idx( it - channelNames.begin() ); if( *it == "A" ) { m_channels += DD::Image::Chan_Alpha; m_channelMap[DD::Image::Chan_Alpha] = idx; } else if( *it == "R" ) { m_channels += DD::Image::Chan_Red; m_channelMap[DD::Image::Chan_Red] = idx; } else if( *it == "G" ) { m_channels += DD::Image::Chan_Green; m_channelMap[DD::Image::Chan_Green] = idx; } else if( *it == "B" ) { m_channels += DD::Image::Chan_Blue; m_channelMap[DD::Image::Chan_Blue] = idx; } } Imath::Box2i dataWindow( m_reader->dataWindow() ); m_dataWindow = DD::Image::Box( dataWindow.min[0], dataWindow.min[1], dataWindow.max[0]+1, dataWindow.max[1]+1 ); errorMsg = ""; return true; } else { errorMsg = "Object is not an IECore::DeepImageReader."; } } catch( const IECore::Exception &e ) { errorMsg = ( boost::format( "DeepImageReader : %s" ) % e.what() ).str(); } return false; }
void JPEGCodec::decompress(const DataChunk &data) { struct jpeg_error_mgr jerr; jerr.error_exit = my_error_exit; jerr.emit_message = my_emit_message; jerr.output_message = my_output_message; jerr.format_message = my_format_message; jerr.reset_error_mgr = my_reset_error_mgr; jerr.trace_level = 0; jerr.num_warnings = 0; jerr.msg_code = 0; jerr.jpeg_message_table = jpeg_std_message_table; jerr.last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; jerr.addon_message_table = NULL; jerr.first_addon_message = 0; jerr.last_jpeg_message = 0; my_source_mgr mgr; mgr.infile = new MemoryFile(data); mgr.buffer = (JOCTET *)malloc(4096 * sizeof(JOCTET)); mgr.bufferSize = 4096; mgr.pub.bytes_in_buffer = 0; mgr.pub.next_input_byte = NULL; if(mgr.buffer == NULL) throw MoxMxf::NullExc("out of memory"); mgr.pub.init_source = my_init_source; mgr.pub.fill_input_buffer = my_fill_input_buffer; mgr.pub.skip_input_data = my_skip_input_data; mgr.pub.resync_to_restart = jpeg_resync_to_restart; mgr.pub.term_source = my_term_source; struct jpeg_decompress_struct cinfo; cinfo.err = &jerr; jpeg_create_decompress(&cinfo); cinfo.src = (jpeg_source_mgr *)&mgr; bool success = true; try { const int status = jpeg_read_header(&cinfo, TRUE); if(status == JPEG_HEADER_OK) { jpeg_start_decompress(&cinfo); const JDIMENSION width = cinfo.image_width; const JDIMENSION height = cinfo.image_height; assert(cinfo.num_components == 3); assert(cinfo.out_color_space == JCS_RGB); const size_t pixelSize = (3 * PixelSize(UINT8)); const size_t rowBytes = (width * pixelSize); const size_t bufSize = (height * rowBytes); DataChunkPtr frameData = new DataChunk(bufSize); char *buf = (char *)frameData->Data; const Box2i dataW = dataWindow(); assert(width == (dataW.max.x - dataW.min.x + 1)); assert(height == (dataW.max.y - dataW.min.y + 1)); assert(dataW.min.x == 0); assert(dataW.min.y == 0); FrameBufferPtr frameBuffer = new FrameBuffer(dataW); frameBuffer->insert("R", Slice(UINT8, &buf[0], pixelSize, rowBytes)); frameBuffer->insert("G", Slice(UINT8, &buf[1], pixelSize, rowBytes)); frameBuffer->insert("B", Slice(UINT8, &buf[2], pixelSize, rowBytes)); frameBuffer->attachData(frameData); JSAMPARRAY scanlines = (JSAMPARRAY)malloc(height * sizeof(JSAMPROW)); if(scanlines == NULL) throw MoxMxf::NullExc("out of memory"); for(int y=0; y < height; y++) { scanlines[y] = (JSAMPROW)(buf + (y * rowBytes)); } JDIMENSION linesRead = 0; while(linesRead < height) { linesRead += jpeg_read_scanlines(&cinfo, &scanlines[linesRead], height - linesRead); } free(scanlines); jpeg_finish_decompress(&cinfo); storeFrame(frameBuffer); } else throw MoxMxf::ArgExc("Error reading header"); } catch(...) { success = false; } jpeg_destroy_decompress(&cinfo); free(mgr.buffer); delete mgr.infile; if(!success) throw MoxMxf::ArgExc("JPEG decompression error"); }
void JPEGCodec::compress(const FrameBuffer &frame) { struct jpeg_error_mgr jerr; jerr.error_exit = my_error_exit; jerr.emit_message = my_emit_message; jerr.output_message = my_output_message; jerr.format_message = my_format_message; jerr.reset_error_mgr = my_reset_error_mgr; jerr.trace_level = 0; jerr.num_warnings = 0; jerr.msg_code = 0; jerr.jpeg_message_table = jpeg_std_message_table; jerr.last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; jerr.addon_message_table = NULL; jerr.first_addon_message = 0; jerr.last_jpeg_message = 0; struct jpeg_compress_struct cinfo; cinfo.err = &jerr; jpeg_create_compress(&cinfo); my_destination_mgr mgr; mgr.outfile = new MemoryFile; mgr.buffer = NULL; mgr.bufferSize = 0; mgr.pub.init_destination = my_init_destination; mgr.pub.empty_output_buffer = my_empty_output_buffer; mgr.pub.term_destination = my_term_destination; cinfo.dest = (jpeg_destination_mgr *)&mgr; const Box2i dataW = dataWindow(); const int width = (dataW.max.x - dataW.min.x + 1); const int height = (dataW.max.y - dataW.min.y + 1); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, _quality, TRUE); bool success = true; try { jpeg_start_compress(&cinfo, TRUE); const size_t tempPixelSize = (3 * PixelSize(UINT8)); const size_t tempRowbytes = (tempPixelSize * width); const size_t tempBufSize = (tempRowbytes * height); DataChunk dataChunk(tempBufSize); char *tempBuffer = (char *)dataChunk.Data; FrameBuffer tempFrameBuffer(dataW); tempFrameBuffer.insert("R", Slice(UINT8, &tempBuffer[0], tempPixelSize, tempRowbytes)); tempFrameBuffer.insert("G", Slice(UINT8, &tempBuffer[1], tempPixelSize, tempRowbytes)); tempFrameBuffer.insert("B", Slice(UINT8, &tempBuffer[2], tempPixelSize, tempRowbytes)); tempFrameBuffer.copyFromFrame(frame); JSAMPARRAY scanlines = (JSAMPARRAY)malloc(height * sizeof(JSAMPROW)); if(scanlines == NULL) throw MoxMxf::NullExc("out of memory"); for(int y=0; y < height; y++) { scanlines[y] = (JSAMPROW)(tempBuffer + (y * tempRowbytes)); } const JDIMENSION linesWrote = jpeg_write_scanlines(&cinfo, scanlines, height); assert(linesWrote == height); jpeg_finish_compress(&cinfo); assert(jerr.msg_code == 0); storeData( mgr.outfile->getDataChunk() ); free(scanlines); } catch(...) { success = false; } jpeg_destroy_compress(&cinfo); if(mgr.buffer != NULL) free(mgr.buffer); delete mgr.outfile; if(!success) throw MoxMxf::ArgExc("JPEG compression error"); }