[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53460] trunk/blender: Alpha premul pipeline cleanup

Sergey Sharybin sergey.vfx at gmail.com
Mon Dec 31 14:52:18 CET 2012


Revision: 53460
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53460
Author:   nazgul
Date:     2012-12-31 13:52:13 +0000 (Mon, 31 Dec 2012)
Log Message:
-----------
Alpha premul pipeline cleanup

This assumptions are now made:
- Internally float buffers are always linear alpha-premul colors
- Readers should worry about delivering float buffers with that
  assumptions.
- There's an input image setting to say whether it's stored with
  straight/premul alpha on the disk.
- Byte buffers are now assumed have straight alpha, readers should
  deliver straight alpha.

Some implementation details:

- Removed scene's color unpremultiply setting, which was very
  much confusing and was wrong for default settings.
  Now all renderers assumes to deliver premultiplied alpha.

- IMB_buffer_byte_from_float will now linearize alpha when
  converting from buffer.

- Sequencer's effects were changed to assume bytes have got
  straight alpha. Most of effects will work with bytes still,
  however for glow it was more tricky to avoid data loss, so
  there's a commented out glow implementation which converts
  byte buffer to floats first, operates on floats and returns
  bytes back. It's slower and not sure if it should actually
  be used -- who're using glow on alpha anyway?

- Sequencer modifiers should also be working nice with straight
  bytes now.

- GLSL preview will predivide float textures to make nice shading,
  shading with byte textures worked nice (GLSL was assuming straight
  alpha).

- Blender Internal will set alpha=1 to the whole sky. The same
  happens in Cycles and there's no way to avoid this -- sky is
  neither straight nor premul and doesn't fit color pipeline well.

- Straight alpha mode for render result was also eliminated.

- Conversion to correct alpha need to be done before linearizing
  float buffer.

- TIFF will now load and save files with proper alpha mode setting
  in file meta data header.

- Remove Use Alpha from texture mapping and replaced with image
  datablock setting.

  Behaves much more predictable and clear from code point of view
  and solves possible regressions when non-premultiplied images were
  used as textures with ignoring alpha channel.

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/addon/properties.py
    trunk/blender/release/scripts/startup/bl_ui/properties_scene.py
    trunk/blender/release/scripts/startup/bl_ui/properties_texture.py
    trunk/blender/release/scripts/startup/bl_ui/space_sequencer.py
    trunk/blender/source/blender/blenkernel/BKE_blender.h
    trunk/blender/source/blender/blenkernel/intern/image.c
    trunk/blender/source/blender/blenkernel/intern/seqeffects.c
    trunk/blender/source/blender/blenkernel/intern/seqmodifier.c
    trunk/blender/source/blender/blenkernel/intern/sequencer.c
    trunk/blender/source/blender/blenkernel/intern/texture.c
    trunk/blender/source/blender/blenlib/BLI_math_color.h
    trunk/blender/source/blender/blenlib/intern/math_color_inline.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/versioning_legacy.c
    trunk/blender/source/blender/collada/DocumentImporter.cpp
    trunk/blender/source/blender/editors/render/render_preview.c
    trunk/blender/source/blender/editors/space_image/image_buttons.c
    trunk/blender/source/blender/gpu/intern/gpu_draw.c
    trunk/blender/source/blender/gpu/intern/gpu_material.c
    trunk/blender/source/blender/imbuf/IMB_colormanagement.h
    trunk/blender/source/blender/imbuf/IMB_imbuf.h
    trunk/blender/source/blender/imbuf/IMB_imbuf_types.h
    trunk/blender/source/blender/imbuf/intern/IMB_filter.h
    trunk/blender/source/blender/imbuf/intern/cineon/cineon_dpx.c
    trunk/blender/source/blender/imbuf/intern/colormanagement.c
    trunk/blender/source/blender/imbuf/intern/divers.c
    trunk/blender/source/blender/imbuf/intern/filter.c
    trunk/blender/source/blender/imbuf/intern/openexr/openexr_api.cpp
    trunk/blender/source/blender/imbuf/intern/png.c
    trunk/blender/source/blender/imbuf/intern/radiance_hdr.c
    trunk/blender/source/blender/imbuf/intern/readimage.c
    trunk/blender/source/blender/imbuf/intern/scaling.c
    trunk/blender/source/blender/imbuf/intern/tiff.c
    trunk/blender/source/blender/makesdna/DNA_image_types.h
    trunk/blender/source/blender/makesdna/DNA_scene_types.h
    trunk/blender/source/blender/makesdna/DNA_sequence_types.h
    trunk/blender/source/blender/makesdna/DNA_texture_types.h
    trunk/blender/source/blender/makesrna/intern/rna_image.c
    trunk/blender/source/blender/makesrna/intern/rna_scene.c
    trunk/blender/source/blender/makesrna/intern/rna_sequencer.c
    trunk/blender/source/blender/makesrna/intern/rna_texture.c
    trunk/blender/source/blender/nodes/composite/node_composite_util.c
    trunk/blender/source/blender/nodes/composite/nodes/node_composite_image.c
    trunk/blender/source/blender/render/intern/include/render_result.h
    trunk/blender/source/blender/render/intern/source/imagetexture.c
    trunk/blender/source/blender/render/intern/source/pipeline.c
    trunk/blender/source/blender/render/intern/source/render_result.c
    trunk/blender/source/blender/render/intern/source/rendercore.c

Modified: trunk/blender/intern/cycles/blender/addon/properties.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/properties.py	2012-12-31 13:07:06 UTC (rev 53459)
+++ trunk/blender/intern/cycles/blender/addon/properties.py	2012-12-31 13:52:13 UTC (rev 53460)
@@ -269,7 +269,7 @@
                 )
         cls.film_transparent = BoolProperty(
                 name="Transparent",
-                description="World background is transparent",
+                description="World background is transparent with premultiplied alpha",
                 default=False,
                 )
 

Modified: trunk/blender/release/scripts/startup/bl_ui/properties_scene.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/properties_scene.py	2012-12-31 13:07:06 UTC (rev 53459)
+++ trunk/blender/release/scripts/startup/bl_ui/properties_scene.py	2012-12-31 13:52:13 UTC (rev 53460)
@@ -263,7 +263,6 @@
         col.separator()
         col.label(text="Render:")
         col.template_colormanaged_view_settings(scene, "view_settings")
-        col.prop(rd, "use_color_unpremultiply")
 
         col = layout.column()
         col.separator()

Modified: trunk/blender/release/scripts/startup/bl_ui/properties_texture.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/properties_texture.py	2012-12-31 13:07:06 UTC (rev 53459)
+++ trunk/blender/release/scripts/startup/bl_ui/properties_texture.py	2012-12-31 13:52:13 UTC (rev 53460)
@@ -442,7 +442,6 @@
 
         col = split.column()
         col.label(text="Alpha:")
-        col.prop(tex, "use_alpha", text="Use")
         col.prop(tex, "use_calculate_alpha", text="Calculate")
         col.prop(tex, "invert_alpha", text="Invert")
         col.separator()

Modified: trunk/blender/release/scripts/startup/bl_ui/space_sequencer.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_sequencer.py	2012-12-31 13:07:06 UTC (rev 53459)
+++ trunk/blender/release/scripts/startup/bl_ui/space_sequencer.py	2012-12-31 13:52:13 UTC (rev 53460)
@@ -602,6 +602,7 @@
                 split.prop(elem, "filename", text="")  # strip.elements[0] could be a fallback
 
             layout.prop(strip.colorspace_settings, "name")
+            layout.prop(strip, "alpha_mode")
 
             layout.operator("sequencer.change_path")
 
@@ -797,7 +798,6 @@
         col.label(text="Colors:")
         col.prop(strip, "color_saturation", text="Saturation")
         col.prop(strip, "color_multiply", text="Multiply")
-        col.prop(strip, "use_premultiply")
         col.prop(strip, "use_float")
 
 

Modified: trunk/blender/source/blender/blenkernel/BKE_blender.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_blender.h	2012-12-31 13:07:06 UTC (rev 53459)
+++ trunk/blender/source/blender/blenkernel/BKE_blender.h	2012-12-31 13:52:13 UTC (rev 53460)
@@ -42,7 +42,7 @@
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         265
-#define BLENDER_SUBVERSION      4
+#define BLENDER_SUBVERSION      5
 
 /* 262 was the last editmesh release but it has compatibility code for bmesh data */
 #define BLENDER_MINVERSION      262

Modified: trunk/blender/source/blender/blenkernel/intern/image.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/image.c	2012-12-31 13:07:06 UTC (rev 53459)
+++ trunk/blender/source/blender/blenkernel/intern/image.c	2012-12-31 13:52:13 UTC (rev 53460)
@@ -312,10 +312,6 @@
 				break;
 
 		ibuf->index = index;
-		if (ima->flag & IMA_CM_PREDIVIDE)
-			ibuf->flags |= IB_cm_predivide;
-		else
-			ibuf->flags &= ~IB_cm_predivide;
 
 		/* this function accepts (link == NULL) */
 		BLI_insertlinkbefore(&ima->ibufs, link, ibuf);
@@ -552,6 +548,26 @@
 	return (ibuf != NULL);
 }
 
+static void image_init_color_management(Image *ima)
+{
+	ImBuf *ibuf;
+	char name[FILE_MAX];
+
+	BKE_image_user_file_path(NULL, ima, name);
+
+	/* will set input color space to image format default's */
+	ibuf = IMB_loadiffname(name, IB_test | IB_alphamode_detect, ima->colorspace_settings.name);
+
+	if (ibuf) {
+		if (ibuf->flags & IB_alphamode_premul)
+			ima->alpha_mode = IMA_ALPHA_PREMUL;
+		else
+			ima->alpha_mode = IMA_ALPHA_STRAIGHT;
+
+		IMB_freeImBuf(ibuf);
+	}
+}
+
 Image *BKE_image_load(const char *filepath)
 {
 	Image *ima;
@@ -579,6 +595,8 @@
 	if (BLI_testextensie_array(filepath, imb_ext_movie))
 		ima->source = IMA_SRC_MOVIE;
 
+	image_init_color_management(ima);
+
 	return ima;
 }
 
@@ -666,7 +684,7 @@
 		/* both byte and float buffers are filling in sRGB space, need to linearize float buffer after BKE_image_buf_fill* functions */
 
 		IMB_buffer_float_from_float(rect_float, rect_float, ibuf->channels, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB,
-		                            ibuf->flags & IB_cm_predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+		                            TRUE, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
 	}
 
 	return ibuf;
@@ -2343,7 +2361,7 @@
 static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
 {
 	const char *colorspace = ima->colorspace_settings.name;
-	int predivide = ima->flag & IMA_CM_PREDIVIDE;
+	int predivide = ima->alpha_mode == IMA_ALPHA_PREMUL;
 
 	ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y);
 
@@ -2375,6 +2393,18 @@
 
 }
 
+static int imbuf_alpha_flags_for_image(Image *ima)
+{
+	int flag = 0;
+
+	if (ima->flag & IMA_IGNORE_ALPHA)
+		flag |= IB_ignore_alpha;
+	else if (ima->alpha_mode == IMA_ALPHA_PREMUL)
+		flag |= IB_alphamode_premul;
+
+	return flag;
+}
+
 static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
 {
 	struct ImBuf *ibuf;
@@ -2389,8 +2419,7 @@
 	BKE_image_user_file_path(iuser, ima, name);
 
 	flag = IB_rect | IB_multilayer;
-	if (ima->flag & IMA_DO_PREMUL)
-		flag |= IB_premul;
+	flag |= imbuf_alpha_flags_for_image(ima);
 
 	/* read ibuf */
 	ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name);
@@ -2549,15 +2578,14 @@
 	/* is there a PackedFile with this image ? */
 	if (ima->packedfile) {
 		flag = IB_rect | IB_multilayer;
-		if (ima->flag & IMA_DO_PREMUL) flag |= IB_premul;
+		flag |= imbuf_alpha_flags_for_image(ima);
 
 		ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data, ima->packedfile->size, flag,
 		                             ima->colorspace_settings.name, "<packed data>");
 	}
 	else {
 		flag = IB_rect | IB_multilayer | IB_metadata;
-		if (ima->flag & IMA_DO_PREMUL)
-			flag |= IB_premul;
+		flag |= imbuf_alpha_flags_for_image(ima);
 
 		/* get the right string */
 		BKE_image_user_frame_calc(iuser, cfra, 0);
@@ -2777,15 +2805,6 @@
 
 	ibuf->dither = dither;
 
-	if (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) {
-		ibuf->flags |= IB_cm_predivide;
-		ima->flag |= IMA_CM_PREDIVIDE;
-	}
-	else {
-		ibuf->flags &= ~IB_cm_predivide;
-		ima->flag &= ~IMA_CM_PREDIVIDE;
-	}
-
 	ima->ok = IMA_OK_LOADED;
 
 	return ibuf;

Modified: trunk/blender/source/blender/blenkernel/intern/seqeffects.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/seqeffects.c	2012-12-31 13:07:06 UTC (rev 53459)
+++ trunk/blender/source/blender/blenkernel/intern/seqeffects.c	2012-12-31 13:52:13 UTC (rev 53460)
@@ -156,42 +156,43 @@
 	seq->seq1 = seq2;
 }
 
-static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,  char *rect1, char *rect2, char *out)
+static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y,  unsigned char *rect1, unsigned char *rect2, unsigned char *out)
 {
-	int fac2, mfac, fac, fac4;
-	int xo, tempc;
-	char *rt1, *rt2, *rt;
+	float fac2, mfac, fac, fac4;
+	int xo;
+	unsigned char *cp1, *cp2, *rt;
+	float tempc[4], rt1[4], rt2[4];
 
 	xo = x;
-	rt1 = (char *) rect1;
-	rt2 = (char *) rect2;
-	rt = (char *) out;
+	cp1 = rect1;
+	cp2 = rect2;
+	rt = out;
 
-	fac2 = (int) (256.0f * facf0);
-	fac4 = (int) (256.0f * facf1);
+	fac2 = facf0;
+	fac4 = facf1;
 
 	while (y--) {
 		x = xo;
 		while (x--) {
-
 			/* rt = rt1 over rt2  (alpha from rt1) */
 
+			straight_uchar_to_premul_float(rt1, cp1);
+			straight_uchar_to_premul_float(rt2, cp2);
+
 			fac = fac2;
-			mfac = 256 - ( (fac2 * rt1[3]) >> 8);
+			mfac = 1.0f - fac2 * rt1[3];
 
-			if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
-			else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
+			if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
+			else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
 			else {
-				tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
-				if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
-				tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
-				if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
-				tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;
-				if (tempc > 255) rt[2] = 255; else rt[2] = tempc;
-				tempc = (fac * rt1[3] + mfac * rt2[3]) >> 8;
-				if (tempc > 255) rt[3] = 255; else rt[3] = tempc;
+				tempc[0] = fac * rt1[0] + mfac * rt2[0];
+				tempc[1] = fac * rt1[1] + mfac * rt2[1];
+				tempc[2] = fac * rt1[2] + mfac * rt2[2];
+				tempc[3] = fac * rt1[3] + mfac * rt2[3];
+
+				premul_float_to_straight_uchar(rt, tempc);
 			}
-			rt1 += 4; rt2 += 4; rt += 4;
+			cp1 += 4; cp2 += 4; rt += 4;
 		}
 
 		if (y == 0) break;
@@ -199,22 +200,23 @@
 
 		x = xo;
 		while (x--) {
+			straight_uchar_to_premul_float(rt1, cp1);
+			straight_uchar_to_premul_float(rt2, cp2);
+
 			fac = fac4;
-			mfac = 256 - ( (fac4 * rt1[3]) >> 8);
+			mfac = 1.0f - (fac4 * rt1[3]);
 
-			if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
-			else if (mfac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
+			if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
+			else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
 			else {
-				tempc = (fac * rt1[0] + mfac * rt2[0]) >> 8;
-				if (tempc > 255) rt[0] = 255; else rt[0] = tempc;
-				tempc = (fac * rt1[1] + mfac * rt2[1]) >> 8;
-				if (tempc > 255) rt[1] = 255; else rt[1] = tempc;
-				tempc = (fac * rt1[2] + mfac * rt2[2]) >> 8;

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list