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); } } } }
static void node_composit_exec_curve_vec(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) { /* stack order input: vec */ /* stack order output: vec */ curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec); }
static void do_curves_fac(bNode *node, float *out, float *in, float *fac) { if (*fac >= 1.0f) curvemapping_evaluate_premulRGBF(node->storage, out, in); else if (*fac <= 0.0f) { copy_v3_v3(out, in); } else { float col[4], mfac= 1.0f-*fac; curvemapping_evaluate_premulRGBF(node->storage, col, in); out[0]= mfac*in[0] + *fac*col[0]; out[1]= mfac*in[1] + *fac*col[1]; out[2]= mfac*in[2] + *fac*col[2]; } out[3]= in[3]; }
void VectorCurveOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) { float input[4]; this->m_inputProgram->readSampled(input, x, y, sampler); curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input); output[3] = input[3]; }
/* only used for image editor curves */ void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf) { ImBuf *tmpbuf; int pixel; float *pix_in; float col[3]; int stride = 4; float *pix_out; if (ibuf == NULL) return; if (ibuf->rect_float == NULL) IMB_float_from_rect(ibuf); else if (ibuf->rect == NULL) imb_addrectImBuf(ibuf); if (!ibuf->rect || !ibuf->rect_float) return; /* work on a temp buffer, so can color manage afterwards. * No worse off memory wise than comp nodes */ tmpbuf = IMB_dupImBuf(ibuf); curvemapping_premultiply(cumap, 0); pix_in = ibuf->rect_float; pix_out = tmpbuf->rect_float; if (ibuf->channels) stride = ibuf->channels; for (pixel = ibuf->x * ibuf->y; pixel > 0; pixel--, pix_in += stride, pix_out += stride) { if (stride < 3) { col[0] = curvemap_evaluateF(cumap->cm, *pix_in); pix_out[1] = pix_out[2] = pix_out[3] = pix_out[0] = col[0]; } else { curvemapping_evaluate_premulRGBF(cumap, col, pix_in); pix_out[0] = col[0]; pix_out[1] = col[1]; pix_out[2] = col[2]; if (stride > 3) pix_out[3] = pix_in[3]; else pix_out[3] = 1.f; } } IMB_rect_from_float(tmpbuf); SWAP(unsigned int *, tmpbuf->rect, ibuf->rect); IMB_freeImBuf(tmpbuf); curvemapping_premultiply(cumap, 1); }
/* same as above, byte version */ void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char vecout_byte[3], const unsigned char vecin_byte[3]) { float vecin[3], vecout[3]; vecin[0] = (float) vecin_byte[0] / 255.0f; vecin[1] = (float) vecin_byte[1] / 255.0f; vecin[2] = (float) vecin_byte[2] / 255.0f; curvemapping_evaluate_premulRGBF(cumap, vecout, vecin); vecout_byte[0] = FTOCHAR(vecout[0]); vecout_byte[1] = FTOCHAR(vecout[1]); vecout_byte[2] = FTOCHAR(vecout[2]); }
static void do_curves(bNode *node, float *out, float *in) { curvemapping_initialize(node->storage); curvemapping_evaluate_premulRGBF(node->storage, out, in); out[3] = in[3]; }