ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ImageFileImpl.cpp
Go to the documentation of this file.
1 /*
2  * Original work Copyright 2009 - 2010 Kevin Ackley (kackley@gwi.net)
3  * Modified work Copyright 2018 - 2020 Andy Maloney <asmaloney@gmail.com>
4  *
5  * Permission is hereby granted, free of charge, to any person or organization
6  * obtaining a copy of the software and accompanying documentation covered by
7  * this license (the "Software") to use, reproduce, display, distribute,
8  * execute, and transmit the Software, and to prepare derivative works of the
9  * Software, and to permit third-parties to whom the Software is furnished to
10  * do so, all subject to the following:
11  *
12  * The copyright notices in the Software and this entire statement, including
13  * the above license grant, this restriction and the following disclaimer,
14  * must be included in all copies of the Software, in whole or in part, and
15  * all derivative works of the Software, unless such copies or derivative
16  * works are solely in the form of machine-executable object code generated by
17  * a source language processor.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  * DEALINGS IN THE SOFTWARE.
26  */
27 
28 #include "ImageFileImpl.h"
29 #include "CheckedFile.h"
30 #include "E57Version.h"
31 #include "E57XmlParser.h"
32 #include "StructureNodeImpl.h"
33 
34 namespace e57
35 {
36  struct NameSpace
37  {
40 
41  NameSpace( const ustring &prefix0, const ustring &uri0 ) : prefix( prefix0 ), uri( uri0 )
42  {
43  }
44  };
45 
47  {
48  char fileSignature[8] = {};
49  uint32_t majorVersion = 0;
50  uint32_t minorVersion = 0;
51  uint64_t filePhysicalLength = 0;
52  uint64_t xmlPhysicalOffset = 0;
53  uint64_t xmlLogicalLength = 0;
54  uint64_t pageSize = 0;
55  // char e57LibraryVersion[8]; //Not in V1.0 Standard
56 
57 #ifdef E57_DEBUG
58  void dump( int indent = 0, std::ostream &os = std::cout ) const;
59 #endif
60  };
61 
62 #ifdef E57_DEBUG
63  void E57FileHeader::dump( int indent, std::ostream &os ) const
64  {
65  os << space( indent ) << "fileSignature: ";
66  os.write( fileSignature, sizeof( fileSignature ) );
67  os << std::endl;
68  os << space( indent ) << "majorVersion: " << majorVersion << std::endl;
69  os << space( indent ) << "minorVersion: " << minorVersion << std::endl;
70  os << space( indent ) << "filePhysicalLength: " << filePhysicalLength << std::endl;
71  os << space( indent ) << "xmlPhysicalOffset: " << xmlPhysicalOffset << std::endl;
72  os << space( indent ) << "xmlLogicalLength: " << xmlLogicalLength << std::endl;
73  os << space( indent ) << "pageSize: " << pageSize << std::endl;
74  }
75 #endif
76 
78  isWriter_( false ), writerCount_( 0 ), readerCount_( 0 ),
79  checksumPolicy( std::max( 0, std::min( policy, 100 ) ) ), file_( nullptr ), xmlLogicalOffset_( 0 ),
80  xmlLogicalLength_( 0 ), unusedLogicalStart_( 0 )
81  {
84  }
85 
86  void ImageFileImpl::construct2( const ustring &fileName, const ustring &mode )
87  {
89 
90 #ifdef E57_MAX_VERBOSE
91  std::cout << "ImageFileImpl() called, fileName=" << fileName << " mode=" << mode << std::endl;
92 #endif
93  unusedLogicalStart_ = sizeof( E57FileHeader );
94  fileName_ = fileName;
95 
97  ImageFileImplSharedPtr imf = shared_from_this();
98 
99  // Accept "w" or "r" modes
100  isWriter_ = ( mode == "w" );
101 
102  if ( !isWriter_ && ( mode != "r" ) )
103  {
104  throw E57_EXCEPTION2( E57_ERROR_BAD_API_ARGUMENT, "mode=" + ustring( mode ) );
105  }
106 
107  file_ = nullptr;
108 
109  // Writing
110  if ( isWriter_ )
111  {
112  try
113  {
115  file_ = new CheckedFile( fileName_, CheckedFile::WriteCreate, checksumPolicy );
116 
117  std::shared_ptr<StructureNodeImpl> root( new StructureNodeImpl( imf ) );
118  root_ = root;
119  root_->setAttachedRecursive();
120 
121  unusedLogicalStart_ = sizeof( E57FileHeader );
122  xmlLogicalOffset_ = 0;
123  xmlLogicalLength_ = 0;
124  }
125  catch ( ... )
126  {
127  delete file_;
128  file_ = nullptr;
129 
130  throw;
131  }
132 
133  return;
134  }
135 
136  // Reading
137  try
138  {
140  file_ = new CheckedFile( fileName_, CheckedFile::ReadOnly, checksumPolicy );
141 
142  std::shared_ptr<StructureNodeImpl> root( new StructureNodeImpl( imf ) );
143  root_ = root;
144  root_->setAttachedRecursive();
145 
146  E57FileHeader header;
147  readFileHeader( file_, header );
148 
149  xmlLogicalOffset_ = file_->physicalToLogical( header.xmlPhysicalOffset );
150  xmlLogicalLength_ = header.xmlLogicalLength;
151  }
152  catch ( ... )
153  {
154  delete file_;
155  file_ = nullptr;
156 
157  throw;
158  }
159 
160  try
161  {
163  E57XmlParser parser( imf );
164 
165  parser.init();
166 
168  E57XmlFileInputSource xmlSection( file_, xmlLogicalOffset_, xmlLogicalLength_ );
169 
170  unusedLogicalStart_ = sizeof( E57FileHeader );
171 
173  parser.parse( xmlSection );
174  }
175  catch ( ... )
176  {
177  delete file_;
178  file_ = nullptr;
179 
180  throw;
181  }
182  }
183 
184  void ImageFileImpl::construct2( const char *input, const uint64_t size )
185  {
187 
188 #ifdef E57_MAX_VERBOSE
189  std::cout << "ImageFileImpl() called, fileName=<StreamBuffer> mode=r" << std::endl;
190 #endif
191  unusedLogicalStart_ = sizeof( E57FileHeader );
192  fileName_ = "<StreamBuffer>";
193 
195  ImageFileImplSharedPtr imf = shared_from_this();
196 
197  isWriter_ = false;
198  file_ = nullptr;
199 
200  try
201  {
203  file_ = new CheckedFile( input, size, checksumPolicy );
204 
205  std::shared_ptr<StructureNodeImpl> root( new StructureNodeImpl( imf ) );
206  root_ = root;
207  root_->setAttachedRecursive();
208 
209  E57FileHeader header;
210  readFileHeader( file_, header );
211 
212  xmlLogicalOffset_ = file_->physicalToLogical( header.xmlPhysicalOffset );
213  xmlLogicalLength_ = header.xmlLogicalLength;
214  }
215  catch ( ... )
216  {
217  delete file_;
218  file_ = nullptr;
219 
220  throw;
221  }
222 
223  try
224  {
226  E57XmlParser parser( imf );
227 
228  parser.init();
229 
231  E57XmlFileInputSource xmlSection( file_, xmlLogicalOffset_, xmlLogicalLength_ );
232 
233  unusedLogicalStart_ = sizeof( E57FileHeader );
234 
236  parser.parse( xmlSection );
237  }
238  catch ( ... )
239  {
240  delete file_;
241  file_ = nullptr;
242 
243  throw;
244  }
245  }
246 
248  {
249  writerCount_++;
250  }
251 
253  {
254  writerCount_--;
255 #ifdef E57_MAX_DEBUG
256  if ( writerCount_ < 0 )
257  {
258  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "fileName=" + fileName_ +
259  " writerCount=" + toString( writerCount_ ) +
260  " readerCount=" + toString( readerCount_ ) );
261  }
262 #endif
263  }
264 
266  {
267  readerCount_++;
268  }
269 
271  {
272  readerCount_--;
273 #ifdef E57_MAX_DEBUG
274  if ( readerCount_ < 0 )
275  {
276  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "fileName=" + fileName_ +
277  " writerCount=" + toString( writerCount_ ) +
278  " readerCount=" + toString( readerCount_ ) );
279  }
280 #endif
281  }
282 
283  std::shared_ptr<StructureNodeImpl> ImageFileImpl::root()
284  {
285  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
286 
287  return root_;
288  }
289 
291  {
293  if ( file_ == nullptr )
294  {
295  return;
296  }
297 
298  if ( isWriter_ )
299  {
301  xmlLogicalOffset_ = unusedLogicalStart_;
302  file_->seek( xmlLogicalOffset_, CheckedFile::Logical );
303  uint64_t xmlPhysicalOffset = file_->position( CheckedFile::Physical );
304  *file_ << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
305 #ifdef E57_OXYGEN_SUPPORT //??? \
306  //??? *file_ << "<?oxygen \
307  // RNGSchema=\"file:/C:/kevin/astm/DataFormat/xif/las_v0_05.rnc\" \
308  // type=\"compact\"?>\n";
309 #endif
310 
311  //??? need to add name space attributes to e57Root
312  root_->writeXml( shared_from_this(), *file_, 0, "e57Root" );
313 
315  while ( ( file_->position( CheckedFile::Logical ) - xmlLogicalOffset_ ) % 4 != 0 )
316  {
317  *file_ << " ";
318  }
319 
321  xmlLogicalLength_ = file_->position( CheckedFile::Logical ) - xmlLogicalOffset_;
322 
324  E57FileHeader header;
325 
326  memcpy( &header.fileSignature, "ASTM-E57", 8 );
327 
331  header.xmlPhysicalOffset = xmlPhysicalOffset;
332  header.xmlLogicalLength = xmlLogicalLength_;
334 #ifdef E57_MAX_VERBOSE
335  header.dump();
336 #endif
337 
339  file_->seek( 0 );
340  file_->write( reinterpret_cast<char *>( &header ), sizeof( header ) );
341 
342  file_->close();
343  }
344 
345  delete file_;
346  file_ = nullptr;
347  }
348 
350  {
352  if ( file_ == nullptr )
353  {
354  return;
355  }
356 
359  if ( isWriter_ )
360  {
361  file_->unlink();
362  }
363  else
364  {
365  file_->close();
366  }
367 
368  delete file_;
369  file_ = nullptr;
370  }
371 
373  {
374  return ( file_ != nullptr );
375  }
376 
378  {
379  return isWriter_;
380  }
381 
383  {
384  return writerCount_;
385  }
386 
388  {
389  return readerCount_;
390  }
391 
393  {
397  try
398  {
399  cancel();
400  }
401  catch ( ... )
402  {
403  };
404 
406  delete file_;
407  file_ = nullptr;
408  }
409 
410  uint64_t ImageFileImpl::allocateSpace( uint64_t byteCount, bool doExtendNow )
411  {
412  uint64_t oldLogicalStart = unusedLogicalStart_;
413 
415  unusedLogicalStart_ += byteCount;
416 
419  if ( doExtendNow )
420  {
421  file_->extend( unusedLogicalStart_ );
422  }
423 
424  return oldLogicalStart;
425  }
426 
428  {
429  return file_;
430  }
431 
433  {
434  // don't checkImageFileOpen, since need to get fileName to report not open
435  return fileName_;
436  }
437 
438  void ImageFileImpl::extensionsAdd( const ustring &prefix, const ustring &uri )
439  {
440  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
441  //??? check if prefix characters ok, check if uri has a double quote char
442  //(others?)
443 
445  ustring dummy;
446 
447  if ( extensionsLookupPrefix( prefix, dummy ) )
448  {
449  throw E57_EXCEPTION2( E57_ERROR_DUPLICATE_NAMESPACE_PREFIX, "prefix=" + prefix + " uri=" + uri );
450  }
451 
452  if ( extensionsLookupUri( uri, dummy ) )
453  {
454  throw E57_EXCEPTION2( E57_ERROR_DUPLICATE_NAMESPACE_URI, "prefix=" + prefix + " uri=" + uri );
455  ;
456  }
457 
459  nameSpaces_.emplace_back( prefix, uri );
460  }
461 
462  bool ImageFileImpl::extensionsLookupPrefix( const ustring &prefix, ustring &uri ) const
463  {
464  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
465 
467  std::vector<NameSpace>::const_iterator it;
468 
469  for ( it = nameSpaces_.begin(); it < nameSpaces_.end(); ++it )
470  {
471  if ( it->prefix == prefix )
472  {
473  uri = it->uri;
474  return true;
475  }
476  }
477 
478  return false;
479  }
480 
481  bool ImageFileImpl::extensionsLookupUri( const ustring &uri, ustring &prefix ) const
482  {
483  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
484 
486  std::vector<NameSpace>::const_iterator it;
487 
488  for ( it = nameSpaces_.begin(); it < nameSpaces_.end(); ++it )
489  {
490  if ( it->uri == uri )
491  {
492  prefix = it->prefix;
493  return true;
494  }
495  }
496 
497  return false;
498  }
499 
501  {
502  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
503 
504  return nameSpaces_.size();
505  }
506 
507  ustring ImageFileImpl::extensionsPrefix( const size_t index ) const
508  {
509  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
510 
511  return nameSpaces_[index].prefix; //??? throw e57 exception here if out of bounds?
512  }
513 
514  ustring ImageFileImpl::extensionsUri( const size_t index ) const
515  {
516  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
517 
518  return nameSpaces_[index].uri; //??? throw e57 exception here if out of bounds?
519  }
520 
522  {
524 
526  size_t found = elementName.find_first_of( '/' );
527 
528  if ( found != std::string::npos )
529  {
530  return false;
531  }
532 
533  ustring prefix, localPart;
534 
535  try
536  {
538  elementNameParse( elementName, prefix, localPart );
539  }
540  catch ( E57Exception & /*ex*/ )
541  {
542  return false;
543  }
544 
546  return ( prefix.length() > 0 );
547  }
548 
549  bool ImageFileImpl::isElementNameLegal( const ustring &elementName, bool allowNumber )
550  {
551 #ifdef E57_MAX_VERBOSE
552  // cout << "isElementNameLegal elementName=""" << elementName << """" <<
553  // std::endl;
554 #endif
555  try
556  {
557  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
558 
560  checkElementNameLegal( elementName, allowNumber );
561  }
562  catch ( E57Exception & /*ex*/ )
563  {
564  return false;
565  }
566 
568  return true;
569  }
570 
571  bool ImageFileImpl::isPathNameLegal( const ustring &pathName )
572  {
573 #ifdef E57_MAX_VERBOSE
574  // cout << "isPathNameLegal elementName=""" << pathName << """" << std::endl;
575 #endif
576  try
577  {
578  checkImageFileOpen( __FILE__, __LINE__, static_cast<const char *>( __FUNCTION__ ) );
579 
581  pathNameCheckWellFormed( pathName );
582  }
583  catch ( E57Exception & /*ex*/ )
584  {
585  return false;
586  }
587 
589  return true;
590  }
591 
592  void ImageFileImpl::checkElementNameLegal( const ustring &elementName, bool allowNumber )
593  {
595 
596  ustring prefix;
597  ustring localPart;
598 
600  elementNameParse( elementName, prefix, localPart, allowNumber );
601 
603  ustring uri;
604 
605  if ( prefix.length() > 0 && !extensionsLookupPrefix( prefix, uri ) )
606  {
607  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName + " prefix=" + prefix );
608  }
609  }
610 
611  void ImageFileImpl::elementNameParse( const ustring &elementName, ustring &prefix, ustring &localPart,
612  bool allowNumber )
613  {
615 
616  //??? check if elementName is good UTF-8?
617 
618  size_t len = elementName.length();
619 
621  if ( len == 0 )
622  {
623  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName );
624  }
625 
626  unsigned char c = elementName[0];
627 
629  if ( allowNumber && '0' <= c && c <= '9' )
630  {
632  for ( size_t i = 1; i < len; i++ )
633  {
634  c = elementName[i];
635 
636  if ( !( '0' <= c && c <= '9' ) )
637  {
638  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName );
639  }
640  }
641 
642  return;
643  }
644 
648  if ( c < 128 && !( ( 'a' <= c && c <= 'z' ) || ( 'A' <= c && c <= 'Z' ) || c == '_' ) )
649  {
650  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName );
651  }
652 
655  for ( size_t i = 1; i < len; i++ )
656  {
657  c = elementName[i];
658 
659  if ( c < 128 && !( ( 'a' <= c && c <= 'z' ) || ( 'A' <= c && c <= 'Z' ) || c == '_' || c == ':' ||
660  ( '0' <= c && c <= '9' ) || c == '-' || c == '.' ) )
661  {
662  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName );
663  }
664  }
665 
667  size_t found = elementName.find_first_of( ':' );
668 
669  if ( found != std::string::npos )
670  {
672  if ( elementName.find_first_of( ':', found + 1 ) != std::string::npos )
673  {
674  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "elementName=" + elementName );
675  }
676 
679  prefix = elementName.substr( 0, found );
680  localPart = elementName.substr( found + 1 );
681 
682  if ( prefix.length() == 0 || localPart.length() == 0 )
683  {
685  "elementName=" + elementName + " prefix=" + prefix + " localPart=" + localPart );
686  }
687  }
688  else
689  {
690  prefix = "";
691  localPart = elementName;
692  }
693  }
694 
696  {
698 
700  bool isRelative = false;
702 
703  pathNameParse( pathName, isRelative, fields );
704  }
705 
706  void ImageFileImpl::pathNameParse( const ustring &pathName, bool &isRelative, StringList &fields )
707  {
708 #ifdef E57_MAX_VERBOSE
709  std::cout << "pathNameParse pathname="
710  ""
711  << pathName
712  << ""
713  ""
714  << std::endl;
715 #endif
717 
719  fields.clear();
720 
721  size_t start = 0;
722 
724  if ( pathName[start] == '/' )
725  {
726  isRelative = false;
727  start = 1;
728  }
729  else
730  {
731  isRelative = true;
732  }
733 
736  while ( start < pathName.size() )
737  {
738  size_t slash = pathName.find_first_of( '/', start );
739 
741  ustring elementName = pathName.substr( start, slash - start );
742 
743  if ( !isElementNameLegal( elementName ) )
744  {
745  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "pathName=" + pathName + " elementName=" + elementName );
746  }
747 
749  fields.push_back( elementName );
750 
751  if ( slash == std::string::npos )
752  {
753  break;
754  }
755 
758  if ( slash == pathName.size() - 1 )
759  {
760  fields.emplace_back( "" );
761  break;
762  }
763 
765  start = slash + 1;
766  }
767 
769  if ( isRelative && fields.empty() )
770  {
771  throw E57_EXCEPTION2( E57_ERROR_BAD_PATH_NAME, "pathName=" + pathName );
772  }
773 
774 #ifdef E57_MAX_VERBOSE
775  std::cout << "pathNameParse returning: isRelative=" << isRelative << " fields.size()=" << fields.size()
776  << " fields=";
777  for ( size_t i = 0; i < fields.size(); i++ )
778  {
779  std::cout << fields[i] << ",";
780  }
781  std::cout << std::endl;
782 #endif
783  }
784 
785  ustring ImageFileImpl::pathNameUnparse( bool isRelative, const std::vector<ustring> &fields )
786  {
787  ustring path;
788 
789  if ( !isRelative )
790  {
791  path.push_back( '/' );
792  }
793 
794  for ( unsigned i = 0; i < fields.size(); ++i )
795  {
796  path.append( fields.at( i ) );
797 
798  if ( i < fields.size() - 1 )
799  {
800  path.push_back( '/' );
801  }
802  }
803 
804  return path;
805  }
806 
807  void ImageFileImpl::readFileHeader( CheckedFile *file, E57FileHeader &header )
808  {
811  static_assert( sizeof( E57FileHeader ) == 48, "Unexpected size of E57FileHeader" );
812 
814  file->read( reinterpret_cast<char *>( &header ), sizeof( header ) );
815 
816 #ifdef E57_MAX_VERBOSE
817  header.dump();
818 #endif
819 
821  if ( strncmp( header.fileSignature, "ASTM-E57", 8 ) != 0 )
822  {
823  throw E57_EXCEPTION2( E57_ERROR_BAD_FILE_SIGNATURE, "fileName=" + file->fileName() );
824  }
825 
827  if ( header.majorVersion > E57_FORMAT_MAJOR )
828  {
830  "fileName=" + file->fileName() +
831  " header.majorVersion=" + toString( header.majorVersion ) +
832  " header.minorVersion=" + toString( header.minorVersion ) );
833  }
834 
838  if ( header.majorVersion == E57_FORMAT_MAJOR && header.minorVersion > E57_FORMAT_MINOR )
839  {
841  "fileName=" + file->fileName() +
842  " header.majorVersion=" + toString( header.majorVersion ) +
843  " header.minorVersion=" + toString( header.minorVersion ) );
844  }
845 
848  {
850  "fileName=" + file->fileName() +
851  " header.filePhysicalLength=" + toString( header.filePhysicalLength ) +
852  " file->length=" + toString( file->length( CheckedFile::Physical ) ) );
853  }
854 
856  if ( header.majorVersion != 0 && header.pageSize != CheckedFile::physicalPageSize )
857  {
858  throw E57_EXCEPTION2( E57_ERROR_BAD_FILE_LENGTH, "fileName=" + file->fileName() );
859  }
860  }
861 
862  void ImageFileImpl::checkImageFileOpen( const char *srcFileName, int srcLineNumber,
863  const char *srcFunctionName ) const
864  {
865  if ( !isOpen() )
866  {
867  throw E57Exception( E57_ERROR_IMAGEFILE_NOT_OPEN, "fileName=" + fileName(), srcFileName, srcLineNumber,
868  srcFunctionName );
869  }
870  }
871 
872  void ImageFileImpl::dump( int indent, std::ostream &os ) const
873  {
875  os << space( indent ) << "fileName: " << fileName_ << std::endl;
876  os << space( indent ) << "writerCount: " << writerCount_ << std::endl;
877  os << space( indent ) << "readerCount: " << readerCount_ << std::endl;
878  os << space( indent ) << "isWriter: " << isWriter_ << std::endl;
879  for ( size_t i = 0; i < extensionsCount(); i++ )
880  {
881  os << space( indent ) << "nameSpace[" << i << "]: prefix=" << extensionsPrefix( i )
882  << " uri=" << extensionsUri( i ) << std::endl;
883  }
884  os << space( indent ) << "root: " << std::endl;
885  root_->dump( indent + 2, os );
886  }
887 
888  unsigned ImageFileImpl::bitsNeeded( int64_t minimum, int64_t maximum )
889  {
895 
896  uint64_t stateCountMinus1 = maximum - minimum;
897 
898  unsigned log2 = 0;
899 
900  if ( stateCountMinus1 & 0xFFFFFFFF00000000LL )
901  {
902  stateCountMinus1 >>= 32;
903  log2 += 32;
904  }
905 
906  if ( stateCountMinus1 & 0xFFFF0000LL )
907  {
908  stateCountMinus1 >>= 16;
909  log2 += 16;
910  }
911 
912  if ( stateCountMinus1 & 0xFF00LL )
913  {
914  stateCountMinus1 >>= 8;
915  log2 += 8;
916  }
917 
918  if ( stateCountMinus1 & 0xF0LL )
919  {
920  stateCountMinus1 >>= 4;
921  log2 += 4;
922  }
923 
924  if ( stateCountMinus1 & 0xCLL )
925  {
926  stateCountMinus1 >>= 2;
927  log2 += 2;
928  }
929 
930  if ( stateCountMinus1 & 0x2LL )
931  {
932  stateCountMinus1 >>= 1;
933  log2 += 1;
934  }
935 
936  if ( stateCountMinus1 & 1LL )
937  {
938  log2++;
939  }
940 
941  return log2;
942  }
943 }
int size
std::vector< PCLPointField > fields
#define E57_EXCEPTION2(ecode, context)
Definition: Common.h:68
void write(const char *buf, size_t nWrite)
static constexpr size_t physicalPageSize
Definition: CheckedFile.h:46
void read(char *buf, size_t nRead, size_t bufSize=0)
void extend(uint64_t newLength, OffsetMode omode=Logical)
uint64_t position(OffsetMode omode=Logical)
static uint64_t physicalToLogical(uint64_t physicalOffset)
Definition: CheckedFile.h:120
e57::ustring fileName() const
Definition: CheckedFile.h:79
uint64_t length(OffsetMode omode=Logical)
void seek(uint64_t offset, OffsetMode omode=Logical)
Object thrown by E57 API functions to communicate the conditions of an error.
Definition: E57Exception.h:100
void parse(InputSource &inputSource)
ImageFileImpl(ReadChecksumPolicy policy)
std::shared_ptr< StructureNodeImpl > root()
bool isElementNameLegal(const ustring &elementName, bool allowNumber=true)
CheckedFile * file() const
bool isWriter() const
void dump(int indent=0, std::ostream &os=std::cout) const
Diagnostic functions:
int writerCount() const
int readerCount() const
void extensionsAdd(const ustring &prefix, const ustring &uri)
Manipulate registered extensions in the file.
unsigned bitsNeeded(int64_t minimum, int64_t maximum)
size_t extensionsCount() const
void checkElementNameLegal(const ustring &elementName, bool allowNumber=true)
bool extensionsLookupUri(const ustring &uri, ustring &prefix) const
void construct2(const ustring &fileName, const ustring &mode)
ustring pathNameUnparse(bool isRelative, const StringList &fields)
uint64_t allocateSpace(uint64_t byteCount, bool doExtendNow)
bool isPathNameLegal(const ustring &pathName)
void pathNameParse(const ustring &pathName, bool &isRelative, StringList &fields)
bool isElementNameExtended(const ustring &elementName)
Utility functions:
ustring fileName() const
void elementNameParse(const ustring &elementName, ustring &prefix, ustring &localPart, bool allowNumber=true)
ustring extensionsPrefix(const size_t index) const
bool extensionsLookupPrefix(const ustring &prefix, ustring &uri) const
ustring extensionsUri(const size_t index) const
void pathNameCheckWellFormed(const ustring &pathName)
int min(int a, int b)
Definition: cutil_math.h:53
int max(int a, int b)
Definition: cutil_math.h:48
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
static const std::string path
Definition: PointCloud.cpp:59
constexpr uint32_t E57_FORMAT_MAJOR
Version numbers of ASTM standard that this library supports.
Definition: E57Version.h:10
int ReadChecksumPolicy
Specifies the percentage of checksums which are verified when reading an ImageFile (0-100%).
Definition: E57Format.h:95
std::shared_ptr< class ImageFileImpl > ImageFileImplSharedPtr
Definition: Common.h:188
@ E57_ERROR_INTERNAL
An unrecoverable inconsistent internal state was detected.
Definition: E57Exception.h:56
@ E57_ERROR_BAD_API_ARGUMENT
bad API function argument provided by user
Definition: E57Exception.h:59
@ E57_ERROR_BAD_FILE_SIGNATURE
file signature not "ASTM-E57"
Definition: E57Exception.h:73
@ E57_ERROR_IMAGEFILE_NOT_OPEN
destImageFile is no longer open
Definition: E57Exception.h:91
@ E57_ERROR_BAD_FILE_LENGTH
size in file header not same as actual
Definition: E57Exception.h:75
@ E57_ERROR_UNKNOWN_FILE_VERSION
incompatible file version
Definition: E57Exception.h:74
@ E57_ERROR_BAD_PATH_NAME
E57 path name is not well formed.
Definition: E57Exception.h:83
@ E57_ERROR_DUPLICATE_NAMESPACE_PREFIX
namespace prefix already defined
Definition: E57Exception.h:77
@ E57_ERROR_DUPLICATE_NAMESPACE_URI
namespace URI already defined
Definition: E57Exception.h:78
std::string ustring
UTF-8 encodeded Unicode string.
Definition: E57Format.h:54
constexpr uint32_t E57_FORMAT_MINOR
Definition: E57Version.h:11
std::string toString(T x)
Definition: Common.h:80
std::vector< std::string > StringList
Definition: Common.h:193
std::string space(size_t n)
Definition: Common.h:73
Definition: Eigen.h:85
uint64_t filePhysicalLength
void dump(int indent=0, std::ostream &os=std::cout) const
uint64_t xmlPhysicalOffset
NameSpace(const ustring &prefix0, const ustring &uri0)