[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28027] trunk/blender: Patch [#21750] Add luma waveform and vectorscope to image view

Matt Ebb matt at mke3.net
Tue Apr 6 04:05:54 CEST 2010


Revision: 28027
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28027
Author:   broken
Date:     2010-04-06 04:05:54 +0200 (Tue, 06 Apr 2010)

Log Message:
-----------
Patch [#21750] Add luma waveform and vectorscope to image view
by Xavier Thomas

This adds the waveform monitor and vectorscope to the image editor 'scopes' 
region, bringing it inline (plus a bit more) with sequence editor functionality,
and a big step closer to the end goal of unifying the display code for image/
comp/sequence editor. It's non-intrusive, using the same code paths as 
the histogram.

There's still room for more tweaks - I modified the original patch, changing 
the openGL immediate mode drawing of the waveform display to vertex arrays for 
speed optimisation. Xavier can look at doing this for the vectorscope now too.

Thanks very much Xavier!

Modified Paths:
--------------
    trunk/blender/release/scripts/ui/space_image.py
    trunk/blender/source/blender/blenkernel/BKE_colortools.h
    trunk/blender/source/blender/blenkernel/intern/colortools.c
    trunk/blender/source/blender/blenlib/intern/math_color.c
    trunk/blender/source/blender/editors/include/UI_interface.h
    trunk/blender/source/blender/editors/interface/interface_draw.c
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/editors/interface/interface_intern.h
    trunk/blender/source/blender/editors/interface/interface_templates.c
    trunk/blender/source/blender/editors/interface/interface_widgets.c
    trunk/blender/source/blender/editors/space_image/image_ops.c
    trunk/blender/source/blender/editors/space_image/space_image.c
    trunk/blender/source/blender/makesdna/DNA_color_types.h
    trunk/blender/source/blender/makesdna/DNA_space_types.h
    trunk/blender/source/blender/makesrna/RNA_access.h
    trunk/blender/source/blender/makesrna/intern/rna_color.c
    trunk/blender/source/blender/makesrna/intern/rna_space.c
    trunk/blender/source/blender/makesrna/intern/rna_ui_api.c

Modified: trunk/blender/release/scripts/ui/space_image.py
===================================================================
--- trunk/blender/release/scripts/ui/space_image.py	2010-04-06 02:05:02 UTC (rev 28026)
+++ trunk/blender/release/scripts/ui/space_image.py	2010-04-06 02:05:54 UTC (rev 28027)
@@ -406,9 +406,44 @@
 
         sima = context.space_data
 
-        layout.template_histogram(sima, "histogram")
+        layout.template_histogram(sima.scopes, "histogram")
+        layout.prop(sima.scopes.histogram, "mode", icon_only=True)
 
+class IMAGE_PT_view_waveform(bpy.types.Panel):
+    bl_space_type = 'IMAGE_EDITOR'
+    bl_region_type = 'PREVIEW'
+    bl_label = "Waveform"
 
+    def poll(self, context):
+        sima = context.space_data
+        return (sima and sima.image)
+
+    def draw(self, context):
+        layout = self.layout
+
+        sima = context.space_data
+        layout.template_waveform(sima, "scopes")
+        sub = layout.row().split(percentage=0.75)
+        sub.prop(sima.scopes, "waveform_alpha")
+        sub.prop(sima.scopes, "waveform_mode", text="", icon_only=True)
+        
+
+class IMAGE_PT_view_vectorscope(bpy.types.Panel):
+    bl_space_type = 'IMAGE_EDITOR'
+    bl_region_type = 'PREVIEW'
+    bl_label = "Vectorscope"
+
+    def poll(self, context):
+        sima = context.space_data
+        return (sima and sima.image)
+
+    def draw(self, context):
+        layout = self.layout
+
+        sima = context.space_data
+        layout.template_vectorscope(sima, "scopes")
+        layout.prop(sima.scopes, "vectorscope_alpha")
+
 class IMAGE_PT_sample_line(bpy.types.Panel):
     bl_space_type = 'IMAGE_EDITOR'
     bl_region_type = 'PREVIEW'
@@ -423,8 +458,27 @@
         layout.operator("image.sample_line")
         sima = context.space_data
         layout.template_histogram(sima, "sample_histogram")
+        layout.prop(sima.sample_histogram, "mode")
 
+class IMAGE_PT_scope_sample(bpy.types.Panel):
+    bl_space_type = 'IMAGE_EDITOR'
+    bl_region_type = 'PREVIEW'
+    bl_label = "Scope Samples"
 
+    def poll(self, context):
+        sima = context.space_data
+        return sima 
+
+    def draw(self, context):
+        layout = self.layout
+        sima = context.space_data
+        split = layout.split()
+        row = split.row()
+        row.prop(sima.scopes, "use_full_resolution")
+        row = split.row()
+        row.active = not sima.scopes.use_full_resolution
+        row.prop(sima.scopes, "accuracy")
+
 class IMAGE_PT_view_properties(bpy.types.Panel):
     bl_space_type = 'IMAGE_EDITOR'
     bl_region_type = 'UI'
@@ -614,7 +668,10 @@
     IMAGE_PT_game_properties,
     IMAGE_PT_view_properties,
     IMAGE_PT_view_histogram,
-    IMAGE_PT_sample_line]
+    IMAGE_PT_view_waveform,
+    IMAGE_PT_view_vectorscope,
+    IMAGE_PT_sample_line,
+    IMAGE_PT_scope_sample]
 
 
 def register():

Modified: trunk/blender/source/blender/blenkernel/BKE_colortools.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_colortools.h	2010-04-06 02:05:02 UTC (rev 28026)
+++ trunk/blender/source/blender/blenkernel/BKE_colortools.h	2010-04-06 02:05:54 UTC (rev 28027)
@@ -31,7 +31,7 @@
 
 struct CurveMapping;
 struct CurveMap;
-struct Histogram;
+struct Scopes;
 struct ImBuf;
 struct rctf;
 
@@ -74,7 +74,8 @@
 void				curvemapping_table_RGBA(struct CurveMapping *cumap, float **array, int *size);
 void				colorcorrection_do_ibuf(struct ImBuf *ibuf, const char *profile);
 
-void				histogram_update(struct Histogram *hist, struct ImBuf *ibuf);
+void				scopes_update(struct Scopes *scopes, struct ImBuf *ibuf, int use_color_management);
+void				scopes_free(struct Scopes *scopes);
 
 #endif
 

Modified: trunk/blender/source/blender/blenkernel/intern/colortools.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/colortools.c	2010-04-06 02:05:02 UTC (rev 28026)
+++ trunk/blender/source/blender/blenkernel/intern/colortools.c	2010-04-06 02:05:54 UTC (rev 28027)
@@ -885,6 +885,8 @@
 
 /* ***************** Histogram **************** */
 
+#define INV_255		(1.f/255.f)
+
 DO_INLINE int get_bin_float(float f)
 {
 	int bin= (int)(f*255);
@@ -897,59 +899,219 @@
 	return bin;
 }
 
+DO_INLINE void save_sample_line(Scopes *scopes, const int idx, const float fx, float *rgb, float *ycc, float *ycc709)
+{
+	switch (scopes->wavefrm_mode) {
+		case SCOPES_WAVEFRM_RGB:
+			scopes->waveform_1[idx + 0] = fx;
+			scopes->waveform_1[idx + 1] = rgb[0];
+			scopes->waveform_2[idx + 0] = fx;
+			scopes->waveform_2[idx + 1] = rgb[1];
+			scopes->waveform_3[idx + 0] = fx;
+			scopes->waveform_3[idx + 1] = rgb[2];
+			break;
+		case SCOPES_WAVEFRM_LUM:
+			scopes->waveform_1[idx + 0] = fx;
+			scopes->waveform_1[idx + 1] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
+			break;
+		case SCOPES_WAVEFRM_YCC_JPEG:
+			scopes->waveform_1[idx + 0] = fx;
+			scopes->waveform_1[idx + 1] = ycc[0] * INV_255;
+			scopes->waveform_2[idx + 0] = fx;
+			scopes->waveform_2[idx + 1] = ycc[1] * INV_255;
+			scopes->waveform_3[idx + 0] = fx;
+			scopes->waveform_3[idx + 1] = ycc[2] * INV_255;
+			break;
+		case SCOPES_WAVEFRM_YCC_709:
+			scopes->waveform_1[idx + 0] = fx;
+			scopes->waveform_1[idx + 1] = ycc709[0] * INV_255;
+			scopes->waveform_2[idx + 0] = fx;
+			scopes->waveform_2[idx + 1] = ycc709[1] * INV_255;
+			scopes->waveform_3[idx + 0] = fx;
+			scopes->waveform_3[idx + 1] = ycc709[2] * INV_255;
+			break;
+		case SCOPES_WAVEFRM_YCC_601:
+		{
+			float ycc601[3];
+			rgb_to_ycc(rgb[0], rgb[1], rgb[2], &ycc601[0], &ycc601[1], &ycc601[2], BLI_YCC_ITU_BT601);
+			scopes->waveform_1[idx + 0] = fx;
+			scopes->waveform_1[idx + 1] = ycc601[0] * INV_255;
+			scopes->waveform_2[idx + 0] = fx;
+			scopes->waveform_2[idx + 1] = ycc601[1] * INV_255;
+			scopes->waveform_3[idx + 0] = fx;
+			scopes->waveform_3[idx + 1] = ycc601[2] * INV_255;
+		}
+			break;
+	}
+}
 
-void histogram_update(Histogram *hist, ImBuf *ibuf)
+void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
 {
-	int x, y, n;
-	double div;
-	float *rf;
-	unsigned char *rc;
-	unsigned int *bin_r, *bin_g, *bin_b;
-	
-	if (hist->ok == 1 ) return;
-	
-	if (hist->xmax == 0.f) hist->xmax = 1.f;
-	if (hist->ymax == 0.f) hist->ymax = 1.f;
-	
+	int x, y, c, n, nl;
+	double div, divl;
+	float *rf, *drf;
+	unsigned char *rc, *drc;
+	unsigned int *bin_r, *bin_g, *bin_b, *bin_lum;
+	int savedlines, saveline;
+	float rgb[3], ycc[3], ycc709[3];
+
+	if (scopes->ok == 1 ) return;
+
+	if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f;
+
 	/* hmmmm */
 	if (!(ELEM(ibuf->channels, 3, 4))) return;
-	
-	hist->channels = 3;
-	
+	scopes->hist.channels = 3;
+	scopes->hist.x_resolution = 256;
+
+	/* temp table to count pix value for histo */
 	bin_r = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
 	bin_g = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
 	bin_b = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
+	bin_lum = MEM_callocN(256 * sizeof(unsigned int), "temp historgram bins");
+
+	/* convert to number of lines with logarithmic scale */
+	scopes->sample_lines = (scopes->accuracy*0.01) * (scopes->accuracy*0.01) * ibuf->y;
 	
+	if (scopes->sample_full)
+		scopes->sample_lines = ibuf->y;
+
+	if( scopes->samples_ibuf) {
+		IMB_freeImBuf(scopes->samples_ibuf);
+		scopes->samples_ibuf=NULL;
+	}
+	/* scan the image */
+	savedlines=0;
+	for (c=0; c<3; c++) {
+		scopes->rgbminmax[c][0]=100.0f;
+		scopes->rgbminmax[c][1]=-100.0f;
+		scopes->yccminmax[c][0]=25500.0f;
+		scopes->yccminmax[c][1]=-25500.0f;
+		scopes->ycc709minmax[c][0]=25500.0f;
+		scopes->ycc709minmax[c][1]=-25500.0f;
+	}
+	
+	scopes->waveform_tot = ibuf->x*scopes->sample_lines;
+	
+	if (scopes->waveform_1)
+		MEM_freeN(scopes->waveform_1);
+	if (scopes->waveform_2)
+		MEM_freeN(scopes->waveform_2);
+	if (scopes->waveform_3)
+		MEM_freeN(scopes->waveform_3);
+	
+	scopes->waveform_1= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 1");
+	scopes->waveform_2= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 2");
+	scopes->waveform_3= MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "waveform point channel 3");
+	
 	if (ibuf->rect_float) {
-		hist->x_resolution = 256;
+		scopes->samples_ibuf = IMB_allocImBuf(ibuf->x, scopes->sample_lines, 32, IB_rectfloat, 0 );
+		rf = ibuf->rect_float;
+		drf= scopes->samples_ibuf->rect_float;
 		
-		/* divide into bins */
-		rf = ibuf->rect_float;
 		for (y = 0; y < ibuf->y; y++) {
+			if (savedlines<scopes->sample_lines && y>=((savedlines)*ibuf->y)/(scopes->sample_lines+1)) {
+				saveline=1;
+			} else saveline=0;
 			for (x = 0; x < ibuf->x; x++) {
-				bin_r[ get_bin_float(rf[0]) ] += 1;
-				bin_g[ get_bin_float(rf[1]) ] += 1;
-				bin_b[ get_bin_float(rf[2]) ] += 1;
+				
+				if (use_color_management)
+					linearrgb_to_srgb_v3_v3(rgb, rf);
+				else
+					copy_v3_v3(rgb, rf);
+
+				rgb_to_ycc(rgb[0],rgb[1],rgb[2],&ycc[0],&ycc[1],&ycc[2],BLI_YCC_JFIF_0_255);
+				rgb_to_ycc(rgb[0],rgb[1],rgb[2],&ycc709[0],&ycc709[1],&ycc709[2],BLI_YCC_ITU_BT709);
+				
+				/* check for min max */
+				for (c=0; c<3; c++) {
+					if (rgb[c] < scopes->rgbminmax[c][0]) scopes->rgbminmax[c][0] = rgb[c];
+					if (rgb[c] > scopes->rgbminmax[c][1]) scopes->rgbminmax[c][1] = rgb[c];
+					if (ycc[c] < scopes->yccminmax[c][0]) scopes->yccminmax[c][0] = ycc[c];
+					if (ycc[c] > scopes->yccminmax[c][1]) scopes->yccminmax[c][1] = ycc[c];
+					if (ycc709[c] < scopes->ycc709minmax[c][0]) scopes->ycc709minmax[c][0] = ycc709[c];
+					if (ycc709[c] > scopes->ycc709minmax[c][1]) scopes->ycc709minmax[c][1] = ycc709[c];
+				}
+				/* increment count for histo*/
+				bin_r[ get_bin_float(rgb[0]) ] += 1;
+				bin_g[ get_bin_float(rgb[1]) ] += 1;
+				bin_b[ get_bin_float(rgb[2]) ] += 1;
+				bin_lum[ get_bin_float(ycc[0] * INV_255) ] += 1;
+				
+				/* save sample if needed */
+				if(saveline) {
+					const float fx = (float)x / (float)ibuf->x;
+					const int idx = 2*(ibuf->x*savedlines+x);
+					
+					save_sample_line(scopes, idx, fx, rgb, ycc, ycc709);
+					
+					drf[0]=rgb[0];
+					drf[1]=rgb[1];
+					drf[2]=rgb[2];
+					drf+= scopes->samples_ibuf->channels;
+				}
 				rf+= ibuf->channels;
 			}
+			if (saveline)
+   				savedlines +=1;
 		}
+									   
 	}
 	else if (ibuf->rect) {
-		hist->x_resolution = 256;
-		

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list