Merging r39717 through r39983 from trunk into soc-2011-tomato
[blender.git] / source / blender / nodes / composite / nodes / node_composite_movieclip.c
1 /*
2  * $Id$
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2011 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Blender Foundation,
26  *                 Sergey Sharybin
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 /** \file blender/nodes/composite/nodes/node_composite_movieclip.c
32  *  \ingroup cmpnodes
33  */
34
35
36 #include "node_composite_util.h"
37
38 static bNodeSocketTemplate cmp_node_movieclip_out[]= {
39         {       SOCK_RGBA,              0,      "Image"},
40         {       SOCK_FLOAT,             1,      "Offset X"},
41         {       SOCK_FLOAT,             1,      "Offset Y"},
42         {       SOCK_FLOAT,             1,      "Scale"},
43         {       -1, 0, ""       }
44 };
45
46 static CompBuf *node_composit_get_movieclip(RenderData *rd, MovieClip *clip, MovieClipUser *user)
47 {
48         ImBuf *ibuf;
49         CompBuf *stackbuf;
50         int type;
51
52         float *rect;
53         int alloc= FALSE;
54
55         ibuf= BKE_movieclip_acquire_ibuf(clip, user);
56
57         if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
58                 IMB_freeImBuf(ibuf);
59                 return NULL;
60         }
61
62         if (ibuf->rect_float == NULL || ibuf->userflags&IB_RECT_INVALID) {
63                 IMB_float_from_rect(ibuf);
64                 ibuf->userflags&= ~IB_RECT_INVALID;
65         }
66
67         /* now we need a float buffer from the image with matching color management */
68         if(ibuf->channels == 4) {
69                 if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
70                         if(ibuf->profile != IB_PROFILE_NONE) {
71                                 rect= ibuf->rect_float;
72                         }
73                         else {
74                                 rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image");
75                                 srgb_to_linearrgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y);
76                                 alloc= TRUE;
77                         }
78                 }
79                 else {
80                         if(ibuf->profile == IB_PROFILE_NONE) {
81                                 rect= ibuf->rect_float;
82                         }
83                         else {
84                                 rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image");
85                                 linearrgb_to_srgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y);
86                                 alloc= TRUE;
87                         }
88                 }
89         }
90         else {
91                 /* non-rgba passes can't use color profiles */
92                 rect= ibuf->rect_float;
93         }
94         /* done coercing into the correct color management */
95
96         if(!alloc) {
97                 rect= MEM_dupallocN(rect);
98                 alloc= 1;
99         }
100
101         type= ibuf->channels;
102
103         if(rd->scemode & R_COMP_CROP) {
104                 stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type);
105                 if(alloc)
106                         MEM_freeN(rect);
107         }
108         else {
109                 /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */
110                 stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE);
111                 stackbuf->rect= rect;
112                 stackbuf->malloc= alloc;
113         }
114
115         IMB_freeImBuf(ibuf);
116
117         return stackbuf;
118 }
119
120 static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out)
121 {
122         if(node->id) {
123                 RenderData *rd= data;
124                 MovieClip *clip= (MovieClip *)node->id;
125                 MovieClipUser *user= (MovieClipUser *)node->storage;
126                 CompBuf *stackbuf= NULL;
127
128                 BKE_movieclip_user_set_frame(user, rd->cfra);
129
130                 stackbuf= node_composit_get_movieclip(rd, clip, user);
131
132                 if (stackbuf) {
133                         MovieTrackingStabilization *stab= &clip->tracking.stabilization;
134
135                         /* put image on stack */
136                         out[0]->data= stackbuf;
137
138                         if(stab->flag&TRACKING_2D_STABILIZATION) {
139                                 float loc[2], scale;
140
141                                 BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y,
142                                                         loc, &scale);
143
144                                 out[1]->vec[0]= loc[0];
145                                 out[2]->vec[0]= loc[1];
146
147                                 out[3]->vec[0]= scale;
148                         }
149
150                         /* generate preview */
151                         generate_preview(data, node, stackbuf);
152                 }
153         }
154 }
155
156 static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp))
157 {
158         MovieClipUser *user= MEM_callocN(sizeof(MovieClipUser), "node movie clip user");
159         node->storage= user;
160         user->framenr= 1;
161 }
162
163 void register_node_type_cmp_movieclip(ListBase *lb)
164 {
165         static bNodeType ntype;
166
167         node_type_base(&ntype, CMP_NODE_MOVIECLIP, "Movie Clip", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS);
168         node_type_socket_templates(&ntype, NULL, cmp_node_movieclip_out);
169         node_type_size(&ntype, 120, 80, 300);
170         node_type_init(&ntype, init);
171         node_type_storage(&ntype, "MovieClipUser", node_free_standard_storage, node_copy_standard_storage);
172         node_type_exec(&ntype, node_composit_exec_movieclip);
173
174         nodeRegisterType(lb, &ntype);
175 }