ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
Encoder.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 <algorithm>
29 #include <cstring>
30 
32 #include "Encoder.h"
33 #include "FloatNodeImpl.h"
34 #include "ImageFileImpl.h"
35 #include "IntegerNodeImpl.h"
36 #include "Packet.h"
37 #include "ScaledIntegerNodeImpl.h"
38 #include "SourceDestBufferImpl.h"
39 
40 using namespace e57;
41 
42 std::shared_ptr<Encoder> Encoder::EncoderFactory( unsigned bytestreamNumber,
43  std::shared_ptr<CompressedVectorNodeImpl> cVector,
44  std::vector<SourceDestBuffer> &sbufs, ustring & /*codecPath*/ )
45 {
46  //??? For now, only handle one input
47  if ( sbufs.size() != 1 )
48  {
49  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "sbufsSize=" + toString( sbufs.size() ) );
50  }
51 
52  SourceDestBuffer sbuf = sbufs.at( 0 );
53 
55  NodeImplSharedPtr prototype = cVector->getPrototype();
56  ustring path = sbuf.pathName();
57  NodeImplSharedPtr encodeNode = prototype->get( path );
58 
59 #ifdef E57_MAX_VERBOSE
60  std::cout << "Node to encode:" << std::endl; //???
61  encodeNode->dump( 2 );
62 #endif
63  switch ( encodeNode->type() )
64  {
65  case E57_INTEGER:
66  {
67  std::shared_ptr<IntegerNodeImpl> ini =
68  std::static_pointer_cast<IntegerNodeImpl>( encodeNode ); // downcast to correct type
69 
71  ImageFileImplSharedPtr imf( encodeNode->destImageFile_ ); //??? should be function for this,
72  // imf->parentFile()
73  //--> ImageFile?
74 
75  unsigned bitsPerRecord = imf->bitsNeeded( ini->minimum(), ini->maximum() );
76 
80  if ( bitsPerRecord == 0 )
81  {
82  std::shared_ptr<Encoder> encoder( new ConstantIntegerEncoder( bytestreamNumber, sbuf, ini->minimum() ) );
83 
84  return encoder;
85  }
86 
87  if ( bitsPerRecord <= 8 )
88  {
89  std::shared_ptr<Encoder> encoder( new BitpackIntegerEncoder<uint8_t>(
90  false, bytestreamNumber, sbuf, DATA_PACKET_MAX , ini->minimum(), ini->maximum(), 1.0, 0.0 ) );
91  return encoder;
92  }
93 
94  if ( bitsPerRecord <= 16 )
95  {
96  std::shared_ptr<Encoder> encoder( new BitpackIntegerEncoder<uint16_t>(
97  false, bytestreamNumber, sbuf, DATA_PACKET_MAX , ini->minimum(), ini->maximum(), 1.0, 0.0 ) );
98  return encoder;
99  }
100 
101  if ( bitsPerRecord <= 32 )
102  {
103  std::shared_ptr<Encoder> encoder( new BitpackIntegerEncoder<uint32_t>(
104  false, bytestreamNumber, sbuf, DATA_PACKET_MAX , ini->minimum(), ini->maximum(), 1.0, 0.0 ) );
105  return encoder;
106  }
107 
108  std::shared_ptr<Encoder> encoder( new BitpackIntegerEncoder<uint64_t>(
109  false, bytestreamNumber, sbuf, DATA_PACKET_MAX , ini->minimum(), ini->maximum(), 1.0, 0.0 ) );
110  return encoder;
111  }
112 
113  case E57_SCALED_INTEGER:
114  {
115  std::shared_ptr<ScaledIntegerNodeImpl> sini =
116  std::static_pointer_cast<ScaledIntegerNodeImpl>( encodeNode ); // downcast to correct type
117 
119  ImageFileImplSharedPtr imf( encodeNode->destImageFile_ ); //??? should be function for this,
120  // imf->parentFile()
121  //--> ImageFile?
122 
123  unsigned bitsPerRecord = imf->bitsNeeded( sini->minimum(), sini->maximum() );
124 
128  if ( bitsPerRecord == 0 )
129  {
130  std::shared_ptr<Encoder> encoder( new ConstantIntegerEncoder( bytestreamNumber, sbuf, sini->minimum() ) );
131 
132  return encoder;
133  }
134 
135  if ( bitsPerRecord <= 8 )
136  {
137  std::shared_ptr<Encoder> encoder(
139  sini->minimum(), sini->maximum(), sini->scale(), sini->offset() ) );
140  return encoder;
141  }
142 
143  if ( bitsPerRecord <= 16 )
144  {
145  std::shared_ptr<Encoder> encoder(
147  sini->minimum(), sini->maximum(), sini->scale(), sini->offset() ) );
148  return encoder;
149  }
150 
151  if ( bitsPerRecord <= 32 )
152  {
153  std::shared_ptr<Encoder> encoder(
155  sini->minimum(), sini->maximum(), sini->scale(), sini->offset() ) );
156  return encoder;
157  }
158 
159  std::shared_ptr<Encoder> encoder(
160  new BitpackIntegerEncoder<uint64_t>( true, bytestreamNumber, sbuf, DATA_PACKET_MAX , sini->minimum(),
161  sini->maximum(), sini->scale(), sini->offset() ) );
162  return encoder;
163  }
164 
165  case E57_FLOAT:
166  {
167  std::shared_ptr<FloatNodeImpl> fni =
168  std::static_pointer_cast<FloatNodeImpl>( encodeNode ); // downcast to correct type
169 
171  std::shared_ptr<Encoder> encoder(
172  new BitpackFloatEncoder( bytestreamNumber, sbuf, DATA_PACKET_MAX , fni->precision() ) );
173  return encoder;
174  }
175 
176  case E57_STRING:
177  {
178  std::shared_ptr<Encoder> encoder(
180 
181  return encoder;
182  }
183 
184  default:
185  {
186  throw E57_EXCEPTION2( E57_ERROR_BAD_PROTOTYPE, "nodeType=" + toString( encodeNode->type() ) );
187  }
188  }
189 }
190 
191 Encoder::Encoder( unsigned bytestreamNumber ) : bytestreamNumber_( bytestreamNumber )
192 {
193 }
194 
195 #ifdef E57_DEBUG
196 void Encoder::dump( int indent, std::ostream &os ) const
197 {
198  os << space( indent ) << "bytestreamNumber: " << bytestreamNumber_ << std::endl;
199 }
200 #endif
201 
203 
204 BitpackEncoder::BitpackEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize,
205  unsigned alignmentSize ) :
206  Encoder( bytestreamNumber ), sourceBuffer_( sbuf.impl() ), outBuffer_( outputMaxSize ), outBufferFirst_( 0 ),
207  outBufferEnd_( 0 ), outBufferAlignmentSize_( alignmentSize ), currentRecordIndex_( 0 )
208 {
209 }
210 
212 {
213  return ( sourceBuffer_->nextIndex() );
214 }
215 
217 {
218  return ( currentRecordIndex_ );
219 }
220 
222 {
224 }
225 
226 void BitpackEncoder::outputRead( char *dest, const size_t byteCount )
227 {
228 #ifdef E57_MAX_VERBOSE
229  std::cout << "BitpackEncoder::outputRead() called, dest=" << dest << " byteCount=" << byteCount << std::endl; //???
230 #endif
231 
233  if ( byteCount > outputAvailable() )
234  {
235  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "byteCount=" + toString( byteCount ) +
236  " outputAvailable=" + toString( outputAvailable() ) );
237  }
238 
240  memcpy( dest, &outBuffer_[outBufferFirst_], byteCount );
241 
242 #ifdef E57_MAX_VERBOSE
243  {
244  unsigned i;
245  for ( i = 0; i < byteCount && i < 20; i++ )
246  {
247  std::cout << " outBuffer[" << outBufferFirst_ + i
248  << "]=" << static_cast<unsigned>( static_cast<unsigned char>( outBuffer_[outBufferFirst_ + i] ) )
249  << std::endl; //???
250  }
251 
252  if ( i < byteCount )
253  {
254  std::cout << " " << byteCount - 1 << " bytes unprinted..." << std::endl;
255  }
256  }
257 #endif
258 
260  outBufferFirst_ += byteCount;
261 
264 }
265 
267 {
268  outBufferFirst_ = 0;
269  outBufferEnd_ = 0;
270 }
271 
272 void BitpackEncoder::sourceBufferSetNew( std::vector<SourceDestBuffer> &sbufs )
273 {
275  if ( sbufs.size() != 1 )
276  {
277  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "sbufsSize=" + toString( sbufs.size() ) );
278  }
279 
280  sourceBuffer_ = sbufs.at( 0 ).impl();
281 }
282 
284 {
286  return ( outBuffer_.size() );
287 }
288 
289 void BitpackEncoder::outputSetMaxSize( unsigned byteCount )
290 {
292  if ( byteCount > outBuffer_.size() )
293  {
294  outBuffer_.resize( byteCount );
295  }
296 }
297 
299 {
304 
306  {
308  outBufferFirst_ = 0;
309  outBufferEnd_ = 0;
310  return;
311  }
312 
314  size_t newEnd = outputAvailable();
315  size_t remainder = newEnd % outBufferAlignmentSize_;
316  if ( remainder > 0 )
317  {
318  newEnd += outBufferAlignmentSize_ - remainder;
319  }
320  size_t newFirst = outBufferFirst_ - ( outBufferEnd_ - newEnd );
321  size_t byteCount = outBufferEnd_ - outBufferFirst_;
322 
324  if ( newEnd % outBufferAlignmentSize_ )
325  {
326  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "newEnd=" + toString( newEnd ) +
327  " outBufferAlignmentSize=" + toString( outBufferAlignmentSize_ ) );
328  }
329 
331  if ( newFirst + byteCount > outBuffer_.size() )
332  {
333  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "newFirst=" + toString( newFirst ) +
334  " byteCount=" + toString( byteCount ) +
335  " outBufferSize=" + toString( outBuffer_.size() ) );
336  }
337 
340  memmove( &outBuffer_[newFirst], &outBuffer_[outBufferFirst_], byteCount );
341 
343  outBufferFirst_ = newFirst;
344  outBufferEnd_ = newEnd;
345 }
346 
347 #ifdef E57_DEBUG
348 void BitpackEncoder::dump( int indent, std::ostream &os ) const
349 {
350  Encoder::dump( indent, os );
351  os << space( indent ) << "sourceBuffer:" << std::endl;
352  sourceBuffer_->dump( indent + 4, os );
353  os << space( indent ) << "outBuffer.size: " << outBuffer_.size() << std::endl;
354  os << space( indent ) << "outBufferFirst: " << outBufferFirst_ << std::endl;
355  os << space( indent ) << "outBufferEnd: " << outBufferEnd_ << std::endl;
356  os << space( indent ) << "outBufferAlignmentSize: " << outBufferAlignmentSize_ << std::endl;
357  os << space( indent ) << "currentRecordIndex: " << currentRecordIndex_ << std::endl;
358  os << space( indent ) << "outBuffer:" << std::endl;
359  unsigned i;
360  for ( i = 0; i < outBuffer_.size() && i < 20; i++ )
361  {
362  os << space( indent + 4 ) << "outBuffer[" << i
363  << "]: " << static_cast<unsigned>( static_cast<unsigned char>( outBuffer_.at( i ) ) ) << std::endl;
364  }
365  if ( i < outBuffer_.size() )
366  {
367  os << space( indent + 4 ) << outBuffer_.size() - i << " more unprinted..." << std::endl;
368  }
369 }
370 #endif
371 
372 //================
373 
374 BitpackFloatEncoder::BitpackFloatEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize,
375  FloatPrecision precision ) :
376  BitpackEncoder( bytestreamNumber, sbuf, outputMaxSize,
377  ( precision == E57_SINGLE ) ? sizeof( float ) : sizeof( double ) ),
378  precision_( precision )
379 {
380 }
381 
382 uint64_t BitpackFloatEncoder::processRecords( size_t recordCount )
383 {
384 #ifdef E57_MAX_VERBOSE
385  std::cout << " BitpackFloatEncoder::processRecords() called, recordCount=" << recordCount << std::endl; //???
386 #endif
387 
391 
392  size_t typeSize = ( precision_ == E57_SINGLE ) ? sizeof( float ) : sizeof( double );
393 
394 #ifdef E57_DEBUG
397  if ( outBufferEnd_ % typeSize )
399  "outBufferEnd=" + toString( outBufferEnd_ ) + " typeSize=" + toString( typeSize ) );
400 #endif
401 
403  size_t maxOutputRecords = ( outBuffer_.size() - outBufferEnd_ ) / typeSize;
404 
406  if ( recordCount > maxOutputRecords )
407  {
408  recordCount = maxOutputRecords;
409  }
410 
411  if ( precision_ == E57_SINGLE )
412  {
414  auto outp = reinterpret_cast<float *>( &outBuffer_[outBufferEnd_] );
415 
417  for ( unsigned i = 0; i < recordCount; i++ )
418  {
419  outp[i] = sourceBuffer_->getNextFloat();
420 #ifdef E57_MAX_VERBOSE
421  std::cout << "encoding float: " << outp[i] << std::endl;
422 #endif
423  }
424  }
425  else
426  {
428  auto outp = reinterpret_cast<double *>( &outBuffer_[outBufferEnd_] );
429 
431  for ( unsigned i = 0; i < recordCount; i++ )
432  {
433  outp[i] = sourceBuffer_->getNextDouble();
434 #ifdef E57_MAX_VERBOSE
435  std::cout << "encoding double: " << outp[i] << std::endl;
436 #endif
437  }
438  }
439 
441  outBufferEnd_ += recordCount * typeSize;
442 
444  currentRecordIndex_ += recordCount;
445 
446  return ( currentRecordIndex_ );
447 }
448 
450 {
452  return ( true );
453 }
454 
456 {
457  return ( ( precision_ == E57_SINGLE ) ? 32.0F : 64.0F );
458 }
459 
460 #ifdef E57_DEBUG
461 void BitpackFloatEncoder::dump( int indent, std::ostream &os ) const
462 {
463  BitpackEncoder::dump( indent, os );
464  if ( precision_ == E57_SINGLE )
465  {
466  os << space( indent ) << "precision: E57_SINGLE" << std::endl;
467  }
468  else
469  {
470  os << space( indent ) << "precision: E57_DOUBLE" << std::endl;
471  }
472 }
473 #endif
474 
475 //================
476 
478  unsigned outputMaxSize ) :
479  BitpackEncoder( bytestreamNumber, sbuf, outputMaxSize, 1 ), totalBytesProcessed_( 0 ), isStringActive_( false ),
480  prefixComplete_( false ), currentCharPosition_( 0 )
481 {
482 }
483 
484 uint64_t BitpackStringEncoder::processRecords( size_t recordCount )
485 {
486 #ifdef E57_MAX_VERBOSE
487  std::cout << " BitpackStringEncoder::processRecords() called, recordCount=" << recordCount << std::endl; //???
488 #endif
489 
493 
495  size_t bytesFree = outBuffer_.size() - outBufferEnd_;
496 
498  char *outp = &outBuffer_[outBufferEnd_];
499  unsigned recordsProcessed = 0;
500 
503  while ( recordsProcessed < recordCount && bytesFree >= 8 )
504  { //??? should be able to proceed if only 1 byte free
506  {
508  size_t len = currentString_.length();
509  if ( len <= 127 )
510  {
511 #ifdef E57_MAX_VERBOSE
512  std::cout << "encoding short string: (len=" << len
513  << ") "
514  ""
515  << currentString_
516  << ""
517  ""
518  << std::endl;
519 #endif
521  auto lengthPrefix = static_cast<uint8_t>( len << 1 );
522  *outp++ = lengthPrefix;
523  bytesFree--;
524  }
525  else
526  {
527 #ifdef E57_DEBUG
529  if ( bytesFree < 8 )
530  {
531  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "bytesFree=" + toString( bytesFree ) );
532  }
533 #endif
534 #ifdef E57_MAX_VERBOSE
535  std::cout << "encoding long string: (len=" << len
536  << ") "
537  ""
538  << currentString_
539  << ""
540  ""
541  << std::endl;
542 #endif
546  uint64_t lengthPrefix = ( static_cast<uint64_t>( len ) << 1 ) | 1LL;
547  *outp++ = static_cast<uint8_t>( lengthPrefix );
548  *outp++ = static_cast<uint8_t>( lengthPrefix >> ( 1 * 8 ) );
549  *outp++ = static_cast<uint8_t>( lengthPrefix >> ( 2 * 8 ) );
550  *outp++ = static_cast<uint8_t>( lengthPrefix >> ( 3 * 8 ) );
551  *outp++ = static_cast<uint8_t>( lengthPrefix >> ( 4 * 8 ) );
552  *outp++ = static_cast<uint8_t>( lengthPrefix >> ( 5 * 8 ) );
553  *outp++ = static_cast<uint8_t>( lengthPrefix >> ( 6 * 8 ) );
554  *outp++ = static_cast<uint8_t>( lengthPrefix >> ( 7 * 8 ) );
555  bytesFree -= 8;
556  }
557  prefixComplete_ = true;
559  }
560  if ( isStringActive_ )
561  {
563  size_t bytesToProcess = std::min( currentString_.length() - currentCharPosition_, bytesFree );
564 
565  for ( size_t i = 0; i < bytesToProcess; i++ )
566  {
567  *outp++ = currentString_[currentCharPosition_ + i];
568  }
569 
570  currentCharPosition_ += bytesToProcess;
571  totalBytesProcessed_ += bytesToProcess;
572  bytesFree -= bytesToProcess;
573 
575  if ( currentCharPosition_ == currentString_.length() )
576  {
577  isStringActive_ = false;
578  recordsProcessed++;
579  }
580  }
581  if ( !isStringActive_ && recordsProcessed < recordCount )
582  {
584  currentString_ = sourceBuffer_->getNextString();
585  isStringActive_ = true;
586  prefixComplete_ = false;
588 #ifdef E57_MAX_VERBOSE
589  std::cout << "getting next string, length=" << currentString_.length() << std::endl;
590 #endif
591  }
592  }
593 
595  outBufferEnd_ = outBuffer_.size() - bytesFree;
596 
598  currentRecordIndex_ += recordsProcessed;
599 
600  return ( currentRecordIndex_ );
601 }
602 
604 {
606  return ( true );
607 }
608 
610 {
612  if ( currentRecordIndex_ > 0 )
613  {
614  return ( 8.0f * totalBytesProcessed_ ) / currentRecordIndex_ + 8;
615  }
616 
618  return 100 * 8.0f;
619 }
620 
621 #ifdef E57_DEBUG
622 void BitpackStringEncoder::dump( int indent, std::ostream &os ) const
623 {
624  BitpackEncoder::dump( indent, os );
625  os << space( indent ) << "totalBytesProcessed: " << totalBytesProcessed_ << std::endl;
626  os << space( indent ) << "isStringActive: " << isStringActive_ << std::endl;
627  os << space( indent ) << "prefixComplete: " << prefixComplete_ << std::endl;
628  os << space( indent ) << "currentString: " << currentString_ << std::endl;
629  os << space( indent ) << "currentCharPosition: " << currentCharPosition_ << std::endl;
630 }
631 #endif
632 
633 //================================================================
634 
635 template <typename RegisterT>
636 BitpackIntegerEncoder<RegisterT>::BitpackIntegerEncoder( bool isScaledInteger, unsigned bytestreamNumber,
637  SourceDestBuffer &sbuf, unsigned outputMaxSize,
638  int64_t minimum, int64_t maximum, double scale,
639  double offset ) :
640  BitpackEncoder( bytestreamNumber, sbuf, outputMaxSize, sizeof( RegisterT ) )
641 {
643  ImageFileImplSharedPtr imf( sbuf.impl()->destImageFile() ); //??? should be function for this,
644  // imf->parentFile() --> ImageFile?
645 
646  isScaledInteger_ = isScaledInteger;
647  minimum_ = minimum;
648  maximum_ = maximum;
649  scale_ = scale;
650  offset_ = offset;
651  bitsPerRecord_ = imf->bitsNeeded( minimum_, maximum_ );
652  sourceBitMask_ = ( bitsPerRecord_ == 64 ) ? ~0 : ( 1ULL << bitsPerRecord_ ) - 1;
653  registerBitsUsed_ = 0;
654  register_ = 0;
655 }
656 
657 template <typename RegisterT> uint64_t BitpackIntegerEncoder<RegisterT>::processRecords( size_t recordCount )
658 {
659  //??? what are state guarantees if get an exception during transfer?
660 #ifdef E57_MAX_VERBOSE
661  std::cout << "BitpackIntegerEncoder::processRecords() called, sizeof(RegisterT)=" << sizeof( RegisterT )
662  << " recordCount=" << recordCount << std::endl;
663  dump( 4 );
664 #endif
665 #ifdef E57_MAX_DEBUG
668  if ( 8 * sizeof( RegisterT ) < bitsPerRecord_ )
669  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "bitsPerRecord=" + toString( bitsPerRecord_ ) );
670 #endif
671 
674  outBufferShiftDown();
675 
676 #ifdef E57_DEBUG
679  if ( outBufferEnd_ % sizeof( RegisterT ) )
680  {
681  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outBufferEnd=" + toString( outBufferEnd_ ) );
682  }
683  size_t transferMax = ( outBuffer_.size() - outBufferEnd_ ) / sizeof( RegisterT );
684 #endif
685 
688  size_t outputWordCapacity = ( outBuffer_.size() - outBufferEnd_ ) / sizeof( RegisterT );
689  size_t maxOutputRecords =
690  ( outputWordCapacity * 8 * sizeof( RegisterT ) + 8 * sizeof( RegisterT ) - registerBitsUsed_ - 1 ) /
691  bitsPerRecord_;
692 
695  recordCount = std::min( recordCount, maxOutputRecords );
696 #ifdef E57_MAX_VERBOSE
697  std::cout << " outputWordCapacity=" << outputWordCapacity << " maxOutputRecords=" << maxOutputRecords
698  << " recordCount=" << recordCount << std::endl;
699 #endif
700 
702  auto outp = reinterpret_cast<RegisterT *>( &outBuffer_[outBufferEnd_] );
703  unsigned outTransferred = 0;
704 
706  for ( unsigned i = 0; i < recordCount; i++ )
707  {
708  int64_t rawValue;
709 
712  if ( isScaledInteger_ )
713  {
714  rawValue = sourceBuffer_->getNextInt64( scale_, offset_ );
715  }
716  else
717  rawValue = sourceBuffer_->getNextInt64();
718 
720  if ( rawValue < minimum_ || maximum_ < rawValue )
721  {
722  throw E57_EXCEPTION2( E57_ERROR_VALUE_OUT_OF_BOUNDS, "rawValue=" + toString( rawValue ) +
723  " minimum=" + toString( minimum_ ) +
724  " maximum=" + toString( maximum_ ) );
725  }
726 
727  auto uValue = static_cast<uint64_t>( rawValue - minimum_ );
728 
729 #ifdef E57_MAX_VERBOSE
730  std::cout << "encoding integer rawValue=" << binaryString( rawValue ) << " = " << hexString( rawValue )
731  << std::endl;
732  std::cout << " uValue =" << binaryString( uValue ) << " = " << hexString( uValue ) << std::endl;
733 #endif
734 #ifdef E57_DEBUG
736  if ( uValue & ~static_cast<uint64_t>( sourceBitMask_ ) )
737  {
738  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "uValue=" + toString( uValue ) );
739  }
740 #endif
742  uValue &= static_cast<uint64_t>( sourceBitMask_ );
743 
745  unsigned newRegisterBitsUsed = registerBitsUsed_ + bitsPerRecord_;
746 #ifdef E57_MAX_VERBOSE
747  std::cout << " registerBitsUsed=" << registerBitsUsed_ << " newRegisterBitsUsed=" << newRegisterBitsUsed
748  << std::endl;
749 #endif
750  if ( newRegisterBitsUsed > 8 * sizeof( RegisterT ) )
751  {
754  register_ |= static_cast<RegisterT>( uValue ) << registerBitsUsed_;
755 #ifdef E57_DEBUG
757  if ( outTransferred >= transferMax )
758  {
759  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outTransferred=" + toString( outTransferred ) + " transferMax" +
760  toString( transferMax ) );
761  }
762 #endif
763  outp[outTransferred] = register_;
764 
765  outTransferred++;
766 
767  register_ = static_cast<RegisterT>( uValue ) >> ( 8 * sizeof( RegisterT ) - registerBitsUsed_ );
768  registerBitsUsed_ = newRegisterBitsUsed - 8 * sizeof( RegisterT );
769  }
770  else if ( newRegisterBitsUsed == 8 * sizeof( RegisterT ) )
771  {
773  register_ |= static_cast<RegisterT>( uValue ) << registerBitsUsed_;
774 #ifdef E57_DEBUG
776  if ( outTransferred >= transferMax )
777  {
778  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outTransferred=" + toString( outTransferred ) + " transferMax" +
779  toString( transferMax ) );
780  }
781 #endif
782  outp[outTransferred] = register_;
783 
784  outTransferred++;
785 
786  register_ = 0;
787  registerBitsUsed_ = 0;
788  }
789  else
790  {
793  register_ |= static_cast<RegisterT>( uValue ) << registerBitsUsed_;
794  registerBitsUsed_ = newRegisterBitsUsed;
795  }
796 #ifdef E57_MAX_VERBOSE
797  std::cout << " After " << outTransferred << " transfers and " << i + 1 << " records, encoder:" << std::endl;
798  dump( 4 );
799 #endif
800  }
801 
803  outBufferEnd_ += outTransferred * sizeof( RegisterT );
804 #ifdef E57_DEBUG
806  if ( outBufferEnd_ > outBuffer_.size() )
807  {
808  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "outBufferEnd=" + toString( outBufferEnd_ ) +
809  " outBuffersize=" + toString( outBuffer_.size() ) );
810  }
811 #endif
812 
814  currentRecordIndex_ += recordCount;
815 
816  return ( currentRecordIndex_ );
817 }
818 
820 {
821 #ifdef E57_MAX_VERBOSE
822  std::cout << "BitpackIntegerEncoder::registerFlushToOutput() called, "
823  "sizeof(RegisterT)="
824  << sizeof( RegisterT ) << std::endl;
825  dump( 4 );
826 #endif
829  if ( registerBitsUsed_ > 0 )
830  {
831  if ( outBufferEnd_ < outBuffer_.size() - sizeof( RegisterT ) )
832  {
833  auto outp = reinterpret_cast<RegisterT *>( &outBuffer_[outBufferEnd_] );
834  *outp = register_;
835  register_ = 0;
836  registerBitsUsed_ = 0;
837  outBufferEnd_ += sizeof( RegisterT );
838  return true; // flush succeeded ??? is this used? correctly?
839  }
840 
841  return false; // flush didn't complete (not enough room).
842  }
843 
844  return true;
845 }
846 
847 template <typename RegisterT> float BitpackIntegerEncoder<RegisterT>::bitsPerRecord()
848 {
849  return ( static_cast<float>( bitsPerRecord_ ) );
850 }
851 
852 #ifdef E57_DEBUG
853 template <typename RegisterT> void BitpackIntegerEncoder<RegisterT>::dump( int indent, std::ostream &os ) const
854 {
855  BitpackEncoder::dump( indent, os );
856  os << space( indent ) << "isScaledInteger: " << isScaledInteger_ << std::endl;
857  os << space( indent ) << "minimum: " << minimum_ << std::endl;
858  os << space( indent ) << "maximum: " << maximum_ << std::endl;
859  os << space( indent ) << "scale: " << scale_ << std::endl;
860  os << space( indent ) << "offset: " << offset_ << std::endl;
861  os << space( indent ) << "bitsPerRecord: " << bitsPerRecord_ << std::endl;
862  os << space( indent ) << "sourceBitMask: " << binaryString( sourceBitMask_ ) << " " << hexString( sourceBitMask_ )
863  << std::endl;
864  os << space( indent ) << "register: " << binaryString( register_ ) << " " << hexString( register_ )
865  << std::endl;
866  os << space( indent ) << "registerBitsUsed: " << registerBitsUsed_ << std::endl;
867 }
868 #endif
869 
870 //================================================================
871 
872 ConstantIntegerEncoder::ConstantIntegerEncoder( unsigned bytestreamNumber, SourceDestBuffer &sbuf, int64_t minimum ) :
873  Encoder( bytestreamNumber ), sourceBuffer_( sbuf.impl() ), currentRecordIndex_( 0 ), minimum_( minimum )
874 {
875 }
876 
877 uint64_t ConstantIntegerEncoder::processRecords( size_t recordCount )
878 {
879 #ifdef E57_MAX_VERBOSE
880  std::cout << "ConstantIntegerEncoder::processRecords() called, recordCount=" << recordCount << std::endl;
881  dump( 4 );
882 #endif
883 
885  for ( unsigned i = 0; i < recordCount; i++ )
886  {
887  int64_t nextInt64 = sourceBuffer_->getNextInt64();
888  if ( nextInt64 != minimum_ )
889  {
891  "nextInt64=" + toString( nextInt64 ) + " minimum=" + toString( minimum_ ) );
892  }
893  }
894 
896  currentRecordIndex_ += recordCount;
897 
898  return ( currentRecordIndex_ );
899 }
900 
902 {
903  return ( sourceBuffer_->nextIndex() );
904 }
905 
907 {
908  return ( currentRecordIndex_ );
909 }
910 
912 {
914  return ( 0.0 );
915 }
916 
918 {
919  return ( true );
920 }
921 
923 {
925  return 0;
926 }
927 
928 void ConstantIntegerEncoder::outputRead( char * /*dest*/, const size_t byteCount )
929 {
931  if ( byteCount > 0 )
932  {
933  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "byteCount=" + toString( byteCount ) );
934  }
935 }
936 
938 {
939 }
940 
941 void ConstantIntegerEncoder::sourceBufferSetNew( std::vector<SourceDestBuffer> &sbufs )
942 {
944  if ( sbufs.size() != 1 )
945  {
946  throw E57_EXCEPTION2( E57_ERROR_INTERNAL, "sbufsSize=" + toString( sbufs.size() ) );
947  }
948 
949  sourceBuffer_ = sbufs.at( 0 ).impl();
950 }
951 
953 {
955  return ( 0 );
956 }
957 
958 void ConstantIntegerEncoder::outputSetMaxSize( unsigned /*byteCount*/ )
959 {
961 }
962 
963 #ifdef E57_DEBUG
964 void ConstantIntegerEncoder::dump( int indent, std::ostream &os ) const
965 {
966  Encoder::dump( indent, os );
967  os << space( indent ) << "currentRecordIndex: " << currentRecordIndex_ << std::endl;
968  os << space( indent ) << "minimum: " << minimum_ << std::endl;
969  os << space( indent ) << "sourceBuffer:" << std::endl;
970  sourceBuffer_->dump( indent + 4, os );
971 }
972 #endif
int offset
int offset_
Definition: FilePLY.cpp:36
#define E57_EXCEPTION2(ecode, context)
Definition: Common.h:68
std::shared_ptr< SourceDestBufferImpl > sourceBuffer_
Definition: Encoder.h:98
size_t outBufferAlignmentSize_
Definition: Encoder.h:103
size_t outBufferFirst_
Definition: Encoder.h:101
void outputSetMaxSize(unsigned byteCount) override
Definition: Encoder.cpp:289
uint64_t currentRecordIndex_
Definition: Encoder.h:105
size_t outputAvailable() const override
Definition: Encoder.cpp:221
void dump(int indent=0, std::ostream &os=std::cout) const override
Definition: Encoder.cpp:348
void sourceBufferSetNew(std::vector< SourceDestBuffer > &sbufs) override
Definition: Encoder.cpp:272
size_t outputGetMaxSize() override
Definition: Encoder.cpp:283
unsigned sourceBufferNextIndex() override
Definition: Encoder.cpp:211
BitpackEncoder(unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize, unsigned alignmentSize)
================
Definition: Encoder.cpp:204
std::vector< char > outBuffer_
Definition: Encoder.h:100
void outputClear() override
get data from encoder
Definition: Encoder.cpp:266
void outputRead(char *dest, const size_t byteCount) override
number of bytes that can be read
Definition: Encoder.cpp:226
void outBufferShiftDown()
Definition: Encoder.cpp:298
size_t outBufferEnd_
Definition: Encoder.h:102
uint64_t currentRecordIndex() override
Definition: Encoder.cpp:216
FloatPrecision precision_
Definition: Encoder.h:122
uint64_t processRecords(size_t recordCount) override
Definition: Encoder.cpp:382
void dump(int indent=0, std::ostream &os=std::cout) const override
Definition: Encoder.cpp:461
BitpackFloatEncoder(unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize, FloatPrecision precision)
Definition: Encoder.cpp:374
float bitsPerRecord() override
Definition: Encoder.cpp:455
bool registerFlushToOutput() override
Definition: Encoder.cpp:449
void dump(int indent=0, std::ostream &os=std::cout) const override
Definition: Encoder.cpp:853
BitpackIntegerEncoder(bool isScaledInteger, unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize, int64_t minimum, int64_t maximum, double scale, double offset)
Definition: Encoder.cpp:636
bool registerFlushToOutput() override
Definition: Encoder.cpp:819
float bitsPerRecord() override
Definition: Encoder.cpp:847
uint64_t processRecords(size_t recordCount) override
Definition: Encoder.cpp:657
float bitsPerRecord() override
Definition: Encoder.cpp:609
bool registerFlushToOutput() override
Definition: Encoder.cpp:603
void dump(int indent=0, std::ostream &os=std::cout) const override
Definition: Encoder.cpp:622
uint64_t processRecords(size_t recordCount) override
Definition: Encoder.cpp:484
uint64_t totalBytesProcessed_
Definition: Encoder.h:138
BitpackStringEncoder(unsigned bytestreamNumber, SourceDestBuffer &sbuf, unsigned outputMaxSize)
Definition: Encoder.cpp:477
ConstantIntegerEncoder(unsigned bytestreamNumber, SourceDestBuffer &sbuf, int64_t minimum)
Definition: Encoder.cpp:872
void outputRead(char *dest, const size_t byteCount) override
number of bytes that can be read
Definition: Encoder.cpp:928
std::shared_ptr< SourceDestBufferImpl > sourceBuffer_
Definition: Encoder.h:193
size_t outputGetMaxSize() override
Definition: Encoder.cpp:952
bool registerFlushToOutput() override
Definition: Encoder.cpp:917
unsigned sourceBufferNextIndex() override
Definition: Encoder.cpp:901
size_t outputAvailable() const override
Definition: Encoder.cpp:922
void dump(int indent=0, std::ostream &os=std::cout) const override
Definition: Encoder.cpp:964
void sourceBufferSetNew(std::vector< SourceDestBuffer > &sbufs) override
Definition: Encoder.cpp:941
uint64_t processRecords(size_t recordCount) override
Definition: Encoder.cpp:877
uint64_t currentRecordIndex() override
Definition: Encoder.cpp:906
float bitsPerRecord() override
Definition: Encoder.cpp:911
void outputSetMaxSize(unsigned byteCount) override
Definition: Encoder.cpp:958
void outputClear() override
get data from encoder
Definition: Encoder.cpp:937
static std::shared_ptr< Encoder > EncoderFactory(unsigned bytestreamNumber, std::shared_ptr< CompressedVectorNodeImpl > cVector, std::vector< SourceDestBuffer > &sbuf, ustring &codecPath)
Definition: Encoder.cpp:42
virtual void dump(int indent=0, std::ostream &os=std::cout) const
Definition: Encoder.cpp:196
virtual float bitsPerRecord()=0
unsigned bytestreamNumber_
Definition: Encoder.h:68
Encoder(unsigned bytestreamNumber)
Definition: Encoder.cpp:191
unsigned bytestreamNumber() const
Definition: Encoder.h:57
ustring pathName() const
Get path name in prototype that this SourceDestBuffer will transfer data to/from.
Definition: E57Format.cpp:2030
int min(int a, int b)
Definition: cutil_math.h:53
QTextStream & endl(QTextStream &stream)
Definition: QtCompat.h:718
static const std::string path
Definition: PointCloud.cpp:59
std::string binaryString(uint64_t x)
Definition: Common.h:111
std::shared_ptr< class NodeImpl > NodeImplSharedPtr
Definition: Common.h:190
std::shared_ptr< class ImageFileImpl > ImageFileImplSharedPtr
Definition: Common.h:188
FloatPrecision
The IEEE floating point number precisions supported.
Definition: E57Format.h:71
@ E57_SINGLE
32 bit IEEE floating point number format
Definition: E57Format.h:72
@ E57_ERROR_INTERNAL
An unrecoverable inconsistent internal state was detected.
Definition: E57Exception.h:56
@ E57_ERROR_VALUE_OUT_OF_BOUNDS
element value out of min/max bounds
Definition: E57Exception.h:81
@ E57_ERROR_BAD_PROTOTYPE
bad prototype in CompressedVectorNode
Definition: E57Exception.h:79
std::string ustring
UTF-8 encodeded Unicode string.
Definition: E57Format.h:54
@ E57_INTEGER
IntegerNode class.
Definition: E57Format.h:62
@ E57_SCALED_INTEGER
ScaledIntegerNode class.
Definition: E57Format.h:63
@ E57_FLOAT
FloatNode class.
Definition: E57Format.h:64
@ E57_STRING
StringNode class.
Definition: E57Format.h:65
std::string toString(T x)
Definition: Common.h:80
constexpr int DATA_PACKET_MAX
maximum size of CompressedVector binary data packet
Definition: Packet.h:49
std::string space(size_t n)
Definition: Common.h:73
std::string hexString(uint64_t x)
Definition: Common.h:87