c2edb3dd52f504617b3a7dd27eb3e6467e261f53
[blender.git] / source / blender / nodes / intern / CMP_nodes / CMP_crop.c
1 /**
2  *
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) 2006 Blender Foundation.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Juho Vepsäläinen
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include "../CMP_util.h"
31
32 /* **************** Crop  ******************** */
33
34 static bNodeSocketType cmp_node_crop_in[]= {
35         {       SOCK_RGBA, 1, "Image",                  0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
36         {       -1, 0, ""       }
37 };
38 static bNodeSocketType cmp_node_crop_out[]= {
39         {       SOCK_RGBA, 0, "Image",                  0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
40         {       -1, 0, ""       }
41 };
42
43 static void node_composit_exec_crop(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
44 {
45         if(in[0]->data) {
46                 NodeTwoXYs *ntxy= node->storage;
47                 CompBuf *cbuf= in[0]->data;
48                 CompBuf *stackbuf;
49                 int x, y;
50                 float *srcfp, *outfp;
51                 rcti outputrect;
52
53                 /* check input image size */
54                 if(cbuf->x <= ntxy->x1 + 1)
55                         ntxy->x1= cbuf->x - 1;
56
57                 if(cbuf->y <= ntxy->y1 + 1)
58                         ntxy->y1= cbuf->y - 1;
59
60                 if(cbuf->x <= ntxy->x2 + 1)
61                         ntxy->x2= cbuf->x - 1;
62
63                 if(cbuf->y <= ntxy->y2 + 1)
64                         ntxy->y2= cbuf->y - 1;
65
66                 /* figure out the minimums and maximums */
67                 outputrect.xmax=MAX2(ntxy->x1, ntxy->x2) + 1;
68                 outputrect.xmin=MIN2(ntxy->x1, ntxy->x2);
69                 outputrect.ymax=MAX2(ntxy->y1, ntxy->y2) + 1;
70                 outputrect.ymin=MIN2(ntxy->y1, ntxy->y2);
71
72                 if(node->custom1) {
73                         /* this option crops the image size too  */     
74                         stackbuf= get_cropped_compbuf(&outputrect, cbuf->rect, cbuf->x, cbuf->y, cbuf->type);
75                 }
76                 else {
77                         /* this option won't crop the size of the image as well  */
78                         /* allocate memory for the output image            */
79                         stackbuf = alloc_compbuf(cbuf->x, cbuf->y, cbuf->type, 1);
80
81                         /* select the cropped part of the image and set it to the output */
82                         for(y=outputrect.ymin; y<outputrect.ymax; y++){
83                                 srcfp= cbuf->rect     + (y * cbuf->x     + outputrect.xmin) * cbuf->type;
84                                 outfp= stackbuf->rect + (y * stackbuf->x + outputrect.xmin) * stackbuf->type;
85                                 for(x=outputrect.xmin; x<outputrect.xmax; x++, outfp+= stackbuf->type, srcfp+= cbuf->type)
86                                                         memcpy(outfp, srcfp, sizeof(float)*stackbuf->type);
87                         }
88                 }
89
90                 out[0]->data= stackbuf;
91         }
92 }
93
94 static void node_composit_init_crop(bNode* node)
95 {
96    NodeTwoXYs *nxy= MEM_callocN(sizeof(NodeTwoXYs), "node xy data");
97    node->storage= nxy;
98    nxy->x1= 0;
99    nxy->x2= 0;
100    nxy->y1= 0;
101    nxy->y2= 0;
102 }
103
104 bNodeType cmp_node_crop= {
105         /* *next,*prev */       NULL, NULL,
106         /* type code   */       CMP_NODE_CROP,
107         /* name        */       "Crop",
108         /* width+range */       140, 100, 320,
109         /* class+opts  */       NODE_CLASS_DISTORT, NODE_OPTIONS,
110         /* input sock  */       cmp_node_crop_in,
111         /* output sock */       cmp_node_crop_out,
112         /* storage     */       "NodeTwoXYs",
113         /* execfunc    */       node_composit_exec_crop,
114         /* butfunc     */       NULL,
115         /* initfunc    */       node_composit_init_crop,
116         /* freestoragefunc    */        node_free_standard_storage,
117         /* copystoragefunc    */        node_copy_standard_storage,
118         /* id          */       NULL
119 };