/*!
* \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);
}
Beispiel #2
0
void read_reference_object_cb(
  Widget	w,
  XtPointer	client_data,
  XtPointer	call_data)
{
  XmFileSelectionBoxCallbackStruct *cbs =
    (XmFileSelectionBoxCallbackStruct *) call_data;
  WlzEffFormat		image_type;
  WlzObject		*obj;
  String		icsfile;
  WlzDomain	domain;
  WlzValues	values;
  WlzObject	*newObj;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  /* set hour glass cursor */
  HGU_XmSetHourGlassCursor(globals.topl);

  /* read the new reference object
     note the switch is to allow direct read
     given the image type to include the model
     input options */
  if( client_data ){
    image_type = (WlzEffFormat) client_data;
    if((icsfile = HGU_XmGetFileStr(globals.topl, cbs->value,
				   cbs->dir))){
      obj = WlzEffReadObj(NULL, icsfile, image_type, 0, 0, 0, &errNum);
      AlcFree(icsfile);
    }
    else {
      obj = NULL;
    }
  }
  else {
    obj = HGU_XmReadExtFFObject(read_obj_dialog, cbs,
			       &image_type, &errNum);
  }
  if( obj == NULL){
    HGU_XmUserError(globals.topl,
		    "Read Reference Object:\n"
		    "    No reference object read - either the\n"
		    "    selected file is empty or it is not the\n"
		    "    correct object type - please check the\n"
		    "    file or make a new selection",
   		    XmDIALOG_FULL_APPLICATION_MODAL);
    /* set hour glass cursor */
    HGU_XmUnsetHourGlassCursor(globals.topl);
    return;
  }

  if( obj->values.core == NULL ){
    HGU_XmUserError(globals.topl,
		    "Read Reference Object:\n"
		    "    The reference object must have a grey-\n"
		    "    value table. Please select an alternate\n"
		    "    object",
		    XmDIALOG_FULL_APPLICATION_MODAL);
    WlzFreeObj( obj );
    /* set hour glass cursor */
    HGU_XmUnsetHourGlassCursor(globals.topl);
    return;
  }

  /* install the new reference object */
  switch( obj->type ){

  case WLZ_2D_DOMAINOBJ:
    if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN, 0, 0,
				      obj->domain.i->line1,
				      obj->domain.i->lastln,
				      obj->domain.i->kol1,
				      obj->domain.i->lastkl,
				      &errNum))){
      domain.p->domains[0] = WlzAssignDomain(obj->domain, NULL);
      if((values.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
					   0, 0, WlzGetBackground(obj, NULL),
					   NULL, &errNum))){
	values.vox->values[0] = WlzAssignValues(obj->values, NULL);
	newObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
			     obj->plist, NULL, &errNum);
	WlzFreeObj(obj);
	obj = newObj;
      }
    }
    globals.origObjType = WLZ_2D_DOMAINOBJ;
    break;

  case WLZ_3D_DOMAINOBJ:
    globals.origObjType = WLZ_3D_DOMAINOBJ;
    break;

  default:
    HGU_XmUserError(globals.topl,
		    "Read Reference Object:\n"
		    "    The reference object must be a 2- or 3-D\n"
		    "    grey-level image. Please select an alternate\n"
		    "    object",
		    XmDIALOG_FULL_APPLICATION_MODAL);
    WlzFreeObj( obj );
    /* set hour glass cursor */
    HGU_XmUnsetHourGlassCursor(globals.topl);
    return;
  }
  globals.origObjExtType = image_type;

  /* set title and reference file list */
  if((icsfile = HGU_XmGetFileStr(globals.topl, cbs->value, cbs->dir)))
  {
    Widget	cascade;
    HGU_XmFileListAddFile(globals.fileList, icsfile, image_type);
    HGU_XmFileListWriteResourceFile(globals.fileList,
				    globals.resourceFile);
    if((cascade = XtNameToWidget(globals.topl,
				 "*file_menu*_pulldown*Recent"))){
      HGU_XmFileListResetMenu(globals.fileList, cascade, referenceFileListCb);
    }
    if( XmStringGetLtoR(cbs->value, XmSTRING_DEFAULT_CHARSET, &icsfile) )
    {
      set_topl_title(icsfile);
      globals.file = icsfile;
    }
  }
  MAPaintLogData("ReferenceFile", globals.file, 0, NULL);

  /* clear feedback object and install new reference object */
  if( errNum == WLZ_ERR_NONE ){
    if( globals.fb_obj ){
      WlzFreeObj(globals.fb_obj);
      globals.fb_obj = NULL;
    }
    install_paint_reference_object( obj );
  }

  /* set hour glass cursor */
  HGU_XmUnsetHourGlassCursor(globals.topl);

  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "read_reference_object_cb", errNum);
  }
  return;
}
Beispiel #3
0
/*!
* \return	New 3D object.
* \ingroup	WlzAllocation
* \brief	Constructs a 3D domain object from 2D domain objects. Each
*		2D object is assigned in turn to the 3D object no domains
*		or values are copied. An empty can be specified by
*		setting the 2D object to NULL. Either all or none of
*		the 2D objects must have values. When the 2D objects
*		have values then the background value of the first 2D
*		object is set to be the background value of the 3D object.
* \param	nObjs			Number of objects.
* \param	objs			The 2D objects, the first of which
*					MUST not be NULL.
* \param	plane1			The plane coordinate of the first
*					2D object.
* \param	xSz			Column voxel size.
* \param	ySz			Line voxel size.
* \param	zSz			Plane voxel size.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject	*WlzConstruct3DObjFromObj(int nObjs, WlzObject **objs,
					 int plane1,
					 float xSz, float ySz, float zSz,
					 WlzErrorNum *dstErr)
{
  int		idx,
  		lastpl;
  WlzDomain	dom3D;
  WlzValues	val3D;
  WlzObject	*obj2D,
  		*obj3D = NULL;
  WlzPixelV	bgd;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  dom3D.core = NULL;
  val3D.core = NULL;
  lastpl = plane1 + nObjs - 1;
  if((nObjs <= 0) || (objs == NULL))
  {
    errNum = WLZ_ERR_PARAM_NULL;
  }
  else if((obj2D = *objs) == NULL)
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else
  {
    switch(obj2D->type)
    {
      case WLZ_EMPTY_OBJ:
	break;
      case WLZ_2D_DOMAINOBJ:
	if(obj2D->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	break;
      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  /* Make a plane domain, set column and line bounds later. */
  if(errNum == WLZ_ERR_NONE)
  {
    dom3D.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
    				 plane1, lastpl,
				 0, 1, 0, 1, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dom3D.p->voxel_size[0] = xSz;
    dom3D.p->voxel_size[1] = ySz;
    dom3D.p->voxel_size[2] = zSz;
  }
  /* Make a voxel value table. */
  if(errNum == WLZ_ERR_NONE)
  {
    if(obj2D->values.core)
    {
      bgd = WlzGetBackground(obj2D, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	val3D.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
					plane1, lastpl, bgd, NULL, &errNum);
      }
    }				    
  }
  for(idx = 0; (errNum == WLZ_ERR_NONE) && (idx < nObjs); ++idx)
  {
    obj2D = *(objs + idx);
    if(obj2D)
    {
      switch(obj2D->type)
      {
	case WLZ_EMPTY_OBJ:
	  break;
	case WLZ_2D_DOMAINOBJ:
	  if(obj2D->domain.core == NULL)
	  {
	    errNum = WLZ_ERR_DOMAIN_NULL;
	  }
	  break;
	default:
	  errNum = WLZ_ERR_OBJECT_TYPE;
	  break;
      }
      if(errNum == WLZ_ERR_NONE)
      {
	*(dom3D.p->domains + idx) = WlzAssignDomain(obj2D->domain, NULL);
	if(val3D.core)
	{
	  if((obj2D->domain.core != NULL) && (obj2D->values.core == NULL))
	  {
	    errNum = WLZ_ERR_VALUES_NULL;
	  }
	  else
	  {
	    *(val3D.vox->values + idx) = WlzAssignValues(obj2D->values, NULL);
	  }
	}
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzStandardPlaneDomain(dom3D.p, val3D.vox);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    obj3D = WlzMakeMain(WLZ_3D_DOMAINOBJ, dom3D, val3D, NULL, NULL, &errNum);
  }
  if(errNum != WLZ_ERR_NONE)
  {
    if(dom3D.core)
    {
      (void )WlzFreeDomain(dom3D);
    }
    if(val3D.core)
    {
      (void )WlzFreeValues(val3D);
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(obj3D);
}
Beispiel #4
0
/*!
* \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;
}
Beispiel #5
0
void referenceFileListCb(
  Widget	w,
  XtPointer	client_data,
  XtPointer	call_data)
{
  HGU_XmFileListCallbackStruct	*cbs=
    (HGU_XmFileListCallbackStruct *) client_data;
  WlzObject	*obj;
  Widget	cascade;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  HGU_XmSetHourGlassCursor(globals.topl);
  if( cbs == NULL ){
    /* clear list selection */
    HGU_XmFileListClearList(globals.fileList);
    HGU_XmFileListWriteResourceFile(globals.fileList,
				    globals.resourceFile);
    if((cascade = XtNameToWidget(globals.topl,
				 "*file_menu*_pulldown*Recent"))){
      HGU_XmFileListResetMenu(globals.fileList, cascade, referenceFileListCb);
    }
  }
  else if((obj = HGU_XmFileListReadObject(w, cbs, &errNum))){
    WlzDomain	domain;
    WlzValues	values;
    WlzObject	*newObj;

    switch( obj->type ){

    case WLZ_2D_DOMAINOBJ:
      if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN, 0, 0,
					obj->domain.i->line1,
					obj->domain.i->lastln,
					obj->domain.i->kol1,
					obj->domain.i->lastkl,
					&errNum))){
	domain.p->domains[0] = WlzAssignDomain(obj->domain, NULL);
	if((values.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
					     0, 0, WlzGetBackground(obj, NULL),
					     NULL, &errNum))){
	  values.vox->values[0] = WlzAssignValues(obj->values, NULL);
	  newObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
			       NULL, NULL, NULL);
	  WlzFreeObj(obj);
	  obj = newObj;
	}
      }
      globals.origObjType = WLZ_2D_DOMAINOBJ;
      break;

    case WLZ_3D_DOMAINOBJ:
      globals.origObjType = WLZ_3D_DOMAINOBJ;
      break;

    default:
      HGU_XmUserError(globals.topl,
		      "Read Reference Object:\n"
		      "    The reference object must be a 2- or 3-D\n"
		      "    grey-level image. Please select an alternate\n"
		      "    object",
		      XmDIALOG_FULL_APPLICATION_MODAL);
      WlzFreeObj( obj );
      /* set hour glass cursor */
      HGU_XmUnsetHourGlassCursor(globals.topl);
      return;
    }
    MAPaintLogData("ReferenceFile", refFileList[0], 0, NULL);
    install_paint_reference_object( obj );

    /* set the title of the top-level window */
    set_topl_title(cbs->file);
    globals.file = AlcStrDup(cbs->file);
    globals.origObjExtType = cbs->format;

    /* add to the file list and write file */
    HGU_XmFileListAddFile(globals.fileList, cbs->file, cbs->format);
    HGU_XmFileListWriteResourceFile(globals.fileList,
				    globals.resourceFile);
    if((cascade = XtNameToWidget(globals.topl,
				 "*file_menu*_pulldown*Recent"))){
      HGU_XmFileListResetMenu(globals.fileList, cascade, referenceFileListCb);
    }
  }

  HGU_XmUnsetHourGlassCursor(globals.topl);

  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "ReferenceFileListCb", errNum);
  }
  return;
}
Beispiel #6
0
/*!
* \return	New Woolz object.
* \ingroup	WlzAllocation
* \brief	Creates a new 2D spatial domain object by adding a
* 		rectangular buffer of values to the given current
* 		object (which may be NULL or empty).
* \param	cObj			Given current object.
* \param	og			Origin of rectangular buffer.
* \param	sz			Buffer size.
* \param	gType			Grey type which must be consistent
* 					with the current object and the
* 					buffer of values.
* \param	bufSz			Number of values in the buffer.
* \param	bufP			Given buffer of values.
* \param	dstErr			Destination error pointer, may be NULL.
*/
static WlzObject *WlzBuildObj2(WlzObject *cObj,
                               WlzIVertex2 og, WlzIVertex2 sz,
                               WlzGreyType gType, int bufSz, WlzGreyP bufP,
                               WlzErrorNum *dstErr)
{
    WlzDomain	bDom;
    WlzValues	bVal,
                nVal;
    WlzObject	*bObj = NULL,
                 *nObj = NULL;
    WlzPixelV	bgdV;
    WlzErrorNum	errNum = WLZ_ERR_NONE;

    bDom.core = NULL;
    bVal.core = NULL;
    nVal.core = NULL;
    bgdV.type = WLZ_GREY_INT;
    bgdV.v.inv = 0;
    if(cObj)
    {
        WlzGreyType cGType = WLZ_GREY_ERROR;;

        switch(cObj->type)
        {
        case WLZ_EMPTY_OBJ:
            cObj = NULL;
            break;
        case WLZ_2D_DOMAINOBJ:
            if(cObj->domain.core == NULL)
            {
                errNum = WLZ_ERR_DOMAIN_NULL;
            }
            else if(cObj->values.core == NULL)
            {
                errNum = WLZ_ERR_VALUES_NULL;
            }
            else
            {
                cGType = WlzGreyTypeFromObj(cObj, &errNum);
                bgdV = WlzGetBackground(cObj, &errNum);
            }
            if((errNum == WLZ_ERR_NONE) && (cGType != gType))
            {
                errNum = WLZ_ERR_GREY_TYPE;
            }
            break;
        default:
            errNum = WLZ_ERR_OBJECT_TYPE;
            break;
        }
    }
    /* Create new object with domain and values of given rectangular buffer. */
    if(errNum == WLZ_ERR_NONE)
    {
        bDom.i = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_RECT,
                                       og.vtY, og.vtY + sz.vtY - 1,
                                       og.vtX, og.vtX + sz.vtX - 1,
                                       &errNum);
    }
    if(errNum == WLZ_ERR_NONE)
    {
        WlzObjectType gTT;

        gTT = WlzGreyTableType(WLZ_GREY_TAB_RECT, gType, NULL);
        bVal.r = WlzMakeRectValueTb(gTT, bDom.i->line1, bDom.i->lastln,
                                    bDom.i->kol1, sz.vtX, bgdV, bufP.inp, &errNum);
    }
    if(errNum == WLZ_ERR_NONE)
    {
        bObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, bDom, bVal, NULL, NULL, &errNum);
    }
    if(errNum == WLZ_ERR_NONE)
    {
        if(cObj == NULL)
        {
            /* Just copy the buffer object. */
            nObj = WlzCopyObject(bObj, &errNum);
        }
        else
        {
            /* Compute union of current and buffer objects. */
            nObj = (cObj)? WlzUnion2(cObj, bObj, &errNum):
                   WlzMakeMain(WLZ_2D_DOMAINOBJ, bDom, nVal,
                               NULL, NULL, &errNum);
            /* Create new value table. */
            if(errNum == WLZ_ERR_NONE)
            {
                WlzObjectType gTT;

                gTT = WlzGreyTableType(WLZ_GREY_TAB_RAGR, gType, NULL);
                nVal.v = WlzNewValueTb(nObj, gTT, bgdV, &errNum);
            }
            if(errNum == WLZ_ERR_NONE)
            {
                nObj->values = WlzAssignValues(nVal, NULL);
            }
            if(errNum == WLZ_ERR_NONE)
            {
                WlzObject 	*tObj;

                /* Copy existing values to new object. */
                tObj = WlzGreyTransfer(nObj, cObj, &errNum);
                (void )WlzFreeObj(nObj);
                nObj = tObj;
                /* Then copy buffer values to new object. */
                if(errNum == WLZ_ERR_NONE)
                {
                    tObj = WlzGreyTransfer(nObj, bObj, &errNum);
                    (void )WlzFreeObj(nObj);
                    nObj = tObj;
                }
            }
        }
    }
    (void )WlzFreeObj(bObj);
    if(dstErr)
    {
        *dstErr = errNum;
    }
    return(nObj);
}
/*!
* \return	Rescaled object.
* \ingroup	WlzTransform
* \brief	Rescales the given 3D domain object using an integer scale.
* \param	gObj			Given object.
* \param	scale			Integer scale factor.
* \param	expand			If zero use \f$\frac{1}{scale}\f$.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject	*WlzIntRescaleObj3D(WlzObject *gObj, int scale, int expand,
				    WlzErrorNum *dstErr)
{
  int		gPIdx,
  		nPIdx;
  WlzDomain	gDom,
  		nDom;
  WlzValues	gVal,
  		nVal,
		dumVal;
  WlzObject	*gTObj = NULL,
  		*nTObj = NULL,
		*rObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  WlzIBox3	nBox;

  nDom.core = NULL;
  nVal.core = NULL;
  dumVal.core = NULL;
  gDom = gObj->domain;
  gVal = gObj->values;
  if(expand)
  {
    nBox.xMin = gDom.p->kol1 * scale;
    nBox.xMax = ((gDom.p->lastkl + 1) * scale) - 1;
    nBox.yMin = gDom.p->line1 * scale;
    nBox.yMax = ((gDom.p->lastln + 1) * scale) - 1;
    nBox.zMin = gDom.p->plane1 * scale;
    nBox.zMax = ((gDom.p->lastpl + 1) * scale) - 1;
  }
  else
  {
    nBox.xMin = gDom.p->kol1 / scale;
    nBox.xMax = gDom.p->lastkl / scale;
    nBox.yMin = gDom.p->line1 / scale;
    nBox.yMax = gDom.p->lastln / scale;
    nBox.zMin = gDom.p->plane1 / scale;
    nBox.zMax = gDom.p->lastpl / scale;
  }
  nDom.p = WlzMakePlaneDomain(gDom.p->type, nBox.zMin, nBox.zMax,
			      nBox.yMin, nBox.yMax, nBox.xMin, nBox.xMax,
			      &errNum);
  if(errNum == WLZ_ERR_NONE)
  {
    if(gVal.core && (gVal.core->type != WLZ_EMPTY_OBJ))
    {
      if(WlzGreyTableIsTiled(gVal.core->type))
      {
        errNum = WLZ_ERR_VALUES_TYPE;
      }
      else
      {
	nVal.vox = WlzMakeVoxelValueTb(gVal.vox->type, nBox.zMin, nBox.zMax,
				WlzGetBackground(gObj, NULL),
				NULL, &errNum);
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    nPIdx = nBox.zMin;
    while((errNum == WLZ_ERR_NONE) && (nPIdx <= nBox.zMax))
    {
      gPIdx = (expand)? nPIdx / scale: nPIdx * scale;
      if(nVal.vox)
      {
        gTObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
                            *(gDom.p->domains + gPIdx),
                            *(gVal.vox->values + gPIdx),
                            NULL, NULL, &errNum);
      }
      else
      {
        gTObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
                            *(gDom.p->domains + gPIdx),
                            dumVal,
                            NULL, NULL, &errNum);
      }
      if(errNum == WLZ_ERR_NONE)
      {
	nTObj = WlzIntRescaleObj2D(gTObj, scale, expand, &errNum);
      }
      (void )WlzFreeObj(gTObj);
      gTObj = NULL;
      if(errNum == WLZ_ERR_NONE)
      {
        *(nDom.p->domains + nPIdx) = WlzAssignDomain(nTObj->domain, NULL);
        if(nVal.vox)
        {
          *(nVal.vox->values + nPIdx) = WlzAssignValues(nTObj->values, NULL);
        }
      }
      (void )WlzFreeObj(nTObj);
      nTObj = NULL;
      ++nPIdx;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    rObj = WlzMakeMain(gObj->type, nDom, nVal, NULL, NULL, &errNum);
  }
  else
  {
    (void )WlzFreePlaneDomain(nDom.p);
    (void )WlzFreeVoxelValueTb(nVal.vox);
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(rObj);
}
Beispiel #8
0
/*! 
* \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;
}
Beispiel #9
0
/*! 
* \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;
}
Beispiel #10
0
/*!
* \return	New 3D domain object with corresponding WLZ_GREY_RGBA values.
* \ingroup      WlzValuesUtils
* \brief	Creates a WLZ_GREY_RGBA valued object from the given compound
* 		array. This is a static function which will always be called
* 		with valid parameters so they aren't checked.
* \param	cObj			Compound array object.
* \param	cSpc 			The colour space.
* \param	dstErr			Destination error pointer may be NULL.
*/
static WlzObject *WlzCompoundToRGBA2D(WlzCompoundArray *cObj,
  				WlzRGBAColorSpace cSpc, WlzErrorNum *dstErr)
{
  int		i,
  		j;
  WlzObject	*rtnObj=NULL;
  WlzPixelV	bckgrnd;
  WlzObject	*objs[4];
  WlzObjectType vType;
  WlzUInt	b[4];
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  /* Make a copy of the object pointers because WlzUnionN() modifies the
   * array if it contains empty objects. */
  for(i = 0; i < 3; ++i)
  {
    objs[i] = cObj->o[i];
  }
  rtnObj = WlzUnionN(3, objs, 0, &errNum);
  if(errNum == WLZ_ERR_NONE)
  {
    /* Add an RGBA valuetable, extract background for each channel */
    vType = WlzGreyTableType(WLZ_GREY_TAB_RAGR, WLZ_GREY_RGBA, &errNum);
    for(i=0; (errNum == WLZ_ERR_NONE) && (i < 3); i++)
    {
      bckgrnd = WlzGetBackground(cObj->o[i], &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
        errNum = WlzValueConvertPixel(&bckgrnd, bckgrnd, WLZ_GREY_UBYTE);
        b[i] = bckgrnd.v.ubv;
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    WlzValues	values;

    bckgrnd.type = WLZ_GREY_RGBA;
    WLZ_RGBA_RGBA_SET(bckgrnd.v.rgbv, b[0], b[1], b[2], 255);
    values.v = WlzNewValueTb(rtnObj, vType, bckgrnd, &errNum);
    if(values.v != NULL)
    {
      rtnObj->values = WlzAssignValues(values, &errNum);
    }
    else
    {
      (void )WlzFreeObj(rtnObj);
      rtnObj = NULL;
    }
  }
  /* Transfer values */
  if( errNum == WLZ_ERR_NONE)
  {
    WlzGreyValueWSpace	*gValWSpc[4];
    WlzIntervalWSpace	iwsp;
    WlzGreyWSpace	gwsp;
    WlzGreyV		gval;

    /* do it dumb fashion for now, rgb only */
    gValWSpc[0] = gValWSpc[1] = gValWSpc[2] = gValWSpc[3] = NULL;
    for(i=0; i < 3; i++)
    {
      if((cObj->o[i] != NULL) && (cObj->o[i]->type != WLZ_EMPTY_OBJ))
      {
        gValWSpc[i] = WlzGreyValueMakeWSp(cObj->o[i], &errNum);
	if(errNum != WLZ_ERR_NONE)
	{
	  break;
	}
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      errNum = WlzInitGreyScan(rtnObj, &iwsp, &gwsp);
    }
    while((errNum == WLZ_ERR_NONE) &&
          ((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE))
    {
      WlzPixelV	pix;

      for(j = iwsp.lftpos; j <= iwsp.rgtpos; j++)
      {
	for(i = 0; i < 3; i++)
	{
	  if(gValWSpc[i] == NULL)
	  {
	    pix.v.ubv = (i < 2)? 0: 255;
	  }
	  else
	  {
	    WlzGreyValueGet(gValWSpc[i], 0, iwsp.linpos, j);
	    pix.type = gValWSpc[i]->gType;
	    pix.v = gValWSpc[i]->gVal[0];
	    WlzValueConvertPixel(&pix, pix, WLZ_GREY_UBYTE);
	  }
	  b[i] = pix.v.ubv;
	}
	WLZ_RGBA_RGBA_SET(gval.rgbv, b[0], b[1], b[2], b[3]);
	*gwsp.u_grintptr.rgbp = gval.rgbv;
	gwsp.u_grintptr.rgbp++;
      }
    }
    if(errNum == WLZ_ERR_EOO)
    {
      errNum = WLZ_ERR_NONE;
    }
    for(i=0; i < 3; i++)
    {
      WlzGreyValueFreeWSp(gValWSpc[i]);
    }
  }
  if(dstErr != NULL)
  {
    *dstErr = errNum;
  }
  return(rtnObj);
}
Beispiel #11
0
/*! 
* \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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
/*! 
* \ingroup      WlzBinaryOps
* \brief        Calculate the intersection of a set of objects. If
 uvt=0 calculate domain only, uvt=1 calculate the mmean grey-value at
 each point. Input objects must be all non-NULL and domain objects of
 the same type i.e. either 2D or 3D otherwise an error is returned.
*
* \return       Intersection object with grey-table as required, if the intersection is empty returns WLZ_EMPTY_OBJ, NULL on error.
* \param    n	number of input objects
* \param    objs	input object array
* \param    uvt	grey-table copy flag (1 - copy, 0 - no copy)
* \param    dstErr	error return.
* \par      Source:
*                WlzIntersectN.c
*/
WlzObject *WlzIntersectN(
  int 	n,
  WlzObject **objs,
  int 	uvt,
  WlzErrorNum *dstErr)
{
  WlzObject 		*obj = NULL;
  WlzIntervalDomain 	*idom;
  WlzInterval 		*itvl, *jtvl;
  WlzIntervalWSpace 	*iwsp;
  WlzIntervalWSpace 	*biwsp,*tiwsp,niwsp;
  WlzGreyWSpace 	*gwsp,ngwsp;
  WlzDomain		domain;
  WlzValues		values;
  WlzObjectType		type;
  WlzPixelV		backg;
  WlzGreyP		greyptr;
  WlzGreyV		gv;
  int 			i, j, k, l, inttot, change, lwas, nints;
  int 			line1, lastln;
  int 			kol1, lastkl;
  WlzErrorNum		errNum = WLZ_ERR_NONE;

  /*
   * check pointers
   */
  /* intersecction of no objects is an empty domain */
  domain.i = NULL;
  values.v = NULL;
  if( n < 1 )
  {
    return WlzMakeEmpty(dstErr);
  }

  /* array pointer == NULL or any object pointer == NULL is an error */
  if(objs == NULL){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else
  {
    for(i=0; i<n; i++){
      if(objs[i] == NULL){
	errNum = WLZ_ERR_OBJECT_NULL;
      }
    }
  }
  if(errNum != WLZ_ERR_NONE)
  {
    obj = NULL;
    if(dstErr) {
      *dstErr = errNum;
    }
    return(obj);
  }

  /* check type of first object */
  switch( objs[0]->type ){

  case WLZ_2D_DOMAINOBJ:
    break;

  case WLZ_3D_DOMAINOBJ:
    return WlzIntersect3d(objs, n, uvt, &errNum);

  case WLZ_EMPTY_OBJ:
    return WlzMakeEmpty(dstErr);

  default:
    errNum = WLZ_ERR_OBJECT_TYPE;
    if(dstErr) {
      *dstErr = errNum;
    }
    return NULL;

  }

  /* check number */
  if (n == 1){
    obj = WlzMakeMain(objs[0]->type, objs[0]->domain, objs[0]->values,
		      NULL, NULL, &errNum);
    if(dstErr) {
      *dstErr = errNum;
    }
    return(obj);
  }

  /* check all objects are non-empty and have the same type
     Note an empty object is not an error */
  for (i=0; i<n; i++){
    if( objs[i]->type != objs[0]->type ){
      if( objs[i]->type == WLZ_EMPTY_OBJ ){
	return WlzMakeEmpty(dstErr);
      }
      else {
	errNum = WLZ_ERR_OBJECT_TYPE;
	if(dstErr) {
	  *dstErr = errNum;
	}
	return NULL;
      }
    }

    /* check for size */
    if( WlzIsEmpty(objs[i], &errNum) ){
      return WlzMakeEmpty(dstErr);
    }
    else {
      if( errNum != WLZ_ERR_NONE ){
	if(dstErr) {
	  *dstErr = errNum;
	}
	return NULL;
      }
    }
  }

  /*
   * Find the line and column bounds of the intersection.
   */
  line1 = objs[0]->domain.i->line1;
  lastln = objs[0]->domain.i->lastln;
  kol1 = objs[0]->domain.i->kol1;
  lastkl = objs[0]->domain.i->lastkl;
  for (i=1; i<n; i++) {
    idom = objs[i]->domain.i;
    if (line1 < idom->line1)
    {
      line1 = idom->line1;
    }
    if (lastln > idom->lastln)
    {
      lastln = idom->lastln;
    }
    if (kol1 < idom->kol1)
    {
      kol1 = idom->kol1;
    }
    if (lastkl > idom->lastkl)
    {
      lastkl = idom->lastkl;
    }
  }
  if( lastkl < kol1 || lastln < line1 ){
    return WlzMakeEmpty(dstErr);
  }

  /*
   * Count the individual intervals so that sufficient space
   * for the intersection may be allocated.
   */
  inttot=0;
  for (i=0; (i < n) && (errNum == WLZ_ERR_NONE); i++) {
    inttot += WlzIntervalCount(objs[i]->domain.i, &errNum);
  }
  if(errNum != WLZ_ERR_NONE) {
    if(dstErr) {
      *dstErr = errNum;
    }
    return NULL;
  }

  /*
   * Set up domain, value table structures, and object.
   */

  if( (idom = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_INTVL,
				    line1, lastln, 0, lastkl-kol1,
				    &errNum)) == NULL ){
    if(dstErr) {
      *dstErr = errNum;
    }
    return NULL;
  }
  if( (itvl = (WlzInterval *)
       AlcMalloc (inttot * sizeof(WlzInterval))) == NULL ){
    WlzFreeIntervalDomain(idom);
    errNum = WLZ_ERR_MEM_ALLOC;
    if(dstErr) {
      *dstErr = errNum;
    }
    return NULL;
  }

  idom->freeptr = AlcFreeStackPush(idom->freeptr, (void *)itvl, NULL);
  lwas = line1;
  jtvl = itvl;
  nints = 0;
  domain.i = idom;
  values.v = NULL;
  if( (obj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
			 domain, values, NULL, NULL, &errNum)) == NULL ){
    WlzFreeIntervalDomain(idom);
    if(dstErr) {
      *dstErr = errNum;
    }
    return NULL;
  }

  /*
   * allocate space for workspaces
   */
  if( (iwsp = (WlzIntervalWSpace *)
       AlcMalloc(n * sizeof(WlzIntervalWSpace))) == NULL ){
    WlzFreeObj( obj );
    errNum = WLZ_ERR_MEM_ALLOC;
    if(dstErr) {
      *dstErr = errNum;
    }
    return NULL;
  }
  biwsp = iwsp;
  tiwsp = biwsp + n;

  /*
   * Construct the intersection object's table of intervals.
   * Initialise scanning on each object/workspace combination.
   * Scan synchronously, setting up the intersection of
   * overlapping intervals.  Needs a clear head !!
   */
  for (i=0; (i < n) && (errNum == WLZ_ERR_NONE); i++) {
    errNum = WlzInitRasterScan(objs[i],iwsp,WLZ_RASTERDIR_ILIC);
    if(errNum == WLZ_ERR_NONE) {
      errNum = WlzNextInterval(iwsp++);
    }
  }
  if(errNum != WLZ_ERR_NONE) {
    WlzFreeObj( obj );
    if(dstErr) {
      *dstErr = errNum;
    }
    return NULL;
  }

  l = lwas;
  for (;;) {
    /*
     * find next line of intersection
     */
    do {
      change = 0;
      for (iwsp=biwsp; iwsp<tiwsp; iwsp++) {
	if (iwsp->linpos > l) {
	  l = iwsp->linpos;
        }
      }
      for (iwsp=biwsp; iwsp<tiwsp; iwsp++) {
	while (iwsp->linpos < l) {
	  if ((errNum = WlzNextInterval(iwsp)) != WLZ_ERR_NONE) {
	    if(errNum == WLZ_ERR_EOO)
	    {
	      errNum = WLZ_ERR_NONE;
	    }
	    goto firstfinished;
	  }
	  if (iwsp->linpos > l) {
	    change = 1;
	  }
	}
      }
    } while (change != 0);
    /*
     * find next interval of intersection
     */
    kol1 = biwsp->lftpos;
    lastkl = biwsp->rgtpos;
    while(errNum == WLZ_ERR_NONE) {
      do {
	change = 0;
	for (iwsp=biwsp; iwsp<tiwsp; iwsp++)
	  if (iwsp->lftpos > lastkl) {
	    kol1 = iwsp->lftpos;
	    lastkl = iwsp->rgtpos;
	  } else if (iwsp->lftpos > kol1)
	    kol1 = iwsp->lftpos;
	for (iwsp=biwsp; iwsp<tiwsp; iwsp++) {
	  while (iwsp->rgtpos < kol1) {
	    if ((errNum = WlzNextInterval(iwsp)) != WLZ_ERR_NONE) {
	      if(errNum == WLZ_ERR_EOO)
	      {
	        errNum = WLZ_ERR_NONE;
	      }
	      goto firstfinished;
	    }
	    if (iwsp->linpos != l) {
	      l = iwsp->linpos;
	      goto jumpline;
	    }
	    if (iwsp->lftpos > kol1)
	      change = 1;
	  }
	}
      } while ((change != 0) && (errNum == WLZ_ERR_NONE));
      if(errNum == WLZ_ERR_NONE)
      {
	for (iwsp=biwsp; iwsp < tiwsp; iwsp++) {
	  if (iwsp->rgtpos <= lastkl) {
	    lastkl = iwsp->rgtpos;
	  }
	}
	if (lastkl >= kol1) {
	  itvl->ileft = kol1 - idom->kol1;
	  itvl->iright = lastkl - idom->kol1;
	  if (l == lwas) {
	    nints++;
	  } else {
	    errNum = WlzMakeInterval(lwas,idom,nints,jtvl);
	    for (j = lwas+1; (j < l) && (errNum == WLZ_ERR_NONE); j++) {
	      errNum = WlzMakeInterval(j,idom,0,NULL);
	    }
	    if(errNum == WLZ_ERR_NONE) {
	      lwas = l;
	      nints = 1;
	      jtvl = itvl;
	    }
	  }
	  itvl++;
	}
	kol1 = lastkl+1;
      }
    }

  jumpline:
    ;
  }

firstfinished:
  if(errNum != WLZ_ERR_NONE) {
    WlzFreeObj(obj);
    if(dstErr) {
      *dstErr = errNum;
    }
    return NULL;
  }

  errNum = WlzMakeInterval(lwas,idom,nints,jtvl);
  for (j = lwas+1; (j <= lastln) && (errNum == WLZ_ERR_NONE); j++) {
    errNum = WlzMakeInterval(j,idom,0,NULL);
  }
  if(errNum != WLZ_ERR_NONE)
  {
    WlzFreeObj(obj);
    AlcFree((void *) biwsp);
    if(dstErr)
    {
      *dstErr = errNum;
    }
    return NULL;
  }

  /*
   * standardise the interval list (remove leading and trailing
   * empty lines, set kol1 so that at least one interval commences
   * at zero, set lastkl correctly)
   */
  (void )WlzStandardIntervalDomain(idom);

  /* check for error or empty */
  nints = WlzIntervalCount(idom, &errNum);
  if( nints < 0 ){
    /* error */
    WlzFreeObj(obj);
    AlcFree((void *) biwsp);
    if(dstErr)
    {
      *dstErr = errNum;
    }
    return NULL;
  }
  else if( nints == 0 ){
    /* empty object */
    WlzFreeObj(obj);
    AlcFree((void *) biwsp);
    return WlzMakeEmpty(dstErr);
  }

  if (uvt != 0) {
    WlzGreyType	grey_type;
    if( (gwsp = (WlzGreyWSpace *)
	 AlcMalloc (n * sizeof (WlzGreyWSpace))) == NULL ){
      WlzFreeObj(obj);
      AlcFree((void *) biwsp);
      errNum = WLZ_ERR_MEM_ALLOC;
      if(dstErr)
      {
        *dstErr = errNum;
      }
      return NULL;
    }

    /* construct an empty "ragged-rectangle" (type 1  or 2) greytable
       choosing the grey-value type from the first object in the list */
    backg = WlzGetBackground(objs[0], &errNum);
    if(errNum == WLZ_ERR_NONE) {
      grey_type = WlzGreyTableTypeToGreyType(objs[0]->values.core->type,
      					     &errNum);
    }
    if(errNum == WLZ_ERR_NONE) {
      type = WlzGreyTableType(WLZ_GREY_TAB_RAGR, grey_type, &errNum);
    }
    if((errNum != WLZ_ERR_NONE) ||
       (values.v = WlzNewValueTb(obj, type, backg, &errNum)) == NULL ){
      WlzFreeObj( obj );
      AlcFree((void *) gwsp);
      AlcFree((void *) biwsp);
      if(dstErr)
      {
        *dstErr = errNum;
      }
      return NULL;
    }
    obj->values = WlzAssignValues(values, &errNum);
    if(errNum != WLZ_ERR_NONE) {
      WlzFreeObj( obj );
      AlcFree((void *) gwsp);
      AlcFree((void *) biwsp);
      if(dstErr)
      { 
	*dstErr = errNum;
      }
      return NULL;
    }
	
    /*
     * fill the grey table with mean of grey values.
     */
    /* initialise the work-spaces and check pixel type */
    errNum = WlzInitGreyScan(obj, &niwsp, &ngwsp);
    iwsp = biwsp;
    for (i=0; (i < n) && (errNum == WLZ_ERR_NONE); i++) {
      errNum = WlzInitGreyScan(objs[i], iwsp, &gwsp[i]);
      if(errNum == WLZ_ERR_NONE) {
	errNum = WlzNextGreyInterval(iwsp++);
      }
      if( gwsp[i].pixeltype != grey_type ){
        errNum = WLZ_ERR_GREY_TYPE;
      }
    }
    if(errNum != WLZ_ERR_NONE) {
      WlzFreeObj( obj );
      AlcFree((void *) gwsp);
      AlcFree((void *) biwsp);
      if(dstErr) {
        *dstErr = errNum;
      }
      return NULL;
    }

    while (WlzNextGreyInterval(&niwsp) == WLZ_ERR_NONE) {
      l = niwsp.linpos;
      greyptr = ngwsp.u_grintptr;
      switch( ngwsp.pixeltype ){

      case WLZ_GREY_INT:
	for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	  gv.inv = 0;
	  for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	    while(iwsp->linrmn >= 0 &&
		  (iwsp->linpos < l ||
		   (iwsp->linpos == l && iwsp->rgtpos < k))){
	      (void )WlzNextGreyInterval(iwsp);
	    }
	    gv.inv += *(gwsp[i].u_grintptr.inp + k - iwsp->lftpos);
	  }
	  *greyptr.inp = gv.inv / n;
	  greyptr.inp++;
	}
	break;

      case WLZ_GREY_SHORT:
	for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	  gv.shv = 0;
	  for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	    while(iwsp->linrmn >= 0 &&
		  (iwsp->linpos < l ||
		   (iwsp->linpos == l && iwsp->rgtpos < k))){
	      (void )WlzNextGreyInterval(iwsp);
	    }
	    gv.shv += *(gwsp[i].u_grintptr.shp + k - iwsp->lftpos);
	  }
	  *greyptr.shp = (short )(gv.shv / n);
	  greyptr.shp++;
	}
	break;

      case WLZ_GREY_UBYTE:
	for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	  gv.ubv = 0;
	  for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	    while(iwsp->linrmn >= 0 &&
		  (iwsp->linpos < l ||
		   (iwsp->linpos == l && iwsp->rgtpos < k))){
	      (void )WlzNextGreyInterval(iwsp);
	    }
	    gv.ubv += *(gwsp[i].u_grintptr.ubp + k - iwsp->lftpos);
	  }
	  *greyptr.ubp = (WlzUByte )(gv.ubv / n);
	  greyptr.ubp++;
	}
	break;

      case WLZ_GREY_FLOAT:
	for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	  gv.flv = 0;
	  for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	    while(iwsp->linrmn >= 0 &&
		  (iwsp->linpos < l ||
		   (iwsp->linpos == l && iwsp->rgtpos < k))){
	      (void )WlzNextGreyInterval(iwsp);
	    }
	    gv.flv += *(gwsp[i].u_grintptr.flp + k - iwsp->lftpos);
	  }
	  *greyptr.flp = gv.flv / n;
	  greyptr.flp++;
	}
	break;

      case WLZ_GREY_DOUBLE:
	for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	  gv.dbv = 0;
	  for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	    while(iwsp->linrmn >= 0 &&
		  (iwsp->linpos < l ||
		   (iwsp->linpos == l && iwsp->rgtpos < k))){
	      (void )WlzNextGreyInterval(iwsp);
	    }
	    gv.dbv += *(gwsp[i].u_grintptr.dbp + k - iwsp->lftpos);
	  }
	  *greyptr.dbp = gv.dbv / n;
	  greyptr.dbp++;
	}
	break;

      case WLZ_GREY_RGBA: /* RGBA to be done again RAB */
	for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	  gv.rgbv = 0;
	  for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	    while(iwsp->linrmn >= 0 &&
		  (iwsp->linpos < l ||
		   (iwsp->linpos == l && iwsp->rgtpos < k))){
	      (void )WlzNextGreyInterval(iwsp);
	    }
	    gv.rgbv += *(gwsp[i].u_grintptr.rgbp + k - iwsp->lftpos);
	  }
	  *greyptr.rgbp = gv.rgbv / n;
	  greyptr.rgbp++;
	}
	break;

      default:
	errNum = WLZ_ERR_GREY_TYPE;
	break;

      }
    }
    if(errNum == WLZ_ERR_EOO)
    {
      errNum = WLZ_ERR_NONE;
    }
    AlcFree((void *) gwsp);
  }
  AlcFree((void *) biwsp);

  if(dstErr) {
    *dstErr = errNum;
  }
  return obj;
}
Beispiel #14
0
int             main(int argc, char **argv)
{
  int		option,
		ok = 1,
		sep = 0,
		usage = 0,
		verbose = 0;
  double	padVal = 0.0;
  WlzDVertex3	param[] = {{1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}};
  WlzIVertex3	order = {0, 0, 0};
  AlgPadType	pad = ALG_PAD_NONE;
  WlzGreyType	gType = WLZ_GREY_ERROR;
  WlzIVertex3	action = {1, 1, 1};
  WlzObject	*inObj = NULL,
  		*outObj = NULL;
  struct timeval times[3];
  const char    *errMsgStr;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  char 		*outFileStr,
  		*inObjFileStr;
  static char	optList[] = "Ghvg:o:m:n:P:p:t:S:",
		defFile[] = "-";

  opterr = 0;
  outFileStr = defFile;
  inObjFileStr = defFile;
  while(ok && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'o':
        outFileStr = optarg;
	break;
      case 'h':
        usage = 1;
	break;
      case 'v':
        verbose = 1;
	break;
      case 'g':
        switch(*optarg)
	{
	  case 'i':
	    gType = WLZ_GREY_INT;
	    break;
	  case 's':
	    gType = WLZ_GREY_SHORT;
	    break;
	  case 'u':
	    gType = WLZ_GREY_UBYTE;
	    break;
	  case 'f':
	    gType = WLZ_GREY_FLOAT;
	    break;
	  case 'd':
	    gType = WLZ_GREY_DOUBLE;
	    break;
	  default:
	    usage = 1;
	    break;
	}
	break;
      case 'm':
	if((optarg == NULL) ||
	   (sscanf(optarg, "%lg,%lg,%lg",
	           &(param[0].vtX), &(param[0].vtY), &(param[0].vtZ)) < 1))
	{
	  usage = 1;
	}
        break;
      case 'n':
	if((optarg == NULL) ||
	   (sscanf(optarg, "%d,%d,%d",
	           &(order.vtX), &(order.vtY), &(order.vtZ)) < 1))
	{
	  usage = 1;
	}
        break;
      case 'P':
        switch(*optarg)
	{
	  case 'b':
	    pad = ALG_PAD_NONE;
	    break;
	  case 'e':
	    pad = ALG_PAD_END;
	    break;
	  case 'v':
	    pad = ALG_PAD_VALUE;
	    break;
	  case 'z':
	    pad = ALG_PAD_ZERO;
	    break;
	  default:
	    usage = 1;
	    break;
	}
	break;
      case 'p':
        if((optarg == NULL) || (sscanf(optarg, "%lg", &padVal) != 1))
	{
	  usage = 1;
	}
	break;
      case 'G':
	/* Only have Gaussian implemented. */
        break;
      case 't':
	if(optarg)
	{
	  char	*actStr;

	  action.vtX = 0;
	  action.vtY = 0;
	  action.vtZ = 0;
	  actStr = strtok(optarg, ",");
	  while(actStr && ok)
	  {
	    if(strcmp(actStr, "x") == 0)
	    {
	      action.vtX = 1;
	    }
	    else if(strcmp(actStr, "y") == 0)
	    {
	      action.vtY = 1;
	    }
	    else if(strcmp(actStr, "z") == 0)
	    {
	      action.vtZ = 1;
	    }
	    else
	    {
	      usage = 1;
	    }
	    actStr = strtok(NULL, ",");
	  }
	}
	break;
      case 'S':
	if(!optarg || (strlen(optarg) > 1))
	{
	  usage = 1;
	}
	else
	{
	  switch(*optarg)
	  {
	    case 'c':
	      sep = 1;
	      break;
	    case 'a':
	      sep = 2;
	      break;
	    case 's':
	      sep = 3;
	      break;
	    default:
	      usage = 1;
	      break;
	  }
	}
        break;
      default:
        usage = 1;
	break;
    }
  }
  if(!usage)
  {
    if(optind < argc)
    {
      if((optind + 1) != argc)
      {
	usage = 1;
      }
      else
      {
	inObjFileStr = *(argv + optind);
      }
    }
  }
  ok = !usage;
  if(ok)
  {
    FILE	*fP = NULL;

    if(verbose)
    {
      (void )fprintf(stderr,
                     "%s: Reading object from %s\n",
		     *argv, strcmp(inObjFileStr, "-")? inObjFileStr: "stdin");
    }
    if(((fP = (strcmp(inObjFileStr, "-")?
	      fopen(inObjFileStr, "r"): stdin)) == NULL) ||
       ((inObj= WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL) ||
       (errNum != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )fprintf(stderr,
		     "%s: Failed to read object from file %s\n",
		     *argv, inObjFileStr);
    }
    if(fP && strcmp(inObjFileStr, "-"))
    {
      fclose(fP);
    }
  }
  if(ok && (pad == ALG_PAD_NONE))
  {
    WlzPixelV	bgd;

    bgd = WlzGetBackground(inObj, &errNum);
    if(errNum == WLZ_ERR_NONE)
    {
      WlzValueConvertPixel(&bgd, bgd, WLZ_GREY_DOUBLE);
      padVal = bgd.v.dbv;
      pad = ALG_PAD_VALUE;
    }
    else
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
                     "%s: Failed to get object background value (%s).\n",
		     *argv, errMsgStr);
    }
  }
  if(ok)
  {
    if(verbose)
    {
      (void )fprintf(stderr,
                     "%s: Filtering object with:\n"
		     "  param[0] = (%g, %g, %g)\n"
		     "  param[1] = (%g, %g, %g)\n"
		     "  order    = (%d, %d, %d)\n"
		     "  action   = (%d, %d, %d)\n"
		     "  gType    = %d\n"
		     "  pad      = %d\n"
		     "  padVal   = %lg\n"
		     "  sep      = %d\n",
		     *argv,
		     param[0].vtX, param[0].vtY, param[0].vtZ,
		     param[1].vtX, param[1].vtY, param[1].vtZ,
		     order.vtX, order.vtY, order.vtZ,
		     action.vtX, action.vtY, action.vtZ,
		     gType, pad, padVal, sep);
      gettimeofday(times + 0, NULL);
    }
    outObj = WlzAssignObject(
	     WlzGaussFilter(inObj, param[0], order, action, gType,
	     		    pad, padVal, sep, &errNum),
	     NULL);
    if(verbose)
    {
      gettimeofday(times + 1, NULL);
      ALC_TIMERSUB(times + 1, times + 0, times + 2);
      (void )fprintf(stderr,
                     "%s: Elapsed time for WlzGaussFilter() %gus\n",
		     argv[0], (1.0e06 * times[2].tv_sec) + times[2].tv_usec);
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
                     "%s: Failed to filter object (%s).\n",
		     *argv, errMsgStr);
    }
  }
  if(ok)
  {
    FILE	*fP = NULL;

    if(verbose)
    {
      (void )fprintf(stderr,
                     "%s: Writing object to %s\n",
		     *argv, strcmp(outFileStr, "-")? outFileStr: "stdout");
    }
    errNum = WLZ_ERR_FILE_OPEN;
    if(((fP = (strcmp(outFileStr, "-")?
	      fopen(outFileStr, "w"): stdout)) == NULL) ||
       ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsgStr);
      (void )fprintf(stderr,
		     "%s: Failed to write output object (%s).\n",
		     *argv,
		     errMsgStr);
    }
    if(fP && strcmp(outFileStr, "-"))
    {
      fclose(fP);
    }
  }
  (void )WlzFreeObj(inObj);
  (void )WlzFreeObj(outObj);
  if(usage)
  {
    (void )fprintf(stderr,
    "Usage: %s%s%s%sExample: %s%s",
    *argv,
    " [-h] [-o<output object>] [-m#,#,#] [-n#,#,#]\n"
    "\t[-g <t>] [-t <flags>] [-P <p>] [-p#] [-G]\n"
    "\t[-S a|c|s] [-v] [<input object>]\n"
    "Version: ",
    WlzVersion(),
    "\n"
    "Options:\n"
    "  -h  Prints this usage information\n"
    "  -o  Output object file name.\n"
    "  -m  Filter parameters; for a Gaussian these are the sigma values\n"
    "      for each orthogonal direction (x, y and z). Default values are\n"
    "      1,1,1.\n"
    "  -n  Order parameters; for a Gaussian these are the order of the\n"
    "      Gaussian's derivatives (eg 0 for no derivative, 1 for 1st\n"
    "      derivative), default 0,0,0.\n"
    "  -g  Required grey type, default is the same as the input object's,\n"
    "      with 'i', 's', 'u', 'f' and 'd' used to request int, short,\n"
    "      unsigned byte, float or double grey values.\n"
    "  -P  Type of padding to use, default is to use the background value,\n"
    "      with 'b', 'e', 'v' and 'z' used to select background, end, given\n"
    "      value and zero padding.\n"
    "  -p  Used to supply given padding value, default 0.0.\n"
    "  -G  Use a Gaussain filter (default).\n"
    "  -S  Use the input object for each of the directional filters rather\n"
    "      than the output of the previous directional filter. The seperate\n"
    "      filter outputs are then combined to form a compound object (c),\n"
    "      the sum (a) or the square root of the sum of the squared values\n"
    "      of the filter passes (s).\n"
    "  -t  Filter directions, eg x filter along lines and x, y filter\n"
    "      along lines then through columns.\n"
    "  -v  Verbose output with parameter values and execution time.\n"
    "Applies a seperable filter to a Woolz domain object with grey values.\n"
    "The input object is read from stdin and the filtered object is\n"
    "written to stdout unless the filenames are given.\n",
    *argv,
    " -m ,3.0,2.0 -t x,y,z -o smooth.wlz in.wlz\n"
    "The input Woolz object is read from in.wlz, and filtered using a\n"
    "Gaussian filter with sigma values of 1.0, 3.0 and 2.0 in the x, y\n"
    "and z directions. The filtered object is then written to the file\n"
    "smoothed.wlz.\n");
  }
  return(!ok);
}
Beispiel #15
0
/*! 
* \ingroup      WlzValuesFilters
* \brief        Perform 2D seperable transform on a 2D grey-level image.
* 		It is the users responsibility to ensure that the grey-value
* 		types are appropriate.
* 		Now extended to include compound objects.
*
* \return       Pointer to transformed object
* \param    obj	Input object pointer
* \param    x_fun	Convolution function to be applied in the x-direction (along the rows).
* \param    x_params	Parameter pointer to be passed to the x-function.
* \param    y_fun	Convolution function to be applied in the y-direction (down the columns).
* \param    y_params	Parameter pointer to be passed to the y-function.
* \param    dstErr	error return.
* \par      Source:
*                WlzSepTrans.c
*/
WlzObject *WlzSepTrans(
  WlzObject		*obj,
  WlzIntervalConvFunc	x_fun,
  void			*x_params,
  WlzIntervalConvFunc	y_fun,
  void			*y_params,
  WlzErrorNum		*dstErr)
{
  WlzIntervalWSpace	iwspace;
  WlzGreyWSpace		gwspace;
  WlzSepTransWSpace	stwspc;
  WlzValues		values;
  WlzObject		*obj1, *obj2;
  int			i, width, height;
  WlzCompoundArray	*cobj1, *cobj2;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  /* check object pointers and type */
  obj2 = NULL;
  stwspc.outbuf.p.dbp = NULL;
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    switch( obj->type ){

    case WLZ_2D_DOMAINOBJ:
      /* check domain and valuetable */
      if( obj->domain.core == NULL ){
	errNum = WLZ_ERR_DOMAIN_NULL;
	break;
      }
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
	break;
      }
      if(WlzGreyTableIsTiled(obj->values.core->type)){
	errNum = WLZ_ERR_VALUES_TYPE;
	break;
      }
      break;

    default:
    case WLZ_3D_DOMAINOBJ:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;

    case WLZ_TRANS_OBJ:
      if((obj1 = WlzSepTrans(obj->values.obj,
			     x_fun, x_params, y_fun, y_params,
			     &errNum)) != NULL){
	values.obj = obj1;
	return WlzMakeMain(obj->type, obj->domain, values,
			   NULL, obj, dstErr);
      }
      break;

    case WLZ_COMPOUND_ARR_1:
    case WLZ_COMPOUND_ARR_2:
      cobj1 = (WlzCompoundArray *) obj;
      if((cobj2 = WlzMakeCompoundArray(cobj1->type, 1, cobj1->n, NULL,
				       cobj1->otype, &errNum)) != NULL){
	/* transform each object, ignore type errors */
	for(i=0; i < cobj1->n; i++){
	  cobj2->o[i] =
	    WlzAssignObject(WlzSepTrans(cobj1->o[i],
					x_fun, x_params, y_fun, y_params,
					&errNum), NULL);
	}
	return (WlzObject *) cobj2;
      }
      break;

    case WLZ_EMPTY_OBJ:
      return WlzMakeEmpty(dstErr);
    }
  }

  /* make space for a calculation buffer - assume worst case of doubles */
  if( errNum == WLZ_ERR_NONE ){
    width  = obj->domain.i->lastkl - obj->domain.i->kol1 + 1;
    height = obj->domain.i->lastln - obj->domain.i->line1 + 1;
    stwspc.inbuf.type = WlzGreyTableTypeToGreyType(obj->values.core->type,
						   NULL);
    stwspc.bckgrnd = WlzGetBackground(obj, NULL);

    switch( stwspc.inbuf.type ){
    case WLZ_GREY_INT:
    case WLZ_GREY_SHORT:
    case WLZ_GREY_UBYTE:
      stwspc.outbuf.type = WLZ_GREY_INT;
      break;
    default:
      stwspc.outbuf.type = stwspc.inbuf.type;
      break;
    }

    if( (stwspc.outbuf.p.dbp = (double *) 
	 AlcMalloc(sizeof(double)*(width>height?width:height))) == NULL){
      errNum = WLZ_ERR_MEM_ALLOC;
    }
  }

  /* tranpose the object - interchange x & y coordinates */
  if( errNum == WLZ_ERR_NONE ){
    obj1 = WlzTransposeObj(obj, &errNum);
  }

  /* perform the y convolution */
  if((errNum == WLZ_ERR_NONE) &&
     ((errNum = WlzInitGreyScan(obj1, &iwspace, &gwspace)) == WLZ_ERR_NONE))
  {
    while( (errNum = WlzNextGreyInterval(&iwspace)) == WLZ_ERR_NONE ){
      stwspc.inbuf.p.inp = gwspace.u_grintptr.inp;
      stwspc.len = iwspace.rgtpos - iwspace.lftpos + 1;
      if((errNum = (*y_fun)(&stwspc, y_params)) == WLZ_ERR_NONE){
	switch(  stwspc.inbuf.type ){
	case WLZ_GREY_INT:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.inp++)
	    *stwspc.inbuf.p.inp = stwspc.outbuf.p.inp[i];
	  break;
	case WLZ_GREY_SHORT:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.shp++)
	    *stwspc.inbuf.p.shp = (short )(stwspc.outbuf.p.inp[i]);
	  break;
	case WLZ_GREY_UBYTE:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.ubp++)
	    *stwspc.inbuf.p.ubp = (WlzUByte )(stwspc.outbuf.p.inp[i]);
	  break;
	case WLZ_GREY_FLOAT:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.flp++)
	    *stwspc.inbuf.p.flp = stwspc.outbuf.p.flp[i];
	  break;
	case WLZ_GREY_DOUBLE:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.dbp++)
	    *stwspc.inbuf.p.dbp = stwspc.outbuf.p.dbp[i];
	  break;
	case WLZ_GREY_RGBA:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.rgbp++)
	    *stwspc.inbuf.p.rgbp = stwspc.outbuf.p.rgbp[i];
	  break;
	default:
	  errNum = WLZ_ERR_GREY_TYPE;
	  break;
	}
      }
      else {
	break; /* break from the while loop */
      }
    }
    if( errNum == WLZ_ERR_EOO ){
      errNum = WLZ_ERR_NONE;
    }
  }

  /* rotate back and free temporary object */
  if( errNum == WLZ_ERR_NONE ){
    obj2 = WlzTransposeObj(obj1, &errNum);
    WlzFreeObj(obj1);
  }

  /* perform x convolution */
  if((errNum == WLZ_ERR_NONE) &&
     ((errNum = WlzInitGreyScan(obj2, &iwspace, &gwspace)) == WLZ_ERR_NONE))
  {
    while((errNum = WlzNextGreyInterval(&iwspace)) == WLZ_ERR_NONE){
      stwspc.inbuf.p.inp = gwspace.u_grintptr.inp;
      stwspc.len = iwspace.rgtpos - iwspace.lftpos + 1;
      if( (errNum = (*x_fun)(&stwspc, x_params)) == WLZ_ERR_NONE ){
	switch(  gwspace.pixeltype ){
	case WLZ_GREY_INT:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.inp++)
	    *stwspc.inbuf.p.inp = stwspc.outbuf.p.inp[i];
	  break;
	case WLZ_GREY_SHORT:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.shp++)
	    *stwspc.inbuf.p.shp = (short )(stwspc.outbuf.p.inp[i]);
	  break;
	case WLZ_GREY_UBYTE:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.ubp++)
	    *stwspc.inbuf.p.ubp = (WlzUByte )(stwspc.outbuf.p.inp[i]);
	  break;
	case WLZ_GREY_FLOAT:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.flp++)
	    *stwspc.inbuf.p.flp = stwspc.outbuf.p.flp[i];
	  break;
	case WLZ_GREY_DOUBLE:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.dbp++)
	    *stwspc.inbuf.p.dbp = stwspc.outbuf.p.dbp[i];
	  break;
	case WLZ_GREY_RGBA:
	  for(i=0; i < stwspc.len; i++, stwspc.inbuf.p.rgbp++)
	    *stwspc.inbuf.p.rgbp = stwspc.outbuf.p.rgbp[i];
	  break;
	default:
	  errNum = WLZ_ERR_GREY_TYPE;
	  break;
	}
      }
      else {
	break; /* break from the while loop */
      }
    }
  }
  if( errNum == WLZ_ERR_EOO ){
    errNum = WLZ_ERR_NONE;
  }

  /* free the buffer and return transformed object */
  if( stwspc.outbuf.p.dbp ){
    AlcFree((void *) stwspc.outbuf.p.dbp);
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return obj2;
}
Beispiel #16
0
/*!
* \return	New 2D domain object.
* \ingroup	WlzArithmetic
* \brief	Computes a new 2D object which shares the domain of the given
*		object, but which has grey values that are the result of
*		applying the given function to the grey values of the
*		given object.
* \param	sObj			Given source domain object with values.
* \param	fn			Scalar function to be applied.
* \param	dstErr			Destination error pointer, may be NULL.
*/
static WlzObject *WlzScalarFn2D(WlzObject *sObj, WlzFnType fn,
			        WlzErrorNum *dstErr)
{
  WlzGreyType	sGType,
  		dGType;
  WlzPixelV	sBgd,
  		dBgd;
  WlzObjectType	dVType;
  WlzObject     *dObj = NULL;
  WlzValues	dVal;
  WlzIntervalWSpace sIWSp,
  		dIWSp;
  WlzGreyWSpace	sGWSp,
  		dGWSp;
  WlzErrorNum   errNum = WLZ_ERR_NONE;

  sGType = WlzGreyTypeFromObj(sObj, &errNum);
  if(errNum == WLZ_ERR_NONE)
  {
    dGType = WlzScalarFnPromoteGType(fn, sGType, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dVType = WlzGreyTableType(WLZ_GREY_TAB_RAGR, dGType, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    sBgd = WlzGetBackground(sObj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dBgd = WlzScalarFnPixel(sBgd, fn, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dVal.v = WlzNewValueTb(sObj, dVType, dBgd, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
    		       sObj->domain, dVal, NULL, NULL, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzInitGreyScan(sObj, &sIWSp, &sGWSp);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzInitGreyScan(dObj, &dIWSp, &dGWSp);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    while((errNum == WLZ_ERR_NONE) &&
          ((errNum = WlzNextGreyInterval(&sIWSp)) == WLZ_ERR_NONE) &&
          ((errNum = WlzNextGreyInterval(&dIWSp)) == WLZ_ERR_NONE))
    {
      int	len;
      WlzGreyP	dGP,
      		sGP;

      len = sIWSp.rgtpos - sIWSp.lftpos + 1;
      dGP = dGWSp.u_grintptr;
      sGP = sGWSp.u_grintptr;
      WlzValueCopyGreyToGrey(dGP, 0, dGType, sGP, 0, sGType, len);
      WlzScalarFnItv(dGP, dGType, len, fn);
    }
    if(errNum == WLZ_ERR_EOO)
    {
      errNum = WLZ_ERR_NONE;
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dObj);
}
Beispiel #17
0
/*!
* \return	New Woolz object.
* \ingroup	WlzAllocation
* \brief	Creates a new or adds to an existing 3D spatial domain
*  		object using a rectangular buffer of values to a single
*  		plane of the given current object (which may be NULL or
*  		empty if the object is to be created).
* 		The returned object will share domains and values of
* 		planes other than the given plane with the current object.
* \param	cObj			Given current object.
* \param	og			Origin of rectangular buffer.
* \param	sz			Buffer size (note 2D).
* \param	gType			Grey type which must be consistent
* 					with the current object (if it is
* 					valid) and the buffer of values.
* \param	bufSz			Number of values in the buffer
* 					(ie sz.vtX * sz.vtY).
* \param	bufP			Given buffer of values.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject	*WlzBuildObj3(WlzObject *cObj,
                          WlzIVertex3 og, WlzIVertex2 sz,
                          WlzGreyType gType,
                          int bufSz, WlzGreyP bufP,
                          WlzErrorNum *dstErr)
{
    int		nPlnReq = 1;
    WlzDomain	cDom,
                nDom;
    WlzValues	cVal,
                nVal;
    WlzObject	*nObj = NULL;
    WlzErrorNum	errNum = WLZ_ERR_NONE;

    cDom.core = NULL;
    nDom.core = NULL;
    cVal.core = NULL;
    nVal.core = NULL;
    if(cObj)
    {
        WlzGreyType cGType = WLZ_GREY_ERROR;;

        switch(cObj->type)
        {
        case WLZ_EMPTY_OBJ:
            cObj = NULL;
            break;
        case WLZ_3D_DOMAINOBJ:
            if(cObj->domain.core == NULL)
            {
                errNum = WLZ_ERR_DOMAIN_NULL;
            }
            else if(cObj->values.core == NULL)
            {
                errNum = WLZ_ERR_VALUES_NULL;
            }
            else
            {
                cDom = cObj->domain;
                cVal = cObj->values;
                cGType = WlzGreyTypeFromObj(cObj, &errNum);
            }
            if((errNum == WLZ_ERR_NONE) && (cGType != gType))
            {
                errNum = WLZ_ERR_GREY_TYPE;
            }
            break;
        default:
            errNum = WLZ_ERR_OBJECT_TYPE;
            break;
        }
    }
    /* Create a new object with new plane domain and voxel values. */
    if(errNum == WLZ_ERR_NONE)
    {
        WlzIBox3	nBox;
        WlzPixelV	bgdV;
        float	vxSz[3];

        nBox.xMin = og.vtX;
        nBox.yMin = og.vtY;
        nBox.zMin = og.vtZ;
        nBox.xMax = og.vtX + sz.vtX - 1;
        nBox.yMax = og.vtY + sz.vtY - 1;
        nBox.zMax = og.vtZ;
        if(cObj)
        {
            nPlnReq = (og.vtZ < cDom.p->plane1) ||
                      (og.vtZ > cDom.p->lastpl) ||
                      ((*(cDom.p->domains + og.vtZ - cDom.p->plane1)).core == NULL);
            nBox.xMin = ALG_MIN(nBox.xMin, cDom.p->kol1);
            nBox.yMin = ALG_MIN(nBox.yMin, cDom.p->line1);
            nBox.zMin = ALG_MIN(nBox.zMin, cDom.p->plane1);
            nBox.xMax = ALG_MAX(nBox.xMax, cDom.p->lastkl);
            nBox.yMax = ALG_MAX(nBox.yMax, cDom.p->lastln);
            nBox.zMax = ALG_MAX(nBox.zMax, cDom.p->lastpl);
            vxSz[0] = cDom.p->voxel_size[0];
            vxSz[1] = cDom.p->voxel_size[1];
            vxSz[2] = cDom.p->voxel_size[2];
            bgdV = WlzGetBackground(cObj, &errNum);
        }
        else
        {
            vxSz[0] = vxSz[1] = vxSz[2] = 1.0f;
            bgdV.type = WLZ_GREY_INT;
            bgdV.v.inv = 0;
        }
        if(errNum == WLZ_ERR_NONE)
        {
            nDom.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
                                        nBox.zMin, nBox.zMax,
                                        nBox.yMin, nBox.yMax,
                                        nBox.xMin, nBox.xMax,
                                        &errNum);
        }
        if(errNum == WLZ_ERR_NONE)
        {
            nVal.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
                                           nBox.zMin, nBox.zMax,
                                           bgdV, NULL, &errNum);
        }
        if(errNum == WLZ_ERR_NONE)
        {
            nDom.p->voxel_size[0] = vxSz[0];
            nDom.p->voxel_size[1] = vxSz[1];
            nDom.p->voxel_size[2] = vxSz[2];
            nObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, nDom, nVal, NULL, NULL, &errNum);
        }
    }
    /* Set the domain and values on each plane for the new object. */
    if(errNum == WLZ_ERR_NONE)
    {
        int		idZ;

        for(idZ = nDom.p->plane1; idZ <= nDom.p->lastpl; ++idZ)
        {
            int	idP;
            WlzDomain	nDom2;
            WlzValues nVal2;

            nDom2.core = NULL;
            nVal2.core = NULL;
            idP = idZ - nDom.p->plane1;
            if(idZ == og.vtZ)
            {
                /* Plane with buffer. */
                WlzIVertex2 og2,
                            sz2;
                WlzObject   *cObj2 = NULL,
                             *nObj2 = NULL;

                og2.vtX = og.vtX;
                og2.vtY = og.vtY;
                sz2.vtX = sz.vtX;
                sz2.vtY = sz.vtY;
                if(nPlnReq == 0)
                {
                    int	idP;

                    idP = idZ - cDom.p->plane1;
                    cObj2 = WlzMakeMain(WLZ_2D_DOMAINOBJ,
                                        *(cDom.p->domains  + idP),
                                        *(cVal.vox->values + idP),
                                        NULL, NULL, &errNum);
                }
                nObj2 = WlzBuildObj2(cObj2, og2, sz2, gType, bufSz, bufP, &errNum);
                if(errNum == WLZ_ERR_NONE)
                {
                    nDom2 = WlzAssignDomain(nObj2->domain, NULL);
                    nVal2 = WlzAssignValues(nObj2->values, NULL);
                }
                (void )WlzFreeObj(cObj2);
                (void )WlzFreeObj(nObj2);
            }
            else if((idZ >= cDom.p->plane1) && (idZ <= cDom.p->lastpl))
            {
                /* Not buffer plane, but previously existing plane. */
                int	idQ;

                idQ = idZ - cDom.p->plane1;
                nDom2 = WlzAssignDomain(*(cDom.p->domains  + idQ), NULL);
                nVal2 = WlzAssignValues(*(cVal.vox->values + idQ), NULL);
            }
            if(errNum == WLZ_ERR_NONE)
            {
                *(nDom.p->domains  + idP) = nDom2;
                *(nVal.vox->values + idP) = nVal2;
            }
            else
            {
                break;
            }
        }
    }
    if(dstErr)
    {
        *dstErr = errNum;
    }
    return(nObj);
}
Beispiel #18
0
/*!
* \return	New 3D domain object.
* \ingroup	WlzArithmetic
* \brief	Computes a new 3D object which shares the domain of the given
*		object, but which has grey values that are the result of
*		applying the given function to the grey values of the
*		given object.
* \param	sObj			Given source domain object with values.
* \param	fn			Scalar function to be applied.
* \param	dstErr			Destination error pointer, may be NULL.
*/
static WlzObject *WlzScalarFn3D(WlzObject *sObj, WlzFnType fn,
			        WlzErrorNum *dstErr)
{
  int		idx,
  		off;
  WlzPixelV	sBgd,
  		dBgd;
  WlzValues	dVal;
  WlzObject     *sObj2D,
		*dObj2D,
  		*dObj = NULL;
  WlzErrorNum   errNum = WLZ_ERR_NONE;

  if(errNum == WLZ_ERR_NONE)
  {
    sBgd = WlzGetBackground(sObj, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dBgd = WlzScalarFnPixel(sBgd, fn, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dVal.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
    				   sObj->domain.p->plane1,
				   sObj->domain.p->lastpl,
				   dBgd, NULL, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    for(idx = sObj->domain.p->plane1; idx <= sObj->domain.p->lastpl; ++idx)
    {
      off = idx - sObj->domain.p->plane1;
      dObj2D = NULL;
      sObj2D = WlzMakeMain(WLZ_2D_DOMAINOBJ,
      		           *(sObj->domain.p->domains + off),
			   *(sObj->values.vox->values + off),
			   NULL, NULL, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
        dObj2D = WlzScalarFn2D(sObj2D, fn, &errNum);
      }
      WlzFreeObj(sObj2D);
      if(errNum == WLZ_ERR_NONE)
      {
        *(dVal.vox->values + off) = WlzAssignValues(dObj2D->values, NULL);
      }
      WlzFreeObj(dObj2D);
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, sObj->domain, dVal,
    		       NULL, NULL, &errNum);
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dObj);
}
/*!
* \return	Rescaled object.
* \ingroup	WlzTransform
* \brief	Rescales the given 2D domain object using an integer scale.
* \param	obj			Given object.
* \param	scale			Integer scale factor.
* \param	expand			If zero use \f$\frac{1}{scale}\f$.
* \param	dstErr			Destination error pointer, may be NULL.
*/
static WlzObject *WlzIntRescaleObj2D(
  WlzObject	*obj,
  int		scale,
  int		expand,
  WlzErrorNum	*dstErr)
{
  WlzObject		*rtnObj=NULL;
  WlzDomain		domain;
  WlzValues		values;
  WlzInterval		*intvls;
  int			k1, kl, l1, ll, l, num_intvls;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  /* check expand or contract */
  if( expand )
  {
    k1 = obj->domain.i->kol1   * scale;
    kl = obj->domain.i->lastkl * scale + scale - 1;
    l1 = obj->domain.i->line1  * scale;
    ll = obj->domain.i->lastln * scale + scale - 1;
  }
  else {
    k1 = obj->domain.i->kol1   / scale;
    kl = obj->domain.i->lastkl / scale;
    l1 = obj->domain.i->line1  / scale;
    ll = obj->domain.i->lastln / scale;
  }

  /* create a new object */
  if((domain.i = WlzMakeIntervalDomain(obj->domain.i->type,
				       l1, ll, k1, kl, &errNum)) != NULL){
    values.core = NULL;
    rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, domain, values, 
			 NULL, NULL, NULL);
  }

  /* fill in the intervals */
  if( errNum == WLZ_ERR_NONE){
    if( domain.i->type == WLZ_INTERVALDOMAIN_INTVL )
    {
      int intvline_offset, max_offset;
      WlzIntervalLine *intvline;

      num_intvls = WlzIntervalCount(obj->domain.i, NULL);
      num_intvls = expand ? num_intvls * scale : num_intvls;
      intvls = (WlzInterval *)AlcMalloc(sizeof(WlzInterval) * num_intvls);
      domain.i->freeptr = AlcFreeStackPush(domain.i->freeptr, (void *)intvls,
      					   NULL);
      max_offset = obj->domain.i->lastln - obj->domain.i->line1;

      for(l=l1; l <= ll; l++)
      {
	int		i;

	intvline_offset = (expand?l/scale:l*scale) - obj->domain.i->line1;
	intvline_offset = WLZ_MAX(intvline_offset, 0);
	intvline_offset = WLZ_MIN(intvline_offset, max_offset);
	intvline = obj->domain.i->intvlines + intvline_offset;

	for(i=0; i < intvline->nintvs; i++)
	{
	  intvls[i].ileft  = (intvline->intvs + i)->ileft;
	  intvls[i].iright = (intvline->intvs + i)->iright;
	  if( expand )
	  {
	    intvls[i].ileft  *= scale;
	    intvls[i].iright *= scale;
	    intvls[i].iright += scale - 1;
	  }
	  else
	  {
	    intvls[i].ileft  /= scale;
	    intvls[i].iright /= scale;
	  }
	}

	i = check_intvs(intvls, i);
	WlzMakeInterval(l, domain.i, i, intvls);
	intvls += i;
      }
      (void) WlzStandardIntervalDomain( domain.i );
    }
  }

  /* create the valuetable */
  if( (errNum == WLZ_ERR_NONE) && obj->values.core )
  {
    WlzIntervalWSpace	iwsp;
    WlzGreyWSpace	gwsp;
    WlzPixelV 		backgrnd;
    WlzGreyValueWSpace	*gVWSp = NULL;
    WlzGreyType		gtype;

    backgrnd = WlzGetBackground(obj, NULL);
    if((values.v = WlzNewValueTb(rtnObj, obj->values.v->type,
				 backgrnd, &errNum)) != NULL){

      rtnObj->values = WlzAssignValues(values, NULL);
      
      /* fill in the grey-values */
      errNum = WlzInitGreyScan(rtnObj, &iwsp, &gwsp);
      if(errNum == WLZ_ERR_NONE) {
	gVWSp = WlzGreyValueMakeWSp(obj, &errNum);
	if(errNum == WLZ_ERR_NONE) {
	  gtype = WlzGreyTableTypeToGreyType(obj->values.v->type, NULL);
	}
	while((errNum == WLZ_ERR_NONE) &&
	      (errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE)
	{
	  int k;
	  int lp = expand ? iwsp.linpos/scale : iwsp.linpos*scale;

	  for( k=0; k <= (iwsp.rgtpos - iwsp.lftpos); k++ )
	  {
	    int	kp = expand ? (k+iwsp.lftpos)/scale : (k+iwsp.lftpos)*scale;

	    WlzGreyValueGet(gVWSp, 0, (double) lp, (double) kp);

	    switch(gtype)
	    {
	    case WLZ_GREY_INT: 
	      gwsp.u_grintptr.inp[k] = (*(gVWSp->gVal)).inv;
	      break;
	    case WLZ_GREY_SHORT:
	      gwsp.u_grintptr.shp[k] = (*(gVWSp->gVal)).shv;
	      break;
	    case WLZ_GREY_UBYTE:
	      gwsp.u_grintptr.ubp[k] = (*(gVWSp->gVal)).ubv;
	      break;
	    case WLZ_GREY_FLOAT:
	      gwsp.u_grintptr.flp[k] = (*(gVWSp->gVal)).flv;
	      break;
	    case WLZ_GREY_DOUBLE:
	      gwsp.u_grintptr.dbp[k] = (*(gVWSp->gVal)).dbv;
	      break;
	    case WLZ_GREY_RGBA:
	      gwsp.u_grintptr.rgbp[k] = (*(gVWSp->gVal)).rgbv;
	      break;
	    default:
	      errNum = WLZ_ERR_GREY_TYPE;
	      break;
	    }
	  }
	}
	if( errNum == WLZ_ERR_EOO ){
	  errNum = WLZ_ERR_NONE;
	}
	WlzGreyValueFreeWSp(gVWSp);
	(void )WlzEndGreyScan(&iwsp, &gwsp);
      }
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
Beispiel #20
0
/*! 
* \ingroup      WlzBinaryOps
* \brief        Calculate the set union of an array of domain objects.
 Domians only unless uvt non-zero in which case make an average grey
 table. Note background values are used in the averaging process. All
 objects must be domain objects of the same type (2D or 3D) unless
 WLZ_EMPTY_OBJ, NULL input objects are an error.

 This function may modify the order of the objects in the array it is
 passed if the array contains empty objects.
*
* \return       Union of the array of object.
* \param    n	number of input objects
* \param    objs	input object array
* \param    uvt	grey-table copy flag, copy if non-zero.
* \param    dstErr	error return.
* \par      Source:
*                WlzUnionN.c
*/
WlzObject *WlzUnionN(
  int		n,
  WlzObject 	**objs,
  int 		uvt,
  WlzErrorNum	*dstErr)
{
  WlzObject		*obj=NULL;
  WlzDomain		domain;
  WlzValues		values;
  WlzIntervalDomain	*idom;
  WlzInterval		*itvl, *jtvl;
  WlzIntervalWSpace	*iwsp;
  WlzIntervalWSpace	*biwsp, *tiwsp, niwsp;
  WlzGreyWSpace		*gwsp, ngwsp;
  WlzObjectType		type;
  int 			i, j, k, l;
  int			inttot, numactive, change, lwas, nints, noverlap;
  WlzPixelV		backg;
  int			line1, lastln;
  int			kol1,lastkl;
  WlzGreyV		gv;
  WlzGreyP		greyptr;
  int			**locbuff;
  int			*locbuffs;
  int			span;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  /* preliminary stuff - count of non-NULL objects, note WLZ_EMPTY_OBJs
     are ignored but NULL objects are an error */
  if( n < 1 ){
    errNum = WLZ_ERR_PARAM_DATA;
  }
  else {
    for (i=0; i<n ; i++ ){
      if ( objs[i] == NULL ){
	errNum = WLZ_ERR_OBJECT_NULL;
	break;
      }
      if( objs[i]->type == WLZ_EMPTY_OBJ ){
	obj = objs[i];
	for ( j=i; j<n-1 ; j++ ){
	  objs[j] = objs[j+1];
	}
	objs[n-1] = obj;
	n--;
	i--;
      }
    }
  }
	
  /* n has been checked therefore no objects implies all empty */
  if( (errNum == WLZ_ERR_NONE) && (n < 1) ){
    return WlzMakeEmpty(dstErr);
  }

  /* now check they are all of the same type */
  if( errNum == WLZ_ERR_NONE ){
    for(i=1; i < n; i++){
      if( objs[i]->type != objs[0]->type ){
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
      }
    }
  }

  /* now test the type note empty objects have been discarded */
  if( errNum == WLZ_ERR_NONE ){
    switch( objs[0]->type ){

    case WLZ_2D_DOMAINOBJ:
      break;

    case WLZ_3D_DOMAINOBJ:
      return WlzUnion3d(n, objs, uvt, dstErr);

    case WLZ_TRANS_OBJ:
    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  /* now discard empty objects */
  if( errNum == WLZ_ERR_NONE ){
    for (i=0; i<n ; i++ ){
      if( WlzIsEmpty(objs[i], NULL) ){
	obj = objs[i];
	for ( j=i; j<n-1 ; j++ ){
	  objs[j] = objs[j+1];
	}
	objs[n-1] = obj;
	n--;
	i--;
      }
    }
  }
  obj = NULL;

  /* recheck number of objects */
  if( (errNum == WLZ_ERR_NONE) && (n < 1) ){
    return WlzMakeEmpty(dstErr);
  }
  if( (errNum == WLZ_ERR_NONE) && (n == 1) ){
    return WlzMakeMain(objs[0]->type, objs[0]->domain,
		       objs[0]->values, NULL, NULL, dstErr);
  }

  /* check if grey-value merge is possible */
  if( errNum == WLZ_ERR_NONE ){
    for (i=0; i<n ; i++ ){
      if( objs[i]->values.core == NULL ){
	uvt = 0;
	break;
      }
    }
  }

  /*
   * find the line and column bounds of the union.
   */
  if( errNum == WLZ_ERR_NONE ){
    line1 = objs[0]->domain.i->line1;
    lastln = objs[0]->domain.i->lastln;
    kol1 = objs[0]->domain.i->kol1;
    lastkl = objs[0]->domain.i->lastkl;
    for (i=1; i<n; i++) {
      idom = objs[i]->domain.i;
      if (line1 > idom->line1)
	line1 = idom->line1;
      if (lastln < idom->lastln)
	lastln = idom->lastln;
      if (kol1 > idom->kol1)
	kol1 = idom->kol1;
      if (lastkl < idom->lastkl)
	lastkl = idom->lastkl;
    }
    span = lastkl - kol1 +1 ;
    if( (locbuff = (int **) AlcMalloc((n+1)*sizeof(int *))) == NULL ){
      errNum = WLZ_ERR_MEM_ALLOC;
    }
  }

  /* space must be allocated for the largest variety of grey-value */
  if( errNum == WLZ_ERR_NONE ){
    if( (locbuffs = (int *) AlcMalloc(sizeof(double)*span*(n+1))) == NULL ){
      AlcFree((void *) locbuff);
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else {
      for(i=0; i <= n; i++){
	locbuff[i] = locbuffs + i*span;
      }
    }
  }
  /*
   * count the individual intervals so that sufficient space
   * for the union may be allocated.
   */
  if( errNum == WLZ_ERR_NONE ){
    inttot=0;
    for(i=0; i < n; i++){
      inttot += WlzIntervalCount(objs[i]->domain.i, &errNum);
    }
  }

  /*
   * set up domain, value table structures, and object.
   */
  if( errNum == WLZ_ERR_NONE ){
    if( (idom = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_INTVL,
				      line1,lastln,kol1,lastkl,
				      &errNum)) == NULL ){
      AlcFree((void *) locbuffs);
      AlcFree((void *) locbuff);
    }
    else if( (itvl = (WlzInterval *)
	      AlcMalloc(inttot * sizeof(WlzInterval))) == NULL){
      AlcFree((void *) locbuffs);
      AlcFree((void *) locbuff);
      WlzFreeIntervalDomain(idom);
      errNum = WLZ_ERR_MEM_ALLOC;
    }
    else {
      idom->freeptr = AlcFreeStackPush(idom->freeptr, (void *)itvl, NULL);
      lwas = line1;
      jtvl = itvl;
      nints = 0;
      domain.i = idom;
      values.v = NULL;
      if( (obj = WlzMakeMain(WLZ_2D_DOMAINOBJ, domain, values,
			     NULL, NULL, &errNum)) == NULL ){
	WlzFreeIntervalDomain( idom );
	AlcFree((void *) locbuffs);
	AlcFree((void *) locbuff);
	return(NULL);
      }
    }
  }    

  /*
   * allocate space for workspaces
   */
  if( errNum == WLZ_ERR_NONE ){
    if( (iwsp = (WlzIntervalWSpace *)
        AlcMalloc (n * sizeof (WlzIntervalWSpace))) == NULL ){
      WlzFreeObj( obj );
      AlcFree((void *) locbuffs);
      AlcFree((void *) locbuff);
      errNum = WLZ_ERR_MEM_ALLOC;
      obj = NULL;
    }
    else {
      biwsp = iwsp;
      tiwsp = iwsp + n;
    }
  }

  /*
   * Construct the union object's table of intervals.
   * Initialise scanning on each object/workspace combination.
   * Scan synchronously, setting up the union of adjacent and
   * overlapping intervals.  Needs a clear head !!
   */
  if( errNum == WLZ_ERR_NONE ){
    for (i=0; i<n; i++) {
      WlzInitRasterScan(objs[i], iwsp, WLZ_RASTERDIR_ILIC);
      WlzNextInterval(iwsp++);
    }
    numactive = n;

    /*
     * find next line and left hand end of next interval of union
     */
    while (numactive > 0) {
      /*
       * find first remaining active object
       */
      iwsp = biwsp;
      while( iwsp->linrmn < 0 ){
	iwsp++;
      }
      /*
       * find minimum line number of remaining active intervals
       */
      l = iwsp->linpos;
      kol1 = iwsp->lftpos;
      lastkl = iwsp->rgtpos;
      for (iwsp++; iwsp<tiwsp; iwsp++)
	if (iwsp->linrmn >= 0 && iwsp->linpos < l) {
	  l = iwsp->linpos;
	  kol1 = iwsp->lftpos;
	  lastkl = iwsp->rgtpos;
	}
      /*
       * find left-most interval in this line
       */
      for (iwsp=biwsp; iwsp<tiwsp; iwsp++)
	if (iwsp->linrmn >= 0 && iwsp->linpos == l && iwsp->lftpos < kol1) {
	  kol1 = iwsp->lftpos;
	  lastkl = iwsp->rgtpos;
	}
      /*
       * construct maximal interval with current left end-point
       */
      do {
	change = 0;
	for (iwsp=biwsp; iwsp<tiwsp; iwsp++) {
	  while( iwsp->linrmn >= 0 && iwsp->linpos == l
		&& iwsp->lftpos <= lastkl+1 ){
	    if (iwsp->rgtpos > lastkl) {
	      lastkl = iwsp->rgtpos;
	      change = 1;
	    }
	    if (WlzNextInterval(iwsp) != WLZ_ERR_NONE) {
	      numactive--;
	    }
	  }
	}
      } while (change == 1);
      itvl->ileft = kol1 - idom->kol1;
      itvl->iright = lastkl - idom->kol1;
      if (l == lwas)
	nints++;
      else {
	(void) WlzMakeInterval(lwas,idom,nints,jtvl);
	for (j = lwas+1; j<l; j++) {
	  (void) WlzMakeInterval(j,idom,0,NULL);
	}
	lwas = l;
	nints = 1;
	jtvl = itvl;
      }
      itvl++;
    }
    (void) WlzMakeInterval(lwas,idom,nints,jtvl);
    for (j = lwas+1; j<=lastln; j++) {
      (void) WlzMakeInterval(j,idom,0,NULL);
    }
  }

  /* now deal with the grey-values if required */
  if( (errNum == WLZ_ERR_NONE) && (uvt != 0) ){
    WlzGreyType	grey_type;

    if( (gwsp = (WlzGreyWSpace *)
	 AlcMalloc (n * sizeof (WlzGreyWSpace))) == NULL){
      WlzFreeObj( obj );
      AlcFree((void *) locbuffs);
      AlcFree((void *) locbuff);
      AlcFree((void *) biwsp);
      errNum = WLZ_ERR_MEM_ALLOC;
      obj = NULL;
    }
    
    /* construct an empty "ragged-rectangle" greytable
       with appropriate grey-type */
    if( errNum == WLZ_ERR_NONE ){
      backg = WlzGetBackground(objs[0], NULL);
      grey_type = WlzGreyTableTypeToGreyType(objs[0]->values.core->type,
					     NULL);
      type = WlzGreyTableType(WLZ_GREY_TAB_RAGR, grey_type, NULL);
      if( (values.v = WlzNewValueTb(obj, type, backg, &errNum)) == NULL ){
	WlzFreeObj( obj );
	AlcFree((void *) locbuffs);
	AlcFree((void *) locbuff);
	AlcFree((void *) biwsp);
	obj = NULL;
      }
      else {
	obj->values = WlzAssignValues(values, NULL);
      }
    }

    /* fill the grey table.  Where more than one input objects
       overlap, take mean of grey values. */
    if( errNum == WLZ_ERR_NONE ){
      WlzInitGreyScan(obj, &niwsp, &ngwsp);
      iwsp = biwsp;
      for (i=0; i<n; i++) {
	WlzInitGreyScan(objs[i], iwsp, &gwsp[i]);
	WlzNextGreyInterval(iwsp++);
	if( gwsp[i].pixeltype != grey_type ){
	  AlcFree((void *) gwsp);
	  AlcFree((void *) locbuffs);
	  AlcFree((void *) locbuff);
	  AlcFree((void *) biwsp);
	  WlzFreeObj( obj );
	  obj = NULL;
	  errNum = WLZ_ERR_GREY_TYPE;
	}      
      }
    }

    if( errNum == WLZ_ERR_NONE ){
      while (WlzNextGreyInterval(&niwsp) == WLZ_ERR_NONE) {
	l = niwsp.linpos;
	greyptr = ngwsp.u_grintptr;
	switch( ngwsp.pixeltype ){

	case WLZ_GREY_INT:
	  for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	    noverlap = 0;
	    gv.inv = 0;
	    for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	      while (iwsp->linrmn >= 0
		     && (iwsp->linpos < l
			 || (iwsp->linpos == l && iwsp->rgtpos < k))){
		WlzNextGreyInterval(iwsp);
	      }
	      if (iwsp->linrmn >= 0 && iwsp->linpos == l &&
		  iwsp->lftpos <= k) {
		noverlap++;
		gv.inv += *(gwsp[i].u_grintptr.inp + k - iwsp->lftpos);
	      }
	    }
	    *greyptr.inp = gv.inv / noverlap;
	    greyptr.inp++;
	  }
	  break;

	case WLZ_GREY_SHORT:
	  for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	    noverlap = 0;
	    gv.shv = 0;
	    for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	      while (iwsp->linrmn >= 0
		     && (iwsp->linpos < l
			 || (iwsp->linpos == l && iwsp->rgtpos < k))){
		WlzNextGreyInterval(iwsp);
	      }
	      if (iwsp->linrmn >= 0 && iwsp->linpos == l &&
		  iwsp->lftpos <= k) {
		noverlap++;
		gv.shv += *(gwsp[i].u_grintptr.shp + k - iwsp->lftpos);
	      }
	    }
	    *greyptr.shp = (short )(gv.shv / noverlap);
	    greyptr.shp++;
	  }
	  break;

	case WLZ_GREY_UBYTE:
	  for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	    noverlap = 0;
	    gv.inv = 0;
	    for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	      while (iwsp->linrmn >= 0
		     && (iwsp->linpos < l
			 || (iwsp->linpos == l && iwsp->rgtpos < k))){
		WlzNextGreyInterval(iwsp);
	      }
	      if (iwsp->linrmn >= 0 && iwsp->linpos == l &&
		  iwsp->lftpos <= k) {
		noverlap++;
		gv.inv += *(gwsp[i].u_grintptr.ubp + k - iwsp->lftpos);
	      }
	    }
	    *greyptr.ubp = (WlzUByte )(gv.inv / noverlap);
 	    greyptr.ubp++;
	  }
	  break;

	case WLZ_GREY_FLOAT:
	  for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	    noverlap = 0;
	    gv.flv = 0;
	    for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	      while (iwsp->linrmn >= 0
		     && (iwsp->linpos < l
			 || (iwsp->linpos == l && iwsp->rgtpos < k))){
		WlzNextGreyInterval(iwsp);
	      }
	      if (iwsp->linrmn >= 0 && iwsp->linpos == l &&
		  iwsp->lftpos <= k) {
		noverlap++;
		gv.flv += *(gwsp[i].u_grintptr.flp + k - iwsp->lftpos);
	      }
	    }
	    *greyptr.flp = gv.flv / noverlap;
	    greyptr.flp++;
	  }
	  break;

	case WLZ_GREY_DOUBLE:
	  for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	    noverlap = 0;
	    gv.dbv = 0;
	    for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	      while (iwsp->linrmn >= 0
		     && (iwsp->linpos < l
			 || (iwsp->linpos == l && iwsp->rgtpos < k))){
		WlzNextGreyInterval(iwsp);
	      }
	      if (iwsp->linrmn >= 0 && iwsp->linpos == l &&
		  iwsp->lftpos <= k) {
		noverlap++;
		gv.dbv += *(gwsp[i].u_grintptr.dbp + k - iwsp->lftpos);
	      }
	    }
	    *greyptr.dbp = gv.dbv / noverlap;
	    greyptr.dbp++;
	  }
	  break;
	case WLZ_GREY_RGBA: /* RGBA to be done - do properly RAB */
	  for (k = niwsp.lftpos; k <= niwsp.rgtpos; k++) {
	    noverlap = 0;
	    gv.rgbv = 0;
	    for (iwsp=biwsp,i=0; iwsp<tiwsp; iwsp++,i++) {
	      while (iwsp->linrmn >= 0
		     && (iwsp->linpos < l
			 || (iwsp->linpos == l && iwsp->rgtpos < k))){
		WlzNextGreyInterval(iwsp);
	      }
	      if (iwsp->linrmn >= 0 && iwsp->linpos == l &&
		  iwsp->lftpos <= k) {
		noverlap++;
		gv.rgbv += *(gwsp[i].u_grintptr.rgbp + k - iwsp->lftpos);
	      }
	    }
	    *greyptr.rgbp = gv.rgbv / noverlap;
	    greyptr.rgbp++;
	  }
	  break;

	default:
	  break;

	}
      }
    }
    AlcFree((void *) gwsp);
  }

  if( errNum == WLZ_ERR_NONE ){
    AlcFree( (void *) biwsp);
    AlcFree( (void *)locbuff );
    AlcFree( (void *)locbuffs );
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return( obj );
}
Beispiel #21
0
/*!
* \return	Transformed object.
* \ingroup	WlzTransform
* \brief	Transform an object using the given view-transform.
*		Typically this is for mapping section data back into
*		the 3D space of the reference image/reconstruction.
* \param	srcObj			Given source object.
* \param	viewStr			Given view transform.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject *Wlz3DViewTransformObj(
    WlzObject		*srcObj,
    WlzThreeDViewStruct	*viewStr,
    WlzErrorNum		*dstErr)
{
    WlzErrorNum		errNum=WLZ_ERR_NONE;
    AlcErrno		alcErr = ALC_ER_NONE;
    WlzObject		*dstObj=NULL;
    int			area;
    int			i, k, p, xp, yp, line;
    int			plane1, lastpl, line1, lastln, kol1, lastkl;
    WlzIVertex3		*vertices;
    int			numVtxs, vtxIdx;
    WlzIntervalWSpace	iwsp;
    WlzGreyWSpace		gwsp;
    WlzDomain		domain, tmpDomain;
    WlzValues		values;
    int			numInts, itvlFlg;
    WlzInterval		*itvl;


    /* check the object */
    if( srcObj == NULL ) {
        errNum = WLZ_ERR_OBJECT_NULL;
    }
    else {
        switch( srcObj->type ) {

        case WLZ_2D_DOMAINOBJ:
            if( srcObj->domain.core == NULL ) {
                errNum = WLZ_ERR_DOMAIN_NULL;
            }
            area = WlzArea(srcObj, &errNum);
            if( area == 0 ) {
                dstObj = WlzMakeEmpty(&errNum);
            }
            break;

        case WLZ_2D_POLYGON: /* to be done at some time to 3D polyline */
        case WLZ_BOUNDLIST: /* convert to 3D polylines */
        case WLZ_TRANS_OBJ:
            errNum = WLZ_ERR_OBJECT_TYPE;
            break;

        default:
            errNum = WLZ_ERR_OBJECT_TYPE;
            break;
        }
    }

    /* create the voxel list */
    if( (errNum == WLZ_ERR_NONE) && (dstObj == NULL) ) {
        numVtxs = sizeof(WlzIVertex3) * (area+4);

        vertices = AlcMalloc(sizeof(WlzIVertex3) * (area+4));
        numVtxs = 0;
        if( vertices ) {
            errNum = WlzInitRasterScan(srcObj, &iwsp, WLZ_RASTERDIR_ILIC);
        }
        else {
            errNum = WLZ_ERR_MEM_ALLOC;
        }

        if( errNum == WLZ_ERR_NONE ) {
            while( (errNum = WlzNextInterval(&iwsp)) == WLZ_ERR_NONE ) {
                float x, y, z;

                if((iwsp.linpos < (int) viewStr->minvals.vtY) ||
                        (iwsp.linpos > (int) viewStr->maxvals.vtY)) {
                    continue;
                }
                yp = iwsp.linpos - (int) viewStr->minvals.vtY;
                for(k=iwsp.lftpos; k <= iwsp.rgtpos; k++) {
                    if((k < (int) viewStr->minvals.vtX) ||
                            (k > (int) viewStr->maxvals.vtX)) {
                        continue;
                    }
                    xp = k - (int) viewStr->minvals.vtX;
                    x = (float )(viewStr->xp_to_x[xp] + viewStr->yp_to_x[yp]);
                    y = (float )(viewStr->xp_to_y[xp] + viewStr->yp_to_y[yp]);
                    z = (float )(viewStr->xp_to_z[xp] + viewStr->yp_to_z[yp]);
                    vertices[numVtxs].vtX = WLZ_NINT(x);
                    vertices[numVtxs].vtY = WLZ_NINT(y);
                    vertices[numVtxs].vtZ = WLZ_NINT(z);
                    numVtxs++;
                }
            }

            if(errNum == WLZ_ERR_EOO) /* Reset error from end of object */
            {
                errNum = WLZ_ERR_NONE;
            }
        }
    }

    /* sort wrt planes, lines, kols */
    if( (errNum == WLZ_ERR_NONE) && (dstObj == NULL) ) {
        qsort((void *) vertices, (size_t) numVtxs, sizeof(WlzIVertex3),
              compareVtxVal);

        /* create planedomain */
        plane1 = vertices[0].vtZ;
        lastpl = vertices[numVtxs - 1].vtZ;
        line1 = vertices[0].vtY;
        lastln = line1;
        kol1 = vertices[0].vtX;
        lastkl = kol1;
        for(i=1; i < numVtxs; i++) {
            if( kol1 > vertices[i].vtX ) {
                kol1 = vertices[i].vtX;
            }
            if( lastkl < vertices[i].vtX ) {
                lastkl = vertices[i].vtX;
            }
            if( line1 > vertices[i].vtY ) {
                line1 = vertices[i].vtY;
            }
            if( lastln < vertices[i].vtY ) {
                lastln = vertices[i].vtY;
            }
        }
        if( (domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
                                           plane1, lastpl,
                                           line1, lastln,
                                           kol1, lastkl,
                                           &errNum)) == NULL ) {
            AlcFree((void *) vertices);
        }
    }

    /* for each plane count intervals and make domain */
    if( (errNum == WLZ_ERR_NONE) && (dstObj == NULL) ) {

        vtxIdx = 0;
        for(p=plane1; p <= lastpl; p++) {

            /* increment vertex index to current plane */
            while( vertices[vtxIdx].vtZ < p ) {
                vtxIdx++;
            }

            /* check for empty domain */
            if( vertices[vtxIdx].vtZ > p ) {
                domain.p->domains[p - plane1].i = NULL;
                continue;
            }

            /* estimate intervals - foreach pixel add one,
            foreach adjacent pixel on the same line subtract one */
            numInts = 1;
            kol1 = vertices[vtxIdx].vtX;
            lastkl = kol1;
            for(i=vtxIdx+1; i < numVtxs; i++) {
                if( vertices[i].vtZ > p ) {
                    break;
                }
                numInts++;
                if((vertices[i].vtY == vertices[i-1].vtY) &&
                        ((vertices[i].vtX == (vertices[i-1].vtX)) ||
                         (vertices[i].vtX == (vertices[i-1].vtX + 1))
                        )) {
                    numInts--;
                }
                if(kol1 > vertices[i].vtX) {
                    kol1 = vertices[i].vtX;
                }
                if(lastkl < vertices[i].vtX) {
                    lastkl = vertices[i].vtX;
                }
            }
            line1 = vertices[vtxIdx].vtY;
            lastln = vertices[i-1].vtY;

            /* make the domain and add the intervals pointer */
            tmpDomain.i = WlzMakeIntervalDomain(WLZ_INTERVALDOMAIN_INTVL,
                                                line1, lastln,
                                                kol1, lastkl,
                                                &errNum);
            itvl = (WlzInterval *) AlcMalloc(sizeof(WlzInterval)*numInts);
            tmpDomain.i->freeptr = AlcFreeStackPush(tmpDomain.i->freeptr,
                                                    (void *) itvl,
                                                    &alcErr);
            if(alcErr != ALC_ER_NONE) {
                errNum = WLZ_ERR_MEM_ALLOC;
            }
            /* one more loop to add the intervals */
            itvl->ileft = vertices[vtxIdx].vtX - kol1;
            line = vertices[vtxIdx].vtY;
            itvlFlg = 1; /* interval started */
            numInts = 1;
            for(i=vtxIdx+1; i < numVtxs; i++) {

                /* new plane -> interval finished if started */
                if( vertices[i].vtZ > p ) {
                    if( itvlFlg ) {
                        itvl[numInts-1].iright = vertices[i-1].vtX - kol1;
                        WlzMakeInterval(line, tmpDomain.i, numInts, itvl);
                        itvl += numInts;
                        itvlFlg = 0; /* interval finished */
                        numInts = 0;
                    }
                    break;
                }

                /* check if new interval */
                if( !itvlFlg ) {
                    itvl->ileft = vertices[i].vtX - kol1;
                    line = vertices[i].vtY;
                    itvlFlg = 1;
                    numInts = 1;
                    continue; /* no further tests */
                }

                /* check for gap  - increment interval count */
                if((vertices[i].vtY == line) &&
                        ((vertices[i].vtX - vertices[i-1].vtX) > 1)) {
                    itvl[numInts-1].iright = vertices[i-1].vtX - kol1;
                    numInts++;
                    itvl[numInts-1].ileft = vertices[i].vtX - kol1;
                    itvlFlg = 1;
                }

                /* check for new-line */
                if( line < vertices[i].vtY ) {
                    itvl[numInts-1].iright = vertices[i-1].vtX - kol1;
                    WlzMakeInterval(line, tmpDomain.i, numInts, itvl);
                    itvl += numInts;
                    itvl->ileft = vertices[i].vtX - kol1;
                    line = vertices[i].vtY;
                    itvlFlg = 1;
                    numInts = 1;
                }

            }

            /* complete the last interval */
            if( itvlFlg ) {
                itvl[numInts-1].iright = vertices[i-1].vtX - kol1;
                WlzMakeInterval(line, tmpDomain.i, numInts, itvl);
                itvl += numInts;
            }

            /* add the domain to the planedomain */
            domain.p->domains[p - plane1] =
                WlzAssignDomain(tmpDomain, &errNum);
            (void) WlzIntervalCount(tmpDomain.i, 0);

        }

    }

    /* create the new object */
    if( (errNum == WLZ_ERR_NONE) && (dstObj == NULL) ) {
        values.core = NULL;
        dstObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
                             NULL, NULL, &errNum);
    }

    /* check for grey-level data */
    if((errNum == WLZ_ERR_NONE) && dstObj &&
            (dstObj->type != WLZ_EMPTY_OBJ) && srcObj->values.core ) {
        WlzPixelV	bckgrnd;
        WlzObject	*tmpObj;
        WlzValues	tmpValues;
        WlzDVertex3	vtx;
        WlzGreyValueWSpace	*gVWSp = NULL;
        WlzObjectType	valueTbType;

        /* explicit intialisation to satisfy strict ANSI on SGI */
        bckgrnd = WlzGetBackground(srcObj, &errNum);
        valueTbType = WlzGreyTableType(WLZ_GREY_TAB_RAGR,
                                       bckgrnd.type, NULL);

        /* make a voxel table */
        values.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
                                         plane1, lastpl, bckgrnd,
                                         NULL, &errNum);
        dstObj->values = WlzAssignValues(values, &errNum);

        /* set up grey-value random access to original
           and loop through planes setting values */
        gVWSp = WlzGreyValueMakeWSp(srcObj, NULL);
        for(p=plane1; p <= lastpl; p++) {

            /* check for empty domain */
            if( domain.p->domains[p-plane1].core == NULL ) {
                continue;
            }

            /* make a value table */
            tmpObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, domain.p->domains[p-plane1],
                                 values.vox->values[p-plane1], NULL, NULL, &errNum);
            tmpValues.v = WlzNewValueTb(tmpObj, valueTbType, bckgrnd, &errNum);
            values.vox->values[p-plane1] = WlzAssignValues(tmpValues, &errNum);
            tmpObj->values = WlzAssignValues(tmpValues, &errNum);

            /* transfer values */
            errNum = WlzInitGreyScan(tmpObj, &iwsp, &gwsp);
            while((errNum == WLZ_ERR_NONE) &&
                    ((errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE)) {

                for(i=0;  i<iwsp.colrmn; i++) {
                    vtx.vtX = iwsp.colpos + i;
                    vtx.vtY = iwsp.linpos;
                    vtx.vtZ = p;
                    Wlz3DSectionTransformVtx(&vtx, viewStr);
                    WlzGreyValueGet(gVWSp, 0.0,
                                    WLZ_NINT(vtx.vtY), WLZ_NINT(vtx.vtX));
                    switch( gwsp.pixeltype ) {
                    case WLZ_GREY_LONG:
                        *(gwsp.u_grintptr.lnp+i) = gVWSp->gVal[0].lnv;
                        break;
                    case WLZ_GREY_INT:
                        *(gwsp.u_grintptr.inp+i) = gVWSp->gVal[0].inv;
                        break;
                    case WLZ_GREY_SHORT:
                        *(gwsp.u_grintptr.shp+i) = gVWSp->gVal[0].shv;
                        break;
                    case WLZ_GREY_UBYTE:
                        *(gwsp.u_grintptr.ubp+i) = gVWSp->gVal[0].ubv;
                        break;
                    case WLZ_GREY_FLOAT:
                        *(gwsp.u_grintptr.flp+i) = gVWSp->gVal[0].flv;
                        break;
                    case WLZ_GREY_DOUBLE:
                        *(gwsp.u_grintptr.dbp+i) = gVWSp->gVal[0].dbv;
                        break;
                    case WLZ_GREY_RGBA:
                        *(gwsp.u_grintptr.rgbp+i) = gVWSp->gVal[0].rgbv;
                        break;
                    case WLZ_GREY_BIT: /* not sure what to do with these */
                    default:
                        break;
                    }
                }
            }
            if(errNum == WLZ_ERR_EOO) /* Reset error from end of object */
            {
                errNum = WLZ_ERR_NONE;
            }
            WlzFreeObj(tmpObj);
        }

        WlzGreyValueFreeWSp(gVWSp);
    }

    /* clean temp allocation */
    if( vertices ) {
        AlcFree((void *) vertices);
    }

    if( dstErr ) {
        *dstErr = errNum;
    }
    return dstObj;
}
Beispiel #22
0
/*! 
* \ingroup      WlzValuesUtils
* \brief        
*
* \return       New object with the same domain <tt>tmpl</tt> but
 values in the intersection with <tt>obj</tt> set to those of the object.
 Returns NULL on error.
* \param    obj	Input object to which the template is applied
* \param    tmpl	Template object
* \param    tmplVal	Template value for regions in the template
 not in the original object
* \param    dstErr	Error return.
* \par      Source:
*                WlzGreyTemplate.c
*/
WlzObject *WlzGreyTemplate(
  WlzObject	*obj,
  WlzObject	*tmpl,
  WlzPixelV	tmplVal,
  WlzErrorNum	*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzObject	*obj1, *obj2;
  WlzValues	values;
  WlzPixelV	bckgrnd;
  WlzObjectType	type;
  WlzGreyType	gtype=WLZ_GREY_UBYTE;
  WlzIntervalWSpace	iwsp1, iwsp2;
  WlzGreyWSpace		gwsp1, gwsp2;
  int			size;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  /* check obj */
  if( obj == NULL ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else {
    switch( obj->type ){
    case WLZ_2D_DOMAINOBJ:
      if( obj->values.core == NULL ){
	errNum = WLZ_ERR_VALUES_NULL;
      }
      else if( WlzGreyTableIsTiled(obj->values.core->type) ){
	errNum = WLZ_ERR_VALUES_TYPE;
      } else {
        bckgrnd = WlzGetBackground(obj, &errNum);
      }
      if(errNum == WLZ_ERR_NONE) {
        gtype = WlzGreyTableTypeToGreyType(obj->values.core->type, NULL);
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      return WlzGreyTemplate3d(obj, tmpl, tmplVal, dstErr);

    case WLZ_TRANS_OBJ:
      if((values.obj = WlzGreyTemplate(obj->values.obj, tmpl,
				       tmplVal, &errNum)) != NULL){
	return WlzMakeMain(WLZ_TRANS_OBJ, obj->domain, values,
			   NULL, NULL, dstErr);
      }
      break;

    case WLZ_EMPTY_OBJ:
      bckgrnd.type = WLZ_GREY_UBYTE;
      bckgrnd.v.ubv = 0;
      break;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  /* check the template */
  if( errNum == WLZ_ERR_NONE ){
    if( tmpl == NULL ){
      errNum = WLZ_ERR_OBJECT_NULL;
    }
    else {
      values.core = NULL;
      switch( tmpl->type ){
      case WLZ_2D_DOMAINOBJ:
	rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, tmpl->domain, values,
			      NULL, NULL, &errNum);
	break;

      case WLZ_TRANS_OBJ:
	rtnObj = WlzMakeMain(WLZ_2D_DOMAINOBJ, tmpl->values.obj->domain,
			      values, NULL, NULL, &errNum);
	break;

      case WLZ_EMPTY_OBJ:
	return WlzMakeEmpty(dstErr);

      case WLZ_2D_POLYGON:
	rtnObj = WlzPolyToObj(tmpl->domain.poly, WLZ_SIMPLE_FILL, &errNum);
	break;

      case WLZ_BOUNDLIST:
	rtnObj = WlzBoundToObj(tmpl->domain.b, WLZ_SIMPLE_FILL, &errNum);
	break;

      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
      }
    }
  }

  /* attach a value table to the template and set to the template value,
     note the background is set to the input object or zero if empty */
  if( errNum == WLZ_ERR_NONE ){
    type = WlzGreyTableType(WLZ_GREY_TAB_RAGR, gtype, NULL);
    if((values.v = WlzNewValueTb(rtnObj, type, bckgrnd, &errNum)) != NULL){
      rtnObj->values = WlzAssignValues(values, NULL);
      errNum = WlzGreySetValue(rtnObj, tmplVal);
    }
  }

  /* copy input obj values within the intersection */
  if( errNum == WLZ_ERR_NONE ){
    if((obj->type != WLZ_EMPTY_OBJ) ){
      if( (obj1 = WlzIntersect2(obj, rtnObj, &errNum)) ){
	obj1->values = WlzAssignValues(rtnObj->values, NULL);
	obj2 = WlzMakeMain(obj1->type, obj1->domain, obj->values,
			   NULL, NULL, NULL);

	errNum = WlzInitGreyScan(obj1, &iwsp1, &gwsp1);
	errNum = WlzInitGreyScan(obj2, &iwsp2, &gwsp2);
	switch( gwsp1.pixeltype ){
	case WLZ_GREY_INT:
	  size = sizeof(int);
	  break;
	case WLZ_GREY_SHORT:
	  size = sizeof(short);
	  break;
	case WLZ_GREY_UBYTE:
	  size = sizeof(WlzUByte);
	  break;
	case WLZ_GREY_FLOAT:
	  size = sizeof(float);
	  break;
	case WLZ_GREY_DOUBLE:
	  size = sizeof(double);
	  break;
	case WLZ_GREY_RGBA:
	  size = sizeof(WlzUInt);
	  break;
	default:
	  errNum = WLZ_ERR_GREY_TYPE;
	  break;
	}

	while((errNum == WLZ_ERR_NONE) &&
	      ((errNum = WlzNextGreyInterval(&iwsp1)) == WLZ_ERR_NONE)){
	  (void) WlzNextGreyInterval(&iwsp2);
	  memcpy((void *) gwsp1.u_grintptr.inp,
		 (const void *) gwsp2.u_grintptr.inp,
		 size * iwsp1.colrmn);
	}
	if( errNum == WLZ_ERR_EOO ){
	  errNum = WLZ_ERR_NONE;
	}
	WlzFreeObj(obj2);
	WlzFreeObj(obj1);
      }
      else {
	WlzFreeObj(rtnObj);
	rtnObj = NULL;
      }
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
Beispiel #23
0
void file_menu_init(
  Widget	topl)
{
  Widget	rc, form, toggle;
  Visual	*visual;
  Arg		arg[1];
  char		fileStr[128];
  FILE 		*fp;
  WlzEffFormat	image_type=WLZEFF_FORMAT_WLZ;

  /* set the top-level title */
  set_topl_title(NULL);

  /* get the visual explicitly */
  visual = HGU_XmWidgetToVisual(topl);
  XtSetArg(arg[0], XmNvisual, visual);

  /* create the read-model file selection dialog */
  read_model_dialog = XmCreateFileSelectionDialog(topl,
						  "read_model_dialog", arg, 1);
  XtAddCallback(read_model_dialog, XmNokCallback,
		read_reference_object_cb, (XtPointer) WLZEFF_FORMAT_WLZ);
  XtAddCallback(read_model_dialog, XmNokCallback, PopdownCallback, NULL);
  XtAddCallback( read_model_dialog, XmNcancelCallback, 
		PopdownCallback, NULL);
  XtAddCallback(read_model_dialog, XmNmapCallback,
		FSBPopupCallback, NULL);
  XtManageChild( read_model_dialog );

  /* create the read-obj file selection dialog */
  read_obj_dialog = HGU_XmCreateExtFFObjectFSB(topl, "read_obj_dialog",
					      read_reference_object_cb, NULL);
  if((rc = XtNameToWidget(read_obj_dialog, "*.formatFormRC"))){

    /* add a form to include file type and fill-blanks toggle */
    form = XtVaCreateManagedWidget("read_file_form", xmFormWidgetClass,
				   rc,
				   XmNborderWidth,	0,
				   NULL);

    /* add a fill-blanks toggles */
    toggle = XtVaCreateManagedWidget("fill_blanks", xmToggleButtonGadgetClass,
				     form,
				     XmNindicatorOn, 	True,
				     XmNindicatorType,	XmN_OF_MANY,
				     XmNset,		False,
				     XmNtopAttachment,	XmATTACH_FORM,
				     XmNleftAttachment,	XmATTACH_FORM,
				     NULL);

    toggle = XtVaCreateManagedWidget("min_domain", xmToggleButtonGadgetClass,
				     form,
				     XmNindicatorOn, 	True,
				     XmNindicatorType,	XmN_OF_MANY,
				     XmNset,		True,
				     XmNtopAttachment,	XmATTACH_FORM,
				     XmNleftAttachment,	XmATTACH_WIDGET,
				     XmNleftWidget,	toggle,
				     NULL);
  }

  HGU_XmExtFFObjectFSBSetType(read_obj_dialog, WLZEFF_FORMAT_WLZ);
  XtManageChild( read_obj_dialog );

  /* add to the save restore list */
  HGU_XmSaveRestoreAddWidget( read_obj_dialog, HGU_XmFSD_SaveFunc,
			     (XtPointer) XtName(topl), NULL, NULL );

  /* create the write-obj file selection dialog */
  write_obj_dialog = HGU_XmCreateExtFFObjectFSB(topl, "write_obj_dialog",
					       write_reference_object_cb,
					       NULL);
  HGU_XmExtFFObjectFSBSetType(write_obj_dialog, WLZEFF_FORMAT_WLZ);


  /* initialise the reference file list pulldown */
  if( !globals.sectViewFlg ){
    Widget	cascade;

    if((cascade = XtNameToWidget(globals.topl,
				 "*file_menu*_pulldown*Recent"))){
      globals.resourceFile = (String) 
	AlcMalloc(sizeof(char) * (strlen(getenv("HOME")) + 16));
      sprintf(globals.resourceFile, "%s/%s", getenv("HOME"), ".maRecentFiles");
      globals.fileList = HGU_XmFileListCreateList(globals.resourceFile, NULL);
      HGU_XmFileListResetMenu(globals.fileList, cascade, referenceFileListCb);
    }
  }

  /* add to the save restore list */
  HGU_XmSaveRestoreAddWidget( write_obj_dialog, HGU_XmFSD_SaveFunc,
			     (XtPointer) XtName(topl), NULL, NULL );

  /* create the object properties dialog */
  obj_props_dialog_init( topl );

  globals.file      = NULL;
  globals.obj       = NULL;
  globals.orig_obj  = NULL;
  globals.fb_obj    = NULL;
  globals.origObjExtType = image_type;

  /* setup the theiler directory and menu item - check for stage */
  XtGetApplicationResources(topl, &globals, set_att_res,
			    XtNumber(set_att_res), NULL, 0);

  /* check the logfile */
  if( globals.logfile ){
    if( (globals.logfileFp = fopen(globals.logfile, "w")) == NULL ){
      fprintf(stderr,
	      "MAPaint: something wrong with the logfile %s\n"
	      "Please check name and permissions\n"
	      "Logging not enabled\n\007", globals.logfile);
    }
    else {
      char		timeBuf[16];
      struct hostent 	*hstnt;
      fprintf(stderr, "MAPaint: logging enabled to %s\n", globals.logfile);
      MAPaintLogData("Filename", globals.logfile, 0, NULL);
      MAPaintLogData("User", getenv("USER"), 0, NULL);
#if defined (LINUX2) || defined (DARWIN)
      strcpy(timeBuf, "00/00/00");
#else
      tmpTime = time(NULL);
      cftime(timeBuf, "%d/%m/%Y", &tmpTime);
#endif /* LINUX2 */
      MAPaintLogData("Date", timeBuf, 0, NULL);
#if defined (LINUX2) || defined (DARWIN)
      strcpy(timeBuf, "00.00");
#else
      cftime(timeBuf, "%H.%M", &tmpTime);
#endif /* LINUX2 */
      MAPaintLogData("Time", timeBuf, 0, NULL);
      hstnt = gethostbyname(getenv("HOST"));
      MAPaintLogData("Host", getenv("HOST"), 0, NULL);
      MAPaintLogData("Hostname", hstnt->h_name, 0, NULL);
    }
  }
  else {
    globals.logfileFp = NULL;
  }

  /* check base directory - if the string has come from the resources then
     we need to duplicate it to allow it to be freed
     possibly some memory leakage here */
  /* note: only non-NULL if set by the user, if NULL then attempt to find
     the cdrom or copied data */
  if( globals.base_theiler_dir ){
    globals.base_theiler_dir = AlcStrDup( globals.base_theiler_dir );
  }
/*  else {
    FILE	*pp;*/
    
    /* search for the Theiler mode directory as per the CDROM 
       should search local disc first */
/*#if defined (LINUX2)
    if((pp = popen("find /mnt -maxdepth 4 -name Models", "r"))){
      while( fscanf(pp, "%s", fileStr) != EOF ){
	if( strstr(fileStr, "Models") ){
	  globals.base_theiler_dir = AlcStrDup(fileStr);
	  break;
	}
      }
      pclose(pp);
    }
#elif defined (DARWIN)
    if( (pp = popen("find /Volumes -maxdepth 4 -name Models", "r")) ){
      while( fscanf(pp, "%s", fileStr) != EOF ){
	if( strstr(fileStr, "Models") ){
	  globals.base_theiler_dir = AlcStrDup(fileStr);
	  break;
	}
      }
      pclose(pp);
    }
#elif defined (SUNOS4) || defined (SUNOS5)
    if( pp = popen("find /cdrom -maxdepth 4 -name Models", "r") ){
      while( fscanf(pp, "%s", fileStr) != EOF ){
	if( strstr(fileStr, "Models") ){
	  globals.base_theiler_dir = AlcStrDup(fileStr);
	  break;
	}
      }
      pclose(pp);
    }
#else
    globals.base_theiler_dir = NULL;
#endif
  }*/
  if( globals.theiler_stage ){
    char *tStr;
    if((tStr = theilerString(globals.theiler_stage))){
      globals.theiler_stage = AlcStrDup(tStr);
    }
    else {
      globals.theiler_stage = NULL;
    }
  }
  theiler_menu_init( topl );

  /* check for an initial reference file else check Theiler stage */
  if( initial_reference_file != NULL ){
    WlzObject 	*obj;

    /* open the reference object file and install */
    if( (fp = fopen(initial_reference_file, "r")) ){
      HGU_XmSetHourGlassCursor(topl);
      if((obj = WlzReadObj( fp, NULL ))){
        WlzDomain	domain;
        WlzValues	values;
        WlzObject	*newObj;
	switch( obj->type ){

	case WLZ_2D_DOMAINOBJ:
	  domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN, 0, 0,
					obj->domain.i->line1,
					obj->domain.i->lastln,
					obj->domain.i->kol1,
					obj->domain.i->lastkl,
					NULL);
	  domain.p->domains[0] = WlzAssignDomain(obj->domain, NULL);
	  values.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
					   0, 0, WlzGetBackground(obj, NULL),
					   NULL, NULL);
	  values.vox->values[0] = WlzAssignValues(obj->values, NULL);
	  newObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
			       NULL, NULL, NULL);
	  WlzFreeObj(obj);
	  obj = newObj;
	  globals.origObjType = WLZ_2D_DOMAINOBJ;
	  break;

	case WLZ_3D_DOMAINOBJ:
	  globals.origObjType = WLZ_3D_DOMAINOBJ;
	  break;

	default:
	  HGU_XmUserError(globals.topl,
			  "Read Reference Object:\n"
			  "    The reference object must be a 2- or 3-D woolz\n"
			  "    grey-level image. Please select an alternate\n"
			  "    object",
			  XmDIALOG_FULL_APPLICATION_MODAL);
	  WlzFreeObj( obj );
	  /* set hour glass cursor */
	  HGU_XmUnsetHourGlassCursor(globals.topl);
	  return;

	}
	HGU_XmFileListAddFile(globals.fileList, initial_reference_file,
			      image_type);
	HGU_XmFileListWriteResourceFile(globals.fileList,
					globals.resourceFile);
	MAPaintLogData("ReferenceFile", initial_reference_file, 0, NULL);
	install_paint_reference_object( obj );

	/* set the globals reference file */
	globals.file = initial_reference_file;

	/* set the title of the top-level window */
	set_topl_title(globals.file);
      }
      else {
	/* if it fails to read, check the file name
	   or the file content for special options */
	if( strstr(initial_reference_file, "MAPaint") ){
	  /* standard MAPaint startup */
	  globals.app_name = "MAPaint";
	  /* set the title of the top-level window */
	  set_topl_title(globals.file);
	}
	else if( strstr(initial_reference_file, "SectionView") ){
	  /* restricted section view startup */
	  globals.app_name = "SectionView";
	  globals.sectViewFlg = 1;
	  /* set the title of the top-level window */
	  set_topl_title(globals.file);
	}
	else if( theilerString(initial_reference_file) ){
	  /* load in theiler stage anatomy etc. */
	  globals.app_name = "SectionView";
	  globals.sectViewFlg = 1;
	  set_theiler_stage_cb(topl, theilerString(initial_reference_file),
			       NULL);
	}
	else {
	  char	strBuf[33];
	  /* check the content */
	  rewind(fp);
	  fscanf(fp, "%32s", strBuf);
	  if( strstr(strBuf, "MAPaint") ){
	    /* standard MAPaint startup */
	    globals.app_name = "MAPaint";
	    /* set the title of the top-level window */
	    set_topl_title(globals.file);
	  }
	  else if( strstr(strBuf, "SectionView") ){
	    /* restricted section view startup */
	    globals.app_name = "SectionView";
	    globals.sectViewFlg = 1;
	    /* set the title of the top-level window */
	    set_topl_title(globals.file);
	  }
	  else if( theilerString(strBuf) ){
	    /* load in theiler stage anatomy etc. */
	    globals.app_name = "SectionView";
	    globals.sectViewFlg = 1;
	    set_theiler_stage_cb(topl,
				 theilerString(strBuf),
				 NULL);
	  }
	}

	/* set the globals reference file */
	globals.file = NULL;
      }
      (void) fclose( fp );

      HGU_XmUnsetHourGlassCursor(topl);
    }
  }
  else if( globals.theiler_stage ){
    globals.app_name = "MAPaint";
    set_theiler_stage_cb(topl, theilerString(globals.theiler_stage), NULL);
  }

  /* reset the colormap */
  if( globals.sectViewFlg == 1 ){
    init_paint_cmapstruct(globals.topl);
  }

  /* check for an initial domain file */
  if( initial_domain_file != NULL ){
    WlzObject 	*obj;

    /* open the domain object file and put it in as a 3D feedback option */
    if( (fp = fopen(initial_domain_file, "rb")) ){
      HGU_XmSetHourGlassCursor(topl);
      if((obj = WlzReadObj( fp, NULL ))){
	if( globals.fb_obj ){
	  WlzFreeObj(globals.fb_obj);
	}
	globals.fb_obj = WlzAssignObject(obj, NULL);
	setup_ref_display_list_cb(read_obj_dialog, NULL, NULL);
      }
      (void) fclose( fp );
      HGU_XmUnsetHourGlassCursor(topl);
    }
  }

  return;
}
/*! 
* \return       Object with transformed grey-values.
* \ingroup      WlzArithmetic
* \brief        Apply a binary operation (add subtract etc) to
*               each pixel value in the given object. The operand value
*               is in <tt>pval</tt>.
* \param    o1	Input object
* \param    pval	Pixel value for binary operation.
* \param    op		Opertor
* \param    dstErr	Error return.
* \par      Source:
*                WlzScalarArithmeticOp.c
*/
WlzObject *WlzScalarBinaryOp2(
  WlzObject	*o1,
  WlzPixelV	pval,
  WlzBinaryOperatorType	op,
  WlzErrorNum	*dstErr)
{
  WlzObject	*obj=NULL, *tmp3;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  WlzValues	values;
  WlzPixelV	old_bckgrnd, new_bckgrnd;
  WlzGreyType	new_grey_type;
  int		p;

  /* check object pointers */
  if( (o1 == NULL) ){
    errNum = WLZ_ERR_OBJECT_NULL;
  }

  /* check object types - WLZ_EMPTY_OBJ is legal */
  if( errNum == WLZ_ERR_NONE ){
    switch( o1->type ){

    case WLZ_2D_DOMAINOBJ: /* FALLTHROUGH */
    case WLZ_3D_DOMAINOBJ: /* FALLTHROUGH */
    case WLZ_TRANS_OBJ:
      break;

    case WLZ_EMPTY_OBJ:
      obj = WlzMakeEmpty(&errNum);
      break;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;

    }
  }

  /* check domains and valuetables */
  if( (errNum == WLZ_ERR_NONE) && (obj == NULL) ){
    switch( o1->type ){

    case WLZ_2D_DOMAINOBJ:
      if( (o1->domain.core == NULL) ){
	errNum = WLZ_ERR_DOMAIN_NULL;
	break;
      }
      if( (o1->values.core == NULL) ){
	errNum = WLZ_ERR_VALUES_NULL;
	break;
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      if( (o1->domain.core == NULL) ){
	errNum = WLZ_ERR_DOMAIN_NULL;
	break;
      }
      if( (o1->domain.p->type != WLZ_PLANEDOMAIN_DOMAIN) ){
	errNum = WLZ_ERR_PLANEDOMAIN_TYPE;
	break;
      }
      if( (o1->values.core == NULL) ){
	errNum = WLZ_ERR_VALUES_NULL;
	break;
      }
      if( (o1->values.vox->type != WLZ_VOXELVALUETABLE_GREY) ){
	errNum = WLZ_ERR_VOXELVALUES_TYPE;
	break;
      }
      break;

    case WLZ_TRANS_OBJ:
      if( (o1->domain.core == NULL) ){
	errNum = WLZ_ERR_DOMAIN_NULL;
	break;
      }
      if( (o1->values.core == NULL) ){
	errNum = WLZ_ERR_VALUES_NULL;
	break;
      }
      if((values.obj = WlzScalarBinaryOp2(o1->values.obj, pval,
					 op, &errNum)) != NULL){
	obj = WlzMakeMain(WLZ_TRANS_OBJ, o1->domain, values,
			  NULL, NULL, &errNum);
	break;
      }
      break;
    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  /* set up temporary object */
  if((errNum == WLZ_ERR_NONE) && (obj == NULL)){
    switch( o1->type ){

    case WLZ_2D_DOMAINOBJ:
      values.core = NULL;
      if( (tmp3 = WlzMakeMain(WLZ_2D_DOMAINOBJ, o1->domain,
			      values, NULL, NULL, &errNum)) == NULL ){
	break;
      }
      old_bckgrnd = WlzGetBackground(o1, NULL);
      switch( WlzGreyTableTypeToGreyType(o1->values.core->type, NULL) ){
      case WLZ_GREY_INT:   /* FALLTHROUGH */
      case WLZ_GREY_SHORT: /* FALLTHROUGH */
      case WLZ_GREY_FLOAT: /* FALLTHROUGH */
      case WLZ_GREY_DOUBLE:
	new_grey_type = WlzGreyTableTypeToGreyType(o1->values.core->type,
						   NULL);
	new_bckgrnd = old_bckgrnd;
	break;	
      case WLZ_GREY_UBYTE:
	new_grey_type = WLZ_GREY_SHORT;
	new_bckgrnd.type = WLZ_GREY_SHORT;
	new_bckgrnd.v.shv = old_bckgrnd.v.ubv;
	break;
      default:
        errNum = WLZ_ERR_OBJECT_TYPE;
	break;
      }
      if(errNum == WLZ_ERR_NONE){
	values.v = WlzNewValueTb(tmp3,
				 WlzGreyTableType(WLZ_GREY_TAB_RAGR,
						  new_grey_type, NULL),
				 new_bckgrnd, &errNum);
	tmp3->values = WlzAssignValues( values, NULL );
      }
      break;

    case WLZ_3D_DOMAINOBJ:
      values.core = NULL;
      if((tmp3 = WlzMakeMain(WLZ_3D_DOMAINOBJ, o1->domain, values,
			     NULL, NULL, &errNum)) == NULL){
	break;
      }

      /* now a new destination voxeltable */
      old_bckgrnd = WlzGetBackground(o1, NULL);
      switch( old_bckgrnd.type ){
      case WLZ_GREY_INT:   /* FALLTHROUGH */
      case WLZ_GREY_SHORT: /* FALLTHROUGH */
      case WLZ_GREY_FLOAT: /* FALLTHROUGH */
      case WLZ_GREY_DOUBLE:
	new_grey_type = old_bckgrnd.type;
	new_bckgrnd = old_bckgrnd;
	break;	
      case WLZ_GREY_UBYTE:
	new_grey_type = WLZ_GREY_SHORT;
	new_bckgrnd.type = WLZ_GREY_SHORT;
	new_bckgrnd.v.shv = old_bckgrnd.v.ubv;
	break;
      default:
        errNum = WLZ_ERR_GREY_TYPE;
	break;
      }
      if(errNum == WLZ_ERR_NONE){
	values.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
					 tmp3->domain.p->plane1,
					 tmp3->domain.p->lastpl,
					 new_bckgrnd, NULL, &errNum);
	if( values.vox == NULL ){break;}

	for(p=tmp3->domain.p->plane1; p <= tmp3->domain.p->lastpl; p++){
	  WlzValues	values2d;

	  /* currently test for NULL domain to imply WLZ_EMPTY_DOMAIN */
	  if( tmp3->domain.p->domains[p-tmp3->domain.p->plane1].core
	     == NULL ){
	    values2d.core = NULL;
	  }
	  else {
	    WlzObject	*tmp2d;
	    values2d.core = NULL;
	    if((tmp2d = WlzMakeMain(WLZ_2D_DOMAINOBJ,
		             tmp3->domain.p->domains[p-tmp3->domain.p->plane1],
		             values2d, NULL, NULL, &errNum)) != NULL){
	      values2d.v = WlzNewValueTb(
		tmp2d, WlzGreyTableType(WLZ_GREY_TAB_RAGR, new_grey_type,
					NULL), new_bckgrnd, &errNum);
	      WlzFreeObj( tmp2d );
	    }
	  }
	  values.vox->values[p-tmp3->domain.p->plane1] = 
	    WlzAssignValues(values2d, NULL);
	}
	tmp3->values = WlzAssignValues(values, NULL);
      }

      break;

    default:
      errNum = WLZ_ERR_OBJECT_TYPE;
      break;
    }
  }

  /* apply operation and free space */
  if((errNum == WLZ_ERR_NONE) && (obj == NULL)){
    if((errNum = WlzScalarBinaryOp(o1, pval, tmp3, op)) != WLZ_ERR_NONE){
      WlzFreeObj( tmp3 );
    }
    else {
      obj = tmp3;
    }
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return obj;
}
Beispiel #25
0
void install_paint_reference_object(
  WlzObject	*obj)
{
  Widget		toggle;
  WlzPixelV		bckgrnd;
  WlzPixelV		min, max, Min, Max;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  if( globals.orig_obj != NULL ){
    WlzFreeObj( globals.orig_obj );
  }
  globals.orig_obj = WlzAssignObject(obj, &errNum);
  obj = NULL;

  /* check input object for grey-value type
     convert if necessary */
  if( errNum == WLZ_ERR_NONE ){
    bckgrnd = WlzGetBackground(globals.orig_obj, &errNum);
    Min.type = WLZ_GREY_INT;
    Max.type = WLZ_GREY_INT;
    Min.v.inv = 0;
    Max.v.inv = 255;
  }
  
  if( errNum == WLZ_ERR_NONE ){
    switch( bckgrnd.type ){
    case WLZ_GREY_LONG:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.lnv < 0) || (max.v.lnv > 255) ){
	if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){
	  WlzGreySetRange(obj, min, max, Min, Max, 0);
	  bckgrnd = WlzGetBackground(obj, &errNum);
	}
      }
      break;
    case WLZ_GREY_INT:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.inv < 0) || (max.v.inv > 255) ){
	obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum);
	WlzGreySetRange(obj, min, max, Min, Max, 0);
	bckgrnd = WlzGetBackground(obj, &errNum);
      }
      break;
    case WLZ_GREY_SHORT:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.shv < 0) || (max.v.shv > 255) ){
	if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_SHORT, &errNum))){
	  WlzGreySetRange(obj, min, max, Min, Max, 0);
	  bckgrnd = WlzGetBackground(obj, &errNum);
	}
      }
      break;
    case WLZ_GREY_FLOAT:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.flv < 0) || (max.v.flv > 255) ){
	if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){
	  WlzGreySetRange(obj, min, max, Min, Max, 0);
	  bckgrnd = WlzGetBackground(obj, &errNum);
	}
      }
      break;
    case WLZ_GREY_DOUBLE:
      WlzGreyRange(globals.orig_obj, &min, &max);
      if( (min.v.dbv < 0) || (max.v.dbv > 255) ){
	if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){
	  WlzGreySetRange(obj, min, max, Min, Max, 0);
	  bckgrnd = WlzGetBackground(obj, &errNum);
	}
      }
      break;

    default:
    case WLZ_GREY_UBYTE:
      break;
    }
  }

  /* copy for later transform for display purposes,
     the original is kept for IP purposes note pixconvert loses
     the background value */
  if( errNum == WLZ_ERR_NONE ){
    if( globals.obj != NULL ){
      WlzFreeObj( globals.obj );
    }
    if( obj ){
      globals.obj =
	WlzAssignObject(WlzConvertPix(obj, WLZ_GREY_UBYTE, &errNum), NULL);
      WlzFreeObj(globals.orig_obj);
      globals.orig_obj = WlzAssignObject(obj, NULL);
    }
    else {
      globals.obj =
	WlzAssignObject(WlzConvertPix(globals.orig_obj,
				      WLZ_GREY_UBYTE, &errNum), NULL);
    }
  }

  if( errNum == WLZ_ERR_NONE ){
    min.type = WLZ_GREY_UBYTE;
    max.type = WLZ_GREY_UBYTE;
    Min.type = WLZ_GREY_UBYTE;
    Max.type = WLZ_GREY_UBYTE;
    min.v.ubv = 0;
    max.v.ubv = 255;
    Min.v.ubv = globals.cmapstruct->gmin;
    Max.v.ubv = globals.cmapstruct->gmax;
    errNum = WlzGreySetRange(globals.obj, min, max, Min, Max, 0);
  }

  /* also convert the background values */
  if( errNum == WLZ_ERR_NONE ){
/*  min = WlzGetBackground(globals.orig_obj, NULL);*/
    WlzValueConvertPixel(&bckgrnd, bckgrnd, WLZ_GREY_INT);
    max.type = WLZ_GREY_INT;
    max.v.inv = ((bckgrnd.v.inv * (Max.v.ubv - Min.v.ubv)) / 255) + Min.v.ubv;
    WlzSetBackground(globals.obj, max);

    /* fill blank planes here - should be a resource option */
    if( (toggle = XtNameToWidget(read_obj_dialog, "*.fill_blanks")) ){
      Boolean	fill_blanks, min_domain;
      XtVaGetValues(toggle, XmNset, &fill_blanks, NULL);
      if( fill_blanks ){
	if( (toggle = XtNameToWidget(read_obj_dialog, "*.min_domain")) ){
	  XtVaGetValues(toggle, XmNset, &min_domain, NULL);
	  if( min_domain ){
	    WlzFillBlankPlanes(globals.obj, 1);
	  } else {
	    WlzFillBlankPlanes(globals.obj, 0);
	  }
	}
	else {
	  WlzFillBlankPlanes(globals.obj, 1);
	}
      }
    }

    /* setup the display list and properties dialog */
    setup_ref_display_list_cb(read_obj_dialog, NULL, NULL);
    setup_obj_props_cb(read_obj_dialog, NULL, NULL);
  }

  /* log the object size */
  if( (errNum == WLZ_ERR_NONE) && globals.logfileFp ){
    char strBuf[64];
    sprintf(strBuf, "(%d, %d, %d, %d, %d, %d)",
	    globals.obj->domain.p->kol1, globals.obj->domain.p->line1,
	    globals.obj->domain.p->plane1, globals.obj->domain.p->lastkl,
	    globals.obj->domain.p->lastln, globals.obj->domain.p->lastpl);
    MAPaintLogData("BoundingBox", strBuf, 0, NULL);
    sprintf(strBuf, "%d", (int) WlzVolume(globals.obj, NULL));
    MAPaintLogData("Volume", strBuf, 0, NULL);
  }

  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl,
			  "install_paint_reference_object", errNum);
  }
  return;
}
/*!
* \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);
}
Beispiel #27
0
/*!
* \return	New object or NULL on error.
* \ingroup	WlzValuesUtils
* \brief 	Transfers grey values from the source object to the
*               destination object within the intersection of the source
*               and destination. Grey values within the destination
*               object outside of the source object are unchanged.
*               It is an error if either object has a different dimension
*               or grey value type, except for when either is an empty
*               object.
* \param	dObj			Destination object which may be
* 					empty, but otherwise should be of the
* 					same dimension as the source object
* 					with valid values..
* \param	sObj			Source object which if not empty must
* 					have both a valid domain and valid
* 					values.
* \param	inplace			Overwrite the destination object's
* 					values if non zero.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject			*WlzGreyTransfer(
				  WlzObject *dObj,
				  WlzObject *sObj,
				  int inplace,
				  WlzErrorNum *dstErr)
{
  WlzObject	*rObj = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if((dObj == NULL) || (sObj == NULL))
  {
    errNum = WLZ_ERR_OBJECT_NULL;
  }
  else if(WlzIsEmpty(dObj, NULL))
  {
    rObj = WlzMakeEmpty(&errNum);
  }
  else if(WlzIsEmpty(sObj, NULL))
  {
    rObj = WlzMakeMain(dObj->type, dObj->domain, dObj->values,
                       dObj->plist, NULL, &errNum);
  }
  else if(dObj->type != sObj->type)
  {
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  else if((dObj->domain.core == NULL) || (sObj->domain.core == NULL))
  {
    errNum = WLZ_ERR_DOMAIN_NULL;
  }
  else if(sObj->values.core == NULL)
  {
    errNum = WLZ_ERR_VALUES_NULL;
  }
  else
  {
    switch(sObj->type)
    {
      case WLZ_2D_DOMAINOBJ:
      case WLZ_3D_DOMAINOBJ: /* FALLTHROUGH */
        {
	  WlzObject	*rIObj = NULL;

	  rIObj = WlzIntersect2(dObj, sObj, &errNum);
	  if((errNum == WLZ_ERR_NONE) && (WlzIsEmpty(rIObj, NULL) == 0))
	  {
	    rObj = (inplace)?
		   WlzMakeMain(dObj->type, dObj->domain, dObj->values,
			       dObj->plist, NULL, &errNum):
		   WlzCopyObject(dObj, &errNum);
	    if(errNum == WLZ_ERR_NONE)
	    {
	      /* If the destination object does not have values then
	       * create them to match the domain of the destination
	       * object. */
	      if((sObj->values.core != NULL) && (rObj->values.core == NULL))
	      {
		WlzPixelV bgdV;
		WlzGreyType gType;
		WlzObjectType gTT;
		WlzValues	newVal;

		newVal.core = NULL;
		bgdV = WlzGetBackground(sObj, &errNum);
		if(errNum == WLZ_ERR_NONE)
		{
		  gType = WlzGreyTypeFromObj(sObj, &errNum);
		}
		if(errNum == WLZ_ERR_NONE)
		{
		  gTT = WlzGreyTableType(WLZ_GREY_TAB_RAGR, gType, NULL);
		  if(rObj->type == WLZ_2D_DOMAINOBJ)
		  {
		    newVal.v = WlzNewValueTb(rObj, gTT, bgdV, &errNum);
		  }
		  else /* rObj->type == WLZ_3D_DOMAINOBJ */
		  {
		    newVal.vox = WlzNewValuesVox(rObj, gTT, bgdV, &errNum);
		  }
		}
		if(errNum == WLZ_ERR_NONE)
		{
		  rObj->values = WlzAssignValues(newVal, NULL);
		}
		if(errNum == WLZ_ERR_NONE)
		{
		  errNum = WlzGreySetValue(rObj, bgdV);
		}
	      }
	    }
	    if(errNum == WLZ_ERR_NONE)
	    {
	      if(sObj->type == WLZ_2D_DOMAINOBJ)
	      {
		WlzObject *sIObj;

		rIObj->values = WlzAssignValues(rObj->values, NULL);
		sIObj = WlzMakeMain(WLZ_2D_DOMAINOBJ,
				    rIObj->domain, sObj->values,
				    NULL, NULL, &errNum);
		if(errNum == WLZ_ERR_NONE)
		{
		  errNum = WlzGreyTransfer2D(rIObj, sIObj);
		}
		(void )WlzFreeObj(sIObj);
	      }
	      else /* sObj->type == WLZ_3D_DOMAINOBJ */
	      {
		int	p,
			  rTiled,
			  sTiled,
			  nPlanes;

		rTiled = WlzGreyTableIsTiled(rObj->values.core->type);
		sTiled = WlzGreyTableIsTiled(sObj->values.core->type);
		nPlanes = rIObj->domain.p->lastpl - rIObj->domain.p->plane1 + 1;
#ifdef _OPENMP
#pragma omp parallel for
#endif
		for(p = 0; p < nPlanes; ++p)
		{
		  if(errNum == WLZ_ERR_NONE)
		  {
		    int	     pln;
		    WlzDomain  dom;
		    WlzValues  val;
		    WlzObject  *rIObj2D = NULL,
			       *sIObj2D = NULL;
		    WlzErrorNum errNum2D = WLZ_ERR_NONE;

		    pln = p + rIObj->domain.p->plane1;
		    dom = rIObj->domain.p->domains[p];
		    val = (rTiled)?
			  rObj->values:
			  rObj->values.vox->values[pln -
						   rObj->values.vox->plane1];
		    rIObj2D = WlzMakeMain(WLZ_2D_DOMAINOBJ,
					  dom, val, NULL, NULL, &errNum2D);
		    if(errNum2D == WLZ_ERR_NONE)
		    {
		      val = (sTiled)?
			    sObj->values:
			    sObj->values.vox->values[pln -
						     sObj->values.vox->plane1];
		      sIObj2D = WlzMakeMain(WLZ_2D_DOMAINOBJ,
					    dom, val, NULL, NULL, &errNum2D);
		    }
		    if(errNum2D == WLZ_ERR_NONE)
		    {
		      errNum2D = WlzGreyTransfer2D(rIObj2D, sIObj2D);
		    }
		    (void )WlzFreeObj(rIObj2D);
		    (void )WlzFreeObj(sIObj2D);
#ifdef _OPENMP
#pragma omp critical
		    {
#endif
		      if((errNum == WLZ_ERR_NONE) && (errNum2D != WLZ_ERR_NONE))
		      {
			errNum = errNum2D;
		      }
#ifdef _OPENMP
		    }
#endif
		  }
		}
	      }
	    }
	  }
	  (void )WlzFreeObj(rIObj);
	}
	break;
      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
        break;
    }
  }
  if(errNum != WLZ_ERR_NONE)
  {
    WlzFreeObj(rObj);
    rObj = NULL;
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(rObj);
}
/*!
* \return	New woolz object or NULL on error.
* \ingroup	WlzArithmetic
* \brief	Scales the values of the given 3D Woolz object so that
* 		\f$v_{new} = m v_{given} + a.\f$ The input object is known
* 		to be a valid 3D 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 *WlzScalarMulAdd3D(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 = WlzGreyTableType(WLZ_GREY_TAB_RAGR, rGType, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    rValues.vox = WlzNewValuesVox(iObj, rVType, bgdV, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    int		idP,
    		plMin,
    		plMax;
    WlzPlaneDomain *iPDom;
    WlzVoxelValues *iVox,
    		*rVox;

    iPDom = iObj->domain.p;
    iVox = iObj->values.vox;
    rVox = rValues.vox;
    plMin = iPDom->plane1;
    plMax = iPDom->lastpl;
#ifdef _OPENMP
#pragma omp parallel for
#endif
    for(idP = plMin; idP <= plMax; ++idP)
    {
      WlzErrorNum errNum2D = WLZ_ERR_NONE;

      if(errNum == WLZ_ERR_NONE)
      {
	int	      idO;
	WlzDomain *iDom2D;
	WlzValues *iVal2D,
		  *rVal2D;

	idO = idP - iPDom->plane1;
	iDom2D = iPDom->domains + idO;
	iVal2D = iVox->values + idO;
	rVal2D = rVox->values + idO;
	if(((*iDom2D).core != NULL) && ((*iVal2D).core != NULL) &&
	   ((*rVal2D).core != NULL))
	{
	  WlzObject *iObj2D = NULL,
		    *rObj2D = NULL;
	  
	  if((iObj2D = WlzMakeMain(WLZ_2D_DOMAINOBJ, *iDom2D, *iVal2D,
				   NULL, NULL, &errNum2D)) != NULL)
	  {
	    rObj2D = WlzScalarMulAdd2D(iObj2D, m, a, rGType, &errNum2D);
	  }
	  if(errNum2D == WLZ_ERR_NONE)
	  {
	    *rVal2D = WlzAssignValues(rObj2D->values, NULL);
	  }
	  (void )WlzFreeObj(iObj2D);
	  (void )WlzFreeObj(rObj2D);
	}
      }
      if(errNum2D != WLZ_ERR_NONE)
      {
#ifdef _OPENMP
#pragma omp critical
	{
#endif
	  if(errNum == WLZ_ERR_NONE)
	  {
	    errNum = errNum2D;
	  }
#ifdef _OPENMP
	}
#endif
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    rObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, iObj->domain, rValues,
    		       iObj->plist, iObj->assoc, &errNum);
  }
  if(errNum != WLZ_ERR_NONE)
  {
    if(rObj == NULL)
    {
      (void )WlzFreeVoxelValueTb(rValues.vox);
    }
    else
    {
      (void )WlzFreeObj(rObj);
      rObj = NULL;
    }
  }
  if(dstErr != NULL)
  {
    *dstErr = errNum;
  }
  return(rObj);
}
Beispiel #29
0
/*!
* \return	New 3D object.
* \ingroup	WlzAllocation
* \brief	Constructs a 3D domain object from 2D domain objects read
*		from the given files. Each file is read in turn and added
*		to the 3D object. An empty plane can be specified by
*		setting the file string to NULL. Either all or none of
*		the 2D objects must have values. When the 2D objects
*		have values then the background value of the first 2D
*		object is set to be the background value of the 3D object.
* \param	nFileStr		Number of file strings.
* \param	fileStr			File strings.
* \param	plane1			The plane coordinate of the first
*					2D object.
* \param	xSz			Column voxel size.
* \param	ySz			Line voxel size.
* \param	zSz			Plane voxel size.
* \param	dstErr			Destination error pointer, may be NULL.
*/
WlzObject	*WlzConstruct3DObjFromFile(int nFileStr, char **fileStr,
					  int plane1,
					  float xSz, float ySz, float zSz,
					  WlzErrorNum *dstErr)
{
  int		idx,
  		lastpl;
  WlzDomain	dom3D;
  WlzValues	val3D;
  WlzObject	*obj2D = NULL,
  		*obj3D = NULL;
  WlzPixelV	bgd;
  FILE		*fP = NULL;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  dom3D.core = NULL;
  val3D.core = NULL;
  lastpl = plane1 + nFileStr - 1;
  if((nFileStr <= 0) || (fileStr == NULL) || (*fileStr == NULL))
  {
    errNum = WLZ_ERR_PARAM_NULL;
  }
  else
  {
    if((fP = fopen(*fileStr, "r")) == NULL)
    {
      errNum = WLZ_ERR_READ_EOF;
    }
    else
    {
      obj2D = WlzReadObj(fP, &errNum);
      (void )fclose(fP);
      fP = NULL;
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    switch(obj2D->type)
    {
      case WLZ_EMPTY_OBJ:
	break;
      case WLZ_2D_DOMAINOBJ:
	if(obj2D->domain.core == NULL)
	{
	  errNum = WLZ_ERR_DOMAIN_NULL;
	}
	break;
      default:
	errNum = WLZ_ERR_OBJECT_TYPE;
	break;
    }
  }
  /* Make a plane domain, set column and line bounds later. */
  if(errNum == WLZ_ERR_NONE)
  {
    dom3D.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN,
    				 plane1, lastpl,
				 0, 1, 0, 1, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    dom3D.p->voxel_size[0] = xSz;
    dom3D.p->voxel_size[1] = ySz;
    dom3D.p->voxel_size[2] = zSz;
  }
  /* Make a voxel value table. */
  if(errNum == WLZ_ERR_NONE)
  {
    if(obj2D->values.core)
    {
      bgd = WlzGetBackground(obj2D, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	val3D.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
					plane1, lastpl, bgd, NULL, &errNum);
      }
    }				    
  }
  idx = 0;
  while((errNum == WLZ_ERR_NONE) && (idx < nFileStr))
  {
    if(obj2D)
    {
      switch(obj2D->type)
      {
	case WLZ_EMPTY_OBJ:
	  break;
	case WLZ_2D_DOMAINOBJ:
	  if(obj2D->domain.core == NULL)
	  {
	    errNum = WLZ_ERR_DOMAIN_NULL;
	  }
	  break;
	default:
	  errNum = WLZ_ERR_OBJECT_TYPE;
	  break;
      }
      if(errNum == WLZ_ERR_NONE)
      {
	*(dom3D.p->domains + idx) = WlzAssignDomain(obj2D->domain, NULL);
	if(val3D.core)
	{
	  if((obj2D->domain.core != NULL) && (obj2D->values.core == NULL))
	  {
	    errNum = WLZ_ERR_VALUES_NULL;
	  }
	  else
	  {
	    *(val3D.vox->values + idx) = WlzAssignValues(obj2D->values, NULL);
	  }
	}
      }
      WlzFreeObj(obj2D);
      obj2D = NULL;
    }
    if(errNum == WLZ_ERR_NONE)
    {
      ++idx;
      if((idx < nFileStr) && *(fileStr + idx))
      {
	if((fP = fopen(*(fileStr + idx), "r")) == NULL)
	{
	  errNum = WLZ_ERR_READ_EOF;
	}
	else
	{
	  obj2D = WlzReadObj(fP, &errNum);
	  (void )fclose(fP);
	  fP = NULL;
	}
      }
    }
  }
  if(errNum == WLZ_ERR_NONE)
  {
    errNum = WlzStandardPlaneDomain(dom3D.p, val3D.vox);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    obj3D = WlzMakeMain(WLZ_3D_DOMAINOBJ, dom3D, val3D, NULL, NULL, &errNum);
  }
  if(errNum != WLZ_ERR_NONE)
  {
    if(dom3D.core)
    {
      (void )WlzFreeDomain(dom3D);
    }
    if(val3D.core)
    {
      (void )WlzFreeValues(val3D);
    }
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(obj3D);
}
Beispiel #30
0
/*!
* \return	New Woolz domain object with gradient grey values or NULL
*		on error.
* \ingroup      WlzValuesFilters
* \brief	Computes the magnitude of the gray values in the
*               3 given Woolz 3D domain objects.
* \param	srcObj0			First object.
* \param	srcObj1			Second object.
* \param	srcObj2			Third object.
* \param	dstErr			Destination error pointer, may
*                                       be null.
*/
static 	WlzObject *WlzGreyMagnitude3D(WlzObject *srcObj0, WlzObject *srcObj1,
				      WlzObject *srcObj2, WlzErrorNum *dstErr)
{
  int		idN,
		idP,
  		nPlanes;
  WlzDomain	dstDom;
  WlzValues	dstVal;
  WlzObject	*dstObj2D,
  		*istObj = NULL,
		*dstObj = NULL;
  WlzObject	*srcObjA[3],
  		*iObj3DA[3],
  		*iObj2DA[3];
  WlzPixelV	bgdV;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  dstDom.core = NULL;
  dstVal.core = NULL;
  iObj3DA[0] = iObj3DA[1] = iObj3DA[2] = NULL;
  if((srcObj0->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN) ||
     (srcObj1->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN) ||
     (srcObj2->domain.core->type != WLZ_PLANEDOMAIN_DOMAIN))
  {
    errNum = WLZ_ERR_DOMAIN_TYPE;
  }
  else if ((srcObj0->values.core->type != WLZ_VOXELVALUETABLE_GREY) ||
           (srcObj1->values.core->type != WLZ_VOXELVALUETABLE_GREY) ||
	   (srcObj2->values.core->type != WLZ_VOXELVALUETABLE_GREY))
  {
    errNum = WLZ_ERR_VALUES_TYPE;
  }
  else
  {
    srcObjA[0] = srcObj0;
    srcObjA[1] = srcObj1;
    srcObjA[2] = srcObj2;
    istObj = WlzIntersectN(3, srcObjA, 0, &errNum);
  }
  if(errNum == WLZ_ERR_NONE)
  {
    if(istObj->type == WLZ_EMPTY_OBJ)
    {
      dstObj = istObj;
    }
    else
    {
      dstDom = WlzAssignDomain(istObj->domain, NULL);
      WlzFreeObj(istObj);
      idN = 0;
      while((errNum == WLZ_ERR_NONE) && (idN < 3))
      {
        iObj3DA[idN] = WlzMakeMain(WLZ_3D_DOMAINOBJ,
				   dstDom, srcObjA[idN]->values,
				   NULL, NULL, &errNum);
        ++idN;
      }
      if(errNum == WLZ_ERR_NONE)
      {
	idP = 0;
        nPlanes = dstDom.p->lastpl - dstDom.p->plane1 + 1;
	while((errNum == WLZ_ERR_NONE) &&
	      (idP < nPlanes))
        {
	  if((dstDom.p->domains + idN)->core == NULL)
	  {
	    (dstVal.vox->values + idP)->core = NULL;
	  }
	  else
	  {
	    dstObj2D = NULL;
	    iObj2DA[0] = iObj2DA[1] = iObj2DA[2] = NULL;
	    idN = 0;
	    /* Make 2D objects. */
	    while((errNum == WLZ_ERR_NONE) && (idN < 3))
	    {
	      iObj2DA[idN] = WlzMakeMain(WLZ_2D_DOMAINOBJ,
				    *(iObj3DA[idN]->domain.p->domains + idP),
				    *(iObj3DA[idN]->values.vox->values + idP),
				    NULL, NULL, &errNum);
	      ++idN;
	    }
	    /* Compute magnitude. */
	    if(errNum == WLZ_ERR_NONE)
	    {
	      dstObj2D = WlzGreyMagnitude2D3(iObj2DA[0], iObj2DA[1],
					     iObj2DA[2], &errNum);
	    }
	    /* If first plane get grey type and background, then create new
	     * 3D object with new voxel values. */
	    if((idP == 0) && (errNum == WLZ_ERR_NONE))
	    {
      	      bgdV = WlzGetBackground(iObj2DA[0], &errNum);
	      if(errNum == WLZ_ERR_NONE)
	      {
		dstVal.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
						 dstDom.p->plane1,
						 dstDom.p->lastpl,
						 bgdV, NULL, &errNum);
	      }
	      if(errNum == WLZ_ERR_NONE)
	      {
	        dstObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, dstDom, dstVal,
				     NULL, NULL, &errNum);
	      }
	    }
	    /* Add 2D values to the 3D objects values. */
	    if(errNum == WLZ_ERR_NONE)
	    {
	      *(dstVal.vox->values + idP) = WlzAssignValues(dstObj2D->values,
	      						    NULL);
	    }
	    /* Free temporary 2D object. */
	    if(dstObj2D)
	    {
	      WlzFreeObj(dstObj2D);
	    }
	    idN = 0;
	    while(idN < 3)
	    {
	      if(iObj2DA[idN])
	      {
		WlzFreeObj(iObj2DA[idN]);
	      }
	      ++idN;
	    }
	  }
	  ++idP;
	}
      }
      /* Free 3D intersection gradient objects. */
      idN = 0;
      while(idN < 3)
      {
	if(iObj3DA[idN])
	{
	  WlzFreeObj(iObj3DA[idN]);
	}
	++idN;
      }
      /* Decrement link count to the destination 3D domain. */
      (void )WlzFreeDomain(dstDom);
    }
  }
  if((errNum != WLZ_ERR_NONE) && (dstObj != NULL))
  {
    WlzFreeObj(dstObj);
    dstObj = NULL;
  }
  if(dstErr)
  {
    *dstErr = errNum;
  }
  return(dstObj);
}