Files
test2/source/blender/blenkernel/intern/verse_bitmap_node.c
Joseph Eagar 30313645b0 Split dissolve_disk into dissolve_vert and dissolve_disk as agreed.
also made dissolve vert bmop use the error api, and put in some code 
to report it to the user in the xkey ui code.

Need to make a file in editors/mesh for client code utility functions for 
bmesh, like e.g. reporting bmesh errors to the user, handling conversion 
more automatically, etc.
2009-03-01 06:36:16 +00:00

452 lines
13 KiB
C

/**
* $Id: verse_bitmap_node.c 12931 2007-12-17 18:20:48Z theeth $
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Contributor(s): Jiri Hnidek.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifdef WITH_VERSE
#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
#include "BLI_dynamiclist.h"
#include "BLI_blenlib.h"
#include "BIF_verse.h"
#include "BKE_verse.h"
#include "verse.h"
/* function prototypes of static functions */
static void cb_b_dimension_set(void *user_data, VNodeID node_id, uint16 width, uint16 height, uint16 depth);
static void cb_b_layer_create(void *user_data, VNodeID node_id, VLayerID layer_id, const char *name, VNBLayerType type);
static void cb_b_layer_destroy(void *user_data, VNodeID node_id, VLayerID layer_id);
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);
static void change_layer_dimension(
VBitmapLayer *vblayer,
unsigned int old_width,
unsigned int old_height,
unsigned int t_old_width,
unsigned int t_old_height);
static void *alloc_verse_bitmap_layer_data(struct VBitmapLayer *vblayer);
/*
* resize/crop verse bitmap layer
*/
static void change_layer_dimension(
VBitmapLayer *vblayer,
unsigned int old_width,
unsigned int old_height,
unsigned int t_old_width,
unsigned int t_old_height)
{
struct VNode *vnode = vblayer->vnode;
unsigned int t_width = ((VBitmapData*)(vnode->data))->t_width;
unsigned int width = ((VBitmapData*)(vnode->data))->width;
unsigned int height = ((VBitmapData*)(vnode->data))->height;
unsigned int x, y, i, j;
i = j = 0;
/* "copy" old data to new data */
if(vblayer->type==VN_B_LAYER_UINT8) {
unsigned char *data = (unsigned char*)vblayer->data;
/* allocate new verse bitmap layer data */
unsigned char *new_data = (unsigned char*)alloc_verse_bitmap_layer_data(vblayer);
for(y=0; y<old_height && y<height; y++, i=y*t_width, j=y*t_old_width) {
for(x=0; x<old_width && y<width; x++, i++, j++) {
new_data[i] = data[j];
}
}
MEM_freeN(vblayer->data);
vblayer->data = new_data;
}
}
/*
* free data stored in verse bitmap layer
*/
void free_bitmap_layer_data(VBitmapLayer *vblayer)
{
struct VerseSession *session = vblayer->vnode->session;
/* free name of bitmap layer */
MEM_freeN(vblayer->name);
/* unsubscribe from verse bitmap layer */
if(session->flag & VERSE_CONNECTED)
verse_send_b_layer_unsubscribe(vblayer->vnode->id, vblayer->id);
/* free image data of bitmap layer */
if(vblayer->data) MEM_freeN(vblayer->data);
}
/*
* allocate data of verse bitmap layer
*/
static void *alloc_verse_bitmap_layer_data(VBitmapLayer *vblayer)
{
struct VNode *vnode = vblayer->vnode;
unsigned int t_width = ((VBitmapData*)(vnode->data))->t_width;
unsigned int t_height = ((VBitmapData*)(vnode->data))->t_height;
unsigned int size;
void *data;
size = t_width*t_height;
/* allocation of own data stored in verse bitmap layer */
switch (vblayer->type) {
case VN_B_LAYER_UINT1:
data = (void*)MEM_mallocN(sizeof(unsigned char)*size, "VBLayer data uint1");
break;
case VN_B_LAYER_UINT8:
data = (void*)MEM_mallocN(sizeof(unsigned char)*size, "VBLayer data uint8");
break;
case VN_B_LAYER_UINT16:
data = (void*)MEM_mallocN(sizeof(unsigned int)*size, "VBLayer data uint16");
break;
case VN_B_LAYER_REAL32:
data = (void*)MEM_mallocN(sizeof(float)*size, "VBLayer data float16");
break;
case VN_B_LAYER_REAL64:
data = (void*)MEM_mallocN(sizeof(double)*size, "VBLayer data float32");
break;
default:
data = NULL;
break;
}
return data;
}
/*
* create verse bitmap layer
*/
VBitmapLayer *create_bitmap_layer(
VNode *vnode,
VLayerID layer_id,
const char *name,
VNBLayerType type)
{
struct VBitmapLayer *vblayer;
unsigned int width = ((VBitmapData*)(vnode->data))->width;
unsigned int height = ((VBitmapData*)(vnode->data))->height;
/* allocate memory for own verse bitmap layer */
vblayer = (VBitmapLayer*)MEM_mallocN(sizeof(VBitmapLayer), "Verse Bitmap Layer");
/* verse bitmap layer will include pointer at parent verse node and own id */
vblayer->vnode = vnode;
vblayer->id = layer_id;
/* name of verse layer */
vblayer->name = (char*)MEM_mallocN(sizeof(char)*(strlen(name)+1), "Verse Bitmap Layer name");
vblayer->name[0] = '\0';
strcpy(vblayer->name, name);
/* type of data stored in verse bitmap layer */
vblayer->type = type;
/* we can allocate memory for layer data, when we know dimmension of layers; when
* we don't know it, then we will allocate this data when we will receive dimmension */
if(width==0 || height==0)
vblayer->data = NULL;
else
vblayer->data = alloc_verse_bitmap_layer_data(vblayer);
vblayer->flag = 0;
return vblayer;
}
/*
* free data of bitmap node
*/
void free_bitmap_node_data(VNode *vnode)
{
if(vnode->data) {
struct VBitmapLayer *vblayer = (VBitmapLayer*)((VBitmapData*)(vnode->data))->layers.lb.first;
/* free all VerseLayer data */
while(vblayer) {
free_bitmap_layer_data(vblayer);
vblayer = vblayer->next;
}
/* free all VerseLayers */
BLI_dlist_destroy(&(((VGeomData*)vnode->data)->layers));
}
}
/*
* create data of bitmap node
*/
VBitmapData *create_bitmap_data()
{
struct VBitmapData *vbitmap;
vbitmap = (VBitmapData*)MEM_mallocN(sizeof(VBitmapData), "Verse Bitmap Data");
BLI_dlist_init(&(vbitmap->layers));
vbitmap->queue.first = vbitmap->queue.last = NULL;
vbitmap->width = 0;
vbitmap->height = 0;
vbitmap->depth = 0;
vbitmap->image = NULL;
vbitmap->post_bitmap_dimension_set = post_bitmap_dimension_set;
vbitmap->post_bitmap_layer_create = post_bitmap_layer_create;
vbitmap->post_bitmap_layer_destroy = post_bitmap_layer_destroy;
vbitmap->post_bitmap_tile_set = post_bitmap_tile_set;
return vbitmap;
}
/*
* callback function, dimension of image was changed, it is neccessary to
* crop all layers
*/
static void cb_b_dimension_set(
void *user_data,
VNodeID node_id,
uint16 width,
uint16 height,
uint16 depth)
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VBitmapLayer *vblayer;
unsigned int old_width, old_height, t_old_width, t_old_height;
if(!session) return;
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
if(!vnode) return;
#ifdef VERSE_DEBUG_PRINT
printf("\t cb_b_dimension_set()\n");
#endif
/* backup old width and height */
old_width = ((VBitmapData*)(vnode->data))->width;
old_height = ((VBitmapData*)(vnode->data))->height;
t_old_width = ((VBitmapData*)(vnode->data))->t_width;
t_old_height = ((VBitmapData*)(vnode->data))->t_height;
/* set up new dimension of layers */
((VBitmapData*)(vnode->data))->width = width;
((VBitmapData*)(vnode->data))->height = height;
((VBitmapData*)(vnode->data))->depth = depth;
/* we cache t_width because tiles aren't one pixel width */
if((width % VN_B_TILE_SIZE)!=0)
((VBitmapData*)(vnode->data))->t_width = (width/VN_B_TILE_SIZE + 1)*VN_B_TILE_SIZE;
else
((VBitmapData*)(vnode->data))->t_width = width;
/* we cache t_height because tiles aren't one pixel height */
if((height % VN_B_TILE_SIZE)!=0)
((VBitmapData*)(vnode->data))->t_height = (height/VN_B_TILE_SIZE + 1)*VN_B_TILE_SIZE;
else
((VBitmapData*)(vnode->data))->t_height = height;
/* crop resize all layers */
vblayer = ((VBitmapData*)vnode->data)->layers.lb.first;
while(vblayer) {
/* when this callback function received after cb_b_layer_create,
* then we have to allocate memory for verse bitmap layer data */
if(!vblayer->data) vblayer->data = alloc_verse_bitmap_layer_data(vblayer);
/* crop/resize all verse bitmap layers */
else change_layer_dimension(vblayer, old_width, old_height, t_old_width, t_old_height);
vblayer = vblayer->next;
}
/* post callback function */
((VBitmapData*)(vnode->data))->post_bitmap_dimension_set(vnode);
}
/*
* callback function, new layer channel of image was created
*/
static void cb_b_layer_create(
void *user_data,
VNodeID node_id,
VLayerID layer_id,
const char *name,
VNBLayerType type)
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VBitmapLayer *vblayer;
if(!session) return;
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
if(!vnode) return;
#ifdef VERSE_DEBUG_PRINT
printf("\t cb_b_layer_create()\n");
#endif
/* when no layer exists, then new layer will be created */
vblayer = create_bitmap_layer(vnode, layer_id, name, type);
/* add verse bitmap layer to list of layers */
BLI_dlist_add_item_index(&((VBitmapData*)vnode->data)->layers, vblayer, layer_id);
/* post callback function */
((VBitmapData*)(vnode->data))->post_bitmap_layer_create(vblayer);
}
/*
* callback function, existing layer of image was destroyed
*/
static void cb_b_layer_destroy(
void *user_data,
VNodeID node_id,
VLayerID layer_id)
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VBitmapLayer *vblayer;
if(!session) return;
/* find node of this layer*/
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
if(!vnode) return;
vblayer = (VBitmapLayer*)BLI_dlist_find_link(&(((VBitmapData*)vnode->data)->layers), layer_id);
if(!vblayer) return;
#ifdef VERSE_DEBUG_PRINT
printf("\t cb_b_layer_destroy()\n");
#endif
/* remove verse bitmap layer from list of layers */
BLI_dlist_rem_item(&(((VBitmapData*)vnode->data)->layers), layer_id);
/* post callback function */
((VBitmapData*)(vnode->data))->post_bitmap_layer_destroy(vblayer);
/* free data of verse bitmap layer */
free_bitmap_layer_data(vblayer);
/* free verse bitmap layer */
MEM_freeN(vblayer);
}
/*
* callback function, small part (8x8 pixels) was changed
*/
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)
{
struct VerseSession *session = (VerseSession*)current_verse_session();
struct VNode *vnode;
struct VBitmapLayer *vblayer;
unsigned int x, y, xs, ys, width, height, t_height, t_width, i, j;
if(!session) return;
/* try to find verse node in dynamic list nodes */
vnode = (VNode*)BLI_dlist_find_link(&(session->nodes), (unsigned int)node_id);
if(!vnode) return;
/* try to find verse bitmap layer in list of layers */
vblayer = (VBitmapLayer*)BLI_dlist_find_link(&(((VBitmapData*)vnode->data)->layers), layer_id);
if(!vblayer) return;
/* we have to have allocated memory for bitmap layer */
if(!vblayer->data) return;
width = ((VBitmapData*)vnode->data)->width;
height = ((VBitmapData*)vnode->data)->height;
/* width of verse image including all tiles */
t_height = ((VBitmapData*)vnode->data)->t_height;
/* height of verse image including all tiles */
t_width = ((VBitmapData*)vnode->data)->t_width;
#ifdef VERSE_DEBUG_PRINT
printf("\t cb_b_tile_set()\n");
#endif
xs = tile_x*VN_B_TILE_SIZE;
ys = tile_y*VN_B_TILE_SIZE;
/* initial position in one dimension vblayer->data (y_start*width + x_start) */
i = ys*t_width + xs;
/* intial position in one dimension tile array */
j = 0;
if(type==VN_B_LAYER_UINT8) {
unsigned char *data = (unsigned char*)vblayer->data;
for(y=ys; y<ys+VN_B_TILE_SIZE && y<height; y++, i=y*t_width+xs)
for(x=xs; x<xs+VN_B_TILE_SIZE && x<width; x++, i++, j++)
data[i] = (unsigned char)tile->vuint8[j];
}
/* post callback function */
((VBitmapData*)(vnode->data))->post_bitmap_tile_set(vblayer, xs, ys);
}
/*
* set up all callbacks functions for image nodes
*/
void set_bitmap_callbacks(void)
{
/* dimension (size) of bitmap was set up or changes (image will be croped) */
verse_callback_set(verse_send_b_dimensions_set, cb_b_dimension_set, NULL);
/* new layer (chanell) of image was added or created */
verse_callback_set(verse_send_b_layer_create, cb_b_layer_create, NULL);
/* existing layer was destroyed */
verse_callback_set(verse_send_b_layer_destroy, cb_b_layer_destroy, NULL);
/* some tile (small part 8x8 pixels of image was changed) */
verse_callback_set(verse_send_b_tile_set, cb_b_tile_set, NULL);
}
#endif