~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/nodes/intern/CMP_nodes/CMP_image.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2007-05-17 11:47:59 UTC
  • mfrom: (1.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20070517114759-yp4ybrnhp2u7pk66
Tags: 2.44-1
* New upstream release.
* Drop debian/patches/01_64bits_stupidity, not needed anymore: as of this
  version blender is 64 bits safe again. Adjust README.Debian accordingly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * $Id: CMP_image.c,v 1.5 2007/04/04 13:58:10 jesterking Exp $
 
3
 *
 
4
 * ***** BEGIN GPL LICENSE BLOCK *****
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * as published by the Free Software Foundation; either version 2
 
9
 * of the License, or (at your option) any later version. 
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software Foundation,
 
18
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
19
 *
 
20
 * The Original Code is Copyright (C) 2006 Blender Foundation.
 
21
 * All rights reserved.
 
22
 *
 
23
 * The Original Code is: all of this file.
 
24
 *
 
25
 * Contributor(s): none yet.
 
26
 *
 
27
 * ***** END GPL LICENSE BLOCK *****
 
28
 */
 
29
 
 
30
#include "../CMP_util.h"
 
31
 
 
32
 
 
33
/* **************** IMAGE (and RenderResult, multilayer image) ******************** */
 
34
 
 
35
static bNodeSocketType cmp_node_rlayers_out[]= {
 
36
        {       SOCK_RGBA, 0, "Image",          0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
 
37
        {       SOCK_VALUE, 0, "Alpha",         1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
38
        {       SOCK_VALUE, 0, "Z",                     1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
39
        {       SOCK_VECTOR, 0, "Normal",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
40
        {       SOCK_VECTOR, 0, "UV",           1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
41
        {       SOCK_VECTOR, 0, "Speed",        1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
42
        {       SOCK_RGBA, 0, "Color",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
43
        {       SOCK_RGBA, 0, "Diffuse",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
44
        {       SOCK_RGBA, 0, "Specular",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
45
        {       SOCK_RGBA, 0, "Shadow",         0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
46
        {       SOCK_RGBA, 0, "AO",                     0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
47
        {       SOCK_RGBA, 0, "Reflect",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
48
        {       SOCK_RGBA, 0, "Refract",        0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
49
        {       SOCK_RGBA, 0, "Radio",          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
50
        {       SOCK_VALUE, 0, "IndexOB",       0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
 
51
        {       -1, 0, ""       }
 
52
};
 
53
 
 
54
 
 
55
/* note: this function is used for multilayer too, to ensure uniform 
 
56
   handling with BKE_image_get_ibuf() */
 
57
static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *iuser)
 
58
{
 
59
        ImBuf *ibuf;
 
60
        CompBuf *stackbuf;
 
61
        int type;
 
62
        
 
63
        ibuf= BKE_image_get_ibuf(ima, iuser);
 
64
        if(ibuf==NULL)
 
65
                return NULL;
 
66
        
 
67
        if(ibuf->rect_float==NULL)
 
68
                IMB_float_from_rect(ibuf);
 
69
        
 
70
        type= ibuf->channels;
 
71
        
 
72
        if(rd->scemode & R_COMP_CROP) {
 
73
                stackbuf= get_cropped_compbuf(&rd->disprect, ibuf->rect_float, ibuf->x, ibuf->y, type);
 
74
        }
 
75
        else {
 
76
                /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
 
77
                stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, 0);
 
78
                stackbuf->rect= ibuf->rect_float;
 
79
        }
 
80
        
 
81
        return stackbuf;
 
82
};
 
83
 
 
84
static CompBuf *node_composit_get_zimage(bNode *node, RenderData *rd)
 
85
{
 
86
        ImBuf *ibuf= BKE_image_get_ibuf((Image *)node->id, node->storage);
 
87
        CompBuf *zbuf= NULL;
 
88
        
 
89
        if(ibuf && ibuf->zbuf_float) {
 
90
                if(rd->scemode & R_COMP_CROP) {
 
91
                        zbuf= get_cropped_compbuf(&rd->disprect, ibuf->zbuf_float, ibuf->x, ibuf->y, CB_VAL);
 
92
                }
 
93
                else {
 
94
                        zbuf= alloc_compbuf(ibuf->x, ibuf->y, CB_VAL, 0);
 
95
                        zbuf->rect= ibuf->zbuf_float;
 
96
                }
 
97
        }
 
98
        return zbuf;
 
99
};
 
100
 
 
101
/* check if layer is available, returns pass buffer */
 
102
static CompBuf *compbuf_multilayer_get(RenderData *rd, RenderLayer *rl, Image *ima, ImageUser *iuser, int passtype)
 
103
{
 
104
        RenderPass *rpass;
 
105
        short index;
 
106
        
 
107
        for(index=0, rpass= rl->passes.first; rpass; rpass= rpass->next, index++)
 
108
                if(rpass->passtype==passtype)
 
109
                        break;
 
110
        
 
111
        if(rpass) {
 
112
                CompBuf *cbuf;
 
113
                
 
114
                iuser->pass= index;
 
115
                BKE_image_multilayer_index(ima->rr, iuser);
 
116
                cbuf= node_composit_get_image(rd, ima, iuser);
 
117
                
 
118
                return cbuf;
 
119
        }
 
120
        return NULL;
 
121
};
 
122
 
 
123
void outputs_multilayer_get(RenderData *rd, RenderLayer *rl, bNodeStack **out, Image *ima, ImageUser *iuser)
 
124
{
 
125
        if(out[RRES_OUT_Z]->hasoutput)
 
126
                out[RRES_OUT_Z]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_Z);
 
127
        if(out[RRES_OUT_VEC]->hasoutput)
 
128
                out[RRES_OUT_VEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_VECTOR);
 
129
        if(out[RRES_OUT_NORMAL]->hasoutput)
 
130
                out[RRES_OUT_NORMAL]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_NORMAL);
 
131
        if(out[RRES_OUT_UV]->hasoutput)
 
132
                out[RRES_OUT_UV]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_UV);
 
133
        
 
134
        if(out[RRES_OUT_RGBA]->hasoutput)
 
135
                out[RRES_OUT_RGBA]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RGBA);
 
136
        if(out[RRES_OUT_DIFF]->hasoutput)
 
137
                out[RRES_OUT_DIFF]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_DIFFUSE);
 
138
        if(out[RRES_OUT_SPEC]->hasoutput)
 
139
                out[RRES_OUT_SPEC]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SPEC);
 
140
        if(out[RRES_OUT_SHADOW]->hasoutput)
 
141
                out[RRES_OUT_SHADOW]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_SHADOW);
 
142
        if(out[RRES_OUT_AO]->hasoutput)
 
143
                out[RRES_OUT_AO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_AO);
 
144
        if(out[RRES_OUT_REFLECT]->hasoutput)
 
145
                out[RRES_OUT_REFLECT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFLECT);
 
146
        if(out[RRES_OUT_REFRACT]->hasoutput)
 
147
                out[RRES_OUT_REFRACT]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_REFRACT);
 
148
        if(out[RRES_OUT_RADIO]->hasoutput)
 
149
                out[RRES_OUT_RADIO]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_RADIO);
 
150
        if(out[RRES_OUT_INDEXOB]->hasoutput)
 
151
                out[RRES_OUT_INDEXOB]->data= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_INDEXOB);
 
152
        
 
153
};
 
154
 
 
155
 
 
156
static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 
157
{
 
158
        
 
159
        /* image assigned to output */
 
160
        /* stack order input sockets: col, alpha */
 
161
        if(node->id) {
 
162
                RenderData *rd= data;
 
163
                Image *ima= (Image *)node->id;
 
164
                ImageUser *iuser= (ImageUser *)node->storage;
 
165
                CompBuf *stackbuf= NULL;
 
166
                
 
167
                /* first set the right frame number in iuser */
 
168
                BKE_image_user_calc_imanr(iuser, rd->cfra, 0);
 
169
                
 
170
                /* force a load, we assume iuser index will be set OK anyway */
 
171
                if(ima->type==IMA_TYPE_MULTILAYER)
 
172
                        BKE_image_get_ibuf(ima, iuser);
 
173
                
 
174
                if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
 
175
                        RenderLayer *rl= BLI_findlink(&ima->rr->layers, iuser->layer);
 
176
                        
 
177
                        if(rl) {
 
178
                                out[0]->data= stackbuf= compbuf_multilayer_get(rd, rl, ima, iuser, SCE_PASS_COMBINED);
 
179
                                
 
180
                                /* go over all layers */
 
181
                                outputs_multilayer_get(rd, rl, out, ima, iuser);
 
182
                        }
 
183
                }
 
184
                else {
 
185
                        stackbuf= node_composit_get_image(rd, ima, iuser);
 
186
 
 
187
                        /* put image on stack */        
 
188
                        out[0]->data= stackbuf;
 
189
                        
 
190
                        if(out[2]->hasoutput)
 
191
                                out[2]->data= node_composit_get_zimage(node, rd);
 
192
                }
 
193
                
 
194
                /* alpha and preview for both types */
 
195
                if(stackbuf) {
 
196
                        if(out[1]->hasoutput)
 
197
                                out[1]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
 
198
 
 
199
                        generate_preview(node, stackbuf);
 
200
                }
 
201
        }       
 
202
};
 
203
 
 
204
static void node_composit_init_image(bNode* node)
 
205
{
 
206
   ImageUser *iuser= MEM_callocN(sizeof(ImageUser), "node image user");
 
207
   node->storage= iuser;
 
208
   iuser->sfra= 1;
 
209
   iuser->fie_ima= 2;
 
210
   iuser->ok= 1;
 
211
}
 
212
 
 
213
bNodeType cmp_node_image= {
 
214
        /* *next,*prev */       NULL, NULL,
 
215
        /* type code   */       CMP_NODE_IMAGE,
 
216
        /* name        */       "Image",
 
217
        /* width+range */       120, 80, 300,
 
218
        /* class+opts  */       NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS,
 
219
        /* input sock  */       NULL,
 
220
        /* output sock */       cmp_node_rlayers_out,
 
221
        /* storage     */       "ImageUser",
 
222
        /* execfunc    */       node_composit_exec_image,
 
223
        /* butfunc     */       NULL,
 
224
        /* initfunc    */       node_composit_init_image,
 
225
        /* freestoragefunc    */        node_free_standard_storage,
 
226
        /* copystoragefunc    */        node_copy_standard_storage,
 
227
        /* id          */       NULL
 
228
};
 
229
 
 
230
/* **************** RENDER RESULT ******************** */
 
231
 
 
232
static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, int recty, int passcode)
 
233
{
 
234
   float *fp= RE_RenderLayerGetPass(rl, passcode);
 
235
   if(fp) {
 
236
      CompBuf *buf;
 
237
      int buftype= CB_VEC3;
 
238
 
 
239
      if(ELEM(passcode, SCE_PASS_Z, SCE_PASS_INDEXOB))
 
240
         buftype= CB_VAL;
 
241
      else if(passcode==SCE_PASS_VECTOR)
 
242
         buftype= CB_VEC4;
 
243
      else if(ELEM(passcode, SCE_PASS_COMBINED, SCE_PASS_RGBA))
 
244
         buftype= CB_RGBA;
 
245
 
 
246
      if(rd->scemode & R_COMP_CROP)
 
247
         buf= get_cropped_compbuf(&rd->disprect, fp, rectx, recty, buftype);
 
248
      else {
 
249
         buf= alloc_compbuf(rectx, recty, buftype, 0);
 
250
         buf->rect= fp;
 
251
      }
 
252
      return buf;
 
253
   }
 
254
   return NULL;
 
255
};
 
256
 
 
257
void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out, int rectx, int recty)
 
258
{
 
259
   if(out[RRES_OUT_Z]->hasoutput)
 
260
      out[RRES_OUT_Z]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_Z);
 
261
   if(out[RRES_OUT_VEC]->hasoutput)
 
262
      out[RRES_OUT_VEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_VECTOR);
 
263
   if(out[RRES_OUT_NORMAL]->hasoutput)
 
264
      out[RRES_OUT_NORMAL]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_NORMAL);
 
265
   if(out[RRES_OUT_UV]->hasoutput)
 
266
      out[RRES_OUT_UV]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_UV);
 
267
 
 
268
   if(out[RRES_OUT_RGBA]->hasoutput)
 
269
      out[RRES_OUT_RGBA]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RGBA);
 
270
   if(out[RRES_OUT_DIFF]->hasoutput)
 
271
      out[RRES_OUT_DIFF]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_DIFFUSE);
 
272
   if(out[RRES_OUT_SPEC]->hasoutput)
 
273
      out[RRES_OUT_SPEC]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SPEC);
 
274
   if(out[RRES_OUT_SHADOW]->hasoutput)
 
275
      out[RRES_OUT_SHADOW]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_SHADOW);
 
276
   if(out[RRES_OUT_AO]->hasoutput)
 
277
      out[RRES_OUT_AO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_AO);
 
278
   if(out[RRES_OUT_REFLECT]->hasoutput)
 
279
      out[RRES_OUT_REFLECT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFLECT);
 
280
   if(out[RRES_OUT_REFRACT]->hasoutput)
 
281
      out[RRES_OUT_REFRACT]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_REFRACT);
 
282
   if(out[RRES_OUT_RADIO]->hasoutput)
 
283
      out[RRES_OUT_RADIO]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_RADIO);
 
284
   if(out[RRES_OUT_INDEXOB]->hasoutput)
 
285
      out[RRES_OUT_INDEXOB]->data= compbuf_from_pass(rd, rl, rectx, recty, SCE_PASS_INDEXOB);
 
286
 
 
287
};
 
288
 
 
289
static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 
290
{
 
291
   Scene *sce= node->id?(Scene *)node->id:G.scene; /* G.scene is WEAK! */
 
292
   RenderData *rd= data;
 
293
   RenderResult *rr;
 
294
 
 
295
   rr= RE_GetResult(RE_GetRender(sce->id.name));
 
296
 
 
297
   if(rr) {
 
298
      SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1);
 
299
      if(srl) {
 
300
         RenderLayer *rl= RE_GetRenderLayer(rr, srl->name);
 
301
         if(rl && rl->rectf) {
 
302
            CompBuf *stackbuf;
 
303
 
 
304
            /* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */
 
305
            if(rd->scemode & R_COMP_CROP)
 
306
               stackbuf= get_cropped_compbuf(&rd->disprect, rl->rectf, rr->rectx, rr->recty, CB_RGBA);
 
307
            else {
 
308
               stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0);
 
309
               stackbuf->rect= rl->rectf;
 
310
            }
 
311
            if(stackbuf==NULL) {
 
312
               printf("Error; Preview Panel in UV Window returns zero sized image\n");
 
313
            }
 
314
            else {
 
315
               stackbuf->xof= rr->xof;
 
316
               stackbuf->yof= rr->yof;
 
317
 
 
318
               /* put on stack */       
 
319
               out[RRES_OUT_IMAGE]->data= stackbuf;
 
320
 
 
321
               if(out[RRES_OUT_ALPHA]->hasoutput)
 
322
                  out[RRES_OUT_ALPHA]->data= valbuf_from_rgbabuf(stackbuf, CHAN_A);
 
323
 
 
324
               node_composit_rlayers_out(rd, rl, out, rr->rectx, rr->recty);
 
325
 
 
326
               generate_preview(node, stackbuf);
 
327
            }
 
328
         }
 
329
      }
 
330
   }    
 
331
};
 
332
 
 
333
 
 
334
bNodeType cmp_node_rlayers= {
 
335
        /* *next,*prev */       NULL, NULL,
 
336
        /* type code   */       CMP_NODE_R_LAYERS,
 
337
        /* name        */       "Render Layers",
 
338
        /* width+range */       150, 100, 300,
 
339
        /* class+opts  */       NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS,
 
340
        /* input sock  */       NULL,
 
341
        /* output sock */       cmp_node_rlayers_out,
 
342
        /* storage     */       "",
 
343
        /* execfunc    */       node_composit_exec_rlayers,
 
344
        /* butfunc     */       NULL,
 
345
        /* initfunc    */       NULL,
 
346
        /* freestoragefunc    */        NULL,
 
347
        /* copystoragefunc    */        NULL,
 
348
        /* id          */       NULL
 
349
 
 
350
};
 
351
 
 
352