/*! * \ingroup WlzValuesUtils * \brief attach grey workspace to interval scanning workspace * * \return Woolz error. * \param obj Object to be scanned. * \param iwsp Interval scanning workspace. * \param gwsp Value table scanning workspace. * \param tranpl Flag to enable value transplanting. * \par Source: * WlzGreyScan.c */ WlzErrorNum WlzInitGreyWSpace(WlzObject *obj, WlzIntervalWSpace *iwsp, WlzGreyWSpace *gwsp, int tranpl) { WlzValues vdmn; WlzErrorNum wlzerrno = WLZ_ERR_NONE; if(obj == NULL) { wlzerrno = WLZ_ERR_OBJECT_NULL; } else if((iwsp == NULL) || (gwsp == NULL)) { wlzerrno = WLZ_ERR_PARAM_NULL; } else { iwsp->gryptr = gwsp; /* Set up gwsp */ gwsp->gtable = obj->values; vdmn = gwsp->gtable; gwsp->pixeltype = WlzGreyTableTypeToGreyType(vdmn.v->type, &wlzerrno); } if(wlzerrno == WLZ_ERR_NONE) { gwsp->gdomaintype = WlzGreyTableTypeToTableType(vdmn.v->type, &wlzerrno); } if(wlzerrno == WLZ_ERR_NONE) { switch (gwsp->gdomaintype) { case WLZ_GREY_TAB_RAGR: /* synchronise grey table line pointer to interval domain - pointer when incremented points to first line */ gwsp->gline = vdmn.v->vtblines + iwsp->linpos - vdmn.v->line1; break; case WLZ_GREY_TAB_RECT: /* rectangular grey table does not have valueline pointers */ break; case WLZ_GREY_TAB_INTL: /* synchronise grey table line pointer to interval domain - pointer when incremented points to first line */ gwsp->gline = (WlzValueLine *) (vdmn.i->vil + iwsp->linpos - vdmn.i->line1); break; default: wlzerrno = WLZ_ERR_VALUES_TYPE; break; } gwsp->intptr = iwsp; gwsp->tranpl = tranpl; } return( wlzerrno ); }
/*! * \ingroup WlzAllocation * \brief Make in interval values table to match the input object The table will have linkcount set to zero. * * \return New interval values table. * \param type Required table type. * \param obj Input object. * \param bckgrnd Values table background value. * \param dstErr Error return. * \par Constraints The woolz object type must resolve to WLZ_GREY_TAB_INTL using WlzGreyTableTypeToTableType()or an error will be reported and NULL returned. For historical reasons the type encodes the table type as well as the grey-value type. * \par Source: * WlzMakeIntervalValues.c */ WlzIntervalValues * WlzMakeIntervalValues(WlzObjectType type, WlzObject *obj, WlzPixelV bckgrnd, WlzErrorNum *dstErr) { WlzValues v; WlzValueIntervalLine *vil; WlzValueLine *val; WlzGreyP g; WlzIntervalWSpace iwsp; WlzIntervalDomain *idom; WlzErrorNum errNum=WLZ_ERR_NONE; /* check the values table type */ v.i = NULL; (void) WlzGreyTableTypeToTableType(type, &errNum); if( errNum == WLZ_ERR_NONE ){ (void) WlzGreyTableTypeToGreyType(type, &errNum); } /* check the object */ if( (errNum == WLZ_ERR_NONE) && (obj == NULL) ){ errNum = WLZ_ERR_OBJECT_NULL; } if( errNum == WLZ_ERR_NONE ){ switch( obj->type ){ case WLZ_2D_DOMAINOBJ: if( obj->domain.core == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; break; } idom = obj->domain.i; break; case WLZ_EMPTY_OBJ: default: errNum = WLZ_ERR_DOMAIN_TYPE; break; } } /* * allocate space for basic, per line and per interval structures */ if((errNum == WLZ_ERR_NONE) && ((v.i = (WlzIntervalValues *) AlcCalloc(sizeof(WlzIntervalValues) + (idom->lastln - idom->line1 + 1) * sizeof(WlzValueIntervalLine) + WlzIntervalCount(idom, NULL) * sizeof(WlzValueLine), 1)) == NULL) ){ errNum = WLZ_ERR_MEM_ALLOC; } if( errNum == WLZ_ERR_NONE ){ vil = (WlzValueIntervalLine *) (v.i + 1); val = (WlzValueLine *) (vil + idom->lastln - idom->line1 + 1); v.i->bckgrnd = bckgrnd; switch( WlzGreyTableTypeToGreyType(type, NULL) ){ case WLZ_GREY_INT: g.inp = (int *) AlcCalloc(WlzArea(obj, NULL), sizeof(int)); break; case WLZ_GREY_SHORT: g.shp = (short *) AlcCalloc(WlzArea(obj, NULL), sizeof(short)); break; case WLZ_GREY_UBYTE: g.ubp = (WlzUByte *) AlcCalloc(WlzArea(obj, NULL), sizeof(WlzUByte)); break; case WLZ_GREY_FLOAT: g.flp = (float *) AlcCalloc(WlzArea(obj, NULL), sizeof(float)); break; case WLZ_GREY_DOUBLE: g.dbp = (double *) AlcCalloc(WlzArea(obj, NULL), sizeof(double)); break; case WLZ_GREY_RGBA: g.rgbp = (WlzUInt *) AlcCalloc(WlzArea(obj, NULL), sizeof(WlzUInt)); break; default: WlzFreeValues( v ); v.i = NULL; errNum = WLZ_ERR_GREY_TYPE; break; } } if( (errNum == WLZ_ERR_NONE) && (g.inp == NULL) ){ WlzFreeValues( v ); v.i = NULL; errNum = WLZ_ERR_MEM_ALLOC; } /* * fill in structure values and initialise scanning */ if( errNum == WLZ_ERR_NONE ){ v.i->type = type; v.i->freeptr = AlcFreeStackPush(v.i->freeptr, (void *)g.inp, NULL); v.i->line1 = idom->line1; v.i->lastln = idom->lastln; v.i->kol1 = idom->kol1; v.i->width = idom->lastkl - idom->kol1 + 1; v.i->vil = vil; v.i->linkcount = 0; v.i->original_table.core = NULL; vil--; if((errNum = WlzInitRasterScan(obj, &iwsp, WLZ_RASTERDIR_ILIC)) != WLZ_ERR_NONE ){ WlzFreeValues( v ); v.i = NULL; } } /* * fill in the line and interval structures, note grey-type already checked. */ if( errNum == WLZ_ERR_NONE ){ while((errNum == WLZ_ERR_NONE) && (errNum = WlzNextInterval(&iwsp)) == WLZ_ERR_NONE){ if (iwsp.nwlpos != 0) { vil += iwsp.nwlpos; vil->vtbint = val; } vil->nintvs++; val->vkol1 = iwsp.lftpos - v.i->kol1; val->vlastkl = iwsp.rgtpos - v.i->kol1; switch( WlzGreyTableTypeToGreyType(type, NULL) ){ case WLZ_GREY_INT: val->values.inp = g.inp; g.inp += iwsp.colrmn; break; case WLZ_GREY_SHORT: val->values.shp = g.shp; g.shp += iwsp.colrmn; break; case WLZ_GREY_UBYTE: val->values.ubp = g.ubp; g.ubp += iwsp.colrmn; break; case WLZ_GREY_FLOAT: val->values.flp = g.flp; g.flp += iwsp.colrmn; break; case WLZ_GREY_DOUBLE: val->values.dbp = g.dbp; g.dbp += iwsp.colrmn; break; case WLZ_GREY_RGBA: val->values.rgbp = g.rgbp; g.rgbp += iwsp.colrmn; break; default: errNum = WLZ_ERR_GREY_TYPE; break; } val++; } switch( errNum ){ case WLZ_ERR_NONE: case WLZ_ERR_EOO: errNum = WLZ_ERR_NONE; break; default: WlzFreeValues( v ); v.i = NULL; break; } } if( dstErr ){ *dstErr = errNum; } return(v.i); }
/*! * \return Woolz error code. * \ingroup WlzValuesUtils * \brief Sets the backgound value of an image object. * \param obj Given object in which to set the * background value. * \param bgd Required background value. */ WlzErrorNum WlzSetBackground(WlzObject *obj, WlzPixelV bgd) { WlzPlaneDomain *planedmn; WlzVoxelValues *voxtab; WlzObject *obj1; int i; WlzErrorNum errNum=WLZ_ERR_NONE; /* check the object */ if( obj == NULL ){ return( WLZ_ERR_OBJECT_NULL ); } switch( obj->type ){ case WLZ_2D_DOMAINOBJ: case WLZ_3D_DOMAINOBJ: break; case WLZ_TRANS_OBJ: return( WlzSetBackground(obj->values.obj, bgd) ); case WLZ_EMPTY_OBJ: return( WLZ_ERR_NONE ); default: return( WLZ_ERR_OBJECT_TYPE ); } if( obj->domain.core == NULL ){ return( WLZ_ERR_DOMAIN_NULL ); } if( obj->values.core == NULL ){ return( WLZ_ERR_NONE ); } /* check the background type */ switch( bgd.type ){ case WLZ_GREY_INT: case WLZ_GREY_SHORT: case WLZ_GREY_UBYTE: case WLZ_GREY_FLOAT: case WLZ_GREY_DOUBLE: case WLZ_GREY_RGBA: break; default: return( WLZ_ERR_GREY_TYPE ); } (void )WlzValueConvertPixel( &bgd, bgd, WlzGreyTableTypeToGreyType(obj->values.core->type, &errNum)); switch( obj->type ){ case WLZ_2D_DOMAINOBJ: switch( WlzGreyTableTypeToTableType(obj->values.core->type, &errNum) ){ case WLZ_GREY_TAB_RAGR: obj->values.v->bckgrnd = bgd; break; case WLZ_GREY_TAB_RECT: obj->values.r->bckgrnd = bgd; break; case WLZ_GREY_TAB_INTL: obj->values.i->bckgrnd = bgd; break; default: return( errNum ); } break; case WLZ_3D_DOMAINOBJ: planedmn = obj->domain.p; if( planedmn->type != WLZ_PLANEDOMAIN_DOMAIN ){ return( WLZ_ERR_PLANEDOMAIN_TYPE ); } voxtab = obj->values.vox; if( voxtab->type != WLZ_VOXELVALUETABLE_GREY ){ return( WLZ_ERR_VOXELVALUES_TYPE ); } for(i=0; i <= planedmn->lastpl - planedmn->plane1; i++){ if( planedmn->domains[i].core == NULL || voxtab->values[i].core == NULL){ continue; } obj1 = WlzMakeMain(WLZ_2D_DOMAINOBJ, planedmn->domains[i], voxtab->values[i], NULL, NULL, &errNum); WlzSetBackground( obj1, bgd ); WlzFreeObj( obj1 ); } voxtab->bckgrnd = bgd; break; default: errNum = WLZ_ERR_OBJECT_TYPE; break; } return( errNum ); }
/*! * \return The background value. If the returned pixel value type is * WLZ_GREY_ERROR then an error has occurred. * \ingroup WlzValuesUtils * \brief Gets the background value of the given object. * \param obj Given object. * \param dstErr Destination error pointer, may be NULL. */ WlzPixelV WlzGetBackground( WlzObject *obj, WlzErrorNum *dstErr) { WlzPlaneDomain *planedmn; WlzPixelV bgd; WlzErrorNum errNum=WLZ_ERR_NONE; /* set up an invalid background return */ bgd.type = WLZ_GREY_ERROR; bgd.v.inv = 0; if( obj == NULL ){ errNum = WLZ_ERR_OBJECT_NULL; } if( errNum == WLZ_ERR_NONE ){ switch( obj->type ){ case WLZ_2D_DOMAINOBJ: if( obj->domain.i == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; break; } if( obj->values.v == NULL ){ bgd.type = WLZ_GREY_INT; bgd.v.inv = 0; break; } switch( WlzGreyTableTypeToTableType(obj->values.core->type, NULL) ){ case WLZ_GREY_TAB_RAGR: bgd = obj->values.v->bckgrnd; break; case WLZ_GREY_TAB_RECT: bgd = obj->values.r->bckgrnd; break; case WLZ_GREY_TAB_INTL: bgd = obj->values.i->bckgrnd; break; default: errNum = WLZ_ERR_VALUES_TYPE; break; } break; case WLZ_3D_DOMAINOBJ: if( obj->domain.p == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; break; } if( obj->values.core == NULL ){ bgd.type = WLZ_GREY_INT; bgd.v.inv = 0; errNum = WLZ_ERR_NONE; break; } planedmn = obj->domain.p; if( planedmn->type != WLZ_PLANEDOMAIN_DOMAIN ){ errNum = WLZ_ERR_PLANEDOMAIN_TYPE; break; } if(WlzGreyTableIsTiled(obj->values.core->type)) { bgd = obj->values.t->bckgrnd; } else if(obj->values.core->type == WLZ_VOXELVALUETABLE_GREY) { bgd = obj->values.vox->bckgrnd; } else { errNum = WLZ_ERR_VALUES_TYPE; } break; case WLZ_TRANS_OBJ: return( WlzGetBackground(obj->values.obj, dstErr) ); case WLZ_EMPTY_OBJ: bgd.type = WLZ_GREY_INT; bgd.v.inv = 0; errNum = WLZ_ERR_NONE; break; default: errNum = WLZ_ERR_OBJECT_TYPE; break; } } if( dstErr ){ *dstErr = errNum; } return bgd; }
/*! * \return Grey value work space or NULL on error. * \ingroup WlzAccess * \brief Creates a grey value work space from the given object. * The resulting grey value work space should be freed * using WlzGreyValueFreeWSp(). * \param obj Given object. * \param dstErrNum Destination error pointer, may be NULL. */ WlzGreyValueWSpace *WlzGreyValueMakeWSp(WlzObject *obj, WlzErrorNum *dstErrNum) { int planeIdx, numPlanes; WlzDomain *planeDomains; WlzValues *planeValues; WlzObjectType gTabType0, gTabType1 = WLZ_DUMMY_ENTRY; WlzGreyType gType0 = WLZ_GREY_ERROR, gType1 = WLZ_GREY_ERROR; WlzPixelV bkdPix; WlzAffineTransform *trans0, *trans1; WlzGreyValueWSpace *gVWSp = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; bkdPix.v.ubv = 0; bkdPix.type = WLZ_GREY_INT; WLZ_DBG((WLZ_DBG_LVL_1), ("WlzGreyValueMakeWSp FE %p %p\n", obj, dstErrNum)); if(obj == NULL) { errNum = WLZ_ERR_PARAM_DATA; } else { switch(obj->type) { case WLZ_2D_DOMAINOBJ: if(obj->domain.core == NULL) { errNum = WLZ_ERR_DOMAIN_NULL; } else if(obj->values.core == NULL) { errNum = WLZ_ERR_VALUES_NULL; } else if((gVWSp = (WlzGreyValueWSpace *)AlcCalloc(1, sizeof(WlzGreyValueWSpace))) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } else { gVWSp->objType = obj->type; gVWSp->values = obj->values; gVWSp->gType = WlzGreyTableTypeToGreyType(obj->values.core->type, &errNum); if(errNum == WLZ_ERR_NONE) { gVWSp->gTabType = WlzGreyTableTypeToTableType( obj->values.core->type, &errNum); gVWSp->gTabType2D = gVWSp->gTabType; } if(errNum == WLZ_ERR_NONE) { switch(gVWSp->gTabType2D) { case WLZ_GREY_TAB_RAGR: gVWSp->values2D = obj->values; bkdPix = gVWSp->values2D.v->bckgrnd; break; case WLZ_GREY_TAB_RECT: gVWSp->values2D = obj->values; bkdPix = gVWSp->values2D.r->bckgrnd; break; case WLZ_GREY_TAB_INTL: gVWSp->values2D = obj->values; bkdPix = gVWSp->values2D.i->bckgrnd; break; case WLZ_GREY_TAB_TILED: gVWSp->values2D = obj->values; bkdPix = gVWSp->values2D.t->bckgrnd; break; default: errNum = WLZ_ERR_VALUES_TYPE; break; } } if(errNum == WLZ_ERR_NONE) { switch(gVWSp->gType) { case WLZ_GREY_LONG: case WLZ_GREY_INT: case WLZ_GREY_SHORT: case WLZ_GREY_UBYTE: case WLZ_GREY_FLOAT: case WLZ_GREY_DOUBLE: case WLZ_GREY_RGBA: break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } if((gVWSp->gType != bkdPix.type) && (errNum == WLZ_ERR_NONE)) { errNum = WLZ_ERR_VALUES_DATA; } } if(errNum == WLZ_ERR_NONE) { gVWSp->gBkd = bkdPix.v; gVWSp->domain = obj->domain; gVWSp->iDom2D = obj->domain.i; if((gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_INTVL) && (gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_RECT)) { errNum = WLZ_ERR_DOMAIN_TYPE; } } break; case WLZ_3D_DOMAINOBJ: if(obj->domain.core == NULL) { errNum = WLZ_ERR_DOMAIN_NULL; } else if(obj->values.core == NULL) { errNum = WLZ_ERR_VALUES_NULL; } else if(obj->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN) { errNum = WLZ_ERR_DOMAIN_TYPE; } else if((gVWSp = (WlzGreyValueWSpace *)AlcCalloc(1, sizeof(WlzGreyValueWSpace))) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } else { gVWSp->objType = obj->type; gVWSp->domain = obj->domain; gVWSp->values = obj->values; if(WlzGreyTableIsTiled(obj->values.core->type) == WLZ_GREY_TAB_TILED) { gVWSp->gTabType = WLZ_GREY_TAB_TILED; gVWSp->gTabType2D = WLZ_GREY_TAB_TILED; gVWSp->gType = WlzGreyTableTypeToGreyType( obj->values.core->type, &errNum); gVWSp->plane = obj->domain.p->plane1; gVWSp->iDom2D = (*(obj->domain.p->domains)).i; gVWSp->gBkd = obj->values.t->bckgrnd.v; if(obj->values.t->bckgrnd.type != gVWSp->gType) { errNum = WLZ_ERR_VALUES_DATA; } } else { gVWSp->gTabType = WLZ_VOXELVALUETABLE_GREY; /* Put in a list of grey-table types - purely for efficiency to avoid re-computing the type for each voxel request. When table types are no longer computed this in principle could go */ numPlanes = obj->domain.p->lastpl - obj->domain.p->plane1 + 1; if((gVWSp->gTabTypes3D = (WlzObjectType *) AlcCalloc(numPlanes, sizeof(WlzObjectType))) == NULL) { errNum = WLZ_ERR_MEM_ALLOC; } if(errNum == WLZ_ERR_NONE) { WlzObjectType *gTabTypes3D; gVWSp->values2D.core = NULL; planeIdx = obj->domain.p->plane1; planeDomains = obj->domain.p->domains; planeValues = obj->values.vox->values; gTabTypes3D = gVWSp->gTabTypes3D; while((planeIdx <= obj->domain.p->lastpl) && (errNum == WLZ_ERR_NONE)) { if(((*planeValues).core) && ((*planeValues).core->type != WLZ_EMPTY_OBJ)) { gType0 = WlzGreyTableTypeToGreyType( (*planeValues).core->type, &errNum); if(errNum == WLZ_ERR_NONE) { gTabType0 = WlzGreyTableTypeToTableType((*planeValues). core->type, &errNum); *gTabTypes3D = gTabType0; } if(errNum == WLZ_ERR_NONE) { if((gType0 != gType1) && (gType1 != WLZ_GREY_ERROR)) { errNum = WLZ_ERR_VALUES_DATA; } else { gType1 = gType0; gTabType1 = gTabType0; if(gVWSp->values2D.core == NULL) { gVWSp->plane = planeIdx; gVWSp->iDom2D = (*planeDomains).i; gVWSp->values2D = *planeValues; } } } } ++planeIdx; ++planeDomains; ++planeValues; ++gTabTypes3D; } if((gType1 == WLZ_GREY_ERROR) || (gTabType1 == WLZ_DUMMY_ENTRY)) { errNum = WLZ_ERR_VALUES_DATA; } } if(errNum == WLZ_ERR_NONE) { gVWSp->gType = gType0; gVWSp->gTabType2D = gVWSp->gTabTypes3D[0]; switch(gVWSp->gTabType2D) { case WLZ_GREY_TAB_RAGR: bkdPix = gVWSp->values2D.v->bckgrnd; break; case WLZ_GREY_TAB_RECT: bkdPix = gVWSp->values2D.r->bckgrnd; break; case WLZ_GREY_TAB_INTL: bkdPix = gVWSp->values2D.i->bckgrnd; break; case WLZ_GREY_TAB_TILED: bkdPix = gVWSp->values2D.t->bckgrnd; break; default: errNum = WLZ_ERR_VALUES_TYPE; break; } if((gVWSp->gType != bkdPix.type) && (errNum == WLZ_ERR_NONE)) { errNum = WLZ_ERR_VALUES_DATA; } else if((gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_INTVL) && (gVWSp->iDom2D->type != WLZ_INTERVALDOMAIN_RECT)) { errNum = WLZ_ERR_DOMAIN_TYPE; } else { gVWSp->gBkd = bkdPix.v; } } } } break; case WLZ_TRANS_OBJ: trans0 = NULL; while((errNum == WLZ_ERR_NONE) && (obj->type == WLZ_TRANS_OBJ)) { if(trans0 == NULL) { trans0 = WlzAffineTransformCopy(obj->domain.t, &errNum); } else { if((trans1 = WlzAffineTransformProduct(trans0, obj->domain.t, &errNum)) != NULL) { WlzFreeAffineTransform(trans0); trans0 = trans1; trans1 = NULL; } } if((obj = obj->values.obj) == NULL) { errNum = WLZ_ERR_OBJECT_NULL; } } if(errNum == WLZ_ERR_NONE) { gVWSp = WlzGreyValueMakeWSp(obj, &errNum); } if(errNum == WLZ_ERR_NONE) { gVWSp->invTrans = WlzAffineTransformInverse(trans0, &errNum); } if(trans0) { WlzFreeAffineTransform(trans0); } break; default: errNum = WLZ_ERR_OBJECT_TYPE; break; } } if((errNum != WLZ_ERR_NONE) && (gVWSp != NULL)) { WlzGreyValueFreeWSp(gVWSp); gVWSp = NULL; } if(dstErrNum) { *dstErrNum = errNum; } WLZ_DBG((WLZ_DBG_LVL_FN|WLZ_DBG_LVL_1), ("WlzGreyValueMakeWSp FX %p\n", gVWSp)); return(gVWSp); }
/*! * \return New woolz object or NULL on error. * \ingroup WlzArithmetic * \brief Scales the values of the given 2D Woolz object so that * \f$v_{new} = m v_{given} + a.\f$ The input object is known * to be a valid 2D domain object with grey values. * \param iObj Given object. * \param m Value to multiply object values by. * \param a Value to add to product. * \param rGType Required grey type for returned object. * \param dstErr Destination error pointer, may be NULL. */ static WlzObject *WlzScalarMulAdd2D(WlzObject *iObj, WlzPixelV m, WlzPixelV a, WlzGreyType rGType, WlzErrorNum *dstErr) { WlzValues rValues; WlzObjectType rVType; WlzPixelV bgdV; WlzObject *rObj = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; rValues.core = NULL; bgdV = WlzGetBackground(iObj, &errNum); if(errNum == WLZ_ERR_NONE) { rVType = WlzGreyTableTypeToTableType(iObj->values.v->type, &errNum); } if(errNum == WLZ_ERR_NONE) { rVType = WlzGreyTableType(rVType, rGType, &errNum); } if(errNum == WLZ_ERR_NONE) { rValues.v = WlzNewValueTb(iObj, rVType, bgdV, &errNum); } if(errNum == WLZ_ERR_NONE) { rObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, iObj->domain, rValues, iObj->plist, iObj->assoc, &errNum); } if(errNum == WLZ_ERR_NONE) { switch(rGType) { case WLZ_GREY_INT: /* FALLTHROUGH */ case WLZ_GREY_SHORT: /* FALLTHROUGH */ case WLZ_GREY_UBYTE: /* FALLTHROUGH */ case WLZ_GREY_RGBA: /* FALLTHROUGH */ case WLZ_GREY_FLOAT: /* FALLTHROUGH */ case WLZ_GREY_DOUBLE: WlzValueConvertPixel(&m, m, WLZ_GREY_DOUBLE); WlzValueConvertPixel(&a, a, WLZ_GREY_DOUBLE); errNum = WlzScalarMulAddSet2D(rObj, iObj, m.v.dbv, a.v.dbv); break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } if(errNum != WLZ_ERR_NONE) { if(rObj == NULL) { (void )WlzFreeValueTb(rValues.v); } else { (void )WlzFreeObj(rObj); rObj = NULL; } } if(dstErr != NULL) { *dstErr = errNum; } return(rObj); }
/*! * \ingroup WlzValuesUtils * \brief Convert a RGBA image to a compound object. The RGBA * channels are at array indices 0,1,2,3 respectively * and the sub-object grey types will be WLZ_GREY_UBYTE. * * \return Compound array of rgba values * \param obj Input domain object with value type * WLZ_GREY_RGBA * \param colSpc The colour space. * \param dstErr Destination error ponyer, may be NULL. */ WlzCompoundArray *WlzRGBAToCompound( WlzObject *obj, WlzRGBAColorSpace colSpc, WlzErrorNum *dstErr) { WlzCompoundArray *cobj=NULL; WlzErrorNum errNum=WLZ_ERR_NONE; /* check object type, and value type */ if( obj ){ switch( obj->type ){ case WLZ_2D_DOMAINOBJ: if( obj->domain.core == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; } else if ( obj->values.core == NULL ){ errNum = WLZ_ERR_VALUES_NULL; } else if( WlzGreyTypeFromObj(obj, &errNum) != WLZ_GREY_RGBA ){ errNum = WLZ_ERR_VALUES_TYPE; } break; case WLZ_3D_DOMAINOBJ: if( obj->domain.core == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; } else if( obj->domain.p->type != WLZ_PLANEDOMAIN_DOMAIN ){ errNum = WLZ_ERR_DOMAIN_TYPE; } else if ( obj->values.core == NULL ){ errNum = WLZ_ERR_VALUES_NULL; } else if( obj->values.vox->type != WLZ_VOXELVALUETABLE_GREY ){ errNum = WLZ_ERR_VALUES_TYPE; } else if( WlzGreyTypeFromObj(obj, &errNum) != WLZ_GREY_RGBA ){ errNum = WLZ_ERR_VALUES_TYPE; } return WlzRGBAToCompound3D(obj, colSpc, dstErr); case WLZ_TRANS_OBJ: /* not difficult, do it later */ errNum = WLZ_ERR_OBJECT_TYPE; break; case WLZ_COMPOUND_ARR_1: case WLZ_COMPOUND_ARR_2: /* bit recursive this ! */ errNum = WLZ_ERR_OBJECT_TYPE; break; case WLZ_EMPTY_OBJ: return (WlzCompoundArray *) WlzMakeEmpty(dstErr); default: errNum = WLZ_ERR_OBJECT_TYPE; } } else { errNum = WLZ_ERR_OBJECT_NULL; } /* check colour space */ if( errNum == WLZ_ERR_NONE ){ switch( colSpc ){ case WLZ_RGBA_SPACE_RGB: case WLZ_RGBA_SPACE_HSB: case WLZ_RGBA_SPACE_CMY: break; default: errNum = WLZ_ERR_PARAM_DATA; break; } } /* create compound object return */ if( errNum == WLZ_ERR_NONE ){ WlzValues values; WlzObject *objs[4]; WlzObjectType type; WlzPixelV oldBck, newBck; type = WlzGreyTableType( WlzGreyTableTypeToTableType(obj->values.core->type, &errNum), WLZ_GREY_UBYTE, &errNum); oldBck = WlzGetBackground(obj, &errNum); /* red */ newBck.type = WLZ_GREY_UBYTE; newBck.v.ubv = (WlzUByte )WLZ_RGBA_RED_GET(oldBck.v.rgbv); values.v = WlzNewValueTb(obj, type, newBck, &errNum); objs[0] = WlzMakeMain(obj->type, obj->domain, values, NULL, NULL, &errNum); /* green */ newBck.v.ubv = (WlzUByte )WLZ_RGBA_GREEN_GET(oldBck.v.rgbv); values.v = WlzNewValueTb(obj, type, newBck, &errNum); objs[1] = WlzMakeMain(obj->type, obj->domain, values, NULL, NULL, &errNum); /* blue */ newBck.v.ubv = (WlzUByte )WLZ_RGBA_BLUE_GET(oldBck.v.rgbv); values.v = WlzNewValueTb(obj, type, newBck, &errNum); objs[2] = WlzMakeMain(obj->type, obj->domain, values, NULL, NULL, &errNum); /* alpha */ newBck.v.ubv = (WlzUByte )WLZ_RGBA_ALPHA_GET(oldBck.v.rgbv); values.v = WlzNewValueTb(obj, type, newBck, &errNum); objs[3] = WlzMakeMain(obj->type, obj->domain, values, NULL, NULL, &errNum); /* create compound object, object pointers are assigned for mode=3 so no need to free objects */ cobj = WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1, 3, 4, &(objs[0]), obj->type, &errNum); } /* iterate through objects setting values */ if( errNum == WLZ_ERR_NONE ){ WlzIntervalWSpace iwsp0, iwsp[4]; WlzGreyWSpace gwsp0, gwsp[4]; int i, j, k; int a, col[3]; errNum = WlzInitGreyScan(obj, &iwsp0, &gwsp0); for(i=0; i < 4; i++){ errNum = WlzInitGreyScan(cobj->o[i], &(iwsp[i]), &(gwsp[i])); } while((errNum == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iwsp0)) == WLZ_ERR_NONE)){ for(i=0; i < 4; i++){ errNum = WlzNextGreyInterval(&(iwsp[i])); } switch( colSpc ){ case WLZ_RGBA_SPACE_RGB: for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++, gwsp0.u_grintptr.rgbp++){ *(gwsp[0].u_grintptr.ubp++) = (WlzUByte )WLZ_RGBA_RED_GET(*(gwsp0.u_grintptr.rgbp)); *(gwsp[1].u_grintptr.ubp++) = (WlzUByte )WLZ_RGBA_GREEN_GET(*(gwsp0.u_grintptr.rgbp)); *(gwsp[2].u_grintptr.ubp++) = (WlzUByte )WLZ_RGBA_BLUE_GET(*(gwsp0.u_grintptr.rgbp)); *(gwsp[3].u_grintptr.ubp++) = (WlzUByte )WLZ_RGBA_ALPHA_GET(*(gwsp0.u_grintptr.rgbp)); } break; case WLZ_RGBA_SPACE_HSB: /* each normalised to [0,255] */ for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++, gwsp0.u_grintptr.rgbp++){ col[0] = WLZ_RGBA_RED_GET(*(gwsp0.u_grintptr.rgbp)); col[1] = WLZ_RGBA_GREEN_GET(*(gwsp0.u_grintptr.rgbp)); col[2] = WLZ_RGBA_BLUE_GET(*(gwsp0.u_grintptr.rgbp)); a = WLZ_RGBA_ALPHA_GET(*(gwsp0.u_grintptr.rgbp)); WlzRGBAConvertRGBToHSV_UBYTENormalised(col); *(gwsp[0].u_grintptr.ubp++) = (WlzUByte )(col[0]); *(gwsp[1].u_grintptr.ubp++) = (WlzUByte )(col[1]); *(gwsp[2].u_grintptr.ubp++) = (WlzUByte )(col[2]); *(gwsp[3].u_grintptr.ubp++) = (WlzUByte )a; } break; case WLZ_RGBA_SPACE_CMY: for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++, gwsp0.u_grintptr.rgbp++){ col[0] = WLZ_RGBA_RED_GET(*(gwsp0.u_grintptr.rgbp)); col[1] = WLZ_RGBA_GREEN_GET(*(gwsp0.u_grintptr.rgbp)); col[2] = WLZ_RGBA_BLUE_GET(*(gwsp0.u_grintptr.rgbp)); a = WLZ_RGBA_ALPHA_GET(*(gwsp0.u_grintptr.rgbp)); *(gwsp[0].u_grintptr.ubp++) = (WlzUByte )((col[1] + col[2]) / 2); *(gwsp[1].u_grintptr.ubp++) = (WlzUByte )((col[2] + col[0]) / 2); *(gwsp[2].u_grintptr.ubp++) = (WlzUByte )((col[0] + col[1]) / 2); *(gwsp[3].u_grintptr.ubp++) = (WlzUByte )a; } break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } if( errNum == WLZ_ERR_EOO ){ errNum = WLZ_ERR_NONE; } } if( dstErr ){ *dstErr = errNum; } return cobj; }
/*! * \ingroup WlzValuesUtils * \brief Convert a grey-level woolz object to RGBA via a colourmap look-up table. Values are clamped to [0,255] and the LUT is assumed to be unsigned byte 3x256 * * \return Woolz object * \param obj Input object to be converted * \param colormap Colourmap array * \param dstErr Error return * \par Source: * WlzRGBAConvert.c */ WlzObject *WlzIndexToRGBA( WlzObject *obj, unsigned char colormap[3][256], WlzErrorNum *dstErr) { WlzObject *rtnObj=NULL; WlzGreyType oldpixtype; WlzGreyP go, gn; WlzIntervalWSpace oldiwsp, newiwsp; WlzGreyWSpace oldgwsp, newgwsp; WlzObjectType newvtbltype; WlzPixelV bg; WlzValues values; int k, greyVal, redVal, greenVal, blueVal; unsigned int rgbaVal; WlzErrorNum errNum=WLZ_ERR_NONE; /* check object - must be domain object with a values table */ if( obj ){ switch( obj->type ){ case WLZ_2D_DOMAINOBJ: if( obj->domain.core ){ if( obj->values.core == NULL ){ errNum = WLZ_ERR_VALUES_NULL; } else { oldpixtype = WlzGreyTableTypeToGreyType(obj->values.core->type, NULL); if( oldpixtype == WLZ_GREY_RGBA ){ return WlzMakeMain(obj->type, obj->domain, obj->values, NULL, NULL, dstErr); } } } else { errNum = WLZ_ERR_DOMAIN_NULL; } break; case WLZ_3D_DOMAINOBJ: return WlzIndexToRGBA3D(obj, colormap, dstErr); default: errNum = WLZ_ERR_OBJECT_TYPE; break; } } else { errNum = WLZ_ERR_OBJECT_NULL; } /* * Set type of new value table so as to preserve * rectangular/single interval/multiple interval * type. */ if( errNum == WLZ_ERR_NONE ){ newvtbltype = WlzGreyTableTypeToTableType(obj->values.core->type, &errNum); } if( errNum == WLZ_ERR_NONE ){ newvtbltype = WlzGreyTableType(newvtbltype, WLZ_GREY_RGBA, &errNum); } /* get the background - note background now carries its own type */ if( errNum == WLZ_ERR_NONE ){ bg = WlzGetBackground(obj, &errNum); switch( bg.type ){ case WLZ_GREY_INT: greyVal = WLZ_CLAMP(bg.v.inv, 0, 255); break; case WLZ_GREY_SHORT: greyVal = WLZ_CLAMP(bg.v.shv, 0, 255); break; case WLZ_GREY_UBYTE: greyVal = bg.v.ubv; break; case WLZ_GREY_FLOAT: greyVal = WLZ_CLAMP(bg.v.flv, 0, 255); break; case WLZ_GREY_DOUBLE: greyVal = (int )WLZ_CLAMP(bg.v.dbv, 0, 255); break; default: errNum = WLZ_ERR_GREY_TYPE; break; } bg.type = WLZ_GREY_RGBA; WLZ_RGBA_RGBA_SET(bg.v.rgbv, colormap[0][greyVal], colormap[1][greyVal], colormap[2][greyVal], 255); } /* * Make the new object with new value table type and value table * allocated (but blank). Share original idom. */ if( errNum == WLZ_ERR_NONE ){ values.v = WlzNewValueTb(obj, newvtbltype, bg, &errNum); } if( errNum == WLZ_ERR_NONE ){ rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, obj->domain, values, obj->plist, obj->assoc, &errNum); } if( errNum == WLZ_ERR_NONE ){ errNum = WlzInitGreyScan(obj, &oldiwsp, &oldgwsp); } if( errNum == WLZ_ERR_NONE ){ errNum = WlzInitGreyScan(rtnObj, &newiwsp, &newgwsp); } while( ((errNum = WlzNextGreyInterval(&oldiwsp)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&newiwsp)) == WLZ_ERR_NONE) ){ go = oldgwsp.u_grintptr; gn = newgwsp.u_grintptr; for(k=0; k <= oldiwsp.colrmn; k++){ switch( oldgwsp.pixeltype ){ case WLZ_GREY_INT: greyVal = WLZ_CLAMP(*(go.inp), 0, 255); go.inp++; break; case WLZ_GREY_SHORT: greyVal = WLZ_CLAMP(*(go.shp), 0, 255); go.shp++; break; case WLZ_GREY_UBYTE: greyVal = *(go.ubp); go.ubp++; break; case WLZ_GREY_FLOAT: greyVal = WLZ_CLAMP(*(go.flp), 0, 255); go.flp++; break; case WLZ_GREY_DOUBLE: greyVal = (int )WLZ_CLAMP(*(go.dbp), 0, 255); go.dbp++; break; default: errNum = WLZ_ERR_GREY_TYPE; break; } redVal = colormap[0][greyVal]; greenVal = colormap[1][greyVal]; blueVal = colormap[2][greyVal]; WLZ_RGBA_RGBA_SET(rgbaVal, redVal, greenVal, blueVal, 0xff); *(gn.rgbp) = rgbaVal; gn.rgbp++; } } /* while */ if(errNum == WLZ_ERR_EOO) /* Reset error from end of intervals */ { errNum = WLZ_ERR_NONE; } if( dstErr ){ *dstErr = errNum; } return rtnObj; }
/*! * \ingroup WlzValuesUtils * \brief Calculate the modulus of the rgb values and return in an image of grey type WLZ_GREY_SHORT * * \return Grey-level object of modulus values * \param obj Input rgba object * \param dstErr error return * \par Source: * WlzRGBAConvert.c */ WlzObject *WlzRGBAToModulus( WlzObject *obj, WlzErrorNum *dstErr) { WlzObject *rtnObj=NULL; WlzErrorNum errNum=WLZ_ERR_NONE; /* check object type, and value type */ if( obj ){ switch( obj->type ){ case WLZ_2D_DOMAINOBJ: if( obj->domain.core == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; } else if ( obj->values.core == NULL ){ errNum = WLZ_ERR_VALUES_NULL; } else if( WlzGreyTypeFromObj(obj, &errNum) != WLZ_GREY_RGBA ){ errNum = WLZ_ERR_VALUES_TYPE; } break; case WLZ_3D_DOMAINOBJ: if( obj->domain.core == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; } else if( obj->domain.p->type != WLZ_PLANEDOMAIN_DOMAIN ){ errNum = WLZ_ERR_DOMAIN_TYPE; } else if ( obj->values.core == NULL ){ errNum = WLZ_ERR_VALUES_NULL; } else if( obj->values.vox->type != WLZ_VOXELVALUETABLE_GREY ){ errNum = WLZ_ERR_VALUES_TYPE; } else if( WlzGreyTypeFromObj(obj, &errNum) != WLZ_GREY_RGBA ){ errNum = WLZ_ERR_VALUES_TYPE; } return WlzRGBAToModulus3D(obj, dstErr); case WLZ_TRANS_OBJ: /* not difficult, do it later */ errNum = WLZ_ERR_OBJECT_TYPE; break; case WLZ_COMPOUND_ARR_1: case WLZ_COMPOUND_ARR_2: /* bit recursive this ! */ errNum = WLZ_ERR_OBJECT_TYPE; break; case WLZ_EMPTY_OBJ: return WlzMakeEmpty(dstErr); default: errNum = WLZ_ERR_OBJECT_TYPE; } } else { errNum = WLZ_ERR_OBJECT_NULL; } /* create object return */ if( errNum == WLZ_ERR_NONE ){ WlzValues values; WlzObjectType type; WlzPixelV oldBck, newBck; type = WlzGreyTableType( WlzGreyTableTypeToTableType(obj->values.core->type, &errNum), WLZ_GREY_SHORT, &errNum); oldBck = WlzGetBackground(obj, &errNum); newBck.type = WLZ_GREY_SHORT; newBck.v.shv = (short )WLZ_RGBA_MODULUS(oldBck.v.rgbv); /* make values table and return object */ values.v = WlzNewValueTb(obj, type, newBck, &errNum); rtnObj = WlzMakeMain(obj->type, obj->domain, values, NULL, NULL, &errNum); } /* iterate through objects setting values */ if( errNum == WLZ_ERR_NONE ){ WlzIntervalWSpace iwsp0, iwsp1; WlzGreyWSpace gwsp0, gwsp1; int j, k; errNum = WlzInitGreyScan(obj, &iwsp0, &gwsp0); errNum = WlzInitGreyScan(rtnObj, &iwsp1, &gwsp1); while((errNum == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iwsp0)) == WLZ_ERR_NONE)){ errNum = WlzNextGreyInterval(&iwsp1); for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++, gwsp0.u_grintptr.rgbp++){ *(gwsp1.u_grintptr.shp++) = (short ) WLZ_RGBA_MODULUS(*(gwsp0.u_grintptr.rgbp)); } } if( errNum == WLZ_ERR_EOO ){ errNum = WLZ_ERR_NONE; } } if( dstErr ){ *dstErr = errNum; } return rtnObj; }
WlzObject *WlzRGBAToChannel( WlzObject *obj, WlzRGBAColorChannel chan, WlzErrorNum *dstErr) { WlzObject *rtnObj=NULL; WlzValues values; WlzObjectType type; WlzPixelV pixVal, oldBck, newBck; WlzErrorNum errNum=WLZ_ERR_NONE; /* check object and channel */ if( obj ){ switch( obj->type ){ case WLZ_2D_DOMAINOBJ: if( obj->domain.core == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; } else if ( obj->values.core == NULL ){ errNum = WLZ_ERR_VALUES_NULL; } else if( WlzGreyTypeFromObj(obj, &errNum) != WLZ_GREY_RGBA ){ errNum = WLZ_ERR_VALUES_TYPE; } break; case WLZ_3D_DOMAINOBJ: if( obj->domain.core == NULL ){ errNum = WLZ_ERR_DOMAIN_NULL; } else if( obj->domain.p->type != WLZ_PLANEDOMAIN_DOMAIN ){ errNum = WLZ_ERR_DOMAIN_TYPE; } else if ( obj->values.core == NULL ){ errNum = WLZ_ERR_VALUES_NULL; } else if( obj->values.vox->type != WLZ_VOXELVALUETABLE_GREY ){ errNum = WLZ_ERR_VALUES_TYPE; } else if( WlzGreyTypeFromObj(obj, &errNum) != WLZ_GREY_RGBA ){ errNum = WLZ_ERR_VALUES_TYPE; } return WlzRGBAToChannel3D(obj, chan, dstErr); case WLZ_TRANS_OBJ: /* not difficult, do it later */ errNum = WLZ_ERR_OBJECT_TYPE; break; case WLZ_COMPOUND_ARR_1: case WLZ_COMPOUND_ARR_2: /* bit recursive this ! */ errNum = WLZ_ERR_OBJECT_TYPE; break; case WLZ_EMPTY_OBJ: return WlzMakeEmpty(dstErr); default: errNum = WLZ_ERR_OBJECT_TYPE; } } else { errNum = WLZ_ERR_OBJECT_NULL; } if( errNum == WLZ_ERR_NONE ){ switch( chan ){ case WLZ_RGBA_CHANNEL_RED: case WLZ_RGBA_CHANNEL_GREEN: case WLZ_RGBA_CHANNEL_BLUE: case WLZ_RGBA_CHANNEL_HUE: case WLZ_RGBA_CHANNEL_SATURATION: case WLZ_RGBA_CHANNEL_BRIGHTNESS: case WLZ_RGBA_CHANNEL_CYAN: case WLZ_RGBA_CHANNEL_MAGENTA: case WLZ_RGBA_CHANNEL_YELLOW: break; default: errNum = WLZ_ERR_PARAM_DATA; break; } } /* now extract data */ if( errNum == WLZ_ERR_NONE ){ type = WlzGreyTableType( WlzGreyTableTypeToTableType(obj->values.core->type, &errNum), WLZ_GREY_UBYTE, &errNum); oldBck = WlzGetBackground(obj, &errNum); newBck.type = WLZ_GREY_UBYTE; newBck.v.ubv = (WlzUByte )WlzRGBAPixelValue(oldBck, chan, &errNum); } /* make values table and return object */ if( errNum == WLZ_ERR_NONE ){ values.v = WlzNewValueTb(obj, type, newBck, &errNum); rtnObj = WlzMakeMain(obj->type, obj->domain, values, NULL, NULL, &errNum); } /* iterate through objects setting values */ if( errNum == WLZ_ERR_NONE ){ WlzIntervalWSpace iwsp0, iwsp1; WlzGreyWSpace gwsp0, gwsp1; int j, k; errNum = WlzInitGreyScan(obj, &iwsp0, &gwsp0); errNum = WlzInitGreyScan(rtnObj, &iwsp1, &gwsp1); pixVal.type = WLZ_GREY_RGBA; while((errNum == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iwsp0)) == WLZ_ERR_NONE)){ errNum = WlzNextGreyInterval(&iwsp1); for(j=0, k=iwsp0.lftpos; k <= iwsp0.rgtpos; j++, k++, gwsp0.u_grintptr.rgbp++){ pixVal.v.rgbv = (*(gwsp0.u_grintptr.rgbp)); *(gwsp1.u_grintptr.ubp++) = (WlzUByte ) WlzRGBAPixelValue(pixVal, chan, &errNum); } } if( errNum == WLZ_ERR_EOO ){ errNum = WLZ_ERR_NONE; } } if( dstErr ){ *dstErr = errNum; } return rtnObj; }