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; } }
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; }
/* 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; }
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 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; }
static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, int recty, int passcode) { float *fp= RE_RenderLayerGetPass(rl, passcode); if(fp) { CompBuf *buf; int buftype= CB_VEC3; if(ELEM4(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB, SCE_PASS_MIST, SCE_PASS_INDEXMA)) buftype= CB_VAL; else if(passcode==SCE_PASS_VECTOR) buftype= CB_VEC4; else if(ELEM(passcode, SCE_PASS_COMBINED, SCE_PASS_RGBA)) buftype= CB_RGBA; if(rd->scemode & R_COMP_CROP) buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype); else { buf= alloc_compbuf(rectx, recty, buftype, 0); buf->rect= fp; } return buf; } return NULL; }
/* 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; ibuf= BKE_image_get_ibuf(ima, iuser); if(ibuf==NULL) return NULL; if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) { if (ibuf->profile == IB_PROFILE_NONE) { /* if float buffer already exists = already linear */ /* else ... */ if (ibuf->rect_float == NULL) { imb_freerectfloatImBuf(ibuf); ibuf->profile = IB_PROFILE_SRGB; IMB_float_from_rect(ibuf); } else { ibuf->profile = IB_PROFILE_LINEAR_RGB; } } } else { if (ibuf->profile == IB_PROFILE_SRGB) { if (ibuf->rect_float != NULL) { imb_freerectfloatImBuf(ibuf); } ibuf->profile = IB_PROFILE_NONE; IMB_float_from_rect(ibuf); } } if (ibuf->rect_float == NULL) { IMB_float_from_rect(ibuf); } type= ibuf->channels; if(rd->scemode & R_COMP_CROP) { stackbuf= get_cropped_compbuf(&rd->disprect, ibuf->rect_float, ibuf->x, ibuf->y, type); } else { /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, 0); stackbuf->rect= ibuf->rect_float; } /*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; };