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_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); } } }
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); }
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 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); }
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); }
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_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); };
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_image(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) { /* image assigned to output */ /* stack order input sockets: col, alpha */ if(node->id) { RenderData *rd= data; Image *ima= (Image *)node->id; ImageUser *iuser= (ImageUser *)node->storage; CompBuf *stackbuf= NULL; /* first set the right frame number in iuser */ BKE_image_user_calc_frame(iuser, rd->cfra, 0); /* force a load, we assume iuser index will be set OK anyway */ if(ima->type==IMA_TYPE_MULTILAYER) BKE_image_get_ibuf(ima, iuser); if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) { RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer); if(rl) { out[0]->data= stackbuf= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_COMBINED); /* go over all layers */ outputs_multilayer_get(rd, rl, out, ima, iuser); } } else { stackbuf= node_composit_get_image(rd, ima, iuser); if (stackbuf) { /*respect image premul option*/ if (stackbuf->type==CB_RGBA && ima->flag & IMA_DO_PREMUL) { int i; float *pixel; /*first duplicate stackbuf->rect, since it's just a pointer to the source imbuf, and we don't want to change that.*/ stackbuf->rect = MEM_dupallocN(stackbuf->rect); /* since stackbuf now has allocated memory, rather than just a pointer, * mark it as allocated so it can be freed properly */ stackbuf->malloc=1; /*premul the image*/ 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]; } } /* put image on stack */ out[0]->data= stackbuf; if(out[2]->hasoutput) out[2]->data= node_composit_get_zimage(node, rd); } } /* alpha and preview for both types */ if(stackbuf) { if(out[1]->hasoutput) out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A); generate_preview(data, node, stackbuf); } } }
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); } }