Exemple #1
0
static void node_composit_exec_displace(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **in, bNodeStack **out)
{
	if(out[0]->hasoutput==0)
		return;
	
	if(in[0]->data && in[1]->data) {
		CompBuf *cbuf= in[0]->data;
		CompBuf *vecbuf= in[1]->data;
		CompBuf *xbuf= in[2]->data;
		CompBuf *ybuf= in[3]->data;
		CompBuf *stackbuf;
		
		cbuf= typecheck_compbuf(cbuf, CB_RGBA);
		vecbuf= typecheck_compbuf(vecbuf, CB_VEC3);
		xbuf= typecheck_compbuf(xbuf, CB_VAL);
		ybuf= typecheck_compbuf(ybuf, CB_VAL);
		
		stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */

		do_displace(stackbuf, cbuf, vecbuf, in[1]->vec, xbuf, ybuf, in[2]->vec, in[3]->vec);
		
		out[0]->data= stackbuf;
		
		
		if(cbuf!=in[0]->data)
			free_compbuf(cbuf);
		if(vecbuf!=in[1]->data)
			free_compbuf(vecbuf);
	}
}
static void node_composit_exec_seprgba(void *UNUSED(data), bNode *UNUSED(node), bNodeStack **in, bNodeStack **out)
{
	/* stack order out: bw channels */
	/* stack order in: col */
	
	/* input no image? then only color operation */
	if (in[0]->data==NULL) {
		out[0]->vec[0] = in[0]->vec[0];
		out[1]->vec[0] = in[0]->vec[1];
		out[2]->vec[0] = in[0]->vec[2];
		out[3]->vec[0] = in[0]->vec[3];
	}
	else {
		/* make sure we get right rgba buffer */
		CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);

		/* don't do any pixel processing, just copy the stack directly (faster, I presume) */
		if (out[0]->hasoutput)
			out[0]->data= valbuf_from_rgbabuf(cbuf, CHAN_R);
		if (out[1]->hasoutput)
			out[1]->data= valbuf_from_rgbabuf(cbuf, CHAN_G);
		if (out[2]->hasoutput)
			out[2]->data= valbuf_from_rgbabuf(cbuf, CHAN_B);
		if (out[3]->hasoutput)
			out[3]->data= valbuf_from_rgbabuf(cbuf, CHAN_A);
		
		if (cbuf!=in[0]->data) 
			free_compbuf(cbuf);

	}
}
static void node_composit_exec_dilateerode(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: mask */
	/* stack order out: mask */
	if (out[0]->hasoutput == 0)
		return;
	
	/* input no image? then only color operation */
	if (in[0]->data == NULL) {
		zero_v4(out[0]->vec);
	}
	else {
		/* make output size of input image */
		CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_VAL);
		CompBuf *stackbuf = dupalloc_compbuf(cbuf);
		short i;
		
		if (node->custom2 > 0) { // positive, dilate
			for (i = 0; i < node->custom2; i++)
				morpho_dilate(stackbuf);
		}
		else if (node->custom2 < 0) { // negative, erode
			for (i = 0; i > node->custom2; i--)
				morpho_erode(stackbuf);
		}
		
		if (cbuf != in[0]->data)
			free_compbuf(cbuf);
		
		out[0]->data = stackbuf;
	}
}
Exemple #4
0
static void node_composit_exec_channel_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	CompBuf *cbuf;
	CompBuf *outbuf;
	
	if(in[0]->hasinput==0)  return;
	if(in[0]->data==NULL) return;
	if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
	
	cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
	
	outbuf=dupalloc_compbuf(cbuf);
	
	/*convert to colorspace*/
	switch(node->custom1) {
	case 1: /*RGB */
		break;
	case 2: /*HSV*/
		composit1_pixel_processor(node, outbuf, cbuf, in[1]->vec, do_rgba_to_hsva, CB_RGBA);
		break;
	case 3: /*YUV*/
		composit1_pixel_processor(node, outbuf, cbuf, in[1]->vec, do_rgba_to_yuva, CB_RGBA);
		break;
	case 4: /*YCC*/
		composit1_pixel_processor(node, outbuf, cbuf, in[1]->vec, do_normalized_rgba_to_ycca2, CB_RGBA);
		break;
	default:
		break;
	}

	/*use the selected channel information to do the key */
	composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_channel_matte, CB_RGBA);

	/*convert back to RGB colorspace in place*/
	switch(node->custom1) {
	case 1: /*RGB*/
		break;
	case 2: /*HSV*/
		composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_hsva_to_rgba, CB_RGBA);
		break;
	case 3: /*YUV*/
		composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_yuva_to_rgba, CB_RGBA);
		break;
	case 4: /*YCC*/
		composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_normalized_ycca_to_rgba2, CB_RGBA);
		break;
	default:
		break;
	}

	generate_preview(data, node, outbuf);
	out[0]->data=outbuf;
	if(out[1]->hasoutput)
		out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A);
	
	if(cbuf!=in[0]->data)
		free_compbuf(cbuf);

}
Exemple #5
0
/* node->custom1 stores if input values are absolute or relative scale */
static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	if(out[0]->hasoutput==0)
		return;
	
	if(in[0]->data) {
		RenderData *rd= data;
		CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
		ImBuf *ibuf;
		int newx, newy;
		
		if(node->custom1==CMP_SCALE_RELATIVE) {
			newx= MAX2((int)(in[1]->vec[0]*cbuf->x), 1);
			newy= MAX2((int)(in[2]->vec[0]*cbuf->y), 1);
		}
		else if(node->custom1==CMP_SCALE_SCENEPERCENT) {
			newx = cbuf->x * (rd->size / 100.0f);
			newy = cbuf->y * (rd->size / 100.0f);
		} else {	/* CMP_SCALE_ABSOLUTE */
			newx= MAX2((int)in[1]->vec[0], 1);
			newy= MAX2((int)in[2]->vec[0], 1);
		}
		newx= MIN2(newx, CMP_SCALE_MAX);
		newy= MIN2(newy, CMP_SCALE_MAX);

		ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0, 0);
		if(ibuf) {
			ibuf->rect_float= cbuf->rect;
			IMB_scaleImBuf(ibuf, newx, newy);
			
			if(ibuf->rect_float == cbuf->rect) {
				/* no scaling happened. */
				stackbuf= pass_on_compbuf(in[0]->data);
			}
			else {
				stackbuf= alloc_compbuf(newx, newy, CB_RGBA, 0);
				stackbuf->rect= ibuf->rect_float;
				stackbuf->malloc= 1;
			}

			ibuf->rect_float= NULL;
			ibuf->mall &= ~IB_rectfloat;
			IMB_freeImBuf(ibuf);
			
			/* also do the translation vector */
			stackbuf->xof = (int)(((float)newx/(float)cbuf->x) * (float)cbuf->xof);
			stackbuf->yof = (int)(((float)newy/(float)cbuf->y) * (float)cbuf->yof);
		}
		else {
			stackbuf= dupalloc_compbuf(cbuf);
			printf("Scaling to %dx%d failed\n", newx, newy);
		}
		
		out[0]->data= stackbuf;
		if(cbuf!=in[0]->data)
			free_compbuf(cbuf);
	}
};
Exemple #6
0
static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	if (in[0]->data) {
		if (node->id) {
			MovieClip *clip = (MovieClip *)node->id;
			CompBuf *cbuf = typecheck_compbuf(in[0]->data, CB_RGBA);
			CompBuf *stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0);
			ImBuf *ibuf;

			ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);

			if (ibuf) {
				RenderData *rd = data;
				ImBuf *obuf;
				MovieTracking *tracking = &clip->tracking;
				int width, height;
				float overscan = 0.0f;
				MovieClipUser user = {0};

				BKE_movieclip_user_set_frame(&user, rd->cfra);

				ibuf->rect_float = cbuf->rect;

				BKE_movieclip_get_size(clip, &user, &width, &height);

				if (!node->storage)
					node->storage = BKE_tracking_distortion_create();

				if (node->custom1 == 0)
					obuf = BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 1);
				else
					obuf = BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 0);

				stackbuf->rect = obuf->rect_float;
				stackbuf->malloc = TRUE;

				obuf->mall &= ~IB_rectfloat;
				obuf->rect_float = NULL;

				IMB_freeImBuf(ibuf);
				IMB_freeImBuf(obuf);
			}

			/* pass on output and free */
			out[0]->data = stackbuf;

			if (cbuf != in[0]->data)
				free_compbuf(cbuf);
		}
		else {
			CompBuf *cbuf = in[0]->data;
			CompBuf *stackbuf = pass_on_compbuf(cbuf);

			out[0]->data = stackbuf;
		}
	}
}
Exemple #7
0
static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	CompBuf *outbuf=0;
	CompBuf *imbuf1=0;
   CompBuf *imbuf2=0;
	NodeChroma *c;
	
	/*is anything connected?*/
	if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;

	/*must have an image imput*/
	if(in[0]->data==NULL) return;

	
	imbuf1=typecheck_compbuf(in[0]->data, CB_RGBA);

   /* if there's an image, use that, if not use the color */
   if(in[1]->data) {
	  imbuf2=typecheck_compbuf(in[1]->data, CB_RGBA);
   }
	
	c=node->storage;
	outbuf=dupalloc_compbuf(imbuf1);
	
	/* note, processor gets a keyvals array passed on as buffer constant */
	composit2_pixel_processor(node, outbuf, imbuf1, in[0]->vec, imbuf2, in[1]->vec, do_diff_matte, CB_RGBA, CB_RGBA);
	
	out[0]->data=outbuf;
	if(out[1]->hasoutput)
		out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A);
	generate_preview(data, node, outbuf);

	if(imbuf1!=in[0]->data)
		free_compbuf(imbuf1);

	if(imbuf2!=in[1]->data)
		free_compbuf(imbuf2);
}
static void node_composit_exec_brightcontrast(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	if (out[0]->hasoutput==0)
		return;
	
	if (in[0]->data) {
		CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
		stackbuf= dupalloc_compbuf(cbuf);
		composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, do_brightnesscontrast, CB_RGBA, CB_VAL, CB_VAL);
		out[0]->data = stackbuf;
		if (cbuf != in[0]->data)
			free_compbuf(cbuf);
	}
}
Exemple #9
0
static void node_composit_exec_transform(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	if (in[0]->data) {
		CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
		CompBuf *stackbuf;

		stackbuf= node_composit_transform(cbuf, in[1]->vec[0], in[2]->vec[0], in[3]->vec[0], in[4]->vec[0], node->custom1);

		/* pass on output and free */
		out[0]->data= stackbuf;

		if (cbuf!=in[0]->data)
			free_compbuf(cbuf);
	}
}
Exemple #10
0
static void node_composit_exec_mapuv(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	if(out[0]->hasoutput==0)
		return;
	
	if(in[0]->data && in[1]->data) {
		CompBuf *cbuf= in[0]->data;
		CompBuf *uvbuf= in[1]->data;
		CompBuf *stackbuf;
		
		cbuf= typecheck_compbuf(cbuf, CB_RGBA);
		uvbuf= typecheck_compbuf(uvbuf, CB_VEC3);
		stackbuf= alloc_compbuf(uvbuf->x, uvbuf->y, CB_RGBA, 1); /* allocs */;
		
		do_mapuv(stackbuf, cbuf, uvbuf, 0.05f*(float)node->custom1);
		
		out[0]->data= stackbuf;
		
		if(cbuf!=in[0]->data)
			free_compbuf(cbuf);
		if(uvbuf!=in[1]->data)
			free_compbuf(uvbuf);
	}
}
Exemple #11
0
static void node_composit_exec_image2cvImage(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
    //TODO: Use atach buffers
	int w,h,x,y;
	float *pixelIn;
	uchar *pixelOut;
	
	if(out[0]->hasoutput==0) return;
	if(in[0]->data){
            
		CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
                out[0]->data=cbuf;
		
	}
}
Exemple #12
0
static void node_composit_exec_premulkey(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	if(out[0]->hasoutput==0)
		return;
	
	if(in[0]->data) {
		CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);

		stackbuf= dupalloc_compbuf(cbuf);
		premul_compbuf(stackbuf, node->custom1 == 1);

		out[0]->data = stackbuf;
		if(cbuf != in[0]->data)
			free_compbuf(cbuf);
	}
}
Exemple #13
0
static void node_composit_exec_view_levels(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	CompBuf* cbuf;
	CompBuf* histogram;
	RenderData *rd=data;
	float mean, std_dev;
	int bins[256];
	int x;

	if(in[0]->hasinput==0)  return;
	if(in[0]->data==NULL) return;

	histogram=alloc_compbuf(256, 256, CB_RGBA, 1);	
	cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);	
		
	/*initalize bins*/
	for(x=0; x<256; x++) {
		bins[x]=0;
	}
	
	/*fill bins */
	fill_bins(node, in[0]->data, bins, rd->color_mgt_flag & R_COLOR_MANAGEMENT);

	/* draw the histogram chart */
	draw_histogram(node, histogram, bins);

	/* calculate the average brightness and contrast */
	mean=brightness_mean(node, in[0]->data);
	std_dev=brightness_standard_deviation(node, in[0]->data, mean);

	/*  Printf debuging ;) 
	printf("Mean: %f\n", mean);
	printf("Std Dev: %f\n", std_dev);
	*/

	if(out[0]->hasoutput)
			out[0]->vec[0]= mean;
	if(out[1]->hasoutput)
			out[1]->vec[0]= std_dev;

	generate_preview(data, node, histogram);

	if(cbuf!=in[0]->data)
		free_compbuf(cbuf);
	free_compbuf(histogram);
}
static void node_composit_exec_distance_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	/*
	 * Loosely based on the Sequencer chroma key plug-in, but enhanced to work in other color spaces and
	 * uses a different difference function (suggested in forums of vfxtalk.com).
	 */
	CompBuf *workbuf;
	CompBuf *inbuf;
	NodeChroma *c;

	/*is anything connected?*/
	if (out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
	/*must have an image imput*/
	if (in[0]->data==NULL) return;

	inbuf=typecheck_compbuf(in[0]->data, CB_RGBA);

	c=node->storage;
	workbuf=dupalloc_compbuf(inbuf);

	/*use the input color*/
	c->key[0] = in[1]->vec[0];
	c->key[1] = in[1]->vec[1];
	c->key[2] = in[1]->vec[2];

	/* work in RGB color space */
	if (c->channel == 1) {
		/* note, processor gets a keyvals array passed on as buffer constant */
		composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_distance_matte, CB_RGBA);
	}
	/* work in YCbCr color space */
	else {
		composit1_pixel_processor(node, workbuf, workbuf, in[0]->vec, do_chroma_distance_matte, CB_RGBA);
	}



	out[0]->data=workbuf;
	if (out[1]->hasoutput)
		out[1]->data=valbuf_from_rgbabuf(workbuf, CHAN_A);
	generate_preview(data, node, workbuf);

	if (inbuf!=in[0]->data)
		free_compbuf(inbuf);
}
Exemple #15
0
static void node_composit_exec_stabilize2d(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	if (in[0]->data && node->id) {
		RenderData *rd= data;
		MovieClip *clip= (MovieClip *)node->id;
		CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
		CompBuf *stackbuf;
		float loc[2], scale, angle;

		BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale, &angle);

		stackbuf= node_composit_transform(cbuf, loc[0], loc[1], angle, scale, node->custom1);

		/* pass on output and free */
		out[0]->data= stackbuf;

		if (cbuf!=in[0]->data)
			free_compbuf(cbuf);
	}
}
Exemple #16
0
static void node_composit_exec_sepyuva(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order out: bw channels */
	/* stack order in: col */
	
	/* input no image? then only color operation */
	if(in[0]->data==NULL) {
		float y, u, v;
	
		rgb_to_yuv(in[0]->vec[0], in[0]->vec[1], in[0]->vec[2], &y, &u, &v);
	
		out[0]->vec[0] = y;
		out[1]->vec[0] = u;
		out[2]->vec[0] = v;
		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 image doesn't get corrupted */
		CompBuf *cbuf= dupalloc_compbuf(in[0]->data);
		CompBuf *cbuf2=typecheck_compbuf(cbuf, CB_RGBA);
	
		/* convert the RGB stackbuf to an YUV representation */
		composit1_pixel_processor(node, cbuf2, cbuf2, in[0]->vec, do_sepyuva, CB_RGBA);
	
		/* 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);
	}
}
Exemple #17
0
static void node_composit_exec_hue_sat(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: Fac, Image */
	/* stack order out: Image */
	if(out[0]->hasoutput==0) return;
	
	/* input no image? then only color operation */
	if(in[1]->data==NULL) {
		do_hue_sat_fac(node, out[0]->vec, in[1]->vec, in[0]->vec);
	}
	else {
		/* make output size of input image */
		CompBuf *cbuf= dupalloc_compbuf(in[1]->data);
		CompBuf *stackbuf=typecheck_compbuf(cbuf,CB_RGBA);
		
		composit2_pixel_processor(node, stackbuf, stackbuf, in[1]->vec, in[0]->data, in[0]->vec, do_hue_sat_fac, CB_RGBA, CB_VAL);

		out[0]->data= stackbuf;

		/* get rid of intermediary cbuf if it's extra */		
		if(stackbuf!=cbuf)
			free_compbuf(cbuf);
	}
}
Exemple #18
0
static void node_composit_exec_chroma_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	CompBuf *cbuf;
	CompBuf *chromabuf;
	NodeChroma *c;
	
	if(in[0]->hasinput==0) return;
	if(in[0]->data==NULL) return;
	if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
	
	cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
	
	chromabuf= dupalloc_compbuf(cbuf);
	
	c=node->storage;
	
	/*convert rgbbuf to normalized chroma space*/
	composit1_pixel_processor(node, chromabuf, cbuf, in[0]->vec, do_rgba_to_ycca_normalized, CB_RGBA);
	/*convert key to normalized chroma color space */
	do_rgba_to_ycca_normalized(node, c->key, in[1]->vec);
	
	/*per pixel chroma key*/
	composit1_pixel_processor(node, chromabuf, chromabuf, in[0]->vec, do_chroma_key, CB_RGBA);
	
	/*convert back*/
	composit1_pixel_processor(node, chromabuf, chromabuf, in[0]->vec, do_ycca_to_rgba_normalized, CB_RGBA);
	
	out[0]->data= chromabuf;
	if(out[1]->hasoutput)
		out[1]->data= valbuf_from_rgbabuf(chromabuf, CHAN_A);
	
	generate_preview(data, node, chromabuf);

	if(cbuf!=in[0]->data)
		free_compbuf(cbuf);
};
Exemple #19
0
static void node_composit_exec_luma_matte(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	CompBuf *cbuf;
	CompBuf *outbuf;
	
	if(in[0]->hasinput==0)  return;
	if(in[0]->data==NULL) return;
	if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return;
	
	cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
	
	outbuf=dupalloc_compbuf(cbuf);

	composit1_pixel_processor(node, outbuf, cbuf, in[1]->vec, do_rgba_to_yuva, CB_RGBA);
	composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_luma_matte, CB_RGBA);
	composit1_pixel_processor(node, outbuf, outbuf, in[1]->vec, do_yuva_to_rgba, CB_RGBA);
	
	generate_preview(data, node, outbuf);
	out[0]->data=outbuf;
	if (out[1]->hasoutput)
		out[1]->data=valbuf_from_rgbabuf(outbuf, CHAN_A);
	if(cbuf!=in[0]->data)
		free_compbuf(cbuf);
}
static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* Originally based on the information from the book "The Art and Science of Digital Composition" and
	 * discussions from vfxtalk.com .*/
	CompBuf *cbuf;
	/* CompBuf *mask; */ /* UNUSED */
	CompBuf *rgbbuf;
	CompBuf *spillmap;
	NodeColorspill *ncs;
	ncs=node->storage;

	/* early out for missing connections */
	if(out[0]->hasoutput==0 ) return;
	if(in[0]->hasinput==0) return;
	if(in[0]->data==NULL) return;
	
	cbuf=typecheck_compbuf(in[0]->data, CB_RGBA);
	/* mask= */ /* UNUSED */ typecheck_compbuf(in[1]->data, CB_VAL);
	spillmap=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
	rgbbuf=dupalloc_compbuf(cbuf);

	switch(node->custom1)
	{
		case 1:  /*red spill*/
		{
			switch(node->custom2)
			{
				case 0: /* simple limit */
				{
					if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
						composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_red, CB_RGBA);
					} else {
						composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_red_fac, CB_RGBA,  CB_VAL);
					}
					break;
				}
				case 1: /* average limit */
				{
					if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
						composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_red, CB_RGBA);
					} else {
						composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_red_fac, CB_RGBA,  CB_VAL);
					}
					break;
				}
			}
			if(ncs->unspill==0) {
				ncs->uspillr=1.0f;
				ncs->uspillg=0.0f;
				ncs->uspillb=0.0f;
			}
			composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_red, CB_RGBA, CB_VAL);
			break;
		}
		case 2: /*green spill*/
		{
			switch(node->custom2)
			{
				case 0: /* simple limit */
				{
					if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
						composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_green, CB_RGBA);
					} else {
						composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_green_fac, CB_RGBA,  CB_VAL);
					}
					break;
				}
				case 1: /* average limit */
				{
					if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
						composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_green, CB_RGBA);
					} else {
						composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_green_fac, CB_RGBA,  CB_VAL);
					}
					break;
				}
			}
			if(ncs->unspill==0) {
				ncs->uspillr=0.0f;
				ncs->uspillg=1.0f;
				ncs->uspillb=0.0f;
			}
			composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_green, CB_RGBA, CB_VAL);
			break;
		}
		case 3: /*blue spill*/
		{
			switch(node->custom2)
			{
				case 0: /* simple limit */
				{
					if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
						composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_simple_spillmap_blue, CB_RGBA);
					} else {
						composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_simple_spillmap_blue_fac, CB_RGBA,  CB_VAL);
					}
					break;
				}
				case 1: /* average limit */
				{
					if ((in[1]->data==NULL) && (in[1]->vec[0] >= 1.f)) {
						composit1_pixel_processor(node, spillmap, cbuf, in[0]->vec, do_average_spillmap_blue, CB_RGBA);
					} else {
						composit2_pixel_processor(node, spillmap, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_average_spillmap_blue_fac, CB_RGBA,  CB_VAL);
					}
					break;
				}
			}
			if(ncs->unspill==0) {
				ncs->uspillr=0.0f;
				ncs->uspillg=0.0f;
				ncs->uspillb=1.0f;
			}
			composit2_pixel_processor(node, rgbbuf, cbuf, in[0]->vec, spillmap, NULL, do_apply_spillmap_blue, CB_RGBA, CB_VAL);
			break;
		}
		default:
			break;
	}

	out[0]->data=rgbbuf;

	if(cbuf!=in[0]->data)
		free_compbuf(cbuf);

	free_compbuf(spillmap);
}
/* only supports RGBA nodes now */
static void node_composit_exec_rotate(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{

	if(out[0]->hasoutput==0)
		return;

	if(in[0]->data) {
		CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA);
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1);	/* note, this returns zero'd image */
		float rad, u, v, s, c, centx, centy, miny, maxy, minx, maxx;
		int x, y, yo, xo;
		ImBuf *ibuf, *obuf;

		rad= (M_PI*in[1]->vec[0])/180.0f;

		s= sin(rad);
		c= cos(rad);
		centx= cbuf->x/2;
		centy= cbuf->y/2;

		minx= -centx;
		maxx= -centx + (float)cbuf->x;
		miny= -centy;
		maxy= -centy + (float)cbuf->y;


		ibuf=IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
		obuf=IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0);

		if(ibuf && obuf){
			ibuf->rect_float=cbuf->rect;
			obuf->rect_float=stackbuf->rect;

			for(y=miny; y<maxy; y++) {
				yo= y+(int)centy;

				for(x=minx; x<maxx;x++) {
					u=c*x + y*s + centx;
					v=-s*x + c*y + centy;
					xo= x+(int)centx;

					switch(node->custom1) {
					case 0:
						neareast_interpolation(ibuf, obuf, u, v, xo, yo);
						break ;
					case 1:
						bilinear_interpolation(ibuf, obuf, u, v, xo, yo);
						break;
					case 2:
						bicubic_interpolation(ibuf, obuf, u, v, xo, yo);
						break;
					}

				}
			}

			/* rotate offset vector too, but why negative rad, ehh?? Has to be replaced with [3][3] matrix once (ton) */
			s= sin(-rad);
			c= cos(-rad);
			centx= (float)cbuf->xof; centy= (float)cbuf->yof;
			stackbuf->xof= (int)( c*centx + s*centy);
			stackbuf->yof= (int)(-s*centx + c*centy);

			IMB_freeImBuf(ibuf);
			IMB_freeImBuf(obuf);
		}

		/* pass on output and free */
		out[0]->data= stackbuf;
		if(cbuf!=in[0]->data) {
			free_compbuf(cbuf);
		}
	}
}
/* write input data into individual files */
static void exec_output_file_singlelayer(RenderData *rd, bNode *node, bNodeStack **in)
{
	Main *bmain= G.main; /* TODO, have this passed along */
	NodeImageMultiFile *nimf= node->storage;
	bNodeSocket *sock;
	int i;
	int has_preview = 0;
	
	for (sock=node->inputs.first, i=0; sock; sock=sock->next, ++i) {
		if (in[i]->data) {
			NodeImageMultiFileSocket *sockdata = sock->storage;
			ImageFormatData *format = (sockdata->use_node_format ? &nimf->format : &sockdata->format);
			char path[FILE_MAX];
			char filename[FILE_MAX];
			CompBuf *cbuf;
			ImBuf *ibuf;
			
			switch (format->planes) {
			case R_IMF_PLANES_BW:
				cbuf = typecheck_compbuf(in[i]->data, CB_VAL);
				break;
			case R_IMF_PLANES_RGB:
				cbuf = typecheck_compbuf(in[i]->data, CB_VEC3);
				break;
			case R_IMF_PLANES_RGBA:
				cbuf = typecheck_compbuf(in[i]->data, CB_RGBA);
				break;
			}
			
			ibuf = IMB_allocImBuf(cbuf->x, cbuf->y, format->planes, 0);
			/* XXX have to set this explicitly it seems */
			switch (format->planes) {
			case R_IMF_PLANES_BW:	ibuf->channels = 1;	break;
			case R_IMF_PLANES_RGB:	ibuf->channels = 3;	break;
			case R_IMF_PLANES_RGBA:	ibuf->channels = 4;	break;
			}
			ibuf->rect_float = cbuf->rect;
			ibuf->dither = rd->dither_intensity;
			
			if (rd->color_mgt_flag & R_COLOR_MANAGEMENT)
				ibuf->profile = IB_PROFILE_LINEAR_RGB;
			
			/* get full path */
			BLI_join_dirfile(path, FILE_MAX, nimf->base_path, sockdata->path);
			BKE_makepicstring(filename, path, bmain->name, rd->cfra, format->imtype, (rd->scemode & R_EXTENSION), TRUE);
			
			if (0 == BKE_imbuf_write(ibuf, filename, format))
				printf("Cannot save Node File Output to %s\n", filename);
			else
				printf("Saved: %s\n", filename);
			
			IMB_freeImBuf(ibuf);
			
			/* simply pick the first valid input for preview */
			if (!has_preview) {
				generate_preview(rd, node, cbuf);
				has_preview = 1;
			}
			
			if (in[i]->data != cbuf) 
				free_compbuf(cbuf);
		}
	}
}
static void node_composit_exec_splitviewer(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(out))
{
	/* image assigned to output */
	/* stack order input sockets: image image */
	
	if(in[0]->data==NULL || in[1]->data==NULL)
		return;
	
	if(node->id && (node->flag & NODE_DO_OUTPUT)) {	/* only one works on out */
		Image *ima= (Image *)node->id;
		RenderData *rd= data;
		ImBuf *ibuf;
		CompBuf *cbuf, *buf1, *buf2, *mask;
		int x, y;
		float offset;
		void *lock;
		
		buf1= typecheck_compbuf(in[0]->data, CB_RGBA);
		buf2= typecheck_compbuf(in[1]->data, CB_RGBA);
		
		BKE_image_user_calc_frame(node->storage, rd->cfra, 0);
		
		/* always returns for viewer image, but we check nevertheless */
		ibuf= BKE_image_acquire_ibuf(ima, node->storage, &lock);
		if(ibuf==NULL) {
			printf("node_composit_exec_viewer error\n");
			BKE_image_release_ibuf(ima, lock);
			return;
		}
		
		/* free all in ibuf */
		imb_freerectImBuf(ibuf);
		imb_freerectfloatImBuf(ibuf);
		IMB_freezbuffloatImBuf(ibuf);
		
		/* make ibuf, and connect to ima */
		ibuf->x= buf1->x;
		ibuf->y= buf1->y;
		imb_addrectfloatImBuf(ibuf);
		
		ima->ok= IMA_OK_LOADED;

		/* output buf */
		cbuf= alloc_compbuf(buf1->x, buf1->y, CB_RGBA, 0);	/* no alloc*/
		cbuf->rect= ibuf->rect_float;
		
		/* mask buf */
		mask= alloc_compbuf(buf1->x, buf1->y, CB_VAL, 1);
		
		
		/* Check which offset mode is selected and limit offset if needed */
		if(node->custom2 == 0) {
			offset = buf1->x / 100.0f * node->custom1;
			CLAMP(offset, 0, buf1->x);
		}
		else {
			offset = buf1->y / 100.0f * node->custom1;
			CLAMP(offset, 0, buf1->y);
		}
		
		if(node->custom2 == 0) {
			for(y=0; y<buf1->y; y++) {
				float *fac= mask->rect + y*buf1->x;
				for(x=offset; x>0; x--, fac++)
					*fac= 1.0f;
			}
		}
		else {
			for(y=0; y<offset; y++) {
				float *fac= mask->rect + y*buf1->x;
				for(x=buf1->x; x>0; x--, fac++)
					*fac= 1.0f;
			}
		}
		
		composit3_pixel_processor(node, cbuf, buf1, in[0]->vec, buf2, in[1]->vec, mask, NULL, do_copy_split_rgba, CB_RGBA, CB_RGBA, CB_VAL);
		
		BKE_image_release_ibuf(ima, lock);
		
		generate_preview(data, node, cbuf);
		free_compbuf(cbuf);
		free_compbuf(mask);
		
		if(in[0]->data != buf1) 
			free_compbuf(buf1);
		if(in[1]->data != buf2) 
			free_compbuf(buf2);
	}
}
Exemple #24
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);
	}
}