Fixed all gcc 4 warnings in blenkernel. Found 2 potentially harmful
[blender.git] / source / blender / blenkernel / intern / verse_bitmap_node.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * Contributor(s): Jiri Hnidek.
24  *
25  * ***** END GPL/BL DUAL LICENSE BLOCK *****
26  */
27
28 #ifdef WITH_VERSE
29
30 #include <string.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_listBase.h"
35
36 #include "BLI_dynamiclist.h"
37 #include "BLI_blenlib.h"
38
39 #include "BIF_verse.h"
40
41 #include "BKE_verse.h"
42
43 #include "verse.h"
44
45 /* function prototypes of static functions */
46 static void cb_b_dimension_set(void *user_data, VNodeID node_id, uint16 width, uint16 height, uint16 depth);
47 static void cb_b_layer_create(void *user_data, VNodeID node_id, VLayerID layer_id, const char *name, VNBLayerType type);
48 static void cb_b_layer_destroy(void *user_data, VNodeID node_id, VLayerID layer_id);
49 static void cb_b_tile_set(void *user_data, VNodeID node_id, VLayerID layer_id, uint16 tile_x, uint16 tile_y, uint16 z,  VNBLayerType type, const VNBTile *tile);
50
51 static void change_layer_dimension(
52                 VBitmapLayer *vblayer,
53                 unsigned int old_width,
54                 unsigned int old_height,
55                 unsigned int t_old_width,
56                 unsigned int t_old_height);
57 static void *alloc_verse_bitmap_layer_data(struct VBitmapLayer *vblayer);
58
59 /*
60  * resize/crop verse bitmap layer
61  */
62 static void change_layer_dimension(
63                 VBitmapLayer *vblayer,
64                 unsigned int old_width,
65                 unsigned int old_height,
66                 unsigned int t_old_width,
67                 unsigned int t_old_height)
68 {
69         struct VNode *vnode = vblayer->vnode;
70         unsigned int t_width = ((VBitmapData*)(vnode->data))->t_width;
71         unsigned int width = ((VBitmapData*)(vnode->data))->width;
72         unsigned int height = ((VBitmapData*)(vnode->data))->height;
73         unsigned int x, y, i, j;
74         
75         i = j = 0;
76
77         /* "copy" old data to new data */
78         if(vblayer->type==VN_B_LAYER_UINT8) {
79                 unsigned char *data = (unsigned char*)vblayer->data;
80                 /* allocate new verse bitmap layer data */
81                 unsigned char *new_data = (unsigned char*)alloc_verse_bitmap_layer_data(vblayer);
82                 for(y=0; y<old_height && y<height; y++, i=y*t_width, j=y*t_old_width) {
83                         for(x=0; x<old_width && y<width; x++, i++, j++) {
84                                 new_data[i] = data[j];
85                         }
86                 }
87                 MEM_freeN(vblayer->data);
88                 vblayer->data = new_data;
89         }
90 }
91
92 /*
93  * free data stored in verse bitmap layer
94  */
95 void free_bitmap_layer_data(VBitmapLayer *vblayer)
96 {
97         struct VerseSession *session = vblayer->vnode->session;
98
99         /* free name of bitmap layer */
100         MEM_freeN(vblayer->name);
101
102         /* unsubscribe from verse bitmap layer */
103         if(session->flag & VERSE_CONNECTED)
104                 verse_send_b_layer_unsubscribe(vblayer->vnode->id, vblayer->id);
105
106         /* free image data of bitmap layer */
107         if(vblayer->data) MEM_freeN(vblayer->data);
108 }
109
110 /*
111  * allocate data of verse bitmap layer
112  */
113 static void *alloc_verse_bitmap_layer_data(VBitmapLayer *vblayer)
114 {
115         struct VNode *vnode = vblayer->vnode;
116         unsigned int t_width = ((VBitmapData*)(vnode->data))->t_width;
117         unsigned int t_height = ((VBitmapData*)(vnode->data))->t_height;
118         unsigned int size;
119         void *data;
120
121         size = t_width*t_height;
122
123         /* allocation of own data stored in verse bitmap layer */
124         switch (vblayer->type) {
125                 case VN_B_LAYER_UINT1:
126                         data = (void*)MEM_mallocN(sizeof(unsigned char)*size, "VBLayer data uint1");
127                         break;
128                 case VN_B_LAYER_UINT8:
129                         data = (void*)MEM_mallocN(sizeof(unsigned char)*size, "VBLayer data uint8");
130                         break;
131                 case VN_B_LAYER_UINT16:
132                         data = (void*)MEM_mallocN(sizeof(unsigned int)*size, "VBLayer data uint16");
133                         break;
134                 case VN_B_LAYER_REAL32:
135                         data = (void*)MEM_mallocN(sizeof(float)*size, "VBLayer data float16");
136                         break;
137                 case VN_B_LAYER_REAL64:
138                         data = (void*)MEM_mallocN(sizeof(double)*size, "VBLayer data float32");
139                         break;
140                 default:
141                         data = NULL;
142                         break;
143         }
144
145         return data;
146 }
147
148 /*
149  * create verse bitmap layer
150  */
151 VBitmapLayer *create_bitmap_layer(
152                 VNode *vnode,
153                 VLayerID layer_id,
154                 const char *name,
155                 VNBLayerType type)
156 {
157         struct VBitmapLayer *vblayer;
158         unsigned int width = ((VBitmapData*)(vnode->data))->width;
159         unsigned int height = ((VBitmapData*)(vnode->data))->height;
160
161         /* allocate memory for own verse bitmap layer */
162         vblayer = (VBitmapLayer*)MEM_mallocN(sizeof(VBitmapLayer), "Verse Bitmap Layer");
163
164         /* verse bitmap layer will include pointer at parent verse node and own id */
165         vblayer->vnode = vnode;
166         vblayer->id = layer_id;
167
168         /* name of verse layer */
169         vblayer->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "Verse Bitmap Layer name");
170         vblayer->name[0] = '\0';
171         strcpy(vblayer->name, name);
172
173         /* type of data stored in verse bitmap layer */
174         vblayer->type = type;
175
176         /* we can allocate memory for layer data, when we know dimmension of layers; when
177          * we don't know it, then we will allocate this data when we will receive dimmension */
178         if(width==0 || height==0)
179                 vblayer->data = NULL;
180         else
181                 vblayer->data = alloc_verse_bitmap_layer_data(vblayer);
182
183         vblayer->flag = 0;
184
185         return vblayer;
186 }
187
188 /*
189  * free data of bitmap node
190  */
191 void free_bitmap_node_data(VNode *vnode)
192 {
193         if(vnode->data) {
194                 struct VBitmapLayer *vblayer = (VBitmapLayer*)((VBitmapData*)(vnode->data))->layers.lb.first;
195
196                 /* free all VerseLayer data */
197                 while(vblayer) {
198                         free_bitmap_layer_data(vblayer);
199                         vblayer = vblayer->next;
200                 }
201
202                 /* free all VerseLayers */
203                 BLI_dlist_destroy(&(((VGeomData*)vnode->data)->layers));
204         }
205 }
206
207 /*
208  * create data of bitmap node
209  */
210 VBitmapData *create_bitmap_data()
211 {
212         struct VBitmapData *vbitmap;
213
214         vbitmap = (VBitmapData*)MEM_mallocN(sizeof(VBitmapData), "Verse Bitmap Data");
215
216         BLI_dlist_init(&(vbitmap->layers));
217         vbitmap->queue.first = vbitmap->queue.last = NULL;
218
219         vbitmap->width = 0;
220         vbitmap->height = 0;
221         vbitmap->depth = 0;
222
223         vbitmap->image = NULL;
224
225         vbitmap->post_bitmap_dimension_set = post_bitmap_dimension_set;
226         vbitmap->post_bitmap_layer_create = post_bitmap_layer_create;
227         vbitmap->post_bitmap_layer_destroy = post_bitmap_layer_destroy;
228         vbitmap->post_bitmap_tile_set = post_bitmap_tile_set;
229
230         return vbitmap;
231 }
232
233 /*
234  * callback function, dimension of image was changed, it is neccessary to
235  * crop all layers
236  */
237 static void cb_b_dimension_set(
238                 void *user_data,
239                 VNodeID node_id,
240                 uint16 width,
241                 uint16 height,
242                 uint16 depth)
243 {
244         struct VerseSession *session = (VerseSession*)current_verse_session();
245         struct VNode *vnode;
246         struct VBitmapLayer *vblayer;
247         unsigned int old_width, old_height, t_old_width, t_old_height;
248         
249         if(!session) return;
250
251         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
252         if(!vnode) return;
253
254 #ifdef VERSE_DEBUG_PRINT
255         printf("\t cb_b_dimension_set()\n");
256 #endif
257
258         /* backup old width and height */
259         old_width = ((VBitmapData*)(vnode->data))->width;
260         old_height = ((VBitmapData*)(vnode->data))->height;
261         t_old_width = ((VBitmapData*)(vnode->data))->t_width;
262         t_old_height = ((VBitmapData*)(vnode->data))->t_height;
263
264         /* set up new dimension of layers */
265         ((VBitmapData*)(vnode->data))->width = width;
266         ((VBitmapData*)(vnode->data))->height = height;
267         ((VBitmapData*)(vnode->data))->depth = depth;
268
269         /* we cache t_width because tiles aren't one pixel width */
270         if((width % VN_B_TILE_SIZE)!=0)
271                 ((VBitmapData*)(vnode->data))->t_width = (width/VN_B_TILE_SIZE + 1)*VN_B_TILE_SIZE;
272         else
273                 ((VBitmapData*)(vnode->data))->t_width = width;
274
275         /* we cache t_height because tiles aren't one pixel height */
276         if((height % VN_B_TILE_SIZE)!=0)
277                 ((VBitmapData*)(vnode->data))->t_height = (height/VN_B_TILE_SIZE + 1)*VN_B_TILE_SIZE;
278         else
279                 ((VBitmapData*)(vnode->data))->t_height = height;
280
281         /* crop resize all layers */
282         vblayer = ((VBitmapData*)vnode->data)->layers.lb.first;
283
284         while(vblayer) {
285                 /* when this callback function received after cb_b_layer_create,
286                  * then we have to allocate memory for verse bitmap layer data */
287                 if(!vblayer->data) vblayer->data = alloc_verse_bitmap_layer_data(vblayer);
288                 /* crop/resize all verse bitmap layers */
289                 else change_layer_dimension(vblayer, old_width, old_height, t_old_width, t_old_height);
290
291                 vblayer = vblayer->next;
292         }
293         
294         /* post callback function */
295         ((VBitmapData*)(vnode->data))->post_bitmap_dimension_set(vnode);
296 }
297
298 /*
299  * callback function, new layer channel of image was created
300  */
301 static void cb_b_layer_create(
302                 void *user_data,
303                 VNodeID node_id,
304                 VLayerID layer_id,
305                 const char *name,
306                 VNBLayerType type)
307 {
308         struct VerseSession *session = (VerseSession*)current_verse_session();
309         struct VNode *vnode;
310         struct VBitmapLayer *vblayer;
311         
312         if(!session) return;
313
314         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
315         if(!vnode) return;
316         
317 #ifdef VERSE_DEBUG_PRINT
318         printf("\t cb_b_layer_create()\n");
319 #endif
320
321         /* when no layer exists, then new layer will be created */
322         vblayer = create_bitmap_layer(vnode, layer_id, name, type);
323
324         /* add verse bitmap layer to list of layers */
325         BLI_dlist_add_item_index(&((VBitmapData*)vnode->data)->layers, vblayer, layer_id);
326
327         /* post callback function */
328         ((VBitmapData*)(vnode->data))->post_bitmap_layer_create(vblayer);
329
330 }
331
332 /*
333  * callback function, existing layer of image was destroyed
334  */
335 static void cb_b_layer_destroy(
336                 void *user_data,
337                 VNodeID node_id,
338                 VLayerID layer_id)
339 {
340         struct VerseSession *session = (VerseSession*)current_verse_session();
341         struct VNode *vnode;
342         struct VBitmapLayer *vblayer;
343         
344         if(!session) return;
345
346         /* find node of this layer*/
347         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
348         if(!vnode) return;
349
350         vblayer = (VBitmapLayer*)BLI_dlist_find_link(&(((VBitmapData*)vnode->data)->layers), layer_id);
351         if(!vblayer) return;
352
353 #ifdef VERSE_DEBUG_PRINT
354         printf("\t cb_b_layer_destroy()\n");
355 #endif
356
357         /* remove verse bitmap layer from list of layers */
358         BLI_dlist_rem_item(&(((VBitmapData*)vnode->data)->layers), layer_id);
359
360         /* post callback function */
361         ((VBitmapData*)(vnode->data))->post_bitmap_layer_destroy(vblayer);
362
363         /* free data of verse bitmap layer */
364         free_bitmap_layer_data(vblayer);
365
366         /* free verse bitmap layer */
367         MEM_freeN(vblayer);
368 }
369
370 /*
371  * callback function, small part (8x8 pixels) was changed
372  */
373 static void cb_b_tile_set(
374                 void *user_data,
375                 VNodeID node_id,
376                 VLayerID layer_id,
377                 uint16 tile_x,
378                 uint16 tile_y,
379                 uint16 z,
380                 VNBLayerType type,
381                 const VNBTile *tile)
382 {
383         struct VerseSession *session = (VerseSession*)current_verse_session();
384         struct VNode *vnode;
385         struct VBitmapLayer *vblayer;
386         unsigned int x, y, xs, ys, width, height, t_height, t_width, i, j;
387         
388         if(!session) return;
389
390         /* try to find verse node in dynamic list nodes */
391         vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
392         if(!vnode) return;
393
394         /* try to find verse bitmap layer in list of layers */
395         vblayer = (VBitmapLayer*)BLI_dlist_find_link(&(((VBitmapData*)vnode->data)->layers), layer_id);
396         if(!vblayer) return;
397
398         /* we have to have allocated memory for bitmap layer */
399         if(!vblayer->data) return;
400
401         width = ((VBitmapData*)vnode->data)->width;
402         height = ((VBitmapData*)vnode->data)->height;
403
404         /* width of verse image including all tiles */
405         t_height = ((VBitmapData*)vnode->data)->t_height;
406         /* height of verse image including all tiles */
407         t_width = ((VBitmapData*)vnode->data)->t_width;
408
409 #ifdef VERSE_DEBUG_PRINT
410         printf("\t cb_b_tile_set()\n");
411 #endif
412
413         xs = tile_x*VN_B_TILE_SIZE;
414         ys = tile_y*VN_B_TILE_SIZE;
415
416         /* initial position in one dimension vblayer->data (y_start*width + x_start) */
417         i = ys*t_width + xs;
418         /* intial position in one dimension tile array */
419         j = 0;
420
421         if(type==VN_B_LAYER_UINT8) {
422                 unsigned char *data = (unsigned char*)vblayer->data;
423                 for(y=ys; y<ys+VN_B_TILE_SIZE && y<height; y++, i=y*t_width+xs)
424                         for(x=xs; x<xs+VN_B_TILE_SIZE && x<width; x++, i++, j++)
425                                 data[i] = (unsigned char)tile->vuint8[j];
426         }
427
428         /* post callback function */
429         ((VBitmapData*)(vnode->data))->post_bitmap_tile_set(vblayer, xs, ys);
430 }
431
432 /*
433  * set up all callbacks functions for image nodes
434  */
435 void set_bitmap_callbacks(void)
436 {
437         /* dimension (size) of bitmap was set up or changes (image will be croped) */
438         verse_callback_set(verse_send_b_dimensions_set, cb_b_dimension_set, NULL);
439
440         /* new layer (chanell) of image was added or created */
441         verse_callback_set(verse_send_b_layer_create, cb_b_layer_create, NULL);
442
443         /* existing layer was destroyed */
444         verse_callback_set(verse_send_b_layer_destroy, cb_b_layer_destroy, NULL);
445
446         /* some tile (small part 8x8 pixels of image was changed) */
447         verse_callback_set(verse_send_b_tile_set, cb_b_tile_set, NULL);
448 }
449
450 #endif
451