diff --git a/src/canonmn_int.cpp b/src/canonmn_int.cpp index 8432a1f32b..28e77fb759 100644 --- a/src/canonmn_int.cpp +++ b/src/canonmn_int.cpp @@ -11,6 +11,7 @@ #include "error.hpp" #include "exif.hpp" #include "i18n.h" // NLS support. +#include "image_int.hpp" #include "makernote_int.hpp" #include "tags_int.hpp" #include "types.hpp" @@ -2833,16 +2834,11 @@ std::ostream& CanonMakerNote::print0x0008(std::ostream& os, const Value& value, } std::ostream& CanonMakerNote::print0x000a(std::ostream& os, const Value& value, const ExifData*) { - std::istringstream is(value.toString()); - uint32_t l = 0; - is >> l; - return os << std::setw(4) << std::setfill('0') << std::hex << ((l & 0xffff0000) >> 16) << std::setw(5) - << std::setfill('0') << std::dec << (l & 0x0000ffff); + uint32_t l = std::stoul(value.toString()); + return os << stringFormat("{:04x}{:05}", (l >> 16) & 0xFFFF, l & 0xFFFF); } std::ostream& CanonMakerNote::print0x000c(std::ostream& os, const Value& value, const ExifData* exifData) { - std::istringstream is(value.toString()); - if (!exifData) { return os << value; } @@ -2851,10 +2847,8 @@ std::ostream& CanonMakerNote::print0x000c(std::ostream& os, const Value& value, auto pos = exifData->findKey(key); // if model is EOS D30 if (pos != exifData->end() && pos->value().count() == 1 && pos->value().toInt64() == 0x01140000) { - uint32_t l = 0; - is >> l; - return os << std::setw(4) << std::setfill('0') << std::hex << ((l & 0xffff0000) >> 16) << std::setw(5) - << std::setfill('0') << std::dec << (l & 0x0000ffff); + uint32_t l = std::stoul(value.toString()); + return os << stringFormat("{:04x}{:05}", (l >> 16) & 0xFFFF, l & 0xFFFF); } return os << value; } diff --git a/src/convert.cpp b/src/convert.cpp index 55ed8e8194..5aad179d72 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -742,11 +742,13 @@ void Converter::cnvExifVersion(const char* from, const char* to) { return; if (!prepareXmpTarget(to)) return; - std::ostringstream value; - for (size_t i = 0; i < pos->count(); ++i) { - value << static_cast(pos->toInt64(i)); + auto count = pos->count(); + std::string value; + value.reserve(count); + for (size_t i = 0; i < count; ++i) { + value += static_cast(pos->toInt64(i)); } - (*xmpData_)[to] = value.str(); + (*xmpData_)[to] = value; if (erase_) exifData_->erase(pos); } @@ -757,13 +759,13 @@ void Converter::cnvExifGPSVersion(const char* from, const char* to) { return; if (!prepareXmpTarget(to)) return; - std::ostringstream value; + std::string value; for (size_t i = 0; i < pos->count(); ++i) { if (i > 0) - value << '.'; - value << pos->toInt64(i); + value += '.'; + value += std::to_string(pos->toInt64(i)); } - (*xmpData_)[to] = value.str(); + (*xmpData_)[to] = value; if (erase_) exifData_->erase(pos); } @@ -826,9 +828,7 @@ void Converter::cnvExifGPSCoord(const char* from, const char* to) { double min = (deg[0] * 60.0) + deg[1] + (deg[2] / 60.0); auto ideg = static_cast(min / 60.0); min -= ideg * 60; - std::ostringstream oss; - oss << ideg << "," << std::fixed << std::setprecision(7) << min << refPos->toString().c_str()[0]; - (*xmpData_)[to] = oss.str(); + (*xmpData_)[to] = stringFormat("{},{:.7f}{}", ideg, min, refPos->toString().front()); if (erase_) exifData_->erase(pos); @@ -883,7 +883,7 @@ void Converter::cnvXmpArray(const char* from, const char* to) { auto pos = xmpData_->findKey(XmpKey(from)); if (pos == xmpData_->end()) return; - std::ostringstream array; + std::string array; for (size_t i = 0; i < pos->count(); ++i) { std::string value = pos->toString(i); if (!pos->value().ok()) { @@ -892,11 +892,11 @@ void Converter::cnvXmpArray(const char* from, const char* to) { #endif return; } - array << value; + array += value; if (i != pos->count() - 1) - array << " "; + array += " "; } - (*exifData_)[to] = array.str(); + (*exifData_)[to] = array; if (erase_) xmpData_->erase(pos); } @@ -997,12 +997,9 @@ void Converter::cnvXmpVersion(const char* from, const char* to) { #endif return; } - std::ostringstream array; - array << static_cast(value[0]) << " " << static_cast(value[1]) << " " << static_cast(value[2]) << " " - << static_cast(value[3]); - - (*exifData_)[to] = array.str(); + (*exifData_)[to] = stringFormat("{} {} {} {}", static_cast(value[0]), static_cast(value[1]), + static_cast(value[2]), static_cast(value[3])); if (erase_) xmpData_->erase(pos); } @@ -1234,7 +1231,7 @@ void Converter::cnvXmpValueToIptc(const char* from, const char* to) { #ifdef EXV_HAVE_XMP_TOOLKIT std::string Converter::computeExifDigest(bool tiff) { - std::ostringstream res; + std::string res; MD5_CTX context; unsigned char digest[16]; @@ -1247,9 +1244,9 @@ std::string Converter::computeExifDigest(bool tiff) { if (!tiff && key.groupName() == "Image") continue; - if (!res.str().empty()) - res << ','; - res << key.tag(); + if (!res.empty()) + res += ','; + res += key.tag(); auto pos = exifData_->findKey(key); if (pos == exifData_->end()) continue; @@ -1259,12 +1256,11 @@ std::string Converter::computeExifDigest(bool tiff) { } } MD5Final(digest, &context); - res << ';'; - res << std::setw(2) << std::setfill('0') << std::hex << std::uppercase; + res += ';'; for (const auto& i : digest) { - res << static_cast(i); + res += stringFormat("{:02X}", i); } - return res.str(); + return res; } #else std::string Converter::computeExifDigest(bool) { diff --git a/src/datasets.cpp b/src/datasets.cpp index 355dee7dfd..36bb719cf9 100644 --- a/src/datasets.cpp +++ b/src/datasets.cpp @@ -443,17 +443,13 @@ bool IptcDataSets::dataSetRepeatable(uint16_t number, uint16_t recordId) { } uint16_t IptcDataSets::dataSet(const std::string& dataSetName, uint16_t recordId) { - uint16_t dataSet = 0; if (int idx = dataSetIdx(dataSetName, recordId); idx != -1) { // dataSetIdx checks the range of recordId - dataSet = records_[recordId][idx].number_; - } else { - if (!isHex(dataSetName, 4, "0x")) - throw Error(ErrorCode::kerInvalidDataset, dataSetName); - std::istringstream is(dataSetName); - is >> std::hex >> dataSet; + return records_[recordId][idx].number_; } - return dataSet; + if (!isHex(dataSetName, 4, "0x")) + throw Error(ErrorCode::kerInvalidDataset, dataSetName); + return std::stoi(dataSetName, nullptr, 16); } std::string IptcDataSets::recordName(uint16_t recordId) { @@ -480,8 +476,7 @@ uint16_t IptcDataSets::recordId(const std::string& recordName) { if (i == 0) { if (!isHex(recordName, 4, "0x")) throw Error(ErrorCode::kerInvalidRecord, recordName); - std::istringstream is(recordName); - is >> std::hex >> i; + i = std::stoi(recordName, nullptr, 16); } return i; } diff --git a/src/futils.cpp b/src/futils.cpp index 25796c98f1..159d8ea089 100644 --- a/src/futils.cpp +++ b/src/futils.cpp @@ -5,6 +5,7 @@ #include "config.h" #include "enforce.hpp" +#include "image_int.hpp" #include "utils.hpp" // + standard includes @@ -240,7 +241,7 @@ bool fileExists(const std::string& path) { std::string strError() { int error = errno; - std::ostringstream os; + std::string os; #ifdef EXV_HAVE_STRERROR_R const size_t n = 1024; #ifdef EXV_STRERROR_R_CHAR_P @@ -251,17 +252,16 @@ std::string strError() { const int ret = strerror_r(error, buf, n); Internal::enforce(ret != ERANGE, Exiv2::ErrorCode::kerCallFailed); #endif - os << buf; + os = buf; // Issue# 908. // report strerror() if strerror_r() returns empty - if (!buf[0]) { - os << strerror(error); + if (os.empty()) { + os = std::strerror(error); } #else - os << std::strerror(error); + os = std::strerror(error); #endif - os << " (errno = " << error << ")"; - return os.str(); + return stringFormat("{} (errno = {})", os, error); } // strError void Uri::Decode(Uri& uri) { diff --git a/src/tags.cpp b/src/tags.cpp index e84d5164a8..293cab2d4c 100644 --- a/src/tags.cpp +++ b/src/tags.cpp @@ -5,6 +5,7 @@ #include "error.hpp" #include "i18n.h" // NLS support. +#include "image_int.hpp" #include "tags_int.hpp" #include "types.hpp" @@ -179,9 +180,7 @@ std::string ExifKey::Impl::tagName() const { if (tagInfo_ && tagInfo_->tag_ != 0xffff) { return tagInfo_->name_; } - std::ostringstream os; - os << "0x" << std::setw(4) << std::setfill('0') << std::right << std::hex << tag_; - return os.str(); + return stringFormat("0x{:04x}", tag_); } void ExifKey::Impl::decomposeKey(const std::string& key) { diff --git a/src/tags_int.cpp b/src/tags_int.cpp index 0d305f4d17..71fb781c3d 100644 --- a/src/tags_int.cpp +++ b/src/tags_int.cpp @@ -2625,10 +2625,7 @@ uint16_t tagNumber(const std::string& tagName, IfdId ifdId) { return ti->tag_; if (!isHex(tagName, 4, "0x")) throw Error(ErrorCode::kerInvalidTag, tagName, ifdId); - std::istringstream is(tagName); - uint16_t tag = 0; - is >> std::hex >> tag; - return tag; + return std::stoi(tagName, nullptr, 16); } // tagNumber std::ostream& printInt64(std::ostream& os, const Value& value, const ExifData*) {