commit before doing some hefty shapekey change, will break compilation
[blender-staging.git] / source / blender / nodes / intern / CMP_nodes / CMP_image.c
index 20308e968d3b70124187925cf329f4fc95a2f718..89a3072ac8dfd5628c35cec0689b55c395e863c9 100644 (file)
@@ -48,6 +48,7 @@ static bNodeSocketType cmp_node_rlayers_out[]= {
        {       SOCK_RGBA, 0, "Refract",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       SOCK_RGBA, 0, "Radio",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       SOCK_VALUE, 0, "IndexOB",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+       {       SOCK_VALUE, 0, "Mist",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
        {       -1, 0, ""       }
 };
 
@@ -64,9 +65,32 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
        if(ibuf==NULL)
                return NULL;
        
-       if(ibuf->rect_float==NULL)
-               IMB_float_from_rect(ibuf);
+       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) {
@@ -78,6 +102,21 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i
                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;
 };
 
@@ -149,6 +188,8 @@ void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, I
                out[RRES_OUT_RADIO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RADIO);
        if(out[RRES_OUT_INDEXOB]->hasoutput)
                out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB);
+       if(out[RRES_OUT_MIST]->hasoutput)
+               out[RRES_OUT_MIST]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_MIST);
        
 };
 
@@ -184,11 +225,32 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b
                else {
                        stackbuf= node_composit_get_image(rd, ima, iuser);
 
-                       /* put image on stack */        
-                       out[0]->data= stackbuf;
+                       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);
+                               
+                                       /*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];
+                                       }
+                               }
                        
-                       if(out[2]->hasoutput)
-                               out[2]->data= node_composit_get_zimage(node, rd);
+                               /* 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 */
@@ -196,7 +258,7 @@ static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, b
                        if(out[1]->hasoutput)
                                out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
 
-                       generate_preview(node, stackbuf);
+                       generate_preview(data, node, stackbuf);
                }
        }       
 };
@@ -205,6 +267,7 @@ static void node_composit_init_image(bNode* node)
 {
    ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
    node->storage= iuser;
+   iuser->frames= 1;
    iuser->sfra= 1;
    iuser->fie_ima= 2;
    iuser->ok= 1;
@@ -236,7 +299,7 @@ static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, in
       CompBuf *buf;
       int buftype= CB_VEC3;
 
-      if(ELEM(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB))
+      if(ELEM3(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB, SCE_PASS_MIST))
          buftype= CB_VAL;
       else if(passcode==SCE_PASS_VECTOR)
          buftype= CB_VEC4;
@@ -282,17 +345,21 @@ void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out
    if(out[RRES_OUT_RADIO]->hasoutput)
       out[RRES_OUT_RADIO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RADIO);
    if(out[RRES_OUT_INDEXOB]->hasoutput)
-      out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB);
+          out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB);
+   if(out[RRES_OUT_MIST]->hasoutput)
+          out[RRES_OUT_MIST]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_MIST);
 
 };
 
 static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
-   Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
+   Scene *sce= (Scene *)node->id;
+   Render *re= (sce)? RE_GetRender(sce->id.name): NULL;
    RenderData *rd= data;
-   RenderResult *rr;
+   RenderResult *rr= NULL;
 
-   rr= RE_GetResult(RE_GetRender(sce->id.name));
+   if(re)
+          rr= RE_AcquireResultRead(re);
 
    if(rr) {
       SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
@@ -323,11 +390,14 @@ static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in,
 
                node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty);
 
-               generate_preview(node, stackbuf);
+               generate_preview(data, node, stackbuf);
             }
          }
       }
-   }   
+   }
+
+   if(re)
+          RE_ReleaseResult(re);
 };