Example #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);
	}
}
Example #2
0
static void streaks(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
{
	CompBuf *bsrc, *tsrc, *tdst, *sbuf;
	int x, y, n;
	unsigned int nump=0;
	fRGB c1, c2, c3, c4;
	float a, ang = 360.f/(float)ndg->angle;

	bsrc = BTP(src, ndg->threshold, 1 << ndg->quality);
	tsrc = dupalloc_compbuf(bsrc); // sample from buffer
	tdst = alloc_compbuf(tsrc->x, tsrc->y, tsrc->type, 1); // sample to buffer
	sbuf = alloc_compbuf(tsrc->x, tsrc->y, tsrc->type, 1);  // streak sum buffer

	
	for (a=0.f; a<360.f; a+=ang) {
		const float an = (a + (float)ndg->angle_ofs)*(float)M_PI/180.f;
		const float vx = cos((double)an), vy = sin((double)an);
		for (n=0; n<ndg->iter; ++n) {
			const float p4 = pow(4.0, (double)n);
			const float vxp = vx*p4, vyp = vy*p4;
			const float wt = pow((double)ndg->fade, (double)p4);
			const float cmo = 1.f - pow((double)ndg->colmod, (double)n+1);	// colormodulation amount relative to current pass
			float* tdstcol = tdst->rect;
			for (y=0; y<tsrc->y; ++y) {
				for (x=0; x<tsrc->x; ++x, tdstcol+=4) {
					// first pass no offset, always same for every pass, exact copy,
					// otherwise results in uneven brightness, only need once
					if (n==0) qd_getPixel(tsrc, x, y, c1); else c1[0]=c1[1]=c1[2]=0;
					qd_getPixelLerp(tsrc, x + vxp,     y + vyp,     c2);
					qd_getPixelLerp(tsrc, x + vxp*2.f, y + vyp*2.f, c3);
					qd_getPixelLerp(tsrc, x + vxp*3.f, y + vyp*3.f, c4);
					// modulate color to look vaguely similar to a color spectrum
					fRGB_rgbmult(c2, 1.f, cmo, cmo);
					fRGB_rgbmult(c3, cmo, cmo, 1.f);
					fRGB_rgbmult(c4, cmo, 1.f, cmo);
					tdstcol[0] = 0.5f*(tdstcol[0] + c1[0] + wt*(c2[0] + wt*(c3[0] + wt*c4[0])));
					tdstcol[1] = 0.5f*(tdstcol[1] + c1[1] + wt*(c2[1] + wt*(c3[1] + wt*c4[1])));
					tdstcol[2] = 0.5f*(tdstcol[2] + c1[2] + wt*(c2[2] + wt*(c3[2] + wt*c4[2])));
				}
			}
			memcpy(tsrc->rect, tdst->rect, sizeof(float)*tdst->x*tdst->y*tdst->type);
		}

		addImage(sbuf, tsrc, 1.f/(float)(6 - ndg->iter));
		memset(tdst->rect, 0, tdst->x*tdst->y*tdst->type*sizeof(float));
		memcpy(tsrc->rect, bsrc->rect, bsrc->x*bsrc->y*bsrc->type*sizeof(float));
		nump++;
	}

	mixImages(dst, sbuf, 0.5f + 0.5f*ndg->mix);

	free_compbuf(tsrc);
	free_compbuf(tdst);
	free_compbuf(sbuf);
	free_compbuf(bsrc);
}
Example #3
0
/* applies to render pipeline */
static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* image assigned to output */
	/* stack order input sockets: col, alpha, z */
	
	if(node->flag & NODE_DO_OUTPUT) {	/* only one works on out */
		Scene *scene= (Scene *)node->id;
		RenderData *rd= data;
		
		if(scene && (rd->scemode & R_DOCOMP)) {
			Render *re= RE_GetRender(scene->id.name);
			RenderResult *rr= RE_AcquireResultWrite(re); 
			if(rr) {
				CompBuf *outbuf, *zbuf=NULL;
				
				if(rr->rectf) 
					MEM_freeN(rr->rectf);
				outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 1);
				
				if(in[1]->data==NULL)
					composit1_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, do_copy_rgba, CB_RGBA);
				else
					composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL);
				
				if(in[2]->data) {
					if(rr->rectz) 
						MEM_freeN(rr->rectz);
					zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 1);
					composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value, CB_VAL);
					rr->rectz= zbuf->rect;
					zbuf->malloc= 0;
					free_compbuf(zbuf);
				}
				generate_preview(data, node, outbuf);
				
				/* we give outbuf to rr... */
				rr->rectf= outbuf->rect;
				outbuf->malloc= 0;
				free_compbuf(outbuf);

				RE_ReleaseResult(re);
				
				/* signal for imageviewer to refresh (it converts to byte rects...) */
				BKE_image_signal(BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"), NULL, IMA_SIGNAL_FREE);
				return;
			}
			else
				RE_ReleaseResult(re);
		}
	}
	if(in[0]->data)
		generate_preview(data, node, in[0]->data);
}
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;
	}
}
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);

	}
}
Example #6
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);

}
Example #7
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);
}
Example #8
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);
	}
};
Example #9
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;
		}
	}
}
Example #10
0
static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
{
	bNodeSocket *sock;
	
	for (sock= node->outputs.first; sock; sock= sock->next) {
		if (sock->cache) {
			free_compbuf(sock->cache);
			sock->cache= NULL;
		}
	}
}
Example #11
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);
	}
}
static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node)
{
	bNodeSocket *sock;
	
	for (sock= node->outputs.first; sock; sock= sock->next) {
		if (sock->cache) {
#ifdef WITH_COMPOSITOR_LEGACY
			free_compbuf(sock->cache);
#endif
			sock->cache= NULL;
		}
	}
}
Example #13
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);
}
Example #14
0
/* Free internal buffers */
static void group_free_internal(bNodeTreeExec *gexec)
{
	bNodeStack *ns;
	int i;
	
	for (i=0, ns=gexec->stack; i < gexec->stacksize; ++i, ++ns) {
		if (!ns->external && !ns->is_copy) {
			if (ns->data) {
				free_compbuf(ns->data);
				ns->data = NULL;
			}
		}
	}
}
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);
	}
}
Example #16
0
static void fglow(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
{
	int x, y;
	float scale, u, v, r, w, d;
	fRGB fcol;
	CompBuf *tsrc, *ckrn;
	unsigned int sz = 1 << ndg->size;
	const float cs_r = 1.f, cs_g = 1.f, cs_b = 1.f;

	// temp. src image
	tsrc = BTP(src, ndg->threshold, 1 << ndg->quality);
	// make the convolution kernel
	ckrn = alloc_compbuf(sz, sz, CB_RGBA, 1);

	scale = 0.25f*sqrtf(sz*sz);

	for (y=0; y<sz; ++y) {
		v = 2.f*(y / (float)sz) - 1.f;
		for (x=0; x<sz; ++x) {
			u = 2.f*(x / (float)sz) - 1.f;
			r = (u*u + v*v)*scale;
			d = -sqrtf(sqrtf(sqrtf(r)))*9.f;
			fcol[0] = expf(d*cs_r), fcol[1] = expf(d*cs_g), fcol[2] = expf(d*cs_b);
			// linear window good enough here, visual result counts, not scientific analysis
			//w = (1.f-fabs(u))*(1.f-fabs(v));
			// actually, Hanning window is ok, cos^2 for some reason is slower
			w = (0.5f + 0.5f*cos((double)u*M_PI))*(0.5f + 0.5f*cos((double)v*M_PI));
			fRGB_mult(fcol, w);
			qd_setPixel(ckrn, x, y, fcol);
		}
	}

	convolve(tsrc, tsrc, ckrn);
	free_compbuf(ckrn);
	mixImages(dst, tsrc, 0.5f + 0.5f*ndg->mix);
	free_compbuf(tsrc);
}
Example #17
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);
	}
}
Example #18
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);
	}
}
Example #19
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);
	}
}
Example #20
0
static void update_node(bNodeTree *ntree, bNode *node)
{
	bNodeSocket *sock;

	for(sock= node->outputs.first; sock; sock= sock->next) {
		if(sock->cache) {
                    if(sock->type < 7)//Only for Blender Sockets
			free_compbuf(sock->cache);
		    sock->cache= NULL;
		}
	}
	node->need_exec= 1;
	
	/* individual node update call */
	if (node->typeinfo->updatefunc)
		node->typeinfo->updatefunc(ntree, node);
}
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);
}
/* while executing tree, free buffers from nodes that are not needed anymore */
static void freeExecutableNode(bNodeTreeExec *exec)
{
	/* node outputs can be freed when:
	 * - not a render result or image node
	 * - when node outputs go to nodes all being set NODE_FINISHED
	 */
	bNodeTree *ntree = exec->nodetree;
	bNodeExec *nodeexec;
	bNode *node;
	bNodeSocket *sock;
	int n;
	
	/* set exec flag for finished nodes that might need freed */
	for (node= ntree->nodes.first; node; node= node->next) {
		if (node->type!=CMP_NODE_R_LAYERS)
			if (node->exec & NODE_FINISHED)
				node->exec |= NODE_FREEBUFS;
	}
	/* clear this flag for input links that are not done yet.
	 * Using the exec data for valid dependency sort.
	 */
	for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
		node = nodeexec->node;
		if ((node->exec & NODE_FINISHED)==0) {
			for (sock= node->inputs.first; sock; sock= sock->next)
				if (sock->link)
					sock->link->fromnode->exec &= ~NODE_FREEBUFS;
		}
	}
	/* now we can free buffers */
	for (node= ntree->nodes.first; node; node= node->next) {
		if (node->exec & NODE_FREEBUFS) {
			for (sock= node->outputs.first; sock; sock= sock->next) {
				bNodeStack *ns= node_get_socket_stack(exec->stack, sock);
				if (ns && ns->data) {
					free_compbuf(ns->data);
					ns->data= NULL;
					// printf("freed buf node %s\n", node->name);
				}
			}
		}
	}
}
Example #23
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);
	}
}
Example #24
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);
};
Example #25
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);
}
Example #26
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);
	}
}
/* return total of executable nodes, for timecursor */
static int setExecutableNodes(bNodeTreeExec *exec, ThreadData *thd)
{
	bNodeTree *ntree = exec->nodetree;
	bNodeStack *nsin[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeStack *nsout[MAX_SOCKET];	/* arbitrary... watch this */
	bNodeExec *nodeexec;
	bNode *node;
	bNodeSocket *sock;
	int n, totnode= 0, group_edit= 0;
	
	/* if we are in group edit, viewer nodes get skipped when group has viewer */
	for (node= ntree->nodes.first; node; node= node->next)
		if (node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT))
			if (ntreeHasType((bNodeTree *)node->id, CMP_NODE_VIEWER))
				group_edit= 1;
	
	/* NB: using the exec data list here to have valid dependency sort */
	for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
		int a;
		node = nodeexec->node;
		
		node_get_stack(node, exec->stack, nsin, nsout);
		
		/* test the outputs */
		/* skip value-only nodes (should be in type!) */
		if (!node_only_value(node)) {
			for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
				if (nsout[a]->data==NULL && nsout[a]->hasoutput) {
					node->need_exec= 1;
					break;
				}
			}
		}
		
		/* test the inputs */
		for (a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
			/* skip viewer nodes in bg render or group edit */
			if ( ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && (G.background || group_edit))
				node->need_exec= 0;
			/* is sock in use? */
			else if (sock->link) {
				bNodeLink *link= sock->link;
				
				/* this is the test for a cyclic case */
				if (link->fromnode==NULL || link->tonode==NULL);
				else if (link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) {
					if (link->fromnode->need_exec) {
						node->need_exec= 1;
						break;
					}
				}
				else {
					node->need_exec= 0;
					printf("Node %s skipped, cyclic dependency\n", node->name);
				}
			}
		}
		
		if (node->need_exec) {
			
			/* free output buffers */
			for (a=0, sock= node->outputs.first; sock; sock= sock->next, a++) {
				if (nsout[a]->data) {
					free_compbuf(nsout[a]->data);
					nsout[a]->data= NULL;
				}
			}
			totnode++;
			/* printf("node needs exec %s\n", node->name); */
			
			/* tag for getExecutableNode() */
			node->exec= 0;
		}
		else {
			/* tag for getExecutableNode() */
			node->exec= NODE_READY|NODE_FINISHED|NODE_SKIPPED;
			
		}
	}
	
	/* last step: set the stack values for only-value nodes */
	/* just does all now, compared to a full buffer exec this is nothing */
	if (totnode) {
		for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) {
			node = nodeexec->node;
			if (node->need_exec==0 && node_only_value(node)) {
				if (node->typeinfo->execfunc) {
					node_get_stack(node, exec->stack, nsin, nsout);
					node->typeinfo->execfunc(thd->rd, node, nsin, nsout);
				}
			}
		}
	}
	
	return totnode;
}
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);
	}
}
Example #29
0
static void ghosts(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
{
	// colormodulation and scale factors (cm & scalef) for 16 passes max: 64
	int x, y, n, p, np;
	fRGB c, tc, cm[64];
	float sc, isc, u, v, sm, s, t, ofs, scalef[64];
	CompBuf *tbuf1, *tbuf2, *gbuf;
	const float cmo = 1.f - ndg->colmod;
	const int qt = 1 << ndg->quality;
	const float s1 = 4.f/(float)qt, s2 = 2.f*s1;

	gbuf = BTP(src, ndg->threshold, qt);
	tbuf1 = dupalloc_compbuf(gbuf);
	IIR_gauss(tbuf1, s1, 0, 3);
	IIR_gauss(tbuf1, s1, 1, 3);
	IIR_gauss(tbuf1, s1, 2, 3);
	tbuf2 = dupalloc_compbuf(tbuf1);
	IIR_gauss(tbuf2, s2, 0, 3);
	IIR_gauss(tbuf2, s2, 1, 3);
	IIR_gauss(tbuf2, s2, 2, 3);

	if (ndg->iter & 1) ofs = 0.5f; else ofs = 0.f;
	for (x=0; x<(ndg->iter*4); x++) {
		y = x & 3;
		cm[x][0] = cm[x][1] = cm[x][2] = 1;
		if (y==1) fRGB_rgbmult(cm[x], 1.f, cmo, cmo);
		if (y==2) fRGB_rgbmult(cm[x], cmo, cmo, 1.f);
		if (y==3) fRGB_rgbmult(cm[x], cmo, 1.f, cmo);
		scalef[x] = 2.1f*(1.f-(x+ofs)/(float)(ndg->iter*4));
		if (x & 1) scalef[x] = -0.99f/scalef[x];
	}

	sc = 2.13;
	isc = -0.97;
	for (y=0; y<gbuf->y; y++) {
		v = (float)(y+0.5f) / (float)gbuf->y;
		for (x=0; x<gbuf->x; x++) {
			u = (float)(x+0.5f) / (float)gbuf->x;
			s = (u-0.5f)*sc + 0.5f, t = (v-0.5f)*sc + 0.5f;
			qd_getPixelLerp(tbuf1, s*gbuf->x, t*gbuf->y, c);
			sm = smoothMask(s, t);
			fRGB_mult(c, sm);
			s = (u-0.5f)*isc + 0.5f, t = (v-0.5f)*isc + 0.5f;
			qd_getPixelLerp(tbuf2, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, tc);
			sm = smoothMask(s, t);
			fRGB_madd(c, tc, sm);
			qd_setPixel(gbuf, x, y, c);
		}
	}

	memset(tbuf1->rect, 0, tbuf1->x*tbuf1->y*tbuf1->type*sizeof(float));
	for (n=1; n<ndg->iter; n++) {
		for (y=0; y<gbuf->y; y++) {
			v = (float)(y+0.5f) / (float)gbuf->y;
			for (x=0; x<gbuf->x; x++) {
				u = (float)(x+0.5f) / (float)gbuf->x;
				tc[0] = tc[1] = tc[2] = 0.f;
				for (p=0;p<4;p++) {
					np = (n<<2) + p;
					s = (u-0.5f)*scalef[np] + 0.5f;
					t = (v-0.5f)*scalef[np] + 0.5f;
					qd_getPixelLerp(gbuf, s*gbuf->x - 0.5f, t*gbuf->y - 0.5f, c);
					fRGB_colormult(c, cm[np]);
					sm = smoothMask(s, t)*0.25f;
					fRGB_madd(tc, c, sm);
				}
				p = (x + y*tbuf1->x)*tbuf1->type;
				tbuf1->rect[p] += tc[0];
				tbuf1->rect[p+1] += tc[1];
				tbuf1->rect[p+2] += tc[2];
			}
		}
		memcpy(gbuf->rect, tbuf1->rect, tbuf1->x*tbuf1->y*tbuf1->type*sizeof(float));
	}

	free_compbuf(tbuf1);
	free_compbuf(tbuf2);

	mixImages(dst, gbuf, 0.5f + 0.5f*ndg->mix);
	free_compbuf(gbuf);
}
Example #30
0
static void star4(NodeGlare* ndg, CompBuf* dst, CompBuf* src)
{
	int x, y, i, xm, xp, ym, yp;
	float c[4] = {0,0,0,0}, tc[4] = {0,0,0,0};
	CompBuf *tbuf1, *tbuf2, *tsrc;
	const float f1 = 1.f - ndg->fade, f2 = (1.f - f1)*0.5f;
	//const float t3 = ndg->threshold*3.f;
	const float sc = (float)(1 << ndg->quality);
	const float isc = 1.f/sc;

	tsrc = BTP(src, ndg->threshold, (int)sc);

	tbuf1 = dupalloc_compbuf(tsrc);
	tbuf2 = dupalloc_compbuf(tsrc);

	for (i=0; i<ndg->iter; i++) {
		// (x || x-1, y-1) to (x || x+1, y+1)
		// F
		for (y=0; y<tbuf1->y; y++) {
			ym = y - i;
			yp = y + i;
			for (x=0; x<tbuf1->x; x++) {
				xm = x - i;
				xp = x + i;
				qd_getPixel(tbuf1, x, y, c);
				fRGB_mult(c, f1);
				qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc);
				fRGB_madd(c, tc, f2);
				qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc);
				fRGB_madd(c, tc, f2);
				qd_setPixel(tbuf1, x, y, c);
			}
		}
		// B
		for (y=tbuf1->y-1; y>=0; y--) {
			ym = y - i;
			yp = y + i;
			for (x=tbuf1->x-1; x>=0; x--) {
				xm = x - i;
				xp = x + i;
				qd_getPixel(tbuf1, x, y, c);
				fRGB_mult(c, f1);
				qd_getPixel(tbuf1, (ndg->angle ? xm : x), ym, tc);
				fRGB_madd(c, tc, f2);
				qd_getPixel(tbuf1, (ndg->angle ? xp : x), yp, tc);
				fRGB_madd(c, tc, f2);
				qd_setPixel(tbuf1, x, y, c);
			}
		}
		// (x-1, y || y+1) to (x+1, y || y-1)
		// F
		for (y=0; y<tbuf2->y; y++) {
			ym = y - i;
			yp = y + i;
			for (x=0; x<tbuf2->x; x++) {
				xm = x - i;
				xp = x + i;
				qd_getPixel(tbuf2, x, y, c);
				fRGB_mult(c, f1);
				qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc);
				fRGB_madd(c, tc, f2);
				qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc);
				fRGB_madd(c, tc, f2);
				qd_setPixel(tbuf2, x, y, c);
			}
		}
		// B
		for (y=tbuf2->y-1; y>=0; y--) {
			ym = y - i;
			yp = y + i;
			for (x=tbuf2->x-1; x>=0; x--) {
				xm = x - i;
				xp = x + i;
				qd_getPixel(tbuf2, x, y, c);
				fRGB_mult(c, f1);
				qd_getPixel(tbuf2, xm, (ndg->angle ? yp : y), tc);
				fRGB_madd(c, tc, f2);
				qd_getPixel(tbuf2, xp, (ndg->angle ? ym : y), tc);
				fRGB_madd(c, tc, f2);
				qd_setPixel(tbuf2, x, y, c);
			}
		}
	}

	for (y=0; y<tbuf1->y; ++y)
		for (x=0; x<tbuf1->x; ++x) {
			unsigned int p = (x + y*tbuf1->x)*tbuf1->type;
			tbuf1->rect[p] += tbuf2->rect[p];
			tbuf1->rect[p+1] += tbuf2->rect[p+1];
			tbuf1->rect[p+2] += tbuf2->rect[p+2];
		}

	for (y=0; y<dst->y; ++y) {
		const float m = 0.5f + 0.5f*ndg->mix;
		for (x=0; x<dst->x; ++x) {
			unsigned int p = (x + y*dst->x)*dst->type;
			qd_getPixelLerp(tbuf1, x*isc, y*isc, tc);
			dst->rect[p] = src->rect[p] + m*(tc[0] - src->rect[p]);
			dst->rect[p+1] = src->rect[p+1] + m*(tc[1] - src->rect[p+1]);
			dst->rect[p+2] = src->rect[p+2] + m*(tc[2] - src->rect[p+2]);
		}
	}

	free_compbuf(tbuf1);
	free_compbuf(tbuf2);
	free_compbuf(tsrc);
}