@@ -146,7 +146,7 @@ void JpegBase::readMetadata() {
146146 byte marker = advanceToMarker (ErrorCode::kerNotAJpeg);
147147
148148 while (marker != sos_ && marker != eoi_ && search > 0 ) {
149- auto [sizebuf, size] = readSegmentSize (marker, *io_);
149+ const auto [sizebuf, size] = readSegmentSize (marker, *io_);
150150
151151 // Read the rest of the segment.
152152 DataBuf buf (size);
@@ -304,7 +304,7 @@ void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, in
304304 }
305305
306306 bool bPrint = option == kpsBasic || option == kpsRecursive;
307- std::vector<size_t > iptcDataSegs;
307+ std::vector<std::pair< size_t , size_t > > iptcDataSegs;
308308
309309 if (bPrint || option == kpsXMP || option == kpsIccProfile || option == kpsIptcErase) {
310310 // mnemonic for markers
@@ -347,7 +347,7 @@ void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, in
347347 first = false ;
348348 bool bLF = bPrint;
349349
350- auto [sizebuf, size] = readSegmentSize (marker, *io_);
350+ const auto [sizebuf, size] = readSegmentSize (marker, *io_);
351351
352352 // Read the rest of the segment.
353353 DataBuf buf (size);
@@ -412,8 +412,7 @@ void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, in
412412 }
413413 } else if (option == kpsIptcErase && signature == " Photoshop 3.0" ) {
414414 // delete IPTC data segment from JPEG
415- iptcDataSegs.push_back (io_->tell () - size);
416- iptcDataSegs.push_back (size);
415+ iptcDataSegs.push_back (std::make_pair (io_->tell () - size, io_->tell ()));
417416 } else if (bPrint) {
418417 const size_t start = 2 ;
419418 const size_t end = size > 34 ? 34 : size;
@@ -518,62 +517,31 @@ void JpegBase::printStructure(std::ostream& out, PrintStructureOption option, in
518517 }
519518 }
520519 if (option == kpsIptcErase && !iptcDataSegs.empty ()) {
521- #ifdef EXIV2_DEBUG_MESSAGES
522- std::cout << " iptc data blocks: " << iptcDataSegs.size () << std::endl;
523- uint32_t toggle = 0 ;
524- for (auto && iptc : iptcDataSegs) {
525- std::cout << iptc;
526- if (toggle++ % 2 )
527- std::cout << std::endl;
528- else
529- std::cout << ' ' ;
530- }
531- #endif
532- size_t count = iptcDataSegs.size ();
533-
534- // figure out which blocks to copy
535- std::vector<size_t > pos (count + 2 );
536- pos[0 ] = 0 ;
537- // copy the data that is not iptc
538- auto it = iptcDataSegs.begin ();
539- for (size_t i = 0 ; i < count; i++) {
540- bool bOdd = (i % 2 ) != 0 ;
541- bool bEven = !bOdd;
542- pos[i + 1 ] = bEven ? *it : pos[i] + *it;
543- ++it;
544- }
545- pos[count + 1 ] = io_->size ();
546- #ifdef EXIV2_DEBUG_MESSAGES
547- for (size_t i = 0 ; i < count + 2 ; i++)
548- std::cout << pos[i] << " " ;
549- std::cout << std::endl;
550- #endif
520+ // Add a sentinel to the end of iptcDataSegs
521+ iptcDataSegs.push_back (std::make_pair (io_->size (), 0 ));
522+
551523 // $ dd bs=1 skip=$((0)) count=$((13164)) if=ETH0138028.jpg of=E1.jpg
552524 // $ dd bs=1 skip=$((49304)) count=2000000 if=ETH0138028.jpg of=E2.jpg
553525 // cat E1.jpg E2.jpg > E.jpg
554526 // exiv2 -pS E.jpg
555527
556528 // binary copy io_ to a temporary file
557529 MemIo tempIo;
558- for (size_t i = 0 ; i < (count / 2 ) + 1 ; i++) {
559- size_t start = pos[2 * i] + 2 ; // step JPG 2 byte marker
560- if (start == 2 )
561- start = 0 ; // read the file 2 byte SOI
562- size_t length = pos[2 * i + 1 ] - start;
563- if (length) {
564- #ifdef EXIV2_DEBUG_MESSAGES
565- std::cout << start << " :" << length << std::endl;
566- #endif
567- io_->seekOrThrow (start, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
568- DataBuf buf (length);
569- io_->readOrThrow (buf.data (), buf.size (), ErrorCode::kerFailedToReadImageData);
570- tempIo.write (buf.c_data (), buf.size ());
571- }
530+ size_t start = 0 ;
531+ for (const auto & p : iptcDataSegs) {
532+ const size_t length = p.first - start;
533+ io_->seekOrThrow (start, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
534+ DataBuf buf (length);
535+ io_->readOrThrow (buf.data (), buf.size (), ErrorCode::kerFailedToReadImageData);
536+ tempIo.write (buf.c_data (), buf.size ());
537+ start = p.second + 2 ; // skip the 2 byte marker
572538 }
573539
574540 io_->seekOrThrow (0 , BasicIo::beg, ErrorCode::kerFailedToReadImageData);
575541 io_->transfer (tempIo); // may throw
576542 io_->seekOrThrow (0 , BasicIo::beg, ErrorCode::kerFailedToReadImageData);
543+
544+ // Check that the result is correctly formatted.
577545 readMetadata ();
578546 }
579547} // JpegBase::printStructure
@@ -591,7 +559,7 @@ void JpegBase::writeMetadata() {
591559}
592560
593561DataBuf JpegBase::readNextSegment (byte marker) {
594- auto [sizebuf, size] = readSegmentSize (marker, *io_);
562+ const auto [sizebuf, size] = readSegmentSize (marker, *io_);
595563
596564 // Read the rest of the segment.
597565 DataBuf buf (size);
0 commit comments