diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index bf50648fea2..c8425d7853c 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -142,9 +142,6 @@ struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct Im /* for multilayer images as well as for render-viewer */ struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima); void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima); - -/* frees all ibufs used by any image datablocks */ -void BKE_image_free_image_ibufs(void); /* goes over all textures that use images */ void BKE_image_free_all_textures(void); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 7bf147b4906..3c30332b18d 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -882,12 +882,12 @@ void curvemapping_table_RGBA(CurveMapping *cumap, float **array, int *size) DO_INLINE int get_bin_float(float f) { - int bin= (int)(f*511); + int bin= (int)(f*255); /* note: clamp integer instead of float to avoid problems with NaN */ - CLAMP(bin, 0, 511); + CLAMP(bin, 0, 255); - //return (int) (((f + 0.25) / 1.5) * 512); + //return (int) (((f + 0.25) / 1.5) * 255); return bin; } @@ -903,17 +903,20 @@ void histogram_update(Histogram *hist, ImBuf *ibuf) if (hist->ok == 1 ) return; + if (hist->xmax == 0.f) hist->xmax = 1.f; + if (hist->ymax == 0.f) hist->ymax = 1.f; + /* hmmmm */ if (!(ELEM(ibuf->channels, 3, 4))) return; hist->channels = 3; - bin_r = MEM_callocN(512 * sizeof(unsigned int), "temp historgram bins"); - bin_g = MEM_callocN(512 * sizeof(unsigned int), "temp historgram bins"); - bin_b = MEM_callocN(512 * sizeof(unsigned int), "temp historgram bins"); + 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"); if (ibuf->rect_float) { - hist->x_resolution = 512; + hist->x_resolution = 256; /* divide into bins */ rf = ibuf->rect_float; @@ -942,7 +945,7 @@ void histogram_update(Histogram *hist, ImBuf *ibuf) /* convert to float */ n=0; - for (x=0; x<512; x++) { + for (x=0; x<256; x++) { if (bin_r[x] > n) n = bin_r[x]; if (bin_g[x] > n) @@ -951,7 +954,7 @@ void histogram_update(Histogram *hist, ImBuf *ibuf) n = bin_b[x]; } div = 1.f/(double)n; - for (x=0; x<512; x++) { + 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; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ad7826ab9c4..cca3d561ed4 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -725,17 +725,6 @@ void BKE_image_print_memlist(void) } } -/* frees all ibufs used by any image datablocks */ -void BKE_image_free_image_ibufs(void) -{ - Image *ima; - - for(ima= G.main->image.first; ima; ima= ima->id.next) { - image_free_buffers(ima); - } - -} - void BKE_image_free_all_textures(void) { Tex *tex; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 5363cf8937c..330209ef6f5 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -690,7 +690,7 @@ static void ui_draw_but_CHARTAB(uiBut *but) #endif -void ui_draw_but_HISTOGRAM(uiBut *but, uiWidgetColors *wcol, rcti *recti) +void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *recti) { Histogram *hist = (Histogram *)but->poin; int res = hist->x_resolution; @@ -699,6 +699,7 @@ void ui_draw_but_HISTOGRAM(uiBut *but, uiWidgetColors *wcol, rcti *recti) int rgb; float w, h; float alpha; + GLint scissor[4]; if (hist==NULL) { printf("hist is null \n"); return; } @@ -709,6 +710,7 @@ void ui_draw_but_HISTOGRAM(uiBut *but, uiWidgetColors *wcol, rcti *recti) w = rect.xmax - rect.xmin; h = rect.ymax - rect.ymin; + h *= hist->ymax; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); @@ -724,6 +726,10 @@ void ui_draw_but_HISTOGRAM(uiBut *but, uiWidgetColors *wcol, rcti *recti) fdrawline(rect.xmin+(i/4.f)*w, rect.ymin, rect.xmin+(i/4.f)*w, rect.ymax); } + /* 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)); + for (rgb=0; rgb<3; rgb++) { float *data; @@ -761,6 +767,9 @@ void ui_draw_but_HISTOGRAM(uiBut *but, uiWidgetColors *wcol, rcti *recti) glDisable(GL_LINE_SMOOTH); } + /* restore scissortest */ + glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glColor4f(0.f, 0.f, 0.f, 0.5f); uiSetRoundBox(15); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 26215f78754..5a56877534d 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -2979,6 +2979,12 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx ui_get_but_vectorf(but, rgb); rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); + /* exception, when using color wheel in 'locked' value state: + * allow choosing a hue for black values, by giving a tiny increment */ + if (but->a2 == 1) { // lock + if (hsv[2] == 0.f) hsv[2] = 0.0001f; + } + ui_hsvcircle_vals_from_pos(hsv, hsv+1, &rect, (float)mx, (float)my); hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); @@ -3412,6 +3418,81 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt return WM_UI_HANDLER_CONTINUE; } +static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx, int my) +{ + Histogram *hist = (Histogram *)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; + + yfac = MIN2(powf(hist->ymax, 2.f), 1.f) * 0.5; + hist->ymax += dy * yfac; + + CLAMP(hist->ymax, 1.f, 100.f); + + data->draglastx= mx; + data->draglasty= my; + + return changed; +} + +static int ui_do_but_HISTOGRAM(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_HISTOGRAM(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) { + Histogram *hist = (Histogram *)but->poin; + hist->ymax = 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_HISTOGRAM(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) { @@ -3926,7 +4007,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) } /* reset to default */ else if(event->type == ZEROKEY && event->val == KM_PRESS) { - if (!(ELEM(but->type, HSVCIRCLE, HSVCUBE))) + if (!(ELEM3(but->type, HSVCIRCLE, HSVCUBE, HISTOGRAM))) ui_set_but_default(C, but); } /* handle menu */ @@ -3996,8 +4077,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) case ROW: case LISTROW: case BUT_IMAGE: - case HISTOGRAM: retval= ui_do_but_EXIT(C, but, data, event); + case HISTOGRAM: + retval= ui_do_but_HISTOGRAM(C, block, but, data, event); break; case TEX: case IDPOIN: diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 47892e45a02..1b4c56ed7d0 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -439,7 +439,7 @@ 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(uiBut *but, struct uiWidgetColors *wcol, rcti *rect); +void ui_draw_but_HISTOGRAM(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_widgets.c b/source/blender/editors/interface/interface_widgets.c index aeea7d4a354..6f17a0d4e6a 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2712,7 +2712,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct break; case HISTOGRAM: - ui_draw_but_HISTOGRAM(but, &tui->wcol_regular, rect); + ui_draw_but_HISTOGRAM(ar, but, &tui->wcol_regular, rect); break; case BUT_CURVE: diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 69d0156d2fa..1b801060a23 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -701,11 +701,6 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) /* render info */ if(ibuf && ima && show_render) draw_render_info(ima, ar); - - /* histogram */ - if (ibuf) { - histogram_update(&sima->hist, ibuf); - } /* XXX integrate this code */ #if 0 diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index ad3407a7414..2a8158de79b 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -815,6 +815,13 @@ 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); + void *lock; + ImBuf *ibuf= ED_space_image_acquire_buffer(sima, &lock); + + histogram_update(&sima->hist, ibuf); + ED_space_image_release_buffer(sima, lock); + ED_region_panels(C, ar, 1, NULL, -1); } @@ -822,6 +829,22 @@ static void image_scope_area_listener(ARegion *ar, wmNotifier *wmn) { /* context changes */ switch(wmn->category) { + case NC_SCENE: + switch(wmn->data) { + case ND_MODE: + case ND_RENDER_RESULT: + case ND_COMPO_RESULT: + ED_region_tag_redraw(ar); + break; + } + break; + case NC_IMAGE: + ED_region_tag_redraw(ar); + break; + case NC_NODE: + ED_region_tag_redraw(ar); + break; + } } diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h index 3094ab69ca2..f971a0a0480 100644 --- a/source/blender/makesdna/DNA_color_types.h +++ b/source/blender/makesdna/DNA_color_types.h @@ -83,12 +83,12 @@ typedef struct CurveMapping { typedef struct Histogram { int channels; int x_resolution; - float data_r[512]; - float data_g[512]; - float data_b[512]; - float min, max; + float data_r[256]; + float data_g[256]; + float data_b[256]; + float xmax, ymax; int ok; - int pad; + int flag; } Histogram; #endif diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 3f79a06566d..709165ecf83 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -524,8 +524,22 @@ static int rna_SceneRenderData_engine_get(PointerRNA *ptr) static void rna_SceneRenderData_color_management_update(Main *bmain, Scene *unused, PointerRNA *ptr) { - /* reset all generated image block buffers to prevent out-of-date conversions */ - BKE_image_free_image_ibufs(); + /* reset image nodes */ + Scene *scene= (Scene*)ptr->id.data; + bNodeTree *ntree=scene->nodetree; + bNode *node; + + if(ntree && scene->use_nodes) { + for (node=ntree->nodes.first; node; node=node->next) { + if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_IMAGE)) { + ED_node_changed_update(&scene->id, node); + WM_main_add_notifier(NC_NODE|NA_EDITED, node); + + if (node->type == CMP_NODE_IMAGE) + BKE_image_signal((Image *)node->id, NULL, IMA_SIGNAL_RELOAD); + } + } + } } static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)