hdf5_iprimitive::read_hdf5_dataset
(
    std::wstring* t,
    std::size_t data_count,
    std::size_t object_number
)
{
    BOOST_ASSERT(data_count == 1);
    std::string path = create_object_data_path(object_number);
    hdf5_dataset dataset(*file_, path);
    hdf5_datatype datatype(dataset);

    // If you can think of a better way to store wchar_t/wstring objects in HDF5, be my guest...
    size_t size = datatype.get_size();

	BOOST_ASSERT(size >= sizeof(wchar_t));
    std::size_t string_size = size / sizeof(wchar_t) - 1;

	t->resize(string_size);
	if(string_size) {
		std::vector<wchar_t> buffer(string_size + 1);
		dataset.read(datatype, &buffer[0]);

        t->replace(0, string_size, &buffer[0], string_size);
	}

    datatype.close();
    dataset.close();
}
Beispiel #2
0
void write_int_data(std::string const& filename, array_2d_t const& array)
{
    h5xx::file file(filename, h5xx::file::trunc);
    std::string name;

    // (1) create and write chunked and compressed dataset
    {
        name = "integer array";
        std::vector<size_t> chunk_dims(2,2);
        // derive dataspace and datatype from the array internally
        h5xx::create_dataset(file, name, array
          , h5xx::policy::storage::chunked(chunk_dims)  /* optional argument */
                .add(h5xx::policy::filter::deflate())
        );
        h5xx::write_dataset(file, name, array);
    }

    // (2) create and write a dataset, using default settings,
    //     explicitly derive dataspace and datatype from input arrray
    {
        name = "integer array, 2";
        // construct dataspace from a Boost multi_array
        h5xx::dataspace dataspace = h5xx::create_dataspace(array);
        // pull datatype from a Boost multi_array
        h5xx::datatype datatype(array);
        h5xx::create_dataset(file, name, datatype, dataspace);
        h5xx::write_dataset(file, name, array);
    }
}
Beispiel #3
0
/**
 * @SYMTestCaseID T_ServicesTestStep_TestServiceDiscovery28L
 *
 * @SYMPREQ 538
 *
 * @SYMTestCaseDesc Test the functionality of GetServiceImplementationsLC 
 * which gets all the implementation details about a specific service 
 * @SYMTestPriority 
 *
 * @SYMTestStatus Implemented
 * 
 * @SYMTestActions Call GetServiceImplementationsLC with the service uid as parameter
 * on z: drive.\n
 * API Calls:\n	
 * RApaLsSession::GetServiceImplementationsLC(TUid aServiceUid, const TDataType& aDataType) const
 * 
 * @SYMTestExpectedResults Returns an array of TApaAppServiceInfo objects. 
 * The size of the array is equal to the number of apps offering the specified service that
 * also handles the speficied datatype. 
 * Each TApaAppServiceInfo contain an app uid and  the respective opaquedata. 
 * The returned data should be the same as that defined in the registration files.
 *  
 */
void CT_ServicesTestStep::TestServiceDiscovery28L()
	{
	INFO_PRINTF1(_L("TestServiceDiscovery28 about to start..."));
	const TUid KUidService1234 = {0x01020304};
	//const TUid KUidServerApp1 = {0x10004c56};
	const TUid KUidServerApp2 = {0x10004c57};
	
	TDataType datatype(KLitCustom1Text);
	CApaAppServiceInfoArray* array = iApaLsSession.GetServiceImplementationsLC(KUidService1234, datatype);
	TArray<TApaAppServiceInfo> implArray(array->Array());
	TInt count = implArray.Count();	
	TEST(count==1);
	_LIT(KService,"Non-localised text for service uid 0x01020304");
	TPtrC8 opaqueData;
	TResourceReader reader;
	TPtrC16 theText;
	TInt val(0);
	TUid myuid = implArray[0].Uid(); 
	TEST(myuid==KUidServerApp2);
	const CArrayFixFlat<TDataTypeWithPriority>& datatypes = implArray[0].DataTypes();
	TEST(datatypes.Count()==1);
	TEST(0 == datatypes[0].iDataType.Des8().CompareF(KLitCustom1Text));
	opaqueData.Set(implArray[0].OpaqueData());
	reader.SetBuffer(&opaqueData); // opaqueData is an LTEXT resource
	theText.Set(reader.ReadTPtrC16());
	User::LeaveIfError(val = theText.Compare(KService));
	TEST(val==KErrNone);
	CleanupStack::PopAndDestroy(array);
	array = NULL;
	}
void CRUDupElimSQLComposer::ComposeIUDUpdateBitmapText()
{
	CDSString pred;
	sql_ += "UPDATE " + iudLogName_;
	
	const CRULogCtlColDesc &desc = 
		iudLogCtlColDescVec[CRUDupElimConst::OFS_UPD_BMP];

	// Compose the real datatype 
	// of the @UPDATE_BITMAP column - CHAR(<size>)
	CDSString datatype(desc.datatype_);

	RUASSERT(updateBmpSize_ > 0);
	datatype += "(" + TInt32ToStr(updateBmpSize_) + ")";

	// -------------------------------------------------------------
    // Date: 2008-03-19  Caroline:
	// In UNICODE config: ISO_MAPPING=UTF8, DEFAULT_CHARSET= UCS2
	// The IUD_LOG_TABLE Clause: 
	//       SET "@UPDATE_BITMAP" = CAST (? AS CHAR(8)) 
	// The "@UPDATE_BITMAP" column is in ISO88591, and the CAST Clause 
	// is implied to UCS2, so we got the incompatible error. 
	// To fix the error, we explicitly say "CHARACTER SET ISO88591".

	datatype += " CHARACTER SET ISO88591 ";
	//---------------------------------------------

	sql_ += "\nSET " + ComposeQuotedColName(desc.name_) + " = ";
	sql_ += ComposeCastExpr(datatype);		

	ComposeUpdateRecsSearchPredicate(pred);
	sql_+= pred + ";";
}
hdf5_iprimitive::read_hdf5_dataset
(
    std::string* t,
    std::size_t data_count,
    std::size_t object_number
)
{
    BOOST_ASSERT(data_count == 1);
    std::string path = create_object_data_path(object_number);
    hdf5_dataset dataset(*file_, path);
    hdf5_datatype datatype(dataset);

    if(datatype.is_variable_length_string()) {
        char* buffer;
        hdf5_dataspace dataspace(dataset);
        dataset.read(datatype, &buffer);
        *t = buffer;
        datatype.reclaim_buffer(dataspace, &buffer);
        dataspace.close();
    }
    else {
        size_t size = datatype.get_size();
        std::vector<char> buffer(size);
        dataset.read(datatype, &buffer[0]);
        t->resize(size);
        t->replace(0, size, &buffer[0], size);
    }

    datatype.close();
    dataset.close();
}
Beispiel #6
0
//6.<变量定义语句>—> var id [ , id ] as <数据类型> ;
void varDefinition(){
	match(var);
	char varname[MAXIDLEN];
	strcpy(varname, token);

	match(id);

	int cnt = 1;
	if (!enter(varname)){
		strcpy(token, varname);
		error(47);
	}


	while (lookahead == comma){
		match(comma);

		strcpy(varname, token);
		match(id);
		cnt++;
		if (!enter(varname)){
			strcpy(token,varname);
			error(47);
		}
	}
	match(as);

	int typetmp = datatype();
	for (int i = 1; i <= cnt; i++){
		comtabs[comtabs.size() - i].type = typetmp;
	}

	match(semicolon);
}
Beispiel #7
0
//3.<参数列表>—> ( id as <数据类型> [,id as <数据类型>] ) |ε
void parameter(){
	if (lookahead == LP){
		match(LP);

		char tmpname[MAXIDLEN];
		strcpy(tmpname, token);

		match(id);
		//在表中插入定义的变量
		if (!enter(tmpname)){
			strcpy(token, tmpname);
			error(47);
		}

		match(as);

		int tmptype = datatype();
		comtabs.back().type = tmptype;
		comtabs.back().funid = curfunc;
		funtabs.back().para.push_back(tmptype); //函数表中添加形参类型
		
		while (lookahead == comma){
			
			match(comma);
			
			strcpy(tmpname, token);
			
			match(id);
			//在表中插入定义的变量
			if (!enter(tmpname)){
				strcpy(token, tmpname);
				error(47);
			}

			match(as);

			int tmptype = datatype();
			comtabs.back().type = tmptype;
			comtabs.back().funid = curfunc;
			funtabs.back().para.push_back(tmptype);
		}

		match(RP);

	}
}
Beispiel #8
0
int tosql_main(int argc, char **argv) {
    std::string bedFile;
    std::string genomeFile;
    std::string sqlFile;
    std::string all_fields("start,end,name,score");
    std::string datatype("qualitative");
    bool haveBed = false;
    bool haveGenome = false;
    bool haveSql = false;
    bool showHelp = false;
    for ( int i=1; i<argc; i++ ) {
        int parameterLength = (int)strlen(argv[i]);
        if (PARAMETER_CHECK("-a", 2, parameterLength)) {
	    i++;
            if (i < argc) {
                haveBed = true;
                bedFile = std::string(argv[i]);
            }
        } else if (PARAMETER_CHECK("-g", 2, parameterLength)) {
	    i++;
            if (i < argc) {
                haveGenome = true;
                genomeFile = std::string(argv[i]);
            } 
        } else if (PARAMETER_CHECK("-o", 2, parameterLength)) {
	    i++;
            if (i < argc) {
                haveSql = true;
                sqlFile = std::string(argv[i]);
            } 
        } else if (PARAMETER_CHECK("-f", 2, parameterLength)) {
	    i++;
            if (i < argc) {
		all_fields = std::string(argv[i]);
            }
        } else if (PARAMETER_CHECK("-t", 2, parameterLength)) {
	    i++;
            if (i < argc) {
		datatype = std::string(argv[i]);
            }
        } else {
	    std::cerr << "\n*****ERROR: Unrecognized parameter: " << argv[i] 
		      << " *****\n\n";
            showHelp = true;
        }
    }
    if (!(haveBed && haveGenome && haveSql)) {
        std::cerr << "\n*****\n*****ERROR: Need -a, -g and -o files. \n*****\n";
        showHelp = true;
    }
    if (showHelp) {
        tosql_help();
    } else {
        ToSql *tosql = new ToSql( bedFile, genomeFile, sqlFile, all_fields, datatype );
        delete tosql;
    }
    return 0;
}
Beispiel #9
0
	bool MOBLFormat::Probe(MOBLReadOptions& readoptions, std::istream& is) throw(MotionFileException)
	{
		/*
	 * The signature block is stored at the beginning of a motion bundle file so the file
	 * format can easily be identified.  The signature is the bson encoding of one of
	 * the following JSON statements:
	 * 
	 * { "CODABUNDLE" : 1 }
	 * { "CODAGZNDLE" : 1 }
	 * 
	 * This means the data structure is:
	 * 
	 * UInt32 Size          : 21  (total size of this signature block as little-endian)
	 * UInt8  DataType      : 16 (0x10, means a BSON cstring text key with corresponding int32 value)
	 * UInt8  FormatID[10]  : "CODABUNDLE" or "CODAGZUNDLE" as ASCII
	 * UInt8  FormatIDTerm  : 0 (BSON terminator for the format id string)
	 * UInt32 FormatVersion : 1
	 * UInt8  SignatureTerm : 0 (BSON terminator for the signature block)
	 */

		// init to zero
		readoptions.FormatVersion = 0;

		// read header
		UInt32 size(0);
		char formatid[11];
		is.read((char*)&size, 4);
		if (size == 21)
		{
			UInt8 datatype(0);
			is.read((char*)&datatype, 1);
			if (datatype == 0x10)
			{
				is.read(formatid, 11);
				is.read((char*)&readoptions.FormatVersion.Value(), 4);
			}
		}

		// must have valid format
		if (readoptions.FormatVersion < 1)
			return false;

		// must be recognised format label
		if (strncmp(formatid, "CODABUNDLE", 11) == 0)
		{
			readoptions.UseGZIP = false;
		}
		else if (strncmp(formatid, "CODAGZNDLE", 11) == 0)
		{
			readoptions.UseGZIP = true;
		}
		else
		{
			return false;
		}

		return true;
	}
Beispiel #10
0
/* ==================================== */
void lshowpoint(struct xvimage * image1, int32_t x, int32_t y, int32_t z)
/* ==================================== */
#undef F_NAME
#define F_NAME "lshowpoint"
{
  int32_t rs, cs, ds, ps;

  rs = rowsize(image1);
  cs = colsize(image1);
  ds = depth(image1);
  ps = rs * cs;
  
  if (datatype(image1) == VFF_TYP_1_BYTE)
  {
    uint8_t *pt1 = UCHARDATA(image1);
#ifdef DEBUG
    printf("rs=%d cs=%d ds=%d type=byte x=%d y=%d z=%d\n", rs, cs, ds, x, y, z);
#endif
    printf("%d\n", pt1[z * ps + y * rs + x]);
  }
  else
  if (datatype(image1) == VFF_TYP_4_BYTE)
  {
    int32_t *pt1 = SLONGDATA(image1);
#ifdef DEBUG
  printf("rs=%d cs=%d ds=%d type=long x=%d y=%d z=%d\n", rs, cs, ds, x, y, z);
#endif
    printf("%ld\n", (long int)pt1[z * ps + y * rs + x]);
  }
  else
  if (datatype(image1) == VFF_TYP_FLOAT)
  {
    float *pt1 = FLOATDATA(image1);
#ifdef DEBUG
  printf("rs=%d cs=%d ds=%d type=float x=%d y=%d z=%d\n", rs, cs, ds, x, y, z);
#endif
    printf("%g\n", pt1[z * ps + y * rs + x]);
  }
  else
  {
    fprintf(stderr, "%s: bad data type\n", F_NAME);
    return;
  }

} // lshowpoint()
Beispiel #11
0
//--------------------------------------------------------------------------
// Function:	CompType::getMemberDataType
///\brief	Returns the generic datatype of the specified member in this
///		compound datatype.
///\param	member_num - IN: Zero-based index of the member
///\return	DataType instance
///\exception	H5::DataTypeIException
// Programmer	Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
DataType CompType::getMemberDataType( unsigned member_num ) const
{
   try {
      DataType datatype(p_get_member_type(member_num));
      return(datatype);
   }
   catch (DataTypeIException E) {
      throw DataTypeIException("CompType::getMemberDataType", E.getDetailMsg());
   }
}
Beispiel #12
0
/* ==================================== */
int32_t lselndg(struct xvimage * image, int32_t inf, int32_t sup)               
/* on selectionne les pixels x tels que inf <= x <= sup */
/* ==================================== */
#undef F_NAME
#define F_NAME "lselndg"
{
  int32_t i;
  int32_t rs = rowsize(image);     /* taille ligne */
  int32_t cs = colsize(image);     /* taille colonne */
  int32_t d = depth(image);        /* nb plans */
  int32_t n = rs * cs;             /* taille plan */
  int32_t N = n * d;               /* taille image */
  
  /* ---------------------------------------------------------- */
  /* calcul du resultat */
  /* ---------------------------------------------------------- */

  if (datatype(image) == VFF_TYP_1_BYTE)
  {
    uint8_t *pt;
    for (pt = UCHARDATA(image), i = 0; i < N; i++, pt++)
      if ((*pt >= inf) && (*pt <= sup)) *pt = NDG_MAX; else *pt = NDG_MIN;
  }
  else
  if (datatype(image) == VFF_TYP_4_BYTE)
  {
    int32_t *pt;
    for (pt = SLONGDATA(image), i = 0; i < N; i++, pt++)
      if (!((*pt >= inf) && (*pt <= sup))) *pt = NDG_MIN;
  }
  else
  {
    fprintf(stderr, "%s: bad image type(s)\n", F_NAME);
    return 0;
  }

  return 1;
}
hdf5_oprimitive::write_hdf5_binary_dataset(
    void const* address,
    std::size_t data_count,
    std::size_t object_number
)
{
    // define the datatype
    hdf5_datatype datatype(H5T_OPAQUE);
    datatype.resize(data_count);

    write_dataset_basic(address, 1, datatype, object_number);

    // end access to the datatype and release resources.
    datatype.close();
}
hdf5_iprimitive::read_hdf5_binary_dataset
(
    void *t,
    std::size_t data_count,
    std::size_t object_number
)
{
    // define the datatype
    hdf5_datatype datatype(H5T_OPAQUE);
    datatype.resize(data_count);

    read_dataset_basic(t, 1, datatype, object_number);

    // end access to the datatype and release resources.
    datatype.close();
}
Beispiel #15
0
//--------------------------------------------------------------------------
// Function:	AbstractDs::getDataType
///\brief	Returns the generic datatype of this abstract dataset, which
///		can be a dataset or an attribute.
///\return	DataType instance
///\exception	H5::DataTypeIException
// Programmer	Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
DataType AbstractDs::getDataType() const
{
    // Gets the id of the datatype used by this dataset or attribute using
    // p_get_type.  p_get_type calls either H5Dget_type or H5Aget_type
    // depending on which object invokes getDataType.  Then, create and
    // return the DataType object
    try {
        DataType datatype(p_get_type());
        return(datatype);
    }
    catch (DataSetIException E) {
        throw DataTypeIException("DataSet::getDataType", E.getDetailMsg());
    }
    catch (AttributeIException E) {
        throw DataTypeIException("Attribute::getDataType", E.getDetailMsg());
    }
}
Beispiel #16
0
//! retrieve datatype from domain if possible
wxString ColumnBase::getDatatype(bool useConfig)
{
    enum
    {
        showType = 0,
        showFormula,
        showAll
    };
    int flag = (useConfig ? showFormula : showType);
    if (useConfig)
        config().getValue("ShowComputed", flag);
    // view columns are all computed and have their source empty
    if (flag == showFormula && !getComputedSource().empty())
        return getComputedSource();

    wxString ret;
    DomainPtr d = getDomain();
    wxString datatype(d ? d->getDatatypeAsString() : sourceM);

    enum
    {
        showDatatype = 0,
        showDomain,
        showBoth
    };
    int show = (useConfig ? showBoth : showDatatype);
    if (useConfig)
        config().getValue("ShowDomains", show);

    if (!d || d->isSystem() || show == showBoth || show == showDatatype)
        ret += datatype;

    if (d && !d->isSystem() && (show == showBoth || show == showDomain))
    {
        if (!ret.empty())
            ret += " ";
        ret += "(" + d->getName_() + ")";
    }

    if (flag == showAll && !getComputedSource().empty())
        ret += " (" + getComputedSource() + ")";
    return ret;
}
Beispiel #17
0
      ModifierFilter(unsigned int type, const unsigned int* vec, size_t length) :
        RemapFilterBase(type)
      {
        targets_.reserve(length / 2);

        {
          Vector_ModifierFlag v;
          targets_.push_back(v);
        }

        for (size_t i = 0; i < length - 1; i += 2) {
          AddDataType datatype(vec[i]);
          AddValue newval(vec[i + 1]);

          switch (datatype) {
            case BRIDGE_DATATYPE_MODIFIERFLAG:
              if (! targets_.empty()) {
                targets_.back().push_back(ModifierFlag(datatype, newval));
              }
              break;

            case BRIDGE_DATATYPE_MODIFIERFLAGS_END:
            {
              Vector_ModifierFlag v;
              targets_.push_back(v);
              break;
            }

            default:
              IOLOG_ERROR("ModifierFilter::add invalid datatype:%u\n", static_cast<unsigned int>(datatype));
              break;
          }
        }

        if (length % 2 > 0) {
          IOLOG_WARN("Invalid length(%d) in BRIDGE_FILTERTYPE_MODIFIER_*\n", static_cast<int>(length));
        }
      }
Beispiel #18
0
/* =============================================================== */
int32_t l3dborder(struct xvimage * f)
/* =============================================================== */
/* 
   extrait la frontière interne
   def: closure{x in F | x free for F}
*/
{
#undef F_NAME
#define F_NAME "l3dborder"
  struct xvimage * g;
  index_t rs, cs, ds, ps;
  index_t x, y, z;
  uint8_t *F;
  uint8_t *G;

  assert(datatype(f) == VFF_TYP_1_BYTE);
  rs = rowsize(f);
  cs = colsize(f);
  ds = depth(f);
  ps = rs * cs;
  F = UCHARDATA(f);
  g = copyimage(f);
  if (g == NULL)
  {   fprintf(stderr,"%s: copyimage failed\n", F_NAME);
      return 0;
  }  
  G = UCHARDATA(g);
  razimage(f);
  for (z = 0; z < ds; z++)
    for (y = 0; y < cs; y++)
      for (x = 0; x < rs; x++)
	if (G[z*ps + y*rs + x] && FaceLibre3d(g, x, y, z))
	  F[z*ps + y*rs + x] = VAL_OBJET;
  l3dmakecomplex(f);
  freeimage(g);
  return 1;
} /* l2dborder() */
Beispiel #19
0
/* ==================================== */
int32_t lbarycentrelab(struct xvimage * imagelab)
/* ==================================== */
{
  int32_t i, j;
  int32_t *F;
  int32_t rs, cs, N;
  int32_t nblabels;
  double *bxx;             /* pour les tables de barycentres par composantes */
  double *byy;
  int32_t *surf;
  int32_t lab;

  if (depth(imagelab) != 1) 
  {
    fprintf(stderr, "lbarycentre: cette version ne traite pas les images volumiques\n");
    return 0;
  }

  if (datatype(imagelab) != VFF_TYP_4_BYTE) 
  {
    fprintf(stderr, "lbarycentrelab: l'image doit etre de type int32_t\n");
    return 0;
  }

  rs = imagelab->row_size;
  cs = imagelab->col_size;
  N = rs * cs;
  F = SLONGDATA(imagelab);

  nblabels = 0;
  for (j = 0; j < N; j++) if (F[j] > nblabels ) nblabels = F[j];

  bxx = (double *)calloc(1,nblabels * sizeof(double));
  byy = (double *)calloc(1,nblabels * sizeof(double));
  surf = (int32_t *)calloc(1,nblabels * sizeof(int32_t));
  if ((bxx == NULL) || (byy == NULL) || (surf == NULL))
  {
    fprintf(stderr, "lbarycentre: malloc failed\n");
    return 0;
  }

  /* ---------------------------------------------------------- */
  /* calcul des isobarycentres par region (sauf fond) */
  /* ---------------------------------------------------------- */
  
  for (i = 0; i < nblabels; i++)
  {
    bxx[i] = 0.0;
    byy[i] = 0.0;
    surf[i] = 0;
  }

  for (j = 0; j < cs; j++)
    for (i = 0; i < rs; i++)
    {
      if (F[j * rs + i] != 0)
      {
        lab = F[j * rs + i] - 1; /* les valeurs des labels sont entre 1 et nblabels */
        surf[lab] += 1;
        bxx[lab] += (double)i;
        byy[lab] += (double)j;
      }
    }

#ifdef DEBUG
printf("%d\n", nblabels);
#endif

  for (i = 0; i < nblabels; i++)
  {
    bxx[i] = bxx[i] / surf[i];
    byy[i] = byy[i] / surf[i];

#ifdef DEBUG
printf("%g %g\n", bxx[i], byy[i]);
#endif

  }

  /* ---------------------------------------------------------- */
  /* marque l'emplacement approximatif des barycentres dans l'image */
  /* ---------------------------------------------------------- */

  for (j = 0; j < N; j++) F[j] = 0;

  for (i = 0; i < nblabels; i++)
    F[(int32_t)(arrondi(byy[i])) * rs + arrondi(bxx[i])] = NDG_MAX;
  
  free(bxx);
  free(byy);
  free(surf);
  return 1;
} /* lbarycentrelab() */
Beispiel #20
0
void PtexReader::blendFaces(FaceData*& face, int faceid, Res res, bool blendu)
{
    Res pres;   // parent res, 1 higher in blend direction
    int length; // length of blend edge (1xN or Nx1)
    int e1, e2; // neighboring edge ids
    if (blendu) {
        assert(res.ulog2 < 0); // res >= 0 requires reduction, not blending
        length = (res.vlog2 <= 0 ? 1 : res.v());
        e1 = e_bottom;
        e2 = e_top;
        pres = Res(res.ulog2+1, res.vlog2);
    }
    else {
        assert(res.vlog2 < 0);
        length = (res.ulog2 <= 0 ? 1 : res.u());
        e1 = e_right;
        e2 = e_left;
        pres = Res(res.ulog2, res.vlog2+1);
    }

    // get neighbor face ids
    FaceInfo& f = _faceinfo[faceid];
    int nf1 = f.adjfaces[e1], nf2 = f.adjfaces[e2];

    // compute rotation of faces relative to current
    int r1 = (f.adjedge(e1)-e1+2)&3;
    int r2 = (f.adjedge(e2)-e2+2)&3;

    // swap u and v res for faces rotated +/- 90 degrees
    Res pres1 = pres, pres2 = pres;
    if (r1 & 1) pres1.swapuv();
    if (r2 & 1) pres2.swapuv();

    // ignore faces that have insufficient res (unlikely, but possible)
    if (nf1 >= 0 && !(_faceinfo[nf1].res >= pres)) nf1 = -1;
    if (nf2 >= 0 && !(_faceinfo[nf2].res >= pres)) nf2 = -1;

    // get parent face data
    int nf = 1;			// number of faces to blend (1 to 3)
    bool flip[3];		// true if long dimension needs to be flipped
    PtexFaceData* psrc[3];	// the face data
    psrc[0] = getData(faceid, pres);
    flip[0] = 0;		// don't flip main face
    if (nf1 >= 0) {
        // face must be flipped if rot is 1 or 2 for blendu, or 2 or 3 for blendv
        // thus, just add the blendu bool val to align the ranges and check bit 1
        // also, no need to flip if length is zero
        flip[nf] = length ? (r1 + blendu) & 1 : 0;
        psrc[nf++] = getData(nf1, pres1);
    }
    if (nf2 >= 0) {
        flip[nf] = length ? (r2 + blendu) & 1 : 0;
        psrc[nf++] = getData(nf2, pres2);
    }

    // get reduce lock and make sure we still need to reduce
    AutoMutex rlocker(reducelock);
    if (face) {
        // another thread must have generated it while we were waiting
        AutoLockCache locker(_cache->cachelock);
        // make sure it's still there now that we have the lock
        if (face) {
            face->ref();
            // release parent data
            for (int i = 0; i < nf; i++) psrc[i]->release();
            return;
        }
    }

    // allocate a new face data (1 x N or N x 1)
    DataType dt = datatype();
    int nchan = nchannels();
    int size = _pixelsize * length;
    PackedFace* pf = new PackedFace((void**)&face, _cache, res,
                                    _pixelsize, size);
    void* data = pf->getData();
    if (nf == 1) {
        // no neighbors - just copy face
        memcpy(data, psrc[0]->getData(), size);
    }
    else {
        float weight = 1.0f / nf;
        memset(data, 0, size);
        for (int i = 0; i < nf; i++)
            PtexUtils::blend(psrc[i]->getData(), weight, data, flip[i],
                             length, dt, nchan);
    }

    {
        AutoLockCache clocker(_cache->cachelock);
        face = pf;

        // clean up unused data
        _cache->purgeData();
    }

    // release parent data
    for (int i = 0; i < nf; i++) psrc[i]->release();
}
Beispiel #21
0
int32_t main(int argc, char *argv[])
{
	struct xvimage *image, *edges;

	FILE *output, *amira_script;
	char output_format;
	double r, v, b;
	iv_scene* scene;
	list *ss_result, *ss_result2;
	complexe *temp, *intersect_edges, *point;
	uint32_t i, rs, ps, d, N, lim, erode, j, keep, k, max, num_pt, *tab_pt, kept;
	char name[BASE_ALLOC];


	//*******************************************
	//Checking input values
	//*******************************************
	if (argc!=4)
	{
		fprintf(stderr, "usage: %s %s\n", argv[0], USAGE);
		return(-1);
	}

	//We read input image
	image=readimage(argv[1]);
	if (image==NULL)
	{
		fprintf(stderr, "Error: Could not read %s.\n", argv[1]);
		return(-1);
	}
	else if(datatype(image)!=VFF_TYP_1_BYTE)
	{
		fprintf(stderr, "Error: only CC image supported\n");
		return(-1);
	}


	//We extract some info
	rs=rowsize(image1);
	cs=colsize(image1);
	d=depth(image1);
	N=rs*cs*d;


	//We produce the edges image
	edges=copyimage(image);
	if(edges==NULL)
	{
		fprintf(stderr, "Memory allocation error : not enough memory.\n");
		return(-1);
	}
	//And keep only intersection edges in this image
	pix=0;
	for(k=0; k<d; k++)
		for(j=0; j<cs; j++)
			for(i=0; i<rs; i++)
			{
				if( (UCHARDATA(image1)[pix] & CC_AX) != 0)
				{
					t=cca_cardinal_containers(image1, pix, i, j, k, CC_AX, rs, rs*cs);
					if(t<3)
						UCHARDATA(image1)[pix]&=(255-CC_AX);
				}

				if( (UCHARDATA(image1)[pix] & CC_AY) != 0)
				{
					t=cca_cardinal_containers(image1, pix, i, j, k, CC_AY, rs, rs*cs);
					if(t<3)
						UCHARDATA(image1)[pix]&=(255-CC_AY);
				}

				if( (UCHARDATA(image1)[pix] & CC_AZ) != 0)
				{
					t=cca_cardinal_containers(image1, pix, i, j, k, CC_AZ, rs, rs*cs);
					if(t<3)
						UCHARDATA(image1)[pix]&=(255-CC_AZ);
				}

				pix++;
			}

	for(i=0; i<N; i++)
		UCHARDATA(image1)[i]&=255-(CC_VOL | CC_FXY | CC_FYZ | CC_FXZ | CC_PT);

	cca_makecomplex(image1);



	if(strcmp(argv[6], "keep")==0)
	{
		strategy=KEEP;
	}
	else if(strcmp(argv[6], "reject")==0)
	{
		strategy=REJECT;
	}
	else
	{
		fprintf(stderr, "usage: %s %s\n", argv[0], USAGE);
		return(-1);
	}


	mode_amira=0;
	if(argc==9)
	{
		if(strcmp(argv[8], "-amira")!=0)
		{
			fprintf(stderr, "usage: %s %s\n", argv[0], USAGE);
			freeimage(image);
			freeimage(edges);
			return(-1);
		}
		else
		{
			mode_amira=1;
		}
	}

	if(strcmp(argv[4], "fusion")==0)
	{
		mode=FUSION;
	}
	else if(strcmp(argv[4], "split")==0)
	{
		mode=SPLIT;
	}
	else
	{
		fprintf(stderr, "usage: %s %s\n", argv[0], USAGE);
		freeimage(image);
		freeimage(edges);
		return(-1);
	}


	rs=rowsize(image);
	ps=colsize(image)*rs;

	if(mode==SPLIT)
	{
		//Each surface will be written in different Inventor File
		//Create an AVIZO script which will allow to open all of them
		sprintf(name, "%s_avizo_load_script.hx", argv[3]);
		amira_script=fopen(name, "wb");
		if(amira_script==NULL)
		{
			fprintf(stderr, "Error: could not create file %s. Check directory permission.\n", name);
			freeimage(image);
			freeimage(edges);
			return(-1);
		}
		amira_script_init(amira_script);
	}
	else
	{
		sprintf(name, "%s.iv", argv[3]);
		output = fopen(name, "wb");
		if(output==NULL)
		{
			fprintf(stderr, "Error: could not create output file %s (directory exists?).\n", name);
			freeimage(image);
			freeimage(edges);
			return(-1);
		}
	}


	if(strcmp(argv[7], "NULL")!=0)
	{
		cca_image=allocimage(NULL, rs, ps/rs, depth(image), VFF_TYP_1_BYTE);
		if(cca_image==NULL)
		{
			fprintf(stderr, "Error: could not allocate memory\n");
			freeimage(image);
			freeimage(edges);
			return(-1);
		}
	}
	else
	{
		cca_image=NULL;
	}




	//*******************************************************
	//Preparation of the image and the scene
	//*******************************************************

	//In case we don't have a complex, uncomment following
	//cca_makecomplex(image);

	scene=inventor_new_scene(10, NULL);

	//Initialize the scene...
	if(scene==NULL)
	{
		fprintf(stderr, "Error when creating new scene.\n");
		return(-1);
	}

	//We add to our object the main materials (keep the surfaces for later)
	inventor_add_material_to_scene(scene, "MatPoint", POS_PT, 0.0, 0.0, 0.0, 0.1, 0.4, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
	inventor_add_material_to_scene(scene, "MatAX", POS_AX, 0.0, 0.0, 0.0, 0.1, 0.1, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
	inventor_add_material_to_scene(scene, "MatAY", POS_AY, 0.0, 0.0, 0.0, 0.1, 0.1, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
	inventor_add_material_to_scene(scene, "MatAZ", POS_AZ, 0.0, 0.0, 0.0, 0.1, 0.1, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
	inventor_add_material_to_scene(scene, "MatVXY", POS_VXY, 0.0, 0.0, 0.0, 0.65, 0.65, 0.65, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
	inventor_add_material_to_scene(scene, "MatVXZ", POS_VXZ, 0.0, 0.0, 0.0, 0.50, 0.50, 0.50, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
	inventor_add_material_to_scene(scene, "MatVYZ", POS_VYZ, 0.0, 0.0, 0.0, 0.80, 0.80, 0.80, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);


	if(mode==FUSION)
	{
		scene->output=output;
		inventor_init_file(scene);
	}



	//********************************************************
	//Make surface segmentation
	//********************************************************

	//Get the intersection edges
	intersect_edges=cca_to_complexe(edges);
	freeimage(edges);
	if(intersect_edges==NULL)
	{
		fprintf(stderr, "Error in function cca_to_complexe()\n");
		inventor_delete_scene(scene);
		freeimage(image);
		return (-1);
	}


	//Make separation of the complex into surface components
	ss_result=cca_simple_surface_segmentation_with_intersection_edges_and_exclusion_inclusion_image(image, intersect_edges, filter, strategy);
	if(ss_result==NULL)
	{
		fprintf(stderr, "Error: cca_simple_surface_segmentation_with_intersection_edges_and_exclusion_inclusion_image() failed.\n");
		inventor_delete_scene(scene);
		freeimage(image);
		return(-1);
	}
	//We don't need the image anymore
	freeimage(image);

	fprintf(stdout, "Found %d surfaces\n", ss_result->cpt -2);


	//The first item is the set of all vertices...
	temp=(complexe*)list_pop(ss_result);
	if(mode==SPLIT)
	{
		//We don't care.
		complexe_free_complexe(temp);
		point=NULL;
		tab_pt=NULL;
		num_pt=0;
	}
	else if(mode==FUSION)
	{
		for(i=0; i<ss_result->cpt; i++)
		{
			//Choose a random color for surfaces
			r=((double)rand())/((double)RAND_MAX);
			v=((double)rand())/((double)RAND_MAX);
			b=((double)rand())/((double)RAND_MAX);
			sprintf(name, "SurfXY_%d", i);
			inventor_add_material_to_scene(scene, name, POS_FXY, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
			r+=0.05; v+=0.05; b+=0.05;
			if(r>1.0) r=1.0;
			if(b>1.0) b=1.0;
			if(v>1.0) v=1.0;
			sprintf(name, "SurfXZ_%d", i);
			inventor_add_material_to_scene(scene, name, POS_FXZ, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
			r+=0.05; v+=0.05; b+=0.05;
			if(r>1.0) r=1.0;
			if(b>1.0) b=1.0;
			if(v>1.0) v=1.0;
			sprintf(name, "SurfYZ_%d", i);
			inventor_add_material_to_scene(scene, name, POS_FYZ, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
			inventor_write_material_to_file(scene, POS_FXY);
			inventor_write_material_to_file(scene, POS_FXZ);
			inventor_write_material_to_file(scene, POS_FYZ);
		}

		//All the surfaces will go in the same file.
		//The array of points therefore interest us, we keep it and write it in the inventor file
		point=temp;
		tab_pt=point->tab_pt_obj;
		num_pt=point->num_pt_obj;
		inventor_new_object(scene);
		//inventor_set_drawstyle(scene, INVISIBLE, 1, 1);
		inventor_declare_points(scene, "Points", tab_pt, num_pt, rs, ps, mode_amira);

	}


	//The second item is the set of all intersect edges... We don't care.
	temp=(complexe*)list_pop(ss_result);
	complexe_free_complexe(temp);






	//*******************************************************
	//Send the surfaces to output file
	//*******************************************************

	i=0; //Will be used for the filename
	kept=0;
	while(!list_isempty(ss_result))
	{
		//Get the object to write
		temp=(complexe*)list_pop(ss_result);

		keep=1;
		if(keep==1)
		{
			if(cca_image!=NULL)
				complexe_add_to_cca(cca_image, temp);

/*			if(temp->num_fxy>0) {k=temp->tab_fxy[0]; f=CC_FXY;}
			else if(temp->num_fxz>0) {k=temp->tab_fxz[0]; f=CC_FXZ;}
			else if(temp->num_fyz>0) {k=temp->tab_fyz[0]; f=CC_FYZ;}
			else assert(0);

			l=cca_list_container(cca_image, k, getxfrompixnum(k, rs, ps), getyfrompixnum(k, rs, ps), getzfrompixnum(k, rs, ps), f, rs, ps);
			assert(l->cpt==2);
			while(!list_isempty(l))
			{
				g=(face_desc*)list_pop(l);
				surf[kept][l->cpt -1]=LONGDATA(labels)[g->pixnumber];
				free(g);
			}
			assert(surf[kept][0] != surf[kept][1]);
			if(surf[kept][0] > surf[kept][1])
			{
				k=surf[kept][1];
				surf[kept][1]=surf[kept][0];
				surf[kept][0]=k;
			}
*/
			kept++;

			if(mode==SPLIT)
				complexe_compute_vertex_array(temp, rs, ps);

			if(mode==SPLIT)
			{
				//Choose a random color for surfaces
				r=((double)rand())/((double)RAND_MAX);
				v=((double)rand())/((double)RAND_MAX);
				b=((double)rand())/((double)RAND_MAX);
				sprintf(name, "SurfXY_%d", i);
				inventor_add_material_to_scene(scene, name, POS_FXY, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
				r+=0.05; v+=0.05; b+=0.05;
				if(r>1.0) r=1.0;
				if(b>1.0) b=1.0;
				if(v>1.0) v=1.0;
				sprintf(name, "SurfXZ_%d", i);
				inventor_add_material_to_scene(scene, name, POS_FXZ, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
				r+=0.05; v+=0.05; b+=0.05;
				if(r>1.0) r=1.0;
				if(b>1.0) b=1.0;
				if(v>1.0) v=1.0;
				sprintf(name, "SurfYZ_%d", i);
				inventor_add_material_to_scene(scene, name, POS_FYZ, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);


				//Create an output file for the surface

				sprintf(name, "%s.surf%d.%d.iv", argv[3], temp->num_fxy+temp->num_fyz+temp->num_fxz, i);
				output = fopen(name, "wb");
				if(output==NULL)
				{
					fprintf(stderr, "Error: could not create output file %s (directory exists?).\n", name);
					while(!list_isempty(ss_result))
					{
						temp=(complexe*)list_pop(ss_result);
						complexe_free_complexe(temp);
					}
					list_delete(ss_result, NO_FREE_DATA);
					inventor_delete_scene(scene);
					return(-1);
				}

				//Link the output with the scene
				scene->output=output;

				//And initialise the scene and the points
				inventor_init_file(scene);
				inventor_new_object(scene);
				//inventor_set_drawstyle(scene, INVISIBLE, 1, 1);
				inventor_declare_points(scene, "Points", temp->tab_pt_obj, temp->num_pt_obj, rs, ps, mode_amira);

				tab_pt=temp->tab_pt_obj;
				num_pt=temp->num_pt_obj;
				temp->num_pt_obj=0;
				temp->tab_pt_obj=NULL;
			}

			inventor_new_object(scene);


			if(mode==FUSION)
			{
				sprintf(name, "SurfXY_%d", i);
				inventor_add_material_to_scene(scene, name, POS_FXY, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
				sprintf(name, "SurfXZ_%d", i);
				inventor_add_material_to_scene(scene, name, POS_FXZ, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
				sprintf(name, "SurfYZ_%d", i);
				inventor_add_material_to_scene(scene, name, POS_FYZ, r, v, b, r, v, b, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
			}

			//inventor_call_defined(scene, "Points");
			complexe_to_inventor(scene, temp, num_pt, tab_pt, rs, ps, mode_amira);

			inventor_close_object(scene);

			fflush(scene->output);

			if(mode==SPLIT)
			{
				inventor_close_object(scene);
				fclose(scene->output);

				//For the amira script
				k=0;
				max=0;
				while(name[k]!='\0')
				{
					if(name[k]=='/')
						max=k+1;

					k++;
				}

				amira_script_add_iv_file(amira_script, &name[max], 1, 30*(i+1));

				free(tab_pt);
			}



		}
		i++;
		complexe_free_complexe(temp);
	}

	if(mode==FUSION)
	{
		inventor_close_object(scene);
		fclose(scene->output);
	}


	fprintf(stdout, "Kept %d surfaces\n", kept);

	/*for(i=0; i<kept-1; i++)
		for(k=i+1; k<kept; k++)
		{
			if(
*/
	if(cca_image!=NULL)
	{
		writeimage(cca_image, argv[7]);
		freeimage(cca_image);
	}

	//****************************************************
	//Program ends
	//****************************************************
	inventor_delete_scene(scene);
	list_delete(ss_result, NO_FREE_DATA);
	if(filter!=NULL)
		freeimage(filter);

	if(mode==SPLIT)
		fclose(amira_script);


	return(0);
}
Beispiel #22
0
/* ==================================== */
int32_t lsquelsmoothval(struct xvimage *image, // entree/sortie: image originale / squelette
              struct xvimage *dx,    // entree/sortie: distance / distance topologique
              struct xvimage *ni,    // entree/sortie: niveaux - image 1D 
              struct xvimage *gr,    // entree: gradient
              int32_t connex, 
              int32_t val_inhibit, 
              int32_t rayon)
/* ==================================== */
#undef F_NAME
#define F_NAME "lsquelsmoothval"
{ 
  int32_t k;
  int32_t x;                       /* index muet de pixel */
  int32_t y;                       /* index muet (generalement un voisin de x) */
  int32_t rs = rowsize(image);     /* taille ligne */
  int32_t cs = colsize(image);     /* taille colonne */
  int32_t N = rs * cs;             /* taille image */
  struct xvimage *dt;          /* pour le calcul de la "distance topologique" */
  uint32_t *DT;           /* fonction "distance topologique" */
  uint8_t *IM = UCHARDATA(image); /* l'image de depart */
  uint32_t *DX = ULONGDATA(dx);    /* fonction distance au complementaire de IM */
  uint8_t *NI = UCHARDATA(ni);    /* fonction niveau (1D) - taille N * 1 */
  uint8_t *GR = UCHARDATA(gr);    /* fonction gradient */
  uint32_t d;
  Rbt * RBT;
  int32_t taillemaxrbt;
  Liste * cx;                  // pour le cercle de centre x
  Liste * cy;                  // pour le cercle de centre y
  uint32_t dmax;

  IndicsInit(N);
  if ((rowsize(dx) != rs) || (colsize(dx) != cs) || (depth(dx) != 1))
  {
    fprintf(stderr, "%s() : bad size for dx\n", F_NAME);
    return(0);
  }
  if (datatype(dx) != VFF_TYP_4_BYTE)
  {
    fprintf(stderr, "%s() : datatype(dx) must be uint32_t\n", F_NAME);
    return(0);
  }
  if ((rowsize(ni) != N) || (colsize(ni) != 1) || (depth(ni) != 1))
  {
    fprintf(stderr, "%s() : bad size for ni\n", F_NAME);
    return(0);
  }
  dt = copyimage(dx);
  DT = ULONGDATA(dt); 
  taillemaxrbt = 2 * rs + 2 * cs ;
  /* cette taille est indicative, le RBT est realloue en cas de depassement */
  RBT = mcrbt_CreeRbtVide(taillemaxrbt);
  if (RBT == NULL)
  {
    fprintf(stderr, "%s() : mcrbt_CreeRbtVide failed\n", F_NAME);
    return(0);
  }

  for (dmax = 0, x = 0; x < N; x++) if (DX[x] > dmax) dmax = DX[x];

  // INITIALISATION DT
  for (x = 0; x < N; x++) if (IM[x]) DT[x] = INFINI; else DT[x] = 0;

  // INITIALISATION DU RBT
  for (x = 0; x < N; x++)
    if (IM[x] && (DX[x] != val_inhibit) && bordext8(IM, x, rs, N))
    {
      mcrbt_RbtInsert(&RBT, DX[x], x);
      Set(x, EN_RBT);
    } // if, for

  cx = CreeListeVide(2*rs + 2*cs);
  cy = CreeListeVide(2*rs + 2*cs);

  d = 1;
  if (connex == 4)
  {
    while (!mcrbt_RbtVide(RBT))
    {
      x = RbtPopMin(RBT);
      UnSet(x, EN_RBT);
#ifdef DEBUG
      printf("pop x = %d,%d, im = %d, dx = %ld\n", x%rs, x/rs, IM[x], DX[x]);
#endif
      if (simple4(IM, x, rs, N))
      {
        if (smooth(image, x, rayon, cx, cy))
	{
          NI[d] = GR[x];
          DT[x] = d;
          IM[x] = 0;
          d++;
          for (k = 0; k < 8; k += 1)         /* parcourt les voisins en 8-connexite  */
          {                                              /* pour empiler les voisins */
            y = voisin(x, k, rs, N);                             /* non deja empiles */
            if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT)))
            {
              mcrbt_RbtInsert(&RBT, DX[y], y);
              Set(y, EN_RBT);
            } /* if y */
          } /* for k */      
	}
        else
	{
          DX[x] += INCR_PRIO;
          if (DX[x] > dmax) break;
          mcrbt_RbtInsert(&RBT, DX[x], x);
          Set(x, EN_RBT);
	}
      } // if (simple4(IM, x, rs, N))
    } /* while (!mcrbt_RbtVide(RBT)) */
  } /* if (connex == 4) */
  else
  if (connex == 8)
  {
    printf("connex 8 NYI\n");
  } /* if (connex == 8) */

  // RECUPERATION DU RESULTAT
  d = 0; // valeur pour l'infini: plus grande valeur finie + 1
  for (x = 0; x < N; x++) if ((DT[x] > d) && (DT[x] < INFINI)) d = DT[x];
  d += 1;
  for (x = 0; x < N; x++) if (DT[x] == INFINI) DX[x] = d; else DX[x] = DT[x];
  
  /* ================================================ */
  /* UN PEU DE MENAGE                                 */
  /* ================================================ */

  IndicsTermine();
  mcrbt_RbtTermine(RBT);
  freeimage(dt);
  ListeTermine(cx);  
  ListeTermine(cy);  
  return(1);
} /* lsquelsmoothval() */
Beispiel #23
0
/* ==================================== */
int32_t lwshedtopobin(struct xvimage *image, struct xvimage *marqueur, int32_t connex)
/* ==================================== */
/*! \fn int32_t lwshedtopobin(struct xvimage *image, struct xvimage *marqueur, int32_t connex)
    \param image (entrée/sortie) : une image ndg
    \param marqueur (entrée/sortie) : une image binaire
    \param connex (entrée) : 4 ou 8 (2D), 6, 18 ou 26 (3D)
    \return code erreur : 0 si échec, 1 sinon
    \brief ligne de partage des eaux "topologique" binaire (algo MC, GB, LN)
*/
#undef F_NAME
#define F_NAME "lwshedtopobin"
{
  register int32_t i, x;      /* index muet */
  int32_t rs = rowsize(image);      /* taille ligne */
  int32_t cs = colsize(image);      /* taille colonne */
  int32_t ds = depth(image);        /* nb plans */
  int32_t ps = rs * cs;             /* taille plan */
  int32_t N = ps * ds;              /* taille image */
  uint8_t *F = UCHARDATA(image);
  uint8_t *G = UCHARDATA(marqueur);
  Fahs * FAHS;                    /* la file d'attente hierarchique */
  int32_t *CM, *newCM;              /* etat d'un pixel */
  ctree * CT;                   /* resultat : l'arbre des composantes */

  if ((datatype(image) != VFF_TYP_1_BYTE) || (datatype(marqueur) != VFF_TYP_1_BYTE))
  {
    fprintf(stderr, "%s: image and marker must be both byte\n", F_NAME);
    return 0;
  }

  if ((rowsize(marqueur) != rs) || (colsize(marqueur) != cs) || (depth(marqueur) != ds))
  {
    fprintf(stderr, "%s: incompatible sizes\n", F_NAME);
    return 0;
  }

  FAHS = CreeFahsVide(N);
  if (FAHS == NULL)
  {   fprintf(stderr, "%s() : CreeFahsVide failed\n", F_NAME);
      return 0;
  }

  IndicsInit(N);
  // imposition des maxima
  for (i = 0; i < N; i++) if (G[i]) F[i] = G[i] = NDG_MAX; 

#ifdef _DEBUG_
  printf("Component tree\n");
#endif
  if ((connex == 4) || (connex == 8))
  {
    if (!ComponentTree(F, rs, N, connex, &CT, &CM))
    {   fprintf(stderr, "%s() : ComponentTree failed\n", F_NAME);
        return 0;
    }
  }
  else if ((connex == 6) || (connex == 18) || (connex == 26))
  {
    if (!ComponentTree3d(F, rs, ps, N, connex, &CT, &CM))
    {   fprintf(stderr, "%s() : ComponentTree failed\n", F_NAME);
        return 0;
    }
  }
  else
  { fprintf(stderr, "%s() : bad value for connex : %d\n", F_NAME, connex);
    return 0;
  }

#ifdef OLDVERSIONBIN
#ifdef _DEBUG_
  printf("Reconstruction \n");
#endif
  Reconstruction(marqueur, image, CM, CT);
  ComponentTreeFree(CT); // AMELIORATION POSSIBLE: modification du CT et reutilisation pour la suite
  free(CM);

#ifdef _DEBUG_
  printf("Component tree \n");
#endif
  if ((connex == 4) || (connex == 8))
  {
    if (!ComponentTree(G, rs, N, connex, &CT, &CM))
    {   fprintf(stderr, "%s() : ComponentTree failed\n", F_NAME);
        return 0;
    }
  }
  else
  {
    if (!ComponentTree3d(G, rs, ps, N, connex, &CT, &CM))
    {   fprintf(stderr, "%s() : ComponentTree failed\n", F_NAME);
        return 0;
    }
  }

  Watershed(marqueur, connex, FAHS, CM, CT);
#endif // #ifdef OLDVERSIONBIN

#ifndef OLDVERSIONBIN
#ifdef _DEBUG_
  printf("Reconstruction - par arbre\n");
#endif
  newCM = (int32_t *)calloc(CT->nbnodes, sizeof(int32_t));
  if (newCM == NULL) {
    fprintf(stderr, "%s : malloc failed\n", F_NAME);
    return 0;
  }
  reconsTree(CT, CM, newCM, N, G);
  //writeimage(marqueur, "marqueur");

  compressTree(CT, CM, newCM, N);

  // Reconstruction de l'image
  for (x=0; x<N; x++) {
      F[x] = CT->tabnodes[CM[x]].data;    
  }
  //writeimage(image, "test");

  /* Not useful
  for (d = 0; d < CT->nbnodes; d++) {
    if ((CT->tabnodes[d].nbsons == -2) || (CT->tabnodes[d].nbsons == -3)){
      CT->tabnodes[d].nbsons = -1;
    }
  }
  */

  Watershed(image, connex, FAHS, CM, CT);
#endif // ifndef OLDVERSIONBIN

#ifdef _DEBUG_
  printf("Watershed\n");
#endif
 
#ifdef _DEBUG_
  printf("Binarisation\n");
#endif
  for (i = 0; i < N; i++) 
    if (CT->tabnodes[CM[i]].nbsons == 0) // maximum
      F[i] = NDG_MAX;
    else
      F[i] = NDG_MIN;

  /* ================================================ */
  /* UN PEU DE MENAGE                                 */
  /* ================================================ */

  IndicsTermine();
  FahsTermine(FAHS);
  ComponentTreeFree(CT);
  free(CM);
#ifndef OLDVERSIONBIN
  free(newCM);
#endif
  return(1);
} /* lwshedtopobin() */
Beispiel #24
0
/* ==================================== */
int32_t lsquelval(struct xvimage *image, // entree/sortie: image originale / squelette
              struct xvimage *dx,    // entree/sortie: distance / distance topologique
              int32_t connex, 
              int32_t val_inhibit)
/* ==================================== */
#undef F_NAME
#define F_NAME "lsquelval"
{ 
  int32_t k;
  int32_t x;                       /* index muet de pixel */
  int32_t y;                       /* index muet (generalement un voisin de x) */
  int32_t rs = rowsize(image);     /* taille ligne */
  int32_t cs = colsize(image);     /* taille colonne */
  int32_t N = rs * cs;             /* taille image */
  struct xvimage *dt;          /* pour le calcul de la "distance topologique" */
  uint8_t *IM = UCHARDATA(image);      /* l'image de depart */
  uint32_t *DX;           /* fonction distance au complementaire de IM */
  uint32_t *DT;                    /* fonction "distance topologique" */
  uint32_t d;
  Rbt * RBT;
  int32_t taillemaxrbt;

  IndicsInit(N);
  if ((rowsize(dx) != rs) || (colsize(dx) != cs) || (depth(dx) != 1))
  {
    fprintf(stderr, "%s() : bad size for dx\n", F_NAME);
    return(0);
  }
  if (datatype(dx) != VFF_TYP_4_BYTE)
  {
    fprintf(stderr, "%s() : datatype(dx) must be uint32_t\n", F_NAME);
    return(0);
  }
  DX = ULONGDATA(dx); 
  dt = copyimage(dx);
  DT = ULONGDATA(dt); 
  taillemaxrbt = 2 * rs + 2 * cs ;
  /* cette taille est indicative, le RBT est realloue en cas de depassement */
  RBT = mcrbt_CreeRbtVide(taillemaxrbt);
  if (RBT == NULL)
  {
    fprintf(stderr, "%s() : mcrbt_CreeRbtVide failed\n", F_NAME);
    return(0);
  }

  /* ================================================ */
  /*               PREMIERE PHASE                     */
  /* ================================================ */

#ifdef VERBOSE
    printf("1ere etape\n");
#endif

  // INITIALISATION DT
  for (x = 0; x < N; x++) if (IM[x]) DT[x] = INFINI; else DT[x] = 0;

  // INITIALISATION DU RBT
  for (x = 0; x < N; x++)
    if (IM[x] && (DX[x] != val_inhibit) && bordext8(IM, x, rs, N))
    {
      mcrbt_RbtInsert(&RBT, DX[x], x);
      Set(x, EN_RBT);
    } // if, for

  d = 1;
  if (connex == 4)
  {
    while (!mcrbt_RbtVide(RBT))
    {
      x = RbtPopMin(RBT);
      UnSet(x, EN_RBT);
#ifdef DEBUG
      printf("pop x = %d,%d, im = %d, dx = %ld\n", x%rs, x/rs, IM[x], DX[x]);
#endif
      if (simple4(IM, x, rs, N))
      {
        DT[x] = d;
        IM[x] = 0;
        d++;
        for (k = 0; k < 8; k += 1)         /* parcourt les voisins en 8-connexite  */
        {                                              /* pour empiler les voisins */
          y = voisin(x, k, rs, N);                             /* non deja empiles */
          if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT)))
          {
            mcrbt_RbtInsert(&RBT, DX[y], y);
            Set(y, EN_RBT);
          } /* if y */
        } /* for k */      
      } // if (simple4(IM, x, rs, N))
    } /* while (!mcrbt_RbtVide(RBT)) */
  } /* if (connex == 4) */
  else
  if (connex == 8)
  {
    while (!mcrbt_RbtVide(RBT))
    {
      x = RbtPopMin(RBT);
      UnSet(x, EN_RBT);
#ifdef DEBUG
      printf("pop x = %d,%d, im = %d, dx = %ld\n", x%rs, x/rs, IM[x], DX[x]);
#endif
      if (simple8(IM, x, rs, N))
      {
        DT[x] = d;
        IM[x] = 0;
        d++;
        for (k = 0; k < 8; k += 1)         /* parcourt les voisins en 8-connexite  */
        {                                              /* pour empiler les voisins */
          y = voisin(x, k, rs, N);                             /* non deja empiles */
          if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT)))
          {
            mcrbt_RbtInsert(&RBT, DX[y], y);
            Set(y, EN_RBT);
          } /* if y */
        } /* for k */      
      } // if (simple8(IM, x, rs, N))
    } /* while (!mcrbt_RbtVide(RBT)) */
  } /* if (connex == 8) */

#ifdef DEBUG
  writeimage(dt, "_dt");
#endif

  /* ================================================ */
  /*               SECONDE PHASE                      */
  /* ================================================ */

#ifdef SECONDE_PHASE

  stabilite = 0;
  while (!stabilite)
  {
#ifdef VERBOSE
    printf("2eme etape\n");
#endif
    stabilite = 1;

    // INITIALISATION DU RBT
    for (j = 1; j < cs-1; j++) 
      for (i = 1; i < rs-1; i++) 
      {
        x = j * rs + i;
        if (DT[x] && (DT[x] != INFINI)) mcrbt_RbtInsert(&RBT, DT[x], x);
      }

    if (connex == 4)
    {
      while (!mcrbt_RbtVide(RBT))
      {
        x = RbtPopMin(RBT);
#ifdef DEBUG
        printf("pop x = %d,%d, dt = %ld\n", x%rs, x/rs, DT[x]);
#endif
        if (abaisse4(x, DT, rs, N)) 
        {
          stabilite = 0;
#ifdef DEBUG
          printf("abaisse a %ld\n", DT[x]);
#endif
	} // if (abaisse4(x, DT, rs, N)) 
      } // while (!mcrbt_RbtVide(RBT))
    } // if (connex == 4)
    else
    if (connex == 8)
    {
      int32_t abaisse;
      while (!mcrbt_RbtVide(RBT))
      {
        x = RbtPopMin(RBT);
#ifdef DEBUG
        printf("pop x = %d,%d, dt = %d\n", x%rs, x/rs, DT[x]);
#endif
        if (abaisse8(x, DT, rs, N)) 
        {
          stabilite = 0;
#ifdef DEBUG
          printf("abaisse a %ld\n", DT[x]);
#endif
	} // if (abaisse8(x, DT, rs, N)) 
      } // while (!mcrbt_RbtVide(RBT))
    } // if (connex == 8)
  } // while (!stabilite)

#endif

  // RECUPERATION DU RESULTAT
  d = 0; // valeur pour l'infini: plus grande valeur finie + 1
  for (x = 0; x < N; x++) if ((DT[x] > d) && (DT[x] < INFINI)) d = DT[x];
  d += 1;
  for (x = 0; x < N; x++) if (DT[x] == INFINI) DX[x] = d; else DX[x] = DT[x];
  
  /* ================================================ */
  /* UN PEU DE MENAGE                                 */
  /* ================================================ */

  IndicsTermine();
  mcrbt_RbtTermine(RBT);
  freeimage(dt);
  return(1);
} /* lsquelval() */
Beispiel #25
0
/* ==================================== */
int32_t lsquelval3d(struct xvimage *image, // entree/sortie: image originale / squelette
                struct xvimage *dx,    // entree/sortie: distance / distance topologique
                int32_t connex, 
                int32_t val_inhibit)
/* ==================================== */
{ 
  int32_t i, j, k;
  int32_t x;                       /* index muet de pixel */
  int32_t y;                       /* index muet (generalement un voisin de x) */
  int32_t rs = rowsize(image);     /* taille ligne */
  int32_t cs = colsize(image);     /* taille colonne */
  int32_t ps = rs * cs;            /* taille plan */
  int32_t ds = depth(image);
  int32_t N = ds * ps;             /* taille image */
  struct xvimage *dt;          /* pour le calcul de la "distance topologique" */
  uint8_t *IM = UCHARDATA(image);      /* l'image de depart */
  uint32_t *DX;           /* fonction distance au complementaire de IM */
  uint32_t *DT;           /* fonction "distance topologique" */
  uint32_t d;
  Rbt * RBT;
  int32_t taillemaxrbt;
  int32_t mctopo3d_t6mm, mctopo3d_t26mm, t6p, mctopo3d_t26p;

  IndicsInit(N);
  mctopo3d_init_topo3d();
  if ((rowsize(dx) != rs) || (colsize(dx) != cs) || (depth(dx) != ds))
  {
    fprintf(stderr, "%s() : bad size for dx\n", F_NAME);
    return(0);
  }
  if (datatype(dx) != VFF_TYP_4_BYTE)
  {
    fprintf(stderr, "%s() : datatype(dx) must be uint32_t\n", F_NAME);
    return(0);
  }
  DX = ULONGDATA(dx); 
  dt = copyimage(dx);
  DT = ULONGDATA(dt); 
  taillemaxrbt = 2 * rs * cs +  2 * rs * ds +  2 * ds * cs;
  /* cette taille est indicative, le RBT est realloue en cas de depassement */
  RBT = mcrbt_CreeRbtVide(taillemaxrbt);
  if (RBT == NULL)
  {
    fprintf(stderr, "%s() : mcrbt_CreeRbtVide failed\n", F_NAME);
    return(0);
  }

  /* ================================================ */
  /*               PREMIERE PHASE                     */
  /* ================================================ */

#ifdef VERBOSE
    printf("1ere etape\n");
#endif

  // INITIALISATION DT
  for (x = 0; x < N; x++) if (IM[x]) DT[x] = -1; else DT[x] = 0;

  // INITIALISATION DU RBT
  for (x = 0; x < N; x++)
    if (IM[x] && (DX[x] != val_inhibit) && mctopo3d_bordext26(IM, x, rs, ps, N))
    {
      mcrbt_RbtInsert(&RBT, DX[x], x);
      Set(x, EN_RBT);
    } // if, for

  d = 1;
  if (connex == 6)
  {
    while (!mcrbt_RbtVide(RBT))
    {
      x = RbtPopMin(RBT);
      UnSet(x, EN_RBT);
      if (mctopo3d_simple6(IM, x, rs, ps, N))
      {
        DT[x] = d;
        IM[x] = 0;
        d++;
        for (k = 0; k < 26; k += 1)       /* parcourt les voisins en 26-connexite  */
        {                                              /* pour empiler les voisins */
          y = voisin26(x, k, rs, ps, N);                       /* non deja empiles */
          if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT)))
          {
            mcrbt_RbtInsert(&RBT, DX[y], y);
            Set(y, EN_RBT);
          } /* if y */
        } /* for k */      
      } // if (mctopo3d_simple6(IM, x, rs, N))
    } /* while (!mcrbt_RbtVide(RBT)) */
  } /* if (connex == 6) */
  else
  if (connex == 26)
  {
    while (!mcrbt_RbtVide(RBT))
    {
      x = RbtPopMin(RBT);
      UnSet(x, EN_RBT);
      if (mctopo3d_simple26(IM, x, rs, ps, N))
      {
        DT[x] = d;
        IM[x] = 0;
        d++;
        for (k = 0; k < 26; k += 1)       /* parcourt les voisins en 26-connexite  */
        {                                              /* pour empiler les voisins */
          y = voisin26(x, k, rs, ps, N);                       /* non deja empiles */
          if ((y != -1) && (IM[y]) && (DX[y] != val_inhibit) && (! IsSet(y, EN_RBT)))
          {
            mcrbt_RbtInsert(&RBT, DX[y], y);
            Set(y, EN_RBT);
          } /* if y */
        } /* for k */      
      } // if (mctopo3d_simple26(IM, x, rs, N))
    } /* while (!mcrbt_RbtVide(RBT)) */
  } /* if (connex == 26) */

  /* ================================================ */
  /*               SECONDE PHASE                      */
  /* ================================================ */

#ifdef VERBOSE
    printf("2eme etape\n");
#endif

  // INITIALISATION DU RBT
  for (k = 1; k < ds-1; k++) 
    for (j = 1; j < cs-1; j++) 
      for (i = 1; i < rs-1; i++) 
      {
        x = k * ps + j * rs + i;
        if (DT[x]) mcrbt_RbtInsert(&RBT, DT[x], x);
      }

  if (connex == 6)
  {
    int32_t abaisse;
    while (!mcrbt_RbtVide(RBT))
    {
      x = RbtPopMin(RBT);
      do
      {
        abaisse = 0;
        mctopo3d_nbtopoh3d26_l((int32_t *)DT, x, DT[x], rs, ps, N, &t6p, &mctopo3d_t26mm);
        if ((t6p == 1) && (mctopo3d_t26mm == 1))
	{
          mctopo3d_nbtopoh3d26_l((int32_t *)DT, x, DT[x], rs, ps, N, &t6p, &mctopo3d_t26mm);
          if ((t6p == 1) && (mctopo3d_t26mm == 1))
	  {
            d = mctopo3d_alpha26m_l((int32_t *)DT, x, rs, ps, N);
            d = mcmin((DT[x]-1),(d+1));
            DT[x] = d;
            abaisse = 1;
	  }
        }
      } while (abaisse);
    } /* while (!mcrbt_RbtVide(RBT)) */
  } /* if (connex == 6) */
  else
  if (connex == 26)
  {
    int32_t abaisse;
    while (!mcrbt_RbtVide(RBT))
    {
      x = RbtPopMin(RBT);
      do
      {
        abaisse = 0;
        mctopo3d_nbtopoh3d6_l((int32_t *)DT, x, DT[x], rs, ps, N, &mctopo3d_t26p, &mctopo3d_t6mm);
        if ((mctopo3d_t26p == 1) && (mctopo3d_t6mm == 1))
	{
          mctopo3d_nbtopoh3d26_l((int32_t *)DT, x, DT[x], rs, ps, N, &mctopo3d_t26p, &mctopo3d_t6mm);
          if ((mctopo3d_t26p == 1) && (mctopo3d_t6mm == 1))
	  {
            d = mctopo3d_alpha26m_l((int32_t *)DT, x, rs, ps, N);
            d = mcmin((DT[x]-1),(d+1));
            DT[x] = d;
            abaisse = 1;
	  }
        }
      } while (abaisse);
    } /* while (!mcrbt_RbtVide(RBT)) */
  } /* if (connex == 26) */


  // RECUPERATION DU RESULTAT
  d = 0;
  for (x = 0; x < N; x++) if ((DT[x] > d) && (DT[x] < INFINI)) d = DT[x];
  d += 1;
  for (x = 0; x < N; x++) if (DT[x] == INFINI) DX[x] = d; else DX[x] = DT[x];

  /* ================================================ */
  /* UN PEU DE MENAGE                                 */
  /* ================================================ */

  mctopo3d_termine_topo3d();
  IndicsTermine();
  mcrbt_RbtTermine(RBT);
  freeimage(dt);
  return(1);
} /* lsquelval3d() */
Beispiel #26
0
/* ==================================== */
int32_t lamont(
        struct xvimage *m,
        struct xvimage *f,
        int32_t connex,
        int32_t strict) 
/* connex : 4, 8 (en 2D), 6, 18, 26 (en 3D) */
/* ==================================== */
#undef F_NAME 
#define F_NAME "lamont"
{
  int32_t i, j, k;                 /* index muet de pixel */
  int32_t rs = rowsize(f);         /* taille ligne */
  int32_t cs = colsize(f);         /* taille colonne */
  int32_t ds = depth(f);           /* nb plans */
  int32_t ps = rs * cs;            /* taille plan */
  int32_t N = ps * ds;             /* taille image */
  int32_t *F = SLONGDATA(f);
  uint8_t *M = UCHARDATA(m);
  Fifo * FIFO;
  int32_t incr_vois;

  if ((rowsize(m) != rs) || (colsize(m) != cs) || (depth(m) != ds))
  {
    fprintf(stderr, "%s: incompatible sizes\n", F_NAME);
    return 0;
  }

  if ((datatype(m) != VFF_TYP_1_BYTE) || (datatype(f) != VFF_TYP_4_BYTE))
  {
    fprintf(stderr, "%s: incompatible types\n", F_NAME);
    return 0;
  }

  switch (connex)
  {
    case 4: incr_vois = 2; break;
    case 8: incr_vois = 1; break;
  } /* switch (connex) */

  FIFO = CreeFifoVide(N);
  if (FIFO == NULL)
  {   fprintf(stderr,"%s : CreeFifoVide failed\n", F_NAME);
      return(0);
  }

  for (i = 0; i < N; i++) if (M[i]) FifoPush(FIFO, i); 

  if ((connex == 4) || (connex == 8))
  {
    if (ds != 1)
    {
      fprintf(stderr,"%s : connexity 4 or 8 not defined for 3D\n", F_NAME);
      return(0);
    }
    if (strict)
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 8; k += incr_vois)
      {
        j = voisin(i, k, rs, N);
        if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
    else
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 8; k += incr_vois)
      {
        j = voisin(i, k, rs, N);
//printf("i=%d ; j=%d ; Mj=%d ; Fj=%ld ; Fi=%ld\n", i, j, M[j], F[j], F[i]);
        if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 6)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 6 not defined for 2D\n", F_NAME);
        return(0);
    }
    if (strict)
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k <= 10; k += 2)
      {
        j = voisin6(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
    else
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k <= 10; k += 2)
      {
        j = voisin6(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 18)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 18 not defined for 2D\n", F_NAME);
        return(0);
    }
    if (strict)
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 18; k += 1)
      {
        j = voisin18(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; }

      } /* for k */
    } /* while ! FifoVide */
    else
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 18; k += 1)
      {
        j = voisin18(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; }

      } /* for k */
    } /* while ! FifoVide */
  } 
  else if (connex == 26)
  {
    if (ds == 1)
    {   fprintf(stderr,"%s : connexity 26 not defined for 2D\n", F_NAME);
        return(0);
    }
    if (strict)
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 26; k += 1)
      {
        j = voisin26(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] > F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
    else
    while (! FifoVide(FIFO))
    {
      i = FifoPop(FIFO);
      for (k = 0; k < 26; k += 1)
      {
        j = voisin26(i, k, rs, ps, N);
        if ((j != -1) && !M[j] && (F[j] >= F[i])) { FifoPush(FIFO, j); M[j] = 255; }
      } /* for k */
    } /* while ! FifoVide */
  } 
  FifoTermine(FIFO);
  return 1;
} /* lamont() */
Beispiel #27
0
/* ==================================== */
int32_t lplanarity(
        struct xvimage *img,     /* image de depart */
        int32_t connex,          /* 6, 18, 26  */
        struct xvimage *res,     /* resultat: image d'attributs */
        int32_t *nlabels)        /* resultat: nombre de regions traitees */
/* ==================================== */
#undef F_NAME
#define F_NAME "lplanarity"
{
  int32_t k;
  index_t w, x, y, areacomp;
  uint8_t *SOURCE = UCHARDATA(img);
  float *RES = FLOATDATA(res);
  index_t rs = rowsize(img);
  index_t cs = colsize(img);
  index_t ds = depth(img);
  index_t ps = rs * cs;
  index_t N = ps * ds;
  Lifo * LIFO;
  float planar;
  double a, b, c, d, error, *px, *py, *pz;

  if (datatype(res) != VFF_TYP_FLOAT) 
  {
    fprintf(stderr, "%s: result image must be of type VFF_TYP_FLOAT\n", F_NAME);
    return 0;
  }

  if ((rowsize(res) != rs) || (colsize(res) != cs) || (depth(res) != ds))
  {
    fprintf(stderr, "%s: incompatible image sizes\n", F_NAME);
    return 0;
  }

  /* le RES initialement est mis a LP_MARK0 */
  for (x = 0; x < N; x++) RES[x] = LP_MARK0;

  LIFO = CreeLifoVide(N);
  if (LIFO == NULL)
    {   fprintf(stderr, "%s: CreeLifoVide failed\n", F_NAME);
      return(0);
  }

  *nlabels = 0;
  for (x = 0; x < N; x++)
  {
    if (SOURCE[x] && (RES[x] == LP_MARK0))
    {
      *nlabels += 1;
      RES[x] = LP_MARK1;
      areacomp = 0;
      LifoPush(LIFO, x);
      while (! LifoVide(LIFO)) // 1er parcours de la composante - compte les points (areacomp)
      {
        w = LifoPop(LIFO);
	areacomp++;
	switch (connex)
	  {
	  case 6:
            for (k = 0; k <= 10; k += 2) /* parcourt les 6 voisins */
            {
              y = voisin6(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK0) && SOURCE[y])
	      {
		RES[y] = LP_MARK1;
		LifoPush(LIFO, y);
	      } /* if y ... */
	    } // for k
	    break;
	  case 18:
            for (k = 0; k < 18; k += 1) /* parcourt les 18 voisins */
            {
              y = voisin18(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK0) && SOURCE[y])
	      {
		RES[y] = LP_MARK1;
		LifoPush(LIFO, y);
	      } /* if y ... */
	    } // for k
	    break;
	  case 26:
            for (k = 0; k < 26; k += 1) /* parcourt les 26 voisins */
            {
              y = voisin26(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK0) && SOURCE[y])
	      {
		RES[y] = LP_MARK1;
		LifoPush(LIFO, y);
	      } /* if y ... */
	    } // for k
	    break;
	  } // switch (connex)
      } /* while (! LifoVide(LIFO)) */

      // init 2eme passe
      px = (double *)malloc(areacomp*sizeof(double)); assert(px != NULL);
      py = (double *)malloc(areacomp*sizeof(double)); assert(py != NULL);
      pz = (double *)malloc(areacomp*sizeof(double)); assert(pz != NULL);

      LifoPush(LIFO, x);     /* on parcourt le plateau une 2eme fois pour collecter les points */
      RES[x] = LP_MARK2;
      areacomp = 0;
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
	px[areacomp] = (double)(w % rs);
	py[areacomp] = (double)((w % ps) / rs);
	pz[areacomp] = (double)(w / ps);
	areacomp++;

	switch (connex)
	  {
	  case 6:
            for (k = 0; k <= 10; k += 2) /* parcourt les 6 voisins */
            {
              y = voisin6(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK1)) 
	      {
		RES[y] = LP_MARK2;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  case 18:
            for (k = 0; k < 18; k += 1) /* parcourt les 18 voisins */
            {
              y = voisin18(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK1)) 
	      {
		RES[y] = LP_MARK2;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  case 26:
            for (k = 0; k < 26; k += 1) /* parcourt les 26 voisins */
            {
              y = voisin26(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK1)) 
	      {
		RES[y] = LP_MARK2;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  } // switch (connex)
      } /* while (! LifoVide(LIFO)) */

      // init 3eme passe - calcul attribut planar
      if (!lidentifyplane(px, py, pz, areacomp, &a, &b, &c, &d, &error))
      {
	fprintf(stderr, "%s: lidentifyplane failed\n", F_NAME);
	return 0;
      }
      free(px); free(py); free(pz);
      planar = (float)(error / areacomp);

      LifoPush(LIFO, x);     /* on parcourt le plateau une 3eme fois pour propager la valeur */
      RES[x] = planar;
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);

	switch (connex)
	  {
	  case 6:
            for (k = 0; k <= 10; k += 2) /* parcourt les 6 voisins */
            {
              y = voisin6(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK2)) 
	      {
		RES[y] = planar;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  case 18:
            for (k = 0; k < 18; k += 1) /* parcourt les 18 voisins */
            {
              y = voisin18(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK2)) 
	      {
		RES[y] = planar;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  case 26:
            for (k = 0; k < 26; k += 1) /* parcourt les 26 voisins */
            {
              y = voisin26(w, k, rs, ps, N);
	      if ((y != -1) && (RES[y] == LP_MARK2)) 
	      {
		RES[y] = planar;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  } // switch (connex)
      } /* while (! LifoVide(LIFO)) */

    } /* if (SOURCE[x] && (RES[x] == LP_MARK0)) */
  } /* for (x = 0; x < N; x++) */

  LifoTermine(LIFO);
  return(1);
} // lplanarity()
Beispiel #28
0
/* ==================================== */
int32_t lattribute3d(
        struct xvimage *img, /* image de depart */
        int32_t connex,          /* 6, 18, 26  */
        int32_t typregion,       /* = <LABMIN | LABMAX | LABPLATEAU> */
        int32_t attrib,          /* 0: surface */
        int32_t seuil,           /* en dessous (<=) de seuil, l'attribut est mis a 0 */
        struct xvimage *lab,     /* resultat: image d'attributs */
        int32_t *nlabels)        /* resultat: nombre de regions traitees */
/* ==================================== */
#undef F_NAME
#define F_NAME "lattribute3d"
{
  int32_t k;
  index_t w, x, y;
  uint8_t *SOURCE = UCHARDATA(img);
  int32_t *LABEL = SLONGDATA(lab);
  index_t rs = rowsize(img);
  index_t cs = colsize(img);
  index_t ds = depth(img);
  index_t ps = rs * cs;
  index_t N = ps * ds;
  Lifo * LIFO;
  int32_t label;
  int32_t val_attrib;

  if (datatype(lab) != VFF_TYP_4_BYTE) 
  {
    fprintf(stderr, "%s: le resultat doit etre de type VFF_TYP_4_BYTE\n", F_NAME);
    return 0;
  }

  if ((rowsize(lab) != rs) || (colsize(lab) != cs) || (depth(lab) != ds))
  {
    fprintf(stderr, "%s: tailles images incompatibles\n", F_NAME);
    return 0;
  }

  /* le LABEL initialement est mis a NONMARQUE */
  for (x = 0; x < N; x++) LABEL[x] = NONMARQUE;

  LIFO = CreeLifoVide(N);
  if (LIFO == NULL)
    {   fprintf(stderr, "%s: CreeLifoVide failed\n", F_NAME);
      return(0);
  }

  *nlabels = 0;

if ((typregion == LABMIN) || (typregion == LABMAX))
{
  for (x = 0; x < N; x++)
  {
    if (LABEL[x] == NONMARQUE)   /* on trouve un point x non etiquete */
    {
      *nlabels += 1;
      LABEL[x] = MARQUE;
      switch (attrib)            /* on initialise les attributs de cette composante */
      {
	case AREA: val_attrib = 0; break;
        default: 
          fprintf(stderr, "%s: bad attribute: %d\n", F_NAME, attrib);
          return 0;
      } /* switch (attrib) */
      LifoPush(LIFO, x);         /* on va parcourir le plateau auquel appartient x */
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
        label = LABEL[w];
        if (label == MARQUE)     /* c'est une propagation de "marquage" : pour l'instant, */
	{                        /* on croit qu'on est dans un extremum */     
          switch (attrib)
          {
  	    case AREA: val_attrib++; break;
	  } /* switch (attrib) */
	  switch (connex)
	  {
	  case 6:
            for (k = 0; k <= 10; k += 2) /* parcourt les 6 voisins */
            {
              y = voisin6(w, k, rs, ps, N);
              if (y != -1)
              {
               if (((typregion == LABMIN) && (SOURCE[y] < SOURCE[w])) || 
                   ((typregion == LABMAX) && (SOURCE[y] > SOURCE[w])))
               {   /* w non dans un minimum (resp. maximum) */
                if (label == MARQUE)
		{
                  label = NONEXTREM;
                  *nlabels -= 1;
                  LABEL[w] = label;
                  LifoPush(LIFO, w);
		}
               }   
	       else if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE))
               {
                LABEL[y] = label;
                LifoPush(LIFO, y);
               } /* if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE)) */
	      } /* if (y != -1) */
	    } // for k
	    break;
	  case 18:
            for (k = 0; k < 18; k += 1) /* parcourt les 18 voisins */
            {
              y = voisin18(w, k, rs, ps, N);
              if (y != -1)
              {
               if (((typregion == LABMIN) && (SOURCE[y] < SOURCE[w])) || 
                   ((typregion == LABMAX) && (SOURCE[y] > SOURCE[w])))
               {   /* w non dans un minimum (resp. maximum) */
                if (label == MARQUE)
		{
                  label = NONEXTREM;
                  *nlabels -= 1;
                  LABEL[w] = label;
                  LifoPush(LIFO, w);
		}
               }   
	       else if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE))
               {
                LABEL[y] = label;
                LifoPush(LIFO, y);
               } /* if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE)) */
	      } /* if (y != -1) */
	    } // for k
	    break;
	  case 26:
            for (k = 0; k < 26; k += 1) /* parcourt les 26 voisins */
            {
              y = voisin26(w, k, rs, ps, N);
              if (y != -1)
              {
               if (((typregion == LABMIN) && (SOURCE[y] < SOURCE[w])) || 
                   ((typregion == LABMAX) && (SOURCE[y] > SOURCE[w])))
               {   /* w non dans un minimum (resp. maximum) */
                if (label == MARQUE)
		{
                  label = NONEXTREM;
                  *nlabels -= 1;
                  LABEL[w] = label;
                  LifoPush(LIFO, w);
		}
               }   
	       else if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE))
               {
                LABEL[y] = label;
                LifoPush(LIFO, y);
               } /* if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE)) */
	      } /* if (y != -1) */
	    } // for k
	    break;
	  } // switch (connex)
	} /* if (label == MARQUE) */
        else                           /* propagation de "demarquage" */
	{
	  switch (connex)
	  {
	  case 6:
            for (k = 0; k <= 10; k += 2) /* parcourt les 6 voisins */
            {
              y = voisin6(w, k, rs, ps, N);
              if (y != -1)
              {
                if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] != NONEXTREM))
                {
                  LABEL[y] = NONEXTREM;
                  LifoPush(LIFO, y);
                } /* if .. */
	      } /* if (y != -1) */
	    } // for k
	    break;
	  case 18:
            for (k = 0; k < 18; k += 1) /* parcourt les 18 voisins */
            {
              y = voisin18(w, k, rs, ps, N);
              if (y != -1)
              {
                if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] != NONEXTREM))
                {
                  LABEL[y] = NONEXTREM;
                  LifoPush(LIFO, y);
                } /* if .. */
	      } /* if (y != -1) */
	    } // for k
	    break;
	  case 26:
            for (k = 0; k < 26; k += 1) /* parcourt les 26 voisins */
            {
              y = voisin26(w, k, rs, ps, N);
              if (y != -1)
              {
                if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] != NONEXTREM))
                {
                  LABEL[y] = NONEXTREM;
                  LifoPush(LIFO, y);
                } /* if .. */
	      } /* if (y != -1) */
	    } // for k
	    break;
	  } // switch (connex)
	} /* else if (label == MARQUE) */
      } /* while (! LifoVide(LIFO)) */

      if (label == MARQUE)
      {
        if (val_attrib <= seuil) val_attrib = 0;
        LifoPush(LIFO, x);         /* on re-parcourt le plateau pour propager l'attribut */
        LABEL[x] = val_attrib;
        while (! LifoVide(LIFO))
        {
          w = LifoPop(LIFO);

	  switch (connex)
	  {
	  case 6:
            for (k = 0; k <= 10; k += 2) /* parcourt les 6 voisins */
            {
              y = voisin6(w, k, rs, ps, N);
              if ((y != -1) && (LABEL[y] == MARQUE)) 
              {
                LABEL[y] = val_attrib;
                LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  case 18:
            for (k = 0; k < 18; k += 1) /* parcourt les 18 voisins */
            {
              y = voisin18(w, k, rs, ps, N);
              if ((y != -1) && (LABEL[y] == MARQUE)) 
              {
                LABEL[y] = val_attrib;
                LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  case 26:
            for (k = 0; k < 26; k += 1) /* parcourt les 26 voisins */
            {
              y = voisin26(w, k, rs, ps, N);
              if ((y != -1) && (LABEL[y] == MARQUE)) 
              {
                LABEL[y] = val_attrib;
                LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  } // switch (connex)
	} /* while (! LifoVide(LIFO)) */
      } /* if (label == MARQUE) */

    } /* if (LABEL[x] != -1) */
  } /* for (x = 0; x < N; x++) */
} /* if ((typregion == LABMIN) || (typregion == LABMAX)) */
else
{
  for (x = 0; x < N; x++)
  {
    if (LABEL[x] == NONMARQUE)
    {
      *nlabels += 1;
      LABEL[x] = *nlabels;
      switch (attrib)            /* on initialise les attributs de cette composante */
      {
	case AREA: val_attrib = 0; break;
        default: 
          fprintf(stderr, "%s: bad attribute: %d\n", F_NAME, attrib);
          return 0;
      } /* switch (attrib) */
      LifoPush(LIFO, x);
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
        switch (attrib)
        {
	  case AREA: val_attrib++; break;
	} /* switch (attrib) */

	switch (connex)
	  {
	  case 6:
            for (k = 0; k <= 10; k += 2) /* parcourt les 6 voisins */
            {
              y = voisin6(w, k, rs, ps, N);
	      if ((y != -1) && (LABEL[y] == NONMARQUE) && (SOURCE[y] == SOURCE[w]))
	      {
		LABEL[y] = MARQUE;
		LifoPush(LIFO, y);
	      } /* if y ... */
	    } // for k
	    break;
	  case 18:
            for (k = 0; k < 18; k += 1) /* parcourt les 18 voisins */
            {
              y = voisin18(w, k, rs, ps, N);
	      if ((y != -1) && (LABEL[y] == NONMARQUE) && (SOURCE[y] == SOURCE[w]))
	      {
		LABEL[y] = MARQUE;
		LifoPush(LIFO, y);
	      } /* if y ... */
	    } // for k
	    break;
	  case 26:
            for (k = 0; k < 26; k += 1) /* parcourt les 26 voisins */
            {
              y = voisin26(w, k, rs, ps, N);
	      if ((y != -1) && (LABEL[y] == NONMARQUE) && (SOURCE[y] == SOURCE[w]))
	      {
		LABEL[y] = MARQUE;
		LifoPush(LIFO, y);
	      } /* if y ... */
	    } // for k
	    break;
	  } // switch (connex)
      } /* while (! LifoVide(LIFO)) */
      if (val_attrib <= seuil) val_attrib = 0;
      LifoPush(LIFO, x);         /* on re-parcourt le plateau pour propager l'attribut */
      LABEL[x] = val_attrib;
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);

	switch (connex)
	  {
	  case 6:
            for (k = 0; k <= 10; k += 2) /* parcourt les 6 voisins */
            {
              y = voisin6(w, k, rs, ps, N);
	      if ((y != -1) && (LABEL[y] == MARQUE)) 
	      {
		LABEL[y] = val_attrib;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  case 18:
            for (k = 0; k < 18; k += 1) /* parcourt les 18 voisins */
            {
              y = voisin18(w, k, rs, ps, N);
	      if ((y != -1) && (LABEL[y] == MARQUE)) 
	      {
		LABEL[y] = val_attrib;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  case 26:
            for (k = 0; k < 26; k += 1) /* parcourt les 26 voisins */
            {
              y = voisin26(w, k, rs, ps, N);
	      if ((y != -1) && (LABEL[y] == MARQUE)) 
	      {
		LABEL[y] = val_attrib;
		LifoPush(LIFO, y);
	      }
	    } // for k
	    break;
	  } // switch (connex)
      } /* while (! LifoVide(LIFO)) */
    } /* if (LABEL[x] == NONMARQUE) */
  } /* for (x = 0; x < N; x++) */
} /* else if ((typregion == LABMIN) || (typregion == LABMAX)) */

  LifoTermine(LIFO);

  *nlabels += 1; /* pour le niveau 0 */
  return(1);
} // lattribute3d()
Beispiel #29
0
/* ==================================== */
int32_t lattribute(
        struct xvimage *img, /* image de depart */
        int32_t connex,          /* 4, 8  */
        int32_t typregion,       /* = <LABMIN | LABMAX | LABPLATEAU> */
        int32_t attrib,          /* 0: surface, 1: perimetre, 2: circularite, 3: nb. trous, 
                                4: excentricite, 5: orientation, 6: diamètre vertical, 7: diamètre horizontal */
        int32_t seuil,           /* en dessous (<=) de seuil, l'attribut est mis a 0 */
        struct xvimage *lab, /* resultat: image d'attributs */
        int32_t *nlabels)        /* resultat: nombre de regions traitees */
/* ==================================== */
#undef F_NAME
#define F_NAME "lattribute"
{
  int32_t k, l;
  index_t w, x, y, z;
  uint8_t *SOURCE = UCHARDATA(img);
  int32_t *LABEL = SLONGDATA(lab);
  index_t rs = rowsize(img);
  index_t cs = colsize(img);
  index_t d = depth(img);
  index_t N = rs * cs;          /* taille image */
  Lifo * LIFO;
  int32_t label;
  int32_t area;
  int32_t perim;
  int32_t min, max;
  int32_t val_attrib;
  double mx1, my1; // cumuls des variables x et y
  double mx2, my2, mxy2; // cumuls des x^2, y^2 et xy
  int32_t incr_vois;

  if (datatype(lab) != VFF_TYP_4_BYTE) 
  {
    fprintf(stderr, "%s: le resultat doit etre de type VFF_TYP_4_BYTE\n", F_NAME);
    return 0;
  }

  if ((rowsize(lab) != rs) || (colsize(lab) != cs) || (depth(lab) != d))
  {
    fprintf(stderr, "%s: tailles images incompatibles\n", F_NAME);
    return 0;
  }

  if (depth(img) != 1) 
  {
    fprintf(stderr, "%s: cette version ne traite pas les images volumiques\n", F_NAME);
    exit(0);
  }

  switch (connex)
  {
    case 4: incr_vois = 2; break;
    case 8: incr_vois = 1; break;
    default: 
      fprintf(stderr, "%s: mauvaise connexite: %d\n", F_NAME, connex);
      return 0;
  } /* switch (connex) */

  /* le LABEL initialement est mis a NONMARQUE */
  for (x = 0; x < N; x++) LABEL[x] = NONMARQUE;

  LIFO = CreeLifoVide(N);
  if (LIFO == NULL)
    {   fprintf(stderr, "%s: CreeLifoVide failed\n", F_NAME);
      return(0);
  }

  *nlabels = 0;

if ((typregion == LABMIN) || (typregion == LABMAX))
{
  for (x = 0; x < N; x++)
  {
    if (LABEL[x] == NONMARQUE)   /* on trouve un point x non etiquete */
    {
      *nlabels += 1;
      LABEL[x] = MARQUE;
#ifdef DEBUGTROU
printf("AMORCE p=%d,%d h=%d set LABEL = %d\n", x%rs, x/rs, SOURCE[x], LABEL[x]);
#endif
      switch (attrib)            /* on initialise les attributs de cette composante */
      {
	case AREA: val_attrib = 0; break;
	case PERIM: val_attrib = 0; break;
	case TROUS: val_attrib = 0; break;
	case CIRC: area = perim = 0; break;
	case EXCEN: 
	case ORIEN: area = 0; mx1 = my1 = mx2 = my2 = mxy2 = 0.0; break;
        case VDIAM: min = cs-1; max = 0; break;
        case HDIAM: min = rs-1; max = 0; break;
        default: 
          fprintf(stderr, "%s: mauvais attribut: %d\n", F_NAME, attrib);
          return 0;
      } /* switch (attrib) */
      LifoPush(LIFO, x);         /* on va parcourir le plateau auquel appartient x */
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
        label = LABEL[w];
        if (label == MARQUE)     /* c'est une propagation de "marquage" : pour l'instant, */
	{                        /* on croit qu'on est dans un extremum */         
          switch (attrib)
          {
  	    case AREA: val_attrib++; break;
  	    case VDIAM: if (w/rs < min) min = w/rs; else if (w/rs > max) max = w/rs; break;
  	    case HDIAM: if (w%rs < min) min = w%rs; else if (w%rs > max) max = w%rs; break;
  	    case EXCEN:
  	    case ORIEN: area++; mx1 += w%rs; my1 += w/rs; mxy2 += (w%rs) * (w/rs);
                        mx2 += (w%rs) * (w%rs); my2 += (w/rs) * (w/rs); break;
  	    case PERIM: 
              if (w%rs==rs-1) val_attrib++; /* point de bord */
              if (w<rs)       val_attrib++; /* point de bord */
              if (w%rs==0)    val_attrib++; /* point de bord */
              if (w>=N-rs)    val_attrib++; /* point de bord */
              for (k = 0; k < 8; k += 2) /* 4-connexite obligatoire */
              {
                y = voisin(w, k, rs, N);
                if ((y != -1) && (SOURCE[y] != SOURCE[w])) val_attrib++;
              } /* for k */
            break;
            case CIRC:
              area++;
              if (w%rs==rs-1) perim++; /* point de bord */
              if (w<rs)       perim++; /* point de bord */
              if (w%rs==0)    perim++; /* point de bord */
              if (w>=N-rs)    perim++; /* point de bord */
              for (k = 0; k < 8; k += 2) /* 4-connexite obligatoire */
              {
                y = voisin(w, k, rs, N);
                if ((y != -1) && (SOURCE[y] != SOURCE[w])) perim++;
              } /* for k */
              break;
	  } /* switch (attrib) */
          for (k = 0; k < 8; k += incr_vois)
          {
            y = voisin(w, k, rs, N);
            if (y != -1)
            {
              if (((typregion == LABMIN) && (SOURCE[y] < SOURCE[w])) || 
                  ((typregion == LABMAX) && (SOURCE[y] > SOURCE[w])))
              {   /* w non dans un minimum (resp. maximum) */
                if (label == MARQUE)
		{
                  label = NONEXTREM;
                  *nlabels -= 1;
                  LABEL[w] = label;
                  LifoPush(LIFO, w);
		}
              } 
              else
              if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE))
              {
                LABEL[y] = label;
#ifdef DEBUGTROU
printf(" p=%d,%d h=%d set LABEL = %d\n", y%rs, y/rs, SOURCE[y], LABEL[y]);
#endif
                LifoPush(LIFO, y);
                if (attrib == TROUS)
	        {
                  int32_t masque = 0, imasque = 1;
                  /* fabrique le masque des voisins de y MARQUES */
                  for (l = 0; l < 8; l += 1)
                  {
                    z = voisin(y, l, rs, N);
                    if ((z != -1) && (LABEL[z] == MARQUE))
                      masque |= imasque; 
                    imasque = imasque << 1;
                  } /* for k ... */
#ifdef DEBUGTROU
printf(" p=%d,%d h=%d masque=%x t4m=%d t8b=%d\n", y%rs, y/rs, SOURCE[y], masque, t4(masque), t8b(masque));
#endif
                  if (connex == 4) 
                    { val_attrib += (t4(masque) - 1); if (t8b(masque) == 0) val_attrib--; }
                  else
                    { val_attrib += (t8(masque) - 1); if (t4b(masque) == 0) val_attrib--; }
	        } /* if (attrib == TROUS) */
              } /* if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] == NONMARQUE)) */
            } /* if (y != -1) */
          } /* for k ... */
	} /* if (label == MARQUE) */
        else                           /* propagation de "demarquage" */
	{
          for (k = 0; k < 8; k += incr_vois)
          {
            y = voisin(w, k, rs, N);
            if (y != -1)
            {
              if ((SOURCE[y] == SOURCE[w]) && (LABEL[y] != NONEXTREM))
              {
                LABEL[y] = NONEXTREM;
                LifoPush(LIFO, y);
              } /* if .. */
            } /* if (y != -1) */
          } /* for k ... */
	} /* else if (label == MARQUE) */
      } /* while (! LifoVide(LIFO)) */

      if (label == MARQUE)
      {
        if (attrib == CIRC) 
	{
          val_attrib = (int32_t)(256 * 4 * M_PI * (double)area / (double)(perim * perim));
          if (val_attrib > 255)
	  {
            fprintf(stderr, "WARNING: indice de circularite > 255 : %d, a=%d, p=%d\n", 
                            val_attrib, area, perim);
            val_attrib = 255;
	  }
	}
        if (attrib == EXCEN) val_attrib = excentricity(mx1, my1, mx2, my2, mxy2, area);
        if (attrib == ORIEN) val_attrib = orientation(mx1, my1, mx2, my2, mxy2, area);
        if (attrib == VDIAM) val_attrib = max - min + 1;
        if (attrib == HDIAM) val_attrib = max - min + 1;
        if (val_attrib <= seuil) val_attrib = 0;
#ifdef VERBOSE
printf("valeur attribut = %d\n", val_attrib);
#endif
        LifoPush(LIFO, x);         /* on re-parcourt le plateau pour propager l'attribut */
        LABEL[x] = val_attrib;
        while (! LifoVide(LIFO))
        {
          w = LifoPop(LIFO);
          for (k = 0; k < 8; k += incr_vois)
          {
            y = voisin(w, k, rs, N);
            if ((y != -1) && (LABEL[y] == MARQUE)) 
            {
              LABEL[y] = val_attrib;
              LifoPush(LIFO, y);
	    }
          } /* for k ... */
	} /* while (! LifoVide(LIFO)) */
      } /* if (label == MARQUE) */

    } /* if (LABEL[x] != -1) */
  } /* for (x = 0; x < N; x++) */
} /* if ((typregion == LABMIN) || (typregion == LABMAX)) */
else
{
  if (attrib == TROUS)
  {
    fprintf(stderr, "%s: attribut TROUS non compatible avec typreg = PLA\n", F_NAME);
    return 0;
  }
  for (x = 0; x < N; x++)
  {
    if (LABEL[x] == NONMARQUE)
    {
      *nlabels += 1;
      LABEL[x] = *nlabels;
      switch (attrib)            /* on initialise les attributs de cette composante */
      {
	case AREA: val_attrib = 0; break;
        case VDIAM: min = cs-1; max = 0; break;
        case HDIAM: min = rs-1; max = 0; break;
	case PERIM: val_attrib = 0; break;
	case CIRC: area = perim = 0; break;
	case EXCEN: 
	case ORIEN: area = 0; mx1 = my1 = mx2 = my2 = mxy2 = 0.0; break;
        default: 
          fprintf(stderr, "%s: mauvais attribut: %d\n", F_NAME, attrib);
          return 0;
      } /* switch (attrib) */
      LifoPush(LIFO, x);
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
        switch (attrib)
        {
	  case AREA: val_attrib++; break;
  	  case VDIAM: if (w/rs < min) min = w/rs; else if (w/rs > max) max = w/rs; break;
  	  case HDIAM: if (w%rs < min) min = w%rs; else if (w%rs > max) max = w%rs; break;
	  case EXCEN:
	  case ORIEN: area++; mx1 += w%rs; my1 += w/rs; mxy2 += (w%rs) * (w/rs);
                      mx2 += (w%rs) * (w%rs); my2 += (w/rs) * (w/rs); break;
  	  case PERIM: 
            if (w%rs==rs-1) val_attrib++; /* point de bord */
            if (w<rs)       val_attrib++; /* point de bord */
            if (w%rs==0)    val_attrib++; /* point de bord */
            if (w>=N-rs)    val_attrib++; /* point de bord */
            for (k = 0; k < 8; k += 2) /* 4-connexite obligatoire */
            {
              y = voisin(w, k, rs, N);
              if ((y != -1) && (SOURCE[y] != SOURCE[w])) val_attrib++;
            } /* for k */
          break;
          case CIRC:
            area++;
            if (w%rs==rs-1) perim++; /* point de bord */
            if (w<rs)       perim++; /* point de bord */
            if (w%rs==0)    perim++; /* point de bord */
            if (w>=N-rs)    perim++; /* point de bord */
            for (k = 0; k < 8; k += 2) /* 4-connexite obligatoire */
            {
              y = voisin(w, k, rs, N);
              if ((y != -1) && (SOURCE[y] != SOURCE[w])) perim++;
            } /* for k */
            break;
	} /* switch (attrib) */

        for (k = 0; k < 8; k += incr_vois)
        {
          y = voisin(w, k, rs, N);
          if ((y != -1) && (LABEL[y] == NONMARQUE) && (SOURCE[y] == SOURCE[w]))
          {
            LABEL[y] = MARQUE;
            LifoPush(LIFO, y);
          } /* if y ... */
        } /* for k ... */
      } /* while (! LifoVide(LIFO)) */

      if (attrib == CIRC) 
      {
        val_attrib = (int32_t)(256 * 4 * M_PI * (double)area / (double)(perim * perim));
        if (val_attrib > 255)
	{
          fprintf(stderr, "WARNING: indice de circularite > 255 : %d, a=%d, p=%d\n", 
                          val_attrib, area, perim);
          val_attrib = 255;
	}
      }
      if (attrib == EXCEN) val_attrib = excentricity(mx1, my1, mx2, my2, mxy2, area);
      if (attrib == ORIEN) val_attrib = orientation(mx1, my1, mx2, my2, mxy2, area);
      if (attrib == VDIAM) val_attrib = max - min + 1;
      if (attrib == HDIAM) val_attrib = max - min + 1;
      if (val_attrib <= seuil) val_attrib = 0;

      LifoPush(LIFO, x);         /* on re-parcourt le plateau pour propager l'attribut */
      LABEL[x] = val_attrib;
      while (! LifoVide(LIFO))
      {
        w = LifoPop(LIFO);
        for (k = 0; k < 8; k += incr_vois)
        {
          y = voisin(w, k, rs, N);
          if ((y != -1) && (LABEL[y] == MARQUE)) 
          {
            LABEL[y] = val_attrib;
            LifoPush(LIFO, y);
	  }
        } /* for k ... */
      } /* while (! LifoVide(LIFO)) */
    } /* if (LABEL[x] == NONMARQUE) */
  } /* for (x = 0; x < N; x++) */
} /* else if ((typregion == LABMIN) || (typregion == LABMAX)) */

  LifoTermine(LIFO);

  *nlabels += 1; /* pour le niveau 0 */
  return(1);
} // lattribute()
Beispiel #30
0
int main(int argc, char**argv) {
  std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
  int i; /* for for loops */
  /* commandline args */
  std::string filename;
  long long start=-1;
  long long end=-1;
  std::string delimiter;
  int shard_pos=-1;
  std::string host;
  std::string user;
  int port=3306;
  std::string password;
  std::string mapper_db;
  std::string schema_name;
  std::string table;
  long long chunk_size = 256 * 1024 * 1024;

  /* fetched from db */
  std::string column_name;
  long long column_id = -1;
  long long schema_id = -1;
  std::string mapper_type;
  std::string shared_path="";
  std::string lookup_db="";


  std::unordered_map<std::string,FILE*>::const_iterator find_file; 
  std::unordered_map<std::string,shard>::const_iterator find_shard;
 

  /* Process commandline............................... */
  std::string new_cmdline = "";

  if(argc == 1) {
    std::cerr << "usage: split -t table -f filename -j start -e end -y delimiter -z shard_pos -h mapper_host -u mapper_user -p mapper_password -d mapper_db -s schema_name -q chunk_size [default 256MB] -P port\n";
    exit(-1);
  }
  for(i=1;i<argc;++i) {
    if(i+1>argc) {
      std::cerr << "ERROR: Argument processing error at: " << argv[i] << " missing argument!\n";
      exit(-1);
    }
    std::string k(argv[i]);
    if(k == "-t") {
        table.assign(argv[++i]);
        new_cmdline += " -t " + table;
        continue;
    }
    if(k == "-f") {
        filename.assign(argv[++i]);
        new_cmdline += " -f " + filename;
        continue;
    }
    if(k == "-y") {
        delimiter.assign(argv[++i]);
        new_cmdline += " -y \"" + delimiter + "\"";
        continue;
    }
    if(k == "-h") {
        host.assign(argv[++i]);
        new_cmdline += " -h " + host;
        continue;
    }
    if(k == "-u") {
        user.assign(argv[++i]);
        new_cmdline += " -u " + user;
        continue;
    }
    if(k == "-p") {
        password.assign(argv[++i]);
        new_cmdline += " -p " + password;
        continue;
    }
    if(k == "-d") {
        mapper_db.assign(argv[++i]);
        new_cmdline += " -d " + mapper_db;
        continue;
    }
    if(k == "-s") {
        schema_name.assign(argv[++i]);
        new_cmdline += " -s " + schema_name;
        continue;
    }
    if(k == "-j") {
        start = atoll(argv[++i]);
        continue;
    }
    if(k == "-e") {
        end = atoll(argv[++i]);
        continue;
    }
    if(k == "-z") {
        shard_pos = atoll(argv[++i]);
        continue;
    }
    if(k == "-q") {
        chunk_size = atoll(argv[++i]);
        continue;
    }
    if(k == "-P") {
        port = atoi(argv[++i]);
        continue;
    }
  
    std::cerr << "ERROR: Argument processing error.  Unexpected token: " << k << "\n";
    exit(-1);

  }

  if(schema_name.length() > 1024) {
    std::cerr << "ERROR: Invalid schema name!\n";
    exit(-1);
  }

  if(table.length() > 1024) {
    std::cerr << "ERROR: Invalid table name!\n";
    exit(-1);
  }

  if(table == "" || filename == "" || delimiter == "" || host == "" || user == "" || password == "" || mapper_db == "" || schema_name == "" || start == -1 || end == -1) {
    std::cerr << "ERROR: all parameters are required\n";
    exit(-1);
  }

  long long fsize = filesize(filename);

  if(start == 0 && end == 0) {
    std::cerr << "Filesize: " << fsize << "\n";
    for(long long i=0;i<fsize;i+=chunk_size) {
      std::cout<< new_cmdline << " -j " << i << " -e " << (i + chunk_size) << "\n";
    }
    exit(0);
  }

  /* last chunk is probably past eof, so fix it*/
  if(end > fsize) end = fsize;

  MYSQL *conn = mysql_init(NULL);
  
  if (conn == NULL) {
      fprintf(stderr, "ERROR: mysql_init() failed\n");
      exit(-1);
  }  

  /* establish a connection to the meta-server*/ 
  if (mysql_real_connect(conn, host.c_str(), user.c_str(), password.c_str(), mapper_db.c_str(), port, NULL, 0) == NULL) {
      std::cerr << "ERROR: " << std::string(mysql_error(conn)) << "\n";
      exit(-1);
  }    

  /* max strings allowed in input validation = 1024, so this holds 4x the amount of data needed for safety*/
  char buffer[4097];

  /* Get the column_name from the database */
  mysql_real_escape_string(conn, buffer,schema_name.c_str(),schema_name.length());
  std::string sql = "select sequence_name,column_sequences.id cs_id, schemata.id s_id,datatype from column_sequences join schemata on schema_id = schemata.id where schema_name='" + std::string(buffer) + "' and sequence_type='shard_column';";
  
  int err=0;

  if(err = mysql_query(conn, sql.c_str())) {
    std::cerr << "ERROR: " << err << ", " << mysql_error(conn) << "\n";
    return 0;
  }
  MYSQL_RES *result = mysql_store_result(conn);
  MYSQL_ROW row = mysql_fetch_row(result);
  if(!row) {
    std::cerr << "ERROR: schema '" << schema_name << "' does not exist\n";
    exit(-1);
  } 
 
  column_name.assign(row[0]);
  column_id = atoll(row[1]);
  schema_id = atoll(row[2]);
  std::string datatype(row[3]); 
  mysql_free_result(result);

  sql = "select var_value from schemata_config where schema_id = " + std::to_string(schema_id) + " and var_name = 'mapper';";
  if(err = mysql_query(conn, sql.c_str())) {
    std::cerr << "ERROR: " << err << ", " << mysql_error(conn) << "\n";
    return 0;
  }
  result = mysql_store_result(conn);
  row = mysql_fetch_row(result);
  mapper_type.assign(row[0]);
  mysql_free_result(result);

  sql = "select var_value from schemata_config where schema_id = " + std::to_string(schema_id) + " and var_name = 'shared_path';";
  if(err = mysql_query(conn, sql.c_str())) {
    std::cerr << "ERROR: " << err << ", " << mysql_error(conn) << "\n";
    return 0;
  }
  result = mysql_store_result(conn);
  row = mysql_fetch_row(result);
  shared_path.assign(row[0]);
  mysql_free_result(result);

  sql = "select var_value from schemata_config where schema_id = " + std::to_string(schema_id) + " and var_name = 'lookup_db';";
  if(err = mysql_query(conn, sql.c_str())) {
    std::cerr << "ERROR: " << err << ", " << mysql_error(conn) << "\n";
    return 0;
  }
  result = mysql_store_result(conn);
  row = mysql_fetch_row(result);
  lookup_db.assign(row[0]);
  mysql_free_result(result);

  shard s = get_random_shard(conn,schema_id);

  MYSQL *conn2 = mysql_init(NULL);
  
  if (conn2 == NULL) {
      fprintf(stderr, "ERROR: mysql_init() failed\n");
      exit(-1);
  }  

  if (mysql_real_connect(conn2, s.host.c_str(), s.user.c_str(), s.password.c_str(), s.db.c_str(), 0, NULL, 0) == NULL) {
      std::cerr << "ERROR: " << std::string(mysql_error(conn)) << "\n";
      exit(-1);
  }    

  mysql_real_escape_string(conn2, buffer,column_name.c_str(),column_name.length());
  char buffer2[4097];
  mysql_real_escape_string(conn2, buffer2,table.c_str(),table.length());

  sql = "select ifnull(max(ordinal_position),-1) from information_schema.columns where table_schema='" + s.db + "' and table_name='" + std::string(buffer2) +"' and column_name = '" + std::string(buffer) + "'";
  if(err = mysql_query(conn, sql.c_str())) {
    std::cerr << "ERROR: " << err << ", " << mysql_error(conn) << "\n";
    return 0;
  }

  result = mysql_store_result(conn);
  row = mysql_fetch_row(result);
  int column_pos = atoi(row[0]);
  mysql_free_result(result);

  /* done with shard MySQL*/
  mysql_close(conn2);

  std::unordered_map<std::string, char> files_to_load;
  bool find_first_terminator=(start != 0);
  int done = 0;
  char line[BLOCK_SIZE];
  int rb;
  int c;
  int wb;

  if(column_pos == -1) {
    /* if not using lookup_db, get each host and db, otherwise there is one lookup_db per host */
    if(lookup_db == "") {
      sql = "select shard_name,db from shards where schema_id = " + std::to_string(schema_id);
    } else {
      sql = "select min(shard_name) from shards where schema_id = " + std::to_string(schema_id) + " GROUP BY host";
    }

    if(err = mysql_query(conn, sql.c_str())) {
      std::cerr << "ERROR: " << err << ", " << mysql_error(conn) << "\n";
      return 0;
    }
    /* buffers result in ram, can close db connection subsequently*/
    result = mysql_store_result(conn); 
    mysql_close(conn);

    std::string path;
    int linecount=0;
    while((row = mysql_fetch_row(result))){
      std::string db;
      std::string host(row[0]);
      if(lookup_db != "") {
        path = shared_path + "/loader/split/" + std::string(row[0]) + "/" + lookup_db + "/" + table + "/"; 
        db = lookup_db;
      } else {
        path = shared_path + "/loader/split/" + std::string(row[0]) + "/" + std::string(row[1]) + "/" + table + "/";
        db = std::string(row[1]);
      }
      system(("mkdir -p " + std::string(path)).c_str());
      path += std::string(md5(std::to_string(getpid()))) + ".txt";
      files_to_load[host + "::" + db + "::" + table + "::" + path] = 1;
      FILE *fh = fopen(filename.c_str(), "rb");
      if(!fh) {
        std::cerr << "ERROR: could not open file for reading:" << filename << "\n";
        exit(-1);
      }
      FILE *fo = fopen(path.c_str(), "wb");
      if(!fo) {
        std::cerr << "ERROR: could not open file for writing:" << path << "\n";
        exit(-1);
      }

      /* simply copy input to output very fast */
      linecount = 0;
      while(!feof(fh)) {

        if(find_first_terminator) {
          fseek(fh,start,SEEK_SET);
          while((c = fgetc(fh))!='\n');
          find_first_terminator = 0;
        }

        if(fgets(line, BLOCK_SIZE,fh) == NULL) break;
        wb = fwrite(line, 1, rb = strlen(line), fo);
        ++linecount;
        if( wb != rb ) {
          std::cerr << "ERROR: io error\n";
          exit(-1);
        }

        if(ftell(fh) >= end) break;
      }      
      fclose(fh);
      fclose(fo);
    }
    std::chrono::steady_clock::time_point end= std::chrono::steady_clock::now();
    std::cerr << "LINES: " << linecount << " MAPS: 0 TIME(ms): " << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() ;
    mysql_free_result(result);
  } else {
    /* this table is sharded */

    sql = "select host,db,shard_name from shards where schema_id = " + std::to_string(schema_id);
    if(err = mysql_query(conn, sql.c_str())) {
      std::cerr << "ERROR: " << err << ", " << mysql_error(conn) << "\n";
      return 0;
    }
    /* buffers result in ram, can close db connection subsequently*/
    result = mysql_store_result(conn); 

    std::string path;
    int linecount=0;

    std::unordered_map<std::string, shard> shards;
    while((row = mysql_fetch_row(result))){
      shard s;
      s.host = std::string(row[0]);
      s.db = std::string(row[1]);
      s.shard_name = std::string(row[2]);
      shards[std::string(row[2])] = s;
    }

    mysql_free_result(result);
    // mysql_close(conn);
    FILE *fh = fopen(filename.c_str(), "rb");
    if(!fh) {
      std::cerr << "could not open file for reading:" << filename << "\n";
      exit(-1);
    }

    if(start != 0) {
      fseek(fh,start,SEEK_SET);
      while((c = fgetc(fh))!='\n');
    }

    std::unordered_map<std::string, FILE*> files;
    char delim = delimiter.c_str()[0];

    long long fpos = ftell(fh);
    char line[BLOCK_SIZE];
    int rb;
    int pos, s_pos,e_pos;
    FILE *fo;

    std::unordered_map<long long, shard> int_shard_cache; 
    std::unordered_map<std::string, shard> string_shard_cache; 
    std::unordered_map<long long,shard>::const_iterator find_int_shard_cache; 
    std::unordered_map<std::string,shard>::const_iterator find_string_shard_cache; 

    long long mapcount = 0;

    while(!feof(fh)) {
      if(fgets(line, BLOCK_SIZE,fh) == NULL) break;
      rb=strlen(line);

      if(line[rb-2] == delim) {
        line[rb-2]='\n';
        line[rb-1]='\0';
        rb-=1;
      }
      pos=1;
      std::string v = "";
      s_pos,e_pos=0;
      for(i=0;i<rb;++i) {
        if(line[i] == delim) {
          pos++;
          continue;
        }
        if(pos == column_pos) v += line[i];
        if(pos > column_pos) {
           break;
        }
      }

      shard s;
      if(datatype == "integer") {
        long long l = atoll(v.c_str());
        find_int_shard_cache = int_shard_cache.find(l);
        if (find_int_shard_cache != int_shard_cache.end()) {
          s = find_int_shard_cache->second; 
        } else {
          ++mapcount;
          s = map(conn, schema_id, column_id, l);
          int_shard_cache[l] = s;
        }
      } else {
        find_string_shard_cache = string_shard_cache.find(v);
        if (find_string_shard_cache != string_shard_cache.end()) {
          s = find_string_shard_cache->second; 
        } else {
          ++mapcount;
          s = map(conn, schema_id, column_id, v);
          string_shard_cache[v] = s;
        }
      }

      find_file = files.find(s.shard_name);
      if( find_file != files.end()) {
        fo = find_file->second;
      } else {
        find_shard = shards.find(s.shard_name);
        std::string path;
        if(find_shard != shards.end()) {
          path = shared_path + "/loader/split/" + (find_shard->second).host+ "/" + (find_shard->second).db + "/" + table + "/";
        } else {
          std::cerr << "ERROR: shard not found in unordered_map!\n";
          exit(-1);
        }
        system(("mkdir -p " + path).c_str());
        path += std::string(md5(std::to_string(getpid()))) + ".txt";
        files_to_load[(find_shard->second).shard_name + "::" + (find_shard->second).db + "::" + table + "::" + path] = 1;
        if(!(fo = fopen(path.c_str(), "wb"))) {
          std::cerr << "Could not open: " << path << " for writing\n";
          exit(-1);
        }
        files[s.shard_name] = fo;
      }

      wb = fwrite(line, 1, rb, fo);
      if( wb != rb ) {
        std::cerr << "ERROR: io error\n";
        exit(-1);
      }

      ++linecount;

      if(ftell(fh) >= end) break;
    }
    std::chrono::steady_clock::time_point end= std::chrono::steady_clock::now();
    std::cerr << "LINES: " << linecount << " MAPS: " << mapcount << " TIME(ms): " << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count(); 

  }

 for ( auto it = files_to_load.begin(); it != files_to_load.end(); ++it ) {
    std::cerr << "|" << it->first  ;
 }
 std::cerr << "\n";
  
}