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(); }
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); } }
/** * @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(); }
//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); }
//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); } }
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; }
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; }
/* ==================================== */ 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()
//-------------------------------------------------------------------------- // 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()); } }
/* ==================================== */ 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(); }
//-------------------------------------------------------------------------- // 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()); } }
//! 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; }
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)); } }
/* =============================================================== */ 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() */
/* ==================================== */ 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() */
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(); }
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); }
/* ==================================== */ 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() */
/* ==================================== */ 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() */
/* ==================================== */ 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() */
/* ==================================== */ 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() */
/* ==================================== */ 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() */
/* ==================================== */ 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()
/* ==================================== */ 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()
/* ==================================== */ 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()
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"; }