コード例 #1
0
static void do_chroma_distance_matte(bNode *node, float *out, float *in)
{
	NodeChroma *c= (NodeChroma *)node->storage;
	float tolerance=c->t1;
	float fper=c->t2;
	/* get falloff amount over tolerance size */
	float falloff=(1.0f-fper) * tolerance;
	float y_key, cb_key, cr_key;
	float y_pix, cb_pix, cr_pix;
	float distance;
	float alpha;

	/*convert key to chroma colorspace */
	rgb_to_ycc(c->key[0], c->key[1], c->key[2], &y_key, &cb_key, &cr_key, BLI_YCC_JFIF_0_255);
	/* normalize the values */
	cb_key=cb_key/255.0f;
	cr_key=cr_key/255.0f;

	/*convert pixel to chroma colorspace */
	rgb_to_ycc(in[0], in[1], in[2], &y_pix, &cb_pix, &cr_pix, BLI_YCC_JFIF_0_255);
	/*normalize the values */
	cb_pix=cb_pix/255.0f;
	cr_pix=cr_pix/255.0f;

	distance=sqrt((cb_key-cb_pix)*(cb_key-cb_pix) +
		(cr_key-cr_pix)*(cr_key-cr_pix));

	copy_v3_v3(out, in);

	if (distance <= tolerance) {
		if (distance <= falloff) {
			alpha = 0.0f;
		}
		else {
			/* alpha as percent (distance / tolerance), each modified by falloff amount (in pixels)*/
			alpha=(distance-falloff)/(tolerance-falloff);
		}

		/*only change if more transparent than before */
		if (alpha < in[3]) {
			/*clamp*/
			if (alpha < 0.0f) alpha = 0.0f;
			if (alpha > 1.0f) alpha = 1.0f;
			out[3]=alpha;
		}
		else { /* leave as before */
			out[3]=in[3];
		}
	}
}
コード例 #2
0
ファイル: CMP_chromaMatte.c プロジェクト: jinjoh/NOOR
static void do_rgba_to_ycca_normalized(bNode *node, float *out, float *in)
{
	/*normalize to the range -1.0 to 1.0) */
	rgb_to_ycc(in[0],in[1],in[2], &out[0], &out[1], &out[2]);
	out[0]=((out[0])-16)/255.0;
	out[1]=((out[1])-128)/255.0;
	out[2]=((out[2])-128)/255.0;
	out[3]=in[3];
}
コード例 #3
0
static void do_sepycca_jfif(bNode *UNUSED(node), float *out, float *in)
{
	float y, cb, cr;
	
	rgb_to_ycc(in[0], in[1], in[2], &y, &cb, &cr, BLI_YCC_JFIF_0_255);
	
	/*divided by 255 to normalize for viewing in */
	out[0]= y/255.0;
	out[1]= cb/255.0;
	out[2]= cr/255.0;
	out[3]= in[3];
}
コード例 #4
0
void ConvertRGBToYCCOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
{
	float inputColor[4];
	float color[3];

	this->m_inputOperation->read(inputColor, x, y, sampler);
	rgb_to_ycc(inputColor[0], inputColor[1], inputColor[2], &color[0], &color[1], &color[2], this->m_mode);

	/* divided by 255 to normalize for viewing in */
	/* R,G,B --> Y,Cb,Cr */
	mul_v3_v3fl(output, color, 1.0f / 255.0f);
	output[3] = inputColor[3];
}
コード例 #5
0
static void do_rgba_to_ycca_normalized(bNode *UNUSED(node), float *out, float *in)
{
   rgb_to_ycc(in[0],in[1],in[2], &out[0], &out[1], &out[2], BLI_YCC_ITU_BT601);

   //normalize to 0..1.0
   out[0]=out[0]/255.0;
   out[1]=out[1]/255.0;
   out[2]=out[2]/255.0;

   //rescale to -1.0..1.0
   out[0]=(out[0]*2.0)-1.0;
   out[1]=(out[1]*2.0)-1.0;
   out[2]=(out[2]*2.0)-1.0;

//	out[0]=((out[0])-16)/255.0;
//	out[1]=((out[1])-128)/255.0;
//	out[2]=((out[2])-128)/255.0;
	out[3]=in[3];
}
コード例 #6
0
ファイル: colortools.c プロジェクト: nttputus/blensor
void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
{
	int x, y, c;
	unsigned int n, nl;
	double div, divl;
	float *rf = NULL;
	unsigned char *rc = NULL;
	unsigned int *bin_r, *bin_g, *bin_b, *bin_lum;
	int savedlines, saveline;
	float rgb[3], ycc[3], luma;
	int ycc_mode = -1;
	const short is_float = (ibuf->rect_float != NULL);

	if (ibuf->rect == NULL && ibuf->rect_float == NULL) return;

	if (scopes->ok == 1) return;

	if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f;

	/* hmmmm */
	if (!(ELEM(ibuf->channels, 3, 4))) return;

	scopes->hist.channels = 3;
	scopes->hist.x_resolution = 256;

	switch (scopes->wavefrm_mode) {
		case SCOPES_WAVEFRM_RGB:
			ycc_mode = -1;
			break;
		case SCOPES_WAVEFRM_LUMA:
		case SCOPES_WAVEFRM_YCC_JPEG:
			ycc_mode = BLI_YCC_JFIF_0_255;
			break;
		case SCOPES_WAVEFRM_YCC_601:
			ycc_mode = BLI_YCC_ITU_BT601;
			break;
		case SCOPES_WAVEFRM_YCC_709:
			ycc_mode = BLI_YCC_ITU_BT709;
			break;
	}

	/* 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.01f) * (scopes->accuracy * 0.01f) * ibuf->y;
	
	if (scopes->sample_full)
		scopes->sample_lines = ibuf->y;

	/* scan the image */
	savedlines = 0;
	for (c = 0; c < 3; c++) {
		scopes->minmax[c][0] = 25500.0f;
		scopes->minmax[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);
	if (scopes->vecscope)
		MEM_freeN(scopes->vecscope);
	
	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");
	scopes->vecscope = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel");
	
	if (is_float)
		rf = ibuf->rect_float;
	else
		rc = (unsigned char *)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++) {

			if (is_float) {
				if (use_color_management)
					linearrgb_to_srgb_v3_v3(rgb, rf);
				else
					copy_v3_v3(rgb, rf);
			}
			else {
				for (c = 0; c < 3; c++)
					rgb[c] = rc[c] * INV_255;
			}

			/* we still need luma for histogram */
			luma = rgb_to_luma(rgb);

			/* check for min max */
			if (ycc_mode == -1) {
				for (c = 0; c < 3; c++) {
					if (rgb[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgb[c];
					if (rgb[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgb[c];
				}
			}
			else {
				rgb_to_ycc(rgb[0], rgb[1], rgb[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode);
				for (c = 0; c < 3; c++) {
					ycc[c] *= INV_255;
					if (ycc[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = ycc[c];
					if (ycc[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = ycc[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(luma)] += 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);
			}

			rf += ibuf->channels;
			rc += ibuf->channels;
		}
		if (saveline)
			savedlines += 1;
	}

	/* 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];
		if (bin_g[x] > n)
			n = bin_g[x];
		if (bin_b[x] > n)
			n = bin_b[x];
		if (bin_lum[x] > nl)
			nl = bin_lum[x];
	}
	div = 1.0 / (double)n;
	divl = 1.0 / (double)nl;
	for (x = 0; x < 256; x++) {
		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);
	MEM_freeN(bin_lum);

	scopes->ok = 1;
}
コード例 #7
0
static void node_composit_exec_sepycca(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* input no image? then only color operation */
	if(in[0]->data==NULL) {
		float y, cb, cr;
	
		switch(node->custom1)
		{
		case 1:
			rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_ITU_BT709);
			break;
		case 2:
			rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_JFIF_0_255);
			break;
		case 0:
		default:
			rgb_to_ycc(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &cb, &cr, BLI_YCC_ITU_BT601);
			break;
		}
	
		/*divided by 255 to normalize for viewing in */
		out[0]->vec[0] = y/255.0;
		out[1]->vec[0] = cb/255.0;
		out[2]->vec[0] = cr/255.0;
		out[3]->vec[0] = in[0]->vec[3];
	}
	else if ((out[0]->hasoutput) || (out[1]->hasoutput) || (out[2]->hasoutput) || (out[3]->hasoutput)) {
		/* make copy of buffer so input buffer doesn't get corrupted */
		CompBuf *cbuf= dupalloc_compbuf(in[0]->data);
		CompBuf *cbuf2=typecheck_compbuf(cbuf, CB_RGBA);
	
		/* convert the RGB stackbuf to an HSV representation */
		switch(node->custom1)
		{
		case 1:
			composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_709, CB_RGBA);
			break;
		case 2:
			composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_jfif, CB_RGBA);
			break;
		case 0:
		default:
			composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepycca_601, CB_RGBA);
			break;
		}
	
		/* separate each of those channels */
		if(out[0]->hasoutput)
			out[0]->data= valbuf_from_rgbabuf(cbuf2, CHAN_R);
		if(out[1]->hasoutput)
			out[1]->data= valbuf_from_rgbabuf(cbuf2, CHAN_G);
		if(out[2]->hasoutput)
			out[2]->data= valbuf_from_rgbabuf(cbuf2, CHAN_B);
		if(out[3]->hasoutput)
			out[3]->data= valbuf_from_rgbabuf(cbuf2, CHAN_A);

		/*not used anymore */
		if(cbuf2!=cbuf)
			free_compbuf(cbuf2);
		free_compbuf(cbuf);
	}
}
コード例 #8
0
ファイル: colortools.c プロジェクト: scorpion81/blender-voro
void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
                   const ColorManagedDisplaySettings *display_settings)
{
	int x, y, c;
	unsigned int nl, na, nr, ng, nb;
	double divl, diva, divr, divg, divb;
	float *rf = NULL;
	unsigned char *rc = NULL;
	unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a;
	int savedlines, saveline;
	float rgba[4], ycc[3], luma;
	int ycc_mode = -1;
	const short is_float = (ibuf->rect_float != NULL);

	struct ColormanageProcessor *cm_processor = NULL;

	if (ibuf->rect == NULL && ibuf->rect_float == NULL) return;

	if (scopes->ok == 1) return;

	if (scopes->hist.ymax == 0.f) scopes->hist.ymax = 1.f;

	/* hmmmm */
	if (!(ELEM(ibuf->channels, 3, 4))) return;

	scopes->hist.channels = 3;
	scopes->hist.x_resolution = 256;

	switch (scopes->wavefrm_mode) {
		case SCOPES_WAVEFRM_RGB:
			ycc_mode = -1;
			break;
		case SCOPES_WAVEFRM_LUMA:
		case SCOPES_WAVEFRM_YCC_JPEG:
			ycc_mode = BLI_YCC_JFIF_0_255;
			break;
		case SCOPES_WAVEFRM_YCC_601:
			ycc_mode = BLI_YCC_ITU_BT601;
			break;
		case SCOPES_WAVEFRM_YCC_709:
			ycc_mode = BLI_YCC_ITU_BT709;
			break;
	}

	/* temp table to count pix value for histogram */
	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_a = 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.01f) * (scopes->accuracy * 0.01f) * ibuf->y;
	
	if (scopes->sample_full)
		scopes->sample_lines = ibuf->y;

	/* scan the image */
	savedlines = 0;
	for (c = 0; c < 3; c++) {
		scopes->minmax[c][0] = 25500.0f;
		scopes->minmax[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);
	if (scopes->vecscope)
		MEM_freeN(scopes->vecscope);
	
	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");
	scopes->vecscope = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel");
	
	if (is_float)
		rf = ibuf->rect_float;
	else
		rc = (unsigned char *)ibuf->rect;

	if (ibuf->rect_float)
		cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);

	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++) {

			if (is_float) {
				copy_v4_v4(rgba, rf);
				IMB_colormanagement_processor_apply_v4(cm_processor, rgba);
			}
			else {
				for (c = 0; c < 4; c++)
					rgba[c] = rc[c] * INV_255;
			}

			/* we still need luma for histogram */
			luma = rgb_to_luma(rgba);

			/* check for min max */
			if (ycc_mode == -1) {
				for (c = 0; c < 3; c++) {
					if (rgba[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = rgba[c];
					if (rgba[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = rgba[c];
				}
			}
			else {
				rgb_to_ycc(rgba[0], rgba[1], rgba[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode);
				for (c = 0; c < 3; c++) {
					ycc[c] *= INV_255;
					if (ycc[c] < scopes->minmax[c][0]) scopes->minmax[c][0] = ycc[c];
					if (ycc[c] > scopes->minmax[c][1]) scopes->minmax[c][1] = ycc[c];
				}
			}
			/* increment count for histo*/
			bin_lum[get_bin_float(luma)] += 1;
			bin_r[get_bin_float(rgba[0])] += 1;
			bin_g[get_bin_float(rgba[1])] += 1;
			bin_b[get_bin_float(rgba[2])] += 1;
			bin_a[get_bin_float(rgba[3])] += 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, rgba, ycc);
			}

			rf += ibuf->channels;
			rc += ibuf->channels;
		}
		if (saveline)
			savedlines += 1;
	}

	/* test for nicer distribution even - non standard, leave it out for a while */
#if 0
	for (x = 0; x < 256; x++) {
		bin_lum[x] = sqrt (bin_lum[x]);
		bin_r[x] = sqrt(bin_r[x]);
		bin_g[x] = sqrt(bin_g[x]);
		bin_b[x] = sqrt(bin_b[x]);
		bin_a[x] = sqrt(bin_a[x]);
	}
#endif
	
	/* convert hist data to float (proportional to max count) */
	nl = na = nr = nb = ng = 0;
	for (x = 0; x < 256; x++) {
		if (bin_lum[x] > nl) nl = bin_lum[x];
		if (bin_r[x]   > nr) nr = bin_r[x];
		if (bin_g[x]   > ng) ng = bin_g[x];
		if (bin_b[x]   > nb) nb = bin_b[x];
		if (bin_a[x]   > na) na = bin_a[x];
	}
	divl = 1.0 / (double)nl;
	diva = 1.0 / (double)na;
	divr = 1.0 / (double)nr;
	divg = 1.0 / (double)ng;
	divb = 1.0 / (double)nb;
	for (x = 0; x < 256; x++) {
		scopes->hist.data_luma[x] = bin_lum[x] * divl;
		scopes->hist.data_r[x] = bin_r[x] * divr;
		scopes->hist.data_g[x] = bin_g[x] * divg;
		scopes->hist.data_b[x] = bin_b[x] * divb;
		scopes->hist.data_a[x] = bin_a[x] * diva;
	}
	MEM_freeN(bin_lum);
	MEM_freeN(bin_r);
	MEM_freeN(bin_g);
	MEM_freeN(bin_b);
	MEM_freeN(bin_a);

	if (cm_processor)
		IMB_colormanagement_processor_free(cm_processor);

	scopes->ok = 1;
}
コード例 #9
0
static void scopes_update_cb(void *userdata, void *userdata_chunk, const int y, const int UNUSED(threadid))
{
	const ScopesUpdateData *data = userdata;

	Scopes *scopes = data->scopes;
	const ImBuf *ibuf = data->ibuf;
	struct ColormanageProcessor *cm_processor = data->cm_processor;
	const unsigned char *display_buffer = data->display_buffer;
	const int ycc_mode = data->ycc_mode;

	ScopesUpdateDataChunk *data_chunk = userdata_chunk;
	unsigned int *bin_lum = data_chunk->bin_lum;
	unsigned int *bin_r = data_chunk->bin_r;
	unsigned int *bin_g = data_chunk->bin_g;
	unsigned int *bin_b = data_chunk->bin_b;
	unsigned int *bin_a = data_chunk->bin_a;
	float *min = data_chunk->min;
	float *max = data_chunk->max;

	const float *rf = NULL;
	const unsigned char *rc = NULL;
	const int rows_per_sample_line = ibuf->y / scopes->sample_lines;
	const int savedlines = y / rows_per_sample_line;
	const bool do_sample_line = (savedlines < scopes->sample_lines) && (y % rows_per_sample_line) == 0;
	const bool is_float = (ibuf->rect_float != NULL);

	if (is_float)
		rf = ibuf->rect_float + ((size_t)y) * ibuf->x * ibuf->channels;
	else {
		rc = display_buffer + ((size_t)y) * ibuf->x * ibuf->channels;
	}

	for (int x = 0; x < ibuf->x; x++) {
		float rgba[4], ycc[3], luma;

		if (is_float) {
			switch (ibuf->channels) {
				case 4:
					copy_v4_v4(rgba, rf);
					IMB_colormanagement_processor_apply_v4(cm_processor, rgba);
					break;
				case 3:
					copy_v3_v3(rgba, rf);
					IMB_colormanagement_processor_apply_v3(cm_processor, rgba);
					rgba[3] = 1.0f;
					break;
				case 2:
					copy_v3_fl(rgba, rf[0]);
					rgba[3] = rf[1];
					break;
				case 1:
					copy_v3_fl(rgba, rf[0]);
					rgba[3] = 1.0f;
					break;
				default:
					BLI_assert(0);
			}
		}
		else {
			for (int c = 4; c--;)
				rgba[c] = rc[c] * INV_255;
		}

		/* we still need luma for histogram */
		luma = IMB_colormanagement_get_luminance(rgba);

		/* check for min max */
		if (ycc_mode == -1) {
			minmax_v3v3_v3(min, max, rgba);
		}
		else {
			rgb_to_ycc(rgba[0], rgba[1], rgba[2], &ycc[0], &ycc[1], &ycc[2], ycc_mode);
			mul_v3_fl(ycc, INV_255);
			minmax_v3v3_v3(min, max, ycc);
		}
		/* increment count for histo*/
		bin_lum[get_bin_float(luma)]++;
		bin_r[get_bin_float(rgba[0])]++;
		bin_g[get_bin_float(rgba[1])]++;
		bin_b[get_bin_float(rgba[2])]++;
		bin_a[get_bin_float(rgba[3])]++;

		/* save sample if needed */
		if (do_sample_line) {
			const float fx = (float)x / (float)ibuf->x;
			const int idx = 2 * (ibuf->x * savedlines + x);
			save_sample_line(scopes, idx, fx, rgba, ycc);
		}

		rf += ibuf->channels;
		rc += ibuf->channels;
	}
}