[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14616] trunk/blender/source/blender/imbuf /intern:

Brecht Van Lommel brechtvanlommel at pandora.be
Tue Apr 29 18:58:22 CEST 2008


Revision: 14616
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14616
Author:   blendix
Date:     2008-04-29 18:57:39 +0200 (Tue, 29 Apr 2008)

Log Message:
-----------

Fix for bug #9014: crash saving the depth pass with openexr or hdr,
both file formats crashed on saving images with less than 4 channels.

Modified Paths:
--------------
    trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp
    trunk/blender/source/blender/imbuf/intern/radiance_hdr.c

Modified: trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp
===================================================================
--- trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp	2008-04-29 16:22:13 UTC (rev 14615)
+++ trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp	2008-04-29 16:57:39 UTC (rev 14616)
@@ -180,7 +180,7 @@
 
 static short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags)
 {
-	
+	int channels = ibuf->channels;
 	int width = ibuf->x;
 	int height = ibuf->y;
 	int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL;   // summarize
@@ -194,7 +194,7 @@
 		header.channels().insert ("R", Channel (HALF));
 		header.channels().insert ("G", Channel (HALF));
 		header.channels().insert ("B", Channel (HALF));
-		if (ibuf->depth==32)
+		if (ibuf->depth==32 && channels >= 4)
 			header.channels().insert ("A", Channel (HALF));
 		if (write_zbuf)		// z we do as float always
 			header.channels().insert ("Z", Channel (FLOAT));
@@ -207,29 +207,29 @@
 		RGBAZ *to = pixels;
 		int xstride= sizeof (RGBAZ);
 		int ystride= xstride*width;
-		
+
 		/* indicate used buffers */
 		frameBuffer.insert ("R", Slice (HALF,  (char *) &pixels[0].r, xstride, ystride));	
 		frameBuffer.insert ("G", Slice (HALF,  (char *) &pixels[0].g, xstride, ystride));
 		frameBuffer.insert ("B", Slice (HALF,  (char *) &pixels[0].b, xstride, ystride));
-		if (ibuf->depth==32)
+		if (ibuf->depth==32 && channels >= 4)
 			frameBuffer.insert ("A", Slice (HALF, (char *) &pixels[0].a, xstride, ystride));
 		if (write_zbuf)
-			frameBuffer.insert ("Z", Slice (FLOAT, (char *) ibuf->zbuf_float + 4*(height-1)*width,
+			frameBuffer.insert ("Z", Slice (FLOAT, (char *)(ibuf->zbuf_float + (height-1)*width),
 											sizeof(float), sizeof(float) * -width));
 		if(ibuf->rect_float) {
 			float *from;
 			
 			for (int i = ibuf->y-1; i >= 0; i--) 
 			{
-				from= ibuf->rect_float + 4*i*width;
+				from= ibuf->rect_float + channels*i*width;
 				
 				for (int j = ibuf->x; j > 0; j--) 
 				{
 					to->r = from[0];
-					to->g = from[1];
-					to->b = from[2];
-					to->a = from[3];
+					to->g = (channels >= 2)? from[1]: from[0];
+					to->b = (channels >= 3)? from[2]: from[0];
+					to->a = (channels >= 4)? from[3]: from[0];
 					to++; from += 4;
 				}
 			}
@@ -239,14 +239,14 @@
 			
 			for (int i = ibuf->y-1; i >= 0; i--) 
 			{
-				from= (unsigned char *)(ibuf->rect + i*width);
+				from= (unsigned char *)ibuf->rect + channels*i*width;
 				
 				for (int j = ibuf->x; j > 0; j--) 
 				{
 					to->r = (float)(from[0])/255.0;
-					to->g = (float)(from[1])/255.0;
-					to->b = (float)(from[2])/255.0;
-					to->a = (float)(from[3])/255.0;
+					to->g = (float)((channels >= 2)? from[1]: from[0])/255.0;
+					to->b = (float)((channels >= 3)? from[2]: from[0])/255.0;
+					to->a = (float)((channels >= 4)? from[3]: from[0])/255.0;
 					to++; from += 4;
 				}
 			}
@@ -272,7 +272,7 @@
 
 static short imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags)
 {
-	
+	int channels = ibuf->channels;
 	int width = ibuf->x;
 	int height = ibuf->y;
 	int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL;   // summarize
@@ -286,24 +286,29 @@
 		header.channels().insert ("R", Channel (FLOAT));
 		header.channels().insert ("G", Channel (FLOAT));
 		header.channels().insert ("B", Channel (FLOAT));
-		if (ibuf->depth==32)
+		if (ibuf->depth==32 && channels >= 4)
 			header.channels().insert ("A", Channel (FLOAT));
 		if (write_zbuf)
 			header.channels().insert ("Z", Channel (FLOAT));
 		
 		FrameBuffer frameBuffer;			
 		OutputFile *file = new OutputFile(name, header);			
-		float *first= ibuf->rect_float + 4*(height-1)*width;
-		int xstride = sizeof(float) * 4;
+		int xstride = sizeof(float) * channels;
 		int ystride = - xstride*width;
+		float *rect[4] = {NULL, NULL, NULL, NULL};
 
-		frameBuffer.insert ("R", Slice (FLOAT,  (char *) first, xstride, ystride));
-		frameBuffer.insert ("G", Slice (FLOAT,  (char *) (first+1), xstride, ystride));
-		frameBuffer.insert ("B", Slice (FLOAT,  (char *) (first+2), xstride, ystride));
-		if (ibuf->depth==32)
-			frameBuffer.insert ("A", Slice (FLOAT,  (char *) (first+3), xstride, ystride));
+		rect[0]= ibuf->rect_float + channels*(height-1)*width;
+		rect[1]= (channels >= 2)? rect[0]+1: rect[0];
+		rect[2]= (channels >= 3)? rect[0]+2: rect[0];
+		rect[3]= (channels >= 4)? rect[0]+3: rect[0];
+
+		frameBuffer.insert ("R", Slice (FLOAT,  (char *)rect[0], xstride, ystride));
+		frameBuffer.insert ("G", Slice (FLOAT,  (char *)rect[1], xstride, ystride));
+		frameBuffer.insert ("B", Slice (FLOAT,  (char *)rect[2], xstride, ystride));
+		if (ibuf->depth==32 && channels >= 4)
+			frameBuffer.insert ("A", Slice (FLOAT,  (char *)rect[3], xstride, ystride));
 		if (write_zbuf)
-			frameBuffer.insert ("Z", Slice (FLOAT, (char *) ibuf->zbuf_float + 4*(height-1)*width,
+			frameBuffer.insert ("Z", Slice (FLOAT, (char *) (ibuf->zbuf_float + (height-1)*width),
 											sizeof(float), sizeof(float) * -width));
 		file->setFrameBuffer (frameBuffer);				  
 		file->writePixels (height);					  

Modified: trunk/blender/source/blender/imbuf/intern/radiance_hdr.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/radiance_hdr.c	2008-04-29 16:22:13 UTC (rev 14615)
+++ trunk/blender/source/blender/imbuf/intern/radiance_hdr.c	2008-04-29 16:57:39 UTC (rev 14616)
@@ -251,7 +251,7 @@
 }
 
 /* ImBuf write */
-static int fwritecolrs(FILE* file, int width, unsigned char* ibufscan, float* fpscan)
+static int fwritecolrs(FILE* file, int width, int channels, unsigned char* ibufscan, float* fpscan)
 {
 	int x, i, j, beg, c2, cnt=0;
 	fCOLOR fcol;
@@ -266,16 +266,16 @@
 	for (i=0;i<width;i++) {
 		if (fpscan) {
 			fcol[RED] = fpscan[j];
-			fcol[GRN] = fpscan[j+1];
-			fcol[BLU] = fpscan[j+2];
+			fcol[GRN] = (channels >= 2)? fpscan[j+1]: fpscan[j];
+			fcol[BLU] = (channels >= 3)? fpscan[j+2]: fpscan[j];
 		} else {
 			fcol[RED] = (float)ibufscan[j] / 255.f;
-			fcol[GRN] = (float)ibufscan[j+1] / 255.f;
-			fcol[BLU] = (float)ibufscan[j+2] /255.f;
+			fcol[GRN] = (float)((channels >= 2)? ibufscan[j+1]: ibufscan[j]) / 255.f;
+			fcol[BLU] = (float)((channels >= 3)? ibufscan[j+2]: ibufscan[j]) / 255.f;
 		}
 		FLOAT2RGBE(fcol, rgbe);
 		copy_rgbe(rgbe, rgbe_scan[i]);
-		j+=4;
+		j+=channels;
 	}
 
 	if ((width < MINELEN) | (width > MAXELEN)) {	/* OOBs, write out flat */
@@ -348,18 +348,18 @@
 	writeHeader(file, width, height);
 
 	if(ibuf->rect)
-		cp= (unsigned char *)(ibuf->rect + (height-1)*width);
+		cp= (unsigned char *)ibuf->rect + ibuf->channels*(height-1)*width;
 	if(ibuf->rect_float)
-		fp= ibuf->rect_float + 4*(height-1)*width;
+		fp= ibuf->rect_float + ibuf->channels*(height-1)*width;
 	
 	for (y=height-1;y>=0;y--) {
-		if (fwritecolrs(file, width, cp, fp) < 0) {
+		if (fwritecolrs(file, width, ibuf->channels, cp, fp) < 0) {
 			fclose(file);
 			printf("HDR write error\n");
 			return 0;
 		}
-		if(cp) cp-= 4*width;
-		if(fp) fp-= 4*width;
+		if(cp) cp-= ibuf->channels*width;
+		if(fp) fp-= ibuf->channels*width;
 	}
 
 	fclose(file);





More information about the Bf-blender-cvs mailing list