Damn it, I've forgot to attach the patch. So here it is. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "hugin and other free panoramic software" group. A list of frequently asked questions is available at: http://wiki.panotools.org/Hugin_FAQ To post to this group, send email to hugin-ptx@googlegroups.com To unsubscribe from this group, send email to hugin-ptx-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/hugin-ptx -~----------~----~----~----~------~----~------~--~---
Index: src/foreign/vigra/vigra_impex/exr.cxx =================================================================== --- src/foreign/vigra/vigra_impex/exr.cxx (revision 3635) +++ src/foreign/vigra/vigra_impex/exr.cxx (working copy) @@ -48,8 +48,10 @@ #include <iostream> #include <ImfRgbaFile.h> +#include <ImfHeader.h> #include <ImfStringAttribute.h> #include <ImfMatrixAttribute.h> +#include <ImfStandardAttributes.h> #include <ImfArray.h> using namespace Imf; @@ -281,6 +283,8 @@ int width, height, components; int extra_components; int bit_depth, color_type; + float scaleFactor; + Compression exrcomp; // scanline counter int scanline; @@ -300,14 +304,16 @@ ~ExrEncoderImpl(); // methods + void setCompressionType( const std::string &, int ); void nextScanline(); void finalize(); void close(); + void rewriteFileUsingScaleFactor(); }; ExrEncoderImpl::ExrEncoderImpl( const std::string & filename ) - : filename(filename), file(0), bands(0), - scanline(0), finalized(false), + : filename(filename), file(0), bands(0), scaleFactor(-1), + exrcomp(ZIP_COMPRESSION) ,scanline(0), finalized(false), x_resolution(0), y_resolution(0) { } @@ -341,7 +347,10 @@ } Imath::Box2i dataWindow (Imath::V2i (position.x , position.y), Imath::V2i (width+position.x -1, height+position.y-1)); - file = new RgbaOutputFile( filename.c_str(), displayWindow, dataWindow, WRITE_RGBA ); + Header header(displayWindow, dataWindow, 1, Imath::V2f(0, 0), 1, INCREASING_Y, exrcomp); + if (scaleFactor != -1) // write scale factor to the EXR header + addWhiteLuminance(header, 1/scaleFactor); + file = new RgbaOutputFile( filename.c_str(), header, WRITE_RGBA ); // enter finalized state finalized = true; } @@ -349,21 +358,89 @@ void ExrEncoderImpl::nextScanline() { // check if there are scanlines left at all, eventually write one + static float maxValue = -1; if ( scanline < height ) { float * src = bands.data(); for (int i=0; i < width; i++) { + if ((*src++ < HALF_MAX) || (*src < maxValue)) { // convert to half - pixels[i].r = *src++; - pixels[i].g = *src++; - pixels[i].b = *src++; - pixels[i].a = *src++; + pixels[i].r = *src; + } else { + maxValue = *src; + scaleFactor = HALF_MAX/maxValue; + rewriteFileUsingScaleFactor(); } + if ((*src++ < HALF_MAX) || (*src < maxValue)){ + // convert to half + pixels[i].g = *src; + } else { + maxValue = *src; + scaleFactor = HALF_MAX/maxValue; + rewriteFileUsingScaleFactor(); + } + if ((*src++ < HALF_MAX) || (*src < maxValue)){ + // convert to half + pixels[i].b = *src; + } else { + maxValue = *src; + scaleFactor = HALF_MAX/maxValue; + rewriteFileUsingScaleFactor(); + } + pixels[i].a = *src; + } + rewriteFileUsingScaleFactor(); file->setFrameBuffer (pixels.begin() - position.x -(scanline+position.y)*width, 1, width); file->writePixels (1); } scanline++; } + /** rewrite saved data with scaleFactor used + * Opens file and then changes every line according to scaleFactor + * @param scaleFactor multiplies every value with it + */ + void ExrEncoderImpl::rewriteFileUsingScaleFactor() { + ExrDecoderImpl *decImpl = new ExrDecoderImpl(filename); + decImpl->init(); + int currentScanLine = scanline; + ArrayVector<float> lastBand = bands; + // reads already saved lines and change them with scale factor + for (scanline = 0; scanline < currentScanLine; scanline++) { + decImpl->nextScanline(); + float *dest = bands.data(); + for (int i = 0; i < (width*4); i++) { + // do not change alpha channel + if ((i+1)%3 != 0) + *dest++ = decImpl->bands[i] * scaleFactor; + } + nextScanline(); + } + // write changes for current scanline + bands = lastBand; + scanline = currentScanLine; + float * src = bands.data(); + for (int i=0; i < width; i++) { + pixels[i].g = *src++ * scaleFactor; + pixels[i].b = *src++ * scaleFactor; + pixels[i].a = *src++ * scaleFactor; + } + } + + void ExrEncoderImpl::setCompressionType( const std::string & comp, int quality){ + if (comp == "NONE") + exrcomp = NO_COMPRESSION; + else if (comp == "RLE") + exrcomp = RLE_COMPRESSION; + else if (comp == "ZIP") + exrcomp = ZIP_COMPRESSION; + else if (comp == "PIZ") + exrcomp = PIZ_COMPRESSION; + else if (comp == "PXR24") + exrcomp = PXR24_COMPRESSION; + else if (comp == "B44") + exrcomp = B44_COMPRESSION; + } + void ExrEncoderImpl::close() { delete file; @@ -407,7 +484,8 @@ void ExrEncoder::setCompressionType( const std::string & comp, int quality ) { - // TODO: support compression types + VIGRA_IMPEX_FINALIZED(pimpl->finalized); + pimpl->setCompressionType(comp, quality); } void ExrEncoder::setPosition( const Diff2D & pos )