Beispiel #1
0
static void node_composit_exec_math(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	CompBuf *cbuf=in[0]->data;
	CompBuf *cbuf2=in[1]->data;
	CompBuf *stackbuf; 

	/* check for inputs and outputs for early out*/
	if(out[0]->hasoutput==0) return;

	/* no image-color operation */
	if(in[0]->data==NULL && in[1]->data==NULL) {
		do_math(node, out[0]->vec, in[0]->vec, in[1]->vec);
		return;
	}

	/*create output based on first input */
	if(cbuf) {
		stackbuf=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1);
	}
	/* and if it doesn't exist use the second input since we 
	 know that one of them must exist at this point*/
	else  {
		stackbuf=alloc_compbuf(cbuf2->x, cbuf2->y, CB_VAL, 1);
	}

	/* operate in case there's valid size */
	composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_math, CB_VAL, CB_VAL);
	out[0]->data= stackbuf;
}
Beispiel #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);
}
Beispiel #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_valtorgb(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: fac */
	/* stack order out: col, alpha */
	
	if(out[0]->hasoutput==0 && out[1]->hasoutput==0) 
		return;
	
	if(node->storage) {
		/* input no image? then only color operation */
		if(in[0]->data==NULL) {
			do_colorband(node->storage, in[0]->vec[0], out[0]->vec);
		}
		else {
			/* make output size of input image */
			CompBuf *cbuf= in[0]->data;
			CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
			
			composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_colorband_composit, CB_VAL);
			
			out[0]->data= stackbuf;
			
			if(out[1]->hasoutput)
				out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);

		}
	}
}
Beispiel #5
0
static void node_composit_exec_alphaover(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: col col */
	/* stack order out: col */
	if(out[0]->hasoutput==0) 
		return;
	
	/* input no image? then only color operation */
	if(in[1]->data==NULL && in[2]->data==NULL) {
		do_alphaover_premul(node, out[0]->vec, in[1]->vec, in[2]->vec, in[0]->vec);
	}
	else {
		/* make output size of input image */
		CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
		NodeTwoFloats *ntf= node->storage;
		
		if(ntf->x != 0.0f)
			composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_mixed, CB_RGBA, CB_RGBA, CB_VAL);
		else if(node->custom1)
			composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_key, CB_RGBA, CB_RGBA, CB_VAL);
		else
			composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, in[0]->vec, do_alphaover_premul, CB_RGBA, CB_RGBA, CB_VAL);
		
		out[0]->data= stackbuf;
	}
}
Beispiel #6
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);
	}
}
Beispiel #7
0
static void node_composit_exec_huecorrect(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	CompBuf *cbuf= in[1]->data;
	CompBuf *stackbuf;
	
	/* stack order input:  fac, image, black level, white level */
	/* stack order output: image */
	
	if(out[0]->hasoutput==0)
		return;

	if(in[0]->vec[0] == 0.f && in[0]->data == NULL) {
		out[0]->data = pass_on_compbuf(cbuf);
		return;
	}
	
	/* input no image? then only color operation */
	if(in[1]->data==NULL) {
		do_huecorrect_fac(node, out[0]->vec, in[1]->vec, in[0]->vec);
	}
	
	if (cbuf) {
		stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* make output size of input image */
		
		if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f))
			composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_huecorrect, CB_RGBA);
		else
			composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_huecorrect_fac, CB_RGBA, CB_VAL);
		
		out[0]->data= stackbuf;
	}
	
}
Beispiel #8
0
static void node_composit_exec_combyuva(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order out: 1 rgba channels */
	/* stack order in: 4 value channels */
	
	/* input no image? then only color operation */
	if((in[0]->data==NULL) && (in[1]->data==NULL) && (in[2]->data==NULL) && (in[3]->data==NULL)) {
		out[0]->vec[0] = in[0]->vec[0];
		out[0]->vec[1] = in[1]->vec[0];
		out[0]->vec[2] = in[2]->vec[0];
		out[0]->vec[3] = in[3]->vec[0];
	}
	else {
		/* make output size of first available input image */
		CompBuf *cbuf;
		CompBuf *stackbuf;

		/* allocate a CompBuf the size of the first available input */
		if (in[0]->data) cbuf = in[0]->data;
		else if (in[1]->data) cbuf = in[1]->data;
		else if (in[2]->data) cbuf = in[2]->data;
		else cbuf = in[3]->data;
		
		stackbuf = alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
		
		composit4_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, 
								  in[2]->data, in[2]->vec, in[3]->data, in[3]->vec, 
								  do_comb_yuva, CB_VAL, CB_VAL, CB_VAL, CB_VAL);

		out[0]->data= stackbuf;
	}	
}
Beispiel #9
0
static void node_composit_exec_setalpha(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order out: RGBA image */
	/* stack order in: col, alpha */
	
	/* input no image? then only color operation */
	if(in[0]->data==NULL && in[1]->data==NULL) {
		out[0]->vec[0] = in[0]->vec[0];
		out[0]->vec[1] = in[0]->vec[1];
		out[0]->vec[2] = in[0]->vec[2];
		out[0]->vec[3] = in[1]->vec[0];
	}
	else {
		/* make output size of input image */
		CompBuf *cbuf= in[0]->data?in[0]->data:in[1]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
		
		if(in[1]->data==NULL && in[1]->vec[0]==1.0f) {
			/* pass on image */
			composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_copy_rgb, CB_RGBA);
		}
		else {
			/* send an compbuf or a value to set as alpha - composit2_pixel_processor handles choosing the right one */
			composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba, CB_RGBA, CB_VAL);
		}
	
		out[0]->data= stackbuf;
	}
}
Beispiel #10
0
static void node_composit_exec_invert(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: fac, Image, Image */
	/* stack order out: Image */
	float *fac= in[0]->vec;
	
	if(out[0]->hasoutput==0) return;
	
	/* input no image? then only color operation */
	if(in[1]->data==NULL && in[0]->data==NULL) {
		do_invert_fac(node, out[0]->vec, in[1]->vec, fac);
	}
	else {
		/* make output size of first available input image, or then size of fac */
		CompBuf *cbuf= in[1]->data?in[1]->data:in[0]->data;

		/* if neither RGB or A toggled on, pass through */
		if (node->custom1 != 0) {
			CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
			
			if (fac[0] < 1.0f || in[0]->data!=NULL)
				composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, fac, do_invert_fac, CB_RGBA, CB_VAL);
			else
				composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_invert, CB_RGBA);
			out[0]->data= stackbuf;
			return;
			
		} else {
			out[0]->data = pass_on_compbuf(cbuf);
			return;
		}
	}
}
Beispiel #11
0
/* generates normal, does dot product */
static void node_composit_exec_normal(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	bNodeSocket *sock= node->outputs.first;
	float *nor= ((bNodeSocketValueVector*)sock->default_value)->value;
	/* stack order input:  normal */
	/* stack order output: normal, value */
	
	/* input no image? then only vector op */
	if(in[0]->data==NULL) {
		VECCOPY(out[0]->vec, nor);
		/* render normals point inside... the widget points outside */
		out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec);
	}
	else if(out[1]->hasoutput) {
		/* make output size of input image */
		CompBuf *cbuf= in[0]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */
		
		composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_normal, CB_VEC3);
		
		out[1]->data= stackbuf;
	}
	
	
}
static void node_composit_exec_curve_rgb(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order input:  fac, image, black level, white level */
	/* stack order output: image */
	
	if (out[0]->hasoutput==0)
		return;

	curvemapping_initialize(node->storage);

	/* input no image? then only color operation */
	if (in[1]->data==NULL) {
		curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[1]->vec);
	}
	else {
		/* make output size of input image */
		CompBuf *cbuf= in[1]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
		
		curvemapping_set_black_white(node->storage, in[2]->vec, in[3]->vec);
		
		if (in[0]->data==NULL && in[0]->vec[0] == 1.0f)
			composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA);
		else
			composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_curves_fac, CB_RGBA, CB_VAL);
		
		out[0]->data= stackbuf;
	}
	
}
Beispiel #13
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);
	}
};
Beispiel #14
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;
		}
	}
}
static CompBuf *node_composit_get_movieclip(RenderData *rd, MovieClip *clip, MovieClipUser *user)
{
	ImBuf *orig_ibuf, *ibuf;
	CompBuf *stackbuf;
	int type;

	float *rect;
	int alloc = FALSE;

	orig_ibuf = BKE_movieclip_get_ibuf(clip, user);

	if (orig_ibuf == NULL || (orig_ibuf->rect == NULL && orig_ibuf->rect_float == NULL)) {
		IMB_freeImBuf(orig_ibuf);
		return NULL;
	}

	ibuf = IMB_dupImBuf(orig_ibuf);
	IMB_freeImBuf(orig_ibuf);

	if (ibuf->rect_float == NULL || (ibuf->userflags & IB_RECT_INVALID)) {
		IMB_float_from_rect(ibuf);
		ibuf->userflags &= ~IB_RECT_INVALID;
	}

	/* now we need a float buffer from the image with matching color management */
	if (ibuf->channels == 4) {
		rect = node_composit_get_float_buffer(rd, ibuf, &alloc);
	}
	else {
		/* non-rgba passes can't use color profiles */
		rect = ibuf->rect_float;
	}
	/* done coercing into the correct color management */

	if (!alloc) {
		rect = MEM_dupallocN(rect);
		alloc = TRUE;
	}

	type = ibuf->channels;

	if (rd->scemode & R_COMP_CROP) {
		stackbuf = get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type);
		if (alloc)
			MEM_freeN(rect);
	}
	else {
		/* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
		stackbuf = alloc_compbuf(ibuf->x, ibuf->y, type, FALSE);
		stackbuf->rect = rect;
		stackbuf->malloc = alloc;
	}

	IMB_freeImBuf(ibuf);

	return stackbuf;
}
Beispiel #16
0
static void node_composit_exec_crop(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	if(in[0]->data) {
		NodeTwoXYs *ntxy= node->storage;
		CompBuf *cbuf= in[0]->data;
		CompBuf *stackbuf;
		int x, y;
		float *srcfp, *outfp;
		rcti outputrect;

		if(node->custom2) {
			ntxy->x1= cbuf->x* ntxy->fac_x1;
			ntxy->x2= cbuf->x* ntxy->fac_x2;
			ntxy->y1= cbuf->y* ntxy->fac_y1;
			ntxy->y2= cbuf->y* ntxy->fac_y2;
		}

		/* check input image size */
		if(cbuf->x <= ntxy->x1 + 1)
			ntxy->x1= cbuf->x - 1;

		if(cbuf->y <= ntxy->y1 + 1)
			ntxy->y1= cbuf->y - 1;

		if(cbuf->x <= ntxy->x2 + 1)
			ntxy->x2= cbuf->x - 1;

		if(cbuf->y <= ntxy->y2 + 1)
			ntxy->y2= cbuf->y - 1;

		/* figure out the minimums and maximums */
		outputrect.xmax=MAX2(ntxy->x1, ntxy->x2) + 1;
		outputrect.xmin=MIN2(ntxy->x1, ntxy->x2);
		outputrect.ymax=MAX2(ntxy->y1, ntxy->y2) + 1;
		outputrect.ymin=MIN2(ntxy->y1, ntxy->y2);

		if(node->custom1) {
			/* this option crops the image size too  */	
			stackbuf= get_cropped_compbuf(&outputrect, cbuf->rect, cbuf->x, cbuf->y, cbuf->type);
		}
		else {
			/* this option won't crop the size of the image as well  */
			/* allocate memory for the output image            */
			stackbuf = alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1);

			/* select the cropped part of the image and set it to the output */
			for(y=outputrect.ymin; y<outputrect.ymax; y++){
				srcfp= cbuf->rect     + (y * cbuf->x     + outputrect.xmin) * cbuf->type;
				outfp= stackbuf->rect + (y * stackbuf->x + outputrect.xmin) * stackbuf->type;
				for(x=outputrect.xmin; x<outputrect.xmax; x++, outfp+= stackbuf->type, srcfp+= cbuf->type)
							memcpy(outfp, srcfp, sizeof(float)*stackbuf->type);
			}
		}

		out[0]->data= stackbuf;
	}
}
Beispiel #17
0
/* note: this function is used for multilayer too, to ensure uniform 
   handling with BKE_image_get_ibuf() */
static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
{
	ImBuf *ibuf;
	CompBuf *stackbuf;
	int type;

	float *rect;
	int alloc= FALSE;

	ibuf= BKE_image_get_ibuf(ima, iuser);
	if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
		return NULL;
	}

	if (ibuf->rect_float == NULL) {
		IMB_float_from_rect(ibuf);
	}

	/* now we need a float buffer from the image with matching color management */
	/* XXX weak code, multilayer is excluded from this */
	rect= ibuf->rect_float;
	
	/* done coercing into the correct color management */


	type= ibuf->channels;
	
	if(rd->scemode & R_COMP_CROP) {
		stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type);
		if(alloc)
			MEM_freeN(rect);
	}
	else {
		/* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
		stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE);
		stackbuf->rect= rect;
		stackbuf->malloc= alloc;
	}
	
	/*code to respect the premul flag of images; I'm
	  not sure if this is a good idea for multilayer images,
	  since it never worked before for them.
	if (type==CB_RGBA && ima->flag & IMA_DO_PREMUL) {
		//premul the image
		int i;
		float *pixel = stackbuf->rect;
		
		for (i=0; i<stackbuf->x*stackbuf->y; i++, pixel += 4) {
			pixel[0] *= pixel[3];
			pixel[1] *= pixel[3];
			pixel[2] *= pixel[3];
		}
	}
	*/
	return stackbuf;
}
Beispiel #18
0
static void node_composit_exec_filter(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	static float soft[9]= {1/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 4/16.0f, 2/16.0f, 1/16.0f, 2/16.0f, 1/16.0f};
	float sharp[9]= {-1,-1,-1,-1,9,-1,-1,-1,-1};
	float laplace[9]= {-1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f, 1.0f, -1/8.0f, -1/8.0f, -1/8.0f, -1/8.0f};
	float sobel[9]= {1,2,1,0,0,0,-1,-2,-1};
	float prewitt[9]= {1,1,1,0,0,0,-1,-1,-1};
	float kirsch[9]= {5,5,5,-3,-3,-3,-2,-2,-2};
	float shadow[9]= {1,2,1,0,1,0,-1,-2,-1};
	
	if(out[0]->hasoutput==0) return;
	
	/* stack order in: Image */
	/* stack order out: Image */
	
	if(in[1]->data) {
		/* make output size of first available input image */
		CompBuf *cbuf= in[1]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1); /* allocs */
		
		/* warning note: xof and yof are applied in pixelprocessor, but should be copied otherwise? */
		stackbuf->xof= cbuf->xof;
		stackbuf->yof= cbuf->yof;
		
		switch(node->custom1) {
			case CMP_FILT_SOFT:
				do_filter3(stackbuf, cbuf, soft, in[0]->vec[0]);
				break;
			case CMP_FILT_SHARP:
				do_filter3(stackbuf, cbuf, sharp, in[0]->vec[0]);
				break;
			case CMP_FILT_LAPLACE:
				do_filter3(stackbuf, cbuf, laplace, in[0]->vec[0]);
				break;
			case CMP_FILT_SOBEL:
				do_filter_edge(stackbuf, cbuf, sobel, in[0]->vec[0]);
				break;
			case CMP_FILT_PREWITT:
				do_filter_edge(stackbuf, cbuf, prewitt, in[0]->vec[0]);
				break;
			case CMP_FILT_KIRSCH:
				do_filter_edge(stackbuf, cbuf, kirsch, in[0]->vec[0]);
				break;
			case CMP_FILT_SHADOW:
				do_filter3(stackbuf, cbuf, shadow, in[0]->vec[0]);
				break;
		}
			
		out[0]->data= stackbuf;
		
		generate_preview(data, node, out[0]->data);
	}
}
Beispiel #19
0
static void node_composit_exec_colorbalance(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	CompBuf *cbuf= in[1]->data;
	CompBuf *stackbuf;
	
	/* stack order input:  fac, image */
	/* stack order output: image */
	if(out[0]->hasoutput==0) return;
	
	if(in[0]->vec[0] == 0.f && in[0]->data == NULL) {
		out[0]->data = pass_on_compbuf(cbuf);
		return;
	}

	{
		NodeColorBalance *n= (NodeColorBalance *)node->storage;
		int c;

		for (c = 0; c < 3; c++) {
			n->lift_lgg[c] = 2.0f - n->lift[c];
			n->gamma_inv[c] = (n->gamma[c] != 0.0f) ? 1.0f/n->gamma[c] : 1000000.0f;
		}
	}

	if (cbuf) {
		stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* create output based on image input */
			
		if (node->custom1 == 0) {
			/* lift gamma gain */
			if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f)) {
				composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_colorbalance_lgg, CB_RGBA);
			}
			else {
				composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_colorbalance_lgg_fac, CB_RGBA, CB_VAL);
			}
		} else {
			/* offset/power/slope : ASC-CDL */
			if ((in[0]->data==NULL) && (in[0]->vec[0] >= 1.f)) {
				composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_colorbalance_cdl, CB_RGBA);
			}
			else {
				composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_colorbalance_cdl_fac, CB_RGBA, CB_VAL);
			}
			
		}

		out[0]->data=stackbuf;
	}
}
Beispiel #20
0
static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
{
	Scene *sce= (Scene *)node->id;
	Render *re= (sce)? RE_GetRender(sce->id.name): NULL;
	RenderData *rd= data;
	RenderResult *rr= NULL;

	if(re)
		rr= RE_AcquireResultRead(re);

	if(rr) {
		SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
		if(srl) {
			RenderLayer *rl= RE_GetRenderLayer(rr, srl->name);
			if(rl && rl->rectf) {
				CompBuf *stackbuf;

				/* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */
				if(rd->scemode & R_COMP_CROP)
					stackbuf= get_cropped_compbuf(&rd->disprect, rl->rectf, rr->rectx, rr->recty, CB_RGBA);
				else {
					stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0);
					stackbuf->rect= rl->rectf;
				}
				if(stackbuf==NULL) {
					printf("Error; Preview Panel in UV Window returns zero sized image\n");
				}
				else {
					stackbuf->xof= rr->xof;
					stackbuf->yof= rr->yof;

					/* put on stack */
					out[RRES_OUT_IMAGE]->data= stackbuf;

					if(out[RRES_OUT_ALPHA]->hasoutput)
						out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);

					node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty);

					generate_preview(data, node, stackbuf);
				}
			}
		}
	}

	if(re)
		RE_ReleaseResult(re);
}
Beispiel #21
0
static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
{
	ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage);
	CompBuf *zbuf= NULL;
	
	if(ibuf && ibuf->zbuf_float) {
		if(rd->scemode & R_COMP_CROP) {
			zbuf= get_cropped_compbuf(&rd->disprect, ibuf->zbuf_float, ibuf->x, ibuf->y, CB_VAL);
		}
		else {
			zbuf= alloc_compbuf(ibuf->x, ibuf->y, CB_VAL, 0);
			zbuf->rect= ibuf->zbuf_float;
		}
	}
	return zbuf;
}
Beispiel #22
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);
}
Beispiel #23
0
static void node_composit_exec_flip(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	if(in[0]->data) {
		CompBuf *cbuf= in[0]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1);	/* note, this returns zero'd image */
		int i, src_pix, src_width, src_height, srcydelt, outydelt, x, y;
		float *srcfp, *outfp;
		
		src_pix= cbuf->type;
		src_width= cbuf->x;
		src_height= cbuf->y;
		srcfp= cbuf->rect;
		outfp= stackbuf->rect;
		srcydelt= src_width*src_pix;
		outydelt= srcydelt;
		
		if(node->custom1) {		/*set up output pointer for y flip*/
			outfp+= (src_height-1)*outydelt;
			outydelt= -outydelt;
		}

		for(y=0; y<src_height; y++) {
			if(node->custom1 == 1) {	/* no x flip so just copy line*/
				memcpy(outfp, srcfp, sizeof(float) * src_pix * src_width);
				srcfp+=srcydelt;
			}
			else {
				outfp += (src_width-1)*src_pix;
				for(x=0; x<src_width; x++) {
					for(i=0; i<src_pix; i++) {
						outfp[i]= srcfp[i];
					}
					outfp -= src_pix;
					srcfp += src_pix;
				}
				outfp += src_pix;
			}
			outfp += outydelt;
		}

		out[0]->data= stackbuf;

	}
}
Beispiel #24
0
static void node_composit_exec_gamma(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[0]->data==NULL) {
		do_gamma(node, out[0]->vec, in[0]->vec, in[1]->vec);
	}
	else {
		/* make output size of input image */
		CompBuf *cbuf= in[0]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
		
		composit2_pixel_processor(node, stackbuf, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_gamma, CB_RGBA, CB_VAL);

		out[0]->data= stackbuf;
	}
}
static void node_composit_exec_map_value(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: valbuf */
	/* stack order out: valbuf */
	if(out[0]->hasoutput==0) return;
	
	/* input no image? then only value operation */
	if(in[0]->data==NULL) {
		do_map_value(node, out[0]->vec, in[0]->vec);
	}
	else {
		/* make output size of input image */
		CompBuf *cbuf= in[0]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */
		
		composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_map_value, CB_VAL);
		
		out[0]->data= stackbuf;
	}
}
static void node_composit_exec_keyingscreen(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
{
	NodeKeyingScreenData *keyingscreen_data = node->storage;
	RenderData *rd = data;
	CompBuf *screenbuf = NULL;

	if (node->id) {
		MovieClip *clip = (MovieClip *) node->id;
		MovieClipUser user = {0};
		int width, height;

		BKE_movieclip_user_set_frame(&user, rd->cfra);
		BKE_movieclip_get_size(clip, &user, &width, &height);

		screenbuf = alloc_compbuf(width, height, CB_RGBA, TRUE);
		compute_gradient_screen(rd, keyingscreen_data, clip, screenbuf);
	}

	out[0]->data = screenbuf;
}
Beispiel #27
0
static void node_composit_exec_cvSmooth(void *data, bNode *node, bNodeStack **in, bNodeStack **out) {
    //TODO: Use atach buffers
    int w, h;
    int p1, p2;
    float p3, p4;
    int type;
    if (out[0]->hasoutput == 0) return;

    if (in[0]->data) {
        IplImage *img, *smth;
        CompBuf* dst_buf;
        img = BOCV_IplImage_attach(in[0]->data);
        w = img->width;
        h = img->height;
        //Make input data as odd value
        p1 = (int) in[1]->vec[0];
        if ((p1 % 2) == 0) {
            p1--;
        }
        //Make input data as odd value
        p2 = (int) in[2]->vec[0];
        if ((p2 % 2) == 0)
            p2--;
        
        p3 = in[3]->vec[0];
        p4 = in[4]->vec[0];

        dst_buf = alloc_compbuf(img->width, img->height, img->nChannels, 1);
        smth = BOCV_IplImage_attach(dst_buf);
        
        type= node->custom1;
        
        cvSmooth(img, smth, type, p1, p2, p3, p4);

        out[0]->data = dst_buf;
        
        BOCV_IplImage_detach(smth);
        BOCV_IplImage_detach(img);
    }

}
Beispiel #28
0
static void node_composit_exec_normalize(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: valbuf */
	/* stack order out: valbuf */
	if (out[0]->hasoutput==0) return;

	/* Input has no image buffer? Then pass the value */
	if (in[0]->data==NULL) {
		copy_v4_v4(out[0]->vec, in[0]->vec);
	}
	else {
		float min = 1.0f+BLENDER_ZMAX;
		float max = -1.0f-BLENDER_ZMAX;
		float mult = 1.0f;
		float *val;
		/* make output size of input image */
		CompBuf *cbuf= in[0]->data;
		int tot= cbuf->x*cbuf->y;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); /* allocs */

		for (val = cbuf->rect; tot; tot--, val++) {
			if ((*val > max) && (*val <= BLENDER_ZMAX)) {
				max = *val;
			}
			if ((*val < min) && (*val >= -BLENDER_ZMAX)) {
				min = *val;
			}
		}
		/* In the rare case of flat buffer, which would cause a divide by 0, just pass the input to the output */
		if ((max-min) != 0.0f) {
			mult = 1.0f/(max-min);
			composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL);
		}
		else {
			memcpy(stackbuf->rect, cbuf->rect, sizeof(float) * cbuf->x * cbuf->y);
		}

		out[0]->data= stackbuf;
	}
}
Beispiel #29
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);
}
Beispiel #30
0
static void node_composit_exec_mix_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
	/* stack order in: fac, Image, Image */
	/* stack order out: Image */
	float *fac= in[0]->vec;
	
	if(out[0]->hasoutput==0) return;
	
	/* input no image? then only color operation */
	if(in[1]->data==NULL && in[2]->data==NULL) {
		do_mix_rgb(node, out[0]->vec, in[1]->vec, in[2]->vec, fac);
	}
	else {
		/* make output size of first available input image */
		CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data;
		CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); /* allocs */
		
		composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, fac, do_mix_rgb, CB_RGBA, CB_RGBA, CB_VAL);
		
		out[0]->data= stackbuf;
		
		generate_preview(data, node, out[0]->data);
	}
}