Fix the eyedropper not working properly with different scene linear spaces
Either was some residue from the past or somebody didn't implement this in the right way. Also fixed memory leak in ED_space_clip_color_sample() caused by missing image buffer release.
This commit is contained in:
		@@ -63,7 +63,7 @@ int ED_space_clip_get_clip_frame_number(struct SpaceClip *sc);
 | 
			
		||||
struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc);
 | 
			
		||||
struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle);
 | 
			
		||||
 | 
			
		||||
bool ED_space_clip_color_sample(struct SpaceClip *sc, struct ARegion *ar, int mval[2], float r_col[3]);
 | 
			
		||||
bool ED_space_clip_color_sample(struct Scene *scene, struct SpaceClip *sc, struct ARegion *ar, int mval[2], float r_col[3]);
 | 
			
		||||
 | 
			
		||||
void ED_clip_update_frame(const struct Main *mainp, int cfra);
 | 
			
		||||
bool ED_clip_view_selection(const struct bContext *C, struct ARegion *ar, bool fit);
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ void          ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, s
 | 
			
		||||
struct Mask  *ED_space_image_get_mask(struct SpaceImage *sima);
 | 
			
		||||
void          ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask);
 | 
			
		||||
 | 
			
		||||
bool ED_space_image_color_sample(struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
 | 
			
		||||
bool ED_space_image_color_sample(struct Scene *scene, struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
 | 
			
		||||
struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **lock_r);
 | 
			
		||||
void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock);
 | 
			
		||||
bool ED_space_image_has_buffer(struct SpaceImage *sima);
 | 
			
		||||
 
 | 
			
		||||
@@ -108,7 +108,7 @@ void ED_node_composite_job(const struct bContext *C, struct bNodeTree *nodetree,
 | 
			
		||||
void ED_operatormacros_node(void);
 | 
			
		||||
 | 
			
		||||
/* node_view.c */
 | 
			
		||||
bool ED_space_node_color_sample(struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
 | 
			
		||||
bool ED_space_node_color_sample(struct Scene *scene, struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
 | 
			
		||||
 | 
			
		||||
#endif /* __ED_NODE_H__ */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -149,7 +149,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
 | 
			
		||||
					int mval[2] = {mx - ar->winrct.xmin,
 | 
			
		||||
					               my - ar->winrct.ymin};
 | 
			
		||||
 | 
			
		||||
					if (ED_space_image_color_sample(sima, ar, mval, r_col)) {
 | 
			
		||||
					if (ED_space_image_color_sample(CTX_data_scene(C), sima, ar, mval, r_col)) {
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
@@ -161,7 +161,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
 | 
			
		||||
					int mval[2] = {mx - ar->winrct.xmin,
 | 
			
		||||
					               my - ar->winrct.ymin};
 | 
			
		||||
 | 
			
		||||
					if (ED_space_node_color_sample(snode, ar, mval, r_col)) {
 | 
			
		||||
					if (ED_space_node_color_sample(CTX_data_scene(C), snode, ar, mval, r_col)) {
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
@@ -173,7 +173,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
 | 
			
		||||
					int mval[2] = {mx - ar->winrct.xmin,
 | 
			
		||||
					               my - ar->winrct.ymin};
 | 
			
		||||
 | 
			
		||||
					if (ED_space_clip_color_sample(sc, ar, mval, r_col)) {
 | 
			
		||||
					if (ED_space_clip_color_sample(CTX_data_scene(C), sc, ar, mval, r_col)) {
 | 
			
		||||
						return;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -260,10 +260,11 @@ ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* returns color in SRGB */
 | 
			
		||||
/* matching ED_space_image_color_sample() */
 | 
			
		||||
bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r_col[3])
 | 
			
		||||
/* Returns color in the display space, matching ED_space_image_color_sample(). */
 | 
			
		||||
bool ED_space_clip_color_sample(Scene *scene, SpaceClip *sc, ARegion *ar, int mval[2], float r_col[3])
 | 
			
		||||
{
 | 
			
		||||
	const char *display_device = scene->display_settings.display_device;
 | 
			
		||||
	struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
 | 
			
		||||
	ImBuf *ibuf;
 | 
			
		||||
	float fx, fy, co[2];
 | 
			
		||||
	bool ret = false;
 | 
			
		||||
@@ -289,16 +290,22 @@ bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r
 | 
			
		||||
 | 
			
		||||
		if (ibuf->rect_float) {
 | 
			
		||||
			fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
 | 
			
		||||
			linearrgb_to_srgb_v3_v3(r_col, fp);
 | 
			
		||||
			copy_v3_v3(r_col, fp);
 | 
			
		||||
			ret = true;
 | 
			
		||||
		}
 | 
			
		||||
		else if (ibuf->rect) {
 | 
			
		||||
			cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
 | 
			
		||||
			rgb_uchar_to_float(r_col, cp);
 | 
			
		||||
			IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
 | 
			
		||||
			ret = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	IMB_freeImBuf(ibuf);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2320,10 +2320,11 @@ static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* returns color in SRGB */
 | 
			
		||||
/* matching ED_space_node_color_sample() */
 | 
			
		||||
bool ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], float r_col[3])
 | 
			
		||||
/* Returns color in the display space, matching ED_space_node_color_sample(). */
 | 
			
		||||
bool ED_space_image_color_sample(Scene *scene, SpaceImage *sima, ARegion *ar, int mval[2], float r_col[3])
 | 
			
		||||
{
 | 
			
		||||
	const char *display_device = scene->display_settings.display_device;
 | 
			
		||||
	struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
 | 
			
		||||
	void *lock;
 | 
			
		||||
	ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
 | 
			
		||||
	float fx, fy;
 | 
			
		||||
@@ -2346,16 +2347,21 @@ bool ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], flo
 | 
			
		||||
 | 
			
		||||
		if (ibuf->rect_float) {
 | 
			
		||||
			fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
 | 
			
		||||
			linearrgb_to_srgb_v3_v3(r_col, fp);
 | 
			
		||||
			copy_v3_v3(r_col, fp);
 | 
			
		||||
			ret = true;
 | 
			
		||||
		}
 | 
			
		||||
		else if (ibuf->rect) {
 | 
			
		||||
			cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
 | 
			
		||||
			rgb_uchar_to_float(r_col, cp);
 | 
			
		||||
			IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
 | 
			
		||||
			ret = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ED_space_image_release_buffer(sima, ibuf, lock);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -417,10 +417,13 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* returns color in SRGB */
 | 
			
		||||
/* matching ED_space_image_color_sample() */
 | 
			
		||||
bool ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3])
 | 
			
		||||
/* Returns color in the display space, matching ED_space_image_color_sample().
 | 
			
		||||
 * And here we've got recursion in the comments tips...
 | 
			
		||||
 */
 | 
			
		||||
bool ED_space_node_color_sample(Scene *scene, SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3])
 | 
			
		||||
{
 | 
			
		||||
	const char *display_device = scene->display_settings.display_device;
 | 
			
		||||
	struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
 | 
			
		||||
	void *lock;
 | 
			
		||||
	Image *ima;
 | 
			
		||||
	ImBuf *ibuf;
 | 
			
		||||
@@ -457,16 +460,20 @@ bool ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], floa
 | 
			
		||||
		if (ibuf->rect_float) {
 | 
			
		||||
			fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
 | 
			
		||||
			/* IB_PROFILE_NONE is default but infact its linear */
 | 
			
		||||
			linearrgb_to_srgb_v3_v3(r_col, fp);
 | 
			
		||||
			copy_v3_v3(r_col, fp);
 | 
			
		||||
			ret = true;
 | 
			
		||||
		}
 | 
			
		||||
		else if (ibuf->rect) {
 | 
			
		||||
			cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x);
 | 
			
		||||
			rgb_uchar_to_float(r_col, cp);
 | 
			
		||||
			IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace);
 | 
			
		||||
			ret = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BKE_image_release_ibuf(ima, ibuf, lock);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user