mitk::ImageDataItem::ImageDataItem(const ImageDataItem& aParent, unsigned int dimension, void *data, bool manageMemory, size_t offset) : m_Data(NULL), m_ManageMemory(false), m_PicDescriptor(NULL), m_VtkImageData(NULL), m_Offset(offset), m_IsComplete(false), m_Size(0), m_Parent(&aParent) { m_PixelType = aParent.GetPixelType(); m_PicDescriptor=mitkIpPicNew(); m_PicDescriptor->bpe=m_PixelType.GetBpe(); m_PicDescriptor->type=m_PixelType.GetType(); m_PicDescriptor->dim=dimension; memcpy(m_PicDescriptor->n, aParent.GetPicDescriptor()->n, sizeof(mitkIpUInt4_t)*_mitkIpPicNDIM); m_PicDescriptor->data=m_Data=static_cast<unsigned char*>(aParent.GetData())+offset; mitkIpFuncCopyTags(m_PicDescriptor, aParent.GetPicDescriptor()); m_Size = _mitkIpPicSize(m_PicDescriptor); if(data != NULL) { memcpy(m_Data, data, m_Size); if(manageMemory) { delete [] (unsigned char*) data; } } m_ReferenceCountLock.Lock(); m_ReferenceCount = 0; m_ReferenceCountLock.Unlock(); }
mitkIpPicDescriptor *mitkIpFuncSelInv ( mitkIpPicDescriptor *pic_old, mitkIpFloat8_t gv_low, mitkIpFloat8_t gv_up, mitkIpFloat8_t gv, mitkIpPicDescriptor *pic_return ) { mitkIpFloat8_t min_gv, max_gv; /* max and min posiible greyvalues */ mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ /* calculate max. and min. possible greyvalues */ if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) == mitkIpFuncERROR ) return ( mitkIpFuncERROR ); /* check whether data are correct */ if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( gv_low > gv_up ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } if ( min_gv > gv_low || max_gv < gv_up ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } if ( min_gv > gv || max_gv < gv ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } /* allocate memory for the transformed image */ pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); if ( pic_new == NULL ) return ( mitkIpFuncERROR ); /* macro to transform the image */ mitkIpPicFORALL_3 ( SELECT, pic_old, gv_low, gv_up, gv ); mitkIpFuncCopyTags(pic_new, pic_old); return ( pic_new ); }
mitkIpPicDescriptor *mitkIpFuncDila ( mitkIpPicDescriptor *pic_old, mitkIpPicDescriptor *pic_mask, mitkIpFuncFlagI_t border ) { mitkIpPicDescriptor *pic_new; pic_new = _mitkIpFuncMorph ( pic_old, pic_mask, mitkIpFuncDilaF, border ); if ( border == mitkIpFuncBorderZero ) pic_new = mitkIpFuncBorder ( pic_new, pic_mask, pic_new ); mitkIpFuncCopyTags(pic_new, pic_old); return ( pic_new ); }
mitkIpPicDescriptor *mitkIpFuncLevWin ( mitkIpPicDescriptor *pic_old, mitkIpFloat8_t level, mitkIpFloat8_t window, mitkIpPicDescriptor *pic_return ) { mitkIpPicDescriptor *pic_new; /* pointer to new image */ mitkIpFloat8_t gv_low; /* lower greyvalue of range */ mitkIpFloat8_t gv_up; /* upper greyvalue of range */ mitkIpFloat8_t max_gv, min_gv; /* max and min possible greyvalues */ /* check image data */ if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* calculate max and min possible greyvalues */ if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* calculate lower and upper greyvalue of range with level and window */ gv_low = level - 0.5 * window; if ( gv_low < min_gv ) gv_low = min_gv; else if ( gv_low > max_gv ) gv_low = max_gv; gv_up = level + 0.5 * window; if ( gv_up < min_gv ) gv_up = min_gv; else if ( gv_up > max_gv ) gv_up = max_gv; /* calculate new image in Function mitkIpFuncSelect */ pic_new = mitkIpFuncSelMM ( pic_old, gv_low, gv_up, pic_return ); /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_old); return ( pic_new ); }
mitkIpPicDescriptor *mitkIpFuncRank ( mitkIpPicDescriptor *pic_old, mitkIpUInt4_t rank, mitkIpUInt4_t mask_dim, mitkIpUInt4_t mask_size, mitkIpFuncFlagI_t border ) { mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ mitkIpInt4_t i; /* loop index */ mitkIpInt4_t offset; /* offset of image */ mitkIpInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ mitkIpInt4_t *off_vekt; /* pointer to offset vector */ mitkIpInt4_t begin; /* 0.5 * mask_size */ mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ mitkIpInt4_t n[_mitkIpPicNDIM]; /* size of each dimension */ mitkIpUInt4_t no_elem; /* number of elements in mask */ mitkIpUInt4_t len; /* length of offset vector */ /* calculate number of elements in mask */ no_elem = mask_size; for ( i = 1; i < mask_dim; i++ ) no_elem = no_elem * mask_size; /* check whether data are correct */ if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( mask_dim < 1 || mask_dim > pic_old->dim ) { _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); return ( mitkIpFuncERROR ); } if ( rank > no_elem ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } if ( mask_size % 2 != 1 ) { _mitkIpFuncSetErrno ( mitkIpFuncSIZE_ERROR ); return ( mitkIpFuncERROR ); } /* initialize vectors and variables */ size[0] = 1; for ( i = 1; i < _mitkIpPicNDIM; i++ ) size[i] = size[i-1] * pic_old->n[i-1]; len = 0; begin = mask_size / 2; for ( i = 0; i < mask_dim; i++ ) n[i] = begin + 1; for ( i = mask_dim; i < _mitkIpPicNDIM; i++ ) n[i] = 1 - begin; /* allocate image structure */ if ( border == mitkIpFuncBorderOld ) pic_new = mitkIpPicClone ( pic_old ); else if ( border == mitkIpFuncBorderZero ) { pic_new = mitkIpPicCopyHeader ( pic_old, 0 ); pic_new->data = calloc ( _mitkIpPicElements ( pic_new ), pic_new->bpe/8 ); } else { _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } /* allocate offset vector */ off_vekt = malloc ( no_elem * sizeof ( mitkIpUInt4_t ) ); if ( off_vekt == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); return ( mitkIpFuncERROR ); } /* calculate offset vector */ for ( ind[0] = -begin; ind[0] < n[0]; ind[0]++ ) for ( ind[7] = -begin; ind[7] < n[7]; ind[7]++ ) for ( ind[6] = -begin; ind[6] < n[6]; ind[6]++ ) for ( ind[5] = -begin; ind[5] < n[5]; ind[5]++ ) for ( ind[4] = -begin; ind[4] < n[4]; ind[4]++ ) for ( ind[3] = -begin; ind[3] < n[3]; ind[3]++ ) for ( ind[2] = -begin; ind[2] < n[2]; ind[2]++ ) for ( ind[1] = -begin; ind[1] < n[1]; ind[1]++ ) { offset = 0; for ( i = 0; i < pic_old->dim; i++ ) offset = offset + ind[i] * size[i]; off_vekt[len] = offset; len++; } if ( rank == 0 ) rank = no_elem / 2 + 1; mitkIpPicFORALL_4 ( RANK, pic_old, begin, no_elem, size, rank ); free ( off_vekt ); /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_old); return ( pic_new ); }
mitkIpPicDescriptor *mitkIpFuncScale ( mitkIpPicDescriptor *pic_old, mitkIpFloat8_t sc_fact[_mitkIpPicNDIM], mitkIpFuncFlagI_t sc_kind ) { mitkIpUInt4_t i; /* loop index */ mitkIpPicDescriptor *pic_new; /* pointer to scaled image */ char is_color=0; /* check whether data are correct */ if(pic_old->bpe==24) { pic_old->bpe=8; is_color=1; } if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if(is_color) pic_old->bpe=24; /* allocate pic_new */ pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } /* copy scaling information to header of pic_new */ pic_new->dim = pic_old->dim; for ( i = 0; i < pic_old->dim; i++ ) pic_new->n[i] = ( sc_fact[i] == 0 ) ? pic_old->n[i] : ( mitkIpUInt4_t ) ( sc_fact[i] * pic_old->n[i] ); /* call scaling routines */ if ( sc_kind == mitkIpFuncScaleNN ) pic_new = _mitkIpFuncScNN ( pic_old, pic_new ); else if ( sc_kind == mitkIpFuncScaleBl ) { pic_new = _mitkIpFuncScBL ( pic_old, pic_new ); /*printf("using NN due to error in _mitkIpFuncScaleBL ... "); pic_new = _mitkIpFuncScNN ( pic_old, pic_new );*/ } else { mitkIpPicFree ( pic_new ); _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_old); return( pic_new ); }
mitkIpPicDescriptor *mitkIpFuncSubC ( mitkIpPicDescriptor *pic_old, mitkIpFloat8_t value, mitkIpFuncFlagI_t keep, mitkIpPicDescriptor *pic_return ) { mitkIpPicDescriptor *pic_new; /* pointer to new image */ mitkIpFloat8_t max_gv; /* max. possible greyvalue */ mitkIpFloat8_t min_gv; /* min. possible greyvalue */ mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ /* check image data */ if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* check value */ if ( value == 0. ) return ( pic_old ); /* else if ( value == 0. ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } */ /* calculate max. and min. possible greyvalues for data type of images*/ if ( _mitkIpFuncExtT ( pic_old->type, pic_old->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* find out data type of new iamge */ if ( keep == mitkIpFuncKeep ) { pic_new = _mitkIpFuncMalloc ( pic_old, pic_return, mitkIpOVERWRITE ); if ( pic_new == NULL ) return ( mitkIpFuncERROR ); } else if ( keep == mitkIpFuncNoKeep ) { /* calculate max. and min. greyvalues of both images */ if ( mitkIpFuncExtr ( pic_old, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); smax = max1 - value; smin = min1 - value; /* change image type of images of type mitkIpPicInt */ if ( pic_old->type == mitkIpPicInt ) { if ( smax < max_gv && smin > min_gv ) { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); } else { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); pic_new->type = mitkIpPicFloat; pic_new->bpe = 64; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); } } /* change image type of images of type mitkIpPicUInt */ else if ( pic_old->type == mitkIpPicUInt ) { if ( smax < max_gv && smin > min_gv ) { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); } else { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); pic_new->type = mitkIpPicInt; pic_new->bpe = 16; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); if ( smax > max_gv || smin < min_gv ) { pic_new->type = mitkIpPicFloat; pic_new->bpe = 64; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); } } } /* change image type of images of type mitkIpPicUInt */ else if ( pic_old->type == mitkIpPicFloat ) { pic_new = mitkIpPicCopyHeader ( pic_old, NULL ); } else { _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); return ( mitkIpFuncERROR ); } } else { _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } if ( keep == mitkIpFuncNoKeep ) pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); if ( pic_new->data == NULL ) { mitkIpPicFree ( pic_new ); _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); return ( mitkIpFuncERROR ); } /* macro to invert the picture (for all data types) */ if ( keep == mitkIpFuncNoKeep ) mitkIpPicFORALL_2 ( SUBC, pic_old, pic_new, value ) if ( keep == mitkIpFuncKeep ) mitkIpPicFORALL_2 ( SUBC3, pic_old, pic_new, value ) /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_old); return pic_new; }
mitkIpPicDescriptor *mitkIpFuncWindowR ( mitkIpPicDescriptor *pic_1, mitkIpPicDescriptor *pic_2, mitkIpUInt4_t *begin, mitkIpFuncFlagI_t keep ) { mitkIpPicDescriptor *pic_new; /* pointer to transformed image */ mitkIpInt4_t i; /* loop index */ mitkIpUInt4_t end[_mitkIpPicNDIM]; /* end of image */ mitkIpUInt4_t size[_mitkIpPicNDIM]; /* */ /* check whether data are correct */ if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( pic_1->dim != pic_2->dim ) { _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_1->type != pic_2->type ) { _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_1->bpe != pic_2->bpe ) { _mitkIpFuncSetErrno ( mitkIpFuncSIZE_ERROR ); return ( mitkIpFuncERROR ); } for ( i = 0; i < pic_1->dim; i++ ) { if ( begin[i] < 0 || begin[i] > pic_1->n[i] ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } end[i] = begin[i] + pic_2->n[i]; if ( end[i] > pic_1->n[i] ) { _mitkIpFuncSetErrno ( mitkIpFuncDATA_ERROR ); return ( mitkIpFuncERROR ); } } /* initialize vectors and variables */ size[0] = 1; for ( i = 1; i < _mitkIpPicNDIM; i++ ) size[i] = size[i-1] * pic_1->n[i-1]; size[pic_1->dim] = 0; for ( i = pic_1->dim; i < _mitkIpPicNDIM; i++ ) { begin[i] = 0; end[i] = 1; } /* allocate image structure */ if ( keep == mitkIpFuncKeep ) pic_new = mitkIpPicClone ( pic_1 ); else pic_new = pic_1; mitkIpPicFORALL_3 ( WINDR, pic_2, begin, end, size ); /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_1); return ( pic_new ); }
mitkIpPicDescriptor *mitkIpFuncGausF ( mitkIpPicDescriptor *pic_old, mitkIpUInt4_t len_mask, mitkIpUInt4_t dim_mask, mitkIpFuncFlagI_t border ) { mitkIpPicDescriptor *pic_new; /* pointer to new image structure */ mitkIpPicDescriptor *pic_mask; /* pointer to mask */ mitkIpUInt4_t n[_mitkIpPicNDIM]; /* size of each dimension */ mitkIpUInt4_t ind[_mitkIpPicNDIM]; /* loop index vector */ mitkIpUInt4_t i, k; /* loop index */ mitkIpUInt4_t no_elem; /* number of mask elements */ mitkIpUInt4_t offset; /* offset of pixels */ mitkIpUInt4_t element; /* used to calculate mask elements */ mitkIpUInt4_t sum; /* sum of all mask elements */ mitkIpUInt4_t nn, nfac, kfac; /* used to calculate bin. coeff */ mitkIpUInt4_t *bin; /* binomial coeffizients */ /* check data */ if ( _mitkIpFuncError ( pic_old ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( pic_old->dim < dim_mask || dim_mask < 1 ) { _mitkIpFuncSetErrno ( mitkIpFuncDIMMASC_ERROR ); return ( mitkIpFuncERROR ); } if ( len_mask % 2 != 1 ) { _mitkIpFuncSetErrno ( mitkIpFuncDIM_ERROR ); return ( mitkIpFuncERROR ); } /* calculate binomial coefficient */ bin = malloc ( len_mask * sizeof ( mitkIpUInt4_t ) ); if ( bin == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); return ( mitkIpFuncERROR ); } nn = len_mask; bin[0] = 1; bin[nn-1] = 1; nfac = 1; kfac = 1; for ( k = 1; k < nn-1; k++ ) { kfac = k * kfac; nfac = nfac * ( nn - k ); bin[k] = nfac / kfac; } /* initialize mask */ pic_mask = mitkIpPicNew(); if ( pic_mask == NULL ) { free ( bin ); _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } pic_mask->type = mitkIpPicFloat; pic_mask->bpe = 64; pic_mask->dim = dim_mask; for ( i = 0; i < dim_mask; i++ ) pic_mask->n[i] = len_mask; pic_mask->data = malloc ( _mitkIpPicSize ( pic_mask ) ); if ( pic_mask->data == NULL ) { free ( bin ); mitkIpPicFree ( pic_mask ); _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } /* initialize vectors */ for ( i = 0; i < pic_mask->dim; i++ ) n[i] = len_mask; for ( i = pic_mask->dim; i < _mitkIpPicNDIM; i++ ) n[i] = 1; /* calculate mask */ offset = 0; sum = 0; for ( ind[7] = 0; ind[7] < n[7]; ind[7]++ ) for ( ind[6] = 0; ind[6] < n[6]; ind[6]++ ) for ( ind[5] = 0; ind[5] < n[5]; ind[5]++ ) for ( ind[4] = 0; ind[4] < n[4]; ind[4]++ ) for ( ind[3] = 0; ind[3] < n[3]; ind[3]++ ) for ( ind[2] = 0; ind[2] < n[2]; ind[2]++ ) for ( ind[1] = 0; ind[1] < n[1]; ind[1]++ ) for ( ind[0] = 0; ind[0] < n[0]; ind[0]++ ) { element = 1; for ( i = 0; i < pic_mask->dim; i++ ) element = element * bin[ind[i]]; (( mitkIpFloat8_t * )pic_mask->data)[offset] = ( mitkIpFloat8_t ) element; sum = sum + element; offset++; } no_elem = _mitkIpPicElements ( pic_mask ); for ( i = 0; i < no_elem; i++ ) (( mitkIpFloat8_t * ) pic_mask->data ) [i] = (( mitkIpFloat8_t * ) pic_mask->data ) [i] / ( mitkIpFloat8_t ) sum; /* convolve image with Gausian mask */ pic_new = mitkIpFuncConv ( pic_old, pic_mask, border ); mitkIpPicFree ( pic_mask ); free ( bin ); /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_old); return ( pic_new ); }
mitkIpPicDescriptor *mitkIpFuncSqrt ( mitkIpPicDescriptor *pic_1, mitkIpFuncFlagI_t keep, mitkIpPicDescriptor *pic_return ) { mitkIpPicDescriptor *pic_new; /* pointer to new image */ mitkIpUInt4_t i; /* loop index */ mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ /* check image data */ if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* calculate max. and min. greyvalues of both images */ if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* calculate max. and min. possible greyvalues for data type of images*/ /* find out data type of new iamge */ if ( keep == mitkIpFuncKeep ) { pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); if ( pic_new == NULL ) return ( mitkIpFuncERROR ); } else if ( keep == mitkIpFuncNoKeep ) { pic_new = mitkIpPicNew (); pic_new->dim = pic_1->dim; pic_new->bpe = 64; pic_new->type = mitkIpPicFloat; for ( i = 0; i < pic_new->dim; i++ ) pic_new->n[i] = pic_1->n[i]; } else { _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } if ( keep == mitkIpFuncNoKeep ) pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); if ( pic_new->data == NULL ) { mitkIpPicFree ( pic_new ); _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); return ( mitkIpFuncERROR ); } /* macro to invert the picture (for all data types) */ mitkIpPicFORALL_1 ( SQRT1, pic_1, pic_new ) /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_1); return pic_new; }
mitkIpPicDescriptor *mitkIpFuncSubI ( mitkIpPicDescriptor *pic_1, mitkIpPicDescriptor *pic_2, mitkIpFuncFlagI_t keep, mitkIpPicDescriptor *pic_return ) { mitkIpPicDescriptor *pic_new; /* pointer to new image */ mitkIpUInt4_t i; /* loop index */ mitkIpFloat8_t max_gv; /* max. possible greyvalue */ mitkIpFloat8_t min_gv; /* min. possible greyvalue */ mitkIpFloat8_t min1, max1; /* extreme greyvalues of 1. image */ mitkIpFloat8_t min2, max2; /* extreme greyvalues of 2. image */ mitkIpFloat8_t smin, smax; /* product of extreme greyvalues */ /* ckeck whether data are correct */ if ( _mitkIpFuncError ( pic_1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( _mitkIpFuncError ( pic_2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* check whether images have the same size */ if ( ( pic_1->type != pic_2->type ) || ( pic_1->bpe != pic_2->bpe ) ) { _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); return NULL; } if ( pic_1->dim == pic_2->dim ) for ( i = 0; i < _mitkIpPicNDIM; i++ ) { if ( pic_1->n[i] != pic_2->n[i] ) { _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); return NULL; } } else { _mitkIpFuncSetErrno ( mitkIpFuncUNFIT_ERROR ); return NULL; } /* calculate max. and min. possible greyvalues for data type of images*/ if ( _mitkIpFuncExtT ( pic_1->type, pic_1->bpe, &min_gv, &max_gv ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); /* find out data type of new iamge */ if ( keep == mitkIpFuncKeep ) { pic_new = _mitkIpFuncMalloc ( pic_1, pic_return, mitkIpOVERWRITE ); if ( pic_new == NULL ) return ( mitkIpFuncERROR ); } else if ( keep == mitkIpFuncNoKeep ) { /* calculate max. and min. greyvalues of both images */ if ( mitkIpFuncExtr ( pic_1, &min1, &max1 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); if ( mitkIpFuncExtr ( pic_2, &min2, &max2 ) != mitkIpFuncOK ) return ( mitkIpFuncERROR ); smax = max1 - max2; smin = min1 - min2; /* change image type of images of type mitkIpPicInt */ if ( pic_1->type == mitkIpPicInt ) { if ( smax < max_gv && smin > min_gv ) { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); } else { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); pic_new->type = mitkIpPicFloat; pic_new->bpe = 64; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); } } /* change image type of images of type mitkIpPicUInt */ else if ( pic_1->type == mitkIpPicUInt ) { if ( smax < max_gv && smin > min_gv ) { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); } else { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); pic_new->type = mitkIpPicInt; pic_new->bpe = 16; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); if ( smax > max_gv || smin < min_gv ) { pic_new->type = mitkIpPicFloat; pic_new->bpe = 64; _mitkIpFuncExtT ( pic_new->type, pic_new->bpe, &min_gv, &max_gv ); } } } /* change image type of images of type mitkIpPicUInt */ else if ( pic_1->type == mitkIpPicFloat ) { pic_new = mitkIpPicCopyHeader ( pic_1, NULL ); } else { _mitkIpFuncSetErrno ( mitkIpFuncTYPE_ERROR ); return ( mitkIpFuncERROR ); } } else { _mitkIpFuncSetErrno ( mitkIpFuncFLAG_ERROR ); return ( mitkIpFuncERROR ); } if ( pic_new == NULL ) { _mitkIpFuncSetErrno ( mitkIpFuncPICNEW_ERROR ); return ( mitkIpFuncERROR ); } if ( keep == mitkIpFuncNoKeep ) pic_new->data = malloc ( _mitkIpPicSize ( pic_new ) ); if ( pic_new->data == NULL ) { mitkIpPicFree ( pic_new ); _mitkIpFuncSetErrno ( mitkIpFuncMALLOC_ERROR ); return ( mitkIpFuncERROR ); } /* macro to invert the picture (for all data types) */ if ( keep == mitkIpFuncNoKeep ) mitkIpPicFORALL_2 ( SUBI, pic_1, pic_2, pic_new ) else if ( keep == mitkIpFuncKeep ) mitkIpPicFORALL_2 ( SUBI3, pic_1, pic_2, pic_new ) /* Copy Tags */ mitkIpFuncCopyTags(pic_new, pic_1); return pic_new; }