@@ -165,7 +165,57 @@ void G2SBigTiffDataset::load(const std::string& path, bool dio)
165165 if (dsname.find (" .g2s" ) == dsname.size () - 4 )
166166 dsname = dsname.substr (0 , dsname.size () - 4 );
167167
168+ // Determine file name prefix
169+ std::string fprefix = " " ;
170+ for (const auto & entry : std::filesystem::directory_iterator (xp))
171+ {
172+ // Skip auto folder paths
173+ auto fname = entry.path ().filename ().u8string ();
174+ if (fname == " ." || fname == " .." )
175+ continue ;
176+
177+ // Skip folders
178+ if (std::filesystem::is_directory (entry))
179+ continue ;
180+
181+ // Skip unsupported file formats
182+ auto fext = entry.path ().extension ().u8string ();
183+ if (fext.size () == 0 )
184+ continue ;
185+ if (fext[0 ] == ' .' )
186+ fext = fext.substr (1 );
187+ std::transform (fext.begin (), fext.end (), fext.begin (), [](char c) { return (char )tolower (c); });
188+ if (fext != " tiff" && fext != " tif" && fext != " g2s.tiff" && fext != " g2s.tif" )
189+ continue ;
190+
191+ auto fx = fname.substr (0 , fname.length () - fext.size () - 1 );
192+ if (fx.find (" .g2s" ) != std::string::npos)
193+ fx = fx.substr (0 , fname.find (" .g2s" ));
194+
195+ if (fprefix.empty ())
196+ // First file -> use the entire file name
197+ fprefix = fx;
198+ else if (fx.find (fprefix) == 0 )
199+ // File name starts with the file prefix
200+ continue ;
201+ else
202+ {
203+ // File prefix is invalid -> Try shorter file prefix
204+ auto lind = fprefix.find_last_of (' _' );
205+ while (lind != std::string::npos)
206+ {
207+ fprefix = fprefix.substr (0 , lind);
208+ if (fx.find (fprefix) == 0 )
209+ break ;
210+ lind = fprefix.find_last_of (' _' );
211+ }
212+ if (fx.find (fprefix) != 0 )
213+ throw std::runtime_error (" Unable to load a dataset. Data chunk file name missmatch" );
214+ }
215+ }
216+
168217 // Enumerate files
218+ std::vector<std::uint32_t > dcindex;
169219 for (const auto & entry : std::filesystem::directory_iterator (xp))
170220 {
171221 // Skip auto folder paths
@@ -187,26 +237,72 @@ void G2SBigTiffDataset::load(const std::string& path, bool dio)
187237 if (fext != " tiff" && fext != " tif" && fext != " g2s.tiff" && fext != " g2s.tif" )
188238 continue ;
189239
190- // We found a supported file type -> Add to results list
240+ // Determine absolute path and create chunk descriptor
191241 auto abspath = std::filesystem::absolute (entry).u8string ();
192242 auto dchunk = std::make_shared<G2SBigTiffStream>(abspath, directIo);
193- datachunks.push_back (dchunk);
243+
244+ // Determine chunk index from a file name
245+ std::uint32_t cind = 0 ;
246+ auto findtoken = fname.substr (0 , fname.length () - fext.size () - 1 );
247+ if (findtoken.find (" .g2s" ) != std::string::npos)
248+ findtoken = findtoken.substr (0 , fname.find (" .g2s" ));
249+ findtoken = findtoken.substr (fprefix.length ());
250+ if (!findtoken.empty ())
251+ {
252+ if (findtoken[0 ] == ' _' )
253+ findtoken = findtoken.substr (1 );
254+ try { cind = std::stoul (findtoken); } catch (...) { }
255+ }
256+
257+ // Check if chunk index is valid and determine insert index
258+ std::int64_t iind = -1 ;
259+ for (std::size_t i = 0 ; i < dcindex.size (); i++)
260+ {
261+ if (dcindex[i] >= cind)
262+ {
263+ iind = (std::int64_t )i;
264+ break ;
265+ }
266+ }
267+ if (iind < 0 )
268+ {
269+ datachunks.push_back (dchunk);
270+ dcindex.push_back (cind);
271+ }
272+ else
273+ {
274+ auto cit = datachunks.begin ();
275+ std::advance (cit, iind);
276+ auto iit = dcindex.begin ();
277+ std::advance (iit, iind);
278+
279+ datachunks.insert (cit, dchunk);
280+ dcindex.insert (iit, cind);
281+ }
194282 }
195283 if (datachunks.empty ())
196284 throw std::runtime_error (" Unable to load a dataset. No files found" );
197285
198286 // Load first data chunk
199- samples = 1 ;
200- imgcounter = 0 ;
201- metadata.clear ();
202- custommeta.clear ();
203- activechunk = datachunks.front ();
204- activechunk->open (false );
205- activechunk->parse (datasetuid, shape, chunksize, metadata, bitdepth);
206- imgcounter += activechunk->getImageCount ();
207- resetAxisInfo ();
208- parseAxisInfo ();
209- parseCustomMetadata ();
287+ try
288+ {
289+ samples = 1 ;
290+ imgcounter = 0 ;
291+ metadata.clear ();
292+ custommeta.clear ();
293+ activechunk = datachunks.front ();
294+ activechunk->open (false );
295+ activechunk->parse (datasetuid, shape, chunksize, metadata, bitdepth);
296+ imgcounter += activechunk->getImageCount ();
297+ resetAxisInfo ();
298+ parseAxisInfo ();
299+ parseCustomMetadata ();
300+ }
301+ catch (std::exception&)
302+ {
303+ close ();
304+ throw ;
305+ }
210306
211307 // Validate dataset parameters
212308 if (activechunk->getChunkIndex () != 0 )
@@ -231,11 +327,19 @@ void G2SBigTiffDataset::load(const std::string& path, bool dio)
231327 }
232328
233329 // Parse headers for other data chunks
234- for (std:: size_t i = 1 ; i < datachunks. size (); i++)
330+ try
235331 {
236- validateDataChunk ((std::uint32_t )i, false );
237- imgcounter += datachunks[i]->getImageCount ();
238- datachunks[i]->close ();
332+ for (std::size_t i = 1 ; i < datachunks.size (); i++)
333+ {
334+ validateDataChunk ((std::uint32_t )i, false );
335+ imgcounter += datachunks[i]->getImageCount ();
336+ datachunks[i]->close ();
337+ }
338+ }
339+ catch (std::exception&)
340+ {
341+ close ();
342+ throw ;
239343 }
240344}
241345
@@ -726,6 +830,11 @@ void G2SBigTiffDataset::validateDataChunk(std::uint32_t chunkind, bool index)
726830 datachunks[chunkind]->close ();
727831 throw std::runtime_error (" Invalid data chunk. Pixel format missmatch" );
728832 }
833+ if (datachunks[chunkind]->getChunkIndex () > 0 && datachunks[chunkind]->getChunkIndex () != chunkind)
834+ {
835+ datachunks[chunkind]->close ();
836+ throw std::runtime_error (" Invalid data chunk. Chunk index missmatch" );
837+ }
729838}
730839
731840/* *
0 commit comments