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 )

Reply via email to