42 bool operator()(
const std::shared_ptr<Encoder> &lhs,
const std::shared_ptr<Encoder> &rhs )
const
44 return ( lhs->bytestreamNumber() < rhs->bytestreamNumber() );
49 std::vector<SourceDestBuffer> &sbufs ) :
50 cVector_( ni ), isOpen_( false )
58 "imageFileName=" + cVector_->imageFileName() +
" cvPathName=" + cVector_->pathName() );
63 proto_ = cVector_->getPrototype();
70 for (
unsigned i = 0; i < sbufs_.size(); i++ )
73 std::vector<SourceDestBuffer> vTemp;
74 vTemp.push_back( sbufs_.at( i ) );
76 ustring codecPath = sbufs_.at( i ).pathName();
81 uint64_t bytestreamNumber = 0;
82 if ( !proto_->findTerminalPosition( readNode, bytestreamNumber ) )
89 bytestreams_.push_back(
98 for (
unsigned i = 0; i < bytestreams_.size(); i++ )
100 if ( bytestreams_.at( i )->bytestreamNumber() != i )
103 toString( bytestreams_.at( i )->bytestreamNumber() ) );
115 sectionLogicalLength_ = 0;
116 dataPhysicalOffset_ = 0;
117 topIndexPhysicalOffset_ = 0;
119 dataPacketsCount_ = 0;
120 indexPacketsCount_ = 0;
124 imf->incrWriterCount();
132 #ifdef E57_MAX_VERBOSE
133 std::cout <<
"~CompressedVectorWriterImpl() called" <<
std::endl;
151 #ifdef E57_MAX_VERBOSE
152 std::cout <<
"CompressedVectorWriterImpl::close() called" <<
std::endl;
157 imf->decrWriterCount();
159 checkImageFileOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
176 while ( totalOutputAvailable() > 0 )
184 sectionLogicalLength_ = imf->unusedLogicalStart_ - sectionHeaderLogicalStart_;
185 #ifdef E57_MAX_VERBOSE
186 std::cout <<
" sectionLogicalLength_=" << sectionLogicalLength_ <<
std::endl;
195 #ifdef E57_MAX_VERBOSE
196 std::cout <<
" CompressedVectorSectionHeader:" <<
std::endl;
205 imf->file_->seek( sectionHeaderLogicalStart_ );
206 imf->file_->write(
reinterpret_cast<char *
>( &header ),
sizeof( header ) );
209 cVector_->setRecordCount( recordCount_ );
210 cVector_->setBinarySectionLogicalStart( sectionHeaderLogicalStart_ );
213 bytestreams_.clear();
215 #ifdef E57_MAX_VERBOSE
216 std::cout <<
" CompressedVectorWriter:" <<
std::endl;
233 void CompressedVectorWriterImpl::setBuffers( std::vector<SourceDestBuffer> &sbufs )
239 if ( !sbufs_.empty() )
241 if ( sbufs_.size() != sbufs.size() )
244 "oldSize=" +
toString( sbufs_.size() ) +
" newSize=" +
toString( sbufs.size() ) );
247 for (
size_t i = 0; i < sbufs_.size(); ++i )
249 std::shared_ptr<SourceDestBufferImpl> oldbuf = sbufs_[i].impl();
250 std::shared_ptr<SourceDestBufferImpl> newBuf = sbufs[i].impl();
253 oldbuf->checkCompatible( newBuf );
260 proto_->checkBuffers( sbufs,
false );
271 write( requestedRecordCount );
276 #ifdef E57_MAX_VERBOSE
277 std::cout <<
"CompressedVectorWriterImpl::write() called" <<
std::endl;
279 checkImageFileOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
280 checkWriterOpen( __FILE__, __LINE__,
static_cast<const char *
>( __FUNCTION__ ) );
283 if ( requestedRecordCount > sbufs_.at( 0 ).impl()->capacity() )
286 "requested=" +
toString( requestedRecordCount ) +
287 " capacity=" +
toString( sbufs_.at( 0 ).impl()->capacity() ) +
" imageFileName=" +
288 cVector_->imageFileName() +
" cvPathName=" + cVector_->pathName() );
292 for (
auto &sbuf : sbufs_ )
294 sbuf.impl()->rewind();
298 uint64_t endRecordIndex = recordCount_ + requestedRecordCount;
302 uint64_t totalRecordCount = 0;
303 for (
auto &bytestream : bytestreams_ )
305 totalRecordCount += endRecordIndex - bytestream->currentRecordIndex();
307 #ifdef E57_MAX_VERBOSE
308 std::cout <<
" totalRecordCount=" << totalRecordCount <<
std::endl;
312 if ( totalRecordCount == 0 )
326 #ifdef E57_MAX_VERBOSE
327 std::cout <<
" currentPacketSize()=" << currentPacketSize() <<
std::endl;
330 #ifdef E57_WRITE_CRAZY_PACKET_MODE
332 constexpr
size_t E57_TARGET_PACKET_SIZE = 500;
337 if ( currentPacketSize() >= E57_TARGET_PACKET_SIZE )
347 float totalBitsPerRecord = 0;
348 for (
auto &bytestream : bytestreams_ )
350 totalBitsPerRecord += bytestream->bitsPerRecord();
353 #ifdef E57_MAX_VERBOSE
354 const float totalBytesPerRecord =
std::max( totalBitsPerRecord / 8, 0.1F );
356 std::cout <<
" totalBytesPerRecord=" << totalBytesPerRecord <<
std::endl;
365 for (
auto &bytestream : bytestreams_ )
367 if ( bytestream->currentRecordIndex() < endRecordIndex )
370 uint64_t recordCount = endRecordIndex - bytestream->currentRecordIndex();
371 recordCount = ( recordCount < 50ULL ) ? recordCount : 50ULL;
372 bytestream->processRecords(
static_cast<unsigned>( recordCount ) );
377 recordCount_ += requestedRecordCount;
383 size_t CompressedVectorWriterImpl::totalOutputAvailable()
const
387 for (
const auto &bytestream : bytestreams_ )
389 total += bytestream->outputAvailable();
395 size_t CompressedVectorWriterImpl::currentPacketSize()
const
398 return (
sizeof( DataPacketHeader ) + bytestreams_.size() *
sizeof( uint16_t ) + totalOutputAvailable() );
401 uint64_t CompressedVectorWriterImpl::packetWrite()
403 #ifdef E57_MAX_VERBOSE
404 std::cout <<
"CompressedVectorWriterImpl::packetWrite() called" <<
std::endl;
408 size_t totalOutput = totalOutputAvailable();
409 if ( totalOutput == 0 )
413 #ifdef E57_MAX_VERBOSE
414 std::cout <<
" totalOutput=" << totalOutput <<
std::endl;
418 size_t packetMaxPayloadBytes =
419 DATA_PACKET_MAX -
sizeof( DataPacketHeader ) - bytestreams_.size() *
sizeof( uint16_t );
420 #ifdef E57_MAX_VERBOSE
421 std::cout <<
" packetMaxPayloadBytes=" << packetMaxPayloadBytes <<
std::endl;
426 std::vector<size_t>
count( bytestreams_.size() );
429 if ( totalOutput < packetMaxPayloadBytes )
432 for (
unsigned i = 0; i < bytestreams_.size(); i++ )
434 count.at( i ) = bytestreams_.at( i )->outputAvailable();
442 float fractionToSend = ( packetMaxPayloadBytes - 1 ) /
static_cast<float>( totalOutput );
443 for (
unsigned i = 0; i < bytestreams_.size(); i++ )
447 static_cast<unsigned>(
std::floor( fractionToSend * bytestreams_.at( i )->outputAvailable() ) );
450 #ifdef E57_MAX_VERBOSE
451 for (
unsigned i = 0; i < bytestreams_.size(); i++ )
453 std::cout <<
" count[" << i <<
"]=" <<
count.at( i ) <<
std::endl;
459 const size_t totalByteCount = std::accumulate(
count.begin(),
count.end(), 0 );
461 if ( totalByteCount > packetMaxPayloadBytes )
464 " packetMaxPayloadBytes=" +
toString( packetMaxPayloadBytes ) );
473 char *packet =
reinterpret_cast<char *
>( &dataPacket_ );
474 #ifdef E57_MAX_VERBOSE
475 std::cout <<
" packet=" << packet <<
std::endl;
483 auto bsbLength =
reinterpret_cast<uint16_t *
>( &packet[
sizeof( DataPacketHeader )] );
484 #ifdef E57_MAX_VERBOSE
485 std::cout <<
" bsbLength=" << bsbLength <<
std::endl;
487 for (
unsigned i = 0; i < bytestreams_.size(); i++ )
489 bsbLength[i] =
static_cast<uint16_t
>(
count.at( i ) );
490 #ifdef E57_MAX_VERBOSE
491 std::cout <<
" Writing " << bsbLength[i] <<
" bytes into bytestream " << i <<
std::endl;
496 char *p =
reinterpret_cast<char *
>( &bsbLength[bytestreams_.size()] );
497 #ifdef E57_MAX_VERBOSE
498 std::cout <<
" after bsbLength, p=" << p <<
std::endl;
502 for (
size_t i = 0; i < bytestreams_.size(); i++ )
504 size_t n =
count.at( i );
516 bytestreams_.at( i )->outputRead( p, n );
523 auto packetLength =
static_cast<unsigned>( p - packet );
524 #ifdef E57_MAX_VERBOSE
525 std::cout <<
" packetLength=" << packetLength <<
std::endl;
530 if ( packetLength !=
sizeof( DataPacketHeader ) + bytestreams_.size() *
sizeof( uint16_t ) + totalByteCount )
533 toString( bytestreams_.size() *
sizeof( uint16_t ) ) +
534 " totalByteCount=" +
toString( totalByteCount ) );
539 while ( packetLength % 4 )
549 #ifdef E57_MAX_VERBOSE
550 std::cout <<
" padding with zero byte, new packetLength=" << packetLength <<
std::endl;
559 dataPacket_.
verify( packetLength );
562 uint64_t packetLogicalOffset = imf->allocateSpace( packetLength,
false );
563 uint64_t packetPhysicalOffset = imf->file_->logicalToPhysical( packetLogicalOffset );
564 imf->file_->seek( packetLogicalOffset );
566 imf->file_->write( packet, packetLength );
568 #ifdef E57_MAX_VERBOSE
579 if ( dataPacketsCount_ == 0 )
581 dataPhysicalOffset_ = packetPhysicalOffset;
588 return ( packetPhysicalOffset );
591 void CompressedVectorWriterImpl::flush()
593 for (
auto &bytestream : bytestreams_ )
595 bytestream->registerFlushToOutput();
599 void CompressedVectorWriterImpl::checkImageFileOpen(
const char *srcFileName,
int srcLineNumber,
600 const char *srcFunctionName )
const
605 void CompressedVectorWriterImpl::checkWriterOpen(
const char *srcFileName,
int srcLineNumber,
606 const char *srcFunctionName )
const
611 "imageFileName=" + cVector_->imageFileName() +
" cvPathName=" + cVector_->pathName(),
612 srcFileName, srcLineNumber, srcFunctionName );
620 for (
unsigned i = 0; i < sbufs_.size(); i++ )
623 sbufs_.at( i ).dump( indent + 4, os );
627 cVector_->dump( indent + 4, os );
630 proto_->dump( indent + 4, os );
632 for (
unsigned i = 0; i < bytestreams_.size(); i++ )
634 os <<
space( indent ) <<
"bytestreams[" << i <<
"]:" <<
std::endl;
635 bytestreams_.at( i )->dump( indent + 4, os );
641 auto p =
reinterpret_cast<uint8_t *
>( &dataPacket_ );
643 for (
unsigned i = 0; i < 40; ++i )
645 os <<
space( indent + 4 ) <<
"dataPacket[" << i <<
"]: " <<
static_cast<unsigned>( p[i] ) <<
std::endl;
649 os <<
space( indent ) <<
"sectionHeaderLogicalStart: " << sectionHeaderLogicalStart_ <<
std::endl;
650 os <<
space( indent ) <<
"sectionLogicalLength: " << sectionLogicalLength_ <<
std::endl;
651 os <<
space( indent ) <<
"dataPhysicalOffset: " << dataPhysicalOffset_ <<
std::endl;
652 os <<
space( indent ) <<
"topIndexPhysicalOffset: " << topIndexPhysicalOffset_ <<
std::endl;
653 os <<
space( indent ) <<
"recordCount: " << recordCount_ <<
std::endl;
654 os <<
space( indent ) <<
"dataPacketsCount: " << dataPacketsCount_ <<
std::endl;
655 os <<
space( indent ) <<
"indexPacketsCount: " << indexPacketsCount_ <<
std::endl;
void dump(int indent=0, std::ostream &os=std::cout)
~CompressedVectorWriterImpl()
std::shared_ptr< CompressedVectorNodeImpl > compressedVectorNode() const
void write(const size_t requestedRecordCount)
CompressedVectorWriterImpl(std::shared_ptr< CompressedVectorNodeImpl > ni, std::vector< SourceDestBuffer > &sbufs)
void verify(unsigned bufferLength=0) const
static std::shared_ptr< Encoder > EncoderFactory(unsigned bytestreamNumber, std::shared_ptr< CompressedVectorNodeImpl > cVector, std::vector< SourceDestBuffer > &sbuf, ustring &codecPath)
QTextStream & endl(QTextStream &stream)
MiniVec< float, N > floor(const MiniVec< float, N > &a)
std::shared_ptr< class NodeImpl > NodeImplSharedPtr
std::shared_ptr< class ImageFileImpl > ImageFileImplSharedPtr
@ E57_ERROR_BUFFERS_NOT_COMPATIBLE
SourceDestBuffers not compatible with previously given ones.
@ E57_ERROR_INTERNAL
An unrecoverable inconsistent internal state was detected.
@ E57_ERROR_BAD_API_ARGUMENT
bad API function argument provided by user
@ E57_ERROR_WRITER_NOT_OPEN
CompressedVectorWriter is no longer open.
std::string ustring
UTF-8 encodeded Unicode string.
std::string toString(T x)
constexpr int DATA_PACKET_MAX
maximum size of CompressedVector binary data packet
std::string space(size_t n)
bool operator()(const std::shared_ptr< Encoder > &lhs, const std::shared_ptr< Encoder > &rhs) const