/*! * \return Compound array. * \ingroup WlzTransform * \brief Computes a compound array of three objects, the objects representing the t11, t12 qnd t22 componemts of a tensor. * \param inobj Given object. * \param basisTensorTr Basis Function tensor transform * \param dstErr Destination error pointer, may be * NULL. */ static WlzCompoundArray *WlzBasisFnTensorTransformObjPrv(WlzObject *inObj, WlzBasisFnTransform *basisTr, WlzErrorNum *dstErr) { WlzObject *objT11 = NULL, *objT12 = NULL, *objT22 = NULL; WlzCompoundArray *cArray = NULL; WlzValues valuesT11, valuesT12, valuesT22; WlzIntervalWSpace iWsp, iWspT11, iWspT12, iWspT22; WlzGreyWSpace gWspT11, gWspT12, gWspT22; WlzDVertex2 sVtx; WlzErrorNum errNum=WLZ_ERR_NONE; WlzObjectType vType; WlzGreyP gPixT11, gPixT12, gPixT22; WlzPixelV backgrnd; WlzFnType basisFnType; double t11Partial, t12APartial, t12BPartial, t22Partial; int k, l; valuesT11.core = NULL; valuesT12.core = NULL; valuesT22.core = NULL; basisFnType = basisTr->basisFn->type; /* Create value tables for the two objects */ vType = WlzGreyTableType(WLZ_GREY_TAB_RAGR, WLZ_GREY_FLOAT, NULL); backgrnd.type = WLZ_GREY_FLOAT; backgrnd.v.inv = 0; if((valuesT11.v = WlzNewValueTb(inObj, vType, backgrnd, &errNum)) != NULL) { if((valuesT12.v = WlzNewValueTb(inObj, vType, backgrnd, &errNum)) != NULL) { valuesT22.v = WlzNewValueTb(inObj, vType, backgrnd, &errNum); } else { WlzFreeValueTb(valuesT11.v); WlzFreeValueTb(valuesT12.v); } } else { WlzFreeValueTb(valuesT11.v); } /* create three Wlz objects to hold t11, t22 and t12 tensor components */ if (errNum == WLZ_ERR_NONE) { if ((objT11 = WlzMakeMain(inObj->type, inObj->domain, valuesT11, NULL, NULL, &errNum)) != NULL) { if ((objT12 = WlzMakeMain(inObj->type, inObj->domain, valuesT12, NULL, NULL, &errNum)) != NULL) { if ((objT22 = WlzMakeMain(inObj->type, inObj->domain, valuesT22, NULL, NULL, &errNum)) == NULL) { WlzFreeObj(objT11); objT11 = NULL; WlzFreeObj(objT12); objT12 = NULL; } } else { WlzFreeObj(objT11); objT11 = NULL; } } } /* initialise workspaces */ if (errNum == WLZ_ERR_NONE) { if ((errNum = WlzInitRasterScan(inObj, &iWsp, WLZ_RASTERDIR_ILIC)) == WLZ_ERR_NONE) { if ((errNum = WlzInitGreyScan(objT11, &iWspT11, &gWspT11)) == WLZ_ERR_NONE) { if ((errNum = WlzInitGreyScan(objT12, &iWspT12, &gWspT12)) == WLZ_ERR_NONE) { errNum = WlzInitGreyScan(objT22, &iWspT22, &gWspT22); } } } } /* Calculate tensor components for MQ2 only */ if (errNum == WLZ_ERR_NONE) { switch (basisFnType) { case WLZ_FN_BASIS_2DMQ: while(((errNum = WlzNextInterval(&iWsp)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iWspT11)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iWspT12)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iWspT22)) == WLZ_ERR_NONE)) { gPixT11 = gWspT11.u_grintptr; gPixT12 = gWspT12.u_grintptr; gPixT22 = gWspT22.u_grintptr; l = iWsp.linpos; for (k = iWsp.lftpos; k <= iWsp.rgtpos; k++) { sVtx.vtX = k; sVtx.vtY = l; t11Partial = WlzBasisFnValueMQ2DPrv(basisTr->basisFn, sVtx, 0); *(gPixT11.flp) = (float)t11Partial; ++(gPixT11.flp); t22Partial = WlzBasisFnValueMQ2DPrv(basisTr->basisFn, sVtx, 1); *(gPixT22.flp) = (float)t22Partial; ++(gPixT22.flp); t12APartial = WlzBasisFnValueMQ2DPrv(basisTr->basisFn, sVtx, 2); t12BPartial = WlzBasisFnValueMQ2DPrv(basisTr->basisFn, sVtx, 3); *(gPixT12.flp) = 0.5 * ((float)t12APartial + (float)t12BPartial); ++(gPixT12.flp); } } if(errNum == WLZ_ERR_EOO) { errNum = WLZ_ERR_NONE; } break; case WLZ_FN_BASIS_2DTPS: while(((errNum = WlzNextInterval(&iWsp)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iWspT11)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iWspT12)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&iWspT22)) == WLZ_ERR_NONE)) { gPixT11 = gWspT11.u_grintptr; gPixT12 = gWspT12.u_grintptr; gPixT22 = gWspT22.u_grintptr; l = iWsp.linpos; for (k = iWsp.lftpos; k <= iWsp.rgtpos; k++) { sVtx.vtX = k; sVtx.vtY = l; t11Partial = WlzBasisFnValueTPS2DPrv(basisTr->basisFn, sVtx, 0); *(gPixT11.flp) = (float)t11Partial; ++(gPixT11.flp); t22Partial = WlzBasisFnValueTPS2DPrv(basisTr->basisFn, sVtx, 1); *(gPixT22.flp) = (float)t22Partial; ++(gPixT22.flp); t12APartial = WlzBasisFnValueTPS2DPrv(basisTr->basisFn, sVtx, 2); t12BPartial = WlzBasisFnValueTPS2DPrv(basisTr->basisFn, sVtx, 3); *(gPixT12.flp) = 0.5 * ((float)t12APartial + (float)t12BPartial); ++(gPixT12.flp); } } if(errNum == WLZ_ERR_EOO) { errNum = WLZ_ERR_NONE; } break; default: errNum = WLZ_ERR_TRANSFORM_TYPE; break; } } /* create compound object */ if (errNum == WLZ_ERR_NONE) { cArray = WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1, 1, 3, NULL, objT11->type, &errNum); if (errNum == WLZ_ERR_NONE) { cArray->o[0] = WlzAssignObject(objT11, NULL); cArray->o[1] = WlzAssignObject(objT22, NULL); cArray->o[2] = WlzAssignObject(objT12, NULL); } } if(dstErr) { *dstErr = errNum; } return(cArray); }
/*! * \ingroup WlzAllocation * \brief Free space allocated to a woolz object. * * \return Error number, values: WLZ_ERR_NONE, WLZ_ERR_MEM_FREE * \param obj Object to be freed. * \par Source: * WlzFreeSpace.c */ WlzErrorNum WlzFreeObj(WlzObject *obj) { int i; WlzCompoundArray *ca = (WlzCompoundArray *) obj; WlzErrorNum errNum = WLZ_ERR_NONE; WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_FN|WLZ_DBG_LVL_1), ("WlzFreeObj FE %p\n", obj)); /* check the object pointer and linkcount */ if (obj == NULL){ return( WLZ_ERR_NONE ); } if( WlzUnlink(&(obj->linkcount), &errNum) ){ /* Check linkcount */ switch( obj->type ){ case WLZ_2D_DOMAINOBJ: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_2D_DOMAINOBJ " "%p %d %p %d %p\n", obj, (obj->domain.i), (obj->domain.i?obj->domain.i->linkcount: 0), (obj->values.core), ((obj->values.core)? obj->values.core->linkcount: 0), (obj->plist))); errNum = WlzFreeDomain(obj->domain); if((errNum == WLZ_ERR_NONE) && (obj->values.core != NULL)) { if(WlzGreyTableIsTiled(obj->values.core->type) == WLZ_GREY_TAB_TILED) { errNum = WlzFreeTiledValues(obj->values.t); } else { errNum = WlzFreeValueTb(obj->values.v); } } if(errNum == WLZ_ERR_NONE) { errNum = WlzFreePropertyList(obj->plist); } if(errNum == WLZ_ERR_NONE) { errNum = WlzFreeObj(obj->assoc); } break; case WLZ_3D_DOMAINOBJ: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_3D_DOMAINOBJ %p, " "%d %p %d %p\n", obj, obj->domain.i, (obj->domain.p? obj->domain.p->linkcount: 0), obj->values.core, (obj->values.core? obj->values.core->linkcount: 0), obj->plist)); errNum = WlzFreePlaneDomain(obj->domain.p); if((errNum == WLZ_ERR_NONE) && (obj->values.core != NULL)){ if(WlzGreyTableIsTiled(obj->values.core->type) == WLZ_GREY_TAB_TILED) { errNum = WlzFreeTiledValues(obj->values.t); } else { errNum = WlzFreeVoxelValueTb(obj->values.vox); } } if(errNum == WLZ_ERR_NONE) { errNum = WlzFreePropertyList(obj->plist); } if(errNum == WLZ_ERR_NONE) { errNum = WlzFreeObj(obj->assoc); } break; case WLZ_TRANS_OBJ: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_TRANS_OBJ %p, " "%d %p %d %p\n", obj, obj->domain.t, ((obj->domain.t)?(obj->domain.t)->linkcount: 0), obj->values.obj, ((obj->values.obj)?(obj->values.obj)->linkcount: 0), obj->plist)); if( WlzFreeAffineTransform(obj->domain.t) || WlzFreeObj(obj->values.obj) || WlzFreePropertyList(obj->plist) || WlzFreeObj(obj->assoc) ){ errNum = WLZ_ERR_MEM_FREE; } break; case WLZ_2D_POLYGON: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_2D_POLYGON %p\n", obj, obj->domain.poly)); errNum = WlzFreePolyDmn(obj->domain.poly); break; case WLZ_BOUNDLIST: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_BOUNDLIST %p\n", obj, obj->domain.b)); errNum = WlzFreeBoundList(obj->domain.b); break; case WLZ_CONTOUR: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_CONTOUR %p\n", obj, obj->domain.ctr)); errNum = WlzFreeContour(obj->domain.ctr); break; case WLZ_CONV_HULL: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_CONV_HULL %p %p\n", obj, obj->domain.core, obj->values.core)); if(obj->domain.core) { switch(obj->domain.core->type) { case WLZ_CONVHULL_DOMAIN_2D: errNum = WlzFreeConvexHullDomain2(obj->domain.cvh2); break; case WLZ_CONVHULL_DOMAIN_3D: errNum = WlzFreeConvexHullDomain3(obj->domain.cvh3); break; default: errNum = WLZ_ERR_DOMAIN_TYPE; break; } } break; case WLZ_CMESH_2D: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_CMESH_2D %p, " "%d %p %d %p\n", obj, obj->domain.cm2, ((obj->domain.cm2)? (obj->domain.cm2)->linkcount: 0), obj->values.x, ((obj->values.x)? (obj->values.x)->linkcount: 0), obj->plist)); errNum = WlzCMeshFree2D(obj->domain.cm2); if((errNum == WLZ_ERR_NONE) && (obj->values.core != NULL)) { errNum = WlzFreeIndexedValues(obj->values.x); } if((errNum == WLZ_ERR_NONE) && (obj->plist != NULL)) { errNum = WlzFreePropertyList(obj->plist); } if((errNum == WLZ_ERR_NONE) && (obj->assoc != NULL)) { errNum = WlzFreeObj(obj->assoc); } break; case WLZ_CMESH_2D5: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_CMESH_2D5 %p, " "%d %p %d %p\n", obj, obj->domain.cm2d5, ((obj->domain.cm2d5)? (obj->domain.cm2d5)->linkcount: 0), obj->values.x, ((obj->values.x)? (obj->values.x)->linkcount: 0), obj->plist)); errNum = WlzCMeshFree2D5(obj->domain.cm2d5); if((errNum == WLZ_ERR_NONE) && (obj->values.core != NULL)) { errNum = WlzFreeIndexedValues(obj->values.x); } if((errNum == WLZ_ERR_NONE) && (obj->plist != NULL)) { errNum = WlzFreePropertyList(obj->plist); } if((errNum == WLZ_ERR_NONE) && (obj->assoc != NULL)) { errNum = WlzFreeObj(obj->assoc); } break; case WLZ_CMESH_3D: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_CMESH_3D %p, " "%d %p %d %p\n", obj, obj->domain.cm3, ((obj->domain.cm3)?(obj->domain.cm3)->linkcount: 0), obj->values.x, ((obj->values.x)?(obj->values.x)->linkcount: 0), obj->plist)); errNum = WlzCMeshFree3D(obj->domain.cm3); if((errNum == WLZ_ERR_NONE) && (obj->values.core != NULL)) { errNum = WlzFreeIndexedValues(obj->values.x); } if((errNum == WLZ_ERR_NONE) && (obj->plist != NULL)) { errNum = WlzFreePropertyList(obj->plist); } if((errNum == WLZ_ERR_NONE) && (obj->assoc != NULL)) { errNum = WlzFreeObj(obj->assoc); } break; case WLZ_POINTS: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_POINTS %p\n", obj, obj->domain.pts)); errNum = WlzFreeDomain(obj->domain); if((errNum == WLZ_ERR_NONE) && (obj->values.core != NULL)) { errNum = WlzFreePointValues(obj->values.pts); } if((errNum == WLZ_ERR_NONE) && (obj->plist != NULL)) { errNum = WlzFreePropertyList(obj->plist); } if((errNum == WLZ_ERR_NONE) && (obj->assoc != NULL)) { errNum = WlzFreeObj(obj->assoc); } break; case WLZ_HISTOGRAM: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_CONV_HULL %p\n", obj, obj->domain.hist)); errNum = WlzFreeDomain(obj->domain); break; case WLZ_RECTANGLE: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_RECTANGLE %p\n", obj, obj->domain.r)); errNum = WlzFreeDomain(obj->domain); break; case WLZ_AFFINE_TRANS: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_AFFINE_TRANS\n", obj)); errNum = WlzFreeAffineTransform(obj->domain.t); break; case WLZ_LUT: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_LUT\n", obj)); errNum = WlzFreeDomain(obj->domain); if(errNum == WLZ_ERR_NONE) { errNum = WlzFreeLUTValues(obj->values); } break; case WLZ_COMPOUND_ARR_1: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_COMPOUND_ARR_1\n", ca)); for (i=0; i<ca->n; i++){ if( WlzFreeObj(ca->o[i]) != WLZ_ERR_NONE ){ errNum = WLZ_ERR_MEM_FREE; } } break; case WLZ_COMPOUND_ARR_2: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_COMPOUND_ARR_2\n", ca)); for (i=0; i<ca->n; i++){ if( WlzFreeObj(ca->o[i]) != WLZ_ERR_NONE ){ errNum = WLZ_ERR_MEM_FREE; } } break; case WLZ_PROPERTY_OBJ: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_PROPERTY_OBJ\n", obj)); errNum = WlzFreePropertyList(obj->plist); break; case WLZ_EMPTY_OBJ: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p WLZ_EMPTY_OBJ\n", obj)); break; default: WLZ_DBG((WLZ_DBG_ALLOC|WLZ_DBG_LVL_1), ("WlzFreeObj %p %d\n", obj, (int )(obj->type))); errNum = WLZ_ERR_OBJECT_TYPE; break; } /* End of switch */ AlcFree((void *) obj); } return( errNum ); }
/*! * \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); }
/*! * \return Shade corrected object or NULL on error. * \ingroup WlzValueFilters * \brief Shade corrects the given 2D domain object with grey * values. Grey value types known to be the same. * \param srcObj Given object to be shade * corrected. * \param shdObj Given bright field object. * \param nrmVal Normalization value. * \param inPlace Modify the grey values of the * given object if non-zero. * \param dstErr Destination error pointer, may * be null. */ static WlzObject *WlzShadeCorrect2DG(WlzObject *srcObj, WlzObject *shdObj, double nrmVal, int inPlace, WlzErrorNum *dstErr) { int tI0, iCnt, red, green, blue; double tD0; WlzUInt tUI0, tUI1; WlzObject *uObj = NULL, *uSrcObj = NULL, *uShdObj = NULL, *rtnObj = NULL; WlzGreyP srcPix, shdPix, rtnPix; WlzValues newVal; WlzIntervalWSpace srcIWSp, shdIWSp, rtnIWSp; WlzGreyWSpace srcGWSp, shdGWSp, rtnGWSp; WlzErrorNum errNum = WLZ_ERR_NONE; /* Find intersection of the given and shade objects. */ uObj = WlzIntersect2(srcObj, shdObj, &errNum); /* Make new objects with the values of the given and shade objects * but the domain of their intersection. */ if(errNum == WLZ_ERR_NONE) { uSrcObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, uObj->domain, srcObj->values, NULL, NULL, &errNum); } if(errNum == WLZ_ERR_NONE) { uShdObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, uObj->domain, shdObj->values, NULL, NULL, &errNum); } /* Make a new object, again using the union for the domain, but this time * either sharing the given objects values or creating a new value table. */ if(errNum == WLZ_ERR_NONE) { if(inPlace) { rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, uObj->domain, srcObj->values, NULL, NULL, &errNum); } else { newVal.v = WlzNewValueTb(uObj, srcObj->values.core->type, WlzGetBackground(srcObj, NULL), &errNum); if(errNum == WLZ_ERR_NONE) { if((rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, uObj->domain, newVal, NULL, NULL, &errNum)) == NULL) { (void )WlzFreeValueTb(newVal.v); } } } } /* Work through the intervals setting the grey values. */ if(errNum == WLZ_ERR_NONE) { if(((errNum = WlzInitGreyScan(uSrcObj, &srcIWSp, &srcGWSp)) == WLZ_ERR_NONE) && ((errNum = WlzInitGreyScan(uShdObj, &shdIWSp, &shdGWSp)) == WLZ_ERR_NONE) && ((errNum = WlzInitGreyScan(rtnObj, &rtnIWSp, &rtnGWSp)) == WLZ_ERR_NONE)) { while(((errNum = WlzNextGreyInterval(&srcIWSp)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&shdIWSp)) == WLZ_ERR_NONE) && ((errNum = WlzNextGreyInterval(&rtnIWSp)) == WLZ_ERR_NONE)) { srcPix = srcGWSp.u_grintptr; shdPix = shdGWSp.u_grintptr; rtnPix = rtnGWSp.u_grintptr; iCnt = rtnIWSp.rgtpos - rtnIWSp.lftpos + 1; switch(rtnGWSp.pixeltype) { case WLZ_GREY_INT: while(iCnt-- > 0) { tD0 = (*(srcPix.inp)++ * nrmVal) / (*(shdPix.inp)++ + 1.0); *(rtnPix.inp)++ = WLZ_NINT(tD0); } break; case WLZ_GREY_SHORT: while(iCnt-- > 0) { tD0 = (*(srcPix.shp)++ * nrmVal) / (*(shdPix.shp)++ + 1.0); tI0 = WLZ_NINT(tD0); *(rtnPix.shp)++ = (short )WLZ_CLAMP(tI0, SHRT_MIN, SHRT_MAX); } break; case WLZ_GREY_UBYTE: while(iCnt-- > 0) { tD0 = (*(srcPix.ubp)++ * nrmVal) / (*(shdPix.ubp)++ + 1.0); tI0 = WLZ_NINT(tD0); *(rtnPix.ubp)++ = (WlzUByte )WLZ_CLAMP(tI0, 0, 255); } break; case WLZ_GREY_FLOAT: while(iCnt-- > 0) { tD0 = (*(srcPix.flp)++ * nrmVal) / (*(shdPix.flp)++ + 1.0); *(rtnPix.flp)++ = (float )tD0; } break; case WLZ_GREY_DOUBLE: while(iCnt-- > 0) { tD0 = (*(srcPix.dbp)++ * nrmVal) / (*(shdPix.dbp)++ + 1.0); *(rtnPix.dbp)++ = tD0; } break; case WLZ_GREY_RGBA: while(iCnt-- > 0) { /* slightly different logic here. Avoid divide by zero by explicit check */ tUI0 = *(srcPix.rgbp)++; tUI1 = *(shdPix.rgbp)++; red = WLZ_RGBA_RED_GET(tUI1); red = (red)? (int )(((WLZ_RGBA_RED_GET(tUI0) * nrmVal))/red): (int )nrmVal; red = WLZ_CLAMP(red, 0, 255); green = WLZ_RGBA_GREEN_GET(tUI1); green = (green)? (int )(((WLZ_RGBA_GREEN_GET(tUI0) * nrmVal))/green): (int )nrmVal; green = WLZ_CLAMP(green, 0, 255); blue = WLZ_RGBA_BLUE_GET(tUI1); blue = (blue)? (int )(((WLZ_RGBA_BLUE_GET(tUI0) * nrmVal))/blue): (int )nrmVal; blue = WLZ_CLAMP(blue, 0, 255); WLZ_RGBA_RGBA_SET(tUI0, red, green, blue, 255); *(rtnPix.rgbp)++ = tUI0; } break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } if(errNum == WLZ_ERR_EOO) /* Reset error from end of intervals */ { errNum = WLZ_ERR_NONE; } } } (void )WlzFreeObj(uObj); (void )WlzFreeObj(uSrcObj); (void )WlzFreeObj(uShdObj); if(errNum != WLZ_ERR_NONE) { (void )WlzFreeObj(rtnObj); rtnObj = NULL; } if(dstErr) { *dstErr = errNum; } return(rtnObj); }