static void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, float *mask_rect_float, void *data_v) { CurveMapping *curve_mapping = (CurveMapping *) data_v; int x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int pixel_index = (y * width + x) * 4; float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f}; float hsv[3], f; if (rect_float) copy_v3_v3(pixel, rect_float + pixel_index); else rgb_uchar_to_float(pixel, rect + pixel_index); rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2); /* adjust hue, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(curve_mapping, 0, hsv[0]); hsv[0] += f - 0.5f; /* adjust saturation, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(curve_mapping, 1, hsv[0]); hsv[1] *= (f * 2.0f); /* adjust value, scaling returned default 0.5 up to 1 */ f = curvemapping_evaluateF(curve_mapping, 2, hsv[0]); hsv[2] *= (f * 2.f); hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */ CLAMP(hsv[1], 0.0f, 1.0f); /* convert back to rgb */ hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2); if (mask_rect_float) copy_v3_v3(mask, mask_rect_float + pixel_index); else if (mask_rect) rgb_uchar_to_float(mask, mask_rect + pixel_index); result[0] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0]; result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1]; result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2]; if (rect_float) copy_v3_v3(rect_float + pixel_index, result); else rgb_float_to_uchar(rect + pixel_index, result); } } }
/* 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; float fx, fy, bufx, bufy; bool ret = false; if (STREQ(snode->tree_idname, ntreeType_Composite->idname) || (snode->flag & SNODE_BACKDRAW) == 0) { /* use viewer image for color sampling only if we're in compositor tree * with backdrop enabled */ return false; } ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (!ibuf) { return false; } /* map the mouse coords to the backdrop image space */ bufx = ibuf->x * snode->zoom; bufy = ibuf->y * snode->zoom; fx = (bufx > 0.0f ? ((float)mval[0] - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f); fy = (bufy > 0.0f ? ((float)mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f); if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) { const float *fp; unsigned char *cp; int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y); CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); if (ibuf->rect_float) { fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); /* IB_PROFILE_NONE is default but infact its linear */ 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; }
static void tonemapmodifier_apply_threaded_simple(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, float *mask_rect_float, void *data_v) { AvgLogLum *avg = (AvgLogLum *)data_v; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pixel_index = (y * width + x) * 4; float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f}; /* Get input value. */ if (rect_float) { copy_v4_v4(input, &rect_float[pixel_index]); } else { straight_uchar_to_premul_float(input, &rect[pixel_index]); } IMB_colormanagement_colorspace_to_scene_linear_v3(input, avg->colorspace); copy_v4_v4(output, input); /* Get mask value. */ if (mask_rect_float) { copy_v3_v3(mask, mask_rect_float + pixel_index); } else if (mask_rect) { rgb_uchar_to_float(mask, mask_rect + pixel_index); } /* Apply correction. */ mul_v3_fl(output, avg->al); float dr = output[0] + avg->tmmd->offset; float dg = output[1] + avg->tmmd->offset; float db = output[2] + avg->tmmd->offset; output[0] /= ((dr == 0.0f) ? 1.0f : dr); output[1] /= ((dg == 0.0f) ? 1.0f : dg); output[2] /= ((db == 0.0f) ? 1.0f : db); const float igm = avg->igm; if (igm != 0.0f) { output[0] = powf(max_ff(output[0], 0.0f), igm); output[1] = powf(max_ff(output[1], 0.0f), igm); output[2] = powf(max_ff(output[2], 0.0f), igm); } /* Apply mask. */ output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0]; output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1]; output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2]; /* Copy result back. */ IMB_colormanagement_scene_linear_to_colorspace_v3(output, avg->colorspace); if (rect_float) { copy_v4_v4(&rect_float[pixel_index], output); } else { premul_float_to_straight_uchar(&rect[pixel_index], output); } } } }
static void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, float *mask_rect_float, void *data_v) { CurveMapping *curve_mapping = (CurveMapping *) data_v; int x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int pixel_index = (y * width + x) * 4; if (rect_float) { float *pixel = rect_float + pixel_index; float result[3]; curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel); if (mask_rect_float) { const float *m = mask_rect_float + pixel_index; pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0]; pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1]; pixel[2] = pixel[2] * (1.0f - m[2]) + result[2] * m[2]; } else { pixel[0] = result[0]; pixel[1] = result[1]; pixel[2] = result[2]; } } if (rect) { unsigned char *pixel = rect + pixel_index; float result[3], tempc[4]; straight_uchar_to_premul_float(tempc, pixel); curvemapping_evaluate_premulRGBF(curve_mapping, result, tempc); if (mask_rect) { float t[3]; rgb_uchar_to_float(t, mask_rect + pixel_index); tempc[0] = tempc[0] * (1.0f - t[0]) + result[0] * t[0]; tempc[1] = tempc[1] * (1.0f - t[1]) + result[1] * t[1]; tempc[2] = tempc[2] * (1.0f - t[2]) + result[2] * t[2]; } else { tempc[0] = result[0]; tempc[1] = result[1]; tempc[2] = result[2]; } premul_float_to_straight_uchar(pixel, tempc); } } } }
/* Byte equivalent of IMB_colormanagement_get_luminance(). */ unsigned char IMB_colormanagement_get_luminance_byte(const unsigned char rgb[3]) { float rgbf[3]; float val; rgb_uchar_to_float(rgbf, rgb); val = dot_v3v3(imbuf_luma_coefficients, rgbf); return unit_float_to_uchar_clamp(val); }
static void whiteBalance_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, float *mask_rect_float, void *data_v) { int x, y; float multiplier[3]; WhiteBalanceThreadData *data = (WhiteBalanceThreadData *) data_v; multiplier[0] = (data->white[0] != 0.0f) ? 1.0f / data->white[0] : FLT_MAX; multiplier[1] = (data->white[1] != 0.0f) ? 1.0f / data->white[1] : FLT_MAX; multiplier[2] = (data->white[2] != 0.0f) ? 1.0f / data->white[2] : FLT_MAX; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int pixel_index = (y * width + x) * 4; float rgba[4], result[4], mask[3] = {1.0f, 1.0f, 1.0f}; if (rect_float) { copy_v3_v3(rgba, rect_float + pixel_index); } else { straight_uchar_to_premul_float(rgba, rect + pixel_index); } copy_v4_v4(result, rgba); #if 0 mul_v3_v3(result, multiplier); #else /* similar to division without the clipping */ for (int i = 0; i < 3; i++) { result[i] = 1.0f - powf(1.0f - rgba[i], multiplier[i]); } #endif if (mask_rect_float) { copy_v3_v3(mask, mask_rect_float + pixel_index); } else if (mask_rect) { rgb_uchar_to_float(mask, mask_rect + pixel_index); } result[0] = rgba[0] * (1.0f - mask[0]) + result[0] * mask[0]; result[1] = rgba[1] * (1.0f - mask[1]) + result[1] * mask[1]; result[2] = rgba[2] * (1.0f - mask[2]) + result[2] * mask[2]; if (rect_float) { copy_v3_v3(rect_float + pixel_index, result); } else { premul_float_to_straight_uchar(rect + pixel_index, result); } } } }
/* matching ED_space_image_color_sample() */ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3]) { void *lock; Image *ima; ImBuf *ibuf; float fx, fy, bufx, bufy; int ret = FALSE; if (STREQ(snode->tree_idname, ntreeType_Composite->idname) || (snode->flag & SNODE_BACKDRAW) == 0) { /* use viewer image for color sampling only if we're in compositor tree * with backdrop enabled */ return FALSE; } ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (!ibuf) { return FALSE; } /* map the mouse coords to the backdrop image space */ bufx = ibuf->x * snode->zoom; bufy = ibuf->y * snode->zoom; fx = (bufx > 0.0f ? ((float)mval[0] - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f); fy = (bufy > 0.0f ? ((float)mval[1] - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f); if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) { float *fp; unsigned char *cp; int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y); CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); 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); ret = TRUE; } else if (ibuf->rect) { cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); rgb_uchar_to_float(r_col, cp); ret = TRUE; } } BKE_image_release_ibuf(ima, ibuf, lock); return ret; }
/* 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; ibuf = ED_space_clip_get_buffer(sc); if (!ibuf) { return false; } /* map the mouse coords to the backdrop image space */ ED_clip_mouse_pos(sc, ar, mval, co); fx = co[0]; fy = co[1]; if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) { const float *fp; unsigned char *cp; int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y); CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); if (ibuf->rect_float) { fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); 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; }
static void whiteBalance_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, float *mask_rect_float, void *data_v) { int x, y; float multiplier[3]; WhiteBalanceThreadData *data = (WhiteBalanceThreadData *) data_v; multiplier[0] = 1.0f / data->white[0]; multiplier[1] = 1.0f / data->white[1]; multiplier[2] = 1.0f / data->white[2]; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int pixel_index = (y * width + x) * 4; float result[3], mask[3] = {1.0f, 1.0f, 1.0f}; if (rect_float) { copy_v3_v3(result, rect_float + pixel_index); } else { straight_uchar_to_premul_float(result, rect + pixel_index); IMB_colormanagement_colorspace_to_scene_linear_v3(result, data->colorspace); } mul_v3_v3(result, multiplier); if (mask_rect_float) copy_v3_v3(mask, mask_rect_float + pixel_index); else if (mask_rect) rgb_uchar_to_float(mask, mask_rect + pixel_index); result[0] = result[0] * (1.0f - mask[0]) + result[0] * mask[0]; result[1] = result[1] * (1.0f - mask[1]) + result[1] * mask[1]; result[2] = result[2] * (1.0f - mask[2]) + result[2] * mask[2]; if (rect_float) copy_v3_v3(rect_float + pixel_index, result); else IMB_colormanagement_scene_linear_to_colorspace_v3(result, data->colorspace); premul_float_to_straight_uchar(rect + pixel_index, result); } } }
/* matching ED_space_image_color_sample() */ bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r_col[3]) { ImBuf *ibuf; float fx, fy, co[2]; bool ret = false; ibuf = ED_space_clip_get_buffer(sc); if (!ibuf) { return false; } /* map the mouse coords to the backdrop image space */ ED_clip_mouse_pos(sc, ar, mval, co); fx = co[0]; fy = co[1]; if (fx >= 0.0f && fy >= 0.0f && fx < 1.0f && fy < 1.0f) { float *fp; unsigned char *cp; int x = (int)(fx * ibuf->x), y = (int)(fy * ibuf->y); CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); if (ibuf->rect_float) { fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); linearrgb_to_srgb_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); ret = true; } } return ret; }
void IMB_saturation(ImBuf *ibuf, float sat) { size_t i; unsigned char *rct = (unsigned char *)ibuf->rect; float *rct_fl = ibuf->rect_float; float hsv[3]; if (rct) { float rgb[3]; for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct += 4) { rgb_uchar_to_float(rgb, rct); rgb_to_hsv_v(rgb, hsv); hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rgb, rgb + 1, rgb + 2); rgb_float_to_uchar(rct, rgb); } } if (rct_fl) { for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, rct_fl += 4) { rgb_to_hsv_v(rct_fl, hsv); hsv_to_rgb(hsv[0], hsv[1] * sat, hsv[2], rct_fl, rct_fl + 1, rct_fl + 2); } } }
static void tonemapmodifier_apply_threaded_photoreceptor(int width, int height, unsigned char *rect, float *rect_float, unsigned char *mask_rect, float *mask_rect_float, void *data_v) { AvgLogLum *avg = (AvgLogLum *)data_v; const float f = expf(-avg->tmmd->intensity); const float m = (avg->tmmd->contrast > 0.0f) ? avg->tmmd->contrast : (0.3f + 0.7f * powf(avg->auto_key, 1.4f)); const float ic = 1.0f - avg->tmmd->correction, ia = 1.0f - avg->tmmd->adaptation; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pixel_index = (y * width + x) * 4; float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f}; /* Get input value. */ if (rect_float) { copy_v4_v4(input, &rect_float[pixel_index]); } else { straight_uchar_to_premul_float(input, &rect[pixel_index]); } IMB_colormanagement_colorspace_to_scene_linear_v3(input, avg->colorspace); copy_v4_v4(output, input); /* Get mask value. */ if (mask_rect_float) { copy_v3_v3(mask, mask_rect_float + pixel_index); } else if (mask_rect) { rgb_uchar_to_float(mask, mask_rect + pixel_index); } /* Apply correction. */ const float L = IMB_colormanagement_get_luminance(output); float I_l = output[0] + ic * (L - output[0]); float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]); float I_a = I_l + ia * (I_g - I_l); output[0] /= (output[0] + powf(f * I_a, m)); I_l = output[1] + ic * (L - output[1]); I_g = avg->cav[1] + ic * (avg->lav - avg->cav[1]); I_a = I_l + ia * (I_g - I_l); output[1] /= (output[1] + powf(f * I_a, m)); I_l = output[2] + ic * (L - output[2]); I_g = avg->cav[2] + ic * (avg->lav - avg->cav[2]); I_a = I_l + ia * (I_g - I_l); output[2] /= (output[2] + powf(f * I_a, m)); /* Apply mask. */ output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0]; output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1]; output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2]; /* Copy result back. */ IMB_colormanagement_scene_linear_to_colorspace_v3(output, avg->colorspace); if (rect_float) { copy_v4_v4(&rect_float[pixel_index], output); } else { premul_float_to_straight_uchar(&rect[pixel_index], output); } } } }
static void mloopcol_to_float(const MLoopCol *mloopcol, float r_col[3]) { rgb_uchar_to_float(r_col, (const unsigned char *)&mloopcol->r); }
/* used for both 3d view and image window */ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_proj, bool use_palette) { Scene *scene = CTX_data_scene(C); Paint *paint = BKE_paint_get_active_from_context(C); Palette *palette = BKE_paint_palette(paint); PaletteColor *color; Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C)); unsigned int col; const unsigned char *cp; CLAMP(x, 0, ar->winx); CLAMP(y, 0, ar->winy); if (use_palette) { if (!palette) { palette = BKE_palette_add(CTX_data_main(C), "Palette"); BKE_paint_palette_set(paint, palette); } color = BKE_palette_color_add(palette); } if (CTX_wm_view3d(C) && texpaint_proj) { /* first try getting a colour directly from the mesh faces if possible */ Object *ob = OBACT; bool sample_success = false; if (ob) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); ViewContext vc; const int mval[2] = {x, y}; unsigned int faceindex; unsigned int totface = dm->getNumTessFaces(dm); MTFace *dm_mtface = dm->getTessFaceDataArray(dm, CD_MTFACE); DM_update_materials(dm, ob); if (dm_mtface) { view3d_set_viewcontext(C, &vc); view3d_operator_needs_opengl(C); if (imapaint_pick_face(&vc, mval, &faceindex, totface)) { Image *image = imapaint_face_image(dm, faceindex); ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); if (ibuf && ibuf->rect) { float uv[2]; float u, v; imapaint_pick_uv(scene, ob, faceindex, mval, uv); sample_success = true; u = fmodf(uv[0], 1.0f); v = fmodf(uv[1], 1.0f); if (u < 0.0f) u += 1.0f; if (v < 0.0f) v += 1.0f; u = u * ibuf->x - 0.5f; v = v * ibuf->y - 0.5f; if (ibuf->rect_float) { float rgba_f[4]; bilinear_interpolation_color_wrap(ibuf, NULL, rgba_f, u, v); straight_to_premul_v4(rgba_f); if (use_palette) { linearrgb_to_srgb_v3_v3(color->rgb, rgba_f); } else { linearrgb_to_srgb_v3_v3(rgba_f, rgba_f); BKE_brush_color_set(scene, br, rgba_f); } } else { unsigned char rgba[4]; bilinear_interpolation_color_wrap(ibuf, rgba, NULL, u, v); if (use_palette) { rgb_uchar_to_float(color->rgb, rgba); } else { float rgba_f[3]; rgb_uchar_to_float(rgba_f, rgba); BKE_brush_color_set(scene, br, rgba_f); } } } BKE_image_release_ibuf(image, ibuf, NULL); } } dm->release(dm); } if (!sample_success) { glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); } else return; } else { glReadBuffer(GL_FRONT); glReadPixels(x + ar->winrct.xmin, y + ar->winrct.ymin, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); } cp = (unsigned char *)&col; if (use_palette) { rgb_uchar_to_float(color->rgb, cp); } else { float rgba_f[3]; rgb_uchar_to_float(rgba_f, cp); BKE_brush_color_set(scene, br, rgba_f); } }
/* used by node view too */ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_default_view, int channels, int x, int y, const unsigned char cp[4], const float fp[4], int *zp, float *zpf) { char str[256]; float dx = 6; /* text colors */ /* XXX colored text not allowed in Blender UI */ #if 0 unsigned char red[3] = {255, 50, 50}; unsigned char green[3] = {0, 255, 0}; unsigned char blue[3] = {100, 100, 255}; #else unsigned char red[3] = {255, 255, 255}; unsigned char green[3] = {255, 255, 255}; unsigned char blue[3] = {255, 255, 255}; #endif float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0; float col[4], finalcol[4]; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); /* noisy, high contrast make impossible to read if lower alpha is used. */ glColor4ub(0, 0, 0, 190); glRecti(0.0, 0.0, BLI_rcti_size_x(&ar->winrct) + 1, 20); glDisable(GL_BLEND); BLF_size(blf_mono_font, 11, 72); glColor3ub(255, 255, 255); BLI_snprintf(str, sizeof(str), "X:%-4d Y:%-4d |", x, y); // UI_DrawString(6, 6, str); // works ok but fixed width is nicer. BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); if (zp) { glColor3ub(255, 255, 255); BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff)); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } if (zpf) { glColor3ub(255, 255, 255); BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } if (channels >= 3) { glColor3ubv(red); if (fp) BLI_snprintf(str, sizeof(str), " R:%-.5f", fp[0]); else if (cp) BLI_snprintf(str, sizeof(str), " R:%-3d", cp[0]); else BLI_snprintf(str, sizeof(str), " R:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); glColor3ubv(green); if (fp) BLI_snprintf(str, sizeof(str), " G:%-.5f", fp[1]); else if (cp) BLI_snprintf(str, sizeof(str), " G:%-3d", cp[1]); else BLI_snprintf(str, sizeof(str), " G:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); glColor3ubv(blue); if (fp) BLI_snprintf(str, sizeof(str), " B:%-.5f", fp[2]); else if (cp) BLI_snprintf(str, sizeof(str), " B:%-3d", cp[2]); else BLI_snprintf(str, sizeof(str), " B:-"); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); if (channels == 4) { glColor3ub(255, 255, 255); if (fp) BLI_snprintf(str, sizeof(str), " A:%-.4f", fp[3]); else if (cp) BLI_snprintf(str, sizeof(str), " A:%-3d", cp[3]); else BLI_snprintf(str, sizeof(str), "- "); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } if (color_manage && channels == 4) { float pixel[4]; if (use_default_view) IMB_colormanagement_pixel_to_display_space_v4(pixel, fp, NULL, &scene->display_settings); else IMB_colormanagement_pixel_to_display_space_v4(pixel, fp, &scene->view_settings, &scene->display_settings); BLI_snprintf(str, sizeof(str), " | CM R:%-.4f G:%-.4f B:%-.4f", pixel[0], pixel[1], pixel[2]); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } } /* color rectangle */ if (channels == 1) { if (fp) { col[0] = col[1] = col[2] = fp[0]; } else if (cp) { col[0] = col[1] = col[2] = (float)cp[0] / 255.0f; } else { col[0] = col[1] = col[2] = 0.0f; } col[3] = 1.0f; } else if (channels == 3) { if (fp) { copy_v3_v3(col, fp); } else if (cp) { rgb_uchar_to_float(col, cp); } else { zero_v3(col); } col[3] = 1.0f; } else if (channels == 4) { if (fp) copy_v4_v4(col, fp); else if (cp) { rgba_uchar_to_float(col, cp); } else { zero_v4(col); } } else { BLI_assert(0); zero_v4(col); } if (color_manage) { if (use_default_view) IMB_colormanagement_pixel_to_display_space_v4(finalcol, col, NULL, &scene->display_settings); else IMB_colormanagement_pixel_to_display_space_v4(finalcol, col, &scene->view_settings, &scene->display_settings); } else { copy_v4_v4(finalcol, col); } glDisable(GL_BLEND); glColor3fv(finalcol); dx += 5; glBegin(GL_QUADS); glVertex2f(dx, 3); glVertex2f(dx, 17); glVertex2f(dx + 30, 17); glVertex2f(dx + 30, 3); glEnd(); /* draw outline */ glColor3ub(128, 128, 128); glBegin(GL_LINE_LOOP); glVertex2f(dx, 3); glVertex2f(dx, 17); glVertex2f(dx + 30, 17); glVertex2f(dx + 30, 3); glEnd(); dx += 35; glColor3ub(255, 255, 255); if (channels == 1) { if (fp) { rgb_to_hsv(fp[0], fp[0], fp[0], &hue, &sat, &val); rgb_to_yuv(fp[0], fp[0], fp[0], &lum, &u, &v); } else if (cp) { rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &hue, &sat, &val); rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[0] / 255.0f, (float)cp[0] / 255.0f, &lum, &u, &v); } BLI_snprintf(str, sizeof(str), "V:%-.4f", val); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); BLI_snprintf(str, sizeof(str), " L:%-.4f", lum); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } else if (channels >= 3) { if (fp) { rgb_to_hsv(fp[0], fp[1], fp[2], &hue, &sat, &val); rgb_to_yuv(fp[0], fp[1], fp[2], &lum, &u, &v); } else if (cp) { rgb_to_hsv((float)cp[0] / 255.0f, (float)cp[1] / 255.0f, (float)cp[2] / 255.0f, &hue, &sat, &val); rgb_to_yuv((float)cp[0] / 255.0f, (float)cp[1] / 255.0f, (float)cp[2] / 255.0f, &lum, &u, &v); } BLI_snprintf(str, sizeof(str), "H:%-.4f", hue); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); BLI_snprintf(str, sizeof(str), " S:%-.4f", sat); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); BLI_snprintf(str, sizeof(str), " V:%-.4f", val); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); BLI_snprintf(str, sizeof(str), " L:%-.4f", lum); BLF_position(blf_mono_font, dx, 6, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); dx += BLF_width(blf_mono_font, str); } (void)dx; }
static void mloopcol_to_float(const MLoopCol *mloopcol, float col_r[3]) { rgb_uchar_to_float(col_r, (unsigned char *)&mloopcol->r); }