[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