Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/ui/space_image.py61
-rw-r--r--source/blender/blenkernel/BKE_colortools.h5
-rw-r--r--source/blender/blenkernel/intern/colortools.c249
-rw-r--r--source/blender/blenlib/intern/math_color.c4
-rw-r--r--source/blender/blenloader/intern/readfile.c24
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/interface/interface_draw.c463
-rw-r--r--source/blender/editors/interface/interface_handlers.c171
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_templates.c79
-rw-r--r--source/blender/editors/interface/interface_widgets.c8
-rw-r--r--source/blender/editors/space_image/image_ops.c25
-rw-r--r--source/blender/editors/space_image/space_image.c41
-rw-r--r--source/blender/makesdna/DNA_color_types.h43
-rw-r--r--source/blender/makesdna/DNA_space_types.h5
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_color.c72
-rw-r--r--source/blender/makesrna/intern/rna_space.c17
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c8
19 files changed, 1168 insertions, 114 deletions
diff --git a/release/scripts/ui/space_image.py b/release/scripts/ui/space_image.py
index 1c48b99939d..b29151563d3 100644
--- a/release/scripts/ui/space_image.py
+++ b/release/scripts/ui/space_image.py
@@ -406,8 +406,43 @@ class IMAGE_PT_view_histogram(bpy.types.Panel):
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'
@@ -423,7 +458,26 @@ class IMAGE_PT_sample_line(bpy.types.Panel):
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'
@@ -614,7 +668,10 @@ classes = [
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():
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index dca8ccb6dbf..f78389fe4de 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -31,7 +31,7 @@
struct CurveMapping;
struct CurveMap;
-struct Histogram;
+struct Scopes;
struct ImBuf;
struct rctf;
@@ -74,7 +74,8 @@ void curvemapping_initialize(struct CurveMapping *cumap);
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
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 4c0c10c127a..2da527d467a 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -885,6 +885,8 @@ void curvemapping_table_RGBA(CurveMapping *cumap, float **array, int *size)
/* ***************** 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 @@ DO_INLINE int get_bin_float(float f)
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;
-
- /* divide into bins */
+ scopes->samples_ibuf = IMB_allocImBuf(ibuf->x, scopes->sample_lines, 32, IB_rectfloat, 0 );
rf = ibuf->rect_float;
+ drf= scopes->samples_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;
-
+ scopes->samples_ibuf = IMB_allocImBuf(ibuf->x, scopes->sample_lines, 32, IB_rect, 0 );
rc = (unsigned char *)ibuf->rect;
+ drc= (unsigned char *) scopes->samples_ibuf->rect;
+
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++) {
+
+ for (c=0; c<3; c++)
+ rgb[c] = rc[c] * INV_255;
+ 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[ rc[0] ] += 1;
bin_g[ rc[1] ] += 1;
bin_b[ rc[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);
+
+ drc[0]=rc[0];
+ drc[1]=rc[1];
+ drc[2]=rc[2];
+ drc+= 4;
+ }
rc += ibuf->channels;
}
+ if (saveline)
+ savedlines +=1;
}
}
-
- /* convert to float */
+
+ /* convert hist data to float (proportional to max count) */
n=0;
+ nl=0;
for (x=0; x<256; x++) {
if (bin_r[x] > n)
n = bin_r[x];
@@ -957,17 +1119,42 @@ void histogram_update(Histogram *hist, ImBuf *ibuf)
n = bin_g[x];
if (bin_b[x] > n)
n = bin_b[x];
+ if (bin_lum[x] > nl)
+ nl = bin_lum[x];
}
div = 1.f/(double)n;
+ divl = 1.f/(double)nl;
for (x=0; x<256; x++) {
- hist->data_r[x] = bin_r[x] * div;
- hist->data_g[x] = bin_g[x] * div;
- hist->data_b[x] = bin_b[x] * div;
+ scopes->hist.data_r[x] = bin_r[x] * div;
+ scopes->hist.data_g[x] = bin_g[x] * div;
+ scopes->hist.data_b[x] = bin_b[x] * div;
+ scopes->hist.data_luma[x] = bin_lum[x] * divl;
}
-
MEM_freeN(bin_r);
MEM_freeN(bin_g);
MEM_freeN(bin_b);
-
- hist->ok=1;
+ MEM_freeN(bin_lum);
+
+ scopes->ok = 1;
}
+
+void scopes_free(Scopes *scopes)
+{
+ if (scopes->waveform_1) {
+ MEM_freeN(scopes->waveform_1);
+ scopes->waveform_1 = NULL;
+ }
+ if (scopes->waveform_2) {
+ MEM_freeN(scopes->waveform_2);
+ scopes->waveform_2 = NULL;
+ }
+ if (scopes->waveform_3) {
+ MEM_freeN(scopes->waveform_3);
+ scopes->waveform_3 = NULL;
+ }
+
+ if( scopes->samples_ibuf) {
+ IMB_freeImBuf(scopes->samples_ibuf);
+ scopes->samples_ibuf=NULL;
+ }
+} \ No newline at end of file
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 6aa85d14084..6637d74dbb1 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -110,7 +110,7 @@ void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb)
}
/* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f */
-/* Output YCC have a range of 16-235 and 16-240 exepect with JFIF_0_255 where the range is 0-255 */
+/* Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */
void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, int colorspace)
{
float sr,sg, sb;
@@ -132,7 +132,7 @@ void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, in
cr=(0.439f*sr)-(0.399f*sg)-(0.040f*sb)+128.0f;
break;
case BLI_YCC_JFIF_0_255 :
- y=(0.299f*sr)+(0.587f*sg)+(0.114f*sb)+16.0f;
+ y=(0.299f*sr)+(0.587f*sg)+(0.114f*sb);
cb=(-0.16874f*sr)-(0.33126f*sg)+(0.5f*sb)+128.0f;
cr=(0.5f*sr)-(0.41869f*sg)-(0.08131f*sb)+128.0f;
break;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 1f6d36dc957..6dcfb7f0ec7 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4836,6 +4836,9 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
SpaceImage *sima= (SpaceImage *)sl;
sima->image= restore_pointer_by_name(newmain, (ID *)sima->image, 1);
+
+ sima->scopes.samples_ibuf = NULL;
+ sima->scopes.ok = 0;
/* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data
* so assume that here we're doing for undo only...
@@ -5108,6 +5111,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sima->iuser.scene= NULL;
sima->iuser.ok= 1;
+ sima->scopes.samples_ibuf = NULL;
+ sima->scopes.ok = 0;
/* WARNING: gpencil data is no longer stored directly in sima after 2.5
* so sacrifice a few old files for now to avoid crashes with new files!
@@ -10731,7 +10736,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
/* put 2.50 compatibility code here until next subversion bump */
{
+ bScreen *sc;
+ /* Image editor scopes */
+ for(sc= main->screen.first; sc; sc= sc->id.next) {
+ ScrArea *sa;
+ for(sa= sc->areabase.first; sa; sa= sa->next) {
+ SpaceLink *sl;
+ for (sl= sa->spacedata.first; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+ sima->scopes.accuracy = 30.0;
+ sima->scopes.hist.mode=HISTO_MODE_RGB;
+ sima->scopes.wavefrm_alpha=0.3;
+ sima->scopes.vecscope_alpha=0.3;
+ sima->scopes.wavefrm_height= 100;
+ sima->scopes.hist.height= 100;
+ }
+ }
+ }
+ }
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index dfc89ea16df..110f69d7f02 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -218,6 +218,8 @@ typedef struct uiLayout uiLayout;
#define HOTKEYEVT (45<<9)
#define BUT_IMAGE (46<<9)
#define HISTOGRAM (47<<9)
+#define WAVEFORM (48<<9)
+#define VECTORSCOPE (49<<9)
#define BUTTYPE (63<<9)
@@ -676,6 +678,8 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot);
void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
void uiTemplateHistogram(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
+void uiTemplateWaveform(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
+void uiTemplateVectorscope(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, char *propname, int type, int levels, int brush);
void uiTemplateColorWheel(uiLayout *layout, struct PointerRNA *ptr, char *propname, int value_slider, int lock);
void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname);
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 893c479c7e9..574bb87f963 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -35,6 +35,7 @@
#include "BLI_math.h"
#include "BKE_colortools.h"
+#include "BKE_global.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -44,6 +45,8 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "BLF_api.h"
+
#include "UI_interface.h"
#include "interface_intern.h"
@@ -685,6 +688,38 @@ static void ui_draw_but_CHARTAB(uiBut *but)
#endif // INTERNATIONAL
#endif
+void histogram_draw_one(float r, float g, float b, float alpha, float x, float y, float w, float h, float *data, int res)
+{
+ int i;
+
+ /* under the curve */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ glColor4f(r, g, b, alpha);
+
+ glShadeModel(GL_FLAT);
+ glBegin(GL_QUAD_STRIP);
+ glVertex2f(x, y);
+ glVertex2f(x, y + (data[0]*h));
+ for (i=1; i < res; i++) {
+ float x2 = x + i * (w/(float)res);
+ glVertex2f(x2, y + (data[i]*h));
+ glVertex2f(x2, y);
+ }
+ glEnd();
+
+ /* curve outline */
+ glColor4f(0.f, 0.f, 0.f, 0.25f);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_LINE_SMOOTH);
+ glBegin(GL_LINE_STRIP);
+ for (i=0; i < res; i++) {
+ float x2 = x + i * (w/(float)res);
+ glVertex2f(x2, y + (data[i]*h));
+ }
+ glEnd();
+ glDisable(GL_LINE_SMOOTH);
+}
void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *recti)
{
@@ -692,10 +727,9 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *
int res = hist->x_resolution;
rctf rect;
int i;
- int rgb;
float w, h;
float scaler_x1, scaler_x2;
- float alpha;
+ //float alpha;
GLint scissor[4];
if (hist==NULL) { printf("hist is null \n"); return; }
@@ -726,43 +760,410 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *
/* need scissor test, histogram can draw outside of boundary */
glGetIntegerv(GL_VIEWPORT, scissor);
glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1));
+
+ if (hist->mode == HISTO_MODE_LUMA)
+ histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res);
+ else {
+ if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R)
+ histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res);
+ if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G)
+ histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res);
+ if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B)
+ histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res);
+ }
+ /* restore scissortest */
+ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ /* height scaling widget */
+ scaler_x1 = rect.xmin + w/2 - SCOPE_RESIZE_PAD;
+ scaler_x2 = rect.xmin + w/2 + SCOPE_RESIZE_PAD;
+
+ glColor4f(0.f, 0.f, 0.f, 0.25f);
+ fdrawline(scaler_x1, rect.ymin-4, scaler_x2, rect.ymin-4);
+ fdrawline(scaler_x1, rect.ymin-7, scaler_x2, rect.ymin-7);
+ glColor4f(1.f, 1.f, 1.f, 0.25f);
+ fdrawline(scaler_x1, rect.ymin-5, scaler_x2, rect.ymin-5);
+ fdrawline(scaler_x1, rect.ymin-8, scaler_x2, rect.ymin-8);
+
+ glColor4f(0.f, 0.f, 0.f, 0.5f);
+ uiSetRoundBox(15);
+ gl_round_box(GL_LINE_LOOP, rect.xmin-1, rect.ymin, rect.xmax+1, rect.ymax+1, 3.0f);
+
+ glDisable(GL_BLEND);
+}
+
+void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *recti)
+{
+ Scopes *scopes = (Scopes *)but->poin;
+ rctf rect;
+ int i, c;
+ float w, w3, h, alpha, yofs;
+ GLint scissor[4];
+ float colors[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
+ float colorsycc[3][3] = {{1,0,1},{1,1,0},{0,1,1}};
+ float colors_alpha[3][3], colorsycc_alpha[3][3]; /* colors pre multiplied by alpha for speed up */
+ float min, max;
+ float scaler_x1, scaler_x2;
+
+ if (scopes==NULL || scopes->samples_ibuf==NULL) return;
+
+ rect.xmin = (float)recti->xmin+1;
+ rect.xmax = (float)recti->xmax-1;
+ rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2;
+ rect.ymax = (float)recti->ymax-1;
+
+ if (scopes->wavefrm_yfac < 0.5f )
+ scopes->wavefrm_yfac =1.0f;
+ w = rect.xmax - rect.xmin-7;
+ h = (rect.ymax - rect.ymin)/scopes->wavefrm_yfac;
+ yofs= rect.ymin + (rect.ymax - rect.ymin -h)/2.0f;
+ w3=w/3.0f;
+
+ /* log scale for alpha */
+ alpha = scopes->wavefrm_alpha*scopes->wavefrm_alpha;
+
+ for(c=0; c<3; c++) {
+ for(i=0; i<3; i++) {
+ colors_alpha[c][i] = colors[c][i] * alpha;
+ colorsycc_alpha[c][i] = colorsycc[c][i] * alpha;
+ }
+ }
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ glColor4f(0.f, 0.f, 0.f, 0.3f);
+ uiSetRoundBox(15);
+ gl_round_box(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f);
+
+
+ /* need scissor test, histogram can draw outside of boundary */
+ glGetIntegerv(GL_VIEWPORT, scissor);
+ glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1));
+
+ glColor4f(1.f, 1.f, 1.f, 0.08f);
+ /* draw grid lines here */
+ for (i=0; i<6; i++) {
+ char str[4];
+ sprintf(str,"%-3d",i*20);
+ str[3]='\0';
+ fdrawline(rect.xmin+22, yofs+(i/5.f)*h, rect.xmax+1, yofs+(i/5.f)*h);
+ BLF_draw_default(rect.xmin+1, yofs-5+(i/5.f)*h, 0, str);
+ /* in the loop because blf_draw reset it */
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+ }
+ /* 3 vertical separation */
+ if (scopes->wavefrm_mode!= SCOPES_WAVEFRM_LUM) {
+ for (i=1; i<3; i++) {
+ fdrawline(rect.xmin+i*w3, rect.ymin, rect.xmin+i*w3, rect.ymax);
+ }
+ }
+ /* separate min max zone on the right */
+ fdrawline(rect.xmin+w, rect.ymin, rect.xmin+w, rect.ymax);
+ /* 16-235-240 level in case of ITU-R BT601/709 */
+ glColor4f(1.f, 0.4f, 0.f, 0.2f);
+ if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)){
+ fdrawline(rect.xmin+22, yofs+h*16.0f/255.0f, rect.xmax+1, yofs+h*16.0f/255.0f);
+ fdrawline(rect.xmin+22, yofs+h*235.0f/255.0f, rect.xmin+w3, yofs+h*235.0f/255.0f);
+ fdrawline(rect.xmin+3*w3, yofs+h*235.0f/255.0f, rect.xmax+1, yofs+h*235.0f/255.0f);
+ fdrawline(rect.xmin+w3, yofs+h*240.0f/255.0f, rect.xmax+1, yofs+h*240.0f/255.0f);
+ }
+
+
+ /* LUMA (1 channel) */
+ glBlendFunc(GL_ONE,GL_ONE);
+ glColor3f(alpha, alpha, alpha);
+ if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUM){
+
+ glBlendFunc(GL_ONE,GL_ONE);
- for (rgb=0; rgb<3; rgb++) {
- float *data = NULL;
+ glPushMatrix();
- if (rgb==0) data = hist->data_r;
- else if (rgb==1) data = hist->data_g;
- else if (rgb==2) data = hist->data_b;
+ glEnableClientState(GL_VERTEX_ARRAY);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- alpha = 0.75;
- if (rgb==0) glColor4f(1.f, 0.f, 0.f, alpha);
- else if (rgb==1) glColor4f(0.f, 1.f, 0.f, alpha);
- else if (rgb==2) glColor4f(0.f, 0.f, 1.f, alpha);
+ glTranslatef(rect.xmin, yofs, 0.f);
+ glScalef(w, h, 0.f);
- glShadeModel(GL_FLAT);
- glBegin(GL_QUAD_STRIP);
- glVertex2f(rect.xmin, rect.ymin);
- glVertex2f(rect.xmin, rect.ymin + (data[0]*h));
- for (i=1; i < res; i++) {
- float x = rect.xmin + i * (w/(float)res);
- glVertex2f(x, rect.ymin + (data[i]*h));
- glVertex2f(x, rect.ymin);
- }
- glEnd();
+ glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
+ glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ glPopMatrix();
+
+ /* min max */
+ glColor3f(.5f, .5f, .5f);
+ min= yofs+scopes->yccminmax[0][0]*h/255.0f;
+ max= yofs+scopes->yccminmax[0][1]*h/255.0f;
+ CLAMP(min, rect.ymin, rect.ymax);
+ CLAMP(max, rect.ymin, rect.ymax);
+ fdrawline(rect.xmax-3,min,rect.xmax-3,max);
+ }
+
+ /* RGB / YCC (3 channels) */
+ else if (ELEM4(scopes->wavefrm_mode, SCOPES_WAVEFRM_RGB, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709, SCOPES_WAVEFRM_YCC_JPEG)) {
+ int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB);
+
+ glBlendFunc(GL_ONE,GL_ONE);
- glColor4f(0.f, 0.f, 0.f, 0.25f);
+ glPushMatrix();
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ glTranslatef(rect.xmin, yofs, 0.f);
+ glScalef(w3, h, 0.f);
+
+ glColor3fv((rgb)?colors_alpha[0]:colorsycc_alpha[0]);
+
+ glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
+ glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+
+ glTranslatef(1.f, 0.f, 0.f);
+ glColor3fv((rgb)?colors_alpha[1]:colorsycc_alpha[1]);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_LINE_SMOOTH);
+ glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_2);
+ glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+
+ glTranslatef(1.f, 0.f, 0.f);
+ glColor3fv((rgb)?colors_alpha[2]:colorsycc_alpha[2]);
+
+ glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_3);
+ glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ glPopMatrix();
+
+
+ /* min max */
+ if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB) {
+ for (c=0; c<3; c++) {
+ glColor3f(colors[c][0]*0.75, colors[c][1]*0.75, colors[c][2]*0.75);
+ min= yofs+scopes->rgbminmax[c][0]*h;
+ max= yofs+scopes->rgbminmax[c][1]*h;
+ CLAMP(min, rect.ymin, rect.ymax);
+ CLAMP(max, rect.ymin, rect.ymax);
+ fdrawline(rect.xmin+w+2+c*2,min,rect.xmin+w+2+c*2,max);
+ }
+ } else {
+ if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_JPEG)) {
+ for (c=0; c<3; c++) {
+ glColor3f(colorsycc[c][0]*0.75, colorsycc[c][1]*0.75, colorsycc[c][2]*0.75);
+ /* we get ITU 601 min max from remapping JPEG*/
+ if (scopes->wavefrm_mode== SCOPES_WAVEFRM_YCC_601) {
+ if(c==0) {
+ min= yofs+(16+(219*scopes->yccminmax[c][0]/255))*h/255.0f;
+ max= yofs+(16+(219*scopes->yccminmax[c][1]/255))*h/255.0f;
+ }
+ else {
+ min= yofs+(16+(224*scopes->yccminmax[c][0]/255))*h/255.0f;
+ max= yofs+(16+(224*scopes->yccminmax[c][1]/255))*h/255.0f;
+ }
+ }
+ /* rescale ycc to 0-1*/
+ else {
+ min= yofs+scopes->yccminmax[c][0]*h/255.0f;
+ max= yofs+scopes->yccminmax[c][1]*h/255.0f;
+ }
+ CLAMP(min, rect.ymin, rect.ymax);
+ CLAMP(max, rect.ymin, rect.ymax);
+ fdrawline(rect.xmin+2+w+c*2,min,rect.xmin+2+w+c*2,max);
+ }
+ }
+ else if (scopes->wavefrm_mode== SCOPES_WAVEFRM_YCC_709) {
+ for (c=0; c<3; c++) {
+ glColor3f(colorsycc[c][0]*0.75, colorsycc[c][1]*0.75, colorsycc[c][2]*0.75);
+ min= yofs+scopes->ycc709minmax[c][0]*h/255.0f;
+ max= yofs+scopes->ycc709minmax[c][1]*h/255.0f;
+ CLAMP(min, rect.ymin, rect.ymax);
+ CLAMP(max, rect.ymin, rect.ymax);
+ fdrawline(rect.xmin+2+w+c*2,min,rect.xmin+2+w+c*2,max);
+ }
+ }
+ }
+ }
+
+ /* restore scissortest */
+ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ /* height scaling widget */
+ scaler_x1 = rect.xmin + w/2 - SCOPE_RESIZE_PAD;
+ scaler_x2 = rect.xmin + w/2 + SCOPE_RESIZE_PAD;
+
+ glColor4f(0.f, 0.f, 0.f, 0.25f);
+ fdrawline(scaler_x1, rect.ymin-4, scaler_x2, rect.ymin-4);
+ fdrawline(scaler_x1, rect.ymin-7, scaler_x2, rect.ymin-7);
+ glColor4f(1.f, 1.f, 1.f, 0.25f);
+ fdrawline(scaler_x1, rect.ymin-5, scaler_x2, rect.ymin-5);
+ fdrawline(scaler_x1, rect.ymin-8, scaler_x2, rect.ymin-8);
+
+ glColor4f(0.f, 0.f, 0.f, 0.5f);
+ uiSetRoundBox(15);
+ gl_round_box(GL_LINE_LOOP, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f);
+
+ glDisable(GL_BLEND);
+}
+
+float polar_to_x(float center, float diam, float ampli, float angle)
+{
+ return center + diam * ampli * cosf(angle);
+}
+
+float polar_to_y(float center, float diam, float ampli, float angle)
+{
+ return center + diam * ampli * sinf(angle);
+}
+
+void vectorscope_draw_target(float centerx, float centery, float diam, float r, float g, float b)
+{
+ float y,u,v;
+ float tangle, tampli;
+ float dangle, dampli, dangle2, dampli2;
+
+ rgb_to_yuv(r,g,b, &y, &u, &v);
+ if (u>0 && v>=0) tangle=atanf(v/u);
+ else if (u>0 && v<0) tangle=atanf(v/u)+2*M_PI;
+ else if (u<0) tangle=atanf(v/u)+M_PI;
+ else if (u==0 && v>0) tangle=M_PI/2.0f;
+ else if (u==0 && v<0) tangle=-M_PI/2.0f;
+ tampli= sqrtf(u*u+v*v);
+
+ /* small target vary by 2.5 degree and 2.5 IRE unit */
+ glColor4f(1.0f, 1.0f, 1.0, 0.12f);
+ dangle= 2.5*M_PI/180.0f;
+ dampli= 2.5f/200.0f;
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle+dangle), polar_to_y(centery,diam,tampli+dampli,tangle+dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle+dangle), polar_to_y(centery,diam,tampli-dampli,tangle+dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle-dangle), polar_to_y(centery,diam,tampli-dampli,tangle-dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle-dangle), polar_to_y(centery,diam,tampli+dampli,tangle-dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle+dangle), polar_to_y(centery,diam,tampli+dampli,tangle+dangle));
+ glEnd();
+ /* big target vary by 10 degree and 20% amplitude */
+ glColor4f(1.0f, 1.0f, 1.0, 0.12f);
+ dangle= 10*M_PI/180.0f;
+ dampli= 0.2*tampli;
+ dangle2= 5.0f*M_PI/180.0f;
+ dampli2= 0.5f*dampli;
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli-dampli2,tangle+dangle), polar_to_y(centery,diam,tampli+dampli-dampli2,tangle+dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle+dangle), polar_to_y(centery,diam,tampli+dampli,tangle+dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle+dangle-dangle2), polar_to_y(centery,diam,tampli+dampli,tangle+dangle-dangle2));
+ glEnd();
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(polar_to_x(centerx,diam,tampli-dampli+dampli2,tangle+dangle), polar_to_y(centery ,diam,tampli-dampli+dampli2,tangle+dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle+dangle), polar_to_y(centery,diam,tampli-dampli,tangle+dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle+dangle-dangle2), polar_to_y(centery,diam,tampli-dampli,tangle+dangle-dangle2));
+ glEnd();
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(polar_to_x(centerx,diam,tampli-dampli+dampli2,tangle-dangle), polar_to_y(centery,diam,tampli-dampli+dampli2,tangle-dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle-dangle), polar_to_y(centery,diam,tampli-dampli,tangle-dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle-dangle+dangle2), polar_to_y(centery,diam,tampli-dampli,tangle-dangle+dangle2));
+ glEnd();
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli-dampli2,tangle-dangle), polar_to_y(centery,diam,tampli+dampli-dampli2,tangle-dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle-dangle), polar_to_y(centery,diam,tampli+dampli,tangle-dangle));
+ glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle-dangle+dangle2), polar_to_y(centery,diam,tampli+dampli,tangle-dangle+dangle2));
+ glEnd();
+}
+
+void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *recti)
+{
+ Scopes *scopes = (Scopes *)but->poin;
+ rctf rect;
+ int i, j, x, y;
+ int skina= 123; /* angle in degree of the skin tone line */
+ float w, h, centerx, centery, diam;
+ float alpha;
+ float colors[6][3]={{.75,0,0},{.75,.75,0},{0,.75,0},{0,.75,.75},{0,0,.75},{.75,0,.75}};
+ unsigned char *rc;
+ float *rf;
+ GLint scissor[4];
+ float u, v;
+ float scaler_x1, scaler_x2;
+
+ if (scopes==NULL || scopes->samples_ibuf==NULL) return;
+
+ rect.xmin = (float)recti->xmin+1;
+ rect.xmax = (float)recti->xmax-1;
+ rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2;
+ rect.ymax = (float)recti->ymax-1;
+
+ w = rect.xmax - rect.xmin;
+ h = rect.ymax - rect.ymin;
+ centerx = rect.xmin + w/2;
+ centery = rect.ymin + h/2;
+ diam= h;
+ if (w<diam) diam=w;
+
+ alpha = scopes->vecscope_alpha*scopes->vecscope_alpha*scopes->vecscope_alpha;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ glColor4f(0.f, 0.f, 0.f, 0.3f);
+ uiSetRoundBox(15);
+ gl_round_box(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f);
+
+ /* need scissor test, hvectorscope can draw outside of boundary */
+ glGetIntegerv(GL_VIEWPORT, scissor);
+ glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1));
+
+ glColor4f(1.f, 1.f, 1.f, 0.08f);
+ /* draw grid elements */
+ /* cross */
+ fdrawline(centerx - (diam/2)-5, centery, centerx + (diam/2)+5, centery);
+ fdrawline(centerx, centery - (diam/2)-5, centerx, centery + (diam/2)+5);
+ /* circles */
+ for(j=0; j<5; j++) {
glBegin(GL_LINE_STRIP);
- for (i=0; i < res; i++) {
- float x = rect.xmin + i * (w/(float)res);
- glVertex2f(x, rect.ymin + (data[i]*h));
+ for(i=0; i<=360; i=i+15) {
+ float a= i*M_PI/180.0;
+ float r= (j+1)/10.0f;
+ glVertex2f( polar_to_x(centerx,diam,r,a), polar_to_y(centery,diam,r,a));
}
glEnd();
- glDisable(GL_LINE_SMOOTH);
}
+ /* skin tone line */
+ glColor4f(1.f, 0.4f, 0.f, 0.2f);
+ fdrawline( polar_to_x(centerx, diam, 0.5f, skina*M_PI/180.0), polar_to_y(centery,diam,0.5,skina*M_PI/180.0),
+ polar_to_x(centerx, diam, 0.1f, skina*M_PI/180.0), polar_to_y(centery,diam,0.1,skina*M_PI/180.0));
+ /* saturation points */
+ for(i=0; i<6; i++)
+ vectorscope_draw_target(centerx, centery, diam, colors[i][0], colors[i][1], colors[i][2]);
+
+ /* pixel point cloud */
+ glBlendFunc(GL_ONE,GL_ONE);
+ glBegin(GL_POINTS);
+ glColor4f(alpha, alpha, alpha, alpha);
+ if (scopes->samples_ibuf->rect_float) {
+ rf = scopes->samples_ibuf->rect_float;
+ for (y=0; y<scopes->samples_ibuf->y; y++) {
+ for (x=0; x<scopes->samples_ibuf->x; x++) {
+ u=-0.147f*rf[0] - 0.289f*rf[1] + 0.436f*rf[2];
+ v= 0.615f*rf[0] - 0.515f*rf[1] - 0.100f*rf[2];
+ glVertex2f(centerx+u*diam, centery+v*diam);
+ rf+=scopes->samples_ibuf->channels;
+ }
+ }
+ }
+ else if(scopes->samples_ibuf->rect) {
+ rc = (unsigned char *)(scopes->samples_ibuf->rect);
+ for (y=0; y<scopes->samples_ibuf->y; y++) {
+ for (x=0; x<scopes->samples_ibuf->x; x++) {
+ u=-0.147f*rc[0]/255.0f - 0.289f*rc[1]/255.0f + 0.436f*rc[2]/255.0f;
+ v= 0.615f*rc[0]/255.0f - 0.515f*rc[1]/255.0f - 0.100f*rc[2]/255.0f;
+ glVertex2f(centerx+u*diam, centery+v*diam);
+ rc+=4;
+ }
+ }
+ }
+ glEnd();
/* restore scissortest */
@@ -773,7 +1174,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *
/* height scaling widget */
scaler_x1 = rect.xmin + w/2 - SCOPE_RESIZE_PAD;
scaler_x2 = rect.xmin + w/2 + SCOPE_RESIZE_PAD;
-
+
glColor4f(0.f, 0.f, 0.f, 0.25f);
fdrawline(scaler_x1, rect.ymin-4, scaler_x2, rect.ymin-4);
fdrawline(scaler_x1, rect.ymin-7, scaler_x2, rect.ymin-7);
@@ -781,7 +1182,6 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *
fdrawline(scaler_x1, rect.ymin-5, scaler_x2, rect.ymin-5);
fdrawline(scaler_x1, rect.ymin-8, scaler_x2, rect.ymin-8);
-
glColor4f(0.f, 0.f, 0.f, 0.5f);
uiSetRoundBox(15);
gl_round_box(GL_LINE_LOOP, rect.xmin-1, rect.ymin, rect.xmax+1, rect.ymax+1, 3.0f);
@@ -789,7 +1189,6 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *
glDisable(GL_BLEND);
}
-
void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *wcol, rcti *rect)
{
ColorBand *coba;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index fc69fc6fafa..9bd29532628 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -801,6 +801,14 @@ static void ui_apply_but_HISTOGRAM(bContext *C, uiBut *but, uiHandleButtonData *
data->applied= 1;
}
+static void ui_apply_but_WAVEFORM(bContext *C, uiBut *but, uiHandleButtonData *data)
+{
+ ui_apply_but_func(C, but);
+ data->retval= but->retval;
+ data->applied= 1;
+}
+
+
static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, int interactive)
{
char *editstr;
@@ -926,6 +934,9 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
case HISTOGRAM:
ui_apply_but_HISTOGRAM(C, but, data);
break;
+ case WAVEFORM:
+ ui_apply_but_WAVEFORM(C, but, data);
+ break;
default:
break;
}
@@ -3460,7 +3471,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt
return WM_UI_HANDLER_CONTINUE;
}
-static int in_histogram_resize_zone(uiBut *but, int x, int y)
+static int in_scope_resize_zone(uiBut *but, int x, int y)
{
// bottom corner return (x > but->x2 - SCOPE_RESIZE_PAD) && (y < but->y1 + SCOPE_RESIZE_PAD);
return (y < but->y1 + SCOPE_RESIZE_PAD);
@@ -3480,7 +3491,7 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx
dy = my - data->draglasty;
- if (in_histogram_resize_zone(but, data->dragstartx, data->dragstarty)) {
+ if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
/* resize histogram widget itself */
hist->height = (but->y2 - but->y1) + (data->dragstarty - my);
} else {
@@ -3548,6 +3559,156 @@ static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandle
return WM_UI_HANDLER_CONTINUE;
}
+static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, int my)
+{
+ Scopes *scopes = (Scopes *)but->poin;
+ rcti rect;
+ int changed= 1;
+ float dx, dy, yfac=1.f;
+
+ rect.xmin= but->x1; rect.xmax= but->x2;
+ rect.ymin= but->y1; rect.ymax= but->y2;
+
+ dx = mx - data->draglastx;
+ dy = my - data->draglasty;
+
+
+ if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
+ /* resize waveform widget itself */
+ scopes->wavefrm_height = (but->y2 - but->y1) + (data->dragstarty - my);
+ } else {
+ /* scale waveform values */
+ yfac = scopes->wavefrm_yfac;
+ scopes->wavefrm_yfac += dy/200.0f;
+
+ CLAMP(scopes->wavefrm_yfac, 0.5f, 2.f);
+ }
+
+ data->draglastx= mx;
+ data->draglasty= my;
+
+ return changed;
+}
+
+static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+ int mx, my;
+
+ mx= event->x;
+ my= event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if(data->state == BUTTON_STATE_HIGHLIGHT) {
+ if(event->type==LEFTMOUSE && event->val==KM_PRESS) {
+ data->dragstartx= mx;
+ data->dragstarty= my;
+ data->draglastx= mx;
+ data->draglasty= my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ /* also do drag the first time */
+ if(ui_numedit_but_WAVEFORM(but, data, mx, my))
+ ui_numedit_apply(C, block, but, data);
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if (event->type == ZEROKEY && event->val == KM_PRESS) {
+ Scopes *scopes = (Scopes *)but->poin;
+ scopes->wavefrm_yfac = 1.f;
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if(data->state == BUTTON_STATE_NUM_EDITING) {
+ if(event->type == ESCKEY) {
+ data->cancel= 1;
+ data->escapecancel= 1;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if(event->type == MOUSEMOVE) {
+ if(mx!=data->draglastx || my!=data->draglasty) {
+ if(ui_numedit_but_WAVEFORM(but, data, mx, my))
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ else if(event->type==LEFTMOUSE && event->val!=KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
+static int ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int mx, int my)
+{
+ Scopes *scopes = (Scopes *)but->poin;
+ rcti rect;
+ int changed= 1;
+ float dx, dy;
+
+ rect.xmin= but->x1; rect.xmax= but->x2;
+ rect.ymin= but->y1; rect.ymax= but->y2;
+
+ dx = mx - data->draglastx;
+ dy = my - data->draglasty;
+
+ if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) {
+ /* resize vectorscope widget itself */
+ scopes->vecscope_height = (but->y2 - but->y1) + (data->dragstarty - my);
+ }
+
+ data->draglastx= mx;
+ data->draglasty= my;
+
+ return changed;
+}
+
+static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
+{
+ int mx, my;
+
+ mx= event->x;
+ my= event->y;
+ ui_window_to_block(data->region, block, &mx, &my);
+
+ if(data->state == BUTTON_STATE_HIGHLIGHT) {
+ if(event->type==LEFTMOUSE && event->val==KM_PRESS) {
+ data->dragstartx= mx;
+ data->dragstarty= my;
+ data->draglastx= mx;
+ data->draglasty= my;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ /* also do drag the first time */
+ if(ui_numedit_but_VECTORSCOPE(but, data, mx, my))
+ ui_numedit_apply(C, block, but, data);
+
+ return WM_UI_HANDLER_BREAK;
+ }
+ }
+ else if(data->state == BUTTON_STATE_NUM_EDITING) {
+ if(event->type == ESCKEY) {
+ data->cancel= 1;
+ data->escapecancel= 1;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else if(event->type == MOUSEMOVE) {
+ if(mx!=data->draglastx || my!=data->draglasty) {
+ if(ui_numedit_but_VECTORSCOPE(but, data, mx, my))
+ ui_numedit_apply(C, block, but, data);
+ }
+ }
+ else if(event->type==LEFTMOUSE && event->val!=KM_PRESS) {
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ return WM_UI_HANDLER_BREAK;
+ }
+
+ return WM_UI_HANDLER_CONTINUE;
+}
+
#ifdef INTERNATIONAL
static int ui_do_but_CHARTAB(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event)
{
@@ -4137,6 +4298,12 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
case HISTOGRAM:
retval= ui_do_but_HISTOGRAM(C, block, but, data, event);
break;
+ case WAVEFORM:
+ retval= ui_do_but_WAVEFORM(C, block, but, data, event);
+ break;
+ case VECTORSCOPE:
+ retval= ui_do_but_VECTORSCOPE(C, block, but, data, event);
+ break;
case TEX:
case IDPOIN:
case SEARCH_MENU:
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index f90b711cc09..77f18115c73 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -443,6 +443,8 @@ extern void gl_round_box_vertical_shade(int mode, float minx, float miny, float
void ui_draw_gradient(rcti *rect, float *rgb, int type, float alpha);
void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
+void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
+void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
void ui_draw_but_COLORBAND(uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
void ui_draw_but_NORMAL(uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
void ui_draw_but_CURVE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 200ef1fa501..bf7ab9fcdce 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1596,12 +1596,85 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, char *propname, int
block= uiLayoutAbsoluteBlock(layout);
//colorband_buttons_layout(layout, block, cptr.data, &rect, !expand, cb);
-
+
hist = (Histogram *)cptr.data;
+
+ hist->height= (hist->height<=0)?100:hist->height;
+
+ bt= uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, hist->height, hist, 0, 0, 0, 0, "");
+ uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
+
+ MEM_freeN(cb);
+}
+
+/********************* Waveform Template ************************/
+
+void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, char *propname, int expand)
+{
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ RNAUpdateCb *cb;
+ uiBlock *block;
+ uiBut *bt;
+ Scopes *scopes;
+ rctf rect;
+
+ if(!prop || RNA_property_type(prop) != PROP_POINTER)
+ return;
- hist->height= (hist->height==0)?100:hist->height;
+ cptr= RNA_property_pointer_get(ptr, prop);
+ if(!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes))
+ return;
+ scopes = (Scopes *)cptr.data;
+
+ cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr= *ptr;
+ cb->prop= prop;
+
+ rect.xmin= 0; rect.xmax= 200;
+ rect.ymin= 0; rect.ymax= 190;
+
+ block= uiLayoutAbsoluteBlock(layout);
+
+ scopes->wavefrm_height= (scopes->wavefrm_height<=0)?100:scopes->wavefrm_height;
+
+ bt= uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->wavefrm_height, scopes, 0, 0, 0, 0, "");
+
+ MEM_freeN(cb);
+}
+
+/********************* Vectorscope Template ************************/
+
+void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, char *propname, int expand)
+{
+ PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
+ PointerRNA cptr;
+ RNAUpdateCb *cb;
+ uiBlock *block;
+ uiBut *bt;
+ Scopes *scopes;
+ rctf rect;
+
+ if(!prop || RNA_property_type(prop) != PROP_POINTER)
+ return;
+
+ cptr= RNA_property_pointer_get(ptr, prop);
+ if(!cptr.data || !RNA_struct_is_a(cptr.type, &RNA_Scopes))
+ return;
+ scopes = (Scopes *)cptr.data;
+
+ cb= MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr= *ptr;
+ cb->prop= prop;
+
+ rect.xmin= 0; rect.xmax= 200;
+ rect.ymin= 0; rect.ymax= 190;
+
+ block= uiLayoutAbsoluteBlock(layout);
+
+ scopes->vecscope_height= (scopes->vecscope_height<=0)?100:scopes->vecscope_height;
- bt= uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, hist->height, hist, 0, 0, 0, 0, "");
+ bt= uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
MEM_freeN(cb);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 1c75a05e084..af990214686 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2727,6 +2727,14 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
ui_draw_but_HISTOGRAM(ar, but, &tui->wcol_regular, rect);
break;
+ case WAVEFORM:
+ ui_draw_but_WAVEFORM(ar, but, &tui->wcol_regular, rect);
+ break;
+
+ case VECTORSCOPE:
+ ui_draw_but_VECTORSCOPE(ar, but, &tui->wcol_regular, rect);
+ break;
+
case BUT_CURVE:
ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
break;
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index c9daeb09f25..55e6ac356c6 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -177,7 +177,7 @@ static void view_pan_exit(bContext *C, wmOperator *op, int cancel)
if(cancel) {
sima->xof= vpd->xof;
sima->yof= vpd->yof;
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
}
WM_cursor_restore(CTX_wm_window(C));
@@ -193,7 +193,7 @@ static int view_pan_exec(bContext *C, wmOperator *op)
sima->xof += offset[0];
sima->yof += offset[1];
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
/* XXX notifier? */
#if 0
@@ -309,7 +309,7 @@ static void view_zoom_exit(bContext *C, wmOperator *op, int cancel)
if(cancel) {
sima->zoom= vpd->zoom;
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
}
WM_cursor_restore(CTX_wm_window(C));
@@ -323,7 +323,7 @@ static int view_zoom_exec(bContext *C, wmOperator *op)
sima_zoom_set_factor(sima, ar, RNA_float_get(op->ptr, "factor"));
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
/* XXX notifier? */
#if 0
@@ -347,7 +347,7 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
factor= 1.0 + (event->x-event->prevx+event->y-event->prevy)/300.0f;
RNA_float_set(op->ptr, "factor", factor);
sima_zoom_set(sima, ar, sima->zoom*factor);
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -369,7 +369,7 @@ static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
factor= 1.0 + (vpd->x-event->x+vpd->y-event->y)/300.0f;
RNA_float_set(op->ptr, "factor", factor);
sima_zoom_set(sima, ar, vpd->zoom*factor);
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
break;
case MIDDLEMOUSE:
case LEFTMOUSE:
@@ -452,7 +452,7 @@ static int view_all_exec(bContext *C, wmOperator *op)
sima->xof= sima->yof= 0.0f;
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -504,7 +504,7 @@ static int view_selected_exec(bContext *C, wmOperator *op)
if(size<=0.01) size= 0.01;
sima_zoom_set(sima, ar, 0.7/size);
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -529,7 +529,7 @@ static int view_zoom_in_exec(bContext *C, wmOperator *op)
sima_zoom_set_factor(sima, ar, 1.25f);
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -552,7 +552,7 @@ static int view_zoom_out_exec(bContext *C, wmOperator *op)
sima_zoom_set_factor(sima, ar, 0.8f);
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -590,7 +590,7 @@ static int view_zoom_ratio_exec(bContext *C, wmOperator *op)
}
#endif
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_region_tag_redraw(CTX_wm_region(C));
return OPERATOR_FINISHED;
}
@@ -1688,16 +1688,17 @@ static int sample_line_exec(bContext *C, wmOperator *op)
hist->data_r[i] = fp[0];
hist->data_g[i] = fp[1];
hist->data_b[i] = fp[2];
+ hist->data_luma[i] = (0.299f*fp[0] + 0.587f*fp[1] + 0.114f*fp[2]);
}
else if (ibuf->rect) {
cp= (unsigned char *)(ibuf->rect + y*ibuf->x + x);
hist->data_r[i] = (float)cp[0]/255.0f;
hist->data_g[i] = (float)cp[1]/255.0f;
hist->data_b[i] = (float)cp[2]/255.0f;
+ hist->data_luma[i] = (0.299f*cp[0] + 0.587f*cp[1] + 0.114f*cp[2])/255;
}
}
}
- hist->ok=1;
ED_space_image_release_buffer(sima, lock);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 0eb377450e9..45903c8079d 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -47,6 +47,7 @@
#include "BKE_screen.h"
#include "BKE_utildefines.h"
+#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "ED_mesh.h"
@@ -98,6 +99,7 @@ void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obe
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
ED_area_tag_redraw(CTX_wm_area(C));
+
}
}
@@ -289,21 +291,21 @@ int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
}
-
-static void image_histogram_tag_refresh(ScrArea *sa)
+static void image_scopes_tag_refresh(ScrArea *sa)
{
SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
ARegion *ar;
-
+
/* only while histogram is visible */
for (ar=sa->regionbase.first; ar; ar=ar->next) {
if (ar->regiontype == RGN_TYPE_PREVIEW && ar->flag & RGN_FLAG_HIDDEN)
return;
}
-
- sima->hist.ok=0;
+
+ sima->scopes.ok=0;
}
+
/* ******************** manage regions ********************* */
ARegion *image_has_buttons_region(ScrArea *sa)
@@ -356,8 +358,8 @@ ARegion *image_has_scope_region(ScrArea *sa)
arnew->alignment= RGN_ALIGN_RIGHT;
arnew->flag = RGN_FLAG_HIDDEN;
-
- image_histogram_tag_refresh(sa);
+
+ image_scopes_tag_refresh(sa);
return arnew;
}
@@ -400,6 +402,13 @@ static SpaceLink *image_new(const bContext *C)
ar->regiontype= RGN_TYPE_PREVIEW;
ar->alignment= RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
+
+ simage->scopes.accuracy=30.0;
+ simage->scopes.hist.mode=HISTO_MODE_RGB;
+ simage->scopes.wavefrm_alpha=0.3;
+ simage->scopes.vecscope_alpha=0.3;
+ simage->scopes.wavefrm_height= 100;
+ simage->scopes.hist.height= 100;
/* main area */
ar= MEM_callocN(sizeof(ARegion), "main area for image");
@@ -417,9 +426,7 @@ static void image_free(SpaceLink *sl)
if(simage->cumap)
curvemapping_free(simage->cumap);
-// if(simage->gpd)
-// XXX free_gpencil_data(simage->gpd);
-
+ scopes_free(&simage->scopes);
}
@@ -590,7 +597,7 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn)
case NC_SCENE:
switch(wmn->data) {
case ND_FRAME:
- image_histogram_tag_refresh(sa);
+ image_scopes_tag_refresh(sa);
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
break;
@@ -598,7 +605,7 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn)
case ND_RENDER_RESULT:
case ND_COMPO_RESULT:
if (ED_space_image_show_render(sima))
- image_histogram_tag_refresh(sa);
+ image_scopes_tag_refresh(sa);
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
break;
@@ -606,14 +613,14 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn)
break;
case NC_IMAGE:
if (wmn->reference == sima->image || !wmn->reference) {
- image_histogram_tag_refresh(sa);
+ image_scopes_tag_refresh(sa);
ED_area_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
break;
case NC_SPACE:
if(wmn->data == ND_SPACE_IMAGE) {
- image_histogram_tag_refresh(sa);
+ image_scopes_tag_refresh(sa);
ED_area_tag_redraw(sa);
}
break;
@@ -837,10 +844,12 @@ static void image_scope_area_init(wmWindowManager *wm, ARegion *ar)
static void image_scope_area_draw(const bContext *C, ARegion *ar)
{
SpaceImage *sima= CTX_wm_space_image(C);
+ Scene *scene= CTX_data_scene(C);
void *lock;
ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock);
- if(ibuf)
- histogram_update(&sima->hist, ibuf);
+ if(ibuf) {
+ scopes_update(&sima->scopes, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT );
+ }
ED_space_image_release_buffer(sima, lock);
ED_region_panels(C, ar, 1, NULL, -1);
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index 2a6dcfcb64e..dd31c349615 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -90,18 +90,57 @@ typedef enum CurveMappingPreset {
CURVE_PRESET_MID9
} CurveMappingPreset;
+/* histogram->mode */
+#define HISTO_MODE_LUMA 0
+#define HISTO_MODE_RGB 1
+#define HISTO_MODE_R 2
+#define HISTO_MODE_G 3
+#define HISTO_MODE_B 4
+
typedef struct Histogram {
int channels;
int x_resolution;
float data_r[256];
float data_g[256];
float data_b[256];
+ float data_luma[256];
float xmax, ymax;
+ int mode;
int height;
+} Histogram;
+
+struct ImBuf;
+
+typedef struct Scopes {
int ok;
- int flag;
+ int sample_full;
+ int sample_lines;
+ float accuracy;
+ int wavefrm_mode;
+ float wavefrm_alpha;
+ float wavefrm_yfac;
+ int wavefrm_height;
+ float vecscope_alpha;
+ int vecscope_height;
+ float rgbminmax[3][2];
+ float yccminmax[3][2];
+ float ycc709minmax[3][2];
+ struct ImBuf *samples_ibuf;
+ struct Histogram hist;
+ float *waveform_1;
+ float *waveform_2;
+ float *waveform_3;
+ int waveform_tot;
int pad;
-} Histogram;
+} Scopes;
+
+/* scopes->wavefrm_mode */
+#define SCOPES_WAVEFRM_LUM 0
+#define SCOPES_WAVEFRM_RGB 1
+#define SCOPES_WAVEFRM_YCC_601 2
+#define SCOPES_WAVEFRM_YCC_709 3
+#define SCOPES_WAVEFRM_YCC_JPEG 4
+
#endif
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 00ade3156c5..6cb22f3b08f 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -44,6 +44,7 @@ struct Text;
struct Script;
struct ImBuf;
struct Image;
+struct Scopes;
struct Histogram;
struct SpaceIpo;
struct BlendHandle;
@@ -260,8 +261,10 @@ typedef struct SpaceImage {
struct bGPdata *gpd; /* grease pencil data */
- struct Histogram hist; /* viewer histogram */
+ struct Scopes scopes; /* histogram waveform and vectorscope */
+
struct Histogram sample_line_hist; /* sample line histogram */
+
} SpaceImage;
typedef struct SpaceNla {
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index e72c5eb9a4d..3ee251c4437 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -383,6 +383,7 @@ extern StructRNA RNA_Scene;
extern StructRNA RNA_SceneGameData;
extern StructRNA RNA_SceneRenderLayer;
extern StructRNA RNA_SceneSequence;
+extern StructRNA RNA_Scopes;
extern StructRNA RNA_Screen;
extern StructRNA RNA_ScrewModifier;
extern StructRNA RNA_Sculpt;
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index daf3f73a3d7..6e409f4b613 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include "RNA_define.h"
+#include "rna_internal.h"
#include "DNA_color_types.h"
@@ -269,6 +270,11 @@ static void rna_ColorRamp_update(Main *bmain, Scene *scene, PointerRNA *ptr)
}
}
+static void rna_Scopes_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ Scopes *s= (Scopes*)ptr->data;
+ s->ok = 0;
+}
#else
@@ -443,12 +449,77 @@ static void rna_def_color_ramp(BlenderRNA *brna)
static void rna_def_histogram(BlenderRNA *brna)
{
StructRNA *srna;
+ PropertyRNA *prop;
+ static EnumPropertyItem prop_mode_items[] = {
+ {HISTO_MODE_LUMA, "Luma", ICON_COLOR, "Luma", ""},
+ {HISTO_MODE_RGB, "RGB", ICON_COLOR, "RGB", ""},
+ {HISTO_MODE_R, "R", ICON_COLOR, "R", ""},
+ {HISTO_MODE_G, "G", ICON_COLOR, "G", ""},
+ {HISTO_MODE_B, "B", ICON_COLOR, "B", ""},
+ {0, NULL, 0, NULL, NULL}};
+
srna= RNA_def_struct(brna, "Histogram", NULL);
RNA_def_struct_ui_text(srna, "Histogram", "Statistical view of the levels of color in an image");
+ prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "mode");
+ RNA_def_property_enum_items(prop, prop_mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Channels to display when drawing the histogram");
+
+}
+
+static void rna_def_scopes(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_wavefrm_mode_items[] = {
+ {SCOPES_WAVEFRM_LUM, "LUMINANCE", ICON_COLOR, "Luminance", ""},
+ {SCOPES_WAVEFRM_RGB, "RGB", ICON_COLOR, "Red Green Blue", ""},
+ {SCOPES_WAVEFRM_YCC_601, "YCBCR601", ICON_COLOR, "YCbCr (ITU 601)", ""},
+ {SCOPES_WAVEFRM_YCC_709, "YCBCR709", ICON_COLOR, "YCbCr (ITU 709)", ""},
+ {SCOPES_WAVEFRM_YCC_JPEG, "YCBCRJPG", ICON_COLOR, "YCbCr (Jpeg)", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "Scopes", NULL);
+ RNA_def_struct_ui_text(srna, "Scopes", "Scopes for statistical view of an image");
+
+ prop= RNA_def_property(srna, "use_full_resolution", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, "Scopes", "sample_full", 1);
+ RNA_def_property_ui_text(prop, "Full Sample", "Sample every pixel of the image");
+ RNA_def_property_update(prop, 0, "rna_Scopes_update");
+
+ prop= RNA_def_property(srna, "accuracy", PROP_FLOAT, PROP_PERCENTAGE);
+ RNA_def_property_float_sdna(prop, "Scopes", "accuracy");
+ RNA_def_property_range(prop, 0.0, 100.0);
+ RNA_def_property_ui_range(prop, 0.0, 100.0, 10, 1);
+ RNA_def_property_ui_text(prop, "Accuracy", "Proportion of original image source pixel lines to sample");
+ RNA_def_property_update(prop, 0, "rna_Scopes_update");
+
+ prop= RNA_def_property(srna, "histogram", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, "Scopes", "hist");
+ RNA_def_property_struct_type(prop, "Histogram");
+ RNA_def_property_ui_text(prop, "Histogram", "Histogram for viewing image statistics");
+
+ prop= RNA_def_property(srna, "waveform_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, "Scopes", "wavefrm_mode");
+ RNA_def_property_enum_items(prop, prop_wavefrm_mode_items);
+ RNA_def_property_ui_text(prop, "Wavefrom Mode", "");
+ RNA_def_property_update(prop, 0, "rna_Scopes_update");
+
+ prop= RNA_def_property(srna, "waveform_alpha", PROP_FLOAT, PROP_PERCENTAGE);
+ RNA_def_property_float_sdna(prop, "Scopes", "wavefrm_alpha");
+ RNA_def_property_range(prop, 0, 1);
+ RNA_def_property_ui_text(prop, "Waveform Opacity", "Opacity of the points");
+
+ prop= RNA_def_property(srna, "vectorscope_alpha", PROP_FLOAT, PROP_PERCENTAGE);
+ RNA_def_property_float_sdna(prop, "Scopes", "vecscope_alpha");
+ RNA_def_property_range(prop, 0, 1);
+ RNA_def_property_ui_text(prop, "Vectorscope Opacity", "Opacity of the points");
}
+
void RNA_def_color(BlenderRNA *brna)
{
rna_def_curvemappoint(brna);
@@ -457,6 +528,7 @@ void RNA_def_color(BlenderRNA *brna)
rna_def_color_ramp_element(brna);
rna_def_color_ramp(brna);
rna_def_histogram(brna);
+ rna_def_scopes(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 8b3a54af4c2..b7165234ef2 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -458,7 +458,7 @@ static void rna_SpaceImageEditor_curves_update(Main *bmain, Scene *scene, Pointe
WM_main_add_notifier(NC_IMAGE, sima->image);
}
-static void rna_SpaceImageEditor_histogram_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+static void rna_SpaceImageEditor_scopes_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
SpaceImage *sima= (SpaceImage*)ptr->data;
ImBuf *ibuf;
@@ -466,13 +466,12 @@ static void rna_SpaceImageEditor_histogram_update(Main *bmain, Scene *scene, Poi
ibuf= ED_space_image_acquire_buffer(sima, &lock);
if(ibuf) {
- histogram_update(&sima->hist, ibuf);
+ scopes_update(&sima->scopes, ibuf, scene->r.color_mgt_flag & R_COLOR_MANAGEMENT);
WM_main_add_notifier(NC_IMAGE, sima->image);
}
ED_space_image_release_buffer(sima, lock);
}
-
/* Space Text Editor */
static void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value)
@@ -1215,12 +1214,12 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "cumap");
RNA_def_property_ui_text(prop, "Curves", "Color curve mapping to use for displaying the image");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, "rna_SpaceImageEditor_curves_update");
-
- prop= RNA_def_property(srna, "histogram", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "hist");
- RNA_def_property_struct_type(prop, "Histogram");
- RNA_def_property_ui_text(prop, "Histogram", "Histogram for viewing image statistics");
- RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, "rna_SpaceImageEditor_histogram_update");
+
+ prop= RNA_def_property(srna, "scopes", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "scopes");
+ RNA_def_property_struct_type(prop, "Scopes");
+ RNA_def_property_ui_text(prop, "Scopes", "Scopes to visualize image statistics.");
+ RNA_def_property_update(prop, NC_SPACE|ND_SPACE_IMAGE, "rna_SpaceImageEditor_scopes_update");
prop= RNA_def_property(srna, "image_pin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "pin", 0);
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 89c7876f6e0..7c78d8a74e7 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -335,6 +335,14 @@ void RNA_api_ui_layout(StructRNA *srna)
api_ui_item_rna_common(func);
RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail.");
+ func= RNA_def_function(srna, "template_waveform", "uiTemplateWaveform");
+ api_ui_item_rna_common(func);
+ RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail.");
+
+ func= RNA_def_function(srna, "template_vectorscope", "uiTemplateVectorscope");
+ api_ui_item_rna_common(func);
+ RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail.");
+
func= RNA_def_function(srna, "template_layers", "uiTemplateLayers");
api_ui_item_rna_common(func);
parm= RNA_def_pointer(func, "used_layers_data", "AnyType", "", "Data from which to take property.");