LLVMFuzzerTestOneInput:
    7|  25.7k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
    8|       |  // Invalid files generate a lot of warnings, so switch off logging.
    9|  25.7k|  Exiv2::LogMsg::setLevel(Exiv2::LogMsg::mute);
   10|       |
   11|  25.7k|  try {
   12|  25.7k|    Exiv2::DataBuf data_copy(data, size);
   13|  25.7k|    Exiv2::Image::UniquePtr image = Exiv2::ImageFactory::open(data_copy.c_data(), size);
   14|  25.7k|    assert(image.get() != 0);
   15|       |
   16|  25.7k|    image->readMetadata();
   17|       |
   18|  25.7k|    Exiv2::PreviewManager pm(*image);
   19|  25.7k|    std::ostringstream os;
   20|  25.7k|    Exiv2::PreviewPropertiesList list = pm.getPreviewProperties();
   21|  25.7k|    for (const auto& pos : list) {
  ------------------
  |  Branch (21:26): [True: 8.96k, False: 25.7k]
  ------------------
   22|  8.96k|      os << pos.mimeType_ << "\n";
   23|       |
   24|  8.96k|      if (pos.width_ != 0 && pos.height_ != 0)
  ------------------
  |  Branch (24:11): [True: 6.76k, False: 2.20k]
  |  Branch (24:30): [True: 6.58k, False: 175]
  ------------------
   25|  6.58k|        os << pos.width_ << " " << pos.height_ << " ";
   26|       |
   27|  8.96k|      os << pos.size_ << "\n";
   28|  8.96k|    }
   29|       |
   30|  25.7k|  } catch (...) {
   31|       |    // Exiv2 throws an exception if the metadata is invalid.
   32|  9.48k|  }
   33|       |
   34|  25.7k|  return 0;
   35|  25.7k|}

_ZN5Exiv28AsfVideo7GUIDTagC2EjttNSt3__15arrayIhLm8EEE:
   81|    124|        data1_(data1), data2_(data2), data3_(data3), data4_(data4) {
   82|    124|    }
_ZNK5Exiv28AsfVideo12HeaderReader7getSizeEv:
  104|    901|    [[nodiscard]] uint64_t getSize() const {
  105|    901|      return size_;
  106|    901|    }
_ZNK5Exiv28AsfVideo12HeaderReader16getRemainingSizeEv:
  108|    167|    [[nodiscard]] uint64_t getRemainingSize() const {
  109|    167|      return remaining_size_;
  110|    167|    }
_ZN5Exiv28AsfVideo12HeaderReader5getIdEv:
  112|    726|    [[nodiscard]] DataBuf& getId() {
  113|    726|      return IdBuf_;
  114|    726|    }

_ZN5Exiv28IoCloserC2ERNS_7BasicIoE:
  249|  79.5k|  explicit IoCloser(BasicIo& bio) : bio_(bio) {
  250|  79.5k|  }
_ZN5Exiv28IoCloserD2Ev:
  252|  79.5k|  virtual ~IoCloser() {
  253|  79.5k|    close();
  254|  79.5k|  }
_ZN5Exiv28IoCloser5closeEv:
  260|  79.5k|  void close() {
  261|  79.5k|    if (bio_.isopen())
  ------------------
  |  Branch (261:9): [True: 79.5k, False: 0]
  ------------------
  262|  79.5k|      bio_.close();
  263|  79.5k|  }
_ZN5Exiv27BasicIoC2Ev:
   40|  41.6k|  BasicIo() = default;

_ZN5Exiv24IlocC2Ejjj:
   24|  6.91k|  explicit Iloc(uint32_t ID = 0, uint32_t start = 0, uint32_t length = 0) : ID_(ID), start_(start), length_(length) {
   25|  6.91k|  }

_ZN5Exiv25ErrorC2INSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEENS_9ErrorCodeERKT_:
  243|    642|  Error(ErrorCode code, const A& arg1) : code_(code), arg1_(toBasicString<char>(arg1)) {
  244|    642|    setMsg(1);
  245|    642|  }
_ZN5Exiv213toBasicStringIcNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS2_IT_NS3_IS8_EENS5_IS8_EEEERKT0_:
  153|    642|std::basic_string<charT> toBasicString(const T& arg) {
  154|    642|  std::basic_ostringstream<charT> os;
  155|    642|  os << arg;
  156|    642|  return os.str();
  157|    642|}
_ZN5Exiv213toBasicStringIcA4_cEENSt3__112basic_stringIT_NS2_11char_traitsIS4_EENS2_9allocatorIS4_EEEERKT0_:
  153|     89|std::basic_string<charT> toBasicString(const T& arg) {
  154|     89|  std::basic_ostringstream<charT> os;
  155|     89|  os << arg;
  156|     89|  return os.str();
  157|     89|}
_ZN5Exiv25ErrorC2IA10_cEENS_9ErrorCodeERKT_:
  243|     75|  Error(ErrorCode code, const A& arg1) : code_(code), arg1_(toBasicString<char>(arg1)) {
  244|     75|    setMsg(1);
  245|     75|  }
_ZN5Exiv213toBasicStringIcA10_cEENSt3__112basic_stringIT_NS2_11char_traitsIS4_EENS2_9allocatorIS4_EEEERKT0_:
  153|     75|std::basic_string<charT> toBasicString(const T& arg) {
  154|     75|  std::basic_ostringstream<charT> os;
  155|     75|  os << arg;
  156|     75|  return os.str();
  157|     75|}
_ZN5Exiv25ErrorC2IA5_cEENS_9ErrorCodeERKT_:
  243|    261|  Error(ErrorCode code, const A& arg1) : code_(code), arg1_(toBasicString<char>(arg1)) {
  244|    261|    setMsg(1);
  245|    261|  }
_ZN5Exiv213toBasicStringIcA5_cEENSt3__112basic_stringIT_NS2_11char_traitsIS4_EENS2_9allocatorIS4_EEEERKT0_:
  153|    261|std::basic_string<charT> toBasicString(const T& arg) {
  154|    261|  std::basic_ostringstream<charT> os;
  155|    261|  os << arg;
  156|    261|  return os.str();
  157|    261|}
_ZN5Exiv25ErrorC2IA4_cEENS_9ErrorCodeERKT_:
  243|     89|  Error(ErrorCode code, const A& arg1) : code_(code), arg1_(toBasicString<char>(arg1)) {
  244|     89|    setMsg(1);
  245|     89|  }
_ZN5Exiv213toBasicStringIcPKcEENSt3__112basic_stringIT_NS3_11char_traitsIS5_EENS3_9allocatorIS5_EEEERKT0_:
  153|     25|std::basic_string<charT> toBasicString(const T& arg) {
  154|     25|  std::basic_ostringstream<charT> os;
  155|     25|  os << arg;
  156|     25|  return os.str();
  157|     25|}
_ZN5Exiv25ErrorC2IPKcEENS_9ErrorCodeERKT_:
  243|     25|  Error(ErrorCode code, const A& arg1) : code_(code), arg1_(toBasicString<char>(arg1)) {
  244|     25|    setMsg(1);
  245|     25|  }

_ZN5Exiv28ExifData5beginEv:
  437|  8.80k|  iterator begin() {
  438|  8.80k|    return exifMetadata_.begin();
  439|  8.80k|  }
_ZN5Exiv28ExifData3endEv:
  441|   383k|  iterator end() {
  442|   383k|    return exifMetadata_.end();
  443|   383k|  }
_ZNK5Exiv28ExifData5beginEv:
  454|  4.47k|  [[nodiscard]] const_iterator begin() const {
  455|  4.47k|    return exifMetadata_.begin();
  456|  4.47k|  }
_ZNK5Exiv28ExifData3endEv:
  458|   685k|  [[nodiscard]] const_iterator end() const {
  459|   685k|    return exifMetadata_.end();
  460|   685k|  }
_ZNK5Exiv28ExifData5emptyEv:
  467|  2.48k|  [[nodiscard]] bool empty() const {
  468|  2.48k|    return exifMetadata_.empty();
  469|  2.48k|  }

_ZN5Exiv25Image16setTypeSupportedENS_9ImageTypeEt:
  456|     70|  void setTypeSupported(ImageType imageType, uint16_t supportedMetadata) {
  457|     70|    imageType_ = imageType;
  458|     70|    supportedMetadata_ = supportedMetadata;
  459|     70|  }

_ZN5Exiv28IptcData5clearEv:
  199|  29.2k|  void clear() {
  200|  29.2k|    iptcMetadata_.clear();
  201|  29.2k|  }
_ZN5Exiv28IptcData3endEv:
  211|  19.4k|  iterator end() {
  212|  19.4k|    return iptcMetadata_.end();
  213|  19.4k|  }
_ZNK5Exiv28IptcData5emptyEv:
  247|  4.94k|  [[nodiscard]] bool empty() const {
  248|  4.94k|    return iptcMetadata_.empty();
  249|  4.94k|  }

_ZN5Exiv28Internal11MatroskaTagC2EmNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS0_16matroskaTypeEnumENS0_19matroskaProcessEnumE:
   69|    396|      _id(id), _label(std::move(label)), _type(type), _process(process) {
   70|    396|  }
_ZN5Exiv28Internal11MatroskaTagC2EmNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   73|    152|      _id(id),
   74|    152|      _label(std::move(label)),
   75|    152|      _type(matroskaTypeEnum::UndefinedType),
   76|    152|      _process(matroskaProcessEnum::Undefined) {
   77|    152|  }
_ZNK5Exiv28Internal11MatroskaTageqEm:
   79|  3.92M|  bool operator==(uint64_t id) const {
   80|  3.92M|    return id == _id;
   81|  3.92M|  }
_ZNK5Exiv28Internal11MatroskaTag9isSkippedEv:
   83|   114k|  [[nodiscard]] bool isSkipped() const {
   84|   114k|    return _process == Skip;
   85|   114k|  }
_ZNK5Exiv28Internal11MatroskaTag11isCompositeEv:
   86|  79.8k|  [[nodiscard]] bool isComposite() const {
   87|  79.8k|    return _process == Composite;
   88|  79.8k|  }

_ZN5Exiv29MetadatumC2Ev:
  261|  2.86M|  Metadatum() = default;
_ZN5Exiv23KeyC2Ev:
   79|  5.70M|  Key() = default;
_ZN5Exiv23KeyC2ERKS0_:
   80|  63.1k|  Key(const Key&) = default;

_ZNK5Exiv28PgfImage8mimeTypeEv:
   52|    199|  [[nodiscard]] std::string mimeType() const override {
   53|    199|    return "image/pgf";
   54|    199|  }

_ZN5Exiv213XmpProperties7XmpLockC2Ev:
   76|  1.76M|    XmpLock() : lock_(getMutex()) {
   77|  1.76M|    }

_ZNK5Exiv29RiffVideo12HeaderReader7getSizeEv:
   54|  8.23k|    [[nodiscard]] uint64_t getSize() const {
   55|  8.23k|      return size_;
   56|  8.23k|    }
_ZNK5Exiv29RiffVideo12HeaderReader5getIdEv:
   58|  75.4k|    [[nodiscard]] const std::string& getId() const {
   59|  75.4k|      return id_;
   60|  75.4k|    }

_ZN5Exiv28Internal9SliceBaseC2Emm:
   20|  3.86M|  SliceBase(size_t begin, size_t end) : begin_(begin), end_(end) {
   21|  3.86M|    if (begin >= end) {
  ------------------
  |  Branch (21:9): [True: 0, False: 3.86M]
  ------------------
   22|      0|      throw std::out_of_range("Begin must be smaller than end");
   23|      0|    }
   24|  3.86M|  }
_ZNK5Exiv28Internal9SliceBase4sizeEv:
   29|  7.73M|  [[nodiscard]] size_t size() const noexcept {
   30|       |    // cannot underflow, as we know that begin < end
   31|  7.73M|    return end_ - begin_;
   32|  7.73M|  }
_ZNK5Exiv28Internal9SliceBase10rangeCheckEm:
   41|  7.73M|  void rangeCheck(size_t index) const {
   42|  7.73M|    if (index >= size()) {
  ------------------
  |  Branch (42:9): [True: 0, False: 7.73M]
  ------------------
   43|      0|      throw std::out_of_range("Index outside of the slice");
   44|      0|    }
   45|  7.73M|  }
_ZN5Exiv25SliceIPKhEC2ES2_mm:
  451|  3.86M|      Internal::ConstSliceBase<Internal::PtrSliceStorage, const T*>(ptr, begin, end) {
  452|       |    // TODO: use using in C++11
  453|  3.86M|  }
_ZN5Exiv28Internal14ConstSliceBaseINS0_15PtrSliceStorageEPKhEC2ERS4_mm:
   90|  3.86M|  ConstSliceBase(data_type& data, size_t begin, size_t end) : SliceBase(begin, end), storage_(data, begin, end) {
   91|  3.86M|  }
_ZN5Exiv28Internal15PtrSliceStorageIPKhEC2ES3_mm:
  319|  3.86M|  PtrSliceStorage(storage_type ptr, size_t /*begin*/, size_t /*end*/) : data_(ptr) {
  320|  3.86M|    if (!ptr) {
  ------------------
  |  Branch (320:9): [True: 0, False: 3.86M]
  ------------------
  321|      0|      throw std::invalid_argument("Null pointer passed to slice constructor");
  322|      0|    }
  323|  3.86M|  }
_ZNK5Exiv28Internal14ConstSliceBaseINS0_15PtrSliceStorageEPKhE2atEm:
   99|  7.73M|  [[nodiscard]] const auto& at(size_t index) const {
  100|  7.73M|    rangeCheck(index);
  101|       |    // we know: begin_ < end <= size() <= SIZE_T_MAX
  102|       |    // and: index < end - begin
  103|       |    // thus: index + begin < end <= SIZE_T_MAX
  104|       |    // => no overflow is possible
  105|  7.73M|    return storage_.unsafeAt(begin_ + index);
  106|  7.73M|  }
_ZNK5Exiv28Internal15PtrSliceStorageIPKhE8unsafeAtEm:
  335|  7.73M|  [[nodiscard]] const auto& unsafeAt(size_t index) const noexcept {
  336|  7.73M|    return data_[index];
  337|  7.73M|  }
_ZN5Exiv214makeSliceUntilIKhEENS_5SliceIPT_EES4_m:
  527|  3.86M|[[nodiscard]] Slice<T*> makeSliceUntil(T* ptr, size_t end) {
  528|  3.86M|  return {ptr, 0, end};
  529|  3.86M|}

_ZN5Exiv27DataBuf5beginEv:
  150|  70.8M|  [[nodiscard]] auto begin() noexcept {
  151|  70.8M|    return pData_.begin();
  152|  70.8M|  }
_ZN5Exiv27DataBuf3endEv:
  154|    691|  [[nodiscard]] auto end() noexcept {
  155|    691|    return pData_.end();
  156|    691|  }
_ZNK5Exiv27DataBuf5beginEv:
  158|  16.1k|  [[nodiscard]] auto begin() const noexcept {
  159|  16.1k|    return pData_.begin();
  160|  16.1k|  }
_ZNK5Exiv27DataBuf3endEv:
  162|  16.2k|  [[nodiscard]] auto end() const noexcept {
  163|  16.2k|    return pData_.end();
  164|  16.2k|  }
_ZNK5Exiv27DataBuf4sizeEv:
  166|  3.01M|  [[nodiscard]] size_t size() const {
  167|  3.01M|    return pData_.size();
  168|  3.01M|  }
_ZNK5Exiv27DataBuf5emptyEv:
  194|  20.2k|  [[nodiscard]] bool empty() const {
  195|  20.2k|    return pData_.empty();
  196|  20.2k|  }
_ZN5Exiv27DataBufC2Ev:
  126|   566k|  DataBuf() = default;
image.cpp:_ZN5Exiv24findIKN12_GLOBAL__N_18RegistryENS_9ImageTypeELm30EEEPKT_RAT1__S5_RKT0_:
  447|  31.8k|const T* find(T (&src)[N], const K& key) {
  448|  31.8k|  static_assert(N > 0, "Passed zero length find");
  449|  31.8k|  auto rc = std::find(src, src + N, key);
  450|  31.8k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 0, False: 31.8k]
  ------------------
  451|  31.8k|}
_ZN5Exiv28toStringItEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  466|  67.4k|std::string toString(const T& arg) {
  467|  67.4k|  return toStringHelper(arg, std::is_integral<T>());
  468|  67.4k|}
_ZN5Exiv214toStringHelperItEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_NS1_17integral_constantIbLb1EEE:
  455|  67.4k|std::string toStringHelper(const T& arg, std::true_type) {
  456|  67.4k|  return std::to_string(arg);
  457|  67.4k|}
_ZN5Exiv29getUShortIPKhEEtRKNS_5SliceIT_EENS_9ByteOrderE:
  227|  3.86M|uint16_t getUShort(const Slice<T>& buf, ByteOrder byteOrder) {
  228|  3.86M|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (228:7): [True: 2.15M, False: 1.71M]
  ------------------
  229|  2.15M|    return static_cast<byte>(buf.at(1)) << 8 | static_cast<byte>(buf.at(0));
  230|  2.15M|  }
  231|  1.71M|  return static_cast<byte>(buf.at(0)) << 8 | static_cast<byte>(buf.at(1));
  232|  3.86M|}
_ZN5Exiv24findIKNS_8Internal10TagDetailsEhLm13EEEPKT_RAT1__S4_RKT0_:
  447|  21.4k|const T* find(T (&src)[N], const K& key) {
  448|  21.4k|  static_assert(N > 0, "Passed zero length find");
  449|  21.4k|  auto rc = std::find(src, src + N, key);
  450|  21.4k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 16.8k, False: 4.66k]
  ------------------
  451|  21.4k|}
_ZN5Exiv24findIKNS_8Internal13TagVocabularyENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEELm2EEEPKT_RAT1__SB_RKT0_:
  447|  2.73k|const T* find(T (&src)[N], const K& key) {
  448|  2.73k|  static_assert(N > 0, "Passed zero length find");
  449|  2.73k|  auto rc = std::find(src, src + N, key);
  450|  2.73k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 1.90k, False: 826]
  ------------------
  451|  2.73k|}
_ZN5Exiv24findIKNS_9XmpNsInfoENS1_2NsELm47EEEPKT_RAT1__S4_RKT0_:
  447|  27.3k|const T* find(T (&src)[N], const K& key) {
  448|  27.3k|  static_assert(N > 0, "Passed zero length find");
  449|  27.3k|  auto rc = std::find(src, src + N, key);
  450|  27.3k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 2.80k, False: 24.5k]
  ------------------
  451|  27.3k|}
_ZN5Exiv24findIKNS_9XmpNsInfoENS1_6PrefixELm47EEEPKT_RAT1__S4_RKT0_:
  447|   883k|const T* find(T (&src)[N], const K& key) {
  448|   883k|  static_assert(N > 0, "Passed zero length find");
  449|   883k|  auto rc = std::find(src, src + N, key);
  450|   883k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 0, False: 883k]
  ------------------
  451|   883k|}
_ZN5Exiv24findIKNS_8mimeTypeEiLm6EEEPKT_RAT1__S3_RKT0_:
  447|    113|const T* find(T (&src)[N], const K& key) {
  448|    113|  static_assert(N > 0, "Passed zero length find");
  449|    113|  auto rc = std::find(src, src + N, key);
  450|    113|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 108, False: 5]
  ------------------
  451|    113|}
types.cpp:_ZN5Exiv24findIKN12_GLOBAL__N_113TypeInfoTableENS_6TypeIdELm24EEEPKT_RAT1__S5_RKT0_:
  447|  2.45M|const T* find(T (&src)[N], const K& key) {
  448|  2.45M|  static_assert(N > 0, "Passed zero length find");
  449|  2.45M|  auto rc = std::find(src, src + N, key);
  450|  2.45M|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 752k, False: 1.69M]
  ------------------
  451|  2.45M|}
_ZN5Exiv28toStringIjEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  466|  24.1k|std::string toString(const T& arg) {
  467|  24.1k|  return toStringHelper(arg, std::is_integral<T>());
  468|  24.1k|}
_ZN5Exiv214toStringHelperIjEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_NS1_17integral_constantIbLb1EEE:
  455|  24.1k|std::string toStringHelper(const T& arg, std::true_type) {
  456|  24.1k|  return std::to_string(arg);
  457|  24.1k|}
_ZN5Exiv28toStringIsEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  466|  5.76k|std::string toString(const T& arg) {
  467|  5.76k|  return toStringHelper(arg, std::is_integral<T>());
  468|  5.76k|}
_ZN5Exiv214toStringHelperIsEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_NS1_17integral_constantIbLb1EEE:
  455|  5.76k|std::string toStringHelper(const T& arg, std::true_type) {
  456|  5.76k|  return std::to_string(arg);
  457|  5.76k|}
_ZN5Exiv28toStringIiEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  466|   164k|std::string toString(const T& arg) {
  467|   164k|  return toStringHelper(arg, std::is_integral<T>());
  468|   164k|}
_ZN5Exiv214toStringHelperIiEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_NS1_17integral_constantIbLb1EEE:
  455|   164k|std::string toStringHelper(const T& arg, std::true_type) {
  456|   164k|  return std::to_string(arg);
  457|   164k|}
_ZN5Exiv28toStringIfEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  466|  1.60k|std::string toString(const T& arg) {
  467|  1.60k|  return toStringHelper(arg, std::is_integral<T>());
  468|  1.60k|}
_ZN5Exiv214toStringHelperIfEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_NS1_17integral_constantIbLb0EEE:
  460|  1.60k|std::string toStringHelper(const T& arg, std::false_type) {
  461|  1.60k|  std::ostringstream os;
  462|  1.60k|  os << arg;
  463|  1.60k|  return os.str();
  464|  1.60k|}
_ZN5Exiv28toStringIdEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  466|   116k|std::string toString(const T& arg) {
  467|   116k|  return toStringHelper(arg, std::is_integral<T>());
  468|   116k|}
_ZN5Exiv214toStringHelperIdEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_NS1_17integral_constantIbLb0EEE:
  460|   116k|std::string toStringHelper(const T& arg, std::false_type) {
  461|   116k|  std::ostringstream os;
  462|   116k|  os << arg;
  463|   116k|  return os.str();
  464|   116k|}
_ZN5Exiv28toStringImEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  466|  12.0k|std::string toString(const T& arg) {
  467|  12.0k|  return toStringHelper(arg, std::is_integral<T>());
  468|  12.0k|}
_ZN5Exiv214toStringHelperImEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_NS1_17integral_constantIbLb1EEE:
  455|  12.0k|std::string toStringHelper(const T& arg, std::true_type) {
  456|  12.0k|  return std::to_string(arg);
  457|  12.0k|}
_ZN5Exiv24findIKNS_8Internal11MatroskaTagEmLm4EEEPKT_RAT1__S4_RKT0_:
  447|  1.59k|const T* find(T (&src)[N], const K& key) {
  448|  1.59k|  static_assert(N > 0, "Passed zero length find");
  449|  1.59k|  auto rc = std::find(src, src + N, key);
  450|  1.59k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 1.05k, False: 537]
  ------------------
  451|  1.59k|}
_ZN5Exiv24findIKNS_8Internal11MatroskaTagEmLm6EEEPKT_RAT1__S4_RKT0_:
  447|  1.10k|const T* find(T (&src)[N], const K& key) {
  448|  1.10k|  static_assert(N > 0, "Passed zero length find");
  449|  1.10k|  auto rc = std::find(src, src + N, key);
  450|  1.10k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 287, False: 815]
  ------------------
  451|  1.10k|}
_ZN5Exiv24findIKNS_8Internal11MatroskaTagEmLm5EEEPKT_RAT1__S4_RKT0_:
  447|  1.10k|const T* find(T (&src)[N], const K& key) {
  448|  1.10k|  static_assert(N > 0, "Passed zero length find");
  449|  1.10k|  auto rc = std::find(src, src + N, key);
  450|  1.10k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 610, False: 491]
  ------------------
  451|  1.10k|}
_ZN5Exiv24findIKNS_8Internal11MatroskaTagEmLm198EEEPKT_RAT1__S4_RKT0_:
  447|  80.9k|const T* find(T (&src)[N], const K& key) {
  448|  80.9k|  static_assert(N > 0, "Passed zero length find");
  449|  80.9k|  auto rc = std::find(src, src + N, key);
  450|  80.9k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 999, False: 79.9k]
  ------------------
  451|  80.9k|}
_ZN5Exiv24findIKNS_8Internal11MatroskaTagEmLm2EEEPKT_RAT1__S4_RKT0_:
  447|  3.59k|const T* find(T (&src)[N], const K& key) {
  448|  3.59k|  static_assert(N > 0, "Passed zero length find");
  449|  3.59k|  auto rc = std::find(src, src + N, key);
  450|  3.59k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 2.31k, False: 1.27k]
  ------------------
  451|  3.59k|}
_ZN5Exiv24findIKNS_8Internal11MatroskaTagEmLm3EEEPKT_RAT1__S4_RKT0_:
  447|  13.3k|const T* find(T (&src)[N], const K& key) {
  448|  13.3k|  static_assert(N > 0, "Passed zero length find");
  449|  13.3k|  auto rc = std::find(src, src + N, key);
  450|  13.3k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 10.4k, False: 2.96k]
  ------------------
  451|  13.3k|}
_ZN5Exiv24findIKNS_8Internal11MatroskaTagEmLm7EEEPKT_RAT1__S4_RKT0_:
  447|  4.19k|const T* find(T (&src)[N], const K& key) {
  448|  4.19k|  static_assert(N > 0, "Passed zero length find");
  449|  4.19k|  auto rc = std::find(src, src + N, key);
  450|  4.19k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 3.23k, False: 957]
  ------------------
  451|  4.19k|}
_ZN5Exiv28toStringIPKhEENSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKT_:
  466|  1.63k|std::string toString(const T& arg) {
  467|  1.63k|  return toStringHelper(arg, std::is_integral<T>());
  468|  1.63k|}
_ZN5Exiv214toStringHelperIPKhEENSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKT_NS3_17integral_constantIbLb0EEE:
  460|  1.63k|std::string toStringHelper(const T& arg, std::false_type) {
  461|  1.63k|  std::ostringstream os;
  462|  1.63k|  os << arg;
  463|  1.63k|  return os.str();
  464|  1.63k|}
_ZN5Exiv28toStringIlEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_:
  466|    710|std::string toString(const T& arg) {
  467|    710|  return toStringHelper(arg, std::is_integral<T>());
  468|    710|}
_ZN5Exiv214toStringHelperIlEENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKT_NS1_17integral_constantIbLb1EEE:
  455|    710|std::string toStringHelper(const T& arg, std::true_type) {
  456|    710|  return std::to_string(arg);
  457|    710|}
_ZN5Exiv28toStringIPhEENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKT_:
  466|  1.57M|std::string toString(const T& arg) {
  467|  1.57M|  return toStringHelper(arg, std::is_integral<T>());
  468|  1.57M|}
_ZN5Exiv214toStringHelperIPhEENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKT_NS2_17integral_constantIbLb0EEE:
  460|  1.57M|std::string toStringHelper(const T& arg, std::false_type) {
  461|  1.57M|  std::ostringstream os;
  462|  1.57M|  os << arg;
  463|  1.57M|  return os.str();
  464|  1.57M|}
_ZN5Exiv24findIKNS_8Internal10TagDetailsEjLm6EEEPKT_RAT1__S4_RKT0_:
  447|  3.06k|const T* find(T (&src)[N], const K& key) {
  448|  3.06k|  static_assert(N > 0, "Passed zero length find");
  449|  3.06k|  auto rc = std::find(src, src + N, key);
  450|  3.06k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 953, False: 2.11k]
  ------------------
  451|  3.06k|}
_ZN5Exiv24findIKNS_8Internal13TagVocabularyENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEELm32EEEPKT_RAT1__SB_RKT0_:
  447|   381k|const T* find(T (&src)[N], const K& key) {
  448|   381k|  static_assert(N > 0, "Passed zero length find");
  449|   381k|  auto rc = std::find(src, src + N, key);
  450|   381k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 41.7k, False: 339k]
  ------------------
  451|   381k|}
_ZN5Exiv24findIKNS_8Internal13TagVocabularyENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEELm61EEEPKT_RAT1__SB_RKT0_:
  447|   381k|const T* find(T (&src)[N], const K& key) {
  448|   381k|  static_assert(N > 0, "Passed zero length find");
  449|   381k|  auto rc = std::find(src, src + N, key);
  450|   381k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 378k, False: 2.97k]
  ------------------
  451|   381k|}
_ZN5Exiv24findIKNS_8Internal10TagDetailsEjLm41EEEPKT_RAT1__S4_RKT0_:
  447|   733k|const T* find(T (&src)[N], const K& key) {
  448|   733k|  static_assert(N > 0, "Passed zero length find");
  449|   733k|  auto rc = std::find(src, src + N, key);
  450|   733k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 680k, False: 53.4k]
  ------------------
  451|   733k|}
_ZN5Exiv24findIKNS_8Internal10TagDetailsEiLm3EEEPKT_RAT1__S4_RKT0_:
  447|  84.3k|const T* find(T (&src)[N], const K& key) {
  448|  84.3k|  static_assert(N > 0, "Passed zero length find");
  449|  84.3k|  auto rc = std::find(src, src + N, key);
  450|  84.3k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 28.2k, False: 56.0k]
  ------------------
  451|  84.3k|}
_ZN5Exiv24findIKNS_8Internal10TagDetailsEiLm6EEEPKT_RAT1__S4_RKT0_:
  447|  13.2k|const T* find(T (&src)[N], const K& key) {
  448|  13.2k|  static_assert(N > 0, "Passed zero length find");
  449|  13.2k|  auto rc = std::find(src, src + N, key);
  450|  13.2k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 11.3k, False: 1.85k]
  ------------------
  451|  13.2k|}
_ZN5Exiv24findIKNS_8Internal10TagDetailsEiLm11EEEPKT_RAT1__S4_RKT0_:
  447|  13.2k|const T* find(T (&src)[N], const K& key) {
  448|  13.2k|  static_assert(N > 0, "Passed zero length find");
  449|  13.2k|  auto rc = std::find(src, src + N, key);
  450|  13.2k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 9.72k, False: 3.50k]
  ------------------
  451|  13.2k|}
_ZN5Exiv24findIKNS_8Internal10TagDetailsEiLm2EEEPKT_RAT1__S4_RKT0_:
  447|  4.72k|const T* find(T (&src)[N], const K& key) {
  448|  4.72k|  static_assert(N > 0, "Passed zero length find");
  449|  4.72k|  auto rc = std::find(src, src + N, key);
  450|  4.72k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 799, False: 3.92k]
  ------------------
  451|  4.72k|}
_ZN5Exiv24findIKNS_8Internal13TagVocabularyENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEELm86EEEPKT_RAT1__SB_RKT0_:
  447|   163k|const T* find(T (&src)[N], const K& key) {
  448|   163k|  static_assert(N > 0, "Passed zero length find");
  449|   163k|  auto rc = std::find(src, src + N, key);
  450|   163k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 138k, False: 24.6k]
  ------------------
  451|   163k|}
_ZN5Exiv24findIKNS_8Internal13TagVocabularyENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEELm17EEEPKT_RAT1__SB_RKT0_:
  447|  63.1k|const T* find(T (&src)[N], const K& key) {
  448|  63.1k|  static_assert(N > 0, "Passed zero length find");
  449|  63.1k|  auto rc = std::find(src, src + N, key);
  450|  63.1k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 60.9k, False: 2.18k]
  ------------------
  451|  63.1k|}
_ZN5Exiv24findIKNS_8Internal10TagDetailsEtLm31EEEPKT_RAT1__S4_RKT0_:
  447|  4.97k|const T* find(T (&src)[N], const K& key) {
  448|  4.97k|  static_assert(N > 0, "Passed zero length find");
  449|  4.97k|  auto rc = std::find(src, src + N, key);
  450|  4.97k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 1.22k, False: 3.75k]
  ------------------
  451|  4.97k|}
_ZN5Exiv24findIKNS_8Internal13TagVocabularyENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEELm16EEEPKT_RAT1__SB_RKT0_:
  447|  2.17k|const T* find(T (&src)[N], const K& key) {
  448|  2.17k|  static_assert(N > 0, "Passed zero length find");
  449|  2.17k|  auto rc = std::find(src, src + N, key);
  450|  2.17k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 886, False: 1.28k]
  ------------------
  451|  2.17k|}
_ZN5Exiv24findIKNS_9GroupInfoENS_5IfdIdELm126EEEPKT_RAT1__S4_RKT0_:
  447|  4.60M|const T* find(T (&src)[N], const K& key) {
  448|  4.60M|  static_assert(N > 0, "Passed zero length find");
  449|  4.60M|  auto rc = std::find(src, src + N, key);
  450|  4.60M|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 0, False: 4.60M]
  ------------------
  451|  4.60M|}
_ZN5Exiv24findIKNS_9GroupInfoENSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEELm126EEEPKT_RAT1__SA_RKT0_:
  447|  2.11M|const T* find(T (&src)[N], const K& key) {
  448|  2.11M|  static_assert(N > 0, "Passed zero length find");
  449|  2.11M|  auto rc = std::find(src, src + N, key);
  450|  2.11M|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 0, False: 2.11M]
  ------------------
  451|  2.11M|}
_ZN5Exiv24findIKNS_8Internal15TiffMappingInfoENS2_3KeyELm5EEEPKT_RAT1__S5_RKT0_:
  447|  1.19M|const T* find(T (&src)[N], const K& key) {
  448|  1.19M|  static_assert(N > 0, "Passed zero length find");
  449|  1.19M|  auto rc = std::find(src, src + N, key);
  450|  1.19M|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 1.18M, False: 8.24k]
  ------------------
  451|  1.19M|}
_ZN5Exiv24findIKNS_8Internal14TiffMnRegistryENSt3__117basic_string_viewIcNS4_11char_traitsIcEEEELm26EEEPKT_RAT1__S9_RKT0_:
  447|  11.3k|const T* find(T (&src)[N], const K& key) {
  448|  11.3k|  static_assert(N > 0, "Passed zero length find");
  449|  11.3k|  auto rc = std::find(src, src + N, key);
  450|  11.3k|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 5.29k, False: 6.02k]
  ------------------
  451|  11.3k|}
_ZN5Exiv24findIKNS_8Internal13NikonArrayIdxENS2_3KeyELm34EEEPKT_RAT1__S5_RKT0_:
  447|    310|const T* find(T (&src)[N], const K& key) {
  448|    310|  static_assert(N > 0, "Passed zero length find");
  449|    310|  auto rc = std::find(src, src + N, key);
  450|    310|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 139, False: 171]
  ------------------
  451|    310|}
_ZN5Exiv28stringToIjEET_RKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERb:
  482|     12|T stringTo(const std::string& s, bool& ok) {
  483|     12|  std::istringstream is(s);
  484|     12|  T tmp = T();
  485|     12|  ok = static_cast<bool>(is >> tmp);
  486|     12|  std::string rest;
  487|     12|  is >> std::skipws >> rest;
  488|     12|  if (!rest.empty())
  ------------------
  |  Branch (488:7): [True: 6, False: 6]
  ------------------
  489|      6|    ok = false;
  490|     12|  return tmp;
  491|     12|}
_ZN5Exiv24findIKPKcNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEELm19EEEPKT_RAT1__SB_RKT0_:
  447|     21|const T* find(T (&src)[N], const K& key) {
  448|     21|  static_assert(N > 0, "Passed zero length find");
  449|     21|  auto rc = std::find(src, src + N, key);
  450|     21|  return rc == src + N ? nullptr : rc;
  ------------------
  |  Branch (450:10): [True: 21, False: 0]
  ------------------
  451|     21|}

_ZNK5Exiv25Value6typeIdEv:
   85|  2.56M|  TypeId typeId() const {
   86|  2.56M|    return type_;
   87|  2.56M|  }
_ZNK5Exiv25Value5cloneEv:
   93|  2.96M|  UniquePtr clone() const {
   94|  2.96M|    return UniquePtr(clone_());
   95|  2.96M|  }
_ZNK5Exiv25Value2okEv:
  181|  3.30k|  bool ok() const {
  182|  3.30k|    return ok_;
  183|  3.30k|  }
_ZNK5Exiv222LangAltValueComparatorclERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
  795|    997|  bool operator()(const std::string& str1, const std::string& str2) const {
  796|    997|    if (str1.size() != str2.size())
  ------------------
  |  Branch (796:9): [True: 271, False: 726]
  ------------------
  797|    271|      return str1.size() > str2.size();
  798|       |
  799|    726|    auto f = [](unsigned char a, unsigned char b) { return std::tolower(a) > std::tolower(b); };
  800|    726|    return std::lexicographical_compare(str1.begin(), str1.end(), str2.begin(), str2.end(), f);
  801|    997|  }
_ZN5Exiv27getTypeItEENS_6TypeIdEv:
 1083|   337k|inline TypeId getType<uint16_t>() {
 1084|   337k|  return unsignedShort;
 1085|   337k|}
_ZN5Exiv27getTypeIjEENS_6TypeIdEv:
 1088|  2.55k|inline TypeId getType<uint32_t>() {
 1089|  2.55k|  return unsignedLong;
 1090|  2.55k|}
_ZN5Exiv27getTypeINSt3__14pairIjjEEEENS_6TypeIdEv:
 1093|  6.43k|inline TypeId getType<URational>() {
 1094|  6.43k|  return unsignedRational;
 1095|  6.43k|}
_ZN5Exiv27getTypeIsEENS_6TypeIdEv:
 1098|  9.10k|inline TypeId getType<int16_t>() {
 1099|  9.10k|  return signedShort;
 1100|  9.10k|}
_ZN5Exiv27getTypeIiEENS_6TypeIdEv:
 1103|  8.81k|inline TypeId getType<int32_t>() {
 1104|  8.81k|  return signedLong;
 1105|  8.81k|}
_ZN5Exiv27getTypeINSt3__14pairIiiEEEENS_6TypeIdEv:
 1108|  1.93k|inline TypeId getType<Rational>() {
 1109|  1.93k|  return signedRational;
 1110|  1.93k|}
_ZN5Exiv27getTypeIfEENS_6TypeIdEv:
 1113|  2.04k|inline TypeId getType<float>() {
 1114|  2.04k|  return tiffFloat;
 1115|  2.04k|}
_ZN5Exiv27getTypeIdEENS_6TypeIdEv:
 1118|  5.26k|inline TypeId getType<double>() {
 1119|  5.26k|  return tiffDouble;
 1120|  5.26k|}
_ZN5Exiv28getValueItEET_PKhNS_9ByteOrderE:
 1314|  1.01M|inline uint16_t getValue(const byte* buf, ByteOrder byteOrder) {
 1315|  1.01M|  return getUShort(buf, byteOrder);
 1316|  1.01M|}
_ZN5Exiv28getValueIjEET_PKhNS_9ByteOrderE:
 1319|  1.00M|inline uint32_t getValue(const byte* buf, ByteOrder byteOrder) {
 1320|  1.00M|  return getULong(buf, byteOrder);
 1321|  1.00M|}
_ZN5Exiv28getValueINSt3__14pairIjjEEEET_PKhNS_9ByteOrderE:
 1324|  1.39M|inline URational getValue(const byte* buf, ByteOrder byteOrder) {
 1325|  1.39M|  return getURational(buf, byteOrder);
 1326|  1.39M|}
_ZN5Exiv28getValueIsEET_PKhNS_9ByteOrderE:
 1329|   887k|inline int16_t getValue(const byte* buf, ByteOrder byteOrder) {
 1330|   887k|  return getShort(buf, byteOrder);
 1331|   887k|}
_ZN5Exiv28getValueIiEET_PKhNS_9ByteOrderE:
 1334|   262k|inline int32_t getValue(const byte* buf, ByteOrder byteOrder) {
 1335|   262k|  return getLong(buf, byteOrder);
 1336|   262k|}
_ZN5Exiv28getValueINSt3__14pairIiiEEEET_PKhNS_9ByteOrderE:
 1339|  28.4k|inline Rational getValue(const byte* buf, ByteOrder byteOrder) {
 1340|  28.4k|  return getRational(buf, byteOrder);
 1341|  28.4k|}
_ZN5Exiv28getValueIfEET_PKhNS_9ByteOrderE:
 1344|  45.8k|inline float getValue(const byte* buf, ByteOrder byteOrder) {
 1345|  45.8k|  return getFloat(buf, byteOrder);
 1346|  45.8k|}
_ZN5Exiv28getValueIdEET_PKhNS_9ByteOrderE:
 1349|   342k|inline double getValue(const byte* buf, ByteOrder byteOrder) {
 1350|   342k|  return getDouble(buf, byteOrder);
 1351|   342k|}
_ZN5Exiv26toDataItEEmPhT_NS_9ByteOrderE:
 1372|  61.5k|inline size_t toData(byte* buf, uint16_t t, ByteOrder byteOrder) {
 1373|  61.5k|  return us2Data(buf, t, byteOrder);
 1374|  61.5k|}
_ZN5Exiv26toDataIjEEmPhT_NS_9ByteOrderE:
 1380|   628k|inline size_t toData(byte* buf, uint32_t t, ByteOrder byteOrder) {
 1381|   628k|  return ul2Data(buf, t, byteOrder);
 1382|   628k|}
_ZN5Exiv26toDataINSt3__14pairIjjEEEEmPhT_NS_9ByteOrderE:
 1388|   420k|inline size_t toData(byte* buf, URational t, ByteOrder byteOrder) {
 1389|   420k|  return ur2Data(buf, t, byteOrder);
 1390|   420k|}
_ZN5Exiv26toDataIsEEmPhT_NS_9ByteOrderE:
 1396|  7.22k|inline size_t toData(byte* buf, int16_t t, ByteOrder byteOrder) {
 1397|  7.22k|  return s2Data(buf, t, byteOrder);
 1398|  7.22k|}
_ZN5Exiv26toDataIiEEmPhT_NS_9ByteOrderE:
 1404|   216k|inline size_t toData(byte* buf, int32_t t, ByteOrder byteOrder) {
 1405|   216k|  return l2Data(buf, t, byteOrder);
 1406|   216k|}
_ZN5Exiv26toDataINSt3__14pairIiiEEEEmPhT_NS_9ByteOrderE:
 1412|  22.0k|inline size_t toData(byte* buf, Rational t, ByteOrder byteOrder) {
 1413|  22.0k|  return r2Data(buf, t, byteOrder);
 1414|  22.0k|}
_ZN5Exiv26toDataIfEEmPhT_NS_9ByteOrderE:
 1420|  6.37k|inline size_t toData(byte* buf, float t, ByteOrder byteOrder) {
 1421|  6.37k|  return f2Data(buf, t, byteOrder);
 1422|  6.37k|}
_ZN5Exiv26toDataIdEEmPhT_NS_9ByteOrderE:
 1428|  48.2k|inline size_t toData(byte* buf, double t, ByteOrder byteOrder) {
 1429|  48.2k|  return d2Data(buf, t, byteOrder);
 1430|  48.2k|}
_ZNK5Exiv29ValueTypeIdE7toInt64Em:
 1548|  1.31k|inline int64_t ValueType<double>::toInt64(size_t n) const {
 1549|  1.31k|  return float_to_integer_helper<int64_t>(n);
 1550|  1.31k|}
_ZNK5Exiv29ValueTypeIdE8toUint32Em:
 1553|  8.69k|inline uint32_t ValueType<double>::toUint32(size_t n) const {
 1554|  8.69k|  return float_to_integer_helper<uint32_t>(n);
 1555|  8.69k|}
_ZNK5Exiv29ValueTypeIfE7toInt64Em:
 1558|  2.39k|inline int64_t ValueType<float>::toInt64(size_t n) const {
 1559|  2.39k|  return float_to_integer_helper<int64_t>(n);
 1560|  2.39k|}
_ZNK5Exiv29ValueTypeIfE8toUint32Em:
 1562|  9.78k|inline uint32_t ValueType<float>::toUint32(size_t n) const {
 1563|  9.78k|  return float_to_integer_helper<uint32_t>(n);
 1564|  9.78k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE7toInt64Em:
 1567|  2.49k|inline int64_t ValueType<Rational>::toInt64(size_t n) const {
 1568|  2.49k|  return rational_to_integer_helper<int64_t>(n);
 1569|  2.49k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE8toUint32Em:
 1571|  10.5k|inline uint32_t ValueType<Rational>::toUint32(size_t n) const {
 1572|  10.5k|  return rational_to_integer_helper<uint32_t>(n);
 1573|  10.5k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE7toInt64Em:
 1576|  2.51k|inline int64_t ValueType<URational>::toInt64(size_t n) const {
 1577|  2.51k|  return rational_to_integer_helper<int64_t>(n);
 1578|  2.51k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE8toUint32Em:
 1580|  6.34k|inline uint32_t ValueType<URational>::toUint32(size_t n) const {
 1581|  6.34k|  return rational_to_integer_helper<uint32_t>(n);
 1582|  6.34k|}
_ZNK5Exiv29ValueTypeIdE23float_to_integer_helperIlEET_m:
 1212|  1.31k|  I float_to_integer_helper(size_t n) const {
 1213|  1.31k|    const auto v = value_.at(n);
 1214|  1.31k|    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
  ------------------
  |  Branch (1214:9): [True: 1.16k, False: 147]
  ------------------
 1215|  1.16k|        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
  ------------------
  |  Branch (1215:9): [True: 762, False: 404]
  ------------------
 1216|    762|      return static_cast<I>(std::lround(v));
 1217|    762|    }
 1218|    551|    return 0;
 1219|  1.31k|  }
_ZNK5Exiv29ValueTypeIdE23float_to_integer_helperIjEET_m:
 1212|  8.69k|  I float_to_integer_helper(size_t n) const {
 1213|  8.69k|    const auto v = value_.at(n);
 1214|  8.69k|    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
  ------------------
  |  Branch (1214:9): [True: 7.36k, False: 1.32k]
  ------------------
 1215|  7.36k|        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
  ------------------
  |  Branch (1215:9): [True: 5.80k, False: 1.55k]
  ------------------
 1216|  5.80k|      return static_cast<I>(std::lround(v));
 1217|  5.80k|    }
 1218|  2.88k|    return 0;
 1219|  8.69k|  }
_ZNK5Exiv29ValueTypeIfE23float_to_integer_helperIlEET_m:
 1212|  2.39k|  I float_to_integer_helper(size_t n) const {
 1213|  2.39k|    const auto v = value_.at(n);
 1214|  2.39k|    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
  ------------------
  |  Branch (1214:9): [True: 2.06k, False: 330]
  ------------------
 1215|  2.06k|        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
  ------------------
  |  Branch (1215:9): [True: 1.49k, False: 565]
  ------------------
 1216|  1.49k|      return static_cast<I>(std::lround(v));
 1217|  1.49k|    }
 1218|    895|    return 0;
 1219|  2.39k|  }
_ZNK5Exiv29ValueTypeIfE23float_to_integer_helperIjEET_m:
 1212|  9.78k|  I float_to_integer_helper(size_t n) const {
 1213|  9.78k|    const auto v = value_.at(n);
 1214|  9.78k|    if (static_cast<decltype(v)>(std::numeric_limits<I>::min()) <= v &&
  ------------------
  |  Branch (1214:9): [True: 8.53k, False: 1.25k]
  ------------------
 1215|  8.53k|        v <= static_cast<decltype(v)>(std::numeric_limits<I>::max())) {
  ------------------
  |  Branch (1215:9): [True: 7.04k, False: 1.48k]
  ------------------
 1216|  7.04k|      return static_cast<I>(std::lround(v));
 1217|  7.04k|    }
 1218|  2.74k|    return 0;
 1219|  9.78k|  }
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE26rational_to_integer_helperIlEET_m:
 1223|  2.49k|  I rational_to_integer_helper(size_t n) const {
 1224|  2.49k|    auto a = value_.at(n).first;
 1225|  2.49k|    auto b = value_.at(n).second;
 1226|       |
 1227|       |    // Protect against divide-by-zero.
 1228|  2.49k|    if (b <= 0) {
  ------------------
  |  Branch (1228:9): [True: 1.21k, False: 1.27k]
  ------------------
 1229|  1.21k|      return 0;
 1230|  1.21k|    }
 1231|       |
 1232|       |    // Check for integer overflow.
 1233|  1.27k|#ifdef __cpp_if_constexpr
 1234|  1.27k|    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
 1235|       |#else
 1236|       |    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
 1237|       |#endif
 1238|       |      // conversion does not change sign
 1239|  1.27k|      const auto imin = std::numeric_limits<I>::min();
 1240|  1.27k|      const auto imax = std::numeric_limits<I>::max();
 1241|  1.27k|      if (imax < b || a < imin || imax < a) {
  ------------------
  |  Branch (1241:11): [True: 0, False: 1.27k]
  |  Branch (1241:23): [True: 0, False: 1.27k]
  |  Branch (1241:35): [True: 0, False: 1.27k]
  ------------------
 1242|      0|        return 0;
 1243|      0|      }
 1244|  1.27k|#ifdef __cpp_if_constexpr
 1245|       |    } else if constexpr (std::is_signed_v<I>) {
 1246|       |#else
 1247|       |    } else if (std::is_signed<I>::value) {
 1248|       |#endif
 1249|       |      // conversion is from unsigned to signed
 1250|       |      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
 1251|       |      if (imax < b || imax < a) {
 1252|       |        return 0;
 1253|       |      }
 1254|       |    } else {
 1255|       |      // conversion is from signed to unsigned
 1256|       |      const auto imax = std::numeric_limits<I>::max();
 1257|       |      if (a < 0) {
 1258|       |        return 0;
 1259|       |      }
 1260|       |      // Inputs are not negative so convert them to unsigned.
 1261|       |      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
 1262|       |      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
 1263|       |      if (imax < b_u || imax < a_u) {
 1264|       |        return 0;
 1265|       |      }
 1266|       |    }
 1267|       |
 1268|  1.27k|    return static_cast<I>(a) / static_cast<I>(b);
 1269|  2.49k|  }
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE26rational_to_integer_helperIjEET_m:
 1223|  10.5k|  I rational_to_integer_helper(size_t n) const {
 1224|  10.5k|    auto a = value_.at(n).first;
 1225|  10.5k|    auto b = value_.at(n).second;
 1226|       |
 1227|       |    // Protect against divide-by-zero.
 1228|  10.5k|    if (b <= 0) {
  ------------------
  |  Branch (1228:9): [True: 3.86k, False: 6.69k]
  ------------------
 1229|  3.86k|      return 0;
 1230|  3.86k|    }
 1231|       |
 1232|       |    // Check for integer overflow.
 1233|  6.69k|#ifdef __cpp_if_constexpr
 1234|       |    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
 1235|       |#else
 1236|       |    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
 1237|       |#endif
 1238|       |      // conversion does not change sign
 1239|       |      const auto imin = std::numeric_limits<I>::min();
 1240|       |      const auto imax = std::numeric_limits<I>::max();
 1241|       |      if (imax < b || a < imin || imax < a) {
 1242|       |        return 0;
 1243|       |      }
 1244|       |#ifdef __cpp_if_constexpr
 1245|       |    } else if constexpr (std::is_signed_v<I>) {
 1246|       |#else
 1247|       |    } else if (std::is_signed<I>::value) {
 1248|       |#endif
 1249|       |      // conversion is from unsigned to signed
 1250|       |      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
 1251|       |      if (imax < b || imax < a) {
 1252|       |        return 0;
 1253|       |      }
 1254|  6.69k|    } else {
 1255|       |      // conversion is from signed to unsigned
 1256|  6.69k|      const auto imax = std::numeric_limits<I>::max();
 1257|  6.69k|      if (a < 0) {
  ------------------
  |  Branch (1257:11): [True: 749, False: 5.95k]
  ------------------
 1258|    749|        return 0;
 1259|    749|      }
 1260|       |      // Inputs are not negative so convert them to unsigned.
 1261|  5.95k|      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
 1262|  5.95k|      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
 1263|  5.95k|      if (imax < b_u || imax < a_u) {
  ------------------
  |  Branch (1263:11): [True: 0, False: 5.95k]
  |  Branch (1263:25): [True: 0, False: 5.95k]
  ------------------
 1264|      0|        return 0;
 1265|      0|      }
 1266|  5.95k|    }
 1267|       |
 1268|  5.95k|    return static_cast<I>(a) / static_cast<I>(b);
 1269|  10.5k|  }
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE26rational_to_integer_helperIlEET_m:
 1223|  2.51k|  I rational_to_integer_helper(size_t n) const {
 1224|  2.51k|    auto a = value_.at(n).first;
 1225|  2.51k|    auto b = value_.at(n).second;
 1226|       |
 1227|       |    // Protect against divide-by-zero.
 1228|  2.51k|    if (b <= 0) {
  ------------------
  |  Branch (1228:9): [True: 471, False: 2.04k]
  ------------------
 1229|    471|      return 0;
 1230|    471|    }
 1231|       |
 1232|       |    // Check for integer overflow.
 1233|  2.04k|#ifdef __cpp_if_constexpr
 1234|       |    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
 1235|       |#else
 1236|       |    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
 1237|       |#endif
 1238|       |      // conversion does not change sign
 1239|       |      const auto imin = std::numeric_limits<I>::min();
 1240|       |      const auto imax = std::numeric_limits<I>::max();
 1241|       |      if (imax < b || a < imin || imax < a) {
 1242|       |        return 0;
 1243|       |      }
 1244|       |#ifdef __cpp_if_constexpr
 1245|  2.04k|    } else if constexpr (std::is_signed_v<I>) {
 1246|       |#else
 1247|       |    } else if (std::is_signed<I>::value) {
 1248|       |#endif
 1249|       |      // conversion is from unsigned to signed
 1250|  2.04k|      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
 1251|  2.04k|      if (imax < b || imax < a) {
  ------------------
  |  Branch (1251:11): [True: 0, False: 2.04k]
  |  Branch (1251:23): [True: 0, False: 2.04k]
  ------------------
 1252|      0|        return 0;
 1253|      0|      }
 1254|       |    } else {
 1255|       |      // conversion is from signed to unsigned
 1256|       |      const auto imax = std::numeric_limits<I>::max();
 1257|       |      if (a < 0) {
 1258|       |        return 0;
 1259|       |      }
 1260|       |      // Inputs are not negative so convert them to unsigned.
 1261|       |      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
 1262|       |      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
 1263|       |      if (imax < b_u || imax < a_u) {
 1264|       |        return 0;
 1265|       |      }
 1266|       |    }
 1267|       |
 1268|  2.04k|    return static_cast<I>(a) / static_cast<I>(b);
 1269|  2.51k|  }
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE26rational_to_integer_helperIjEET_m:
 1223|  6.34k|  I rational_to_integer_helper(size_t n) const {
 1224|  6.34k|    auto a = value_.at(n).first;
 1225|  6.34k|    auto b = value_.at(n).second;
 1226|       |
 1227|       |    // Protect against divide-by-zero.
 1228|  6.34k|    if (b <= 0) {
  ------------------
  |  Branch (1228:9): [True: 1.25k, False: 5.09k]
  ------------------
 1229|  1.25k|      return 0;
 1230|  1.25k|    }
 1231|       |
 1232|       |    // Check for integer overflow.
 1233|  5.09k|#ifdef __cpp_if_constexpr
 1234|  5.09k|    if constexpr (std::is_signed_v<I> == std::is_signed_v<decltype(a)>) {
 1235|       |#else
 1236|       |    if (std::is_signed<I>::value == std::is_signed<decltype(a)>::value) {
 1237|       |#endif
 1238|       |      // conversion does not change sign
 1239|  5.09k|      const auto imin = std::numeric_limits<I>::min();
 1240|  5.09k|      const auto imax = std::numeric_limits<I>::max();
 1241|  5.09k|      if (imax < b || a < imin || imax < a) {
  ------------------
  |  Branch (1241:11): [True: 0, False: 5.09k]
  |  Branch (1241:23): [True: 0, False: 5.09k]
  |  Branch (1241:35): [True: 0, False: 5.09k]
  ------------------
 1242|      0|        return 0;
 1243|      0|      }
 1244|  5.09k|#ifdef __cpp_if_constexpr
 1245|       |    } else if constexpr (std::is_signed_v<I>) {
 1246|       |#else
 1247|       |    } else if (std::is_signed<I>::value) {
 1248|       |#endif
 1249|       |      // conversion is from unsigned to signed
 1250|       |      const auto imax = static_cast<std::make_unsigned_t<I>>(std::numeric_limits<I>::max());
 1251|       |      if (imax < b || imax < a) {
 1252|       |        return 0;
 1253|       |      }
 1254|       |    } else {
 1255|       |      // conversion is from signed to unsigned
 1256|       |      const auto imax = std::numeric_limits<I>::max();
 1257|       |      if (a < 0) {
 1258|       |        return 0;
 1259|       |      }
 1260|       |      // Inputs are not negative so convert them to unsigned.
 1261|       |      const auto a_u = static_cast<std::make_unsigned_t<decltype(a)>>(a);
 1262|       |      const auto b_u = static_cast<std::make_unsigned_t<decltype(b)>>(b);
 1263|       |      if (imax < b_u || imax < a_u) {
 1264|       |        return 0;
 1265|       |      }
 1266|       |    }
 1267|       |
 1268|  5.09k|    return static_cast<I>(a) / static_cast<I>(b);
 1269|  6.34k|  }
_ZN5Exiv29ValueTypeItEC2Ev:
 1433|   337k|ValueType<T>::ValueType() : Value(getType<T>()) {
 1434|   337k|}
_ZN5Exiv25ValueD2Ev:
   43|  4.18M|  virtual ~Value() = default;
_ZN5Exiv29ValueTypeItE4readEPKhmNS_9ByteOrderE:
 1467|   335k|int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
 1468|   335k|  value_.clear();
 1469|   335k|  size_t ts = TypeInfo::typeSize(typeId());
 1470|   335k|  if (ts > 0 && len % ts != 0)
  ------------------
  |  Branch (1470:7): [True: 335k, False: 0]
  |  Branch (1470:17): [True: 663, False: 334k]
  ------------------
 1471|    663|    len = (len / ts) * ts;
 1472|  1.35M|  for (size_t i = 0; i < len; i += ts) {
  ------------------
  |  Branch (1472:22): [True: 1.01M, False: 335k]
  ------------------
 1473|  1.01M|    value_.push_back(getValue<T>(buf + i, byteOrder));
 1474|  1.01M|  }
 1475|   335k|  return 0;
 1476|   335k|}
_ZN5Exiv29ValueTypeItE4readERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 1479|  1.68k|int ValueType<T>::read(const std::string& buf) {
 1480|  1.68k|  std::istringstream is(buf);
 1481|  1.68k|  T tmp;
 1482|  1.68k|  ValueList val;
 1483|  2.46k|  while (is >> tmp)
  ------------------
  |  Branch (1483:10): [True: 780, False: 1.68k]
  ------------------
 1484|    780|    val.push_back(tmp);
 1485|  1.68k|  if (!is.eof())
  ------------------
  |  Branch (1485:7): [True: 0, False: 1.68k]
  ------------------
 1486|      0|    return 1;
 1487|  1.68k|  value_ = std::move(val);
 1488|  1.68k|  return 0;
 1489|  1.68k|}
_ZN5Exiv29ValueTypeItE11setDataAreaEPKhm:
 1649|  1.39k|int ValueType<T>::setDataArea(const byte* buf, size_t len) {
 1650|  1.39k|  if (len > 0)
  ------------------
  |  Branch (1650:7): [True: 1.21k, False: 180]
  ------------------
 1651|  1.21k|    pDataArea_ = Blob(buf, buf + len);
 1652|    180|  else
 1653|    180|    pDataArea_.clear();
 1654|  1.39k|  return 0;
 1655|  1.39k|}
_ZNK5Exiv29ValueTypeItE4copyEPhNS_9ByteOrderE:
 1492|  4.21k|size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
 1493|  4.21k|  size_t offset = 0;
 1494|  61.5k|  for (const auto& val : value_) {
  ------------------
  |  Branch (1494:24): [True: 61.5k, False: 4.21k]
  ------------------
 1495|  61.5k|    offset += toData(buf + offset, val, byteOrder);
 1496|  61.5k|  }
 1497|  4.21k|  return offset;
 1498|  4.21k|}
_ZNK5Exiv29ValueTypeItE5countEv:
 1501|   489k|size_t ValueType<T>::count() const {
 1502|   489k|  return value_.size();
 1503|   489k|}
_ZNK5Exiv29ValueTypeItE4sizeEv:
 1506|  8.90k|size_t ValueType<T>::size() const {
 1507|  8.90k|  return TypeInfo::typeSize(typeId()) * value_.size();
 1508|  8.90k|}
_ZNK5Exiv29ValueTypeItE5writeERNSt3__113basic_ostreamIcNS2_11char_traitsIcEEEE:
 1516|    495|std::ostream& ValueType<T>::write(std::ostream& os) const {
 1517|    495|  auto end = value_.end();
 1518|    495|  auto i = value_.begin();
 1519|  8.96k|  while (i != end) {
  ------------------
  |  Branch (1519:10): [True: 8.47k, False: 495]
  ------------------
 1520|  8.47k|    os << std::setprecision(15) << *i;
 1521|  8.47k|    if (++i != end)
  ------------------
  |  Branch (1521:9): [True: 8.19k, False: 282]
  ------------------
 1522|  8.19k|      os << " ";
 1523|  8.47k|  }
 1524|    495|  return os;
 1525|    495|}
_ZNK5Exiv29ValueTypeItE7toInt64Em:
 1535|   128k|int64_t ValueType<T>::toInt64(size_t n) const {
 1536|   128k|  ok_ = true;
 1537|   128k|  return static_cast<int64_t>(value_.at(n));
 1538|   128k|}
_ZNK5Exiv29ValueTypeItE8toUint32Em:
 1540|   136k|uint32_t ValueType<T>::toUint32(size_t n) const {
 1541|   136k|  ok_ = true;
 1542|   136k|  return static_cast<uint32_t>(value_.at(n));
 1543|   136k|}
_ZNK5Exiv29ValueTypeItE12sizeDataAreaEv:
 1639|  4.29k|size_t ValueType<T>::sizeDataArea() const {
 1640|  4.29k|  return pDataArea_.size();
 1641|  4.29k|}
_ZNK5Exiv29ValueTypeItE8dataAreaEv:
 1644|    675|DataBuf ValueType<T>::dataArea() const {
 1645|    675|  return {pDataArea_.data(), pDataArea_.size()};
 1646|    675|}
_ZNK5Exiv29ValueTypeItE6clone_Ev:
 1511|   685k|ValueType<T>* ValueType<T>::clone_() const {
 1512|   685k|  return new ValueType<T>(*this);
 1513|   685k|}
_ZN5Exiv29ValueTypeItEC2ERKS1_:
 1447|   685k|ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
 1448|   685k|  if (!rhs.pDataArea_.empty())
  ------------------
  |  Branch (1448:7): [True: 4.33k, False: 681k]
  ------------------
 1449|  4.33k|    pDataArea_ = rhs.pDataArea_;
 1450|   685k|}
_ZN5Exiv25ValueC2ERKS0_:
  225|  2.06M|  Value(const Value&) = default;
_ZN5Exiv29ValueTypeIjE4readEPKhmNS_9ByteOrderE:
 1467|  37.6k|int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
 1468|  37.6k|  value_.clear();
 1469|  37.6k|  size_t ts = TypeInfo::typeSize(typeId());
 1470|  37.6k|  if (ts > 0 && len % ts != 0)
  ------------------
  |  Branch (1470:7): [True: 37.6k, False: 0]
  |  Branch (1470:17): [True: 36, False: 37.5k]
  ------------------
 1471|     36|    len = (len / ts) * ts;
 1472|  1.04M|  for (size_t i = 0; i < len; i += ts) {
  ------------------
  |  Branch (1472:22): [True: 1.00M, False: 37.6k]
  ------------------
 1473|  1.00M|    value_.push_back(getValue<T>(buf + i, byteOrder));
 1474|  1.00M|  }
 1475|  37.6k|  return 0;
 1476|  37.6k|}
_ZN5Exiv29ValueTypeIjE11setDataAreaEPKhm:
 1649|    522|int ValueType<T>::setDataArea(const byte* buf, size_t len) {
 1650|    522|  if (len > 0)
  ------------------
  |  Branch (1650:7): [True: 214, False: 308]
  ------------------
 1651|    214|    pDataArea_ = Blob(buf, buf + len);
 1652|    308|  else
 1653|    308|    pDataArea_.clear();
 1654|    522|  return 0;
 1655|    522|}
_ZNK5Exiv29ValueTypeIjE4copyEPhNS_9ByteOrderE:
 1492|  18.4k|size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
 1493|  18.4k|  size_t offset = 0;
 1494|   628k|  for (const auto& val : value_) {
  ------------------
  |  Branch (1494:24): [True: 628k, False: 18.4k]
  ------------------
 1495|   628k|    offset += toData(buf + offset, val, byteOrder);
 1496|   628k|  }
 1497|  18.4k|  return offset;
 1498|  18.4k|}
_ZNK5Exiv29ValueTypeIjE5countEv:
 1501|  73.6k|size_t ValueType<T>::count() const {
 1502|  73.6k|  return value_.size();
 1503|  73.6k|}
_ZNK5Exiv29ValueTypeIjE4sizeEv:
 1506|  37.9k|size_t ValueType<T>::size() const {
 1507|  37.9k|  return TypeInfo::typeSize(typeId()) * value_.size();
 1508|  37.9k|}
_ZNK5Exiv29ValueTypeIjE5writeERNSt3__113basic_ostreamIcNS2_11char_traitsIcEEEE:
 1516|  3.73k|std::ostream& ValueType<T>::write(std::ostream& os) const {
 1517|  3.73k|  auto end = value_.end();
 1518|  3.73k|  auto i = value_.begin();
 1519|  22.9k|  while (i != end) {
  ------------------
  |  Branch (1519:10): [True: 19.2k, False: 3.73k]
  ------------------
 1520|  19.2k|    os << std::setprecision(15) << *i;
 1521|  19.2k|    if (++i != end)
  ------------------
  |  Branch (1521:9): [True: 15.7k, False: 3.48k]
  ------------------
 1522|  15.7k|      os << " ";
 1523|  19.2k|  }
 1524|  3.73k|  return os;
 1525|  3.73k|}
_ZNK5Exiv29ValueTypeIjE7toInt64Em:
 1535|  8.66k|int64_t ValueType<T>::toInt64(size_t n) const {
 1536|  8.66k|  ok_ = true;
 1537|  8.66k|  return static_cast<int64_t>(value_.at(n));
 1538|  8.66k|}
_ZNK5Exiv29ValueTypeIjE8toUint32Em:
 1540|  11.3k|uint32_t ValueType<T>::toUint32(size_t n) const {
 1541|  11.3k|  ok_ = true;
 1542|  11.3k|  return static_cast<uint32_t>(value_.at(n));
 1543|  11.3k|}
_ZNK5Exiv29ValueTypeIjE12sizeDataAreaEv:
 1639|  5.47k|size_t ValueType<T>::sizeDataArea() const {
 1640|  5.47k|  return pDataArea_.size();
 1641|  5.47k|}
_ZNK5Exiv29ValueTypeIjE8dataAreaEv:
 1644|    137|DataBuf ValueType<T>::dataArea() const {
 1645|    137|  return {pDataArea_.data(), pDataArea_.size()};
 1646|    137|}
_ZNK5Exiv29ValueTypeIjE6clone_Ev:
 1511|   118k|ValueType<T>* ValueType<T>::clone_() const {
 1512|   118k|  return new ValueType<T>(*this);
 1513|   118k|}
_ZN5Exiv29ValueTypeIjEC2ERKS1_:
 1447|   118k|ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
 1448|   118k|  if (!rhs.pDataArea_.empty())
  ------------------
  |  Branch (1448:7): [True: 412, False: 118k]
  ------------------
 1449|    412|    pDataArea_ = rhs.pDataArea_;
 1450|   118k|}
_ZN5Exiv29ValueTypeINSt3__14pairIjjEEEC2Ev:
 1433|  6.43k|ValueType<T>::ValueType() : Value(getType<T>()) {
 1434|  6.43k|}
_ZN5Exiv29ValueTypeINSt3__14pairIjjEEE4readEPKhmNS_9ByteOrderE:
 1467|  6.41k|int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
 1468|  6.41k|  value_.clear();
 1469|  6.41k|  size_t ts = TypeInfo::typeSize(typeId());
 1470|  6.41k|  if (ts > 0 && len % ts != 0)
  ------------------
  |  Branch (1470:7): [True: 6.41k, False: 0]
  |  Branch (1470:17): [True: 0, False: 6.41k]
  ------------------
 1471|      0|    len = (len / ts) * ts;
 1472|  1.40M|  for (size_t i = 0; i < len; i += ts) {
  ------------------
  |  Branch (1472:22): [True: 1.39M, False: 6.41k]
  ------------------
 1473|  1.39M|    value_.push_back(getValue<T>(buf + i, byteOrder));
 1474|  1.39M|  }
 1475|  6.41k|  return 0;
 1476|  6.41k|}
_ZN5Exiv29ValueTypeINSt3__14pairIjjEEE11setDataAreaEPKhm:
 1649|    631|int ValueType<T>::setDataArea(const byte* buf, size_t len) {
 1650|    631|  if (len > 0)
  ------------------
  |  Branch (1650:7): [True: 229, False: 402]
  ------------------
 1651|    229|    pDataArea_ = Blob(buf, buf + len);
 1652|    402|  else
 1653|    402|    pDataArea_.clear();
 1654|    631|  return 0;
 1655|    631|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE4copyEPhNS_9ByteOrderE:
 1492|  1.76k|size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
 1493|  1.76k|  size_t offset = 0;
 1494|   420k|  for (const auto& val : value_) {
  ------------------
  |  Branch (1494:24): [True: 420k, False: 1.76k]
  ------------------
 1495|   420k|    offset += toData(buf + offset, val, byteOrder);
 1496|   420k|  }
 1497|  1.76k|  return offset;
 1498|  1.76k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE5countEv:
 1501|  18.2k|size_t ValueType<T>::count() const {
 1502|  18.2k|  return value_.size();
 1503|  18.2k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE4sizeEv:
 1506|  4.99k|size_t ValueType<T>::size() const {
 1507|  4.99k|  return TypeInfo::typeSize(typeId()) * value_.size();
 1508|  4.99k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE5writeERNS1_13basic_ostreamIcNS1_11char_traitsIcEEEE:
 1516|    699|std::ostream& ValueType<T>::write(std::ostream& os) const {
 1517|    699|  auto end = value_.end();
 1518|    699|  auto i = value_.begin();
 1519|  4.98k|  while (i != end) {
  ------------------
  |  Branch (1519:10): [True: 4.28k, False: 699]
  ------------------
 1520|  4.28k|    os << std::setprecision(15) << *i;
 1521|  4.28k|    if (++i != end)
  ------------------
  |  Branch (1521:9): [True: 3.98k, False: 302]
  ------------------
 1522|  3.98k|      os << " ";
 1523|  4.28k|  }
 1524|    699|  return os;
 1525|    699|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE12sizeDataAreaEv:
 1639|  2.44k|size_t ValueType<T>::sizeDataArea() const {
 1640|  2.44k|  return pDataArea_.size();
 1641|  2.44k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE8dataAreaEv:
 1644|      6|DataBuf ValueType<T>::dataArea() const {
 1645|      6|  return {pDataArea_.data(), pDataArea_.size()};
 1646|      6|}
_ZNK5Exiv29ValueTypeINSt3__14pairIjjEEE6clone_Ev:
 1511|  21.8k|ValueType<T>* ValueType<T>::clone_() const {
 1512|  21.8k|  return new ValueType<T>(*this);
 1513|  21.8k|}
_ZN5Exiv29ValueTypeINSt3__14pairIjjEEEC2ERKS4_:
 1447|  21.8k|ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
 1448|  21.8k|  if (!rhs.pDataArea_.empty())
  ------------------
  |  Branch (1448:7): [True: 779, False: 21.0k]
  ------------------
 1449|    779|    pDataArea_ = rhs.pDataArea_;
 1450|  21.8k|}
_ZN5Exiv29ValueTypeIsEC2Ev:
 1433|  9.10k|ValueType<T>::ValueType() : Value(getType<T>()) {
 1434|  9.10k|}
_ZN5Exiv29ValueTypeIsE4readEPKhmNS_9ByteOrderE:
 1467|  2.37k|int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
 1468|  2.37k|  value_.clear();
 1469|  2.37k|  size_t ts = TypeInfo::typeSize(typeId());
 1470|  2.37k|  if (ts > 0 && len % ts != 0)
  ------------------
  |  Branch (1470:7): [True: 2.37k, False: 0]
  |  Branch (1470:17): [True: 65, False: 2.30k]
  ------------------
 1471|     65|    len = (len / ts) * ts;
 1472|   889k|  for (size_t i = 0; i < len; i += ts) {
  ------------------
  |  Branch (1472:22): [True: 887k, False: 2.37k]
  ------------------
 1473|   887k|    value_.push_back(getValue<T>(buf + i, byteOrder));
 1474|   887k|  }
 1475|  2.37k|  return 0;
 1476|  2.37k|}
_ZN5Exiv29ValueTypeIsE4readERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 1479|  6.73k|int ValueType<T>::read(const std::string& buf) {
 1480|  6.73k|  std::istringstream is(buf);
 1481|  6.73k|  T tmp;
 1482|  6.73k|  ValueList val;
 1483|  23.7k|  while (is >> tmp)
  ------------------
  |  Branch (1483:10): [True: 16.9k, False: 6.73k]
  ------------------
 1484|  16.9k|    val.push_back(tmp);
 1485|  6.73k|  if (!is.eof())
  ------------------
  |  Branch (1485:7): [True: 0, False: 6.73k]
  ------------------
 1486|      0|    return 1;
 1487|  6.73k|  value_ = std::move(val);
 1488|  6.73k|  return 0;
 1489|  6.73k|}
_ZN5Exiv29ValueTypeIsE11setDataAreaEPKhm:
 1649|    661|int ValueType<T>::setDataArea(const byte* buf, size_t len) {
 1650|    661|  if (len > 0)
  ------------------
  |  Branch (1650:7): [True: 262, False: 399]
  ------------------
 1651|    262|    pDataArea_ = Blob(buf, buf + len);
 1652|    399|  else
 1653|    399|    pDataArea_.clear();
 1654|    661|  return 0;
 1655|    661|}
_ZNK5Exiv29ValueTypeIsE4copyEPhNS_9ByteOrderE:
 1492|    667|size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
 1493|    667|  size_t offset = 0;
 1494|  7.22k|  for (const auto& val : value_) {
  ------------------
  |  Branch (1494:24): [True: 7.22k, False: 667]
  ------------------
 1495|  7.22k|    offset += toData(buf + offset, val, byteOrder);
 1496|  7.22k|  }
 1497|    667|  return offset;
 1498|    667|}
_ZNK5Exiv29ValueTypeIsE5countEv:
 1501|  7.87k|size_t ValueType<T>::count() const {
 1502|  7.87k|  return value_.size();
 1503|  7.87k|}
_ZNK5Exiv29ValueTypeIsE4sizeEv:
 1506|  1.46k|size_t ValueType<T>::size() const {
 1507|  1.46k|  return TypeInfo::typeSize(typeId()) * value_.size();
 1508|  1.46k|}
_ZNK5Exiv29ValueTypeIsE5writeERNSt3__113basic_ostreamIcNS2_11char_traitsIcEEEE:
 1516|    502|std::ostream& ValueType<T>::write(std::ostream& os) const {
 1517|    502|  auto end = value_.end();
 1518|    502|  auto i = value_.begin();
 1519|  79.2k|  while (i != end) {
  ------------------
  |  Branch (1519:10): [True: 78.7k, False: 502]
  ------------------
 1520|  78.7k|    os << std::setprecision(15) << *i;
 1521|  78.7k|    if (++i != end)
  ------------------
  |  Branch (1521:9): [True: 78.4k, False: 303]
  ------------------
 1522|  78.4k|      os << " ";
 1523|  78.7k|  }
 1524|    502|  return os;
 1525|    502|}
_ZNK5Exiv29ValueTypeIsE7toInt64Em:
 1535|    452|int64_t ValueType<T>::toInt64(size_t n) const {
 1536|    452|  ok_ = true;
 1537|    452|  return static_cast<int64_t>(value_.at(n));
 1538|    452|}
_ZNK5Exiv29ValueTypeIsE8toUint32Em:
 1540|  4.03k|uint32_t ValueType<T>::toUint32(size_t n) const {
 1541|  4.03k|  ok_ = true;
 1542|  4.03k|  return static_cast<uint32_t>(value_.at(n));
 1543|  4.03k|}
_ZNK5Exiv29ValueTypeIsE12sizeDataAreaEv:
 1639|    849|size_t ValueType<T>::sizeDataArea() const {
 1640|    849|  return pDataArea_.size();
 1641|    849|}
_ZNK5Exiv29ValueTypeIsE8dataAreaEv:
 1644|    217|DataBuf ValueType<T>::dataArea() const {
 1645|    217|  return {pDataArea_.data(), pDataArea_.size()};
 1646|    217|}
_ZNK5Exiv29ValueTypeIsE6clone_Ev:
 1511|  13.7k|ValueType<T>* ValueType<T>::clone_() const {
 1512|  13.7k|  return new ValueType<T>(*this);
 1513|  13.7k|}
_ZN5Exiv29ValueTypeIsEC2ERKS1_:
 1447|  13.7k|ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
 1448|  13.7k|  if (!rhs.pDataArea_.empty())
  ------------------
  |  Branch (1448:7): [True: 814, False: 12.9k]
  ------------------
 1449|    814|    pDataArea_ = rhs.pDataArea_;
 1450|  13.7k|}
_ZN5Exiv29ValueTypeIiEC2Ev:
 1433|  8.81k|ValueType<T>::ValueType() : Value(getType<T>()) {
 1434|  8.81k|}
_ZN5Exiv29ValueTypeIiE4readEPKhmNS_9ByteOrderE:
 1467|  8.81k|int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
 1468|  8.81k|  value_.clear();
 1469|  8.81k|  size_t ts = TypeInfo::typeSize(typeId());
 1470|  8.81k|  if (ts > 0 && len % ts != 0)
  ------------------
  |  Branch (1470:7): [True: 8.81k, False: 0]
  |  Branch (1470:17): [True: 72, False: 8.74k]
  ------------------
 1471|     72|    len = (len / ts) * ts;
 1472|   271k|  for (size_t i = 0; i < len; i += ts) {
  ------------------
  |  Branch (1472:22): [True: 262k, False: 8.81k]
  ------------------
 1473|   262k|    value_.push_back(getValue<T>(buf + i, byteOrder));
 1474|   262k|  }
 1475|  8.81k|  return 0;
 1476|  8.81k|}
_ZN5Exiv29ValueTypeIiE11setDataAreaEPKhm:
 1649|    460|int ValueType<T>::setDataArea(const byte* buf, size_t len) {
 1650|    460|  if (len > 0)
  ------------------
  |  Branch (1650:7): [True: 177, False: 283]
  ------------------
 1651|    177|    pDataArea_ = Blob(buf, buf + len);
 1652|    283|  else
 1653|    283|    pDataArea_.clear();
 1654|    460|  return 0;
 1655|    460|}
_ZNK5Exiv29ValueTypeIiE4copyEPhNS_9ByteOrderE:
 1492|  5.42k|size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
 1493|  5.42k|  size_t offset = 0;
 1494|   216k|  for (const auto& val : value_) {
  ------------------
  |  Branch (1494:24): [True: 216k, False: 5.42k]
  ------------------
 1495|   216k|    offset += toData(buf + offset, val, byteOrder);
 1496|   216k|  }
 1497|  5.42k|  return offset;
 1498|  5.42k|}
_ZNK5Exiv29ValueTypeIiE5countEv:
 1501|  17.6k|size_t ValueType<T>::count() const {
 1502|  17.6k|  return value_.size();
 1503|  17.6k|}
_ZNK5Exiv29ValueTypeIiE4sizeEv:
 1506|  11.6k|size_t ValueType<T>::size() const {
 1507|  11.6k|  return TypeInfo::typeSize(typeId()) * value_.size();
 1508|  11.6k|}
_ZNK5Exiv29ValueTypeIiE5writeERNSt3__113basic_ostreamIcNS2_11char_traitsIcEEEE:
 1516|    629|std::ostream& ValueType<T>::write(std::ostream& os) const {
 1517|    629|  auto end = value_.end();
 1518|    629|  auto i = value_.begin();
 1519|   206k|  while (i != end) {
  ------------------
  |  Branch (1519:10): [True: 206k, False: 629]
  ------------------
 1520|   206k|    os << std::setprecision(15) << *i;
 1521|   206k|    if (++i != end)
  ------------------
  |  Branch (1521:9): [True: 205k, False: 433]
  ------------------
 1522|   205k|      os << " ";
 1523|   206k|  }
 1524|    629|  return os;
 1525|    629|}
_ZNK5Exiv29ValueTypeIiE7toInt64Em:
 1535|  3.92k|int64_t ValueType<T>::toInt64(size_t n) const {
 1536|  3.92k|  ok_ = true;
 1537|  3.92k|  return static_cast<int64_t>(value_.at(n));
 1538|  3.92k|}
_ZNK5Exiv29ValueTypeIiE8toUint32Em:
 1540|  3.64k|uint32_t ValueType<T>::toUint32(size_t n) const {
 1541|  3.64k|  ok_ = true;
 1542|  3.64k|  return static_cast<uint32_t>(value_.at(n));
 1543|  3.64k|}
_ZNK5Exiv29ValueTypeIiE12sizeDataAreaEv:
 1639|    603|size_t ValueType<T>::sizeDataArea() const {
 1640|    603|  return pDataArea_.size();
 1641|    603|}
_ZNK5Exiv29ValueTypeIiE8dataAreaEv:
 1644|    127|DataBuf ValueType<T>::dataArea() const {
 1645|    127|  return {pDataArea_.data(), pDataArea_.size()};
 1646|    127|}
_ZNK5Exiv29ValueTypeIiE6clone_Ev:
 1511|  30.6k|ValueType<T>* ValueType<T>::clone_() const {
 1512|  30.6k|  return new ValueType<T>(*this);
 1513|  30.6k|}
_ZN5Exiv29ValueTypeIiEC2ERKS1_:
 1447|  30.6k|ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
 1448|  30.6k|  if (!rhs.pDataArea_.empty())
  ------------------
  |  Branch (1448:7): [True: 397, False: 30.2k]
  ------------------
 1449|    397|    pDataArea_ = rhs.pDataArea_;
 1450|  30.6k|}
_ZN5Exiv29ValueTypeINSt3__14pairIiiEEEC2Ev:
 1433|  1.93k|ValueType<T>::ValueType() : Value(getType<T>()) {
 1434|  1.93k|}
_ZN5Exiv29ValueTypeINSt3__14pairIiiEEE4readEPKhmNS_9ByteOrderE:
 1467|  1.93k|int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
 1468|  1.93k|  value_.clear();
 1469|  1.93k|  size_t ts = TypeInfo::typeSize(typeId());
 1470|  1.93k|  if (ts > 0 && len % ts != 0)
  ------------------
  |  Branch (1470:7): [True: 1.93k, False: 0]
  |  Branch (1470:17): [True: 0, False: 1.93k]
  ------------------
 1471|      0|    len = (len / ts) * ts;
 1472|  30.3k|  for (size_t i = 0; i < len; i += ts) {
  ------------------
  |  Branch (1472:22): [True: 28.4k, False: 1.93k]
  ------------------
 1473|  28.4k|    value_.push_back(getValue<T>(buf + i, byteOrder));
 1474|  28.4k|  }
 1475|  1.93k|  return 0;
 1476|  1.93k|}
_ZN5Exiv29ValueTypeINSt3__14pairIiiEEE11setDataAreaEPKhm:
 1649|    483|int ValueType<T>::setDataArea(const byte* buf, size_t len) {
 1650|    483|  if (len > 0)
  ------------------
  |  Branch (1650:7): [True: 156, False: 327]
  ------------------
 1651|    156|    pDataArea_ = Blob(buf, buf + len);
 1652|    327|  else
 1653|    327|    pDataArea_.clear();
 1654|    483|  return 0;
 1655|    483|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE4copyEPhNS_9ByteOrderE:
 1492|    614|size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
 1493|    614|  size_t offset = 0;
 1494|  22.0k|  for (const auto& val : value_) {
  ------------------
  |  Branch (1494:24): [True: 22.0k, False: 614]
  ------------------
 1495|  22.0k|    offset += toData(buf + offset, val, byteOrder);
 1496|  22.0k|  }
 1497|    614|  return offset;
 1498|    614|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE5countEv:
 1501|  11.9k|size_t ValueType<T>::count() const {
 1502|  11.9k|  return value_.size();
 1503|  11.9k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE4sizeEv:
 1506|  1.49k|size_t ValueType<T>::size() const {
 1507|  1.49k|  return TypeInfo::typeSize(typeId()) * value_.size();
 1508|  1.49k|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE5writeERNS1_13basic_ostreamIcNS1_11char_traitsIcEEEE:
 1516|    687|std::ostream& ValueType<T>::write(std::ostream& os) const {
 1517|    687|  auto end = value_.end();
 1518|    687|  auto i = value_.begin();
 1519|  10.1k|  while (i != end) {
  ------------------
  |  Branch (1519:10): [True: 9.44k, False: 687]
  ------------------
 1520|  9.44k|    os << std::setprecision(15) << *i;
 1521|  9.44k|    if (++i != end)
  ------------------
  |  Branch (1521:9): [True: 8.96k, False: 485]
  ------------------
 1522|  8.96k|      os << " ";
 1523|  9.44k|  }
 1524|    687|  return os;
 1525|    687|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE12sizeDataAreaEv:
 1639|    418|size_t ValueType<T>::sizeDataArea() const {
 1640|    418|  return pDataArea_.size();
 1641|    418|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE8dataAreaEv:
 1644|     15|DataBuf ValueType<T>::dataArea() const {
 1645|     15|  return {pDataArea_.data(), pDataArea_.size()};
 1646|     15|}
_ZNK5Exiv29ValueTypeINSt3__14pairIiiEEE6clone_Ev:
 1511|  6.04k|ValueType<T>* ValueType<T>::clone_() const {
 1512|  6.04k|  return new ValueType<T>(*this);
 1513|  6.04k|}
_ZN5Exiv29ValueTypeINSt3__14pairIiiEEEC2ERKS4_:
 1447|  6.04k|ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
 1448|  6.04k|  if (!rhs.pDataArea_.empty())
  ------------------
  |  Branch (1448:7): [True: 265, False: 5.78k]
  ------------------
 1449|    265|    pDataArea_ = rhs.pDataArea_;
 1450|  6.04k|}
_ZN5Exiv29ValueTypeIfEC2Ev:
 1433|  2.04k|ValueType<T>::ValueType() : Value(getType<T>()) {
 1434|  2.04k|}
_ZN5Exiv29ValueTypeIfE4readEPKhmNS_9ByteOrderE:
 1467|  2.04k|int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
 1468|  2.04k|  value_.clear();
 1469|  2.04k|  size_t ts = TypeInfo::typeSize(typeId());
 1470|  2.04k|  if (ts > 0 && len % ts != 0)
  ------------------
  |  Branch (1470:7): [True: 2.04k, False: 0]
  |  Branch (1470:17): [True: 0, False: 2.04k]
  ------------------
 1471|      0|    len = (len / ts) * ts;
 1472|  47.8k|  for (size_t i = 0; i < len; i += ts) {
  ------------------
  |  Branch (1472:22): [True: 45.8k, False: 2.04k]
  ------------------
 1473|  45.8k|    value_.push_back(getValue<T>(buf + i, byteOrder));
 1474|  45.8k|  }
 1475|  2.04k|  return 0;
 1476|  2.04k|}
_ZN5Exiv29ValueTypeIfE11setDataAreaEPKhm:
 1649|    679|int ValueType<T>::setDataArea(const byte* buf, size_t len) {
 1650|    679|  if (len > 0)
  ------------------
  |  Branch (1650:7): [True: 216, False: 463]
  ------------------
 1651|    216|    pDataArea_ = Blob(buf, buf + len);
 1652|    463|  else
 1653|    463|    pDataArea_.clear();
 1654|    679|  return 0;
 1655|    679|}
_ZNK5Exiv29ValueTypeIfE4copyEPhNS_9ByteOrderE:
 1492|    459|size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
 1493|    459|  size_t offset = 0;
 1494|  6.37k|  for (const auto& val : value_) {
  ------------------
  |  Branch (1494:24): [True: 6.37k, False: 459]
  ------------------
 1495|  6.37k|    offset += toData(buf + offset, val, byteOrder);
 1496|  6.37k|  }
 1497|    459|  return offset;
 1498|    459|}
_ZNK5Exiv29ValueTypeIfE5countEv:
 1501|  10.9k|size_t ValueType<T>::count() const {
 1502|  10.9k|  return value_.size();
 1503|  10.9k|}
_ZNK5Exiv29ValueTypeIfE4sizeEv:
 1506|  1.03k|size_t ValueType<T>::size() const {
 1507|  1.03k|  return TypeInfo::typeSize(typeId()) * value_.size();
 1508|  1.03k|}
_ZNK5Exiv29ValueTypeIfE5writeERNSt3__113basic_ostreamIcNS2_11char_traitsIcEEEE:
 1516|    541|std::ostream& ValueType<T>::write(std::ostream& os) const {
 1517|    541|  auto end = value_.end();
 1518|    541|  auto i = value_.begin();
 1519|  52.8k|  while (i != end) {
  ------------------
  |  Branch (1519:10): [True: 52.3k, False: 541]
  ------------------
 1520|  52.3k|    os << std::setprecision(15) << *i;
 1521|  52.3k|    if (++i != end)
  ------------------
  |  Branch (1521:9): [True: 52.0k, False: 329]
  ------------------
 1522|  52.0k|      os << " ";
 1523|  52.3k|  }
 1524|    541|  return os;
 1525|    541|}
_ZNK5Exiv29ValueTypeIfE12sizeDataAreaEv:
 1639|    352|size_t ValueType<T>::sizeDataArea() const {
 1640|    352|  return pDataArea_.size();
 1641|    352|}
_ZNK5Exiv29ValueTypeIfE8dataAreaEv:
 1644|     12|DataBuf ValueType<T>::dataArea() const {
 1645|     12|  return {pDataArea_.data(), pDataArea_.size()};
 1646|     12|}
_ZNK5Exiv29ValueTypeIfE6clone_Ev:
 1511|  5.58k|ValueType<T>* ValueType<T>::clone_() const {
 1512|  5.58k|  return new ValueType<T>(*this);
 1513|  5.58k|}
_ZN5Exiv29ValueTypeIfEC2ERKS1_:
 1447|  5.58k|ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
 1448|  5.58k|  if (!rhs.pDataArea_.empty())
  ------------------
  |  Branch (1448:7): [True: 294, False: 5.28k]
  ------------------
 1449|    294|    pDataArea_ = rhs.pDataArea_;
 1450|  5.58k|}
_ZN5Exiv29ValueTypeIdEC2Ev:
 1433|  5.26k|ValueType<T>::ValueType() : Value(getType<T>()) {
 1434|  5.26k|}
_ZN5Exiv29ValueTypeIdE4readEPKhmNS_9ByteOrderE:
 1467|  5.26k|int ValueType<T>::read(const byte* buf, size_t len, ByteOrder byteOrder) {
 1468|  5.26k|  value_.clear();
 1469|  5.26k|  size_t ts = TypeInfo::typeSize(typeId());
 1470|  5.26k|  if (ts > 0 && len % ts != 0)
  ------------------
  |  Branch (1470:7): [True: 5.26k, False: 0]
  |  Branch (1470:17): [True: 0, False: 5.26k]
  ------------------
 1471|      0|    len = (len / ts) * ts;
 1472|   347k|  for (size_t i = 0; i < len; i += ts) {
  ------------------
  |  Branch (1472:22): [True: 342k, False: 5.26k]
  ------------------
 1473|   342k|    value_.push_back(getValue<T>(buf + i, byteOrder));
 1474|   342k|  }
 1475|  5.26k|  return 0;
 1476|  5.26k|}
_ZN5Exiv29ValueTypeIdE11setDataAreaEPKhm:
 1649|    565|int ValueType<T>::setDataArea(const byte* buf, size_t len) {
 1650|    565|  if (len > 0)
  ------------------
  |  Branch (1650:7): [True: 161, False: 404]
  ------------------
 1651|    161|    pDataArea_ = Blob(buf, buf + len);
 1652|    404|  else
 1653|    404|    pDataArea_.clear();
 1654|    565|  return 0;
 1655|    565|}
_ZNK5Exiv29ValueTypeIdE4copyEPhNS_9ByteOrderE:
 1492|    695|size_t ValueType<T>::copy(byte* buf, ByteOrder byteOrder) const {
 1493|    695|  size_t offset = 0;
 1494|  48.2k|  for (const auto& val : value_) {
  ------------------
  |  Branch (1494:24): [True: 48.2k, False: 695]
  ------------------
 1495|  48.2k|    offset += toData(buf + offset, val, byteOrder);
 1496|  48.2k|  }
 1497|    695|  return offset;
 1498|    695|}
_ZNK5Exiv29ValueTypeIdE5countEv:
 1501|  12.2k|size_t ValueType<T>::count() const {
 1502|  12.2k|  return value_.size();
 1503|  12.2k|}
_ZNK5Exiv29ValueTypeIdE4sizeEv:
 1506|  1.48k|size_t ValueType<T>::size() const {
 1507|  1.48k|  return TypeInfo::typeSize(typeId()) * value_.size();
 1508|  1.48k|}
_ZNK5Exiv29ValueTypeIdE5writeERNSt3__113basic_ostreamIcNS2_11char_traitsIcEEEE:
 1516|    490|std::ostream& ValueType<T>::write(std::ostream& os) const {
 1517|    490|  auto end = value_.end();
 1518|    490|  auto i = value_.begin();
 1519|  1.33k|  while (i != end) {
  ------------------
  |  Branch (1519:10): [True: 847, False: 490]
  ------------------
 1520|    847|    os << std::setprecision(15) << *i;
 1521|    847|    if (++i != end)
  ------------------
  |  Branch (1521:9): [True: 560, False: 287]
  ------------------
 1522|    560|      os << " ";
 1523|    847|  }
 1524|    490|  return os;
 1525|    490|}
_ZNK5Exiv29ValueTypeIdE12sizeDataAreaEv:
 1639|    287|size_t ValueType<T>::sizeDataArea() const {
 1640|    287|  return pDataArea_.size();
 1641|    287|}
_ZNK5Exiv29ValueTypeIdE8dataAreaEv:
 1644|     11|DataBuf ValueType<T>::dataArea() const {
 1645|     11|  return {pDataArea_.data(), pDataArea_.size()};
 1646|     11|}
_ZNK5Exiv29ValueTypeIdE6clone_Ev:
 1511|  12.4k|ValueType<T>* ValueType<T>::clone_() const {
 1512|  12.4k|  return new ValueType<T>(*this);
 1513|  12.4k|}
_ZN5Exiv29ValueTypeIdEC2ERKS1_:
 1447|  12.4k|ValueType<T>::ValueType(const ValueType<T>& rhs) : Value(rhs.typeId()), value_(rhs.value_) {
 1448|  12.4k|  if (!rhs.pDataArea_.empty())
  ------------------
  |  Branch (1448:7): [True: 139, False: 12.2k]
  ------------------
 1449|    139|    pDataArea_ = rhs.pDataArea_;
 1450|  12.4k|}
_ZZNK5Exiv222LangAltValueComparatorclERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_ENKUlhhE_clEhh:
  799|  10.9k|    auto f = [](unsigned char a, unsigned char b) { return std::tolower(a) > std::tolower(b); };
_ZN5Exiv29ValueTypeIjEC2Ev:
 1433|  2.55k|ValueType<T>::ValueType() : Value(getType<T>()) {
 1434|  2.55k|}

_ZNK5Exiv27XmpData9usePacketEv:
  215|  4.40k|  [[nodiscard]] bool usePacket() const {
  216|  4.40k|    return usePacket_;
  217|  4.40k|  }
_ZN5Exiv27XmpData9usePacketEb:
  220|  11.4k|  bool usePacket(bool b) {
  221|  11.4k|    bool r = usePacket_;
  222|  11.4k|    usePacket_ = b;
  223|  11.4k|    return r;
  224|  11.4k|  }
_ZN5Exiv27XmpData9setPacketENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  226|  11.4k|  void setPacket(std::string xmpPacket) {
  227|  11.4k|    xmpPacket_ = std::move(xmpPacket);
  228|  11.4k|    usePacket(false);
  229|  11.4k|  }
_ZN5Exiv27XmpDataC2Ev:
  139|  36.8k|  XmpData() = default;
_ZN5Exiv28XmpdatumaSINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEERS0_RKT_:
  366|  35.0k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|  35.0k|    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|       |    setValue(Exiv2::toString(value));
  375|  35.0k|  return *this;
  376|  35.0k|}
_ZN5Exiv28XmpdatumaSIdEERS0_RKT_:
  366|   116k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|   116k|    setValue(Exiv2::toString(value));
  375|   116k|  return *this;
  376|   116k|}
_ZN5Exiv28XmpdatumaSImEERS0_RKT_:
  366|  12.0k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|  12.0k|    setValue(Exiv2::toString(value));
  375|  12.0k|  return *this;
  376|  12.0k|}
_ZN5Exiv28XmpdatumaSIjEERS0_RKT_:
  366|  24.1k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|  24.1k|    setValue(Exiv2::toString(value));
  375|  24.1k|  return *this;
  376|  24.1k|}
_ZN5Exiv28XmpdatumaSIPKhEERS0_RKT_:
  366|  1.63k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|  1.63k|    setValue(Exiv2::toString(value));
  375|  1.63k|  return *this;
  376|  1.63k|}
_ZN5Exiv28XmpdatumaSIA4_cEERS0_RKT_:
  366|  3.04k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|  3.04k|    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|       |    setValue(Exiv2::toString(value));
  375|  3.04k|  return *this;
  376|  3.04k|}
_ZN5Exiv28XmpdatumaSIlEERS0_RKT_:
  366|    710|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|    710|    setValue(Exiv2::toString(value));
  375|    710|  return *this;
  376|    710|}
_ZN5Exiv28XmpdatumaSIfEERS0_RKT_:
  366|  1.60k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|  1.60k|    setValue(Exiv2::toString(value));
  375|  1.60k|  return *this;
  376|  1.60k|}
_ZN5Exiv28XmpdatumaSIA18_cEERS0_RKT_:
  366|    228|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|    228|    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|       |    setValue(Exiv2::toString(value));
  375|    228|  return *this;
  376|    228|}
_ZN5Exiv28XmpdatumaSItEERS0_RKT_:
  366|  67.4k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|  67.4k|    setValue(Exiv2::toString(value));
  375|  67.4k|  return *this;
  376|  67.4k|}
_ZN5Exiv28XmpdatumaSIsEERS0_RKT_:
  366|  5.76k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|  5.76k|    setValue(Exiv2::toString(value));
  375|  5.76k|  return *this;
  376|  5.76k|}
_ZN5Exiv28XmpdatumaSIPhEERS0_RKT_:
  366|   142k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|   142k|    setValue(Exiv2::toString(value));
  375|   142k|  return *this;
  376|   142k|}
_ZN5Exiv28XmpdatumaSIPKcEERS0_RKT_:
  366|  84.0k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|  84.0k|    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|       |    setValue(Exiv2::toString(value));
  375|  84.0k|  return *this;
  376|  84.0k|}
_ZN5Exiv28XmpdatumaSIiEERS0_RKT_:
  366|   164k|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|       |    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|   164k|    setValue(Exiv2::toString(value));
  375|   164k|  return *this;
  376|   164k|}
_ZN5Exiv28XmpdatumaSIA12_cEERS0_RKT_:
  366|    240|Xmpdatum& Xmpdatum::operator=(const T& value) {
  367|       |  if constexpr (std::is_same_v<T, bool>)
  368|       |    setValue(value ? "True" : "False");
  369|       |  else if constexpr (std::is_convertible_v<T, std::string>)
  370|    240|    setValue(value);
  371|       |  else if constexpr (std::is_base_of_v<Value, T>)
  372|       |    setValue(&value);
  373|       |  else
  374|       |    setValue(Exiv2::toString(value));
  375|    240|  return *this;
  376|    240|}

_ZNK5Exiv28AsfVideo7GUIDTageqERKS1_:
   42|  9.04k|bool AsfVideo::GUIDTag::operator==(const AsfVideo::GUIDTag& other) const {
   43|  9.04k|  return data1_ == other.data1_ && data2_ == other.data2_ && data3_ == other.data3_ && data4_ == other.data4_;
  ------------------
  |  Branch (43:10): [True: 1.21k, False: 7.83k]
  |  Branch (43:36): [True: 1.18k, False: 25]
  |  Branch (43:62): [True: 1.17k, False: 17]
  |  Branch (43:88): [True: 1.16k, False: 10]
  ------------------
   44|  9.04k|}
_ZN5Exiv28AsfVideo7GUIDTagC2EPKh:
   46|  9.76k|AsfVideo::GUIDTag::GUIDTag(const uint8_t* bytes) {
   47|  9.76k|  data1_ = Exiv2::getULong(bytes, ByteOrder::littleEndian);
   48|  9.76k|  data2_ = Exiv2::getUShort(bytes + DWORD, ByteOrder::littleEndian);
   49|  9.76k|  data3_ = Exiv2::getUShort(bytes + DWORD + WORD, ByteOrder::littleEndian);
   50|  9.76k|  std::copy(bytes + QWORD, bytes + (2 * QWORD), data4_.begin());
   51|  9.76k|}
_ZNK5Exiv28AsfVideo7GUIDTagltERKS1_:
   61|  5.68k|bool AsfVideo::GUIDTag::operator<(const GUIDTag& other) const {
   62|  5.68k|  if (data1_ != other.data1_)
  ------------------
  |  Branch (62:7): [True: 4.43k, False: 1.25k]
  ------------------
   63|  4.43k|    return data1_ < other.data1_;
   64|  1.25k|  if (data2_ != other.data2_)
  ------------------
  |  Branch (64:7): [True: 39, False: 1.21k]
  ------------------
   65|     39|    return data2_ < other.data2_;
   66|  1.21k|  if (data3_ != other.data3_)
  ------------------
  |  Branch (66:7): [True: 26, False: 1.18k]
  ------------------
   67|     26|    return data3_ < other.data3_;
   68|  1.18k|  return std::lexicographical_compare(data4_.begin(), data4_.end(), other.data4_.begin(), other.data4_.end());
   69|  1.21k|}
_ZN5Exiv28AsfVideoC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
  182|    387|AsfVideo::AsfVideo(BasicIo::UniquePtr io) : Image(ImageType::asf, mdNone, std::move(io)) {
  183|    387|}  // AsfVideo::AsfVideo
_ZNK5Exiv28AsfVideo8mimeTypeEv:
  185|    393|std::string AsfVideo::mimeType() const {
  186|    393|  return "video/asf";
  187|    393|}
_ZN5Exiv28AsfVideo12readMetadataEv:
  192|    387|void AsfVideo::readMetadata() {
  193|    387|  if (io_->open() != 0)
  ------------------
  |  Branch (193:7): [True: 0, False: 387]
  ------------------
  194|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  195|       |
  196|       |  // Ensure that this is the correct image type
  197|    387|  if (!isAsfType(*io_, false)) {
  ------------------
  |  Branch (197:7): [True: 0, False: 387]
  ------------------
  198|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (198:9): [True: 0, False: 0]
  |  Branch (198:25): [True: 0, False: 0]
  ------------------
  199|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  200|      0|    throw Error(ErrorCode::kerNotAnImage, "ASF");
  201|      0|  }
  202|       |
  203|    387|  IoCloser closer(*io_);
  204|    387|  clearMetadata();
  205|    387|  io_->seek(0, BasicIo::beg);
  206|    387|  height_ = width_ = 1;
  207|       |
  208|    387|  xmpData()["Xmp.video.FileSize"] = io_->size() / 1048576.;
  209|    387|  xmpData()["Xmp.video.MimeType"] = mimeType();
  210|       |
  211|    387|  decodeBlock();
  212|       |
  213|    387|  xmpData_["Xmp.video.AspectRatio"] = getAspectRatio(width_, height_);
  214|    387|}  // AsfVideo::readMetadata
_ZN5Exiv28AsfVideo12HeaderReaderC2ERKNSt3__110unique_ptrINS_7BasicIoENS2_14default_deleteIS4_EEEE:
  216|    901|AsfVideo::HeaderReader::HeaderReader(const BasicIo::UniquePtr& io) : IdBuf_(GUID) {
  217|    901|  if (io->size() >= io->tell() + GUID + QWORD) {
  ------------------
  |  Branch (217:7): [True: 901, False: 0]
  ------------------
  218|    901|    io->readOrThrow(IdBuf_.data(), IdBuf_.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  219|       |
  220|    901|    size_ = readQWORDTag(io);
  221|    901|    if (size_ >= GUID + QWORD)
  ------------------
  |  Branch (221:9): [True: 307, False: 594]
  ------------------
  222|    307|      remaining_size_ = size_ - GUID - QWORD;
  223|    901|  }
  224|    901|}
_ZN5Exiv28AsfVideo11decodeBlockEv:
  226|    932|void AsfVideo::decodeBlock() {
  227|    932|  Internal::enforce(GUID + QWORD <= io_->size() - io_->tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
  228|    932|  HeaderReader objectHeader(io_);
  229|       |#ifdef EXIV2_DEBUG_MESSAGES
  230|       |  EXV_INFO << "decodeBlock = " << GUIDTag(objectHeader.getId().data()).to_string()
  231|       |           << "\tsize= " << objectHeader.getSize() << "\t " << io_->tell() << "/" << io_->size() << '\n';
  232|       |#endif
  233|    932|  Internal::enforce(objectHeader.getSize() <= io_->size() - io_->tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
  234|    932|  auto tag = GUIDReferenceTags.find(GUIDTag(objectHeader.getId().data()));
  235|       |
  236|    932|  if (tag != GUIDReferenceTags.end()) {
  ------------------
  |  Branch (236:7): [True: 575, False: 357]
  ------------------
  237|    575|    if (tag->second == "Header")
  ------------------
  |  Branch (237:9): [True: 375, False: 200]
  ------------------
  238|    375|      decodeHeader();
  239|    200|    else if (tag->second == "File_Properties")
  ------------------
  |  Branch (239:14): [True: 0, False: 200]
  ------------------
  240|      0|      fileProperties();
  241|    200|    else if (tag->second == "Stream_Properties")
  ------------------
  |  Branch (241:14): [True: 0, False: 200]
  ------------------
  242|      0|      streamProperties();
  243|    200|    else if (tag->second == "Header_Extension")
  ------------------
  |  Branch (243:14): [True: 0, False: 200]
  ------------------
  244|      0|      headerExtension();
  245|    200|    else if (tag->second == "Codec_List")
  ------------------
  |  Branch (245:14): [True: 0, False: 200]
  ------------------
  246|      0|      codecList();
  247|    200|    else if (tag->second == "Extended_Content_Description")
  ------------------
  |  Branch (247:14): [True: 0, False: 200]
  ------------------
  248|      0|      extendedContentDescription();
  249|    200|    else if (tag->second == "Content_Description")
  ------------------
  |  Branch (249:14): [True: 184, False: 16]
  ------------------
  250|    184|      contentDescription();
  251|     16|    else if (tag->second == "Extended_Stream_Properties")
  ------------------
  |  Branch (251:14): [True: 0, False: 16]
  ------------------
  252|      0|      extendedStreamProperties();
  253|     16|    else if (tag->second == "Degradable_JPEG_Media")
  ------------------
  |  Branch (253:14): [True: 0, False: 16]
  ------------------
  254|      0|      DegradableJPEGMedia();
  255|     16|    else {  // tag found but not processed
  256|       |      // Make sure that the remaining size is non-zero, so that we won't
  257|       |      // keep revisiting the same location in the file.
  258|     16|      const uint64_t remaining_size = objectHeader.getRemainingSize();
  259|     16|      Internal::enforce(remaining_size > 0, Exiv2::ErrorCode::kerCorruptedMetadata);
  260|     16|      io_->seekOrThrow(io_->tell() + remaining_size, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  261|     16|    }
  262|    575|  } else {  // tag not found
  263|       |    // Make sure that the remaining size is non-zero, so that we won't keep
  264|       |    // revisiting the same location in the file.
  265|    357|    const uint64_t remaining_size = objectHeader.getRemainingSize();
  266|    357|    Internal::enforce(remaining_size > 0, Exiv2::ErrorCode::kerCorruptedMetadata);
  267|    357|    io_->seekOrThrow(io_->tell() + remaining_size, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  268|    357|  }
  269|       |
  270|    932|}  // AsfVideo::decodeBlock
_ZN5Exiv28AsfVideo12decodeHeaderEv:
  272|    375|void AsfVideo::decodeHeader() {
  273|    375|  DataBuf nbHeadersBuf(DWORD + 1);
  274|    375|  io_->readOrThrow(nbHeadersBuf.data(), DWORD, Exiv2::ErrorCode::kerCorruptedMetadata);
  275|       |
  276|    375|  uint32_t nb_headers = Exiv2::getULong(nbHeadersBuf.data(), littleEndian);
  277|    375|  Internal::enforce(nb_headers < std::numeric_limits<uint32_t>::max(), Exiv2::ErrorCode::kerCorruptedMetadata);
  278|    375|  io_->seekOrThrow(io_->tell() + (BYTE * 2), BasicIo::beg,
  279|    375|                   ErrorCode::kerFailedToReadImageData);  // skip two reserved tags
  280|    920|  for (uint32_t i = 0; i < nb_headers; i++) {
  ------------------
  |  Branch (280:24): [True: 545, False: 375]
  ------------------
  281|    545|    decodeBlock();
  282|    545|  }
  283|    375|}
_ZN5Exiv28AsfVideo18contentDescriptionEv:
  430|    184|void AsfVideo::contentDescription() {
  431|    184|  uint16_t title_length = readWORDTag(io_);
  432|    184|  uint16_t author_length = readWORDTag(io_);
  433|    184|  uint16_t copyright_length = readWORDTag(io_);
  434|    184|  uint16_t desc_length = readWORDTag(io_);
  435|    184|  uint16_t rating_length = readWORDTag(io_);
  436|       |
  437|    184|  if (title_length)
  ------------------
  |  Branch (437:7): [True: 84, False: 100]
  ------------------
  438|     84|    xmpData()["Xmp.video.Title"] = readStringWcharTag(io_, title_length);
  439|       |
  440|    184|  if (author_length)
  ------------------
  |  Branch (440:7): [True: 79, False: 105]
  ------------------
  441|     79|    xmpData()["Xmp.video.Author"] = readStringWcharTag(io_, author_length);
  442|       |
  443|    184|  if (copyright_length)
  ------------------
  |  Branch (443:7): [True: 80, False: 104]
  ------------------
  444|     80|    xmpData()["Xmp.video.Copyright"] = readStringWcharTag(io_, copyright_length);
  445|       |
  446|    184|  if (desc_length)
  ------------------
  |  Branch (446:7): [True: 66, False: 118]
  ------------------
  447|     66|    xmpData()["Xmp.video.Description"] = readStringWcharTag(io_, desc_length);
  448|       |
  449|    184|  if (rating_length)
  ------------------
  |  Branch (449:7): [True: 107, False: 77]
  ------------------
  450|    107|    xmpData()["Xmp.video.Rating"] = readStringWcharTag(io_, rating_length);
  451|       |
  452|    184|}  // AsfVideo::extendedContentDescription
_ZN5Exiv214newAsfInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  470|    387|Image::UniquePtr newAsfInstance(BasicIo::UniquePtr io, bool /*create*/) {
  471|    387|  auto image = std::make_unique<AsfVideo>(std::move(io));
  472|    387|  if (!image->good()) {
  ------------------
  |  Branch (472:7): [True: 0, False: 387]
  ------------------
  473|      0|    return nullptr;
  474|      0|  }
  475|    387|  return image;
  476|    387|}
_ZN5Exiv29isAsfTypeERNS_7BasicIoEb:
  478|  9.36k|bool isAsfType(BasicIo& iIo, bool advance) {
  479|  9.36k|  byte buf[GUID];
  480|  9.36k|  iIo.read(buf, GUID);
  481|       |
  482|  9.36k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (482:7): [True: 0, False: 9.36k]
  |  Branch (482:22): [True: 320, False: 9.04k]
  ------------------
  483|    320|    return false;
  484|    320|  }
  485|       |
  486|  9.04k|  bool matched = isASFType(buf);
  487|  9.04k|  if (!advance || !matched) {
  ------------------
  |  Branch (487:7): [True: 9.04k, False: 0]
  |  Branch (487:19): [True: 0, False: 0]
  ------------------
  488|  9.04k|    iIo.seek(0, BasicIo::beg);
  489|  9.04k|  }
  490|       |
  491|  9.04k|  return matched;
  492|  9.36k|}
asfvideo.cpp:_ZN5Exiv2L9isASFTypeEPKh:
  178|  9.04k|static bool isASFType(const byte buf[]) {
  179|  9.04k|  return Header == AsfVideo::GUIDTag(buf);
  180|  9.04k|}

_ZN5Exiv27BasicIoD2Ev:
   53|  41.6k|BasicIo::~BasicIo() = default;
_ZN5Exiv27BasicIo11readOrThrowEPhmNS_9ErrorCodeE:
   55|  12.4M|void BasicIo::readOrThrow(byte* buf, size_t rcount, ErrorCode err) {
   56|  12.4M|  const size_t nread = read(buf, rcount);
   57|  12.4M|  Internal::enforce(nread == rcount, err);
   58|  12.4M|  Internal::enforce(!error(), err);
   59|  12.4M|}
_ZN5Exiv27BasicIo11seekOrThrowElNS0_8PositionENS_9ErrorCodeE:
   61|  14.4k|void BasicIo::seekOrThrow(int64_t offset, Position pos, ErrorCode err) {
   62|  14.4k|  const int r = seek(offset, pos);
   63|  14.4k|  Internal::enforce(r == 0, err);
   64|  14.4k|}
_ZN5Exiv25MemIo4ImplC2EPKhm:
  617|  32.8k|MemIo::Impl::Impl(const byte* data, size_t size) : data_(const_cast<byte*>(data)), size_(size) {
  618|  32.8k|}
_ZN5Exiv25MemIo4Impl7reserveEm:
  671|   331k|void MemIo::Impl::reserve(size_t wcount) {
  672|   331k|  const size_t need = wcount + idx_;
  673|   331k|  size_t blockSize = 32 * 1024;  // 32768
  674|   331k|  const size_t maxBlockSize = 4 * 1024 * 1024;
  675|       |
  676|   331k|  if (!isMalloced_) {
  ------------------
  |  Branch (676:7): [True: 4.40k, False: 327k]
  ------------------
  677|       |    // Minimum size for 1st block
  678|  4.40k|    auto size = std::max<size_t>(blockSize * (1 + need / blockSize), size_);
  679|  4.40k|    auto data = static_cast<byte*>(std::malloc(size));
  680|  4.40k|    if (!data) {
  ------------------
  |  Branch (680:9): [True: 0, False: 4.40k]
  ------------------
  681|      0|      throw Error(ErrorCode::kerMallocFailed);
  682|      0|    }
  683|  4.40k|    if (data_) {
  ------------------
  |  Branch (683:9): [True: 0, False: 4.40k]
  ------------------
  684|      0|      std::memcpy(data, data_, size_);
  685|      0|    }
  686|  4.40k|    data_ = data;
  687|  4.40k|    sizeAlloced_ = size;
  688|  4.40k|    isMalloced_ = true;
  689|  4.40k|  }
  690|       |
  691|   331k|  if (need > size_) {
  ------------------
  |  Branch (691:7): [True: 317k, False: 14.8k]
  ------------------
  692|   317k|    if (need > sizeAlloced_) {
  ------------------
  |  Branch (692:9): [True: 115, False: 316k]
  ------------------
  693|    115|      blockSize = std::min(2 * sizeAlloced_, maxBlockSize);
  694|       |      // Allocate in blocks
  695|    115|      size_t want = blockSize * (1 + need / blockSize);
  696|    115|      data_ = static_cast<byte*>(std::realloc(data_, want));
  697|    115|      if (!data_) {
  ------------------
  |  Branch (697:11): [True: 0, False: 115]
  ------------------
  698|      0|        throw Error(ErrorCode::kerMallocFailed);
  699|      0|      }
  700|    115|      sizeAlloced_ = want;
  701|    115|    }
  702|   317k|    size_ = need;
  703|   317k|  }
  704|   331k|}
_ZN5Exiv25MemIoC2Ev:
  706|  8.80k|MemIo::MemIo() : p_(std::make_unique<Impl>()) {
  707|  8.80k|}
_ZN5Exiv25MemIoC2EPKhm:
  709|  32.8k|MemIo::MemIo(const byte* data, size_t size) : p_(std::make_unique<Impl>(data, size)) {
  710|  32.8k|}
_ZN5Exiv25MemIoD2Ev:
  712|  41.6k|MemIo::~MemIo() {
  713|  41.6k|  if (p_->isMalloced_) {
  ------------------
  |  Branch (713:7): [True: 4.40k, False: 37.2k]
  ------------------
  714|  4.40k|    std::free(p_->data_);
  715|  4.40k|  }
  716|  41.6k|}
_ZN5Exiv25MemIo5writeEPKhm:
  718|   329k|size_t MemIo::write(const byte* data, size_t wcount) {
  719|   329k|  p_->reserve(wcount);
  720|   329k|  if (data) {
  ------------------
  |  Branch (720:7): [True: 314k, False: 14.8k]
  ------------------
  721|   314k|    std::memcpy(&p_->data_[p_->idx_], data, wcount);
  722|   314k|  }
  723|   329k|  p_->idx_ += wcount;
  724|   329k|  return wcount;
  725|   329k|}
_ZN5Exiv25MemIo8transferERNS_7BasicIoE:
  727|  4.30k|void MemIo::transfer(BasicIo& src) {
  728|  4.30k|  if (auto memIo = dynamic_cast<MemIo*>(&src)) {
  ------------------
  |  Branch (728:12): [True: 4.30k, False: 0]
  ------------------
  729|       |    // Optimization if src is another instance of MemIo
  730|  4.30k|    if (p_->isMalloced_) {
  ------------------
  |  Branch (730:9): [True: 0, False: 4.30k]
  ------------------
  731|      0|      std::free(p_->data_);
  732|      0|    }
  733|  4.30k|    p_->idx_ = 0;
  734|  4.30k|    p_->data_ = memIo->p_->data_;
  735|  4.30k|    p_->size_ = memIo->p_->size_;
  736|  4.30k|    p_->isMalloced_ = memIo->p_->isMalloced_;
  737|  4.30k|    memIo->p_->idx_ = 0;
  738|  4.30k|    memIo->p_->data_ = nullptr;
  739|  4.30k|    memIo->p_->size_ = 0;
  740|  4.30k|    memIo->p_->isMalloced_ = false;
  741|  4.30k|  } else {
  742|       |    // Generic reopen to reset position to start
  743|      0|    if (src.open() != 0) {
  ------------------
  |  Branch (743:9): [True: 0, False: 0]
  ------------------
  744|      0|      throw Error(ErrorCode::kerDataSourceOpenFailed, src.path(), strError());
  745|      0|    }
  746|      0|    p_->idx_ = 0;
  747|      0|    write(src);
  748|      0|    src.close();
  749|      0|  }
  750|  4.30k|  if (error() || src.error())
  ------------------
  |  Branch (750:7): [True: 0, False: 4.30k]
  |  Branch (750:18): [True: 0, False: 4.30k]
  ------------------
  751|      0|    throw Error(ErrorCode::kerMemoryTransferFailed, strError());
  752|  4.30k|}
_ZN5Exiv25MemIo4putbEh:
  772|  2.19k|int MemIo::putb(byte data) {
  773|  2.19k|  p_->reserve(1);
  774|  2.19k|  p_->data_[p_->idx_++] = data;
  775|  2.19k|  return data;
  776|  2.19k|}
_ZN5Exiv25MemIo4seekElNS_7BasicIo8PositionE:
  778|  1.24M|int MemIo::seek(int64_t offset, Position pos) {
  779|  1.24M|  int64_t newIdx = 0;
  780|       |
  781|  1.24M|  switch (pos) {
  ------------------
  |  Branch (781:11): [True: 1.24M, False: 0]
  ------------------
  782|   623k|    case BasicIo::cur:
  ------------------
  |  Branch (782:5): [True: 623k, False: 619k]
  ------------------
  783|   623k|      newIdx = p_->idx_ + offset;
  784|   623k|      break;
  785|   619k|    case BasicIo::beg:
  ------------------
  |  Branch (785:5): [True: 619k, False: 623k]
  ------------------
  786|   619k|      newIdx = offset;
  787|   619k|      break;
  788|    171|    case BasicIo::end:
  ------------------
  |  Branch (788:5): [True: 171, False: 1.24M]
  ------------------
  789|    171|      newIdx = p_->size_ + offset;
  790|    171|      break;
  791|  1.24M|  }
  792|       |
  793|  1.24M|  if (newIdx < 0)
  ------------------
  |  Branch (793:7): [True: 0, False: 1.24M]
  ------------------
  794|      0|    return 1;
  795|       |
  796|  1.24M|  if (newIdx > static_cast<int64_t>(p_->size_)) {
  ------------------
  |  Branch (796:7): [True: 11.8k, False: 1.23M]
  ------------------
  797|  11.8k|    p_->eof_ = true;
  798|  11.8k|    return 1;
  799|  11.8k|  }
  800|       |
  801|  1.23M|  p_->idx_ = static_cast<size_t>(newIdx);
  802|  1.23M|  p_->eof_ = false;
  803|  1.23M|  return 0;
  804|  1.24M|}
_ZN5Exiv25MemIo4mmapEb:
  806|  32.6k|byte* MemIo::mmap(bool /*isWriteable*/) {
  807|  32.6k|  return p_->data_;
  808|  32.6k|}
_ZNK5Exiv25MemIo4tellEv:
  814|  1.17M|size_t MemIo::tell() const {
  815|  1.17M|  return p_->idx_;
  816|  1.17M|}
_ZNK5Exiv25MemIo4sizeEv:
  818|   589k|size_t MemIo::size() const {
  819|   589k|  return p_->size_;
  820|   589k|}
_ZN5Exiv25MemIo4openEv:
  822|   112k|int MemIo::open() {
  823|   112k|  p_->idx_ = 0;
  824|   112k|  p_->eof_ = false;
  825|   112k|  return 0;
  826|   112k|}
_ZNK5Exiv25MemIo6isopenEv:
  828|  79.5k|bool MemIo::isopen() const {
  829|  79.5k|  return true;
  830|  79.5k|}
_ZN5Exiv25MemIo5closeEv:
  832|  79.5k|int MemIo::close() {
  833|  79.5k|  return 0;
  834|  79.5k|}
_ZN5Exiv25MemIo4readEm:
  836|  59.8k|DataBuf MemIo::read(size_t rcount) {
  837|  59.8k|  DataBuf buf(rcount);
  838|  59.8k|  size_t readCount = read(buf.data(), buf.size());
  839|  59.8k|  buf.resize(readCount);
  840|  59.8k|  return buf;
  841|  59.8k|}
_ZN5Exiv25MemIo4readEPhm:
  843|  14.0M|size_t MemIo::read(byte* buf, size_t rcount) {
  844|  14.0M|  const auto avail = std::max<size_t>(p_->size_ - p_->idx_, 0);
  845|  14.0M|  const auto allow = std::min<size_t>(rcount, avail);
  846|  14.0M|  if (allow > 0) {
  ------------------
  |  Branch (846:7): [True: 13.8M, False: 175k]
  ------------------
  847|  13.8M|    std::memcpy(buf, &p_->data_[p_->idx_], allow);
  848|  13.8M|  }
  849|  14.0M|  p_->idx_ += allow;
  850|  14.0M|  if (rcount > avail) {
  ------------------
  |  Branch (850:7): [True: 13.6k, False: 14.0M]
  ------------------
  851|  13.6k|    p_->eof_ = true;
  852|  13.6k|  }
  853|  14.0M|  return allow;
  854|  14.0M|}
_ZN5Exiv25MemIo4getbEv:
  856|   365k|int MemIo::getb() {
  857|   365k|  if (p_->idx_ >= p_->size_) {
  ------------------
  |  Branch (857:7): [True: 576, False: 365k]
  ------------------
  858|    576|    p_->eof_ = true;
  859|    576|    return EOF;
  860|    576|  }
  861|   365k|  return p_->data_[p_->idx_++];
  862|   365k|}
_ZNK5Exiv25MemIo5errorEv:
  864|  13.1M|int MemIo::error() const {
  865|  13.1M|  return 0;
  866|  13.1M|}
_ZNK5Exiv25MemIo3eofEv:
  868|  8.28M|bool MemIo::eof() const {
  869|  8.28M|  return p_->eof_;
  870|  8.28M|}
_ZNK5Exiv25MemIo4pathEv:
  872|  14.5k|const std::string& MemIo::path() const noexcept {
  873|  14.5k|  static std::string _path{"MemIo"};
  874|  14.5k|  return _path;
  875|  14.5k|}
_ZN5Exiv25MemIo4ImplC2Ev:
  597|  8.80k|  Impl() = default;                     //!< Default constructor

_ZN5Exiv29BmffImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEbm:
   87|  3.47k|    Image(ImageType::bmff, mdExif | mdIptc | mdXmp, std::move(io)), max_box_depth_(max_box_depth) {
   88|  3.47k|}  // BmffImage::BmffImage
_ZN5Exiv29BmffImage7fullBoxEj:
  109|  56.4k|bool BmffImage::fullBox(uint32_t box) {
  110|  56.4k|  return box == TAG::meta || box == TAG::iinf || box == TAG::iloc || box == TAG::thmb || box == TAG::prvw;
  ------------------
  |  Branch (110:10): [True: 5.69k, False: 50.7k]
  |  Branch (110:30): [True: 334, False: 50.3k]
  |  Branch (110:50): [True: 1.45k, False: 48.9k]
  |  Branch (110:70): [True: 2.66k, False: 46.2k]
  |  Branch (110:90): [True: 500, False: 45.7k]
  ------------------
  111|  56.4k|}
_ZNK5Exiv29BmffImage8mimeTypeEv:
  120|  5.76k|std::string BmffImage::mimeType() const {
  121|  5.76k|  switch (fileType_) {
  122|      5|    case TAG::avci:
  ------------------
  |  Branch (122:5): [True: 5, False: 5.76k]
  ------------------
  123|      5|      return "image/avci";
  124|      4|    case TAG::avcs:
  ------------------
  |  Branch (124:5): [True: 4, False: 5.76k]
  ------------------
  125|      4|      return "image/avcs";
  126|      4|    case TAG::avif:
  ------------------
  |  Branch (126:5): [True: 4, False: 5.76k]
  ------------------
  127|     14|    case TAG::avio:
  ------------------
  |  Branch (127:5): [True: 10, False: 5.75k]
  ------------------
  128|     21|    case TAG::avis:
  ------------------
  |  Branch (128:5): [True: 7, False: 5.76k]
  ------------------
  129|     21|      return "image/avif";
  130|      3|    case TAG::heic:
  ------------------
  |  Branch (130:5): [True: 3, False: 5.76k]
  ------------------
  131|      6|    case TAG::heim:
  ------------------
  |  Branch (131:5): [True: 3, False: 5.76k]
  ------------------
  132|      9|    case TAG::heis:
  ------------------
  |  Branch (132:5): [True: 3, False: 5.76k]
  ------------------
  133|     12|    case TAG::heix:
  ------------------
  |  Branch (133:5): [True: 3, False: 5.76k]
  ------------------
  134|     12|      return "image/heic";
  135|      3|    case TAG::heif:
  ------------------
  |  Branch (135:5): [True: 3, False: 5.76k]
  ------------------
  136|      6|    case TAG::mif1:
  ------------------
  |  Branch (136:5): [True: 3, False: 5.76k]
  ------------------
  137|      6|      return "image/heif";
  138|      3|    case TAG::j2is:
  ------------------
  |  Branch (138:5): [True: 3, False: 5.76k]
  ------------------
  139|      3|      return "image/j2is";
  140|      3|    case TAG::j2ki:
  ------------------
  |  Branch (140:5): [True: 3, False: 5.76k]
  ------------------
  141|      3|      return "image/hej2k";
  142|      0|    case TAG::crx:
  ------------------
  |  Branch (142:5): [True: 0, False: 5.76k]
  ------------------
  143|      0|      return "image/x-canon-cr3";
  144|      3|    case TAG::jxl:
  ------------------
  |  Branch (144:5): [True: 3, False: 5.76k]
  ------------------
  145|      3|      return "image/jxl";  // https://github.com/novomesk/qt-jpegxl-image-plugin/issues/1
  146|  5.71k|    default:
  ------------------
  |  Branch (146:5): [True: 5.71k, False: 57]
  ------------------
  147|  5.71k|      return "image/generic";
  148|  5.76k|  }
  149|  5.76k|}
_ZNK5Exiv29BmffImage10pixelWidthEv:
  151|    176|uint32_t BmffImage::pixelWidth() const {
  152|    176|  auto imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
  153|    176|  if (imageWidth == exifData_.end() || imageWidth->count() == 0)
  ------------------
  |  Branch (153:7): [True: 176, False: 0]
  |  Branch (153:7): [True: 176, False: 0]
  |  Branch (153:40): [True: 0, False: 0]
  ------------------
  154|    176|    return pixelWidth_;
  155|      0|  return imageWidth->toUint32();
  156|    176|}
_ZNK5Exiv29BmffImage11pixelHeightEv:
  158|    176|uint32_t BmffImage::pixelHeight() const {
  159|    176|  auto imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
  160|    176|  if (imageHeight == exifData_.end() || imageHeight->count() == 0)
  ------------------
  |  Branch (160:7): [True: 176, False: 0]
  |  Branch (160:7): [True: 176, False: 0]
  |  Branch (160:41): [True: 0, False: 0]
  ------------------
  161|    176|    return pixelHeight_;
  162|      0|  return imageHeight->toUint32();
  163|    176|}
_ZN5Exiv29BmffImage8uuidNameERKNS_7DataBufE:
  165|    793|std::string BmffImage::uuidName(const Exiv2::DataBuf& uuid) {
  166|    793|  const char* uuidCano = "\x85\xC0\xB6\x87\x82\xF\x11\xE0\x81\x11\xF4\xCE\x46\x2B\x6A\x48";
  167|    793|  const char* uuidXmp = "\xBE\x7A\xCF\xCB\x97\xA9\x42\xE8\x9C\x71\x99\x94\x91\xE3\xAF\xAC";
  168|    793|  const char* uuidCanp = "\xEA\xF4\x2B\x5E\x1C\x98\x4B\x88\xB9\xFB\xB7\xDC\x40\x6E\x4D\x16";
  169|    793|  if (uuid.cmpBytes(0, uuidCano, 16) == 0)
  ------------------
  |  Branch (169:7): [True: 142, False: 651]
  ------------------
  170|    142|    return "cano";
  171|    651|  if (uuid.cmpBytes(0, uuidXmp, 16) == 0)
  ------------------
  |  Branch (171:7): [True: 165, False: 486]
  ------------------
  172|    165|    return "xmp";
  173|    486|  if (uuid.cmpBytes(0, uuidCanp, 16) == 0)
  ------------------
  |  Branch (173:7): [True: 334, False: 152]
  ------------------
  174|    334|    return "canp";
  175|    152|  return "";
  176|    486|}
_ZN5Exiv29BmffImage16brotliUncompressEPKhmRNS_7DataBufE:
  184|     88|void BmffImage::brotliUncompress(const byte* compressedBuf, size_t compressedBufSize, DataBuf& arr) {
  185|     88|  auto decoder = BrotliDecoder(BrotliDecoderCreateInstance(nullptr, nullptr, nullptr), BrotliDecoderDestroyInstance);
  186|     88|  size_t uncompressedLen = compressedBufSize * 2;  // just a starting point
  187|     88|  BrotliDecoderResult result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;
  188|     88|  int dos = 0;
  189|     88|  size_t available_in = compressedBufSize;
  190|     88|  const byte* next_in = compressedBuf;
  191|     88|  size_t available_out;
  192|     88|  byte* next_out;
  193|     88|  size_t total_out = 0;
  194|       |
  195|    352|  while (result != BROTLI_DECODER_RESULT_SUCCESS) {
  ------------------
  |  Branch (195:10): [True: 322, False: 30]
  ------------------
  196|    322|    arr.alloc(uncompressedLen);
  197|    322|    available_out = uncompressedLen - total_out;
  198|    322|    next_out = arr.data() + total_out;
  199|    322|    result =
  200|    322|        BrotliDecoderDecompressStream(decoder.get(), &available_in, &next_in, &available_out, &next_out, &total_out);
  201|    322|    if (result == BROTLI_DECODER_RESULT_SUCCESS) {
  ------------------
  |  Branch (201:9): [True: 30, False: 292]
  ------------------
  202|     30|      arr.resize(total_out);
  203|    292|    } else if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT) {
  ------------------
  |  Branch (203:16): [True: 244, False: 48]
  ------------------
  204|    244|      uncompressedLen *= 2;
  205|       |      // DoS protection - can't be bigger than 128k
  206|    244|      if (uncompressedLen > 131072) {
  ------------------
  |  Branch (206:11): [True: 30, False: 214]
  ------------------
  207|     30|        if (++dos > 1 || total_out > 131072)
  ------------------
  |  Branch (207:13): [True: 10, False: 20]
  |  Branch (207:26): [True: 0, False: 20]
  ------------------
  208|     10|          break;
  209|     20|        uncompressedLen = 131072;
  210|     20|      }
  211|    244|    } else if (result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) {
  ------------------
  |  Branch (211:16): [True: 23, False: 25]
  ------------------
  212|       |      // compressed input buffer in incomplete
  213|     23|      throw Error(ErrorCode::kerFailedToReadImageData);
  214|     25|    } else {
  215|       |      // something bad happened
  216|     25|      throw Error(ErrorCode::kerErrorMessage, BrotliDecoderErrorString(BrotliDecoderGetErrorCode(decoder.get())));
  217|     25|    }
  218|    322|  }
  219|       |
  220|     40|  if (result != BROTLI_DECODER_RESULT_SUCCESS) {
  ------------------
  |  Branch (220:7): [True: 10, False: 30]
  ------------------
  221|     10|    throw Error(ErrorCode::kerFailedToReadImageData);
  222|     10|  }
  223|     40|}
_ZN5Exiv29BmffImage10boxHandlerERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEENS_20PrintStructureOptionEmm:
  227|  57.5k|                               uint64_t pbox_end, size_t depth) {
  228|  57.5k|  const size_t address = io_->tell();
  229|       |  // never visit a box twice!
  230|  57.5k|  if (depth == 0)
  ------------------
  |  Branch (230:7): [True: 23.4k, False: 34.0k]
  ------------------
  231|  23.4k|    visits_.clear();
  232|  57.5k|  if (visits_.contains(address) || visits_.size() > visits_max_ || depth >= max_box_depth_) {
  ------------------
  |  Branch (232:7): [True: 0, False: 57.5k]
  |  Branch (232:36): [True: 38, False: 57.5k]
  |  Branch (232:68): [True: 1, False: 57.5k]
  ------------------
  233|     39|    throw Error(ErrorCode::kerCorruptedMetadata);
  234|     39|  }
  235|  57.5k|  visits_.insert(address);
  236|       |
  237|       |#ifdef EXIV2_DEBUG_MESSAGES
  238|       |  bool bTrace = true;
  239|       |#else
  240|  57.5k|  bool bTrace = option == kpsBasic || option == kpsRecursive;
  ------------------
  |  Branch (240:17): [True: 0, False: 57.5k]
  |  Branch (240:39): [True: 0, False: 57.5k]
  ------------------
  241|  57.5k|#endif
  242|       |
  243|       |  // 8-byte buffer for parsing the box length and type.
  244|  57.5k|  byte hdrbuf[2 * sizeof(uint32_t)];
  245|       |
  246|  57.5k|  size_t hdrsize = sizeof(hdrbuf);
  247|  57.5k|  Internal::enforce(hdrsize <= static_cast<size_t>(pbox_end - address), Exiv2::ErrorCode::kerCorruptedMetadata);
  248|  57.5k|  if (io_->read(hdrbuf, sizeof(hdrbuf)) != sizeof(hdrbuf))
  ------------------
  |  Branch (248:7): [True: 0, False: 57.5k]
  ------------------
  249|      0|    return pbox_end;
  250|       |
  251|       |  // The box length is encoded as a uint32_t by default, but the special value 1 means
  252|       |  // that it's a uint64_t.
  253|  57.5k|  uint64_t box_length = getULong(&hdrbuf[0], endian_);
  254|  57.5k|  uint32_t box_type = getULong(&hdrbuf[sizeof(uint32_t)], endian_);
  255|  57.5k|  bool bLF = true;
  256|       |
  257|  57.5k|  if (bTrace) {
  ------------------
  |  Branch (257:7): [True: 0, False: 57.5k]
  ------------------
  258|      0|    bLF = true;
  259|      0|    out << Internal::indent(depth) << "Exiv2::BmffImage::boxHandler: " << toAscii(box_type)
  260|      0|        << stringFormat(" {:8}->{} ", address, box_length);
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
  261|      0|  }
  262|       |
  263|  57.5k|  if (box_length == 1) {
  ------------------
  |  Branch (263:7): [True: 179, False: 57.3k]
  ------------------
  264|       |    // The box size is encoded as a uint64_t, so we need to read another 8 bytes.
  265|    179|    hdrsize += 8;
  266|    179|    Internal::enforce(hdrsize <= static_cast<size_t>(pbox_end - address), Exiv2::ErrorCode::kerCorruptedMetadata);
  267|    179|    DataBuf data(8);
  268|    179|    io_->read(data.data(), data.size());
  269|    179|    box_length = data.read_uint64(0, endian_);
  270|    179|  }
  271|       |
  272|  57.5k|  if (box_length == 0) {
  ------------------
  |  Branch (272:7): [True: 20.8k, False: 36.6k]
  ------------------
  273|       |    // Zero length is also valid and indicates box extends to the end of file.
  274|  20.8k|    box_length = pbox_end - address;
  275|  20.8k|  }
  276|       |
  277|       |  // read data in box and restore file position
  278|  57.5k|  const size_t restore = io_->tell();
  279|  57.5k|  Internal::enforce(box_length >= hdrsize, Exiv2::ErrorCode::kerCorruptedMetadata);
  280|  57.5k|  Internal::enforce(box_length - hdrsize <= pbox_end - restore, Exiv2::ErrorCode::kerCorruptedMetadata);
  281|       |
  282|  57.5k|  const auto buffer_size = box_length - hdrsize;
  283|  57.5k|  if (skipBox(box_type)) {
  ------------------
  |  Branch (283:7): [True: 260, False: 57.2k]
  ------------------
  284|    260|    if (bTrace) {
  ------------------
  |  Branch (284:9): [True: 0, False: 260]
  ------------------
  285|      0|      out << '\n';
  286|      0|    }
  287|       |    // The enforce() above checks that restore + buffer_size won't
  288|       |    // exceed pbox_end, and by implication, won't exceed LONG_MAX
  289|    260|    return restore + buffer_size;
  290|    260|  }
  291|       |
  292|  57.2k|  DataBuf data(static_cast<size_t>(buffer_size));
  293|  57.2k|  const size_t box_end = restore + data.size();
  294|  57.2k|  io_->read(data.data(), data.size());
  295|  57.2k|  io_->seek(restore, BasicIo::beg);
  296|       |
  297|  57.2k|  size_t skip = 0;  // read position in data.pData_
  298|  57.2k|  uint8_t version = 0;
  299|  57.2k|  uint32_t flags = 0;
  300|       |
  301|  57.2k|  if (fullBox(box_type)) {
  ------------------
  |  Branch (301:7): [True: 10.6k, False: 46.5k]
  ------------------
  302|  10.6k|    Internal::enforce(data.size() - skip >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
  303|  10.6k|    flags = data.read_uint32(skip, endian_);  // version/flags
  304|  10.6k|    version = static_cast<uint8_t>(flags >> 24);
  305|  10.6k|    flags &= 0x00ffffff;
  306|  10.6k|    skip += 4;
  307|  10.6k|  }
  308|       |
  309|  57.2k|  switch (box_type) {
  310|       |    //  See notes in skipBox()
  311|  10.3k|    case TAG::ftyp: {
  ------------------
  |  Branch (311:5): [True: 10.3k, False: 46.9k]
  ------------------
  312|  10.3k|      Internal::enforce(data.size() >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
  313|  10.3k|      fileType_ = data.read_uint32(0, endian_);
  314|  10.3k|      if (bTrace) {
  ------------------
  |  Branch (314:11): [True: 0, False: 10.3k]
  ------------------
  315|      0|        out << "brand: " << toAscii(fileType_);
  316|      0|      }
  317|  10.3k|    } break;
  318|       |
  319|       |    // 8.11.6.1
  320|    334|    case TAG::iinf: {
  ------------------
  |  Branch (320:5): [True: 334, False: 56.9k]
  ------------------
  321|    334|      if (bTrace) {
  ------------------
  |  Branch (321:11): [True: 0, False: 334]
  ------------------
  322|      0|        out << '\n';
  323|      0|        bLF = false;
  324|      0|      }
  325|       |
  326|    334|      Internal::enforce(data.size() - skip >= 2, Exiv2::ErrorCode::kerCorruptedMetadata);
  327|    334|      uint16_t n = data.read_uint16(skip, endian_);
  328|    334|      skip += 2;
  329|       |
  330|    334|      io_->seek(skip, BasicIo::cur);
  331|    571|      while (n-- > 0) {
  ------------------
  |  Branch (331:14): [True: 237, False: 334]
  ------------------
  332|    237|        io_->seek(boxHandler(out, option, box_end, depth + 1), BasicIo::beg);
  333|    237|      }
  334|    334|    } break;
  335|       |
  336|       |    // 8.11.6.2
  337|    530|    case TAG::infe: {  // .__._.__hvc1_ 2 0 0 1 0 1 0 0 104 118 99 49 0
  ------------------
  |  Branch (337:5): [True: 530, False: 56.7k]
  ------------------
  338|    530|      Internal::enforce(data.size() - skip >= 8, Exiv2::ErrorCode::kerCorruptedMetadata);
  339|    530|      /* getULong (data.pData_+skip,endian_) ; */ skip += 4;
  340|    530|      uint16_t ID = data.read_uint16(skip, endian_);
  341|    530|      skip += 2;
  342|    530|      /* getShort(data.pData_+skip,endian_) ; */ skip += 2;  // protection
  343|    530|      std::string id;
  344|       |      // Check that the string has a '\0' terminator.
  345|    530|      const char* str = data.c_str(skip);
  346|    530|      const size_t maxlen = data.size() - skip;
  347|    530|      Internal::enforce(maxlen > 0 && strnlen(str, maxlen) < maxlen, Exiv2::ErrorCode::kerCorruptedMetadata);
  ------------------
  |  Branch (347:25): [True: 519, False: 11]
  |  Branch (347:39): [True: 516, False: 3]
  ------------------
  348|    530|      std::string name(str);
  349|    530|      if (Internal::contains(name, "Exif")) {  // "Exif" or "ExifExif"
  ------------------
  |  Branch (349:11): [True: 101, False: 429]
  ------------------
  350|    101|        exifID_ = ID;
  351|    101|        id = " *** Exif ***";
  352|    429|      } else if (Internal::contains(name, "mime\0xmp") || Internal::contains(name, "mime\0application/rdf+xml")) {
  ------------------
  |  Branch (352:18): [True: 179, False: 250]
  |  Branch (352:59): [True: 0, False: 250]
  ------------------
  353|    165|        xmpID_ = ID;
  354|    165|        id = " *** XMP ***";
  355|    165|      }
  356|    530|      if (bTrace) {
  ------------------
  |  Branch (356:11): [True: 0, False: 530]
  ------------------
  357|      0|        out << stringFormat("ID = {:3} {} {}", ID, name, id);
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
  358|      0|      }
  359|    530|    } break;
  360|       |
  361|  12.2k|    case TAG::moov:
  ------------------
  |  Branch (361:5): [True: 12.2k, False: 44.9k]
  ------------------
  362|  12.2k|    case TAG::iprp:
  ------------------
  |  Branch (362:5): [True: 18, False: 57.2k]
  ------------------
  363|  12.3k|    case TAG::ipco:
  ------------------
  |  Branch (363:5): [True: 12, False: 57.2k]
  ------------------
  364|  17.9k|    case TAG::meta: {
  ------------------
  |  Branch (364:5): [True: 5.69k, False: 51.5k]
  ------------------
  365|  17.9k|      if (bTrace) {
  ------------------
  |  Branch (365:11): [True: 0, False: 17.9k]
  ------------------
  366|      0|        out << '\n';
  367|      0|        bLF = false;
  368|      0|      }
  369|  17.9k|      io_->seek(skip, BasicIo::cur);
  370|  51.2k|      while (io_->tell() < box_end) {
  ------------------
  |  Branch (370:14): [True: 33.2k, False: 17.9k]
  ------------------
  371|  33.2k|        io_->seek(boxHandler(out, option, box_end, depth + 1), BasicIo::beg);
  372|  33.2k|      }
  373|       |      // post-process meta box to recover Exif and XMP
  374|  17.9k|      if (box_type == TAG::meta) {
  ------------------
  |  Branch (374:11): [True: 2.04k, False: 15.9k]
  ------------------
  375|  2.04k|        auto ilo = ilocs_.find(exifID_);
  376|  2.04k|        if (ilo != ilocs_.end()) {
  ------------------
  |  Branch (376:13): [True: 49, False: 1.99k]
  ------------------
  377|     49|          const Iloc& iloc = ilo->second;
  378|     49|          if (bTrace) {
  ------------------
  |  Branch (378:15): [True: 0, False: 49]
  ------------------
  379|      0|            out << Internal::indent(depth) << "Exiv2::BMFF Exif: " << iloc.toString() << '\n';
  380|      0|          }
  381|     49|          parseTiff(Internal::Tag::root, iloc.length_, iloc.start_);
  382|     49|        }
  383|  2.04k|        ilo = ilocs_.find(xmpID_);
  384|  2.04k|        if (ilo != ilocs_.end()) {
  ------------------
  |  Branch (384:13): [True: 94, False: 1.95k]
  ------------------
  385|     94|          const Iloc& iloc = ilo->second;
  386|     94|          if (bTrace) {
  ------------------
  |  Branch (386:15): [True: 0, False: 94]
  ------------------
  387|      0|            out << Internal::indent(depth) << "Exiv2::BMFF XMP: " << iloc.toString() << '\n';
  388|      0|          }
  389|     94|          parseXmp(iloc.length_, iloc.start_);
  390|     94|        }
  391|  2.04k|        ilocs_.clear();
  392|  2.04k|      }
  393|  17.9k|    } break;
  394|       |
  395|       |    // 8.11.3.1
  396|  1.44k|    case TAG::iloc: {
  ------------------
  |  Branch (396:5): [True: 1.44k, False: 55.8k]
  ------------------
  397|  1.44k|      Internal::enforce(data.size() - skip >= 2, Exiv2::ErrorCode::kerCorruptedMetadata);
  398|  1.44k|      uint8_t u = data.read_uint8(skip++);
  399|  1.44k|      uint16_t offsetSize = u >> 4;
  400|  1.44k|      uint16_t lengthSize = u & 0xF;
  401|       |#if 0
  402|       |                uint16_t indexSize  = 0       ;
  403|       |                u             = data.read_uint8(skip++);
  404|       |                if ( version == 1 || version == 2 ) {
  405|       |                    indexSize = u & 0xF ;
  406|       |                }
  407|       |#else
  408|  1.44k|      skip++;
  409|  1.44k|#endif
  410|  1.44k|      Internal::enforce(data.size() - skip >= (version < 2u ? 2u : 4u), Exiv2::ErrorCode::kerCorruptedMetadata);
  ------------------
  |  Branch (410:48): [True: 1.04k, False: 397]
  ------------------
  411|  1.44k|      uint32_t itemCount = version < 2 ? data.read_uint16(skip, endian_) : data.read_uint32(skip, endian_);
  ------------------
  |  Branch (411:28): [True: 1.04k, False: 397]
  ------------------
  412|  1.44k|      skip += version < 2 ? 2 : 4;
  ------------------
  |  Branch (412:15): [True: 1.04k, False: 397]
  ------------------
  413|  1.44k|      if (itemCount && itemCount < box_length / 14 && offsetSize == 4 && lengthSize == 4 &&
  ------------------
  |  Branch (413:11): [True: 1.23k, False: 210]
  |  Branch (413:24): [True: 925, False: 306]
  |  Branch (413:55): [True: 839, False: 86]
  |  Branch (413:74): [True: 818, False: 21]
  ------------------
  414|    818|          ((box_length - 16) % itemCount) == 0) {
  ------------------
  |  Branch (414:11): [True: 773, False: 45]
  ------------------
  415|    773|        if (bTrace) {
  ------------------
  |  Branch (415:13): [True: 0, False: 773]
  ------------------
  416|      0|          out << '\n';
  417|      0|          bLF = false;
  418|      0|        }
  419|    773|        auto step = (static_cast<size_t>(box_length) - 16) / itemCount;  // length of data per item.
  420|    773|        size_t base = skip;
  421|  5.69k|        for (uint32_t i = 0; i < itemCount; i++) {
  ------------------
  |  Branch (421:30): [True: 4.92k, False: 773]
  ------------------
  422|  4.92k|          skip = base + (i * step);  // move in 14, 16 or 18 byte steps
  423|  4.92k|          Internal::enforce(data.size() - skip >= (version > 2u ? 4u : 2u), Exiv2::ErrorCode::kerCorruptedMetadata);
  ------------------
  |  Branch (423:52): [True: 1.68k, False: 3.23k]
  ------------------
  424|  4.92k|          Internal::enforce(data.size() - skip >= step, Exiv2::ErrorCode::kerCorruptedMetadata);
  425|  4.92k|          uint32_t ID = version > 2 ? data.read_uint32(skip, endian_) : data.read_uint16(skip, endian_);
  ------------------
  |  Branch (425:25): [True: 1.56k, False: 3.35k]
  ------------------
  426|  4.92k|          auto offset = [&data, skip, step] {
  427|  4.92k|            if (step == 14 || step == 16)
  428|  4.92k|              return data.read_uint32(skip + step - 8, endian_);
  429|  4.92k|            if (step == 18)
  430|  4.92k|              return data.read_uint32(skip + 4, endian_);
  431|  4.92k|            return 0u;
  432|  4.92k|          }();
  433|       |
  434|  4.92k|          uint32_t ldata = data.read_uint32(skip + step - 4, endian_);
  435|  4.92k|          if (bTrace) {
  ------------------
  |  Branch (435:15): [True: 0, False: 4.92k]
  ------------------
  436|      0|            out << Internal::indent(depth)
  437|      0|                << stringFormat("{:8} | {:8} |   ID | {:4} | {:6},{:6}\n", address + skip, step, ID, offset, ldata);
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
  438|      0|          }
  439|       |          // save data for post-processing in meta box
  440|  4.92k|          if (offset && ldata && ID != unknownID_) {
  ------------------
  |  Branch (440:15): [True: 4.19k, False: 724]
  |  Branch (440:25): [True: 4.07k, False: 119]
  |  Branch (440:34): [True: 3.78k, False: 297]
  ------------------
  441|  3.78k|            ilocs_[ID] = Iloc{ID, offset, ldata};
  442|  3.78k|          }
  443|  4.92k|        }
  444|    773|      }
  445|  1.44k|    } break;
  446|       |
  447|    233|    case TAG::ispe: {
  ------------------
  |  Branch (447:5): [True: 233, False: 57.0k]
  ------------------
  448|    233|      Internal::enforce(data.size() - skip >= 12, Exiv2::ErrorCode::kerCorruptedMetadata);
  449|    233|      skip += 4;
  450|    233|      uint32_t width = data.read_uint32(skip, endian_);
  451|    233|      skip += 4;
  452|    233|      uint32_t height = data.read_uint32(skip, endian_);
  453|    233|      skip += 4;
  454|    233|      if (bTrace) {
  ------------------
  |  Branch (454:11): [True: 0, False: 233]
  ------------------
  455|      0|        out << stringFormat("pixelWidth_, pixelHeight_ = {}, {}", width, height);
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
  456|      0|      }
  457|       |      // HEIC files can have multiple ispe records
  458|       |      // Store largest width/height
  459|    233|      if (width > pixelWidth_ && height > pixelHeight_) {
  ------------------
  |  Branch (459:11): [True: 139, False: 94]
  |  Branch (459:34): [True: 69, False: 70]
  ------------------
  460|     69|        pixelWidth_ = width;
  461|     69|        pixelHeight_ = height;
  462|     69|      }
  463|    233|    } break;
  464|       |
  465|       |    // 12.1.5.2
  466|    390|    case TAG::colr: {
  ------------------
  |  Branch (466:5): [True: 390, False: 56.8k]
  ------------------
  467|    390|      if (data.size() >= (skip + 4 + 8)) {  // .____.HLino..__mntrR 2 0 0 0 0 12 72 76 105 110 111 2 16 ...
  ------------------
  |  Branch (467:11): [True: 130, False: 260]
  ------------------
  468|       |        // https://www.ics.uci.edu/~dan/class/267/papers/jpeg2000.pdf
  469|    130|        uint8_t meth = data.read_uint8(skip + 0);
  470|    130|        uint8_t prec = data.read_uint8(skip + 1);
  471|    130|        uint8_t approx = data.read_uint8(skip + 2);
  472|    130|        auto colour_type = std::string(data.c_str(), 4);
  473|    130|        skip += 4;
  474|    130|        if (colour_type == "rICC" || colour_type == "prof") {
  ------------------
  |  Branch (474:13): [True: 14, False: 116]
  |  Branch (474:38): [True: 10, False: 106]
  ------------------
  475|     24|          DataBuf profile(data.c_data(skip), data.size() - skip);
  476|     24|          setIccProfile(std::move(profile));
  477|    106|        } else if (meth == 2 && prec == 0 && approx == 0) {
  ------------------
  |  Branch (477:20): [True: 41, False: 65]
  |  Branch (477:33): [True: 31, False: 10]
  |  Branch (477:46): [True: 20, False: 11]
  ------------------
  478|       |          // JP2000 files have a 3 byte head // 2 0 0 icc......
  479|     20|          skip -= 1;
  480|     20|          DataBuf profile(data.c_data(skip), data.size() - skip);
  481|     20|          setIccProfile(std::move(profile));
  482|     20|        }
  483|    130|      }
  484|    390|    } break;
  485|       |
  486|    793|    case TAG::uuid: {
  ------------------
  |  Branch (486:5): [True: 793, False: 56.4k]
  ------------------
  487|    793|      DataBuf uuid(16);
  488|    793|      io_->read(uuid.data(), uuid.size());
  489|    793|      std::string name = uuidName(uuid);
  490|    793|      if (bTrace) {
  ------------------
  |  Branch (490:11): [True: 0, False: 793]
  ------------------
  491|      0|        out << " uuidName " << name << '\n';
  492|      0|        bLF = false;
  493|      0|      }
  494|    793|      if (name == "cano" || name == "canp") {
  ------------------
  |  Branch (494:11): [True: 142, False: 651]
  |  Branch (494:29): [True: 334, False: 317]
  ------------------
  495|    476|        if (name == "canp") {
  ------------------
  |  Branch (495:13): [True: 334, False: 142]
  ------------------
  496|       |          // based on
  497|       |          // https://github.com/lclevy/canon_cr3/blob/7be75d6/parse_cr3.py#L271
  498|    334|          io_->seek(8, BasicIo::cur);
  499|    334|        }
  500|  1.09k|        while (io_->tell() < box_end) {
  ------------------
  |  Branch (500:16): [True: 614, False: 476]
  ------------------
  501|    614|          io_->seek(boxHandler(out, option, box_end, depth + 1), BasicIo::beg);
  502|    614|        }
  503|    476|      } else if (name == "xmp") {
  ------------------
  |  Branch (503:18): [True: 165, False: 152]
  ------------------
  504|    165|        parseXmp(box_length, io_->tell());
  505|    165|      }
  506|    793|    } break;
  507|       |
  508|  1.41k|    case TAG::cmt1:
  ------------------
  |  Branch (508:5): [True: 1.41k, False: 55.8k]
  ------------------
  509|  1.41k|      parseTiff(Internal::Tag::root, box_length);
  510|  1.41k|      break;
  511|    533|    case TAG::cmt2:
  ------------------
  |  Branch (511:5): [True: 533, False: 56.7k]
  ------------------
  512|    533|      parseTiff(Internal::Tag::cmt2, box_length);
  513|    533|      break;
  514|    615|    case TAG::cmt3:
  ------------------
  |  Branch (514:5): [True: 615, False: 56.6k]
  ------------------
  515|    615|      parseTiff(Internal::Tag::cmt3, box_length);
  516|    615|      break;
  517|    402|    case TAG::cmt4:
  ------------------
  |  Branch (517:5): [True: 402, False: 56.8k]
  ------------------
  518|    402|      parseTiff(Internal::Tag::cmt4, box_length);
  519|    402|      break;
  520|  1.90k|    case TAG::exif:
  ------------------
  |  Branch (520:5): [True: 1.90k, False: 55.3k]
  ------------------
  521|  1.90k|      parseTiff(Internal::Tag::root, buffer_size, io_->tell());
  522|  1.90k|      break;
  523|    146|    case TAG::xml:
  ------------------
  |  Branch (523:5): [True: 146, False: 57.0k]
  ------------------
  524|    146|      parseXmp(buffer_size, io_->tell());
  525|    146|      break;
  526|     88|    case TAG::brob: {
  ------------------
  |  Branch (526:5): [True: 88, False: 57.1k]
  ------------------
  527|     88|      Internal::enforce(data.size() >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
  528|     88|      uint32_t realType = data.read_uint32(0, endian_);
  529|     88|      if (bTrace) {
  ------------------
  |  Branch (529:11): [True: 0, False: 88]
  ------------------
  530|      0|        out << "type: " << toAscii(realType);
  531|      0|      }
  532|     88|#ifdef EXV_HAVE_BROTLI
  533|     88|      DataBuf arr;
  534|     88|      brotliUncompress(data.c_data(4), data.size() - 4, arr);
  535|     88|      if (realType == TAG::exif) {
  ------------------
  |  Branch (535:11): [True: 1, False: 87]
  ------------------
  536|      1|        uint32_t offset = Safe::add(arr.read_uint32(0, endian_), 4u);
  537|      1|        Internal::enforce(Safe::add(offset, 4u) < arr.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  538|      1|        Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), arr.c_data(offset), arr.size() - offset,
  539|      1|                                           Internal::Tag::root, Internal::TiffMapping::findDecoder);
  540|     87|      } else if (realType == TAG::xml) {
  ------------------
  |  Branch (540:18): [True: 0, False: 87]
  ------------------
  541|      0|        try {
  542|      0|          Exiv2::XmpParser::decode(xmpData(), std::string(arr.c_str(), arr.size()));
  543|      0|        } catch (...) {
  544|      0|          throw Error(ErrorCode::kerFailedToReadImageData);
  545|      0|        }
  546|      0|      }
  547|     88|#endif
  548|     88|    } break;
  549|  2.66k|    case TAG::thmb:
  ------------------
  |  Branch (549:5): [True: 2.66k, False: 54.5k]
  ------------------
  550|  2.66k|      switch (version) {
  551|  2.04k|        case 0:  // JPEG
  ------------------
  |  Branch (551:9): [True: 2.04k, False: 620]
  ------------------
  552|  2.04k|          parseCr3Preview(data, out, bTrace, version, skip, skip + 2, skip + 4, skip + 12);
  553|  2.04k|          break;
  554|    401|        case 1:  // HDR
  ------------------
  |  Branch (554:9): [True: 401, False: 2.26k]
  ------------------
  555|    401|          parseCr3Preview(data, out, bTrace, version, skip + 2, skip + 4, skip + 8, skip + 12);
  556|    401|          break;
  557|    219|        default:
  ------------------
  |  Branch (557:9): [True: 219, False: 2.44k]
  ------------------
  558|    219|          break;
  559|  2.66k|      }
  560|  2.66k|      break;
  561|  2.66k|    case TAG::prvw:
  ------------------
  |  Branch (561:5): [True: 500, False: 56.7k]
  ------------------
  562|    500|      switch (version) {
  563|     39|        case 0:  // JPEG
  ------------------
  |  Branch (563:9): [True: 39, False: 461]
  ------------------
  564|    424|        case 1:  // HDR
  ------------------
  |  Branch (564:9): [True: 385, False: 115]
  ------------------
  565|    424|          parseCr3Preview(data, out, bTrace, version, skip + 2, skip + 4, skip + 8, skip + 12);
  566|    424|          break;
  567|     76|        default:
  ------------------
  |  Branch (567:9): [True: 76, False: 424]
  ------------------
  568|     76|          break;
  569|    500|      }
  570|    499|      break;
  571|       |
  572|  16.0k|    default:
  ------------------
  |  Branch (572:5): [True: 16.0k, False: 41.1k]
  ------------------
  573|  16.0k|      break; /* do nothing */
  574|  57.2k|  }
  575|  42.0k|  if (bLF && bTrace)
  ------------------
  |  Branch (575:7): [True: 42.0k, False: 0]
  |  Branch (575:14): [True: 0, False: 42.0k]
  ------------------
  576|      0|    out << '\n';
  577|       |
  578|       |  // return address of next box
  579|  42.0k|  return box_end;
  580|  57.2k|}
_ZN5Exiv29BmffImage9parseTiffEjmm:
  582|  1.95k|void BmffImage::parseTiff(uint32_t root_tag, uint64_t length, uint64_t start) {
  583|  1.95k|  Internal::enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
  584|  1.95k|  Internal::enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
  585|  1.95k|  Internal::enforce(start <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()),
  586|  1.95k|                    ErrorCode::kerCorruptedMetadata);
  587|  1.95k|  Internal::enforce(length <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
  588|       |
  589|       |  // read and parse exif data
  590|  1.95k|  const size_t restore = io_->tell();
  591|  1.95k|  DataBuf exif(static_cast<size_t>(length));
  592|  1.95k|  io_->seek(static_cast<int64_t>(start), BasicIo::beg);
  593|  1.95k|  if (exif.size() > 8 && io_->read(exif.data(), exif.size()) == exif.size()) {
  ------------------
  |  Branch (593:7): [True: 1.09k, False: 856]
  |  Branch (593:26): [True: 1.09k, False: 0]
  ------------------
  594|       |    // hunt for "II" or "MM"
  595|  1.09k|    const size_t eof = std::numeric_limits<size_t>::max();  // impossible value for punt
  596|  1.09k|    size_t punt = eof;
  597|   806k|    for (size_t i = 0; i < exif.size() - 9 && punt == eof; ++i) {
  ------------------
  |  Branch (597:24): [True: 805k, False: 245]
  |  Branch (597:47): [True: 805k, False: 850]
  ------------------
  598|   805k|      auto charCurrent = exif.read_uint8(i);
  599|   805k|      auto charNext = exif.read_uint8(i + 1);
  600|   805k|      if (charCurrent == charNext && (charCurrent == 'I' || charCurrent == 'M'))
  ------------------
  |  Branch (600:11): [True: 678k, False: 126k]
  |  Branch (600:39): [True: 429, False: 678k]
  |  Branch (600:61): [True: 461, False: 677k]
  ------------------
  601|    890|        punt = i;
  602|   805k|    }
  603|  1.09k|    if (punt != eof) {
  ------------------
  |  Branch (603:9): [True: 890, False: 205]
  ------------------
  604|    890|      Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), exif.c_data(punt), exif.size() - punt,
  605|    890|                                         root_tag, Internal::TiffMapping::findDecoder);
  606|    890|    }
  607|  1.09k|  }
  608|  1.95k|  io_->seek(restore, BasicIo::beg);
  609|  1.95k|}
_ZN5Exiv29BmffImage9parseTiffEjm:
  611|  2.96k|void BmffImage::parseTiff(uint32_t root_tag, uint64_t length) {
  612|  2.96k|  if (length > 8) {
  ------------------
  |  Branch (612:7): [True: 752, False: 2.21k]
  ------------------
  613|    752|    Internal::enforce(length - 8 <= io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
  614|    752|    Internal::enforce(length - 8 <= std::numeric_limits<size_t>::max(), ErrorCode::kerCorruptedMetadata);
  615|    752|    DataBuf data(static_cast<size_t>(length - 8u));
  616|    752|    const size_t bufRead = io_->read(data.data(), data.size());
  617|       |
  618|    752|    if (io_->error())
  ------------------
  |  Branch (618:9): [True: 0, False: 752]
  ------------------
  619|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  620|    752|    if (bufRead != data.size())
  ------------------
  |  Branch (620:9): [True: 0, False: 752]
  ------------------
  621|      0|      throw Error(ErrorCode::kerInputDataReadFailed);
  622|       |
  623|    752|    Internal::TiffParserWorker::decode(exifData(), iptcData(), xmpData(), data.c_data(), data.size(), root_tag,
  624|    752|                                       Internal::TiffMapping::findDecoder);
  625|    752|  }
  626|  2.96k|}
_ZN5Exiv29BmffImage8parseXmpEmm:
  628|    405|void BmffImage::parseXmp(uint64_t length, uint64_t start) {
  629|    405|  Internal::enforce(start <= io_->size(), ErrorCode::kerCorruptedMetadata);
  630|    405|  Internal::enforce(length <= io_->size() - start, ErrorCode::kerCorruptedMetadata);
  631|       |
  632|    405|  const size_t restore = io_->tell();
  633|    405|  io_->seek(static_cast<int64_t>(start), BasicIo::beg);
  634|       |
  635|    405|  auto lengthSizeT = static_cast<size_t>(length);
  636|    405|  DataBuf xmp(lengthSizeT + 1);
  637|    405|  xmp.write_uint8(lengthSizeT, 0);  // ensure xmp is null terminated!
  638|    405|  if (io_->read(xmp.data(), lengthSizeT) != lengthSizeT)
  ------------------
  |  Branch (638:7): [True: 0, False: 405]
  ------------------
  639|      0|    throw Error(ErrorCode::kerInputDataReadFailed);
  640|    405|  if (io_->error())
  ------------------
  |  Branch (640:7): [True: 0, False: 405]
  ------------------
  641|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  642|    405|  try {
  643|    405|    Exiv2::XmpParser::decode(xmpData(), std::string(xmp.c_str()));
  644|    405|  } catch (...) {
  645|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  646|      0|  }
  647|       |
  648|    322|  io_->seek(restore, BasicIo::beg);
  649|    322|}
_ZN5Exiv29BmffImage15parseCr3PreviewERKNS_7DataBufERNSt3__113basic_ostreamIcNS4_11char_traitsIcEEEEbhmmmm:
  654|  2.87k|                                size_t relative_position) {
  655|       |  // Derived from https://github.com/lclevy/canon_cr3
  656|  2.87k|  const size_t here = io_->tell();
  657|  2.87k|  Internal::enforce(here <= std::numeric_limits<size_t>::max() - relative_position, ErrorCode::kerCorruptedMetadata);
  658|  2.87k|  NativePreview nativePreview;
  659|  2.87k|  nativePreview.position_ = here + relative_position;
  660|  2.87k|  nativePreview.width_ = data.read_uint16(width_offset, endian_);
  661|  2.87k|  nativePreview.height_ = data.read_uint16(height_offset, endian_);
  662|  2.87k|  nativePreview.size_ = data.read_uint32(size_offset, endian_);
  663|  2.87k|  nativePreview.filter_ = "";
  664|  2.87k|  nativePreview.mimeType_ = [version] {
  665|  2.87k|    if (version == 0)
  666|  2.87k|      return "image/jpeg";
  667|  2.87k|    return "application/octet-stream";
  668|  2.87k|  }();
  669|  2.87k|  if (bTrace) {
  ------------------
  |  Branch (669:7): [True: 0, False: 2.87k]
  ------------------
  670|      0|    out << stringFormat("width,height,size = {},{},{}", nativePreview.width_, nativePreview.height_,
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
  671|      0|                        nativePreview.size_);
  672|      0|  }
  673|  2.87k|  nativePreviews_.push_back(std::move(nativePreview));
  674|  2.87k|}
_ZNK5Exiv29BmffImage11openOrThrowEv:
  693|  3.47k|void BmffImage::openOrThrow() const {
  694|  3.47k|  if (io_->open() != 0) {
  ------------------
  |  Branch (694:7): [True: 0, False: 3.47k]
  ------------------
  695|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  696|      0|  }
  697|       |  // Ensure that this is the correct image type
  698|  3.47k|  if (!isBmffType(*io_, false)) {
  ------------------
  |  Branch (698:7): [True: 0, False: 3.47k]
  ------------------
  699|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (699:9): [True: 0, False: 0]
  |  Branch (699:25): [True: 0, False: 0]
  ------------------
  700|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  701|      0|    throw Error(ErrorCode::kerNotAnImage, "BMFF");
  702|      0|  }
  703|  3.47k|}
_ZN5Exiv29BmffImage12readMetadataEv:
  705|  3.47k|void BmffImage::readMetadata() {
  706|  3.47k|  openOrThrow();
  707|  3.47k|  IoCloser closer(*io_);
  708|       |
  709|  3.47k|  clearMetadata();
  710|  3.47k|  ilocs_.clear();
  711|  3.47k|  visits_max_ = io_->size() / 16;
  712|  3.47k|  unknownID_ = 0xffff;
  713|  3.47k|  exifID_ = unknownID_;
  714|  3.47k|  xmpID_ = unknownID_;
  715|       |
  716|  3.47k|  uint64_t address = 0;
  717|  3.47k|  const auto file_end = io_->size();
  718|  26.9k|  while (address < file_end) {
  ------------------
  |  Branch (718:10): [True: 23.4k, False: 3.47k]
  ------------------
  719|  23.4k|    io_->seek(address, BasicIo::beg);
  720|  23.4k|    address = boxHandler(std::cout, kpsNone, file_end, 0);
  721|  23.4k|  }
  722|  3.47k|  bReadMetadata_ = true;
  723|  3.47k|}  // BmffImage::readMetadata
_ZN5Exiv215newBmffInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  768|  3.47k|Image::UniquePtr newBmffInstance(BasicIo::UniquePtr io, bool create) {
  769|  3.47k|  auto image = std::make_unique<BmffImage>(std::move(io), create);
  770|  3.47k|  if (!image->good()) {
  ------------------
  |  Branch (770:7): [True: 0, False: 3.47k]
  ------------------
  771|      0|    return nullptr;
  772|      0|  }
  773|  3.47k|  return image;
  774|  3.47k|}
_ZN5Exiv210isBmffTypeERNS_7BasicIoEb:
  776|  11.1k|bool isBmffType(BasicIo& iIo, bool advance) {
  777|  11.1k|  const int32_t len = 12;
  778|  11.1k|  byte buf[len];
  779|  11.1k|  iIo.read(buf, len);
  780|  11.1k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (780:7): [True: 0, False: 11.1k]
  |  Branch (780:22): [True: 320, False: 10.7k]
  ------------------
  781|    320|    return false;
  782|    320|  }
  783|       |
  784|       |  // bmff should start with "ftyp"
  785|  10.7k|  bool const is_ftyp = (buf[4] == 'f' && buf[5] == 't' && buf[6] == 'y' && buf[7] == 'p');
  ------------------
  |  Branch (785:25): [True: 10.2k, False: 527]
  |  Branch (785:42): [True: 10.2k, False: 22]
  |  Branch (785:59): [True: 10.2k, False: 16]
  |  Branch (785:76): [True: 10.2k, False: 6]
  ------------------
  786|       |  // jxl files have a special start indicator of "JXL "
  787|  10.7k|  bool const is_jxl = (buf[4] == 'J' && buf[5] == 'X' && buf[6] == 'L' && buf[7] == ' ');
  ------------------
  |  Branch (787:24): [True: 237, False: 10.5k]
  |  Branch (787:41): [True: 226, False: 11]
  |  Branch (787:58): [True: 214, False: 12]
  |  Branch (787:75): [True: 204, False: 10]
  ------------------
  788|       |
  789|  10.7k|  bool matched = is_jxl || is_ftyp;
  ------------------
  |  Branch (789:18): [True: 204, False: 10.5k]
  |  Branch (789:28): [True: 10.2k, False: 367]
  ------------------
  790|  10.7k|  if (!advance || !matched) {
  ------------------
  |  Branch (790:7): [True: 10.7k, False: 0]
  |  Branch (790:19): [True: 0, False: 0]
  ------------------
  791|  10.7k|    iIo.seek(0, BasicIo::beg);
  792|  10.7k|  }
  793|  10.7k|  return matched;
  794|  11.1k|}
bmffimage.cpp:_ZN5Exiv2L7skipBoxEj:
  113|  56.6k|static bool skipBox(uint32_t box) {
  114|       |  // Allows boxHandler() to optimise the reading of files by identifying
  115|       |  // box types that we're not interested in. Box types listed here must
  116|       |  // not appear in the cases in switch (box_type) in boxHandler().
  117|  56.6k|  return box == 0 || box == TAG::mdat;  // mdat is where the main image lives and can be huge
  ------------------
  |  Branch (117:10): [True: 193, False: 56.4k]
  |  Branch (117:22): [True: 67, False: 56.4k]
  ------------------
  118|  56.6k|}
bmffimage.cpp:_ZZN5Exiv29BmffImage10boxHandlerERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEENS_20PrintStructureOptionEmmENK3$_0clEv:
  426|  4.80k|          auto offset = [&data, skip, step] {
  427|  4.80k|            if (step == 14 || step == 16)
  ------------------
  |  Branch (427:17): [True: 2.54k, False: 2.25k]
  |  Branch (427:31): [True: 1.56k, False: 694]
  ------------------
  428|  4.10k|              return data.read_uint32(skip + step - 8, endian_);
  429|    694|            if (step == 18)
  ------------------
  |  Branch (429:17): [True: 421, False: 273]
  ------------------
  430|    421|              return data.read_uint32(skip + 4, endian_);
  431|    273|            return 0u;
  432|    694|          }();
bmffimage.cpp:_ZZN5Exiv29BmffImage15parseCr3PreviewERKNS_7DataBufERNSt3__113basic_ostreamIcNS4_11char_traitsIcEEEEbhmmmmENK3$_0clEv:
  664|  2.86k|  nativePreview.mimeType_ = [version] {
  665|  2.86k|    if (version == 0)
  ------------------
  |  Branch (665:9): [True: 2.08k, False: 783]
  ------------------
  666|  2.08k|      return "image/jpeg";
  667|    783|    return "application/octet-stream";
  668|  2.86k|  }();

_ZN5Exiv28BmpImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
   26|    668|BmpImage::BmpImage(BasicIo::UniquePtr io) : Image(ImageType::bmp, mdNone, std::move(io)) {
   27|    668|}
_ZNK5Exiv28BmpImage8mimeTypeEv:
   29|      3|std::string BmpImage::mimeType() const {
   30|       |  // "image/bmp" is a Generic Bitmap
   31|      3|  return "image/x-ms-bmp";  // Microsoft Bitmap
   32|      3|}
_ZN5Exiv28BmpImage12readMetadataEv:
   46|    658|void BmpImage::readMetadata() {
   47|       |#ifdef EXIV2_DEBUG_MESSAGES
   48|       |  std::cerr << "Exiv2::BmpImage::readMetadata: Reading Windows bitmap file " << io_->path() << "\n";
   49|       |#endif
   50|    658|  if (io_->open() != 0) {
  ------------------
  |  Branch (50:7): [True: 0, False: 658]
  ------------------
   51|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   52|      0|  }
   53|    658|  IoCloser closer(*io_);
   54|       |
   55|       |  // Ensure that this is the correct image type
   56|    658|  if (!isBmpType(*io_, false)) {
  ------------------
  |  Branch (56:7): [True: 0, False: 658]
  ------------------
   57|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (57:9): [True: 0, False: 0]
  |  Branch (57:25): [True: 0, False: 0]
  ------------------
   58|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   59|      0|    throw Error(ErrorCode::kerNotAnImage, "BMP");
   60|      0|  }
   61|    658|  clearMetadata();
   62|       |
   63|       |  /*
   64|       |    The Windows bitmap header goes as follows -- all numbers are in little-endian byte order:
   65|       |
   66|       |    offset  length   name                   description
   67|       |    ======  =======  =====================  =======
   68|       |     0      2 bytes  signature              always 'BM'
   69|       |     2      4 bytes  bitmap size
   70|       |     6      4 bytes  reserved
   71|       |    10      4 bytes  bitmap offset
   72|       |    14      4 bytes  header size
   73|       |    18      4 bytes  bitmap width
   74|       |    22      4 bytes  bitmap height
   75|       |    26      2 bytes  plane count
   76|       |    28      2 bytes  depth
   77|       |    30      4 bytes  compression            0 = none; 1 = RLE, 8 bits/pixel; 2 = RLE, 4 bits/pixel; 3 = bitfield;
   78|       |    4 = JPEG; 5 = PNG 34      4 bytes  image size             size of the raw bitmap data, in bytes 38      4
   79|       |    bytes  horizontal resolution  (in pixels per meter) 42      4 bytes  vertical resolution    (in pixels per
   80|       |    meter) 46      4 bytes  color count 50      4 bytes  important colors       number of "important" colors
   81|       |  */
   82|    658|  byte buf[26];
   83|    658|  if (io_->read(buf, sizeof(buf)) == sizeof(buf)) {
  ------------------
  |  Branch (83:7): [True: 658, False: 0]
  ------------------
   84|    658|    pixelWidth_ = getULong(buf + 18, littleEndian);
   85|    658|    pixelHeight_ = getULong(buf + 22, littleEndian);
   86|    658|  }
   87|    658|}
_ZN5Exiv214newBmpInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
   96|    668|Image::UniquePtr newBmpInstance(BasicIo::UniquePtr io, bool /*create*/) {
   97|    668|  auto image = std::make_unique<BmpImage>(std::move(io));
   98|    668|  if (!image->good()) {
  ------------------
  |  Branch (98:7): [True: 10, False: 658]
  ------------------
   99|     10|    return nullptr;
  100|     10|  }
  101|    658|  return image;
  102|    668|}
_ZN5Exiv29isBmpTypeERNS_7BasicIoEb:
  104|  15.8k|bool isBmpType(BasicIo& iIo, bool advance) {
  105|  15.8k|  const int32_t len = 2;
  106|  15.8k|  const std::array<byte, len> BmpImageId{'B', 'M'};
  107|  15.8k|  std::array<byte, len> buf;
  108|  15.8k|  iIo.read(buf.data(), len);
  109|  15.8k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (109:7): [True: 0, False: 15.8k]
  |  Branch (109:22): [True: 320, False: 15.5k]
  ------------------
  110|    320|    return false;
  111|    320|  }
  112|  15.5k|  bool matched = buf == BmpImageId;
  113|  15.5k|  if (!advance || !matched) {
  ------------------
  |  Branch (113:7): [True: 15.5k, False: 0]
  |  Branch (113:19): [True: 0, False: 0]
  ------------------
  114|  15.5k|    iIo.seek(-len, BasicIo::cur);
  115|  15.5k|  }
  116|  15.5k|  return matched;
  117|  15.8k|}

_ZN5Exiv28Internal7canonEvEl:
 3041|     22|float canonEv(int64_t val) {
 3042|       |  // temporarily remove sign
 3043|     22|  int sign = 1;
 3044|     22|  if (val < 0) {
  ------------------
  |  Branch (3044:7): [True: 0, False: 22]
  ------------------
 3045|      0|    sign = -1;
 3046|      0|    val = -val;
 3047|      0|  }
 3048|       |  // remove fraction
 3049|     22|  const auto remainder = val & 0x1f;
 3050|     22|  val -= remainder;
 3051|     22|  auto frac = static_cast<float>(remainder);
 3052|       |  // convert 1/3 (0x0c) and 2/3 (0x14) codes
 3053|     22|  if (frac == 0x0c) {
  ------------------
  |  Branch (3053:7): [True: 0, False: 22]
  ------------------
 3054|      0|    frac = 32.0F / 3;
 3055|     22|  } else if (frac == 0x14) {
  ------------------
  |  Branch (3055:14): [True: 0, False: 22]
  ------------------
 3056|      0|    frac = 64.0F / 3;
 3057|     22|  } else if ((val == 160) && (frac == 0x08)) {  // for Sigma f/6.3 lenses that report f/6.2 to camera
  ------------------
  |  Branch (3057:14): [True: 0, False: 22]
  |  Branch (3057:30): [True: 0, False: 0]
  ------------------
 3058|      0|    frac = 30.0F / 3;
 3059|      0|  }
 3060|     22|  return sign * (val + frac) / 32.0F;
 3061|     22|}

_ZN5Exiv28Internal14CanonMakerNote7tagListEv:
   38|  35.7k|  static constexpr auto tagList() {
   39|  35.7k|    return tagInfo_;
   40|  35.7k|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListCsEv:
   42|  36.9k|  static constexpr auto tagListCs() {
   43|  36.9k|    return tagInfoCs_;
   44|  36.9k|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListSiEv:
   46|   275k|  static constexpr auto tagListSi() {
   47|   275k|    return tagInfoSi_;
   48|   275k|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListCfEv:
   54|    770|  static constexpr auto tagListCf() {
   55|    770|    return tagInfoCf_;
   56|    770|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListPiEv:
   58|    542|  static constexpr auto tagListPi() {
   59|    542|    return tagInfoPi_;
   60|    542|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListTiEv:
   62|    333|  static constexpr auto tagListTi() {
   63|    333|    return tagInfoTi_;
   64|    333|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListFiEv:
   66|    317|  static constexpr auto tagListFi() {
   67|    317|    return tagInfoFi_;
   68|    317|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListPaEv:
   50|  9.58k|  static constexpr auto tagListPa() {
   51|  9.58k|    return tagInfoPa_;
   52|  9.58k|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListPrEv:
   70|    420|  static constexpr auto tagListPr() {
   71|    420|    return tagInfoPr_;
   72|    420|  }
_ZN5Exiv28Internal14CanonMakerNote14tagListVigCor2Ev:
  134|    293|  static constexpr auto tagListVigCor2() {
  135|    293|    return tagInfoVigCor2_;
  136|    293|  }
_ZN5Exiv28Internal14CanonMakerNote11tagListLiOpEv:
  138|    578|  static constexpr auto tagListLiOp() {
  139|    578|    return tagInfoLiOp_;
  140|    578|  }
_ZN5Exiv28Internal14CanonMakerNote14tagListAfMiAdjEv:
  126|     87|  static constexpr auto tagListAfMiAdj() {
  127|     87|    return tagInfoAfMiAdj_;
  128|     87|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListLeEv:
  142|   214k|  static constexpr auto tagListLe() {
  143|   214k|    return tagInfoLe_;
  144|   214k|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListAmEv:
  146|    393|  static constexpr auto tagListAm() {
  147|    393|    return tagInfoAm_;
  148|    393|  }
_ZN5Exiv28Internal14CanonMakerNote10tagListFilEv:
  154|    369|  static constexpr auto tagListFil() {
  155|    369|    return tagInfoFil_;
  156|    369|  }
_ZN5Exiv28Internal14CanonMakerNote9tagListMeEv:
  150|    630|  static constexpr auto tagListMe() {
  151|    630|    return tagInfoMe_;
  152|    630|  }
_ZN5Exiv28Internal14CanonMakerNote10tagListHdrEv:
  158|    332|  static constexpr auto tagListHdr() {
  159|    332|    return tagInfoHdr_;
  160|    332|  }
_ZN5Exiv28Internal14CanonMakerNote10tagListAfCEv:
  162|    296|  static constexpr auto tagListAfC() {
  163|    296|    return tagInfoAfC_;
  164|    296|  }
_ZN5Exiv28Internal14CanonMakerNote11tagListRawBEv:
  166|    108|  static constexpr auto tagListRawB() {
  167|    108|    return tagInfoRawB_;
  168|    108|  }

_ZN5Exiv28Internal14CasioMakerNote7tagListEv:
   34|    199|  static constexpr auto tagList() {
   35|    199|    return tagInfo_;
   36|    199|  }
_ZN5Exiv28Internal15Casio2MakerNote7tagListEv:
   52|  33.3k|  static constexpr auto tagList() {
   53|  33.3k|    return tagInfo_;
   54|  33.3k|  }

_ZN5Exiv29ConverterC2ERNS_8ExifDataERNS_7XmpDataE:
  495|  1.20k|    exifData_(&exifData), iptcData_(nullptr), xmpData_(&xmpData), iptcCharset_(nullptr) {
  496|  1.20k|}
_ZN5Exiv29ConverterC2ERNS_8IptcDataERNS_7XmpDataEPKc:
  499|  1.20k|    exifData_(nullptr), iptcData_(&iptcData), xmpData_(&xmpData), iptcCharset_(iptcCharset) {
  500|  1.20k|}
_ZN5Exiv29Converter10cnvFromXmpEv:
  510|  2.41k|void Converter::cnvFromXmp() {
  511|   303k|  for (auto&& c : conversion_) {
  ------------------
  |  Branch (511:17): [True: 303k, False: 2.41k]
  ------------------
  512|   303k|    if ((c.metadataId_ == mdExif && exifData_) || (c.metadataId_ == mdIptc && iptcData_)) {
  ------------------
  |  Branch (512:10): [True: 250k, False: 53.0k]
  |  Branch (512:37): [True: 125k, False: 125k]
  |  Branch (512:52): [True: 53.0k, False: 125k]
  |  Branch (512:79): [True: 26.5k, False: 26.5k]
  ------------------
  513|   151k|      std::invoke(c.key2ToKey1_, *this, c.key2_, c.key1_);
  514|   151k|    }
  515|   303k|  }
  516|  2.41k|}
_ZN5Exiv29Converter17prepareExifTargetEPKcb:
  521|  2.60k|bool Converter::prepareExifTarget(const char* to, bool force) {
  522|  2.60k|  auto pos = exifData_->findKey(ExifKey(to));
  523|  2.60k|  if (pos == exifData_->end())
  ------------------
  |  Branch (523:7): [True: 2.60k, False: 0]
  ------------------
  524|  2.60k|    return true;
  525|      0|  if (!overwrite_ && !force)
  ------------------
  |  Branch (525:7): [True: 0, False: 0]
  |  Branch (525:22): [True: 0, False: 0]
  ------------------
  526|      0|    return false;
  527|      0|  exifData_->erase(pos);
  528|      0|  return true;
  529|      0|}
_ZN5Exiv29Converter17prepareIptcTargetEPKcb:
  531|    328|bool Converter::prepareIptcTarget(const char* to, bool force) {
  532|    328|  auto pos = iptcData_->findKey(IptcKey(to));
  533|    328|  if (pos == iptcData_->end())
  ------------------
  |  Branch (533:7): [True: 328, False: 0]
  ------------------
  534|    328|    return true;
  535|      0|  if (!overwrite_ && !force)
  ------------------
  |  Branch (535:7): [True: 0, False: 0]
  |  Branch (535:22): [True: 0, False: 0]
  ------------------
  536|      0|    return false;
  537|      0|  while ((pos = iptcData_->findKey(IptcKey(to))) != iptcData_->end()) {
  ------------------
  |  Branch (537:10): [True: 0, False: 0]
  ------------------
  538|      0|    iptcData_->erase(pos);
  539|      0|  }
  540|      0|  return true;
  541|      0|}
_ZN5Exiv29Converter11cnvXmpValueEPKcS2_:
  844|   108k|void Converter::cnvXmpValue(const char* from, const char* to) {
  845|   108k|  auto pos = xmpData_->findKey(XmpKey(from));
  846|   108k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (846:7): [True: 108k, False: 199]
  ------------------
  847|   108k|    return;
  848|    199|  if (!prepareExifTarget(to))
  ------------------
  |  Branch (848:7): [True: 0, False: 199]
  ------------------
  849|      0|    return;
  850|    199|  std::string value;
  851|    199|  if (!getTextValue(value, pos)) {
  ------------------
  |  Branch (851:7): [True: 0, False: 199]
  ------------------
  852|      0|#ifndef SUPPRESS_WARNINGS
  853|      0|    EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  854|      0|#endif
  855|      0|    return;
  856|      0|  }
  857|       |  // Todo: Escape non-ASCII characters in XMP text values
  858|    199|  ExifKey key(to);
  859|    199|  if (auto ed = Exifdatum(key); ed.setValue(value) == 0) {
  ------------------
  |  Branch (859:33): [True: 199, False: 0]
  ------------------
  860|    199|    exifData_->add(ed);
  861|    199|  }
  862|    199|  if (erase_)
  ------------------
  |  Branch (862:7): [True: 0, False: 199]
  ------------------
  863|      0|    xmpData_->erase(pos);
  864|    199|}
_ZN5Exiv29Converter13cnvXmpCommentEPKcS2_:
  866|  1.20k|void Converter::cnvXmpComment(const char* from, const char* to) {
  867|  1.20k|  if (!prepareExifTarget(to))
  ------------------
  |  Branch (867:7): [True: 0, False: 1.20k]
  ------------------
  868|      0|    return;
  869|  1.20k|  auto pos = xmpData_->findKey(XmpKey(from));
  870|  1.20k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (870:7): [True: 1.20k, False: 0]
  ------------------
  871|  1.20k|    return;
  872|      0|  std::string value;
  873|      0|  if (!getTextValue(value, pos)) {
  ------------------
  |  Branch (873:7): [True: 0, False: 0]
  ------------------
  874|      0|#ifndef SUPPRESS_WARNINGS
  875|      0|    EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  876|      0|#endif
  877|      0|    return;
  878|      0|  }
  879|       |  // Assumes the XMP value is encoded in UTF-8, as it should be
  880|      0|  (*exifData_)[to] = "charset=Unicode " + value;
  881|      0|  if (erase_)
  ------------------
  |  Branch (881:7): [True: 0, False: 0]
  ------------------
  882|      0|    xmpData_->erase(pos);
  883|      0|}
_ZN5Exiv29Converter11cnvXmpArrayEPKcS2_:
  885|  1.20k|void Converter::cnvXmpArray(const char* from, const char* to) {
  886|  1.20k|  if (!prepareExifTarget(to))
  ------------------
  |  Branch (886:7): [True: 0, False: 1.20k]
  ------------------
  887|      0|    return;
  888|  1.20k|  auto pos = xmpData_->findKey(XmpKey(from));
  889|  1.20k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (889:7): [True: 1.20k, False: 0]
  ------------------
  890|  1.20k|    return;
  891|      0|  std::string array;
  892|      0|  for (size_t i = 0; i < pos->count(); ++i) {
  ------------------
  |  Branch (892:22): [True: 0, False: 0]
  ------------------
  893|      0|    std::string value = pos->toString(i);
  894|      0|    if (!pos->value().ok()) {
  ------------------
  |  Branch (894:9): [True: 0, False: 0]
  ------------------
  895|      0|#ifndef SUPPRESS_WARNINGS
  896|      0|      EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  897|      0|#endif
  898|      0|      return;
  899|      0|    }
  900|      0|    array += value;
  901|      0|    if (i != pos->count() - 1)
  ------------------
  |  Branch (901:9): [True: 0, False: 0]
  ------------------
  902|      0|      array += " ";
  903|      0|  }
  904|      0|  (*exifData_)[to] = array;
  905|      0|  if (erase_)
  ------------------
  |  Branch (905:7): [True: 0, False: 0]
  ------------------
  906|      0|    xmpData_->erase(pos);
  907|      0|}
_ZN5Exiv29Converter10cnvXmpDateEPKcS2_:
  909|  4.82k|void Converter::cnvXmpDate(const char* from, const char* to) {
  910|  4.82k|  auto pos = xmpData_->findKey(XmpKey(from));
  911|  4.82k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (911:7): [True: 4.82k, False: 0]
  ------------------
  912|  4.82k|    return;
  913|      0|  if (!prepareExifTarget(to))
  ------------------
  |  Branch (913:7): [True: 0, False: 0]
  ------------------
  914|      0|    return;
  915|      0|#ifdef EXV_HAVE_XMP_TOOLKIT
  916|      0|  std::string value = pos->toString();
  917|      0|  if (!pos->value().ok()) {
  ------------------
  |  Branch (917:7): [True: 0, False: 0]
  ------------------
  918|      0|#ifndef SUPPRESS_WARNINGS
  919|      0|    EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  920|      0|#endif
  921|      0|    return;
  922|      0|  }
  923|      0|  XMP_DateTime datetime;
  924|      0|  try {
  925|      0|    SXMPUtils::ConvertToDate(value, &datetime);
  926|      0|    if (std::string(to) != "Exif.GPSInfo.GPSTimeStamp") {
  ------------------
  |  Branch (926:9): [True: 0, False: 0]
  ------------------
  927|      0|      SXMPUtils::ConvertToLocalTime(&datetime);
  928|       |
  929|      0|      (*exifData_)[to] = stringFormat("{:4}:{:02}:{:02} {:02}:{:02}:{:02}", datetime.year, datetime.month, datetime.day,
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
  930|      0|                                      datetime.hour, datetime.minute, datetime.second);
  931|       |
  932|      0|      if (datetime.nanoSecond) {
  ------------------
  |  Branch (932:11): [True: 0, False: 0]
  ------------------
  933|      0|        const char* subsecTag = nullptr;
  934|      0|        if (std::string(to) == "Exif.Image.DateTime") {
  ------------------
  |  Branch (934:13): [True: 0, False: 0]
  ------------------
  935|      0|          subsecTag = "Exif.Photo.SubSecTime";
  936|      0|        } else if (std::string(to) == "Exif.Photo.DateTimeOriginal") {
  ------------------
  |  Branch (936:20): [True: 0, False: 0]
  ------------------
  937|      0|          subsecTag = "Exif.Photo.SubSecTimeOriginal";
  938|      0|        } else if (std::string(to) == "Exif.Photo.DateTimeDigitized") {
  ------------------
  |  Branch (938:20): [True: 0, False: 0]
  ------------------
  939|      0|          subsecTag = "Exif.Photo.SubSecTimeDigitized";
  940|      0|        }
  941|      0|        if (subsecTag) {
  ------------------
  |  Branch (941:13): [True: 0, False: 0]
  ------------------
  942|      0|          prepareExifTarget(subsecTag, true);
  943|      0|          (*exifData_)[subsecTag] = std::to_string(datetime.nanoSecond);
  944|      0|        }
  945|      0|      }
  946|      0|    } else {  // "Exif.GPSInfo.GPSTimeStamp"
  947|       |      // Ignore the time zone, assuming the time is in UTC as it should be
  948|       |
  949|      0|      URational rhour(datetime.hour, 1);
  950|      0|      URational rmin(datetime.minute, 1);
  951|      0|      URational rsec(datetime.second, 1);
  952|      0|      if (datetime.nanoSecond != 0) {
  ------------------
  |  Branch (952:11): [True: 0, False: 0]
  ------------------
  953|      0|        if (datetime.second != 0) {
  ------------------
  |  Branch (953:13): [True: 0, False: 0]
  ------------------
  954|       |          // Add the seconds to rmin so that the ns fit into rsec
  955|      0|          rmin.second = 60;
  956|      0|          rmin.first *= 60;
  957|      0|          rmin.first += datetime.second;
  958|      0|        }
  959|      0|        rsec.second = 1000000000;
  960|      0|        rsec.first = datetime.nanoSecond;
  961|      0|      }
  962|       |
  963|      0|      std::ostringstream array;
  964|      0|      array << rhour << " " << rmin << " " << rsec;
  965|      0|      (*exifData_)[to] = array.str();
  966|       |
  967|      0|      prepareExifTarget("Exif.GPSInfo.GPSDateStamp", true);
  968|      0|      (*exifData_)["Exif.GPSInfo.GPSDateStamp"] =
  969|      0|          stringFormat("{:4}:{:02}:{:02}", datetime.year, datetime.month, datetime.day);
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
  970|      0|    }
  971|      0|  }
  972|      0|#ifndef SUPPRESS_WARNINGS
  973|      0|  catch (const XMP_Error& e) {
  974|      0|    EXV_WARNING << "Failed to convert " << from << " to " << to << " (" << e.GetErrMsg() << ")\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  975|      0|    return;
  976|      0|  }
  977|       |#else
  978|       |  catch (const XMP_Error&) {
  979|       |    return;
  980|       |  }
  981|       |#endif  // SUPPRESS_WARNINGS
  982|       |
  983|      0|  if (erase_)
  ------------------
  |  Branch (983:7): [True: 0, False: 0]
  ------------------
  984|      0|    xmpData_->erase(pos);
  985|       |#else
  986|       |#ifndef SUPPRESS_WARNINGS
  987|       |  EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  988|       |#endif
  989|       |#endif  // !EXV_HAVE_XMP_TOOLKIT
  990|      0|}
_ZN5Exiv29Converter13cnvXmpVersionEPKcS2_:
  992|  2.41k|void Converter::cnvXmpVersion(const char* from, const char* to) {
  993|  2.41k|  auto pos = xmpData_->findKey(XmpKey(from));
  994|  2.41k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (994:7): [True: 2.41k, False: 0]
  ------------------
  995|  2.41k|    return;
  996|      0|  if (!prepareExifTarget(to))
  ------------------
  |  Branch (996:7): [True: 0, False: 0]
  ------------------
  997|      0|    return;
  998|      0|  std::string value = pos->toString();
  999|      0|  if (!pos->value().ok() || value.length() < 4) {
  ------------------
  |  Branch (999:7): [True: 0, False: 0]
  |  Branch (999:29): [True: 0, False: 0]
  ------------------
 1000|      0|#ifndef SUPPRESS_WARNINGS
 1001|      0|    EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1002|      0|#endif
 1003|      0|    return;
 1004|      0|  }
 1005|       |
 1006|      0|  (*exifData_)[to] = stringFormat("{} {} {} {}", static_cast<int>(value[0]), static_cast<int>(value[1]),
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
 1007|      0|                                  static_cast<int>(value[2]), static_cast<int>(value[3]));
 1008|      0|  if (erase_)
  ------------------
  |  Branch (1008:7): [True: 0, False: 0]
  ------------------
 1009|      0|    xmpData_->erase(pos);
 1010|      0|}
_ZN5Exiv29Converter16cnvXmpGPSVersionEPKcS2_:
 1012|  1.20k|void Converter::cnvXmpGPSVersion(const char* from, const char* to) {
 1013|  1.20k|  auto pos = xmpData_->findKey(XmpKey(from));
 1014|  1.20k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (1014:7): [True: 1.20k, False: 0]
  ------------------
 1015|  1.20k|    return;
 1016|      0|  if (!prepareExifTarget(to))
  ------------------
  |  Branch (1016:7): [True: 0, False: 0]
  ------------------
 1017|      0|    return;
 1018|      0|  std::string value = pos->toString();
 1019|      0|  if (!pos->value().ok()) {
  ------------------
  |  Branch (1019:7): [True: 0, False: 0]
  ------------------
 1020|      0|#ifndef SUPPRESS_WARNINGS
 1021|      0|    EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1022|      0|#endif
 1023|      0|    return;
 1024|      0|  }
 1025|       |
 1026|      0|  std::replace(value.begin(), value.end(), '.', ' ');
 1027|      0|  (*exifData_)[to] = value;
 1028|      0|  if (erase_)
  ------------------
  |  Branch (1028:7): [True: 0, False: 0]
  ------------------
 1029|      0|    xmpData_->erase(pos);
 1030|      0|}
_ZN5Exiv29Converter11cnvXmpFlashEPKcS2_:
 1032|  1.20k|void Converter::cnvXmpFlash(const char* from, const char* to) {
 1033|  1.20k|  auto pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Fired"));
 1034|  1.20k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (1034:7): [True: 1.20k, False: 0]
  ------------------
 1035|  1.20k|    return;
 1036|      0|  if (!prepareExifTarget(to))
  ------------------
  |  Branch (1036:7): [True: 0, False: 0]
  ------------------
 1037|      0|    return;
 1038|      0|  unsigned short value = 0;
 1039|       |
 1040|      0|  if (pos != xmpData_->end() && pos->count() > 0) {
  ------------------
  |  Branch (1040:7): [True: 0, False: 0]
  |  Branch (1040:7): [True: 0, False: 0]
  |  Branch (1040:33): [True: 0, False: 0]
  ------------------
 1041|      0|    auto fired = pos->toUint32();
 1042|      0|    if (pos->value().ok())
  ------------------
  |  Branch (1042:9): [True: 0, False: 0]
  ------------------
 1043|      0|      value |= fired & 1;
 1044|      0|#ifndef SUPPRESS_WARNINGS
 1045|      0|    else
 1046|      0|      EXV_WARNING << "Failed to convert " << std::string(from) << "/exif:Fired"
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1047|      0|                  << " to " << to << "\n";
 1048|      0|#endif
 1049|      0|  }
 1050|      0|  pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Return"));
 1051|      0|  if (pos != xmpData_->end() && pos->count() > 0) {
  ------------------
  |  Branch (1051:7): [True: 0, False: 0]
  |  Branch (1051:7): [True: 0, False: 0]
  |  Branch (1051:33): [True: 0, False: 0]
  ------------------
 1052|      0|    auto ret = pos->toUint32();
 1053|      0|    if (pos->value().ok())
  ------------------
  |  Branch (1053:9): [True: 0, False: 0]
  ------------------
 1054|      0|      value |= (ret & 3) << 1;
 1055|      0|#ifndef SUPPRESS_WARNINGS
 1056|      0|    else
 1057|      0|      EXV_WARNING << "Failed to convert " << std::string(from) << "/exif:Return"
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1058|      0|                  << " to " << to << "\n";
 1059|      0|#endif
 1060|      0|  }
 1061|      0|  pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Mode"));
 1062|      0|  if (pos != xmpData_->end() && pos->count() > 0) {
  ------------------
  |  Branch (1062:7): [True: 0, False: 0]
  |  Branch (1062:7): [True: 0, False: 0]
  |  Branch (1062:33): [True: 0, False: 0]
  ------------------
 1063|      0|    auto mode = pos->toUint32();
 1064|      0|    if (pos->value().ok())
  ------------------
  |  Branch (1064:9): [True: 0, False: 0]
  ------------------
 1065|      0|      value |= (mode & 3) << 3;
 1066|      0|#ifndef SUPPRESS_WARNINGS
 1067|      0|    else
 1068|      0|      EXV_WARNING << "Failed to convert " << std::string(from) << "/exif:Mode"
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1069|      0|                  << " to " << to << "\n";
 1070|      0|#endif
 1071|      0|  }
 1072|      0|  pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:Function"));
 1073|      0|  if (pos != xmpData_->end() && pos->count() > 0) {
  ------------------
  |  Branch (1073:7): [True: 0, False: 0]
  |  Branch (1073:7): [True: 0, False: 0]
  |  Branch (1073:33): [True: 0, False: 0]
  ------------------
 1074|      0|    auto function = pos->toUint32();
 1075|      0|    if (pos->value().ok())
  ------------------
  |  Branch (1075:9): [True: 0, False: 0]
  ------------------
 1076|      0|      value |= (function & 1) << 5;
 1077|      0|#ifndef SUPPRESS_WARNINGS
 1078|      0|    else
 1079|      0|      EXV_WARNING << "Failed to convert " << std::string(from) << "/exif:Function"
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1080|      0|                  << " to " << to << "\n";
 1081|      0|#endif
 1082|      0|  }
 1083|      0|  pos = xmpData_->findKey(XmpKey(std::string(from) + "/exif:RedEyeMode"));
 1084|      0|  if (pos != xmpData_->end()) {
  ------------------
  |  Branch (1084:7): [True: 0, False: 0]
  ------------------
 1085|      0|    if (pos->count() > 0) {
  ------------------
  |  Branch (1085:9): [True: 0, False: 0]
  ------------------
 1086|      0|      auto red = pos->toUint32();
 1087|      0|      if (pos->value().ok())
  ------------------
  |  Branch (1087:11): [True: 0, False: 0]
  ------------------
 1088|      0|        value |= (red & 1) << 6;
 1089|      0|#ifndef SUPPRESS_WARNINGS
 1090|      0|      else
 1091|      0|        EXV_WARNING << "Failed to convert " << std::string(from) << "/exif:RedEyeMode"
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1092|      0|                    << " to " << to << "\n";
 1093|      0|#endif
 1094|      0|    }
 1095|      0|    if (erase_)
  ------------------
  |  Branch (1095:9): [True: 0, False: 0]
  ------------------
 1096|      0|      xmpData_->erase(pos);
 1097|      0|  }
 1098|       |
 1099|      0|  (*exifData_)[to] = value;
 1100|      0|}
_ZN5Exiv29Converter14cnvXmpGPSCoordEPKcS2_:
 1102|  4.82k|void Converter::cnvXmpGPSCoord(const char* from, const char* to) {
 1103|  4.82k|  auto pos = xmpData_->findKey(XmpKey(from));
 1104|  4.82k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (1104:7): [True: 4.82k, False: 0]
  ------------------
 1105|  4.82k|    return;
 1106|      0|  if (!prepareExifTarget(to))
  ------------------
  |  Branch (1106:7): [True: 0, False: 0]
  ------------------
 1107|      0|    return;
 1108|      0|  std::string value = pos->toString();
 1109|      0|  if (!pos->value().ok()) {
  ------------------
  |  Branch (1109:7): [True: 0, False: 0]
  ------------------
 1110|      0|#ifndef SUPPRESS_WARNINGS
 1111|      0|    EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1112|      0|#endif
 1113|      0|    return;
 1114|      0|  }
 1115|      0|  if (value.empty()) {
  ------------------
  |  Branch (1115:7): [True: 0, False: 0]
  ------------------
 1116|      0|#ifndef SUPPRESS_WARNINGS
 1117|      0|    EXV_WARNING << from << " is empty\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1118|      0|#endif
 1119|      0|    return;
 1120|      0|  }
 1121|       |
 1122|      0|  double deg = 0.0;
 1123|      0|  double min = 0.0;
 1124|      0|  double sec = 0.0;
 1125|      0|  char ref = value.back();
 1126|      0|  char sep1 = '\0';
 1127|      0|  char sep2 = '\0';
 1128|       |
 1129|      0|  value.pop_back();
 1130|       |
 1131|      0|  std::istringstream in(value);
 1132|       |
 1133|      0|  in >> deg >> sep1 >> min >> sep2;
 1134|       |
 1135|      0|  if (sep2 == ',') {
  ------------------
  |  Branch (1135:7): [True: 0, False: 0]
  ------------------
 1136|      0|    in >> sec;
 1137|      0|  } else {
 1138|      0|    sec = (min - static_cast<int>(min)) * 60.0;
 1139|      0|    min = static_cast<double>(static_cast<int>(min));
 1140|      0|  }
 1141|       |
 1142|      0|  if (in.bad() || (ref != 'N' && ref != 'S' && ref != 'E' && ref != 'W') || sep1 != ',' || !in.eof()) {
  ------------------
  |  Branch (1142:7): [True: 0, False: 0]
  |  Branch (1142:20): [True: 0, False: 0]
  |  Branch (1142:34): [True: 0, False: 0]
  |  Branch (1142:48): [True: 0, False: 0]
  |  Branch (1142:62): [True: 0, False: 0]
  |  Branch (1142:77): [True: 0, False: 0]
  |  Branch (1142:92): [True: 0, False: 0]
  ------------------
 1143|      0|#ifndef SUPPRESS_WARNINGS
 1144|      0|    EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1145|      0|#endif
 1146|      0|    return;
 1147|      0|  }
 1148|       |
 1149|      0|  Rational rdeg = floatToRationalCast(static_cast<float>(deg));
 1150|      0|  Rational rmin = floatToRationalCast(static_cast<float>(min));
 1151|      0|  Rational rsec = floatToRationalCast(static_cast<float>(sec));
 1152|       |
 1153|      0|  std::ostringstream array;
 1154|      0|  array << rdeg << " " << rmin << " " << rsec;
 1155|      0|  (*exifData_)[to] = array.str();
 1156|       |
 1157|      0|  prepareExifTarget((std::string(to) + "Ref").c_str(), true);
 1158|      0|  char ref_str[2] = {ref, 0};
 1159|      0|  (*exifData_)[std::string(to) + "Ref"] = ref_str;
 1160|       |
 1161|      0|  if (erase_)
  ------------------
  |  Branch (1161:7): [True: 0, False: 0]
  ------------------
 1162|      0|    xmpData_->erase(pos);
 1163|      0|}
_ZN5Exiv29Converter17cnvXmpValueToIptcEPKcS2_:
 1193|  26.5k|void Converter::cnvXmpValueToIptc(const char* from, const char* to) {
 1194|  26.5k|  auto pos = xmpData_->findKey(XmpKey(from));
 1195|  26.5k|  if (pos == xmpData_->end())
  ------------------
  |  Branch (1195:7): [True: 26.1k, False: 328]
  ------------------
 1196|  26.1k|    return;
 1197|    328|  if (!prepareIptcTarget(to))
  ------------------
  |  Branch (1197:7): [True: 0, False: 328]
  ------------------
 1198|      0|    return;
 1199|       |
 1200|    328|  if (pos->typeId() == langAlt || pos->typeId() == xmpText) {
  ------------------
  |  Branch (1200:7): [True: 80, False: 248]
  |  Branch (1200:35): [True: 93, False: 155]
  ------------------
 1201|    173|    std::string value;
 1202|    173|    if (!getTextValue(value, pos)) {
  ------------------
  |  Branch (1202:9): [True: 21, False: 152]
  ------------------
 1203|     21|#ifndef SUPPRESS_WARNINGS
 1204|     21|      EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|     21|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 21]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     21|  LogMsg(LogMsg::warn).os()
  ------------------
 1205|     21|#endif
 1206|     21|      return;
 1207|     21|    }
 1208|    152|    (*iptcData_)[to] = value;
 1209|    152|    (*iptcData_)["Iptc.Envelope.CharacterSet"] = "\033%G";  // indicate UTF-8 encoding
 1210|    152|    if (erase_)
  ------------------
  |  Branch (1210:9): [True: 0, False: 152]
  ------------------
 1211|      0|      xmpData_->erase(pos);
 1212|    152|    return;
 1213|    173|  }
 1214|       |
 1215|    155|  size_t count = pos->count();
 1216|    155|  bool added = false;
 1217|  2.95k|  for (size_t i = 0; i < count; ++i) {
  ------------------
  |  Branch (1217:22): [True: 2.79k, False: 155]
  ------------------
 1218|  2.79k|    std::string value = pos->toString(i);
 1219|  2.79k|    if (!pos->value().ok()) {
  ------------------
  |  Branch (1219:9): [True: 0, False: 2.79k]
  ------------------
 1220|      0|#ifndef SUPPRESS_WARNINGS
 1221|      0|      EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1222|      0|#endif
 1223|      0|      continue;
 1224|      0|    }
 1225|  2.79k|    IptcKey key(to);
 1226|  2.79k|    Iptcdatum id(key);
 1227|  2.79k|    id.setValue(value);
 1228|  2.79k|    iptcData_->add(id);
 1229|  2.79k|    added = true;
 1230|  2.79k|  }
 1231|    155|  if (added)
  ------------------
  |  Branch (1231:7): [True: 149, False: 6]
  ------------------
 1232|    149|    (*iptcData_)["Iptc.Envelope.CharacterSet"] = "\033%G";  // indicate UTF-8 encoding
 1233|    155|  if (erase_)
  ------------------
  |  Branch (1233:7): [True: 0, False: 155]
  ------------------
 1234|      0|    xmpData_->erase(pos);
 1235|    155|}
_ZN5Exiv213copyXmpToExifERKNS_7XmpDataERNS_8ExifDataE:
 1330|  1.20k|void copyXmpToExif(const XmpData& xmpData, ExifData& exifData) {
 1331|  1.20k|  Converter converter(exifData, const_cast<XmpData&>(xmpData));
 1332|  1.20k|  converter.cnvFromXmp();
 1333|  1.20k|}
_ZN5Exiv213copyXmpToIptcERKNS_7XmpDataERNS_8IptcDataE:
 1368|  1.20k|void copyXmpToIptc(const XmpData& xmpData, IptcData& iptcData) {
 1369|  1.20k|  Converter converter(iptcData, const_cast<XmpData&>(xmpData));
 1370|  1.20k|  converter.cnvFromXmp();
 1371|  1.20k|}
_ZN5Exiv220convertStringCharsetERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPKcS9_:
 1380|    452|bool convertStringCharset([[maybe_unused]] std::string& str, const char* from, const char* to) {
 1381|    452|  if (0 == strcmp(from, to))
  ------------------
  |  Branch (1381:7): [True: 0, False: 452]
  ------------------
 1382|      0|    return true;  // nothing to do
 1383|    452|#ifdef EXV_HAVE_ICONV
 1384|    452|  return convertStringCharsetIconv(str, from, to);
 1385|       |#elif defined _WIN32
 1386|       |  return convertStringCharsetWindows(str, from, to);
 1387|       |#else
 1388|       |#ifndef SUPPRESS_WARNINGS
 1389|       |  EXV_WARNING << "Charset conversion required but no character mapping functionality available.\n";
 1390|       |#endif
 1391|       |  return false;
 1392|       |#endif
 1393|    452|}
convert.cpp:_ZN12_GLOBAL__N_125convertStringCharsetIconvERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_17basic_string_viewIcS3_EES9_:
 1402|    452|bool convertStringCharsetIconv(std::string& str, std::string_view from, std::string_view to) {
 1403|    452|  if (from == to)
  ------------------
  |  Branch (1403:7): [True: 0, False: 452]
  ------------------
 1404|      0|    return true;  // nothing to do
 1405|       |
 1406|    452|  bool ret = true;
 1407|    452|  auto cd = iconv_open(to.data(), from.data());
 1408|    452|  if (cd == iconv_t(-1)) {
  ------------------
  |  Branch (1408:7): [True: 0, False: 452]
  ------------------
 1409|      0|#ifndef SUPPRESS_WARNINGS
 1410|      0|    EXV_WARNING << "iconv_open: " << strError() << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1411|      0|#endif
 1412|      0|    return false;
 1413|      0|  }
 1414|    452|  std::string outstr;
 1415|       |#ifdef WINICONV_CONST
 1416|       |  auto inptr = (WINICONV_CONST char*)(str.c_str());
 1417|       |#else
 1418|    452|  auto inptr = (EXV_ICONV_CONST char*)(str.c_str());
 1419|    452|#endif
 1420|    452|  size_t inbytesleft = str.length();
 1421|  1.51k|  while (inbytesleft) {
  ------------------
  |  Branch (1421:10): [True: 1.28k, False: 227]
  ------------------
 1422|  1.28k|    char outbuf[256];
 1423|  1.28k|    char* outptr = outbuf;
 1424|  1.28k|    size_t outbytesleft = sizeof(outbuf);
 1425|  1.28k|    size_t rc = iconv(cd, &inptr, &inbytesleft, &outptr, &outbytesleft);
 1426|  1.28k|    const size_t outbytesProduced = sizeof(outbuf) - outbytesleft;
 1427|  1.28k|    if (rc == std::numeric_limits<size_t>::max() && errno != E2BIG) {
  ------------------
  |  Branch (1427:9): [True: 1.09k, False: 196]
  |  Branch (1427:53): [True: 225, False: 865]
  ------------------
 1428|    225|#ifndef SUPPRESS_WARNINGS
 1429|    225|      EXV_WARNING << "iconv: " << strError() << " inbytesleft = " << inbytesleft << "\n";
  ------------------
  |  |  138|    225|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 225]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    225|  LogMsg(LogMsg::warn).os()
  ------------------
 1430|    225|#endif
 1431|    225|      ret = false;
 1432|    225|      break;
 1433|    225|    }
 1434|  1.06k|    outstr.append(std::string(outbuf, outbytesProduced));
 1435|  1.06k|  }
 1436|       |
 1437|    452|  if (cd)
  ------------------
  |  Branch (1437:7): [True: 452, False: 0]
  ------------------
 1438|    452|    iconv_close(cd);
 1439|       |
 1440|    452|  if (ret)
  ------------------
  |  Branch (1440:7): [True: 227, False: 225]
  ------------------
 1441|    227|    str = std::move(outstr);
 1442|    452|  return ret;
 1443|    452|}
convert.cpp:_ZN12_GLOBAL__N_112getTextValueERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_11__wrap_iterIPN5Exiv28XmpdatumEEE:
 1592|    372|bool getTextValue(std::string& value, XmpData::iterator pos) {
 1593|    372|  if (pos->typeId() == langAlt) {
  ------------------
  |  Branch (1593:7): [True: 94, False: 278]
  ------------------
 1594|       |    // get the default language entry without x-default qualifier
 1595|     94|    value = pos->toString(0);
 1596|     94|    if (!pos->value().ok() && pos->count() == 1) {
  ------------------
  |  Branch (1596:9): [True: 63, False: 31]
  |  Branch (1596:31): [True: 42, False: 21]
  ------------------
 1597|       |      // If there is no default but exactly one entry, take that
 1598|       |      // without the qualifier
 1599|     42|      value = pos->toString();
 1600|     42|      if (pos->value().ok() && value.starts_with("lang=")) {
  ------------------
  |  Branch (1600:11): [True: 42, False: 0]
  |  Branch (1600:32): [True: 42, False: 0]
  ------------------
 1601|     42|        const std::string::size_type first_space_pos = value.find_first_of(' ');
 1602|     42|        if (first_space_pos != std::string::npos) {
  ------------------
  |  Branch (1602:13): [True: 42, False: 0]
  ------------------
 1603|     42|          value = value.substr(first_space_pos + 1);
 1604|     42|        } else {
 1605|      0|          value.clear();
 1606|      0|        }
 1607|     42|      }
 1608|     42|    }
 1609|    278|  } else {
 1610|    278|    value = pos->toString();
 1611|    278|  }
 1612|    372|  return pos->value().ok();
 1613|    372|}

_ZN5Exiv28Internal9Cr2HeaderC2ENS_9ByteOrderE:
   14|  31.9k|Cr2Header::Cr2Header(ByteOrder byteOrder) : TiffHeaderBase(42, 16, byteOrder, 0x00000010) {
   15|  31.9k|}
_ZN5Exiv28Internal9Cr2Header4readEPKhm:
   17|  31.9k|bool Cr2Header::read(const byte* pData, size_t size) {
   18|  31.9k|  if (!pData || size < 16) {
  ------------------
  |  Branch (18:7): [True: 0, False: 31.9k]
  |  Branch (18:17): [True: 0, False: 31.9k]
  ------------------
   19|      0|    return false;
   20|      0|  }
   21|       |
   22|  31.9k|  if (pData[0] == 'I' && pData[0] == pData[1]) {
  ------------------
  |  Branch (22:7): [True: 3.78k, False: 28.1k]
  |  Branch (22:26): [True: 3.76k, False: 27]
  ------------------
   23|  3.76k|    setByteOrder(littleEndian);
   24|  28.1k|  } else if (pData[0] == 'M' && pData[0] == pData[1]) {
  ------------------
  |  Branch (24:14): [True: 5.84k, False: 22.3k]
  |  Branch (24:33): [True: 5.80k, False: 39]
  ------------------
   25|  5.80k|    setByteOrder(bigEndian);
   26|  22.3k|  } else {
   27|  22.3k|    return false;
   28|  22.3k|  }
   29|  9.56k|  if (tag() != getUShort(pData + 2, byteOrder()))
  ------------------
  |  Branch (29:7): [True: 848, False: 8.72k]
  ------------------
   30|    848|    return false;
   31|  8.72k|  setOffset(getULong(pData + 4, byteOrder()));
   32|  8.72k|  if (0 != memcmp(pData + 8, cr2sig_.data(), 4))
  ------------------
  |  Branch (32:7): [True: 8.35k, False: 368]
  ------------------
   33|  8.35k|    return false;
   34|    368|  offset2_ = getULong(pData + 12, byteOrder());
   35|       |
   36|    368|  return true;
   37|  8.72k|}

_ZN5Exiv28Cr2ImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   24|     92|    Image(ImageType::cr2, mdExif | mdIptc | mdXmp, std::move(io)) {
   25|     92|}  // Cr2Image::Cr2Image
_ZNK5Exiv28Cr2Image8mimeTypeEv:
   27|    157|std::string Cr2Image::mimeType() const {
   28|    157|  return "image/x-canon-cr2";
   29|    157|}
_ZNK5Exiv28Cr2Image10pixelWidthEv:
   31|     12|uint32_t Cr2Image::pixelWidth() const {
   32|     12|  auto imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
   33|     12|  if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
  ------------------
  |  Branch (33:7): [True: 0, False: 12]
  |  Branch (33:7): [True: 0, False: 12]
  |  Branch (33:40): [True: 0, False: 0]
  ------------------
   34|      0|    return imageWidth->toUint32();
   35|      0|  }
   36|     12|  return 0;
   37|     12|}
_ZNK5Exiv28Cr2Image11pixelHeightEv:
   39|     12|uint32_t Cr2Image::pixelHeight() const {
   40|     12|  auto imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
   41|     12|  if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
  ------------------
  |  Branch (41:7): [True: 0, False: 12]
  |  Branch (41:7): [True: 0, False: 12]
  |  Branch (41:41): [True: 0, False: 0]
  ------------------
   42|      0|    return imageHeight->toUint32();
   43|      0|  }
   44|     12|  return 0;
   45|     12|}
_ZN5Exiv28Cr2Image12readMetadataEv:
   59|     92|void Cr2Image::readMetadata() {
   60|       |#ifdef EXIV2_DEBUG_MESSAGES
   61|       |  std::cerr << "Reading CR2 file " << io_->path() << "\n";
   62|       |#endif
   63|     92|  if (io_->open() != 0) {
  ------------------
  |  Branch (63:7): [True: 0, False: 92]
  ------------------
   64|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   65|      0|  }
   66|     92|  IoCloser closer(*io_);
   67|       |  // Ensure that this is the correct image type
   68|     92|  if (!isCr2Type(*io_, false)) {
  ------------------
  |  Branch (68:7): [True: 0, False: 92]
  ------------------
   69|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (69:9): [True: 0, False: 0]
  |  Branch (69:25): [True: 0, False: 0]
  ------------------
   70|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   71|      0|    throw Error(ErrorCode::kerNotAnImage, "CR2");
   72|      0|  }
   73|     92|  clearMetadata();
   74|     92|  ByteOrder bo = Cr2Parser::decode(exifData_, iptcData_, xmpData_, io_->mmap(), io_->size());
   75|     92|  setByteOrder(bo);
   76|     92|}  // Cr2Image::readMetadata
_ZN5Exiv29Cr2Parser6decodeERNS_8ExifDataERNS_8IptcDataERNS_7XmpDataEPKhm:
  102|     92|ByteOrder Cr2Parser::decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size) {
  103|     92|  Internal::Cr2Header cr2Header;
  104|     92|  return Internal::TiffParserWorker::decode(exifData, iptcData, xmpData, pData, size, Internal::Tag::root,
  105|     92|                                            Internal::TiffMapping::findDecoder, &cr2Header);
  106|     92|}
_ZN5Exiv214newCr2InstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  131|     92|Image::UniquePtr newCr2Instance(BasicIo::UniquePtr io, bool create) {
  132|     92|  auto image = std::make_unique<Cr2Image>(std::move(io), create);
  133|     92|  if (!image->good()) {
  ------------------
  |  Branch (133:7): [True: 0, False: 92]
  ------------------
  134|      0|    return nullptr;
  135|      0|  }
  136|     92|  return image;
  137|     92|}
_ZN5Exiv29isCr2TypeERNS_7BasicIoEb:
  139|  31.9k|bool isCr2Type(BasicIo& iIo, bool advance) {
  140|  31.9k|  const int32_t len = 16;
  141|  31.9k|  byte buf[len];
  142|  31.9k|  iIo.read(buf, len);
  143|  31.9k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (143:7): [True: 0, False: 31.9k]
  |  Branch (143:22): [True: 154, False: 31.8k]
  ------------------
  144|    154|    return false;
  145|    154|  }
  146|  31.8k|  Internal::Cr2Header header;
  147|  31.8k|  bool rc = header.read(buf, len);
  148|  31.8k|  if (!advance || !rc) {
  ------------------
  |  Branch (148:7): [True: 31.8k, False: 0]
  |  Branch (148:19): [True: 0, False: 0]
  ------------------
  149|  31.8k|    iIo.seek(-len, BasicIo::cur);
  150|  31.8k|  }
  151|  31.8k|  return rc;
  152|  31.9k|}

_ZN5Exiv28CrwImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   26|    570|CrwImage::CrwImage(BasicIo::UniquePtr io, bool /*create*/) : Image(ImageType::crw, mdExif | mdComment, std::move(io)) {
   27|    570|}  // CrwImage::CrwImage
_ZNK5Exiv28CrwImage8mimeTypeEv:
   29|    600|std::string CrwImage::mimeType() const {
   30|    600|  return "image/x-canon-crw";
   31|    600|}
_ZNK5Exiv28CrwImage10pixelWidthEv:
   33|     15|uint32_t CrwImage::pixelWidth() const {
   34|     15|  auto widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
   35|     15|  if (widthIter != exifData_.end() && widthIter->count() > 0) {
  ------------------
  |  Branch (35:7): [True: 0, False: 15]
  |  Branch (35:7): [True: 0, False: 15]
  |  Branch (35:39): [True: 0, False: 0]
  ------------------
   36|      0|    return widthIter->toUint32();
   37|      0|  }
   38|     15|  return 0;
   39|     15|}
_ZNK5Exiv28CrwImage11pixelHeightEv:
   41|     15|uint32_t CrwImage::pixelHeight() const {
   42|     15|  auto heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension"));
   43|     15|  if (heightIter != exifData_.end() && heightIter->count() > 0) {
  ------------------
  |  Branch (43:7): [True: 0, False: 15]
  |  Branch (43:7): [True: 0, False: 15]
  |  Branch (43:40): [True: 0, False: 0]
  ------------------
   44|      0|    return heightIter->toUint32();
   45|      0|  }
   46|     15|  return 0;
   47|     15|}
_ZN5Exiv28CrwImage12readMetadataEv:
   54|    570|void CrwImage::readMetadata() {
   55|       |#ifdef EXIV2_DEBUG_MESSAGES
   56|       |  std::cerr << "Reading CRW file " << io_->path() << "\n";
   57|       |#endif
   58|    570|  if (io_->open()) {
  ------------------
  |  Branch (58:7): [True: 0, False: 570]
  ------------------
   59|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   60|      0|  }
   61|    570|  IoCloser closer(*io_);
   62|       |  // Ensure that this is the correct image type
   63|    570|  if (!isCrwType(*io_, false)) {
  ------------------
  |  Branch (63:7): [True: 0, False: 570]
  ------------------
   64|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (64:9): [True: 0, False: 0]
  |  Branch (64:25): [True: 0, False: 0]
  ------------------
   65|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   66|      0|    throw Error(ErrorCode::kerNotACrwImage);
   67|      0|  }
   68|    570|  clearMetadata();
   69|    570|  DataBuf file(io().size());
   70|    570|  io_->read(file.data(), file.size());
   71|       |
   72|    570|  CrwParser::decode(this, io_->mmap(), io_->size());
   73|       |
   74|    570|}  // CrwImage::readMetadata
_ZN5Exiv29CrwParser6decodeEPNS_8CrwImageEPKhm:
  106|    570|void CrwParser::decode(CrwImage* pCrwImage, const byte* pData, size_t size) {
  107|       |  // Parse the image, starting with a CIFF header component
  108|    570|  Internal::CiffHeader header;
  109|    570|  header.read(pData, size);
  110|    570|  header.decode(*pCrwImage);
  111|       |
  112|       |  // a hack to get absolute offset of preview image inside CRW structure
  113|    570|  if (auto preview = header.findComponent(0x2007, 0x0000)) {
  ------------------
  |  Branch (113:12): [True: 3, False: 567]
  ------------------
  114|      3|    (pCrwImage->exifData())["Exif.Image2.JPEGInterchangeFormat"] = static_cast<uint32_t>(preview->pData() - pData);
  115|      3|    (pCrwImage->exifData())["Exif.Image2.JPEGInterchangeFormatLength"] = static_cast<uint32_t>(preview->size());
  116|      3|  }
  117|    570|}  // CrwParser::decode
_ZN5Exiv214newCrwInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  134|    570|Image::UniquePtr newCrwInstance(BasicIo::UniquePtr io, bool create) {
  135|    570|  auto image = std::make_unique<CrwImage>(std::move(io), create);
  136|    570|  if (!image->good()) {
  ------------------
  |  Branch (136:7): [True: 0, False: 570]
  ------------------
  137|      0|    return nullptr;
  138|      0|  }
  139|    570|  return image;
  140|    570|}
_ZN5Exiv29isCrwTypeERNS_7BasicIoEb:
  142|  32.8k|bool isCrwType(BasicIo& iIo, bool advance) {
  143|  32.8k|  bool result = true;
  144|  32.8k|  byte tmpBuf[14];
  145|  32.8k|  iIo.read(tmpBuf, 14);
  146|  32.8k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (146:7): [True: 0, False: 32.8k]
  |  Branch (146:22): [True: 154, False: 32.6k]
  ------------------
  147|    154|    return false;
  148|    154|  }
  149|  32.6k|  if (('I' != tmpBuf[0] || 'I' != tmpBuf[1]) && ('M' != tmpBuf[0] || 'M' != tmpBuf[1])) {
  ------------------
  |  Branch (149:8): [True: 28.3k, False: 4.39k]
  |  Branch (149:28): [True: 27, False: 4.36k]
  |  Branch (149:50): [True: 22.3k, False: 6.01k]
  |  Branch (149:70): [True: 39, False: 5.97k]
  ------------------
  150|  22.3k|    result = false;
  151|  22.3k|  }
  152|  32.6k|  if (result && std::memcmp(tmpBuf + 6, Internal::CiffHeader::signature(), 8) != 0) {
  ------------------
  |  Branch (152:7): [True: 10.3k, False: 22.3k]
  |  Branch (152:17): [True: 8.63k, False: 1.71k]
  ------------------
  153|  8.63k|    result = false;
  154|  8.63k|  }
  155|  32.6k|  if (!advance || !result)
  ------------------
  |  Branch (155:7): [True: 32.6k, False: 0]
  |  Branch (155:19): [True: 0, False: 0]
  ------------------
  156|  32.6k|    iIo.seek(-14, BasicIo::cur);
  157|  32.6k|  return result;
  158|  32.8k|}

_ZN5Exiv28Internal13CiffComponent3addENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE:
  126|  7.19k|const CiffComponent::UniquePtr& CiffComponent::add(UniquePtr component) {
  127|  7.19k|  return doAdd(std::move(component));
  128|  7.19k|}
_ZN5Exiv28Internal13CiffDirectory5doAddENSt3__110unique_ptrINS0_13CiffComponentENS2_14default_deleteIS4_EEEE:
  134|  7.19k|const CiffComponent::UniquePtr& CiffDirectory::doAdd(UniquePtr component) {
  135|  7.19k|  return components_.emplace_back(std::move(component));
  136|  7.19k|}  // CiffDirectory::doAdd
_ZN5Exiv28Internal10CiffHeader4readEPKhm:
  140|    570|void CiffHeader::read(const byte* pData, size_t size) {
  141|    570|  if (size < 14)
  ------------------
  |  Branch (141:7): [True: 0, False: 570]
  ------------------
  142|      0|    throw Error(ErrorCode::kerNotACrwImage);
  143|       |
  144|    570|  if (pData[0] == 'I' && pData[0] == pData[1]) {
  ------------------
  |  Branch (144:7): [True: 403, False: 167]
  |  Branch (144:26): [True: 403, False: 0]
  ------------------
  145|    403|    byteOrder_ = littleEndian;
  146|    403|  } else if (pData[0] == 'M' && pData[0] == pData[1]) {
  ------------------
  |  Branch (146:14): [True: 167, False: 0]
  |  Branch (146:33): [True: 167, False: 0]
  ------------------
  147|    167|    byteOrder_ = bigEndian;
  148|    167|  } else {
  149|      0|    throw Error(ErrorCode::kerNotACrwImage);
  150|      0|  }
  151|    570|  offset_ = getULong(pData + 2, byteOrder_);
  152|    570|  if (offset_ < 14 || offset_ > size)
  ------------------
  |  Branch (152:7): [True: 16, False: 554]
  |  Branch (152:23): [True: 58, False: 496]
  ------------------
  153|     74|    throw Error(ErrorCode::kerNotACrwImage);
  154|    496|  if (std::memcmp(pData + 6, signature(), 8) != 0) {
  ------------------
  |  Branch (154:7): [True: 0, False: 496]
  ------------------
  155|      0|    throw Error(ErrorCode::kerNotACrwImage);
  156|      0|  }
  157|       |
  158|    496|  pPadding_.clear();
  159|    496|  if (offset_ > 14) {
  ------------------
  |  Branch (159:7): [True: 408, False: 88]
  ------------------
  160|    408|    pPadding_.resize(offset_ - 14);
  161|    408|    padded_ = offset_ - 14;
  162|    408|    std::copy_n(pData + 14, padded_, pPadding_.begin());
  163|    408|  }
  164|       |
  165|    496|  pRootDir_ = std::make_unique<CiffDirectory>();
  166|    496|  pRootDir_->readDirectory(pData + offset_, size - offset_, byteOrder_);
  167|    496|}  // CiffHeader::read
_ZN5Exiv28Internal13CiffComponent4readEPKhmjNS_9ByteOrderE:
  169|  7.40k|void CiffComponent::read(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder) {
  170|  7.40k|  doRead(pData, size, start, byteOrder);
  171|  7.40k|}
_ZN5Exiv28Internal13CiffComponent6doReadEPKhmjNS_9ByteOrderE:
  173|  7.40k|void CiffComponent::doRead(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder) {
  174|       |  // We're going read 10 bytes. Make sure they won't be out-of-bounds.
  175|  7.40k|  enforce(size >= 10 && start <= size - 10, ErrorCode::kerNotACrwImage);
  ------------------
  |  Branch (175:11): [True: 7.40k, False: 0]
  |  Branch (175:25): [True: 7.40k, False: 0]
  ------------------
  176|  7.40k|  tag_ = getUShort(pData + start, byteOrder);
  177|       |
  178|  7.40k|  DataLocId dl = dataLocation();
  179|       |
  180|  7.40k|  if (dl == DataLocId::valueData) {
  ------------------
  |  Branch (180:7): [True: 2.53k, False: 4.87k]
  ------------------
  181|  2.53k|    size_ = getULong(pData + start + 2, byteOrder);
  182|  2.53k|    offset_ = getULong(pData + start + 6, byteOrder);
  183|       |
  184|       |    // Make sure that the sub-region does not overlap with the 10 bytes
  185|       |    // that we just read. (Otherwise a malicious file could cause an
  186|       |    // infinite recursion.) There are two cases two consider because
  187|       |    // the sub-region is allowed to be either before or after the 10
  188|       |    // bytes in memory.
  189|  2.53k|    if (offset_ < start) {
  ------------------
  |  Branch (189:9): [True: 2.33k, False: 194]
  ------------------
  190|       |      // Sub-region is before in memory.
  191|  2.33k|      enforce(size_ <= start - offset_, ErrorCode::kerOffsetOutOfRange);
  192|  2.33k|    } else {
  193|       |      // Sub-region is after in memory.
  194|    194|      enforce(offset_ >= start + 10, ErrorCode::kerOffsetOutOfRange);
  195|    194|      enforce(offset_ <= size, ErrorCode::kerOffsetOutOfRange);
  196|    194|      enforce(size_ <= size - offset_, ErrorCode::kerOffsetOutOfRange);
  197|    194|    }
  198|  2.53k|  }
  199|  7.40k|  if (dl == DataLocId::directoryData) {
  ------------------
  |  Branch (199:7): [True: 4.86k, False: 2.54k]
  ------------------
  200|  4.86k|    size_ = 8;
  201|  4.86k|    offset_ = start + 2;
  202|  4.86k|  }
  203|  7.40k|  pData_ = pData + offset_;
  204|       |#ifdef EXIV2_DEBUG_MESSAGES
  205|       |  std::cout << "  Entry for tag 0x" << std::hex << tagId() << " (0x" << tag() << "), " << std::dec << size_
  206|       |            << " Bytes, Offset is " << offset_ << "\n";
  207|       |#endif
  208|       |
  209|  7.40k|}  // CiffComponent::doRead
_ZN5Exiv28Internal13CiffDirectory6doReadEPKhmjNS_9ByteOrderE:
  211|    926|void CiffDirectory::doRead(const byte* pData, size_t size, uint32_t start, ByteOrder byteOrder) {
  212|    926|  CiffComponent::doRead(pData, size, start, byteOrder);
  213|       |#ifdef EXIV2_DEBUG_MESSAGES
  214|       |  std::cout << "Reading directory 0x" << std::hex << tag() << "\n";
  215|       |#endif
  216|    926|  if (this->offset() + this->size() > size)
  ------------------
  |  Branch (216:7): [True: 0, False: 926]
  ------------------
  217|      0|    throw Error(ErrorCode::kerOffsetOutOfRange);
  218|       |
  219|    926|  readDirectory(pData + offset(), this->size(), byteOrder);
  220|       |#ifdef EXIV2_DEBUG_MESSAGES
  221|       |  std::cout << "<---- 0x" << std::hex << tag() << "\n";
  222|       |#endif
  223|    926|}  // CiffDirectory::doRead
_ZN5Exiv28Internal13CiffDirectory13readDirectoryEPKhmNS_9ByteOrderE:
  225|  1.39k|void CiffDirectory::readDirectory(const byte* pData, size_t size, ByteOrder byteOrder) {
  226|  1.39k|  if (size < 4)
  ------------------
  |  Branch (226:7): [True: 14, False: 1.37k]
  ------------------
  227|     14|    throw Error(ErrorCode::kerCorruptedMetadata);
  228|  1.37k|  uint32_t o = getULong(pData + size - 4, byteOrder);
  229|  1.37k|  if (o > size - 2)
  ------------------
  |  Branch (229:7): [True: 49, False: 1.33k]
  ------------------
  230|     49|    throw Error(ErrorCode::kerCorruptedMetadata);
  231|  1.33k|  uint16_t count = getUShort(pData + o, byteOrder);
  232|       |#ifdef EXIV2_DEBUG_MESSAGES
  233|       |  std::cout << "Directory at offset " << std::dec << o << ", " << count << " entries \n";
  234|       |#endif
  235|  1.33k|  o += 2;
  236|  1.33k|  if (count * 10u > size - o)
  ------------------
  |  Branch (236:7): [True: 23, False: 1.30k]
  ------------------
  237|     23|    throw Error(ErrorCode::kerCorruptedMetadata);
  238|       |
  239|  8.71k|  for (uint16_t i = 0; i < count; ++i) {
  ------------------
  |  Branch (239:24): [True: 7.40k, False: 1.30k]
  ------------------
  240|  7.40k|    uint16_t tag = getUShort(pData + o, byteOrder);
  241|  7.40k|    auto m = [this, tag]() -> UniquePtr {
  242|  7.40k|      if (this->typeId(tag) == TypeId::directory)
  243|  7.40k|        return std::make_unique<CiffDirectory>();
  244|  7.40k|      return std::make_unique<CiffEntry>();
  245|  7.40k|    }();
  246|  7.40k|    m->setDir(this->tag());
  247|  7.40k|    m->read(pData, size, o, byteOrder);
  248|  7.40k|    add(std::move(m));
  249|  7.40k|    o += 10;
  250|  7.40k|  }
  251|  1.30k|}  // CiffDirectory::readDirectory
_ZNK5Exiv28Internal10CiffHeader6decodeERNS_5ImageE:
  253|    215|void CiffHeader::decode(Image& image) const {
  254|       |  // Nothing to decode from the header itself, just add correct byte order
  255|    215|  if (pRootDir_)
  ------------------
  |  Branch (255:7): [True: 215, False: 0]
  ------------------
  256|    215|    pRootDir_->decode(image, byteOrder_);
  257|    215|}
_ZNK5Exiv28Internal13CiffComponent6decodeERNS_5ImageENS_9ByteOrderE:
  259|  6.06k|void CiffComponent::decode(Image& image, ByteOrder byteOrder) const {
  260|  6.06k|  doDecode(image, byteOrder);
  261|  6.06k|}
_ZNK5Exiv28Internal9CiffEntry8doDecodeERNS_5ImageENS_9ByteOrderE:
  263|  4.97k|void CiffEntry::doDecode(Image& image, ByteOrder byteOrder) const {
  264|  4.97k|  CrwMap::decode(*this, image, byteOrder);
  265|  4.97k|}  // CiffEntry::doDecode
_ZNK5Exiv28Internal13CiffDirectory8doDecodeERNS_5ImageENS_9ByteOrderE:
  267|  1.09k|void CiffDirectory::doDecode(Image& image, ByteOrder byteOrder) const {
  268|  5.85k|  for (auto&& component : components_) {
  ------------------
  |  Branch (268:25): [True: 5.85k, False: 1.09k]
  ------------------
  269|  5.85k|    component->decode(image, byteOrder);
  270|  5.85k|  }
  271|  1.09k|}  // CiffDirectory::doDecode
_ZN5Exiv28Internal13CiffComponent6typeIdEt:
  435|  8.32k|TypeId CiffComponent::typeId(uint16_t tag) {
  436|  8.32k|  switch (tag & 0x3800) {
  ------------------
  |  Branch (436:11): [True: 8.29k, False: 33]
  ------------------
  437|  2.01k|    case 0x0000:
  ------------------
  |  Branch (437:5): [True: 2.01k, False: 6.31k]
  ------------------
  438|  2.01k|      return unsignedByte;
  439|    827|    case 0x0800:
  ------------------
  |  Branch (439:5): [True: 827, False: 7.50k]
  ------------------
  440|    827|      return asciiString;
  441|  2.19k|    case 0x1000:
  ------------------
  |  Branch (441:5): [True: 2.19k, False: 6.12k]
  ------------------
  442|  2.19k|      return unsignedShort;
  443|    594|    case 0x1800:
  ------------------
  |  Branch (443:5): [True: 594, False: 7.73k]
  ------------------
  444|    594|      return unsignedLong;
  445|  1.73k|    case 0x2000:
  ------------------
  |  Branch (445:5): [True: 1.73k, False: 6.59k]
  ------------------
  446|  1.73k|      return undefined;
  447|    166|    case 0x2800:
  ------------------
  |  Branch (447:5): [True: 166, False: 8.16k]
  ------------------
  448|    926|    case 0x3000:
  ------------------
  |  Branch (448:5): [True: 760, False: 7.56k]
  ------------------
  449|    926|      return directory;
  450|  8.32k|  }
  451|     33|  return invalidTypeId;
  452|  8.32k|}  // CiffComponent::typeId
_ZN5Exiv28Internal13CiffComponent12dataLocationEt:
  454|  7.40k|DataLocId CiffComponent::dataLocation(uint16_t tag) {
  455|  7.40k|  switch (tag & 0xc000) {
  456|  2.53k|    case 0x0000:
  ------------------
  |  Branch (456:5): [True: 2.53k, False: 4.87k]
  ------------------
  457|  2.53k|      return DataLocId::valueData;
  458|  4.86k|    case 0x4000:
  ------------------
  |  Branch (458:5): [True: 4.86k, False: 2.54k]
  ------------------
  459|  4.86k|      return DataLocId::directoryData;
  460|     13|    default:
  ------------------
  |  Branch (460:5): [True: 13, False: 7.39k]
  ------------------
  461|     13|      throw Error(ErrorCode::kerCorruptedMetadata);
  462|  7.40k|  }
  463|  7.40k|}  // CiffComponent::dataLocation
_ZNK5Exiv28Internal10CiffHeader13findComponentEtt:
  470|    215|CiffComponent* CiffHeader::findComponent(uint16_t crwTagId, uint16_t crwDir) const {
  471|    215|  if (!pRootDir_)
  ------------------
  |  Branch (471:7): [True: 0, False: 215]
  ------------------
  472|      0|    return nullptr;
  473|    215|  return pRootDir_->findComponent(crwTagId, crwDir);
  474|    215|}  // CiffHeader::findComponent
_ZN5Exiv28Internal13CiffComponent13findComponentEtt:
  476|  6.06k|CiffComponent* CiffComponent::findComponent(uint16_t crwTagId, uint16_t crwDir) {
  477|  6.06k|  return doFindComponent(crwTagId, crwDir);
  478|  6.06k|}  // CiffComponent::findComponent
_ZN5Exiv28Internal13CiffComponent15doFindComponentEtt:
  480|  4.97k|CiffComponent* CiffComponent::doFindComponent(uint16_t crwTagId, uint16_t crwDir) {
  481|  4.97k|  if (tagId() == crwTagId && dir() == crwDir) {
  ------------------
  |  Branch (481:7): [True: 16, False: 4.95k]
  |  Branch (481:30): [True: 3, False: 13]
  ------------------
  482|      3|    return this;
  483|      3|  }
  484|  4.97k|  return nullptr;
  485|  4.97k|}  // CiffComponent::doFindComponent
_ZN5Exiv28Internal13CiffDirectory15doFindComponentEtt:
  487|  1.09k|CiffComponent* CiffDirectory::doFindComponent(uint16_t crwTagId, uint16_t crwDir) {
  488|  5.85k|  for (auto&& component : components_) {
  ------------------
  |  Branch (488:25): [True: 5.85k, False: 1.08k]
  ------------------
  489|  5.85k|    if (auto cc = component->findComponent(crwTagId, crwDir))
  ------------------
  |  Branch (489:14): [True: 3, False: 5.84k]
  ------------------
  490|      3|      return cc;
  491|  5.85k|  }
  492|  1.08k|  return nullptr;
  493|  1.09k|}  // CiffDirectory::doFindComponent
_ZN5Exiv28Internal6CrwMap6decodeERKNS0_13CiffComponentERNS_5ImageENS_9ByteOrderE:
  604|  4.97k|void CrwMap::decode(const CiffComponent& ciffComponent, Image& image, ByteOrder byteOrder) {
  605|  4.97k|  const CrwMapping* cmi = crwMapping(ciffComponent.dir(), ciffComponent.tagId());
  606|  4.97k|  if (cmi && cmi->toExif_) {
  ------------------
  |  Branch (606:7): [True: 379, False: 4.59k]
  |  Branch (606:14): [True: 379, False: 0]
  ------------------
  607|    379|    cmi->toExif_(ciffComponent, cmi, image, byteOrder);
  608|    379|  }
  609|  4.97k|}  // CrwMap::decode
_ZN5Exiv28Internal6CrwMap10crwMappingEtt:
  611|  4.97k|const CrwMapping* CrwMap::crwMapping(uint16_t crwDir, uint16_t crwTagId) {
  612|   105k|  for (auto&& crw : crwMapping_) {
  ------------------
  |  Branch (612:19): [True: 105k, False: 4.59k]
  ------------------
  613|   105k|    if (crw.crwDir_ == crwDir && crw.crwTagId_ == crwTagId) {
  ------------------
  |  Branch (613:9): [True: 9.52k, False: 95.4k]
  |  Branch (613:34): [True: 379, False: 9.14k]
  ------------------
  614|    379|      return &crw;
  615|    379|    }
  616|   105k|  }
  617|  4.59k|  return nullptr;
  618|  4.97k|}  // CrwMap::crwMapping
_ZN5Exiv28Internal6CrwMap12decode0x0805ERKNS0_13CiffComponentEPKNS0_10CrwMappingERNS_5ImageENS_9ByteOrderE:
  621|     13|                          ByteOrder /*byteOrder*/) {
  622|     13|  auto s = std::string(reinterpret_cast<const char*>(ciffComponent.pData()), ciffComponent.size());
  623|     13|  image.setComment(s);
  624|     13|}  // CrwMap::decode0x0805
_ZN5Exiv28Internal6CrwMap12decode0x080aERKNS0_13CiffComponentEPKNS0_10CrwMappingERNS_5ImageENS_9ByteOrderE:
  627|     50|                          ByteOrder byteOrder) {
  628|     50|  if (ciffComponent.typeId() != asciiString)
  ------------------
  |  Branch (628:7): [True: 0, False: 50]
  ------------------
  629|      0|    return;
  630|       |
  631|       |  // Make
  632|     50|  ExifKey key1("Exif.Image.Make");
  633|     50|  auto value1 = Value::create(ciffComponent.typeId());
  634|     50|  uint32_t i = 0;
  635|    306|  while (i < ciffComponent.size()) {
  ------------------
  |  Branch (635:10): [True: 285, False: 21]
  ------------------
  636|    285|    ++i;
  637|    285|    if (ciffComponent.pData()[i - 1] == '\0') {
  ------------------
  |  Branch (637:9): [True: 29, False: 256]
  ------------------
  638|     29|      break;
  639|     29|    }
  640|    285|  }
  641|     50|  value1->read(ciffComponent.pData(), i, byteOrder);
  642|     50|  image.exifData().add(key1, value1.get());
  643|       |
  644|       |  // Model
  645|     50|  ExifKey key2("Exif.Image.Model");
  646|     50|  auto value2 = Value::create(ciffComponent.typeId());
  647|     50|  uint32_t j = i;
  648|     97|  while (i < ciffComponent.size()) {
  ------------------
  |  Branch (648:10): [True: 70, False: 27]
  ------------------
  649|     70|    ++i;
  650|     70|    if (ciffComponent.pData()[i - 1] == '\0') {
  ------------------
  |  Branch (650:9): [True: 23, False: 47]
  ------------------
  651|     23|      break;
  652|     23|    }
  653|     70|  }
  654|     50|  value2->read(ciffComponent.pData() + j, i - j, byteOrder);
  655|     50|  image.exifData().add(key2, value2.get());
  656|     50|}  // CrwMap::decode0x080a
_ZN5Exiv28Internal6CrwMap11decodeArrayERKNS0_13CiffComponentEPKNS0_10CrwMappingERNS_5ImageENS_9ByteOrderE:
  659|     43|                         ByteOrder byteOrder) {
  660|     43|  if (ciffComponent.typeId() != unsignedShort) {
  ------------------
  |  Branch (660:7): [True: 0, False: 43]
  ------------------
  661|      0|    decodeBasic(ciffComponent, pCrwMapping, image, byteOrder);
  662|      0|    return;
  663|      0|  }
  664|       |
  665|     43|  int64_t aperture = 0;
  666|     43|  int64_t shutterSpeed = 0;
  667|       |
  668|     43|  auto ifdId = [pCrwMapping] {
  669|     43|    if (pCrwMapping->tag_ == 0x0001)
  670|     43|      return IfdId::canonCsId;
  671|     43|    if (pCrwMapping->tag_ == 0x0004)
  672|     43|      return IfdId::canonSiId;
  673|     43|    if (pCrwMapping->tag_ == 0x000f)
  674|     43|      return IfdId::canonCfId;
  675|     43|    if (pCrwMapping->tag_ == 0x0012)
  676|     43|      return IfdId::canonPiId;
  677|     43|    return IfdId::ifdIdNotSet;
  678|     43|  }();
  679|       |
  680|     43|  std::string groupName(Internal::groupName(ifdId));
  681|     43|  const size_t component_size = ciffComponent.size();
  682|     43|  enforce(component_size % 2 == 0, ErrorCode::kerCorruptedMetadata);
  683|     43|  enforce(component_size / 2 <= static_cast<size_t>(std::numeric_limits<uint16_t>::max()),
  684|     43|          ErrorCode::kerCorruptedMetadata);
  685|     43|  const auto num_components = static_cast<uint16_t>(component_size / 2);
  686|     43|  uint16_t c = 1;
  687|    172|  while (c < num_components) {
  ------------------
  |  Branch (687:10): [True: 129, False: 43]
  ------------------
  688|    129|    uint16_t n = 1;
  689|    129|    ExifKey key(c, groupName);
  690|    129|    UShortValue value;
  691|    129|    if (ifdId == IfdId::canonCsId && c == 23 && component_size >= 52)
  ------------------
  |  Branch (691:9): [True: 30, False: 99]
  |  Branch (691:38): [True: 0, False: 30]
  |  Branch (691:49): [True: 0, False: 0]
  ------------------
  692|      0|      n = 3;
  693|    129|    value.read(ciffComponent.pData() + (c * 2), n * 2, byteOrder);
  694|    129|    image.exifData().add(key, &value);
  695|    129|    if (ifdId == IfdId::canonSiId && c == 21)
  ------------------
  |  Branch (695:9): [True: 33, False: 96]
  |  Branch (695:38): [True: 0, False: 33]
  ------------------
  696|      0|      aperture = value.toInt64();
  697|    129|    if (ifdId == IfdId::canonSiId && c == 22)
  ------------------
  |  Branch (697:9): [True: 33, False: 96]
  |  Branch (697:38): [True: 0, False: 33]
  ------------------
  698|      0|      shutterSpeed = value.toInt64();
  699|    129|    c += n;
  700|    129|  }
  701|       |
  702|     43|  if (ifdId == IfdId::canonSiId) {
  ------------------
  |  Branch (702:7): [True: 11, False: 32]
  ------------------
  703|       |    // Exif.Photo.FNumber
  704|     11|    float f = fnumber(canonEv(aperture));
  705|     11|    auto [r, s] = floatToRationalCast(f);
  706|     11|    auto ur = URational(r, s);
  707|     11|    URationalValue fn;
  708|     11|    fn.value_.push_back(ur);
  709|     11|    image.exifData().add(ExifKey("Exif.Photo.FNumber"), &fn);
  710|       |
  711|       |    // Exif.Photo.ExposureTime
  712|     11|    ur = exposureTime(canonEv(shutterSpeed));
  713|     11|    URationalValue et;
  714|     11|    et.value_.push_back(ur);
  715|     11|    image.exifData().add(ExifKey("Exif.Photo.ExposureTime"), &et);
  716|     11|  }
  717|     43|}  // CrwMap::decodeArray
_ZN5Exiv28Internal6CrwMap12decode0x180eERKNS0_13CiffComponentEPKNS0_10CrwMappingERNS_5ImageENS_9ByteOrderE:
  720|     18|                          ByteOrder byteOrder) {
  721|     18|  if (ciffComponent.size() < 8 || ciffComponent.typeId() != unsignedLong) {
  ------------------
  |  Branch (721:7): [True: 0, False: 18]
  |  Branch (721:35): [True: 0, False: 18]
  ------------------
  722|      0|    decodeBasic(ciffComponent, pCrwMapping, image, byteOrder);
  723|      0|    return;
  724|      0|  }
  725|     18|  ULongValue v;
  726|     18|  v.read(ciffComponent.pData(), 8, byteOrder);
  727|     18|  time_t t = v.value_.at(0);
  728|     18|  std::tm r;
  729|       |#ifdef _WIN32
  730|       |  auto tm = localtime_s(&r, &t) ? nullptr : &r;
  731|       |#else
  732|     18|  auto tm = localtime_r(&t, &r);
  733|     18|#endif
  734|     18|  if (!tm)
  ------------------
  |  Branch (734:7): [True: 0, False: 18]
  ------------------
  735|      0|    return;
  736|     18|  const size_t m = 20;
  737|     18|  char s[m];
  738|     18|  std::strftime(s, m, "%Y:%m:%d %T", tm);
  739|       |
  740|     18|  ExifKey key(pCrwMapping->tag_, Internal::groupName(pCrwMapping->ifdId_));
  741|     18|  AsciiValue value;
  742|     18|  value.read(s);
  743|     18|  image.exifData().add(key, &value);
  744|     18|}  // CrwMap::decode0x180e
_ZN5Exiv28Internal6CrwMap12decode0x1810ERKNS0_13CiffComponentEPKNS0_10CrwMappingERNS_5ImageENS_9ByteOrderE:
  747|     21|                          ByteOrder byteOrder) {
  748|     21|  if (ciffComponent.typeId() != unsignedLong || ciffComponent.size() < 28) {
  ------------------
  |  Branch (748:7): [True: 0, False: 21]
  |  Branch (748:49): [True: 21, False: 0]
  ------------------
  749|     21|    decodeBasic(ciffComponent, pCrwMapping, image, byteOrder);
  750|     21|    return;
  751|     21|  }
  752|       |
  753|      0|  ExifKey key1("Exif.Photo.PixelXDimension");
  754|      0|  ULongValue value1;
  755|      0|  value1.read(ciffComponent.pData(), 4, byteOrder);
  756|      0|  image.exifData().add(key1, &value1);
  757|       |
  758|      0|  ExifKey key2("Exif.Photo.PixelYDimension");
  759|      0|  ULongValue value2;
  760|      0|  value2.read(ciffComponent.pData() + 4, 4, byteOrder);
  761|      0|  image.exifData().add(key2, &value2);
  762|       |
  763|      0|  int32_t r = getLong(ciffComponent.pData() + 12, byteOrder);
  764|      0|  uint16_t o = RotationMap::orientation(r);
  765|      0|  image.exifData()["Exif.Image.Orientation"] = o;
  766|       |
  767|      0|}  // CrwMap::decode0x1810
_ZN5Exiv28Internal6CrwMap12decode0x2008ERKNS0_13CiffComponentEPKNS0_10CrwMappingERNS_5ImageENS_9ByteOrderE:
  770|     19|                          ByteOrder /*byteOrder*/) {
  771|     19|  ExifThumb exifThumb(image.exifData());
  772|     19|  exifThumb.setJpegThumbnail(ciffComponent.pData(), ciffComponent.size());
  773|     19|}  // CrwMap::decode0x2008
_ZN5Exiv28Internal6CrwMap11decodeBasicERKNS0_13CiffComponentEPKNS0_10CrwMappingERNS_5ImageENS_9ByteOrderE:
  776|    236|                         ByteOrder byteOrder) {
  777|       |  // create a key and value pair
  778|    236|  ExifKey key(pCrwMapping->tag_, Internal::groupName(pCrwMapping->ifdId_));
  779|    236|  Value::UniquePtr value;
  780|    236|  if (ciffComponent.typeId() != directory) {
  ------------------
  |  Branch (780:7): [True: 236, False: 0]
  ------------------
  781|    236|    value = Value::create(ciffComponent.typeId());
  782|    236|    size_t size = 0;
  783|    236|    if (pCrwMapping->size_ != 0) {
  ------------------
  |  Branch (783:9): [True: 18, False: 218]
  ------------------
  784|     18|      size = pCrwMapping->size_;  // size in the mapping table overrides all
  785|    218|    } else if (ciffComponent.typeId() == asciiString) {
  ------------------
  |  Branch (785:16): [True: 84, False: 134]
  ------------------
  786|       |      // determine size from the data, by looking for the first 0
  787|     84|      uint32_t i = 0;
  788|    460|      while (i < ciffComponent.size()) {
  ------------------
  |  Branch (788:14): [True: 427, False: 33]
  ------------------
  789|    427|        ++i;
  790|    427|        if (ciffComponent.pData()[i - 1] == '\0') {
  ------------------
  |  Branch (790:13): [True: 51, False: 376]
  ------------------
  791|     51|          break;
  792|     51|        }
  793|    427|      }
  794|     84|      size = i;
  795|    134|    } else {
  796|       |      // by default, use the size from the directory entry
  797|    134|      size = ciffComponent.size();
  798|    134|    }
  799|    236|    value->read(ciffComponent.pData(), size, byteOrder);
  800|    236|  }
  801|       |  // Add metadatum to exif data
  802|    236|  image.exifData().add(key, value.get());
  803|    236|}  // CrwMap::decodeBasic
crwimage_int.cpp:_ZZN5Exiv28Internal13CiffDirectory13readDirectoryEPKhmNS_9ByteOrderEENK3$_0clEv:
  241|  7.40k|    auto m = [this, tag]() -> UniquePtr {
  242|  7.40k|      if (this->typeId(tag) == TypeId::directory)
  ------------------
  |  Branch (242:11): [True: 926, False: 6.47k]
  ------------------
  243|    926|        return std::make_unique<CiffDirectory>();
  244|  6.47k|      return std::make_unique<CiffEntry>();
  245|  7.40k|    }();
crwimage_int.cpp:_ZZN5Exiv28Internal6CrwMap11decodeArrayERKNS0_13CiffComponentEPKNS0_10CrwMappingERNS_5ImageENS_9ByteOrderEENK3$_0clEv:
  668|     43|  auto ifdId = [pCrwMapping] {
  669|     43|    if (pCrwMapping->tag_ == 0x0001)
  ------------------
  |  Branch (669:9): [True: 10, False: 33]
  ------------------
  670|     10|      return IfdId::canonCsId;
  671|     33|    if (pCrwMapping->tag_ == 0x0004)
  ------------------
  |  Branch (671:9): [True: 11, False: 22]
  ------------------
  672|     11|      return IfdId::canonSiId;
  673|     22|    if (pCrwMapping->tag_ == 0x000f)
  ------------------
  |  Branch (673:9): [True: 10, False: 12]
  ------------------
  674|     10|      return IfdId::canonCfId;
  675|     12|    if (pCrwMapping->tag_ == 0x0012)
  ------------------
  |  Branch (675:9): [True: 12, False: 0]
  ------------------
  676|     12|      return IfdId::canonPiId;
  677|      0|    return IfdId::ifdIdNotSet;
  678|     12|  }();

_ZNK5Exiv28Internal13CiffComponent5pDataEv:
  213|  1.30k|  [[nodiscard]] const byte* pData() const {
  214|  1.30k|    return pData_;
  215|  1.30k|  }
_ZNK5Exiv28Internal13CiffComponent4sizeEv:
  203|  2.90k|  [[nodiscard]] size_t size() const {
  204|  2.90k|    return size_;
  205|  2.90k|  }
_ZN5Exiv28Internal10CiffHeader9signatureEv:
  418|  10.8k|  static auto signature() {
  419|  10.8k|    return signature_;
  420|  10.8k|  }
_ZN5Exiv28Internal13CiffComponent6setDirEt:
  146|  7.40k|  void setDir(uint16_t dir) {
  147|  7.40k|    dir_ = dir;
  148|  7.40k|  }
_ZNK5Exiv28Internal13CiffComponent3dirEv:
  183|  4.99k|  [[nodiscard]] uint16_t dir() const {
  184|  4.99k|    return dir_;
  185|  4.99k|  }
_ZNK5Exiv28Internal13CiffComponent3tagEv:
  188|  7.40k|  [[nodiscard]] uint16_t tag() const {
  189|  7.40k|    return tag_;
  190|  7.40k|  }
_ZNK5Exiv28Internal13CiffComponent6offsetEv:
  208|  1.79k|  [[nodiscard]] size_t offset() const {
  209|  1.79k|    return offset_;
  210|  1.79k|  }
_ZNK5Exiv28Internal13CiffComponent5tagIdEv:
  218|  9.94k|  [[nodiscard]] uint16_t tagId() const {
  219|  9.94k|    return tag_ & 0x3fff;
  220|  9.94k|  }
_ZNK5Exiv28Internal13CiffComponent6typeIdEv:
  223|    922|  [[nodiscard]] TypeId typeId() const {
  224|    922|    return typeId(tag_);
  225|    922|  }
_ZNK5Exiv28Internal13CiffComponent12dataLocationEv:
  228|  7.40k|  [[nodiscard]] DataLocId dataLocation() const {
  229|  7.40k|    return dataLocation(tag_);
  230|  7.40k|  }
_ZN5Exiv28Internal13CiffComponentC2Ev:
   71|  7.90k|  CiffComponent() = default;
_ZN5Exiv28Internal13CiffComponentD2Ev:
   75|  7.90k|  virtual ~CiffComponent() = default;

_ZN5Exiv212IptcDataSets10dataSetIdxEtt:
  377|  94.0k|int IptcDataSets::dataSetIdx(uint16_t number, uint16_t recordId) {
  378|  94.0k|  if (recordId != envelope && recordId != application2)
  ------------------
  |  Branch (378:7): [True: 50.6k, False: 43.3k]
  |  Branch (378:31): [True: 13.6k, False: 37.0k]
  ------------------
  379|  13.6k|    return -1;
  380|  80.4k|  const DataSet* dataSet = records_[recordId];
  381|  80.4k|  int idx;
  382|  1.26M|  for (idx = 0; dataSet[idx].number_ != number; ++idx) {
  ------------------
  |  Branch (382:17): [True: 1.19M, False: 65.7k]
  ------------------
  383|  1.19M|    if (dataSet[idx].number_ == 0xffff)
  ------------------
  |  Branch (383:9): [True: 14.6k, False: 1.18M]
  ------------------
  384|  14.6k|      return -1;
  385|  1.19M|  }
  386|  65.7k|  return idx;
  387|  80.4k|}
_ZN5Exiv212IptcDataSets10dataSetIdxERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEt:
  389|  3.57k|int IptcDataSets::dataSetIdx(const std::string& dataSetName, uint16_t recordId) {
  390|  3.57k|  if (recordId != envelope && recordId != application2)
  ------------------
  |  Branch (390:7): [True: 3.27k, False: 301]
  |  Branch (390:31): [True: 0, False: 3.27k]
  ------------------
  391|      0|    return -1;
  392|  3.57k|  const DataSet* dataSet = records_[recordId];
  393|  3.57k|  int idx;
  394|  98.5k|  for (idx = 0; dataSet[idx].name_ != dataSetName; ++idx) {
  ------------------
  |  Branch (394:17): [True: 94.9k, False: 3.57k]
  ------------------
  395|  94.9k|    if (dataSet[idx].number_ == 0xffff)
  ------------------
  |  Branch (395:9): [True: 0, False: 94.9k]
  ------------------
  396|      0|      return -1;
  397|  94.9k|  }
  398|  3.57k|  return idx;
  399|  3.57k|}
_ZN5Exiv212IptcDataSets11dataSetTypeEtt:
  401|  31.3k|TypeId IptcDataSets::dataSetType(uint16_t number, uint16_t recordId) {
  402|  31.3k|  int idx = dataSetIdx(number, recordId);
  403|  31.3k|  if (idx == -1)
  ------------------
  |  Branch (403:7): [True: 9.43k, False: 21.9k]
  ------------------
  404|  9.43k|    return unknownDataSet.type_;
  405|  21.9k|  return records_[recordId][idx].type_;
  406|  31.3k|}
_ZN5Exiv212IptcDataSets11dataSetNameEtt:
  408|  31.7k|std::string IptcDataSets::dataSetName(uint16_t number, uint16_t recordId) {
  409|  31.7k|  if (int idx = dataSetIdx(number, recordId); idx != -1)
  ------------------
  |  Branch (409:47): [True: 22.3k, False: 9.43k]
  ------------------
  410|  22.3k|    return records_[recordId][idx].name_;
  411|       |
  412|  9.43k|  return stringFormat("0x{:04x}", number);
  ------------------
  |  |   18|  9.43k|#define stringFormat std::format
  ------------------
  413|  31.7k|}
_ZN5Exiv212IptcDataSets17dataSetRepeatableEtt:
  436|  30.9k|bool IptcDataSets::dataSetRepeatable(uint16_t number, uint16_t recordId) {
  437|  30.9k|  int idx = dataSetIdx(number, recordId);
  438|  30.9k|  if (idx == -1)
  ------------------
  |  Branch (438:7): [True: 9.43k, False: 21.5k]
  ------------------
  439|  9.43k|    return unknownDataSet.repeatable_;
  440|  21.5k|  return records_[recordId][idx].repeatable_;
  441|  30.9k|}
_ZN5Exiv212IptcDataSets7dataSetERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEt:
  443|  3.57k|uint16_t IptcDataSets::dataSet(const std::string& dataSetName, uint16_t recordId) {
  444|  3.57k|  if (int idx = dataSetIdx(dataSetName, recordId); idx != -1) {
  ------------------
  |  Branch (444:52): [True: 3.57k, False: 0]
  ------------------
  445|       |    // dataSetIdx checks the range of recordId
  446|  3.57k|    return records_[recordId][idx].number_;
  447|  3.57k|  }
  448|      0|  if (!isHex(dataSetName, 4, "0x"))
  ------------------
  |  Branch (448:7): [True: 0, False: 0]
  ------------------
  449|      0|    throw Error(ErrorCode::kerInvalidDataset, dataSetName);
  450|      0|  return static_cast<uint16_t>(std::stoi(dataSetName, nullptr, 16));
  451|      0|}
_ZN5Exiv212IptcDataSets10recordNameEt:
  453|  31.7k|std::string IptcDataSets::recordName(uint16_t recordId) {
  454|  31.7k|  if (recordId == envelope || recordId == application2) {
  ------------------
  |  Branch (454:7): [True: 14.5k, False: 17.1k]
  |  Branch (454:31): [True: 12.6k, False: 4.54k]
  ------------------
  455|  27.1k|    return recordInfo_[recordId].name_;
  456|  27.1k|  }
  457|       |
  458|  4.54k|  return stringFormat("0x{:04x}", recordId);
  ------------------
  |  |   18|  4.54k|#define stringFormat std::format
  ------------------
  459|  31.7k|}
_ZN5Exiv212IptcDataSets8recordIdERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  468|  3.57k|uint16_t IptcDataSets::recordId(const std::string& recordName) {
  469|  3.57k|  uint16_t i;
  470|  3.88k|  for (i = IptcDataSets::application2; i > 0; --i) {
  ------------------
  |  Branch (470:40): [True: 3.88k, False: 0]
  ------------------
  471|  3.88k|    if (recordInfo_[i].name_ == recordName)
  ------------------
  |  Branch (471:9): [True: 3.57k, False: 301]
  ------------------
  472|  3.57k|      break;
  473|  3.88k|  }
  474|  3.57k|  if (i == 0) {
  ------------------
  |  Branch (474:7): [True: 0, False: 3.57k]
  ------------------
  475|      0|    if (!isHex(recordName, 4, "0x"))
  ------------------
  |  Branch (475:9): [True: 0, False: 0]
  ------------------
  476|      0|      throw Error(ErrorCode::kerInvalidRecord, recordName);
  477|      0|    i = static_cast<uint16_t>(std::stoi(recordName, nullptr, 16));
  478|      0|  }
  479|  3.57k|  return i;
  480|  3.57k|}
_ZN5Exiv27IptcKeyC2ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  490|  3.57k|IptcKey::IptcKey(std::string key) : tag_(0), record_(0), key_(std::move(key)) {
  491|  3.57k|  decomposeKey();
  492|  3.57k|}
_ZN5Exiv27IptcKeyC2Ett:
  494|  28.1k|IptcKey::IptcKey(uint16_t tag, uint16_t record) : tag_(tag), record_(record) {
  495|  28.1k|  makeKey();
  496|  28.1k|}
_ZNK5Exiv27IptcKey3tagEv:
  522|   275k|uint16_t IptcKey::tag() const {
  523|   275k|  return tag_;
  524|   275k|}
_ZNK5Exiv27IptcKey6recordEv:
  530|  75.7k|uint16_t IptcKey::record() const {
  531|  75.7k|  return record_;
  532|  75.7k|}
_ZNK5Exiv27IptcKey5cloneEv:
  534|  63.1k|IptcKey::UniquePtr IptcKey::clone() const {
  535|  63.1k|  return UniquePtr(clone_());
  536|  63.1k|}
_ZNK5Exiv27IptcKey6clone_Ev:
  538|  63.1k|IptcKey* IptcKey::clone_() const {
  539|  63.1k|  return new IptcKey(*this);
  540|  63.1k|}
_ZN5Exiv27IptcKey12decomposeKeyEv:
  542|  3.57k|void IptcKey::decomposeKey() {
  543|       |  // Check that the key has the expected format with RE
  544|  3.57k|  auto posDot1 = key_.find('.');
  545|  3.57k|  auto posDot2 = key_.find('.', posDot1 + 1);
  546|       |
  547|  3.57k|  if (posDot1 == std::string::npos || posDot2 == std::string::npos) {
  ------------------
  |  Branch (547:7): [True: 0, False: 3.57k]
  |  Branch (547:39): [True: 0, False: 3.57k]
  ------------------
  548|      0|    throw Error(ErrorCode::kerInvalidKey, key_);
  549|      0|  }
  550|       |
  551|       |  // Get the family name, record name and dataSet name parts of the key
  552|  3.57k|  const std::string familyName = key_.substr(0, posDot1);
  553|  3.57k|  if (familyName != familyName_)
  ------------------
  |  Branch (553:7): [True: 0, False: 3.57k]
  ------------------
  554|      0|    throw Error(ErrorCode::kerInvalidKey, key_);
  555|       |
  556|  3.57k|  std::string recordName = key_.substr(posDot1 + 1, posDot2 - posDot1 - 1);
  557|  3.57k|  std::string dataSetName = key_.substr(posDot2 + 1);
  558|       |
  559|       |  // Use the parts of the key to find dataSet and recordId
  560|  3.57k|  uint16_t recId = IptcDataSets::recordId(recordName);
  561|  3.57k|  uint16_t dataSet = IptcDataSets::dataSet(dataSetName, recId);
  562|       |
  563|       |  // Possibly translate hex name parts (0xabcd) to real names
  564|  3.57k|  recordName = IptcDataSets::recordName(recId);
  565|  3.57k|  dataSetName = IptcDataSets::dataSetName(dataSet, recId);
  566|       |
  567|  3.57k|  tag_ = dataSet;
  568|  3.57k|  record_ = recId;
  569|  3.57k|  key_ = familyName + "." + recordName + "." + dataSetName;
  570|  3.57k|}
_ZN5Exiv27IptcKey7makeKeyEv:
  572|  28.1k|void IptcKey::makeKey() {
  573|  28.1k|  key_ = std::string(familyName_) + "." + IptcDataSets::recordName(record_) + "." +
  574|  28.1k|         IptcDataSets::dataSetName(tag_, record_);
  575|  28.1k|}

_ZN5Exiv28Internal7enforceIJEEEvbNS_9ErrorCodeEDpOT_:
   46|  29.2M|constexpr void enforce(bool condition, Exiv2::ErrorCode err_code, T&&... args) {
   47|  29.2M|  enforce<Exiv2::Error>(condition, err_code, std::forward<T>(args)...);
   48|  29.2M|}
_ZN5Exiv28Internal7enforceINS_5ErrorEJRNS_9ErrorCodeEEEEvbDpOT0_:
   35|  29.2M|constexpr void enforce(bool condition, T&&... args) {
   36|  29.2M|  if (!condition) {
  ------------------
  |  Branch (36:7): [True: 8.35k, False: 29.2M]
  ------------------
   37|  8.35k|    throw exception_t(std::forward<T>(args)...);
   38|  8.35k|  }
   39|  29.2M|}

_ZN5Exiv28EpsImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
 1026|  3.45k|EpsImage::EpsImage(BasicIo::UniquePtr io, bool create) : Image(ImageType::eps, mdXmp, std::move(io)) {
 1027|       |  // LogMsg::setLevel(LogMsg::debug);
 1028|  3.45k|  if (create && io_->open() == 0) {
  ------------------
  |  Branch (1028:7): [True: 0, False: 3.45k]
  |  Branch (1028:17): [True: 0, False: 0]
  ------------------
 1029|       |#ifdef DEBUG
 1030|       |    EXV_DEBUG << "Exiv2::EpsImage:: Creating blank EPS image\n";
 1031|       |#endif
 1032|      0|    IoCloser closer(*io_);
 1033|      0|    if (io_->write(reinterpret_cast<const byte*>(epsBlank.data()), epsBlank.size()) != epsBlank.size()) {
  ------------------
  |  Branch (1033:9): [True: 0, False: 0]
  ------------------
 1034|      0|#ifndef SUPPRESS_WARNINGS
 1035|      0|      EXV_WARNING << "Failed to write blank EPS image.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1036|      0|#endif
 1037|      0|      throw Error(ErrorCode::kerImageWriteFailed);
 1038|      0|    }
 1039|      0|  }
 1040|  3.45k|}
_ZNK5Exiv28EpsImage8mimeTypeEv:
 1042|  5.38k|std::string EpsImage::mimeType() const {
 1043|  5.38k|  return "application/postscript";
 1044|  5.38k|}
_ZN5Exiv28EpsImage12readMetadataEv:
 1050|  3.45k|void EpsImage::readMetadata() {
 1051|       |#ifdef DEBUG
 1052|       |  EXV_DEBUG << "Exiv2::EpsImage::readMetadata: Reading EPS file " << io_->path() << "\n";
 1053|       |#endif
 1054|       |
 1055|       |  // read metadata
 1056|  3.45k|  readWriteEpsMetadata(*io_, xmpPacket_, nativePreviews_, /* write = */ false);
 1057|       |
 1058|       |  // decode XMP metadata
 1059|  3.45k|  if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_) > 1) {
  ------------------
  |  Branch (1059:7): [True: 622, False: 2.83k]
  |  Branch (1059:30): [True: 204, False: 418]
  ------------------
 1060|    204|#ifndef SUPPRESS_WARNINGS
 1061|    204|    EXV_WARNING << "Failed to decode XMP metadata.\n";
  ------------------
  |  |  138|    204|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 204]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    204|  LogMsg(LogMsg::warn).os()
  ------------------
 1062|    204|#endif
 1063|    204|    throw Error(ErrorCode::kerFailedToReadImageData);
 1064|    204|  }
 1065|       |
 1066|       |#ifdef DEBUG
 1067|       |  EXV_DEBUG << "Exiv2::EpsImage::readMetadata: Finished reading EPS file " << io_->path() << "\n";
 1068|       |#endif
 1069|  3.45k|}
_ZN5Exiv214newEpsInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
 1094|  3.45k|Image::UniquePtr newEpsInstance(BasicIo::UniquePtr io, bool create) {
 1095|  3.45k|  auto image = std::make_unique<EpsImage>(std::move(io), create);
 1096|  3.45k|  if (!image->good()) {
  ------------------
  |  Branch (1096:7): [True: 0, False: 3.45k]
  ------------------
 1097|      0|    return nullptr;
 1098|      0|  }
 1099|  3.45k|  return image;
 1100|  3.45k|}
_ZN5Exiv29isEpsTypeERNS_7BasicIoEb:
 1102|  23.4k|bool isEpsType(BasicIo& iIo, bool advance) {
 1103|       |  // read as many bytes as needed for the longest (DOS) EPS signature
 1104|  23.4k|  constexpr auto bufSize = [] {
 1105|  23.4k|    auto f = [](const auto& a, const auto& b) { return a.size() < b.size(); };
 1106|  23.4k|    return std::max_element(epsFirstLine.begin(), epsFirstLine.end(), f)->size();
 1107|  23.4k|  }();
 1108|  23.4k|  const size_t restore = iIo.tell();  // save
 1109|  23.4k|  DataBuf buf = iIo.read(bufSize);
 1110|  23.4k|  if (iIo.error() || buf.size() != bufSize) {
  ------------------
  |  Branch (1110:7): [True: 0, False: 23.4k]
  |  Branch (1110:22): [True: 0, False: 23.4k]
  ------------------
 1111|      0|    iIo.seek(restore, BasicIo::beg);
 1112|      0|    return false;
 1113|      0|  }
 1114|       |  // check for all possible (DOS) EPS signatures
 1115|  23.4k|  bool matched = (buf.cmpBytes(0, dosEpsSignature.data(), dosEpsSignature.size()) == 0);
 1116|  23.4k|  if (!matched) {
  ------------------
  |  Branch (1116:7): [True: 22.4k, False: 962]
  ------------------
 1117|  58.9k|    for (auto&& eps : epsFirstLine) {
  ------------------
  |  Branch (1117:21): [True: 58.9k, False: 16.5k]
  ------------------
 1118|  58.9k|      if (buf.cmpBytes(0, eps.data(), eps.size()) == 0) {
  ------------------
  |  Branch (1118:11): [True: 5.95k, False: 52.9k]
  ------------------
 1119|  5.95k|        matched = true;
 1120|  5.95k|        break;
 1121|  5.95k|      }
 1122|  58.9k|    }
 1123|  22.4k|  }
 1124|       |  // seek back if possible and requested
 1125|  23.4k|  if (!advance || !matched) {
  ------------------
  |  Branch (1125:7): [True: 23.4k, False: 0]
  |  Branch (1125:19): [True: 0, False: 0]
  ------------------
 1126|  23.4k|    iIo.seek(restore, BasicIo::beg);
 1127|  23.4k|  }
 1128|  23.4k|  return matched;
 1129|  23.4k|}
epsimage.cpp:_ZN12_GLOBAL__N_120readWriteEpsMetadataERN5Exiv27BasicIoERNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERNS3_6vectorINS0_13NativePreviewENS7_ISC_EEEEb:
  224|  3.45k|void readWriteEpsMetadata(BasicIo& io, std::string& xmpPacket, NativePreviewList& nativePreviews, bool write) {
  225|       |  // open input file
  226|  3.45k|  if (io.open() != 0) {
  ------------------
  |  Branch (226:7): [True: 0, False: 3.45k]
  ------------------
  227|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io.path(), strError());
  228|      0|  }
  229|  3.45k|  IoCloser closer(io);
  230|       |
  231|       |  // read from input file via memory map
  232|  3.45k|  const byte* data = io.mmap();
  233|       |
  234|       |  // default positions and sizes
  235|  3.45k|  const size_t size = io.size();
  236|  3.45k|  size_t posEps = 0;
  237|  3.45k|  size_t posEndEps = size;
  238|  3.45k|  uint32_t posWmf = 0;
  239|  3.45k|  uint32_t sizeWmf = 0;
  240|  3.45k|  uint32_t posTiff = 0;
  241|  3.45k|  uint32_t sizeTiff = 0;
  242|       |
  243|  3.45k|  ErrorCode errcode = write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData;
  ------------------
  |  Branch (243:23): [True: 0, False: 3.45k]
  ------------------
  244|       |
  245|       |  // check for DOS EPS
  246|  3.45k|  const bool dosEps =
  247|  3.45k|      (size >= dosEpsSignature.size() && memcmp(data, dosEpsSignature.data(), dosEpsSignature.size()) == 0);
  ------------------
  |  Branch (247:8): [True: 3.45k, False: 0]
  |  Branch (247:42): [True: 481, False: 2.97k]
  ------------------
  248|  3.45k|  if (dosEps) {
  ------------------
  |  Branch (248:7): [True: 481, False: 2.97k]
  ------------------
  249|       |#ifdef DEBUG
  250|       |    EXV_DEBUG << "readWriteEpsMetadata: Found DOS EPS signature\n";
  251|       |#endif
  252|       |
  253|    481|    enforce(size >= 30, errcode);
  254|    481|    posEps = getULong(data + 4, littleEndian);
  255|    481|    posEndEps = getULong(data + 8, littleEndian) + posEps;
  256|    481|    posWmf = getULong(data + 12, littleEndian);
  257|    481|    sizeWmf = getULong(data + 16, littleEndian);
  258|    481|    posTiff = getULong(data + 20, littleEndian);
  259|    481|    sizeTiff = getULong(data + 24, littleEndian);
  260|       |#ifdef DEBUG
  261|       |    EXV_DEBUG << "readWriteEpsMetadata: EPS section at position " << posEps << ", size " << (posEndEps - posEps)
  262|       |              << "\n";
  263|       |    EXV_DEBUG << "readWriteEpsMetadata: WMF section at position " << posWmf << ", size " << sizeWmf << "\n";
  264|       |    EXV_DEBUG << "readWriteEpsMetadata: TIFF section at position " << posTiff << ", size " << sizeTiff << "\n";
  265|       |#endif
  266|    481|    if (uint16_t checksum = getUShort(data + 28, littleEndian); checksum != 0xFFFF) {
  ------------------
  |  Branch (266:65): [True: 410, False: 71]
  ------------------
  267|       |#ifdef DEBUG
  268|       |      EXV_DEBUG << "readWriteEpsMetadata: DOS EPS checksum is not FFFF\n";
  269|       |#endif
  270|    410|    }
  271|    481|    if ((posWmf != 0 || sizeWmf != 0) && (posTiff != 0 || sizeTiff != 0)) {
  ------------------
  |  Branch (271:10): [True: 300, False: 181]
  |  Branch (271:25): [True: 62, False: 119]
  |  Branch (271:43): [True: 278, False: 74]
  |  Branch (271:59): [True: 56, False: 18]
  ------------------
  272|    334|#ifndef SUPPRESS_WARNINGS
  273|    334|      EXV_WARNING << "DOS EPS file has both WMF and TIFF section. Only one of those is allowed.\n";
  ------------------
  |  |  138|    334|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 334]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    334|  LogMsg(LogMsg::warn).os()
  ------------------
  274|    334|#endif
  275|    334|      if (write)
  ------------------
  |  Branch (275:11): [True: 0, False: 334]
  ------------------
  276|      0|        throw Error(ErrorCode::kerImageWriteFailed);
  277|    334|    }
  278|    481|    if (sizeWmf == 0 && sizeTiff == 0) {
  ------------------
  |  Branch (278:9): [True: 203, False: 278]
  |  Branch (278:25): [True: 78, False: 125]
  ------------------
  279|     78|#ifndef SUPPRESS_WARNINGS
  280|     78|      EXV_WARNING << "DOS EPS file has neither WMF nor TIFF section. Exactly one of those is required.\n";
  ------------------
  |  |  138|     78|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 78]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     78|  LogMsg(LogMsg::warn).os()
  ------------------
  281|     78|#endif
  282|     78|      if (write)
  ------------------
  |  Branch (282:11): [True: 0, False: 78]
  ------------------
  283|      0|        throw Error(ErrorCode::kerImageWriteFailed);
  284|     78|    }
  285|    481|    enforce(30 <= posEps, errcode);
  286|    481|    enforce(sizeWmf == 0 || 30 <= posWmf, errcode);
  ------------------
  |  Branch (286:13): [True: 231, False: 250]
  |  Branch (286:29): [True: 195, False: 55]
  ------------------
  287|    481|    enforce(sizeTiff == 0 || 30 <= posTiff, errcode);
  ------------------
  |  Branch (287:13): [True: 183, False: 298]
  |  Branch (287:30): [True: 238, False: 60]
  ------------------
  288|       |
  289|    481|    enforce(posEps <= posEndEps && posEndEps <= size, errcode);
  ------------------
  |  Branch (289:13): [True: 325, False: 156]
  |  Branch (289:36): [True: 147, False: 178]
  ------------------
  290|    481|    enforce(posWmf <= size && sizeWmf <= size - posWmf, errcode);
  ------------------
  |  Branch (290:13): [True: 115, False: 366]
  |  Branch (290:31): [True: 93, False: 22]
  ------------------
  291|    481|    enforce(posTiff <= size && sizeTiff <= size - posTiff, errcode);
  ------------------
  |  Branch (291:13): [True: 71, False: 410]
  |  Branch (291:32): [True: 51, False: 20]
  ------------------
  292|    481|  }
  293|       |
  294|       |  // check first line
  295|  3.45k|  std::string firstLine;
  296|  3.45k|  const size_t posSecondLine = readLine(firstLine, data, posEps, posEndEps);
  297|       |#ifdef DEBUG
  298|       |  EXV_DEBUG << "readWriteEpsMetadata: First line: " << firstLine << "\n";
  299|       |#endif
  300|  3.45k|  auto it = std::find(epsFirstLine.begin(), epsFirstLine.end(), firstLine);
  301|  3.45k|  if (it == epsFirstLine.end()) {
  ------------------
  |  Branch (301:7): [True: 89, False: 3.37k]
  ------------------
  302|     89|    throw Error(ErrorCode::kerNotAnImage, "EPS");
  303|     89|  }
  304|       |
  305|       |  // determine line ending style of the first line
  306|  3.37k|  if (posSecondLine >= posEndEps) {
  ------------------
  |  Branch (306:7): [True: 13, False: 3.35k]
  ------------------
  307|     13|#ifndef SUPPRESS_WARNINGS
  308|     13|    EXV_WARNING << "Premature end of file after first line.\n";
  ------------------
  |  |  138|     13|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 13]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     13|  LogMsg(LogMsg::warn).os()
  ------------------
  309|     13|#endif
  310|     13|    throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (310:17): [True: 0, False: 13]
  ------------------
  311|     13|  }
  312|  3.35k|  const std::string lineEnding(reinterpret_cast<const char*>(data + posEps + firstLine.size()),
  313|  3.35k|                               posSecondLine - (posEps + firstLine.size()));
  314|       |#ifdef DEBUG
  315|       |  if (lineEnding == "\n") {
  316|       |    EXV_DEBUG << "readWriteEpsMetadata: Line ending style: Unix (LF)\n";
  317|       |  } else if (lineEnding == "\r") {
  318|       |    EXV_DEBUG << "readWriteEpsMetadata: Line ending style: Mac (CR)\n";
  319|       |  } else if (lineEnding == "\r\n") {
  320|       |    EXV_DEBUG << "readWriteEpsMetadata: Line ending style: DOS (CR LF)\n";
  321|       |  } else {
  322|       |    EXV_DEBUG << "readWriteEpsMetadata: Line ending style: (unknown)\n";
  323|       |  }
  324|       |#endif
  325|       |
  326|       |  // scan comments
  327|  3.35k|  size_t posLanguageLevel = posEndEps;
  328|  3.35k|  size_t posContainsXmp = posEndEps;
  329|  3.35k|  size_t posPages = posEndEps;
  330|  3.35k|  size_t posExiv2Version = posEndEps;
  331|  3.35k|  size_t posExiv2Website = posEndEps;
  332|  3.35k|  size_t posEndComments = posEndEps;
  333|  3.35k|  size_t posAi7Thumbnail = posEndEps;
  334|  3.35k|  size_t posAi7ThumbnailEndData = posEndEps;
  335|  3.35k|  size_t posBeginPhotoshop = posEndEps;
  336|  3.35k|  size_t posEndPhotoshop = posEndEps;
  337|  3.35k|  size_t posPage = posEndEps;
  338|  3.35k|  size_t posBeginPageSetup = posEndEps;
  339|  3.35k|  size_t posEndPageSetup = posEndEps;
  340|  3.35k|  size_t posPageTrailer = posEndEps;
  341|  3.35k|  size_t posEof = posEndEps;
  342|  3.35k|  std::vector<std::pair<size_t, size_t>> removableEmbeddings;
  343|  3.35k|  size_t depth = 0;
  344|  3.35k|  const size_t maxDepth = std::numeric_limits<size_t>::max();
  345|  3.35k|  bool illustrator8 = false;
  346|  3.35k|  bool corelDraw = false;
  347|  3.35k|  bool implicitPage = false;
  348|  3.35k|  bool implicitPageSetup = false;
  349|  3.35k|  bool implicitPageTrailer = false;
  350|  3.35k|  bool inDefaultsPreviewPrologSetup = false;
  351|  3.35k|  bool inRemovableEmbedding = false;
  352|  3.35k|  std::string removableEmbeddingEndLine;
  353|  3.35k|  size_t removableEmbeddingsWithUnmarkedTrailer = 0;
  354|   539k|  for (size_t pos = posEps; pos < posEof;) {
  ------------------
  |  Branch (354:29): [True: 536k, False: 3.29k]
  ------------------
  355|   536k|    const size_t startPos = pos;
  356|   536k|    std::string line;
  357|   536k|    pos = readLine(line, data, startPos, posEndEps);
  358|       |#ifdef DEBUG
  359|       |    bool significantLine = true;
  360|       |#endif
  361|       |    // nested documents
  362|   536k|    if (posPage == posEndEps && (line.starts_with("%%IncludeDocument:") || line.starts_with("%%BeginDocument:"))) {
  ------------------
  |  Branch (362:9): [True: 107k, False: 429k]
  |  Branch (362:34): [True: 14, False: 107k]
  |  Branch (362:76): [True: 10, False: 107k]
  ------------------
  363|     24|#ifndef SUPPRESS_WARNINGS
  364|     24|      EXV_WARNING << "Nested document at invalid position: " << startPos << "\n";
  ------------------
  |  |  138|     24|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 24]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     24|  LogMsg(LogMsg::warn).os()
  ------------------
  365|     24|#endif
  366|     24|      throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (366:19): [True: 0, False: 24]
  ------------------
  367|     24|    }
  368|   536k|    if (line.starts_with("%%BeginDocument:")) {
  ------------------
  |  Branch (368:9): [True: 8.02k, False: 528k]
  ------------------
  369|  8.02k|      if (depth == maxDepth) {
  ------------------
  |  Branch (369:11): [True: 0, False: 8.02k]
  ------------------
  370|      0|#ifndef SUPPRESS_WARNINGS
  371|      0|        EXV_WARNING << "Document too deeply nested at position: " << startPos << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  372|      0|#endif
  373|      0|        throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (373:21): [True: 0, False: 0]
  ------------------
  374|      0|      }
  375|  8.02k|      depth++;
  376|   528k|    } else if (line.starts_with("%%EndDocument")) {
  ------------------
  |  Branch (376:16): [True: 223, False: 527k]
  ------------------
  377|    223|      if (depth == 0) {
  ------------------
  |  Branch (377:11): [True: 14, False: 209]
  ------------------
  378|     14|#ifndef SUPPRESS_WARNINGS
  379|     14|        EXV_WARNING << "Unmatched EndDocument at position: " << startPos << "\n";
  ------------------
  |  |  138|     14|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 14]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     14|  LogMsg(LogMsg::warn).os()
  ------------------
  380|     14|#endif
  381|     14|        throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (381:21): [True: 0, False: 14]
  ------------------
  382|     14|      }
  383|    209|      depth--;
  384|   527k|    } else {
  385|       |#ifdef DEBUG
  386|       |      significantLine = false;
  387|       |#endif
  388|   527k|    }
  389|       |#ifdef DEBUG
  390|       |    if (significantLine) {
  391|       |      EXV_DEBUG << "readWriteEpsMetadata: Found significant line \"" << line << "\" at position: " << startPos << "\n";
  392|       |    }
  393|       |    significantLine = true;
  394|       |#endif
  395|   536k|    if (depth != 0)
  ------------------
  |  Branch (395:9): [True: 25.4k, False: 510k]
  ------------------
  396|  25.4k|      continue;
  397|       |    // explicit "Begin" comments
  398|   510k|    if (line.starts_with("%%BeginPreview:")) {
  ------------------
  |  Branch (398:9): [True: 591, False: 510k]
  ------------------
  399|    591|      inDefaultsPreviewPrologSetup = true;
  400|   510k|    } else if (line == "%%BeginDefaults") {
  ------------------
  |  Branch (400:16): [True: 1.51k, False: 508k]
  ------------------
  401|  1.51k|      inDefaultsPreviewPrologSetup = true;
  402|   508k|    } else if (line == "%%BeginProlog") {
  ------------------
  |  Branch (402:16): [True: 605, False: 508k]
  ------------------
  403|    605|      inDefaultsPreviewPrologSetup = true;
  404|   508k|    } else if (line == "%%BeginSetup") {
  ------------------
  |  Branch (404:16): [True: 207, False: 507k]
  ------------------
  405|    207|      inDefaultsPreviewPrologSetup = true;
  406|   507k|    } else if (posPage == posEndEps && line.starts_with("%%Page:")) {
  ------------------
  |  Branch (406:16): [True: 106k, False: 401k]
  |  Branch (406:40): [True: 89, False: 105k]
  ------------------
  407|     89|      posPage = startPos;
  408|   507k|    } else if (posPage != posEndEps && line.starts_with("%%Page:")) {
  ------------------
  |  Branch (408:16): [True: 401k, False: 105k]
  |  Branch (408:40): [True: 25, False: 401k]
  ------------------
  409|     25|      if (implicitPage) {
  ------------------
  |  Branch (409:11): [True: 10, False: 15]
  ------------------
  410|     10|#ifndef SUPPRESS_WARNINGS
  411|     10|        EXV_WARNING << "Page at position " << startPos << " conflicts with implicit page at position: " << posPage
  ------------------
  |  |  138|     10|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 10]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     10|  LogMsg(LogMsg::warn).os()
  ------------------
  412|      0|                    << "\n";
  413|     10|#endif
  414|     10|        throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (414:21): [True: 0, False: 10]
  ------------------
  415|     10|      }
  416|     15|#ifndef SUPPRESS_WARNINGS
  417|     15|      EXV_WARNING << "Unable to handle multiple PostScript pages. Found second page at position: " << startPos << "\n";
  ------------------
  |  |  138|     15|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 15]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     15|  LogMsg(LogMsg::warn).os()
  ------------------
  418|     15|#endif
  419|     15|      throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (419:19): [True: 0, False: 15]
  ------------------
  420|   507k|    } else if (line == "%%BeginPageSetup") {
  ------------------
  |  Branch (420:16): [True: 2.41k, False: 505k]
  ------------------
  421|  2.41k|      posBeginPageSetup = startPos;
  422|   505k|    } else if (!inRemovableEmbedding && line == "%Exiv2BeginXMP: Before %%EndPageSetup") {
  ------------------
  |  Branch (422:16): [True: 337k, False: 167k]
  |  Branch (422:41): [True: 510, False: 336k]
  ------------------
  423|    510|      inRemovableEmbedding = true;
  424|    510|      removableEmbeddings.emplace_back(startPos, startPos);
  425|    510|      removableEmbeddingEndLine = "%Exiv2EndXMP";
  426|   504k|    } else if (!inRemovableEmbedding && line == "%Exiv2BeginXMP: After %%PageTrailer") {
  ------------------
  |  Branch (426:16): [True: 336k, False: 167k]
  |  Branch (426:41): [True: 2.09k, False: 334k]
  ------------------
  427|  2.09k|      inRemovableEmbedding = true;
  428|  2.09k|      removableEmbeddings.emplace_back(startPos, startPos);
  429|  2.09k|      removableEmbeddingEndLine = "%Exiv2EndXMP";
  430|   502k|    } else if (!inRemovableEmbedding && line == "%ADOBeginClientInjection: PageSetup End \"AI11EPS\"") {
  ------------------
  |  Branch (430:16): [True: 334k, False: 167k]
  |  Branch (430:41): [True: 485, False: 334k]
  ------------------
  431|    485|      inRemovableEmbedding = true;
  432|    485|      removableEmbeddings.emplace_back(startPos, startPos);
  433|    485|      removableEmbeddingEndLine = "%ADOEndClientInjection: PageSetup End \"AI11EPS\"";
  434|   502k|    } else if (!inRemovableEmbedding && line == "%ADOBeginClientInjection: PageTrailer Start \"AI11EPS\"") {
  ------------------
  |  Branch (434:16): [True: 334k, False: 167k]
  |  Branch (434:41): [True: 349, False: 333k]
  ------------------
  435|    349|      inRemovableEmbedding = true;
  436|    349|      removableEmbeddings.emplace_back(startPos, startPos);
  437|    349|      removableEmbeddingEndLine = "%ADOEndClientInjection: PageTrailer Start \"AI11EPS\"";
  438|   501k|    } else if (!inRemovableEmbedding && line == "%begin_xml_code") {
  ------------------
  |  Branch (438:16): [True: 333k, False: 167k]
  |  Branch (438:41): [True: 3.94k, False: 330k]
  ------------------
  439|  3.94k|      inRemovableEmbedding = true;
  440|  3.94k|      removableEmbeddings.emplace_back(startPos, startPos);
  441|  3.94k|      removableEmbeddingEndLine = "%end_xml_code";
  442|  3.94k|      removableEmbeddingsWithUnmarkedTrailer++;
  443|   497k|    } else {
  444|       |#ifdef DEBUG
  445|       |      significantLine = false;
  446|       |#endif
  447|   497k|    }
  448|       |#ifdef DEBUG
  449|       |    if (significantLine) {
  450|       |      EXV_DEBUG << "readWriteEpsMetadata: Found significant line \"" << line << "\" at position: " << startPos << "\n";
  451|       |    }
  452|       |    significantLine = true;
  453|       |#endif
  454|       |    // implicit comments
  455|   510k|    if (line == "%%EOF" || line == "%begin_xml_code" || line.size() < 2 || line.front() != '%' || '\x21' > line[1] ||
  ------------------
  |  Branch (455:9): [True: 15, False: 510k]
  |  Branch (455:28): [True: 5.61k, False: 505k]
  |  Branch (455:57): [True: 176k, False: 328k]
  |  Branch (455:76): [True: 190k, False: 138k]
  |  Branch (455:99): [True: 9.28k, False: 129k]
  ------------------
  456|   381k|        line[1] > '\x7e') {
  ------------------
  |  Branch (456:9): [True: 203, False: 128k]
  ------------------
  457|   381k|      if (posEndComments == posEndEps) {
  ------------------
  |  Branch (457:11): [True: 2.15k, False: 379k]
  ------------------
  458|  2.15k|        posEndComments = startPos;
  459|       |#ifdef DEBUG
  460|       |        EXV_DEBUG << "readWriteEpsMetadata: Found implicit EndComments at position: " << startPos << "\n";
  461|       |#endif
  462|  2.15k|      }
  463|   381k|    }
  464|   510k|    if (posPage == posEndEps && posEndComments != posEndEps && !inDefaultsPreviewPrologSetup && !inRemovableEmbedding &&
  ------------------
  |  Branch (464:9): [True: 106k, False: 403k]
  |  Branch (464:33): [True: 90.2k, False: 16.7k]
  |  Branch (464:64): [True: 26.5k, False: 63.6k]
  |  Branch (464:97): [True: 3.75k, False: 22.7k]
  ------------------
  465|  3.75k|        !onlyWhitespaces(line)) {
  ------------------
  |  Branch (465:9): [True: 1.86k, False: 1.89k]
  ------------------
  466|  1.86k|      posPage = startPos;
  467|  1.86k|      implicitPage = true;
  468|       |#ifdef DEBUG
  469|       |      EXV_DEBUG << "readWriteEpsMetadata: Found implicit Page at position: " << startPos << "\n";
  470|       |#endif
  471|  1.86k|    }
  472|   510k|    if (posBeginPageSetup == posEndEps &&
  ------------------
  |  Branch (472:9): [True: 104k, False: 406k]
  ------------------
  473|   104k|        (implicitPage || (posPage != posEndEps && !inRemovableEmbedding && !line.empty() && line.front() != '%'))) {
  ------------------
  |  Branch (473:10): [True: 1.84k, False: 102k]
  |  Branch (473:27): [True: 1.77k, False: 100k]
  |  Branch (473:51): [True: 1.39k, False: 379]
  |  Branch (473:76): [True: 1.10k, False: 288]
  |  Branch (473:93): [True: 42, False: 1.06k]
  ------------------
  474|  1.88k|      posBeginPageSetup = startPos;
  475|  1.88k|      implicitPageSetup = true;
  476|       |#ifdef DEBUG
  477|       |      EXV_DEBUG << "readWriteEpsMetadata: Found implicit BeginPageSetup at position: " << startPos << "\n";
  478|       |#endif
  479|  1.88k|    }
  480|   510k|    if (posEndPageSetup == posEndEps && implicitPageSetup && !inRemovableEmbedding && !line.empty() &&
  ------------------
  |  Branch (480:9): [True: 164k, False: 346k]
  |  Branch (480:41): [True: 51.1k, False: 112k]
  |  Branch (480:62): [True: 26.9k, False: 24.2k]
  |  Branch (480:87): [True: 10.6k, False: 16.2k]
  ------------------
  481|  10.6k|        line.front() != '%') {
  ------------------
  |  Branch (481:9): [True: 1.60k, False: 9.08k]
  ------------------
  482|  1.60k|      posEndPageSetup = startPos;
  483|       |#ifdef DEBUG
  484|       |      EXV_DEBUG << "readWriteEpsMetadata: Found implicit EndPageSetup at position: " << startPos << "\n";
  485|       |#endif
  486|  1.60k|    }
  487|   510k|    if (!line.empty() && line.front() != '%')
  ------------------
  |  Branch (487:9): [True: 340k, False: 170k]
  |  Branch (487:26): [True: 195k, False: 144k]
  ------------------
  488|   195k|      continue;  // performance optimization
  489|   315k|    if (line == "%%EOF" || line == "%%Trailer" || line == "%%PageTrailer") {
  ------------------
  |  Branch (489:9): [True: 15, False: 315k]
  |  Branch (489:28): [True: 795, False: 314k]
  |  Branch (489:51): [True: 512, False: 313k]
  ------------------
  490|  1.32k|      if (posBeginPageSetup == posEndEps) {
  ------------------
  |  Branch (490:11): [True: 19, False: 1.30k]
  ------------------
  491|     19|        posBeginPageSetup = startPos;
  492|     19|        implicitPageSetup = true;
  493|       |#ifdef DEBUG
  494|       |        EXV_DEBUG << "readWriteEpsMetadata: Found implicit BeginPageSetup at position: " << startPos << "\n";
  495|       |#endif
  496|     19|      }
  497|  1.32k|      if (posEndPageSetup == posEndEps) {
  ------------------
  |  Branch (497:11): [True: 33, False: 1.28k]
  ------------------
  498|     33|        posEndPageSetup = startPos;
  499|     33|        implicitPageSetup = true;
  500|       |#ifdef DEBUG
  501|       |        EXV_DEBUG << "readWriteEpsMetadata: Found implicit EndPageSetup at position: " << startPos << "\n";
  502|       |#endif
  503|     33|      }
  504|  1.32k|    }
  505|   315k|    if ((line == "%%EOF" || line == "%%Trailer") && posPageTrailer == posEndEps) {
  ------------------
  |  Branch (505:10): [True: 15, False: 315k]
  |  Branch (505:29): [True: 795, False: 314k]
  |  Branch (505:53): [True: 64, False: 746]
  ------------------
  506|     64|      posPageTrailer = startPos;
  507|     64|      implicitPageTrailer = true;
  508|       |#ifdef DEBUG
  509|       |      EXV_DEBUG << "readWriteEpsMetadata: Found implicit PageTrailer at position: " << startPos << "\n";
  510|       |#endif
  511|     64|    }
  512|       |    // remaining explicit comments
  513|   315k|    if (posEndComments == posEndEps && posLanguageLevel == posEndEps && line.starts_with("%%LanguageLevel:")) {
  ------------------
  |  Branch (513:9): [True: 17.3k, False: 297k]
  |  Branch (513:40): [True: 16.9k, False: 462]
  |  Branch (513:73): [True: 23, False: 16.9k]
  ------------------
  514|     23|      posLanguageLevel = startPos;
  515|   315k|    } else if (posEndComments == posEndEps && posContainsXmp == posEndEps && line.starts_with("%ADO_ContainsXMP:")) {
  ------------------
  |  Branch (515:16): [True: 17.3k, False: 297k]
  |  Branch (515:47): [True: 15.9k, False: 1.42k]
  |  Branch (515:78): [True: 871, False: 15.0k]
  ------------------
  516|    871|      posContainsXmp = startPos;
  517|   314k|    } else if (posEndComments == posEndEps && posPages == posEndEps && line.starts_with("%%Pages:")) {
  ------------------
  |  Branch (517:16): [True: 16.4k, False: 297k]
  |  Branch (517:47): [True: 14.5k, False: 1.97k]
  |  Branch (517:72): [True: 47, False: 14.4k]
  ------------------
  518|     47|      posPages = startPos;
  519|   314k|    } else if (posEndComments == posEndEps && posExiv2Version == posEndEps && line.starts_with("%Exiv2Version:")) {
  ------------------
  |  Branch (519:16): [True: 16.4k, False: 297k]
  |  Branch (519:47): [True: 16.1k, False: 300]
  |  Branch (519:79): [True: 32, False: 16.1k]
  ------------------
  520|     32|      posExiv2Version = startPos;
  521|   314k|    } else if (posEndComments == posEndEps && posExiv2Website == posEndEps && line.starts_with("%Exiv2Website:")) {
  ------------------
  |  Branch (521:16): [True: 16.4k, False: 297k]
  |  Branch (521:47): [True: 15.4k, False: 928]
  |  Branch (521:79): [True: 33, False: 15.4k]
  ------------------
  522|     33|      posExiv2Website = startPos;
  523|   314k|    } else if (posEndComments == posEndEps && line.starts_with("%%Creator: Adobe Illustrator") &&
  ------------------
  |  Branch (523:16): [True: 16.3k, False: 297k]
  |  Branch (523:47): [True: 777, False: 15.6k]
  ------------------
  524|    777|               firstLine == "%!PS-Adobe-3.0 EPSF-3.0") {
  ------------------
  |  Branch (524:16): [True: 195, False: 582]
  ------------------
  525|    195|      illustrator8 = true;
  526|   313k|    } else if (posEndComments == posEndEps && line.starts_with("%AI7_Thumbnail:")) {
  ------------------
  |  Branch (526:16): [True: 16.1k, False: 297k]
  |  Branch (526:47): [True: 708, False: 15.4k]
  ------------------
  527|    708|      posAi7Thumbnail = startPos;
  528|   313k|    } else if (posEndComments == posEndEps && posAi7Thumbnail != posEndEps && posAi7ThumbnailEndData == posEndEps &&
  ------------------
  |  Branch (528:16): [True: 15.4k, False: 297k]
  |  Branch (528:47): [True: 3.25k, False: 12.2k]
  |  Branch (528:79): [True: 2.55k, False: 707]
  ------------------
  529|  2.55k|               line == "%%EndData") {
  ------------------
  |  Branch (529:16): [True: 215, False: 2.33k]
  ------------------
  530|    215|      posAi7ThumbnailEndData = startPos;
  531|   313k|    } else if (posEndComments == posEndEps && line == "%%EndComments") {
  ------------------
  |  Branch (531:16): [True: 15.2k, False: 297k]
  |  Branch (531:47): [True: 11, False: 15.2k]
  ------------------
  532|     11|      posEndComments = startPos;
  533|   313k|    } else if (inDefaultsPreviewPrologSetup && line.starts_with("%%BeginResource: procset wCorel")) {
  ------------------
  |  Branch (533:16): [True: 131k, False: 181k]
  |  Branch (533:48): [True: 711, False: 130k]
  ------------------
  534|    711|      corelDraw = true;
  535|   312k|    } else if (line == "%%EndPreview") {
  ------------------
  |  Branch (535:16): [True: 196, False: 312k]
  ------------------
  536|    196|      inDefaultsPreviewPrologSetup = false;
  537|   312k|    } else if (line == "%%EndDefaults") {
  ------------------
  |  Branch (537:16): [True: 473, False: 311k]
  ------------------
  538|    473|      inDefaultsPreviewPrologSetup = false;
  539|   311k|    } else if (line == "%%EndProlog") {
  ------------------
  |  Branch (539:16): [True: 558, False: 311k]
  ------------------
  540|    558|      inDefaultsPreviewPrologSetup = false;
  541|   311k|    } else if (line == "%%EndSetup") {
  ------------------
  |  Branch (541:16): [True: 214, False: 310k]
  ------------------
  542|    214|      inDefaultsPreviewPrologSetup = false;
  543|   310k|    } else if (posEndPageSetup == posEndEps && line == "%%EndPageSetup") {
  ------------------
  |  Branch (543:16): [True: 129k, False: 180k]
  |  Branch (543:48): [True: 20, False: 129k]
  ------------------
  544|     20|      posEndPageSetup = startPos;
  545|   310k|    } else if (posPageTrailer == posEndEps && line == "%%PageTrailer") {
  ------------------
  |  Branch (545:16): [True: 217k, False: 93.1k]
  |  Branch (545:47): [True: 34, False: 217k]
  ------------------
  546|     34|      posPageTrailer = startPos;
  547|   310k|    } else if (posBeginPhotoshop == posEndEps && line.starts_with("%BeginPhotoshop:")) {
  ------------------
  |  Branch (547:16): [True: 233k, False: 77.0k]
  |  Branch (547:50): [True: 142, False: 233k]
  ------------------
  548|    142|      posBeginPhotoshop = pos;
  549|   310k|    } else if (posBeginPhotoshop != posEndEps && posEndPhotoshop == posEndEps && line == "%EndPhotoshop") {
  ------------------
  |  Branch (549:16): [True: 77.0k, False: 233k]
  |  Branch (549:50): [True: 36.8k, False: 40.1k]
  |  Branch (549:82): [True: 71, False: 36.7k]
  ------------------
  550|     71|      posEndPhotoshop = startPos;
  551|   310k|    } else if (inRemovableEmbedding && line == removableEmbeddingEndLine) {
  ------------------
  |  Branch (551:16): [True: 126k, False: 184k]
  |  Branch (551:40): [True: 6.89k, False: 119k]
  ------------------
  552|  6.89k|      inRemovableEmbedding = false;
  553|  6.89k|      removableEmbeddings.back().second = pos;
  554|   303k|    } else if (line == "%%EOF") {
  ------------------
  |  Branch (554:16): [True: 15, False: 303k]
  ------------------
  555|     15|      posEof = startPos;
  556|   303k|    } else {
  557|       |#ifdef DEBUG
  558|       |      significantLine = false;
  559|       |#endif
  560|   303k|    }
  561|       |#ifdef DEBUG
  562|       |    if (significantLine) {
  563|       |      EXV_DEBUG << "readWriteEpsMetadata: Found significant line \"" << line << "\" at position: " << startPos << "\n";
  564|       |    }
  565|       |#endif
  566|   315k|  }
  567|       |
  568|       |  // check for unfinished nested documents
  569|  3.29k|  if (depth != 0) {
  ------------------
  |  Branch (569:7): [True: 37, False: 3.25k]
  ------------------
  570|     37|#ifndef SUPPRESS_WARNINGS
  571|     37|    EXV_WARNING << "Unmatched BeginDocument (" << depth << "x)\n";
  ------------------
  |  |  138|     37|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 37]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     37|  LogMsg(LogMsg::warn).os()
  ------------------
  572|     37|#endif
  573|     37|    throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (573:17): [True: 0, False: 37]
  ------------------
  574|     37|  }
  575|       |
  576|       |  // look for the unmarked trailers of some removable XMP embeddings
  577|  3.25k|  size_t posXmpTrailerEnd = posEof;
  578|  3.34k|  for (size_t i = 0; i < removableEmbeddingsWithUnmarkedTrailer; i++) {
  ------------------
  |  Branch (578:22): [True: 432, False: 2.91k]
  ------------------
  579|    432|    std::string line1;
  580|    432|    const size_t posLine1 = readPrevLine(line1, data, posXmpTrailerEnd, posEndEps);
  581|    432|    std::string line2;
  582|    432|    const size_t posLine2 = readPrevLine(line2, data, posLine1, posEndEps);
  583|    432|    size_t posXmpTrailer;
  584|    432|    if (line1 == "[/EMC pdfmark") {  // Exiftool style
  ------------------
  |  Branch (584:9): [True: 89, False: 343]
  ------------------
  585|     89|      posXmpTrailer = posLine1;
  586|    343|    } else if (line1 == "[/NamespacePop pdfmark" &&
  ------------------
  |  Branch (586:16): [True: 27, False: 316]
  ------------------
  587|     27|               line2 ==
  ------------------
  |  Branch (587:16): [True: 1, False: 26]
  ------------------
  588|     27|                   "[{nextImage} 1 dict begin /Metadata {photoshop_metadata_stream} def currentdict end /PUT "
  589|     27|                   "pdfmark") {  // Photoshop style
  590|      1|      posXmpTrailer = posLine2;
  591|    342|    } else {
  592|    342|#ifndef SUPPRESS_WARNINGS
  593|    342|      EXV_WARNING << "Unable to find XMP embedding trailer ending at position: " << posXmpTrailerEnd << "\n";
  ------------------
  |  |  138|    342|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 342]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    342|  LogMsg(LogMsg::warn).os()
  ------------------
  594|    342|#endif
  595|    342|      if (write)
  ------------------
  |  Branch (595:11): [True: 0, False: 342]
  ------------------
  596|      0|        throw Error(ErrorCode::kerImageWriteFailed);
  597|    342|      break;
  598|    342|    }
  599|     90|    removableEmbeddings.emplace_back(posXmpTrailer, posXmpTrailerEnd);
  600|       |#ifdef DEBUG
  601|       |    auto [r, s] = removableEmbeddings.back();
  602|       |    EXV_DEBUG << "readWriteEpsMetadata: Recognized unmarked trailer of removable XMP embedding at [" << r << "," << s
  603|       |              << ")\n";
  604|       |#endif
  605|     90|    posXmpTrailerEnd = posXmpTrailer;
  606|     90|  }
  607|       |
  608|       |  // interpret comment "%ADO_ContainsXMP:"
  609|  3.25k|  std::string line;
  610|  3.25k|  readLine(line, data, posContainsXmp, posEndEps);
  611|  3.25k|  bool containsXmp;
  612|  3.25k|  if (line == "%ADO_ContainsXMP: MainFirst" || line == "%ADO_ContainsXMP:MainFirst") {
  ------------------
  |  Branch (612:7): [True: 441, False: 2.81k]
  |  Branch (612:48): [True: 710, False: 2.10k]
  ------------------
  613|    721|    containsXmp = true;
  614|  2.53k|  } else if (line.empty() || line == "%ADO_ContainsXMP: NoMain" || line == "%ADO_ContainsXMP:NoMain") {
  ------------------
  |  Branch (614:14): [True: 2.38k, False: 149]
  |  Branch (614:30): [True: 10, False: 139]
  |  Branch (614:68): [True: 10, False: 129]
  ------------------
  615|  1.97k|    containsXmp = false;
  616|  1.97k|  } else {
  617|    559|#ifndef SUPPRESS_WARNINGS
  618|    559|    EXV_WARNING << "Invalid line \"" << line << "\" at position: " << posContainsXmp << "\n";
  ------------------
  |  |  138|    559|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 559]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    559|  LogMsg(LogMsg::warn).os()
  ------------------
  619|    559|#endif
  620|    559|    throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (620:17): [True: 0, False: 559]
  ------------------
  621|    559|  }
  622|       |
  623|  2.69k|  const bool deleteXmp = (write && xmpPacket.empty());
  ------------------
  |  Branch (623:27): [True: 0, False: 2.69k]
  |  Branch (623:36): [True: 0, False: 0]
  ------------------
  624|  2.69k|  bool fixBeginXmlPacket = false;
  625|  2.69k|  bool useFlexibleEmbedding = false;
  626|  2.69k|  size_t xmpPos = posEndEps;
  627|  2.69k|  size_t xmpSize = 0;
  628|  2.69k|  if (containsXmp) {
  ------------------
  |  Branch (628:7): [True: 721, False: 1.97k]
  ------------------
  629|       |    // search for XMP metadata
  630|    721|    findXmp(xmpPos, xmpSize, data, posEps, posEndEps, write);
  631|    721|    if (xmpPos == posEndEps) {
  ------------------
  |  Branch (631:9): [True: 48, False: 673]
  ------------------
  632|     48|#ifndef SUPPRESS_WARNINGS
  633|     48|      EXV_WARNING << "Unable to find XMP metadata as announced at position: " << posContainsXmp << "\n";
  ------------------
  |  |  138|     48|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 48]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     48|  LogMsg(LogMsg::warn).os()
  ------------------
  634|     48|#endif
  635|     48|    }
  636|       |    // check embedding of XMP metadata
  637|    721|    const size_t posLineAfterXmp = readLine(line, data, xmpPos + xmpSize, posEndEps);
  638|    721|    if (!line.empty()) {
  ------------------
  |  Branch (638:9): [True: 561, False: 160]
  ------------------
  639|    561|#ifndef SUPPRESS_WARNINGS
  640|    561|      EXV_WARNING << "Unexpected " << line.size() << " bytes of data after XMP at position: " << (xmpPos + xmpSize)
  ------------------
  |  |  138|    561|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 561]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    561|  LogMsg(LogMsg::warn).os()
  ------------------
  641|      0|                  << "\n";
  642|    561|#endif
  643|    561|    } else if (!deleteXmp) {
  ------------------
  |  Branch (643:16): [True: 126, False: 34]
  ------------------
  644|    126|      readLine(line, data, posLineAfterXmp, posEndEps);
  645|    126|      if (line == "% &&end XMP packet marker&&" || line == "%  &&end XMP packet marker&&") {
  ------------------
  |  Branch (645:11): [True: 13, False: 113]
  |  Branch (645:52): [True: 9, False: 104]
  ------------------
  646|     22|        useFlexibleEmbedding = true;
  647|     22|      }
  648|    126|    }
  649|    721|  }
  650|  2.69k|  if (useFlexibleEmbedding) {
  ------------------
  |  Branch (650:7): [True: 22, False: 2.67k]
  ------------------
  651|       |#ifdef DEBUG
  652|       |    EXV_DEBUG << "readWriteEpsMetadata: Using flexible XMP embedding\n";
  653|       |#endif
  654|     22|    const size_t posBeginXmlPacket = readPrevLine(line, data, xmpPos, posEndEps);
  655|     22|    if (line.starts_with("%begin_xml_packet:")) {
  ------------------
  |  Branch (655:9): [True: 1, False: 21]
  ------------------
  656|       |#ifdef DEBUG
  657|       |      EXV_DEBUG << "readWriteEpsMetadata: XMP embedding contains %begin_xml_packet\n";
  658|       |#endif
  659|      1|      if (write) {
  ------------------
  |  Branch (659:11): [True: 0, False: 1]
  ------------------
  660|      0|        fixBeginXmlPacket = true;
  661|      0|        xmpSize += (xmpPos - posBeginXmlPacket);
  662|      0|        xmpPos = posBeginXmlPacket;
  663|      0|      }
  664|     21|    } else if (posBeginPhotoshop != posEndEps) {
  ------------------
  |  Branch (664:16): [True: 5, False: 16]
  ------------------
  665|      5|#ifndef SUPPRESS_WARNINGS
  666|      5|      EXV_WARNING << "Missing %begin_xml_packet in Photoshop EPS at position: " << xmpPos << "\n";
  ------------------
  |  |  138|      5|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 5]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      5|  LogMsg(LogMsg::warn).os()
  ------------------
  667|      5|#endif
  668|      5|      if (write)
  ------------------
  |  Branch (668:11): [True: 0, False: 5]
  ------------------
  669|      0|        throw Error(ErrorCode::kerImageWriteFailed);
  670|      5|    }
  671|     22|  }
  672|  2.69k|  if (!useFlexibleEmbedding) {
  ------------------
  |  Branch (672:7): [True: 2.64k, False: 56]
  ------------------
  673|       |    // check if there are irremovable XMP metadata blocks before EndPageSetup
  674|  2.64k|    size_t posOtherXmp = containsXmp ? xmpPos : posEps;
  ------------------
  |  Branch (674:26): [True: 665, False: 1.97k]
  ------------------
  675|  2.64k|    size_t sizeOtherXmp = 0;
  676|  14.6k|    for (;;) {
  677|  14.6k|      findXmp(posOtherXmp, sizeOtherXmp, data, posOtherXmp + sizeOtherXmp, posEndPageSetup, write);
  678|  14.6k|      if (posOtherXmp >= posEndPageSetup)
  ------------------
  |  Branch (678:11): [True: 2.39k, False: 12.2k]
  ------------------
  679|  2.39k|        break;
  680|  12.2k|      bool isRemovableEmbedding = false;
  681|   430k|      for (const auto& [r, s] : removableEmbeddings) {
  ------------------
  |  Branch (681:31): [True: 430k, False: 245]
  ------------------
  682|   430k|        if (r <= posOtherXmp && posOtherXmp < s) {
  ------------------
  |  Branch (682:13): [True: 430k, False: 555]
  |  Branch (682:33): [True: 12.0k, False: 418k]
  ------------------
  683|  12.0k|          isRemovableEmbedding = true;
  684|  12.0k|          break;
  685|  12.0k|        }
  686|   430k|      }
  687|  12.2k|      if (!isRemovableEmbedding) {
  ------------------
  |  Branch (687:11): [True: 90, False: 12.1k]
  ------------------
  688|     90|#ifndef SUPPRESS_WARNINGS
  689|     90|        EXV_WARNING << "XMP metadata block is not removable at position: " << posOtherXmp << "\n";
  ------------------
  |  |  138|     90|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 90]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     90|  LogMsg(LogMsg::warn).os()
  ------------------
  690|     90|#endif
  691|     90|        if (write)
  ------------------
  |  Branch (691:13): [True: 0, False: 90]
  ------------------
  692|      0|          throw Error(ErrorCode::kerImageWriteFailed);
  693|     90|        break;
  694|     90|      }
  695|  12.2k|    }
  696|  2.64k|  }
  697|       |
  698|  2.69k|  if (!write) {
  ------------------
  |  Branch (698:7): [True: 2.50k, False: 189]
  ------------------
  699|       |    // copy XMP metadata
  700|  2.50k|    xmpPacket.assign(reinterpret_cast<const char*>(data + xmpPos), xmpSize);
  701|       |
  702|       |    // native previews
  703|  2.50k|    nativePreviews.clear();
  704|  2.50k|    if (posAi7ThumbnailEndData != posEndEps) {
  ------------------
  |  Branch (704:9): [True: 214, False: 2.29k]
  ------------------
  705|    214|      NativePreview nativePreview;
  706|    214|      std::string dummy;
  707|    214|      std::string lineAi7Thumbnail;
  708|    214|      const size_t posBeginData = readLine(lineAi7Thumbnail, data, posAi7Thumbnail, posEndEps);
  709|    214|      std::istringstream lineStreamAi7Thumbnail(lineAi7Thumbnail);
  710|    214|      lineStreamAi7Thumbnail >> dummy;
  711|    214|      lineStreamAi7Thumbnail >> nativePreview.width_;
  712|    214|      lineStreamAi7Thumbnail >> nativePreview.height_;
  713|    214|      std::string depthStr;
  714|    214|      lineStreamAi7Thumbnail >> depthStr;
  715|    214|      std::string lineBeginData;
  716|    214|      const size_t posAfterBeginData = readLine(lineBeginData, data, posBeginData, posEndEps);
  717|    214|      std::istringstream lineStreamBeginData(lineBeginData);
  718|    214|      std::string beginData;
  719|    214|      lineStreamBeginData >> beginData;
  720|    214|      lineStreamBeginData >> dummy;
  721|    214|      std::string type;
  722|    214|      lineStreamBeginData >> type;
  723|    214|      nativePreview.position_ = static_cast<long>(posAfterBeginData);
  724|    214|      nativePreview.size_ = static_cast<uint32_t>(posAi7ThumbnailEndData - posAfterBeginData);
  725|    214|      nativePreview.filter_ = "hex-ai7thumbnail-pnm";
  726|    214|      nativePreview.mimeType_ = "image/x-portable-anymap";
  727|    214|      if (depthStr != "8") {
  ------------------
  |  Branch (727:11): [True: 184, False: 30]
  ------------------
  728|    184|#ifndef SUPPRESS_WARNINGS
  729|    184|        EXV_WARNING << "Unable to handle Illustrator thumbnail depth: " << depthStr << "\n";
  ------------------
  |  |  138|    184|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 184]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    184|  LogMsg(LogMsg::warn).os()
  ------------------
  730|    184|#endif
  731|    184|      } else if (beginData != "%%BeginData:") {
  ------------------
  |  Branch (731:18): [True: 30, False: 0]
  ------------------
  732|     30|#ifndef SUPPRESS_WARNINGS
  733|     30|        EXV_WARNING << "Unable to handle Illustrator thumbnail data section: " << lineBeginData << "\n";
  ------------------
  |  |  138|     30|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 30]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     30|  LogMsg(LogMsg::warn).os()
  ------------------
  734|     30|#endif
  735|     30|      } else if (type != "Hex") {
  ------------------
  |  Branch (735:18): [True: 0, False: 0]
  ------------------
  736|      0|#ifndef SUPPRESS_WARNINGS
  737|      0|        EXV_WARNING << "Unable to handle Illustrator thumbnail data type: " << type << "\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  738|      0|#endif
  739|      0|      } else {
  740|      0|        nativePreviews.push_back(std::move(nativePreview));
  741|      0|      }
  742|    214|    }
  743|  2.50k|    if (posEndPhotoshop != posEndEps) {
  ------------------
  |  Branch (743:9): [True: 67, False: 2.44k]
  ------------------
  744|     67|      auto sizePhotoshop = posEndPhotoshop - posBeginPhotoshop;
  745|     67|      NativePreview nativePreview{posBeginPhotoshop, sizePhotoshop, 0, 0, "hex-irb", "image/jpeg"};
  746|     67|      nativePreviews.push_back(std::move(nativePreview));
  747|     67|    }
  748|  2.50k|    if (sizeWmf != 0) {
  ------------------
  |  Branch (748:9): [True: 0, False: 2.50k]
  ------------------
  749|      0|      NativePreview nativePreview{posWmf, sizeWmf, 0, 0, "", "image/x-wmf"};
  750|      0|      nativePreviews.push_back(std::move(nativePreview));
  751|      0|    }
  752|  2.50k|    if (sizeTiff != 0) {
  ------------------
  |  Branch (752:9): [True: 0, False: 2.50k]
  ------------------
  753|      0|      NativePreview nativePreview{posTiff, sizeTiff, 0, 0, "", "image/tiff"};
  754|      0|      nativePreviews.push_back(std::move(nativePreview));
  755|      0|    }
  756|  2.50k|  } else {
  757|       |    // check for Adobe Illustrator 8.0 or older
  758|    189|    if (illustrator8) {
  ------------------
  |  Branch (758:9): [True: 0, False: 189]
  ------------------
  759|      0|#ifndef SUPPRESS_WARNINGS
  760|      0|      EXV_WARNING << "Unable to write to EPS files created by Adobe Illustrator 8.0 or older.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  761|      0|#endif
  762|      0|      throw Error(ErrorCode::kerImageWriteFailed);
  763|      0|    }
  764|       |
  765|       |    // create temporary output file
  766|    189|    MemIo tempIo;
  767|    189|    if (!tempIo.isopen()) {
  ------------------
  |  Branch (767:9): [True: 0, False: 189]
  ------------------
  768|      0|#ifndef SUPPRESS_WARNINGS
  769|      0|      EXV_WARNING << "Unable to create temporary file for writing.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  770|      0|#endif
  771|      0|      throw Error(ErrorCode::kerImageWriteFailed);
  772|      0|    }
  773|       |#ifdef DEBUG
  774|       |    EXV_DEBUG << "readWriteEpsMetadata: Created temporary file " << tempIo.path() << "\n";
  775|       |#endif
  776|       |
  777|       |    // sort all positions
  778|    189|    std::vector<size_t> positions;
  779|    189|    positions.push_back(posLanguageLevel);
  780|    189|    positions.push_back(posContainsXmp);
  781|    189|    positions.push_back(posPages);
  782|    189|    positions.push_back(posExiv2Version);
  783|    189|    positions.push_back(posExiv2Website);
  784|    189|    positions.push_back(posEndComments);
  785|    189|    positions.push_back(posPage);
  786|    189|    positions.push_back(posBeginPageSetup);
  787|    189|    positions.push_back(posEndPageSetup);
  788|    189|    positions.push_back(posPageTrailer);
  789|    189|    positions.push_back(posEof);
  790|    189|    positions.push_back(posEndEps);
  791|    189|    if (useFlexibleEmbedding) {
  ------------------
  |  Branch (791:9): [True: 0, False: 189]
  ------------------
  792|      0|      positions.push_back(xmpPos);
  793|      0|    }
  794|    189|    for (const auto& [r, s] : removableEmbeddings) {
  ------------------
  |  Branch (794:29): [True: 0, False: 189]
  ------------------
  795|      0|      positions.push_back(r);
  796|      0|    }
  797|    189|    std::sort(positions.begin(), positions.end());
  798|       |
  799|       |    // assemble result EPS document
  800|    189|    if (dosEps) {
  ------------------
  |  Branch (800:9): [True: 0, False: 189]
  ------------------
  801|       |      // DOS EPS header will be written afterwards
  802|      0|      writeTemp(tempIo, std::string(30, '\x00'));
  803|      0|    }
  804|    189|    const std::string containsXmpLine = deleteXmp ? "%ADO_ContainsXMP: NoMain" : "%ADO_ContainsXMP: MainFirst";
  ------------------
  |  Branch (804:41): [True: 0, False: 189]
  ------------------
  805|    189|    const uint32_t posEpsNew = posTemp(tempIo);
  806|    189|    size_t prevPos = posEps;
  807|    189|    size_t prevSkipPos = prevPos;
  808|    189|    for (const auto& pos : positions) {
  ------------------
  |  Branch (808:26): [True: 0, False: 189]
  ------------------
  809|      0|      if (pos == prevPos)
  ------------------
  |  Branch (809:11): [True: 0, False: 0]
  ------------------
  810|      0|        continue;
  811|       |#ifdef DEBUG
  812|       |      EXV_DEBUG << "readWriteEpsMetadata: Writing at " << pos << "\n";
  813|       |#endif
  814|      0|      if (pos < prevSkipPos) {
  ------------------
  |  Branch (814:11): [True: 0, False: 0]
  ------------------
  815|      0|#ifndef SUPPRESS_WARNINGS
  816|      0|        EXV_WARNING << "Internal error while assembling the result EPS document: "
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  817|      0|                       "Unable to continue at position "
  818|      0|                    << pos << " after skipping to position " << prevSkipPos << "\n";
  819|      0|#endif
  820|      0|        throw Error(ErrorCode::kerImageWriteFailed);
  821|      0|      }
  822|      0|      writeTemp(tempIo, data + prevSkipPos, pos - prevSkipPos);
  823|      0|      const size_t posLineEnd = readLine(line, data, pos, posEndEps);
  824|      0|      size_t skipPos = pos;
  825|       |      // add last line ending if necessary
  826|      0|      if (pos == posEndEps && pos >= 1 && data[pos - 1] != '\r' && data[pos - 1] != '\n') {
  ------------------
  |  Branch (826:11): [True: 0, False: 0]
  |  Branch (826:31): [True: 0, False: 0]
  |  Branch (826:43): [True: 0, False: 0]
  |  Branch (826:68): [True: 0, False: 0]
  ------------------
  827|      0|        writeTemp(tempIo, lineEnding);
  828|       |#ifdef DEBUG
  829|       |        EXV_DEBUG << "readWriteEpsMetadata: Added missing line ending of last line\n";
  830|       |#endif
  831|      0|      }
  832|       |      // update and complement DSC comments
  833|      0|      if (pos == posLanguageLevel && posLanguageLevel != posEndEps && !deleteXmp && !useFlexibleEmbedding &&
  ------------------
  |  Branch (833:11): [True: 0, False: 0]
  |  Branch (833:38): [True: 0, False: 0]
  |  Branch (833:71): [True: 0, False: 0]
  |  Branch (833:85): [True: 0, False: 0]
  ------------------
  834|      0|          (line == "%%LanguageLevel:1" || line == "%%LanguageLevel: 1")) {
  ------------------
  |  Branch (834:12): [True: 0, False: 0]
  |  Branch (834:43): [True: 0, False: 0]
  ------------------
  835|      0|        writeTemp(tempIo, "%%LanguageLevel: 2" + lineEnding);
  836|      0|        skipPos = posLineEnd;
  837|       |#ifdef DEBUG
  838|       |        EXV_DEBUG << "readWriteEpsMetadata: Skipping to " << skipPos << " at " << __FILE__ << ":" << __LINE__ << "\n";
  839|       |#endif
  840|      0|      }
  841|      0|      if (pos == posContainsXmp && posContainsXmp != posEndEps && line != containsXmpLine) {
  ------------------
  |  Branch (841:11): [True: 0, False: 0]
  |  Branch (841:36): [True: 0, False: 0]
  |  Branch (841:67): [True: 0, False: 0]
  ------------------
  842|      0|        writeTemp(tempIo, containsXmpLine + lineEnding);
  843|      0|        skipPos = posLineEnd;
  844|       |#ifdef DEBUG
  845|       |        EXV_DEBUG << "readWriteEpsMetadata: Skipping to " << skipPos << " at " << __FILE__ << ":" << __LINE__ << "\n";
  846|       |#endif
  847|      0|      }
  848|      0|      if (pos == posExiv2Version && posExiv2Version != posEndEps) {
  ------------------
  |  Branch (848:11): [True: 0, False: 0]
  |  Branch (848:37): [True: 0, False: 0]
  ------------------
  849|      0|        writeTemp(tempIo, "%Exiv2Version: " + versionNumberHexString() + lineEnding);
  850|      0|        skipPos = posLineEnd;
  851|       |#ifdef DEBUG
  852|       |        EXV_DEBUG << "readWriteEpsMetadata: Skipping to " << skipPos << " at " << __FILE__ << ":" << __LINE__ << "\n";
  853|       |#endif
  854|      0|      }
  855|      0|      if (pos == posExiv2Website && posExiv2Website != posEndEps) {
  ------------------
  |  Branch (855:11): [True: 0, False: 0]
  |  Branch (855:37): [True: 0, False: 0]
  ------------------
  856|      0|        writeTemp(tempIo, "%Exiv2Website: http://www.exiv2.org/" + lineEnding);
  857|      0|        skipPos = posLineEnd;
  858|       |#ifdef DEBUG
  859|       |        EXV_DEBUG << "readWriteEpsMetadata: Skipping to " << skipPos << " at " << __FILE__ << ":" << __LINE__ << "\n";
  860|       |#endif
  861|      0|      }
  862|      0|      if (pos == posEndComments) {
  ------------------
  |  Branch (862:11): [True: 0, False: 0]
  ------------------
  863|      0|        if (posLanguageLevel == posEndEps && !deleteXmp && !useFlexibleEmbedding) {
  ------------------
  |  Branch (863:13): [True: 0, False: 0]
  |  Branch (863:46): [True: 0, False: 0]
  |  Branch (863:60): [True: 0, False: 0]
  ------------------
  864|      0|          writeTemp(tempIo, "%%LanguageLevel: 2" + lineEnding);
  865|      0|        }
  866|      0|        if (posContainsXmp == posEndEps) {
  ------------------
  |  Branch (866:13): [True: 0, False: 0]
  ------------------
  867|      0|          writeTemp(tempIo, containsXmpLine + lineEnding);
  868|      0|        }
  869|      0|        if (posPages == posEndEps) {
  ------------------
  |  Branch (869:13): [True: 0, False: 0]
  ------------------
  870|      0|          writeTemp(tempIo, "%%Pages: 1" + lineEnding);
  871|      0|        }
  872|      0|        if (posExiv2Version == posEndEps) {
  ------------------
  |  Branch (872:13): [True: 0, False: 0]
  ------------------
  873|      0|          writeTemp(tempIo, "%Exiv2Version: " + versionNumberHexString() + lineEnding);
  874|      0|        }
  875|      0|        if (posExiv2Website == posEndEps) {
  ------------------
  |  Branch (875:13): [True: 0, False: 0]
  ------------------
  876|      0|          writeTemp(tempIo, "%Exiv2Website: http://www.exiv2.org/" + lineEnding);
  877|      0|        }
  878|      0|        readLine(line, data, posEndComments, posEndEps);
  879|      0|        if (line != "%%EndComments") {
  ------------------
  |  Branch (879:13): [True: 0, False: 0]
  ------------------
  880|      0|          writeTemp(tempIo, "%%EndComments" + lineEnding);
  881|      0|        }
  882|      0|      }
  883|      0|      if (pos == posPage && !line.starts_with("%%Page:")) {
  ------------------
  |  Branch (883:11): [True: 0, False: 0]
  |  Branch (883:29): [True: 0, False: 0]
  ------------------
  884|      0|        writeTemp(tempIo, "%%Page: 1 1" + lineEnding);
  885|      0|        writeTemp(tempIo, "%%EndPageComments" + lineEnding);
  886|      0|      }
  887|      0|      if (pos == posBeginPageSetup && line != "%%BeginPageSetup") {
  ------------------
  |  Branch (887:11): [True: 0, False: 0]
  |  Branch (887:39): [True: 0, False: 0]
  ------------------
  888|      0|        writeTemp(tempIo, "%%BeginPageSetup" + lineEnding);
  889|      0|      }
  890|       |      // insert XMP metadata into existing flexible embedding
  891|      0|      if (useFlexibleEmbedding && pos == xmpPos) {
  ------------------
  |  Branch (891:11): [True: 0, False: 0]
  |  Branch (891:35): [True: 0, False: 0]
  ------------------
  892|      0|        if (fixBeginXmlPacket) {
  ------------------
  |  Branch (892:13): [True: 0, False: 0]
  ------------------
  893|      0|          writeTemp(tempIo, "%begin_xml_packet: " + toString(xmpPacket.size()) + lineEnding);
  894|      0|        }
  895|      0|        writeTemp(tempIo, xmpPacket);
  896|      0|        skipPos += xmpSize;
  897|       |#ifdef DEBUG
  898|       |        EXV_DEBUG << "readWriteEpsMetadata: Skipping to " << skipPos << " at " << __FILE__ << ":" << __LINE__ << "\n";
  899|       |#endif
  900|      0|      }
  901|      0|      if (!useFlexibleEmbedding) {
  ------------------
  |  Branch (901:11): [True: 0, False: 0]
  ------------------
  902|       |        // remove preceding embedding(s)
  903|      0|        for (const auto& [p, s] : removableEmbeddings) {
  ------------------
  |  Branch (903:33): [True: 0, False: 0]
  ------------------
  904|      0|          if (pos == p) {
  ------------------
  |  Branch (904:15): [True: 0, False: 0]
  ------------------
  905|      0|            skipPos = s;
  906|       |#ifdef DEBUG
  907|       |            EXV_DEBUG << "readWriteEpsMetadata: Skipping to " << skipPos << " at " << __FILE__ << ":" << __LINE__
  908|       |                      << "\n";
  909|       |#endif
  910|      0|            break;
  911|      0|          }
  912|      0|        }
  913|       |        // insert XMP metadata with new flexible embedding, if necessary
  914|      0|        if (pos == posEndPageSetup && !deleteXmp) {
  ------------------
  |  Branch (914:13): [True: 0, False: 0]
  |  Branch (914:39): [True: 0, False: 0]
  ------------------
  915|      0|          writeTemp(tempIo, "%Exiv2BeginXMP: Before %%EndPageSetup" + lineEnding);
  916|      0|          if (corelDraw) {
  ------------------
  |  Branch (916:15): [True: 0, False: 0]
  ------------------
  917|      0|            writeTemp(tempIo, "%Exiv2Notice: The following line is needed by CorelDRAW." + lineEnding);
  918|      0|            writeTemp(tempIo, "@rs" + lineEnding);
  919|      0|          }
  920|      0|          if (posBeginPhotoshop != posEndEps) {
  ------------------
  |  Branch (920:15): [True: 0, False: 0]
  ------------------
  921|      0|            writeTemp(tempIo, "%Exiv2Notice: The following line is needed by Photoshop." + lineEnding);
  922|      0|            writeTemp(tempIo, "%begin_xml_code" + lineEnding);
  923|      0|          }
  924|      0|          writeTemp(tempIo, "/currentdistillerparams where" + lineEnding);
  925|      0|          writeTemp(tempIo, "{pop currentdistillerparams /CoreDistVersion get 5000 lt} {true} ifelse" + lineEnding);
  926|      0|          writeTemp(tempIo, "{userdict /Exiv2_pdfmark /cleartomark load put" + lineEnding);
  927|      0|          writeTemp(tempIo, "    userdict /Exiv2_metafile_pdfmark {flushfile cleartomark} bind put}" + lineEnding);
  928|      0|          writeTemp(tempIo, "{userdict /Exiv2_pdfmark /pdfmark load put" + lineEnding);
  929|      0|          writeTemp(tempIo, "    userdict /Exiv2_metafile_pdfmark {/PUT pdfmark} bind put} ifelse" + lineEnding);
  930|      0|          writeTemp(tempIo, "[/NamespacePush Exiv2_pdfmark" + lineEnding);
  931|      0|          writeTemp(tempIo, "[/_objdef {Exiv2_metadata_stream} /type /stream /OBJ Exiv2_pdfmark" + lineEnding);
  932|      0|          writeTemp(tempIo, "[{Exiv2_metadata_stream} 2 dict begin" + lineEnding);
  933|      0|          writeTemp(tempIo,
  934|      0|                    "    /Type /Metadata def /Subtype /XML def currentdict end /PUT Exiv2_pdfmark" + lineEnding);
  935|      0|          writeTemp(tempIo, "[{Exiv2_metadata_stream}" + lineEnding);
  936|      0|          writeTemp(tempIo, "    currentfile 0 (% &&end XMP packet marker&&)" + lineEnding);
  937|      0|          writeTemp(tempIo, "    /SubFileDecode filter Exiv2_metafile_pdfmark" + lineEnding);
  938|      0|          if (posBeginPhotoshop != posEndEps) {
  ------------------
  |  Branch (938:15): [True: 0, False: 0]
  ------------------
  939|      0|            writeTemp(tempIo,
  940|      0|                      "%Exiv2Notice: The following line is needed by Photoshop. "
  941|      0|                      "Parameter must be exact size of XMP metadata." +
  942|      0|                          lineEnding);
  943|      0|            writeTemp(tempIo, "%begin_xml_packet: " + toString(xmpPacket.size()) + lineEnding);
  944|      0|          }
  945|      0|          writeTemp(tempIo, xmpPacket);
  946|      0|          writeTemp(tempIo, lineEnding);
  947|      0|          writeTemp(tempIo, "% &&end XMP packet marker&&" + lineEnding);
  948|      0|          writeTemp(tempIo, "[/Document 1 dict begin" + lineEnding);
  949|      0|          writeTemp(tempIo,
  950|      0|                    "    /Metadata {Exiv2_metadata_stream} def currentdict end /BDC Exiv2_pdfmark" + lineEnding);
  951|      0|          if (posBeginPhotoshop != posEndEps) {
  ------------------
  |  Branch (951:15): [True: 0, False: 0]
  ------------------
  952|      0|            writeTemp(tempIo, "%Exiv2Notice: The following line is needed by Photoshop." + lineEnding);
  953|      0|            writeTemp(tempIo, "%end_xml_code" + lineEnding);
  954|      0|          }
  955|      0|          if (corelDraw) {
  ------------------
  |  Branch (955:15): [True: 0, False: 0]
  ------------------
  956|      0|            writeTemp(tempIo, "%Exiv2Notice: The following line is needed by CorelDRAW." + lineEnding);
  957|      0|            writeTemp(tempIo, "@sv" + lineEnding);
  958|      0|          }
  959|      0|          writeTemp(tempIo, "%Exiv2EndXMP" + lineEnding);
  960|      0|        }
  961|      0|      }
  962|      0|      if (pos == posEndPageSetup && line != "%%EndPageSetup") {
  ------------------
  |  Branch (962:11): [True: 0, False: 0]
  |  Branch (962:37): [True: 0, False: 0]
  ------------------
  963|      0|        writeTemp(tempIo, "%%EndPageSetup" + lineEnding);
  964|      0|      }
  965|      0|      if (!useFlexibleEmbedding && pos == posPageTrailer && !deleteXmp) {
  ------------------
  |  Branch (965:11): [True: 0, False: 0]
  |  Branch (965:36): [True: 0, False: 0]
  |  Branch (965:61): [True: 0, False: 0]
  ------------------
  966|      0|        if (!implicitPageTrailer) {
  ------------------
  |  Branch (966:13): [True: 0, False: 0]
  ------------------
  967|      0|          skipPos = posLineEnd;
  968|       |#ifdef DEBUG
  969|       |          EXV_DEBUG << "readWriteEpsMetadata: Skipping to " << skipPos << " at " << __FILE__ << ":" << __LINE__ << "\n";
  970|       |#endif
  971|      0|        }
  972|      0|        writeTemp(tempIo, "%%PageTrailer" + lineEnding);
  973|      0|        writeTemp(tempIo, "%Exiv2BeginXMP: After %%PageTrailer" + lineEnding);
  974|      0|        writeTemp(tempIo, "[/EMC Exiv2_pdfmark" + lineEnding);
  975|      0|        writeTemp(tempIo, "[/NamespacePop Exiv2_pdfmark" + lineEnding);
  976|      0|        writeTemp(tempIo, "%Exiv2EndXMP" + lineEnding);
  977|      0|      }
  978|       |      // add EOF comment if necessary
  979|      0|      if (pos == posEndEps && posEof == posEndEps) {
  ------------------
  |  Branch (979:11): [True: 0, False: 0]
  |  Branch (979:31): [True: 0, False: 0]
  ------------------
  980|      0|        writeTemp(tempIo, "%%EOF" + lineEnding);
  981|      0|      }
  982|      0|      prevPos = pos;
  983|      0|      prevSkipPos = skipPos;
  984|      0|    }
  985|    189|    const uint32_t posEndEpsNew = posTemp(tempIo);
  986|       |#ifdef DEBUG
  987|       |    EXV_DEBUG << "readWriteEpsMetadata: New EPS size: " << (posEndEpsNew - posEpsNew) << "\n";
  988|       |#endif
  989|    189|    if (dosEps) {
  ------------------
  |  Branch (989:9): [True: 0, False: 189]
  ------------------
  990|       |      // write WMF and/or TIFF section if present
  991|      0|      writeTemp(tempIo, data + posWmf, sizeWmf);
  992|      0|      writeTemp(tempIo, data + posTiff, sizeTiff);
  993|       |#ifdef DEBUG
  994|       |      EXV_DEBUG << "readWriteEpsMetadata: New DOS EPS total size: " << posTemp(tempIo) << "\n";
  995|       |#endif
  996|       |      // write DOS EPS header
  997|      0|      if (tempIo.seek(0, BasicIo::beg) != 0) {
  ------------------
  |  Branch (997:11): [True: 0, False: 0]
  ------------------
  998|      0|#ifndef SUPPRESS_WARNINGS
  999|      0|        EXV_WARNING << "Internal error while seeking in temporary file.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
 1000|      0|#endif
 1001|      0|        throw Error(ErrorCode::kerImageWriteFailed);
 1002|      0|      }
 1003|      0|      byte dosEpsHeader[30];
 1004|      0|      dosEpsSignature.copy(reinterpret_cast<char*>(dosEpsHeader), dosEpsSignature.size());
 1005|      0|      ul2Data(dosEpsHeader + 4, posEpsNew, littleEndian);
 1006|      0|      ul2Data(dosEpsHeader + 8, posEndEpsNew - posEpsNew, littleEndian);
 1007|      0|      ul2Data(dosEpsHeader + 12, sizeWmf == 0 ? 0 : posEndEpsNew, littleEndian);
  ------------------
  |  Branch (1007:34): [True: 0, False: 0]
  ------------------
 1008|      0|      ul2Data(dosEpsHeader + 16, sizeWmf, littleEndian);
 1009|      0|      ul2Data(dosEpsHeader + 20, sizeTiff == 0 ? 0 : posEndEpsNew + sizeWmf, littleEndian);
  ------------------
  |  Branch (1009:34): [True: 0, False: 0]
  ------------------
 1010|      0|      ul2Data(dosEpsHeader + 24, sizeTiff, littleEndian);
 1011|      0|      us2Data(dosEpsHeader + 28, 0xFFFF, littleEndian);
 1012|      0|      writeTemp(tempIo, dosEpsHeader, sizeof(dosEpsHeader));
 1013|      0|    }
 1014|       |
 1015|       |    // copy temporary file to real output file
 1016|    189|    io.close();
 1017|    189|    io.transfer(tempIo);
 1018|    189|  }
 1019|  2.69k|}
epsimage.cpp:_ZN12_GLOBAL__N_18readLineERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPKhmm:
  117|   543k|size_t readLine(std::string& line, const byte* data, size_t startPos, size_t size) {
  118|   543k|  line.clear();
  119|   543k|  size_t pos = startPos;
  120|       |  // step through line
  121|  96.8M|  while (pos < size && data[pos] != '\r' && data[pos] != '\n') {
  ------------------
  |  Branch (121:10): [True: 96.8M, False: 5.19k]
  |  Branch (121:24): [True: 96.6M, False: 198k]
  |  Branch (121:45): [True: 96.2M, False: 339k]
  ------------------
  122|  96.2M|    line += data[pos];
  123|  96.2M|    pos++;
  124|  96.2M|  }
  125|       |  // skip line ending, if present
  126|   543k|  if (pos >= size)
  ------------------
  |  Branch (126:7): [True: 5.19k, False: 538k]
  ------------------
  127|  5.19k|    return pos;
  128|   538k|  pos++;
  129|   538k|  if (pos >= size)
  ------------------
  |  Branch (129:7): [True: 318, False: 537k]
  ------------------
  130|    318|    return pos;
  131|   537k|  if (data[pos - 1] == '\r' && data[pos] == '\n')
  ------------------
  |  Branch (131:7): [True: 198k, False: 339k]
  |  Branch (131:32): [True: 6.43k, False: 191k]
  ------------------
  132|  6.43k|    pos++;
  133|   537k|  return pos;
  134|   538k|}
epsimage.cpp:_ZN12_GLOBAL__N_115onlyWhitespacesERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
  110|  3.75k|bool onlyWhitespaces(const std::string& s) {
  111|       |  // According to the DSC 3.0 specification, 4.4 Parsing Rules,
  112|       |  // only spaces and tabs are considered to be white space characters.
  113|  3.75k|  return s.find_first_not_of(" \t") == std::string::npos;
  114|  3.75k|}
epsimage.cpp:_ZN12_GLOBAL__N_112readPrevLineERNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPKhmm:
  137|    886|size_t readPrevLine(std::string& line, const byte* data, size_t startPos, size_t size) {
  138|    886|  line.clear();
  139|    886|  size_t pos = startPos;
  140|    886|  if (pos > size)
  ------------------
  |  Branch (140:7): [True: 0, False: 886]
  ------------------
  141|      0|    return pos;
  142|       |  // skip line ending of previous line, if present
  143|    886|  if (pos <= 0)
  ------------------
  |  Branch (143:7): [True: 0, False: 886]
  ------------------
  144|      0|    return pos;
  145|    886|  if (data[pos - 1] == '\r' || data[pos - 1] == '\n') {
  ------------------
  |  Branch (145:7): [True: 409, False: 477]
  |  Branch (145:32): [True: 172, False: 305]
  ------------------
  146|    581|    pos--;
  147|    581|    if (pos <= 0)
  ------------------
  |  Branch (147:9): [True: 0, False: 581]
  ------------------
  148|      0|      return pos;
  149|    581|    if (data[pos - 1] == '\r' && data[pos] == '\n') {
  ------------------
  |  Branch (149:9): [True: 146, False: 435]
  |  Branch (149:34): [True: 41, False: 105]
  ------------------
  150|     41|      pos--;
  151|     41|      if (pos <= 0)
  ------------------
  |  Branch (151:11): [True: 0, False: 41]
  ------------------
  152|      0|        return pos;
  153|     41|    }
  154|    581|  }
  155|       |  // step through previous line
  156|  7.94M|  while (pos >= 1 && data[pos - 1] != '\r' && data[pos - 1] != '\n') {
  ------------------
  |  Branch (156:10): [True: 7.94M, False: 2]
  |  Branch (156:22): [True: 7.94M, False: 592]
  |  Branch (156:47): [True: 7.94M, False: 292]
  ------------------
  157|  7.94M|    pos--;
  158|  7.94M|    line += data[pos];
  159|  7.94M|  }
  160|    886|  std::reverse(line.begin(), line.end());
  161|    886|  return pos;
  162|    886|}
epsimage.cpp:_ZN12_GLOBAL__N_17findXmpERmS0_PKhmmb:
  165|  15.3k|void findXmp(size_t& xmpPos, size_t& xmpSize, const byte* data, size_t startPos, size_t size, bool write) {
  166|       |  // search for valid XMP header
  167|  15.3k|  xmpSize = 0;
  168|  21.6M|  for (xmpPos = startPos; xmpPos < size; xmpPos++) {
  ------------------
  |  Branch (168:27): [True: 21.6M, False: 2.44k]
  ------------------
  169|  21.6M|    if (data[xmpPos] != '\x00' && data[xmpPos] != '<')
  ------------------
  |  Branch (169:9): [True: 15.7M, False: 5.95M]
  |  Branch (169:35): [True: 15.6M, False: 56.7k]
  ------------------
  170|  15.6M|      continue;
  171|  48.0M|    for (auto&& header : xmpHeaders) {
  ------------------
  |  Branch (171:24): [True: 48.0M, False: 6.00M]
  ------------------
  172|  48.0M|      if (xmpPos + header.size() > size)
  ------------------
  |  Branch (172:11): [True: 49.9k, False: 48.0M]
  ------------------
  173|  49.9k|        continue;
  174|  48.0M|      if (memcmp(data + xmpPos, header.data(), header.size()) != 0)
  ------------------
  |  Branch (174:11): [True: 48.0M, False: 12.9k]
  ------------------
  175|  48.0M|        continue;
  176|       |#ifdef DEBUG
  177|       |      EXV_DEBUG << "findXmp: Found XMP header at position: " << xmpPos << "\n";
  178|       |#endif
  179|       |
  180|       |      // search for valid XMP trailer
  181|  37.0M|      for (size_t trailerPos = xmpPos + header.size(); trailerPos < size; trailerPos++) {
  ------------------
  |  Branch (181:56): [True: 37.0M, False: 110]
  ------------------
  182|  37.0M|        if (data[xmpPos] != '\x00' && data[xmpPos] != '<')
  ------------------
  |  Branch (182:13): [True: 37.0M, False: 0]
  |  Branch (182:39): [True: 0, False: 37.0M]
  ------------------
  183|      0|          continue;
  184|   148M|        for (const auto& [trailer, readOnly] : xmpTrailers) {
  ------------------
  |  Branch (184:46): [True: 148M, False: 37.0M]
  ------------------
  185|   148M|          if (trailerPos + trailer.size() > size)
  ------------------
  |  Branch (185:15): [True: 5.14k, False: 148M]
  ------------------
  186|  5.14k|            continue;
  187|   148M|          if (memcmp(data + trailerPos, trailer.data(), trailer.size()) != 0)
  ------------------
  |  Branch (187:15): [True: 148M, False: 12.8k]
  ------------------
  188|   148M|            continue;
  189|       |#ifdef DEBUG
  190|       |          EXV_DEBUG << "findXmp: Found XMP trailer at position: " << trailerPos << "\n";
  191|       |#endif
  192|       |
  193|  12.8k|          if (readOnly) {
  ------------------
  |  Branch (193:15): [True: 25, False: 12.8k]
  ------------------
  194|     25|#ifndef SUPPRESS_WARNINGS
  195|     25|            EXV_WARNING << "Unable to handle read-only XMP metadata yet. Please provide your "
  ------------------
  |  |  138|     25|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 25]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     25|  LogMsg(LogMsg::warn).os()
  ------------------
  196|      0|                           "sample EPS file to the Exiv2 project: http://dev.exiv2.org/projects/exiv2\n";
  197|     25|#endif
  198|     25|            throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (198:25): [True: 0, False: 25]
  ------------------
  199|     25|          }
  200|       |
  201|       |          // search for end of XMP trailer
  202|  3.09M|          for (size_t trailerEndPos = trailerPos + trailer.size(); trailerEndPos + xmpTrailerEnd.size() <= size;
  ------------------
  |  Branch (202:68): [True: 3.09M, False: 54]
  ------------------
  203|  3.09M|               trailerEndPos++) {
  204|  3.09M|            if (memcmp(data + trailerEndPos, xmpTrailerEnd.data(), xmpTrailerEnd.size()) == 0) {
  ------------------
  |  Branch (204:17): [True: 12.7k, False: 3.07M]
  ------------------
  205|  12.7k|              xmpSize = (trailerEndPos + xmpTrailerEnd.size()) - xmpPos;
  206|  12.7k|              return;
  207|  12.7k|            }
  208|  3.09M|          }
  209|     54|#ifndef SUPPRESS_WARNINGS
  210|     54|          EXV_WARNING << "Found XMP header but incomplete XMP trailer.\n";
  ------------------
  |  |  138|     54|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 54]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     54|  LogMsg(LogMsg::warn).os()
  ------------------
  211|     54|#endif
  212|     54|          throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (212:23): [True: 0, False: 54]
  ------------------
  213|  12.8k|        }
  214|  37.0M|      }
  215|    110|#ifndef SUPPRESS_WARNINGS
  216|    110|      EXV_WARNING << "Found XMP header but no XMP trailer.\n";
  ------------------
  |  |  138|    110|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 110]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    110|  LogMsg(LogMsg::warn).os()
  ------------------
  217|    110|#endif
  218|    110|      throw Error(write ? ErrorCode::kerImageWriteFailed : ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (218:19): [True: 0, False: 110]
  ------------------
  219|  12.9k|    }
  220|  6.01M|  }
  221|  15.3k|}

_ZN5Exiv26LogMsg8setLevelENS0_5LevelE:
  119|  25.7k|void LogMsg::setLevel(LogMsg::Level level) {
  120|  25.7k|  level_ = level;
  121|  25.7k|}
_ZN5Exiv26LogMsg5levelEv:
  127|  1.58M|LogMsg::Level LogMsg::level() {
  128|  1.58M|  return level_;
  129|  1.58M|}
_ZN5Exiv25ErrorC2ENS_9ErrorCodeE:
  155|  13.0k|Error::Error(ErrorCode code) : code_(code) {
  156|  13.0k|  setMsg(0);
  157|  13.0k|}
_ZNK5Exiv25Error4codeEv:
  159|      7|ErrorCode Error::code() const noexcept {
  160|      7|  return code_;
  161|      7|}
_ZN5Exiv25Error6setMsgEi:
  167|  14.1k|void Error::setMsg(int count) {
  168|  14.1k|  std::string msg{_(errList.at(static_cast<size_t>(code_)))};
  ------------------
  |  |   40|  14.1k|#define _(String) (String)
  ------------------
  169|  14.1k|  auto pos = msg.find("%0");
  170|  14.1k|  if (pos != std::string::npos) {
  ------------------
  |  Branch (170:7): [True: 0, False: 14.1k]
  ------------------
  171|      0|    msg.replace(pos, 2, std::to_string(static_cast<int>(code_)));
  172|      0|  }
  173|  14.1k|  if (count > 0) {
  ------------------
  |  Branch (173:7): [True: 1.09k, False: 13.0k]
  ------------------
  174|  1.09k|    pos = msg.find("%1");
  175|  1.09k|    if (pos != std::string::npos) {
  ------------------
  |  Branch (175:9): [True: 1.09k, False: 0]
  ------------------
  176|  1.09k|      msg.replace(pos, 2, arg1_);
  177|  1.09k|    }
  178|  1.09k|  }
  179|  14.1k|  if (count > 1) {
  ------------------
  |  Branch (179:7): [True: 0, False: 14.1k]
  ------------------
  180|      0|    pos = msg.find("%2");
  181|      0|    if (pos != std::string::npos) {
  ------------------
  |  Branch (181:9): [True: 0, False: 0]
  ------------------
  182|      0|      msg.replace(pos, 2, arg2_);
  183|      0|    }
  184|      0|  }
  185|  14.1k|  if (count > 2) {
  ------------------
  |  Branch (185:7): [True: 0, False: 14.1k]
  ------------------
  186|      0|    pos = msg.find("%3");
  187|      0|    if (pos != std::string::npos) {
  ------------------
  |  Branch (187:9): [True: 0, False: 0]
  ------------------
  188|      0|      msg.replace(pos, 2, arg3_);
  189|      0|    }
  190|      0|  }
  191|  14.1k|  msg_ = std::move(msg);
  192|  14.1k|}

_ZN5Exiv29ExifdatumC2ERKNS_7ExifKeyEPKNS_5ValueE:
  157|  1.20M|Exifdatum::Exifdatum(const ExifKey& key, const Value* pValue) : key_(key.clone()) {
  158|  1.20M|  if (pValue)
  ------------------
  |  Branch (158:7): [True: 1.19M, False: 3.41k]
  ------------------
  159|  1.19M|    value_ = pValue->clone();
  160|  1.20M|}
_ZN5Exiv29ExifdatumC2ERKS0_:
  162|  1.34M|Exifdatum::Exifdatum(const Exifdatum& rhs) {
  163|  1.34M|  if (rhs.key_)
  ------------------
  |  Branch (163:7): [True: 1.34M, False: 0]
  ------------------
  164|  1.34M|    key_ = rhs.key_->clone();  // deep copy
  165|  1.34M|  if (rhs.value_)
  ------------------
  |  Branch (165:7): [True: 1.34M, False: 0]
  ------------------
  166|  1.34M|    value_ = rhs.value_->clone();  // deep copy
  167|  1.34M|}
_ZN5Exiv29ExifdatumD2Ev:
  169|  2.54M|Exifdatum::~Exifdatum() = default;
_ZNK5Exiv29Exifdatum5valueEv:
  203|   161k|const Value& Exifdatum::value() const {
  204|   161k|  if (!value_)
  ------------------
  |  Branch (204:7): [True: 0, False: 161k]
  ------------------
  205|      0|    throw Error(ErrorCode::kerValueNotSet, key());
  206|   161k|  return *value_;
  207|   161k|}
_ZN5Exiv29ExifdatumaSERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  224|  2.32k|Exifdatum& Exifdatum::operator=(const std::string& value) {
  225|  2.32k|  setValue(value);
  226|  2.32k|  return *this;
  227|  2.32k|}
_ZN5Exiv29ExifdatumaSERKt:
  229|     22|Exifdatum& Exifdatum::operator=(const uint16_t& value) {
  230|     22|  return Exiv2::setValue(*this, value);
  231|     22|}
_ZN5Exiv29ExifdatumaSERKj:
  233|  2.54k|Exifdatum& Exifdatum::operator=(const uint32_t& value) {
  234|  2.54k|  return Exiv2::setValue(*this, value);
  235|  2.54k|}
_ZN5Exiv29ExifdatumaSERKNS_5ValueE:
  253|  8.41k|Exifdatum& Exifdatum::operator=(const Value& value) {
  254|  8.41k|  setValue(&value);
  255|  8.41k|  return *this;
  256|  8.41k|}
_ZN5Exiv29Exifdatum8setValueEPKNS_5ValueE:
  258|  8.41k|void Exifdatum::setValue(const Value* pValue) {
  259|  8.41k|  value_.reset();
  260|  8.41k|  if (pValue)
  ------------------
  |  Branch (260:7): [True: 8.41k, False: 0]
  ------------------
  261|  8.41k|    value_ = pValue->clone();
  262|  8.41k|}
_ZN5Exiv29Exifdatum8setValueERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  264|  2.52k|int Exifdatum::setValue(const std::string& value) {
  265|  2.52k|  if (!value_) {
  ------------------
  |  Branch (265:7): [True: 1.23k, False: 1.29k]
  ------------------
  266|  1.23k|    TypeId type = key_->defaultTypeId();
  267|  1.23k|    value_ = Value::create(type);
  268|  1.23k|  }
  269|  2.52k|  return value_->read(value);
  270|  2.52k|}
_ZNK5Exiv29Exifdatum11setDataAreaEPKhm:
  272|     19|int Exifdatum::setDataArea(const byte* buf, size_t len) const {
  273|     19|  return value_ ? value_->setDataArea(buf, len) : -1;
  ------------------
  |  Branch (273:10): [True: 19, False: 0]
  ------------------
  274|     19|}
_ZNK5Exiv29Exifdatum3keyEv:
  276|  40.6M|std::string Exifdatum::key() const {
  277|  40.6M|  return key_ ? key_->key() : "";
  ------------------
  |  Branch (277:10): [True: 40.6M, False: 0]
  ------------------
  278|  40.6M|}
_ZNK5Exiv29Exifdatum9groupNameEv:
  284|   900k|std::string Exifdatum::groupName() const {
  285|   900k|  return key_ ? key_->groupName() : "";
  ------------------
  |  Branch (285:10): [True: 900k, False: 0]
  ------------------
  286|   900k|}
_ZNK5Exiv29Exifdatum3tagEv:
  300|   657k|uint16_t Exifdatum::tag() const {
  301|   657k|  return key_ ? key_->tag() : 0xffff;
  ------------------
  |  Branch (301:10): [True: 657k, False: 0]
  ------------------
  302|   657k|}
_ZNK5Exiv29Exifdatum5ifdIdEv:
  304|   142k|IfdId Exifdatum::ifdId() const {
  305|   142k|  return key_ ? key_->ifdId() : IfdId::ifdIdNotSet;
  ------------------
  |  Branch (305:10): [True: 142k, False: 0]
  ------------------
  306|   142k|}
_ZNK5Exiv29Exifdatum3idxEv:
  312|   142k|int Exifdatum::idx() const {
  313|   142k|  return key_ ? key_->idx() : 0;
  ------------------
  |  Branch (313:10): [True: 142k, False: 0]
  ------------------
  314|   142k|}
_ZNK5Exiv29Exifdatum4copyEPhNS_9ByteOrderE:
  316|    107|size_t Exifdatum::copy(byte* buf, ByteOrder byteOrder) const {
  317|    107|  return value_ ? value_->copy(buf, byteOrder) : 0;
  ------------------
  |  Branch (317:10): [True: 107, False: 0]
  ------------------
  318|    107|}
_ZNK5Exiv29Exifdatum6typeIdEv:
  320|  1.00k|TypeId Exifdatum::typeId() const {
  321|  1.00k|  return value_ ? value_->typeId() : invalidTypeId;
  ------------------
  |  Branch (321:10): [True: 1.00k, False: 0]
  ------------------
  322|  1.00k|}
_ZNK5Exiv29Exifdatum8typeSizeEv:
  328|    540|size_t Exifdatum::typeSize() const {
  329|    540|  return TypeInfo::typeSize(typeId());
  330|    540|}
_ZNK5Exiv29Exifdatum5countEv:
  332|  98.3k|size_t Exifdatum::count() const {
  333|  98.3k|  return value_ ? value_->count() : 0;
  ------------------
  |  Branch (333:10): [True: 98.3k, False: 0]
  ------------------
  334|  98.3k|}
_ZNK5Exiv29Exifdatum4sizeEv:
  336|   142k|size_t Exifdatum::size() const {
  337|   142k|  return value_ ? value_->size() : 0;
  ------------------
  |  Branch (337:10): [True: 142k, False: 0]
  ------------------
  338|   142k|}
_ZNK5Exiv29Exifdatum8toStringEv:
  340|  5.09k|std::string Exifdatum::toString() const {
  341|  5.09k|  return value_ ? value_->toString() : "";
  ------------------
  |  Branch (341:10): [True: 5.09k, False: 0]
  ------------------
  342|  5.09k|}
_ZNK5Exiv29Exifdatum7toInt64Em:
  348|   110k|int64_t Exifdatum::toInt64(size_t n) const {
  349|   110k|  return value_ ? value_->toInt64(n) : -1;
  ------------------
  |  Branch (349:10): [True: 110k, False: 0]
  ------------------
  350|   110k|}
_ZNK5Exiv29Exifdatum8getValueEv:
  360|   142k|Value::UniquePtr Exifdatum::getValue() const {
  361|   142k|  return value_ ? value_->clone() : nullptr;
  ------------------
  |  Branch (361:10): [True: 142k, False: 0]
  ------------------
  362|   142k|}
_ZNK5Exiv29Exifdatum12sizeDataAreaEv:
  364|    607|size_t Exifdatum::sizeDataArea() const {
  365|    607|  return value_ ? value_->sizeDataArea() : 0;
  ------------------
  |  Branch (365:10): [True: 607, False: 0]
  ------------------
  366|    607|}
_ZNK5Exiv29Exifdatum8dataAreaEv:
  368|    170|DataBuf Exifdatum::dataArea() const {
  369|    170|  return value_ ? value_->dataArea() : DataBuf(nullptr, 0);
  ------------------
  |  Branch (369:10): [True: 170, False: 0]
  ------------------
  370|    170|}
_ZN5Exiv210ExifThumbCC2ERKNS_8ExifDataE:
  372|     19|ExifThumbC::ExifThumbC(const ExifData& exifData) : exifData_(exifData) {
  373|     19|}
_ZN5Exiv29ExifThumbC2ERNS_8ExifDataE:
  411|     19|ExifThumb::ExifThumb(ExifData& exifData) : ExifThumbC(exifData), exifData_(exifData) {
  412|     19|}
_ZN5Exiv29ExifThumb16setJpegThumbnailEPKhm:
  435|     19|void ExifThumb::setJpegThumbnail(const byte* buf, size_t size) {
  436|     19|  exifData_["Exif.Thumbnail.Compression"] = std::uint16_t{6};
  437|     19|  Exifdatum& format = exifData_["Exif.Thumbnail.JPEGInterchangeFormat"];
  438|     19|  format = 0U;
  439|     19|  format.setDataArea(buf, size);
  440|     19|  exifData_["Exif.Thumbnail.JPEGInterchangeFormatLength"] = static_cast<uint32_t>(size);
  441|     19|}
_ZN5Exiv28ExifDataixERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  447|  22.1k|Exifdatum& ExifData::operator[](const std::string& key) {
  448|  22.1k|  ExifKey exifKey(key);
  449|  22.1k|  auto pos = findKey(exifKey);
  450|  22.1k|  if (pos == end()) {
  ------------------
  |  Branch (450:7): [True: 3.21k, False: 18.9k]
  ------------------
  451|  3.21k|    return exifMetadata_.emplace_back(exifKey);
  452|  3.21k|  }
  453|  18.9k|  return *pos;
  454|  22.1k|}
_ZN5Exiv28ExifData3addERKNS_7ExifKeyEPKNS_5ValueE:
  456|  1.19M|void ExifData::add(const ExifKey& key, const Value* pValue) {
  457|  1.19M|  add(Exifdatum(key, pValue));
  458|  1.19M|}
_ZN5Exiv28ExifData3addERKNS_9ExifdatumE:
  460|  1.19M|void ExifData::add(const Exifdatum& exifdatum) {
  461|       |  // allow duplicates
  462|  1.19M|  exifMetadata_.push_back(exifdatum);
  463|  1.19M|}
_ZNK5Exiv28ExifData7findKeyERKNS_7ExifKeyE:
  465|   681k|ExifData::const_iterator ExifData::findKey(const ExifKey& key) const {
  466|   681k|  return std::find_if(exifMetadata_.begin(), exifMetadata_.end(), FindExifdatumByKey(key.key()));
  467|   681k|}
_ZN5Exiv28ExifData7findKeyERKNS_7ExifKeyE:
  469|  71.4k|ExifData::iterator ExifData::findKey(const ExifKey& key) {
  470|  71.4k|  return std::find_if(exifMetadata_.begin(), exifMetadata_.end(), FindExifdatumByKey(key.key()));
  471|  71.4k|}
_ZN5Exiv28ExifData5clearEv:
  473|  27.5k|void ExifData::clear() {
  474|  27.5k|  exifMetadata_.clear();
  475|  27.5k|}
_ZN5Exiv28ExifData5eraseENSt3__115__list_iteratorINS_9ExifdatumEPvEES5_:
  485|  4.40k|ExifData::iterator ExifData::erase(ExifData::iterator beg, ExifData::iterator end) {
  486|  4.40k|  return exifMetadata_.erase(beg, end);
  487|  4.40k|}
_ZN5Exiv210ExifParser6decodeERNS_8ExifDataEPKhm:
  493|    300|ByteOrder ExifParser::decode(ExifData& exifData, const byte* pData, size_t size) {
  494|    300|  IptcData iptcData;
  495|    300|  XmpData xmpData;
  496|    300|  ByteOrder bo = TiffParser::decode(exifData, iptcData, xmpData, pData, size);
  497|    300|#ifndef SUPPRESS_WARNINGS
  498|    300|  if (!iptcData.empty()) {
  ------------------
  |  Branch (498:7): [True: 12, False: 288]
  ------------------
  499|     12|    EXV_WARNING << "Ignoring IPTC information encoded in the Exif data.\n";
  ------------------
  |  |  138|     12|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 12]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     12|  LogMsg(LogMsg::warn).os()
  ------------------
  500|     12|  }
  501|    300|  if (!xmpData.empty()) {
  ------------------
  |  Branch (501:7): [True: 1, False: 299]
  ------------------
  502|      1|    EXV_WARNING << "Ignoring XMP information encoded in the Exif data.\n";
  ------------------
  |  |  138|      1|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 1]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      1|  LogMsg(LogMsg::warn).os()
  ------------------
  503|      1|  }
  504|    300|#endif
  505|    300|  return bo;
  506|    300|}
exif.cpp:_ZNK12_GLOBAL__N_118FindExifdatumByKeyclERKN5Exiv29ExifdatumE:
   45|  40.6M|  bool operator()(const Exiv2::Exifdatum& exifdatum) const {
   46|  40.6M|    return key_ == exifdatum.key();
   47|  40.6M|  }
exif.cpp:_ZN12_GLOBAL__N_118FindExifdatumByKeyC2ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   39|   752k|  explicit FindExifdatumByKey(std::string key) : key_(std::move(key)) {
   40|   752k|  }
_ZN5Exiv28setValueItEERNS_9ExifdatumES2_RKT_:
  150|     22|Exiv2::Exifdatum& setValue(Exiv2::Exifdatum& exifDatum, const T& value) {
  151|     22|  auto v = std::make_unique<Exiv2::ValueType<T>>();
  152|     22|  v->value_.push_back(value);
  153|     22|  exifDatum.value_ = std::move(v);
  154|     22|  return exifDatum;
  155|     22|}
_ZN5Exiv28setValueIjEERNS_9ExifdatumES2_RKT_:
  150|  2.54k|Exiv2::Exifdatum& setValue(Exiv2::Exifdatum& exifDatum, const T& value) {
  151|  2.54k|  auto v = std::make_unique<Exiv2::ValueType<T>>();
  152|  2.54k|  v->value_.push_back(value);
  153|  2.54k|  exifDatum.value_ = std::move(v);
  154|  2.54k|  return exifDatum;
  155|  2.54k|}

_ZN5Exiv28Internal13FujiMakerNote7tagListEv:
   19|    909|  static constexpr auto tagList() {
   20|    909|    return tagInfo_;
   21|    909|  }

_ZN5Exiv28GifImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
   19|     43|GifImage::GifImage(BasicIo::UniquePtr io) : Image(ImageType::gif, mdNone, std::move(io)) {
   20|     43|}
_ZNK5Exiv28GifImage8mimeTypeEv:
   22|      6|std::string GifImage::mimeType() const {
   23|      6|  return "image/gif";
   24|      6|}
_ZN5Exiv28GifImage12readMetadataEv:
   41|     33|void GifImage::readMetadata() {
   42|       |#ifdef EXIV2_DEBUG_MESSAGES
   43|       |  std::cerr << "Exiv2::GifImage::readMetadata: Reading GIF file " << io_->path() << "\n";
   44|       |#endif
   45|     33|  if (io_->open() != 0) {
  ------------------
  |  Branch (45:7): [True: 0, False: 33]
  ------------------
   46|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   47|      0|  }
   48|     33|  IoCloser closer(*io_);
   49|       |  // Ensure that this is the correct image type
   50|     33|  if (!isGifType(*io_, true)) {
  ------------------
  |  Branch (50:7): [True: 0, False: 33]
  ------------------
   51|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (51:9): [True: 0, False: 0]
  |  Branch (51:25): [True: 0, False: 0]
  ------------------
   52|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   53|      0|    throw Error(ErrorCode::kerNotAnImage, "GIF");
   54|      0|  }
   55|     33|  clearMetadata();
   56|       |
   57|     33|  byte buf[4];
   58|     33|  if (io_->read(buf, sizeof(buf)) == sizeof(buf)) {
  ------------------
  |  Branch (58:7): [True: 33, False: 0]
  ------------------
   59|     33|    pixelWidth_ = getShort(buf, littleEndian);
   60|     33|    pixelHeight_ = getShort(buf + 2, littleEndian);
   61|     33|  }
   62|     33|}  // GifImage::readMetadata
_ZN5Exiv214newGifInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
   71|     43|Image::UniquePtr newGifInstance(BasicIo::UniquePtr io, bool /*create*/) {
   72|     43|  auto image = std::make_unique<GifImage>(std::move(io));
   73|     43|  if (!image->good()) {
  ------------------
  |  Branch (73:7): [True: 10, False: 33]
  ------------------
   74|     10|    return nullptr;
   75|     10|  }
   76|     33|  return image;
   77|     43|}
_ZN5Exiv29isGifTypeERNS_7BasicIoEb:
   79|  15.3k|bool isGifType(BasicIo& iIo, bool advance) {
   80|  15.3k|  const int32_t len = 6;
   81|  15.3k|  const std::array<byte, len> Gif87aId{'G', 'I', 'F', '8', '7', 'a'};
   82|  15.3k|  const std::array<byte, len> Gif89aId{'G', 'I', 'F', '8', '9', 'a'};
   83|  15.3k|  std::array<byte, len> buf;
   84|  15.3k|  iIo.read(buf.data(), len);
   85|  15.3k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (85:7): [True: 0, False: 15.3k]
  |  Branch (85:22): [True: 330, False: 15.0k]
  ------------------
   86|    330|    return false;
   87|    330|  }
   88|  15.0k|  bool matched = buf == Gif87aId || buf == Gif89aId;
  ------------------
  |  Branch (88:18): [True: 42, False: 15.0k]
  |  Branch (88:37): [True: 67, False: 14.9k]
  ------------------
   89|  15.0k|  if (!advance || !matched) {
  ------------------
  |  Branch (89:7): [True: 15.0k, False: 33]
  |  Branch (89:19): [True: 0, False: 33]
  ------------------
   90|  15.0k|    iIo.seek(-len, BasicIo::cur);
   91|  15.0k|  }
   92|  15.0k|  return matched;
   93|  15.3k|}

_Z24string_from_unterminatedPKcm:
   13|  11.8k|std::string string_from_unterminated(const char* data, size_t data_length) {
   14|  11.8k|  if (data_length == 0) {
  ------------------
  |  Branch (14:7): [True: 0, False: 11.8k]
  ------------------
   15|      0|    return {};
   16|      0|  }
   17|  11.8k|  const size_t StringLength = strnlen(data, data_length);
   18|  11.8k|  return {data, StringLength};
   19|  11.8k|}
_ZN5Exiv212readQWORDTagERKNSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEE:
   22|  2.47k|uint64_t readQWORDTag(const BasicIo::UniquePtr& io) {
   23|  2.47k|  Internal::enforce(QWORD <= io->size() - io->tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
   24|  2.47k|  auto FieldBuf = io->read(QWORD);
   25|  2.47k|  return FieldBuf.read_uint64(0, littleEndian);
   26|  2.47k|}
_ZN5Exiv212readDWORDTagERKNSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEE:
   28|  30.6k|uint32_t readDWORDTag(const BasicIo::UniquePtr& io) {
   29|  30.6k|  Internal::enforce(DWORD <= io->size() - io->tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
   30|  30.6k|  DataBuf FieldBuf = io->read(DWORD);
   31|  30.6k|  return FieldBuf.read_uint32(0, littleEndian);
   32|  30.6k|}
_ZN5Exiv211readWORDTagERKNSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEE:
   34|  3.41k|uint16_t readWORDTag(const BasicIo::UniquePtr& io) {
   35|  3.41k|  Internal::enforce(WORD <= io->size() - io->tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
   36|  3.41k|  DataBuf FieldBuf = io->read(WORD);
   37|  3.41k|  return FieldBuf.read_uint16(0, littleEndian);
   38|  3.41k|}
_ZN5Exiv218readStringWcharTagERKNSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEm:
   40|    416|std::string readStringWcharTag(const BasicIo::UniquePtr& io, size_t length) {
   41|    416|  Internal::enforce(length <= io->size() - io->tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
   42|    416|  DataBuf FieldBuf(length + 1);
   43|    416|  io->readOrThrow(FieldBuf.data(), length, ErrorCode::kerFailedToReadImageData);
   44|    416|  std::string wst(FieldBuf.begin(), FieldBuf.end() - 3);
   45|    416|  if (wst.size() % 2 != 0)
  ------------------
  |  Branch (45:7): [True: 92, False: 324]
  ------------------
   46|     92|    Exiv2::convertStringCharset(wst, "UCS-2LE", "UTF-8");
   47|    416|  Exiv2::convertStringCharset(wst, "UCS-2LE", "UTF-8");
   48|    416|  return wst;
   49|    416|}
_ZN5Exiv213readStringTagERKNSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEm:
   51|  22.7k|std::string readStringTag(const BasicIo::UniquePtr& io, size_t length) {
   52|  22.7k|  Internal::enforce(length <= io->size() - io->tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
   53|  22.7k|  DataBuf FieldBuf(length + 1);
   54|  22.7k|  io->readOrThrow(FieldBuf.data(), length, ErrorCode::kerFailedToReadImageData);
   55|  22.7k|  return Exiv2::toString(FieldBuf.data()).substr(0, length);
   56|  22.7k|}
_ZN5Exiv214getAspectRatioEmm:
   58|  3.88k|std::string getAspectRatio(uint64_t width, uint64_t height) {
   59|  3.88k|  if (height == 0 || width == 0)
  ------------------
  |  Branch (59:7): [True: 506, False: 3.38k]
  |  Branch (59:22): [True: 28, False: 3.35k]
  ------------------
   60|    534|    return std::to_string(width) + ":" + std::to_string(height);
   61|       |
   62|  3.35k|  auto ratioWidth = width / std::gcd(width, height);
   63|  3.35k|  auto ratioHeight = height / std::gcd(width, height);
   64|  3.35k|  return std::to_string(ratioWidth) + ":" + std::to_string(ratioHeight);
   65|  3.88k|}

_ZN5Exiv25ImageC2ENS_9ImageTypeEtNSt3__110unique_ptrINS_7BasicIoENS2_14default_deleteIS4_EEEE:
  140|  31.9k|    io_(std::move(io)), imageType_(type), supportedMetadata_(supportedMetadata) {
  141|  31.9k|}
_ZN5Exiv25ImageD2Ev:
  143|  31.9k|Image::~Image() = default;
_ZN5Exiv25Image19isBigEndianPlatformEv:
  181|    405|bool Image::isBigEndianPlatform() {
  182|    405|  return std::endian::native == std::endian::big;
  183|    405|}
_ZN5Exiv25Image8byteSwapEjb:
  205|  1.19k|uint32_t Image::byteSwap(uint32_t value, bool bSwap) {
  206|       |#ifdef __cpp_lib_byteswap
  207|       |  return bSwap ? std::byteswap(value) : value;
  208|       |#elif defined(_MSC_VER)
  209|       |  return bSwap ? _byteswap_ulong(value) : value;
  210|       |#else
  211|  1.19k|  uint32_t result = 0;
  212|  1.19k|  result |= (value & 0x000000FFU) << 24;
  213|  1.19k|  result |= (value & 0x0000FF00U) << 8;
  214|  1.19k|  result |= (value & 0x00FF0000U) >> 8;
  215|  1.19k|  result |= (value & 0xFF000000U) >> 24;
  216|  1.19k|  return bSwap ? result : value;
  ------------------
  |  Branch (216:10): [True: 0, False: 1.19k]
  ------------------
  217|  1.19k|#endif
  218|  1.19k|}
_ZN5Exiv25Image13clearMetadataEv:
  537|  27.1k|void Image::clearMetadata() {
  538|  27.1k|  clearExifData();
  539|  27.1k|  clearIptcData();
  540|  27.1k|  clearXmpPacket();
  541|  27.1k|  clearXmpData();
  542|  27.1k|  clearComment();
  543|  27.1k|  clearIccProfile();
  544|  27.1k|}
_ZN5Exiv25Image8exifDataEv:
  546|  5.30k|ExifData& Image::exifData() {
  547|  5.30k|  return exifData_;
  548|  5.30k|}
_ZN5Exiv25Image8iptcDataEv:
  550|  2.60k|IptcData& Image::iptcData() {
  551|  2.60k|  return iptcData_;
  552|  2.60k|}
_ZN5Exiv25Image7xmpDataEv:
  554|  9.30k|XmpData& Image::xmpData() {
  555|  9.30k|  return xmpData_;
  556|  9.30k|}
_ZN5Exiv25Image9xmpPacketEv:
  558|  2.58k|std::string& Image::xmpPacket() {
  559|       |  // Serialize the current XMP
  560|  2.58k|  if (!xmpData_.empty() && !writeXmpFromPacket()) {
  ------------------
  |  Branch (560:7): [True: 0, False: 2.58k]
  |  Branch (560:28): [True: 0, False: 0]
  ------------------
  561|      0|    XmpParser::encode(xmpPacket_, xmpData_, XmpParser::useCompactFormat | XmpParser::omitAllFormatting);
  562|      0|  }
  563|  2.58k|  return xmpPacket_;
  564|  2.58k|}
_ZN5Exiv25Image13clearExifDataEv:
  586|  27.1k|void Image::clearExifData() {
  587|  27.1k|  exifData_.clear();
  588|  27.1k|}
_ZN5Exiv25Image13clearIptcDataEv:
  594|  27.1k|void Image::clearIptcData() {
  595|  27.1k|  iptcData_.clear();
  596|  27.1k|}
_ZN5Exiv25Image14clearXmpPacketEv:
  602|  27.1k|void Image::clearXmpPacket() {
  603|  27.1k|  xmpPacket_.clear();
  604|  27.1k|  writeXmpFromPacket(true);
  605|  27.1k|}
_ZN5Exiv25Image12clearXmpDataEv:
  614|  27.1k|void Image::clearXmpData() {
  615|  27.1k|  xmpData_.clear();
  616|  27.1k|  writeXmpFromPacket(false);
  617|  27.1k|}
_ZN5Exiv25Image18writeXmpFromPacketEb:
  625|  54.2k|void Image::writeXmpFromPacket(bool flag) {
  626|  54.2k|  writeXmpFromPacket_ = flag;
  627|  54.2k|}
_ZN5Exiv25Image12clearCommentEv:
  633|  27.1k|void Image::clearComment() {
  634|  27.1k|  comment_.erase();
  635|  27.1k|}
_ZN5Exiv25Image10setCommentERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  637|    105|void Image::setComment(const std::string& comment) {
  638|    105|  comment_ = comment;
  639|    105|}
_ZN5Exiv25Image13setIccProfileEONS_7DataBufEb:
  641|    148|void Image::setIccProfile(Exiv2::DataBuf&& iccProfile, bool bTestValid) {
  642|    148|  iccProfile_ = std::move(iccProfile);
  643|    148|  if (bTestValid) {
  ------------------
  |  Branch (643:7): [True: 148, False: 0]
  ------------------
  644|    148|    checkIccProfile();
  645|    148|  }
  646|    148|}
_ZN5Exiv25Image16appendIccProfileEPKhmb:
  648|  2.14k|void Image::appendIccProfile(const uint8_t* bytes, size_t size, bool bTestValid) {
  649|  2.14k|  if (size == 0) {
  ------------------
  |  Branch (649:7): [True: 1.50k, False: 642]
  ------------------
  650|  1.50k|    return;
  651|  1.50k|  }
  652|    642|  const size_t start = iccProfile_.size();
  653|    642|  iccProfile_.resize(Safe::add(start, size));
  654|    642|  memcpy(iccProfile_.data(start), bytes, size);
  655|    642|  if (bTestValid) {
  ------------------
  |  Branch (655:7): [True: 24, False: 618]
  ------------------
  656|     24|    checkIccProfile();
  657|     24|  }
  658|    642|}
_ZNK5Exiv25Image15checkIccProfileEv:
  660|    172|void Image::checkIccProfile() const {
  661|    172|  if (iccProfile_.size() < sizeof(long)) {
  ------------------
  |  Branch (661:7): [True: 22, False: 150]
  ------------------
  662|     22|    throw Error(ErrorCode::kerInvalidIccProfile);
  663|     22|  }
  664|    150|  const size_t size = iccProfile_.read_uint32(0, bigEndian);
  665|    150|  if (size != iccProfile_.size()) {
  ------------------
  |  Branch (665:7): [True: 60, False: 90]
  ------------------
  666|     60|    throw Error(ErrorCode::kerInvalidIccProfile);
  667|     60|  }
  668|    150|}
_ZN5Exiv25Image15clearIccProfileEv:
  670|  27.1k|void Image::clearIccProfile() {
  671|  27.1k|  iccProfile_.reset();
  672|  27.1k|}
_ZN5Exiv25Image12setByteOrderENS_9ByteOrderE:
  674|  8.97k|void Image::setByteOrder(ByteOrder byteOrder) {
  675|  8.97k|  byteOrder_ = byteOrder;
  676|  8.97k|}
_ZNK5Exiv25Image9byteOrderEv:
  678|     40|ByteOrder Image::byteOrder() const {
  679|     40|  return byteOrder_;
  680|     40|}
_ZNK5Exiv25Image10pixelWidthEv:
  682|  1.78k|uint32_t Image::pixelWidth() const {
  683|  1.78k|  return pixelWidth_;
  684|  1.78k|}
_ZNK5Exiv25Image11pixelHeightEv:
  686|  1.78k|uint32_t Image::pixelHeight() const {
  687|  1.78k|  return pixelHeight_;
  688|  1.78k|}
_ZNK5Exiv25Image8exifDataEv:
  690|   616k|const ExifData& Image::exifData() const {
  691|   616k|  return exifData_;
  692|   616k|}
_ZNK5Exiv25Image7xmpDataEv:
  698|  16.3k|const XmpData& Image::xmpData() const {
  699|  16.3k|  return xmpData_;
  700|  16.3k|}
_ZNK5Exiv25Image7commentEv:
  702|    860|std::string Image::comment() const {
  703|    860|  return comment_;
  704|    860|}
_ZNK5Exiv25Image2ioEv:
  710|  22.3k|BasicIo& Image::io() const {
  711|  22.3k|  return *io_;
  712|  22.3k|}
_ZNK5Exiv25Image14nativePreviewsEv:
  718|  69.1k|const NativePreviewList& Image::nativePreviews() const {
  719|  69.1k|  return nativePreviews_;
  720|  69.1k|}
_ZNK5Exiv25Image4goodEv:
  722|  31.8k|bool Image::good() const {
  723|  31.8k|  if (io_->open() != 0)
  ------------------
  |  Branch (723:7): [True: 0, False: 31.8k]
  ------------------
  724|      0|    return false;
  725|  31.8k|  IoCloser closer(*io_);
  726|  31.8k|  return ImageFactory::checkType(imageType_, *io_, false);
  727|  31.8k|}
_ZN5Exiv212ImageFactory9checkTypeENS_9ImageTypeERNS_7BasicIoEb:
  777|  31.8k|bool ImageFactory::checkType(ImageType type, BasicIo& io, bool advance) {
  778|  31.8k|  if (auto r = Exiv2::find(registry, type))
  ------------------
  |  Branch (778:12): [True: 31.8k, False: 0]
  ------------------
  779|  31.8k|    return r->isThisType_(io, advance);
  780|      0|  return false;
  781|  31.8k|}
_ZN5Exiv212ImageFactory4openEPKhm:
  863|  32.7k|Image::UniquePtr ImageFactory::open(const byte* data, size_t size) {
  864|  32.7k|  auto image = open(std::make_unique<MemIo>(data, size));  // may throw
  865|  32.7k|  if (!image)
  ------------------
  |  Branch (865:7): [True: 749, False: 32.0k]
  ------------------
  866|    749|    throw Error(ErrorCode::kerMemoryContainsUnknownImageType);
  867|  32.0k|  return image;
  868|  32.7k|}
_ZN5Exiv212ImageFactory4openENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
  870|  32.7k|Image::UniquePtr ImageFactory::open(BasicIo::UniquePtr io) {
  871|  32.7k|  if (io->open() != 0) {
  ------------------
  |  Branch (871:7): [True: 0, False: 32.7k]
  ------------------
  872|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io->path(), strError());
  873|      0|  }
  874|   603k|  for (const auto& r : registry) {
  ------------------
  |  Branch (874:22): [True: 603k, False: 933]
  ------------------
  875|   603k|    if (r.isThisType_(*io, false)) {
  ------------------
  |  Branch (875:9): [True: 31.8k, False: 571k]
  ------------------
  876|  31.8k|      return r.newInstance_(std::move(io), false);
  877|  31.8k|    }
  878|   603k|  }
  879|    933|  return nullptr;
  880|  32.7k|}
_ZN5Exiv26appendERNSt3__16vectorIhNS0_9allocatorIhEEEEPKhm:
  918|  7.28k|void append(Blob& blob, const byte* buf, size_t len) {
  919|  7.28k|  if (len != 0) {
  ------------------
  |  Branch (919:7): [True: 7.28k, False: 0]
  ------------------
  920|  7.28k|    Blob::size_type size = blob.size();
  921|  7.28k|    if (blob.capacity() - size < len) {
  ------------------
  |  Branch (921:9): [True: 411, False: 6.87k]
  ------------------
  922|    411|      blob.reserve(size + 65536);
  923|    411|    }
  924|  7.28k|    blob.resize(size + len);
  925|  7.28k|    std::copy_n(buf, len, blob.begin() + size);
  926|  7.28k|  }
  927|  7.28k|}  // append
image.cpp:_ZNK12_GLOBAL__N_18RegistryeqERKN5Exiv29ImageTypeE:
   66|   579k|  bool operator==(const ImageType& imageType) const {
   67|   579k|    return imageType == imageType_;
   68|   579k|  }

_ZN5Exiv29IptcdatumC2ERKNS_7IptcKeyEPKNS_5ValueE:
   56|  31.3k|Iptcdatum::Iptcdatum(const IptcKey& key, const Value* pValue) : key_(key.clone()) {
   57|  31.3k|  if (pValue)
  ------------------
  |  Branch (57:7): [True: 28.1k, False: 3.14k]
  ------------------
   58|  28.1k|    value_ = pValue->clone();
   59|  31.3k|}
_ZN5Exiv29IptcdatumC2ERKS0_:
   61|  31.8k|Iptcdatum::Iptcdatum(const Iptcdatum& rhs) {
   62|  31.8k|  if (rhs.key_)
  ------------------
  |  Branch (62:7): [True: 31.8k, False: 0]
  ------------------
   63|  31.8k|    key_ = rhs.key_->clone();  // deep copy
   64|  31.8k|  if (rhs.value_)
  ------------------
  |  Branch (64:7): [True: 31.8k, False: 0]
  ------------------
   65|  31.8k|    value_ = rhs.value_->clone();  // deep copy
   66|  31.8k|}
_ZN5Exiv29IptcdatumD2Ev:
   68|  63.1k|Iptcdatum::~Iptcdatum() = default;
_ZNK5Exiv29Iptcdatum6recordEv:
   86|  75.0k|uint16_t Iptcdatum::record() const {
   87|  75.0k|  return key_ ? key_->record() : 0;
  ------------------
  |  Branch (87:10): [True: 75.0k, False: 0]
  ------------------
   88|  75.0k|}
_ZNK5Exiv29Iptcdatum3tagEv:
  110|   274k|uint16_t Iptcdatum::tag() const {
  111|   274k|  return key_ ? key_->tag() : 0;
  ------------------
  |  Branch (111:10): [True: 274k, False: 0]
  ------------------
  112|   274k|}
_ZN5Exiv29IptcdatumaSERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  186|    453|Iptcdatum& Iptcdatum::operator=(const std::string& value) {
  187|    453|  setValue(value);
  188|    453|  return *this;
  189|    453|}
_ZN5Exiv29Iptcdatum8setValueERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  202|  3.25k|int Iptcdatum::setValue(const std::string& value) {
  203|  3.25k|  if (!value_) {
  ------------------
  |  Branch (203:7): [True: 3.14k, False: 102]
  ------------------
  204|  3.14k|    TypeId type = IptcDataSets::dataSetType(tag(), record());
  205|  3.14k|    value_ = Value::create(type);
  206|  3.14k|  }
  207|  3.25k|  return value_->read(value);
  208|  3.25k|}
_ZN5Exiv28IptcDataixERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  210|    453|Iptcdatum& IptcData::operator[](const std::string& key) {
  211|    453|  IptcKey iptcKey(key);
  212|    453|  auto pos = findKey(iptcKey);
  213|    453|  if (pos == end()) {
  ------------------
  |  Branch (213:7): [True: 351, False: 102]
  ------------------
  214|    351|    return iptcMetadata_.emplace_back(iptcKey);
  215|    351|  }
  216|    102|  return *pos;
  217|    453|}
_ZN5Exiv28IptcData3addERKNS_7IptcKeyEPKNS_5ValueE:
  234|  28.1k|int IptcData::add(const IptcKey& key, const Value* value) {
  235|  28.1k|  return add(Iptcdatum(key, value));
  236|  28.1k|}
_ZN5Exiv28IptcData3addERKNS_9IptcdatumE:
  238|  30.9k|int IptcData::add(const Iptcdatum& iptcDatum) {
  239|  30.9k|  if (!IptcDataSets::dataSetRepeatable(iptcDatum.tag(), iptcDatum.record()) &&
  ------------------
  |  Branch (239:7): [True: 18.6k, False: 12.3k]
  |  Branch (239:7): [True: 17.3k, False: 13.6k]
  ------------------
  240|  18.6k|      findId(iptcDatum.tag(), iptcDatum.record()) != end()) {
  ------------------
  |  Branch (240:7): [True: 17.3k, False: 1.31k]
  ------------------
  241|  17.3k|    return 6;
  242|  17.3k|  }
  243|       |  // allow duplicates
  244|  13.6k|  iptcMetadata_.push_back(iptcDatum);
  245|  13.6k|  return 0;
  246|  30.9k|}
_ZN5Exiv28IptcData7findKeyERKNS_7IptcKeyE:
  252|    781|IptcData::iterator IptcData::findKey(const IptcKey& key) {
  253|    781|  return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(), FindIptcdatum(key.tag(), key.record()));
  254|    781|}
_ZN5Exiv28IptcData6findIdEtt:
  260|  18.6k|IptcData::iterator IptcData::findId(uint16_t dataset, uint16_t record) {
  261|  18.6k|  return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(), FindIptcdatum(dataset, record));
  262|  18.6k|}
_ZN5Exiv210IptcParser6decodeERNS_8IptcDataEPKhm:
  362|  1.45k|int IptcParser::decode(IptcData& iptcData, const byte* pData, size_t size) {
  363|       |#ifdef EXIV2_DEBUG_MESSAGES
  364|       |  std::cerr << "IptcParser::decode, size = " << size << "\n";
  365|       |#endif
  366|  1.45k|  auto pRead = pData;
  367|  1.45k|  const auto pEnd = pData + size;
  368|  1.45k|  iptcData.clear();
  369|       |
  370|  1.45k|  uint16_t record = 0;
  371|  1.45k|  uint16_t dataSet = 0;
  372|  1.45k|  uint32_t sizeData = 0;
  373|  1.45k|  byte extTest = 0;
  374|       |
  375|  1.24M|  while (6 <= static_cast<size_t>(pEnd - pRead)) {
  ------------------
  |  Branch (375:10): [True: 1.24M, False: 750]
  ------------------
  376|       |    // First byte should be a marker. If it isn't, scan forward and skip
  377|       |    // the chunk bytes present in some images. This deviates from the
  378|       |    // standard, which advises to treat such cases as errors.
  379|  1.24M|    if (*pRead++ != marker_)
  ------------------
  |  Branch (379:9): [True: 1.21M, False: 28.9k]
  ------------------
  380|  1.21M|      continue;
  381|  28.9k|    record = *pRead++;
  382|  28.9k|    dataSet = *pRead++;
  383|       |
  384|  28.9k|    extTest = *pRead;
  385|  28.9k|    if (extTest & 0x80) {
  ------------------
  |  Branch (385:9): [True: 2.13k, False: 26.7k]
  ------------------
  386|       |      // extended dataset
  387|  2.13k|      uint16_t sizeOfSize = (getUShort(pRead, bigEndian) & 0x7FFF);
  388|  2.13k|      if (sizeOfSize > 4)
  ------------------
  |  Branch (388:11): [True: 144, False: 1.99k]
  ------------------
  389|    144|        return 5;
  390|  1.99k|      pRead += 2;
  391|  1.99k|      if (sizeOfSize > pEnd - pRead)
  ------------------
  |  Branch (391:11): [True: 11, False: 1.98k]
  ------------------
  392|     11|        return 6;
  393|  1.98k|      sizeData = 0;
  394|  6.69k|      for (; sizeOfSize > 0; --sizeOfSize) {
  ------------------
  |  Branch (394:14): [True: 4.71k, False: 1.98k]
  ------------------
  395|  4.71k|        sizeData |= *pRead++ << (8 * (sizeOfSize - 1));
  396|  4.71k|      }
  397|  26.7k|    } else {
  398|       |      // standard dataset
  399|  26.7k|      sizeData = getUShort(pRead, bigEndian);
  400|  26.7k|      pRead += 2;
  401|  26.7k|    }
  402|  28.7k|    if (sizeData <= static_cast<size_t>(pEnd - pRead)) {
  ------------------
  |  Branch (402:9): [True: 28.2k, False: 546]
  ------------------
  403|  28.2k|      int rc = readData(iptcData, dataSet, record, pRead, sizeData);
  404|  28.2k|      if (rc != 0) {
  ------------------
  |  Branch (404:11): [True: 0, False: 28.2k]
  ------------------
  405|      0|#ifndef SUPPRESS_WARNINGS
  406|      0|        EXV_WARNING << "Failed to read IPTC dataset " << IptcKey(dataSet, record) << " (rc = " << rc << "); skipped.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  407|      0|#endif
  408|      0|      }
  409|  28.2k|    } else {
  410|    546|#ifndef SUPPRESS_WARNINGS
  411|    546|      EXV_WARNING << "IPTC dataset " << IptcKey(dataSet, record) << " has invalid size " << sizeData << "; skipped.\n";
  ------------------
  |  |  138|    546|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 546]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    546|  LogMsg(LogMsg::warn).os()
  ------------------
  412|    546|#endif
  413|    546|      return 7;
  414|    546|    }
  415|  28.2k|    pRead += sizeData;
  416|  28.2k|  }
  417|       |
  418|    750|  return 0;
  419|  1.45k|}  // IptcParser::decode
_ZN5Exiv210IptcParser6encodeERKNS_8IptcDataE:
  421|  4.40k|DataBuf IptcParser::encode(const IptcData& iptcData) {
  422|  4.40k|  DataBuf buf;
  423|  4.40k|  if (iptcData.empty())
  ------------------
  |  Branch (423:7): [True: 4.40k, False: 0]
  ------------------
  424|  4.40k|    return buf;
  425|       |
  426|      0|  buf = DataBuf(iptcData.size());
  427|      0|  byte* pWrite = buf.data();
  428|       |
  429|       |  // Copy the iptc data sets and sort them by record but preserve the order of datasets
  430|      0|  IptcMetadata sortedIptcData(iptcData.begin(), iptcData.end());
  431|      0|  std::stable_sort(sortedIptcData.begin(), sortedIptcData.end(),
  432|      0|                   [](const auto& l, const auto& r) { return l.record() < r.record(); });
  433|       |
  434|      0|  for (const auto& iter : sortedIptcData) {
  ------------------
  |  Branch (434:25): [True: 0, False: 0]
  ------------------
  435|       |    // marker, record Id, dataset num
  436|      0|    *pWrite++ = marker_;
  437|      0|    *pWrite++ = static_cast<byte>(iter.record());
  438|      0|    *pWrite++ = static_cast<byte>(iter.tag());
  439|       |
  440|       |    // extended or standard dataset?
  441|      0|    if (size_t dataSize = iter.size(); dataSize > 32767) {
  ------------------
  |  Branch (441:40): [True: 0, False: 0]
  ------------------
  442|       |      // always use 4 bytes for extended length
  443|      0|      uint16_t sizeOfSize = 4 | 0x8000;
  444|      0|      us2Data(pWrite, sizeOfSize, bigEndian);
  445|      0|      pWrite += 2;
  446|      0|      ul2Data(pWrite, static_cast<uint32_t>(dataSize), bigEndian);
  447|      0|      pWrite += 4;
  448|      0|    } else {
  449|      0|      us2Data(pWrite, static_cast<uint16_t>(dataSize), bigEndian);
  450|      0|      pWrite += 2;
  451|      0|    }
  452|      0|    pWrite += iter.value().copy(pWrite, bigEndian);
  453|      0|  }
  454|       |
  455|      0|  return buf;
  456|  4.40k|}  // IptcParser::encode
iptc.cpp:_ZNK12_GLOBAL__N_113FindIptcdatumclERKN5Exiv29IptcdatumE:
   41|   221k|  bool operator()(const Exiv2::Iptcdatum& iptcdatum) const {
   42|   221k|    return dataset_ == iptcdatum.tag() && record_ == iptcdatum.record();
  ------------------
  |  Branch (42:12): [True: 22.2k, False: 199k]
  |  Branch (42:43): [True: 17.4k, False: 4.87k]
  ------------------
   43|   221k|  }
iptc.cpp:_ZN12_GLOBAL__N_113FindIptcdatumC2Ett:
   35|  19.4k|  FindIptcdatum(uint16_t dataset, uint16_t record) : dataset_(dataset), record_(record) {
   36|  19.4k|  }
iptc.cpp:_ZN12_GLOBAL__N_18readDataERN5Exiv28IptcDataEttPKhj:
  463|  28.2k|int readData(Exiv2::IptcData& iptcData, uint16_t dataSet, uint16_t record, const Exiv2::byte* data, uint32_t sizeData) {
  464|  28.2k|  Exiv2::TypeId type = Exiv2::IptcDataSets::dataSetType(dataSet, record);
  465|  28.2k|  auto value = Exiv2::Value::create(type);
  466|  28.2k|  int rc = value->read(data, sizeData, Exiv2::bigEndian);
  467|  28.2k|  if (0 == rc) {
  ------------------
  |  Branch (467:7): [True: 14.7k, False: 13.4k]
  ------------------
  468|  14.7k|    Exiv2::IptcKey key(dataSet, record);
  469|  14.7k|    iptcData.add(key, value.get());
  470|  14.7k|  } else if (1 == rc) {
  ------------------
  |  Branch (470:14): [True: 13.3k, False: 50]
  ------------------
  471|       |    // If the first attempt failed, try with a string value
  472|  13.3k|    value = Exiv2::Value::create(Exiv2::string);
  473|  13.3k|    rc = value->read(data, sizeData, Exiv2::bigEndian);
  474|  13.3k|    if (0 == rc) {
  ------------------
  |  Branch (474:9): [True: 13.3k, False: 0]
  ------------------
  475|  13.3k|      Exiv2::IptcKey key(dataSet, record);
  476|  13.3k|      iptcData.add(key, value.get());
  477|  13.3k|    }
  478|  13.3k|  }
  479|  28.2k|  return rc;
  480|  28.2k|}

_ZN5Exiv28Jp2ImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
  100|  1.21k|Jp2Image::Jp2Image(BasicIo::UniquePtr io, bool create) : Image(ImageType::jp2, mdExif | mdIptc | mdXmp, std::move(io)) {
  101|  1.21k|  if (create && io_->open() == 0) {
  ------------------
  |  Branch (101:7): [True: 0, False: 1.21k]
  |  Branch (101:17): [True: 0, False: 0]
  ------------------
  102|       |#ifdef EXIV2_DEBUG_MESSAGES
  103|       |    std::cerr << "Exiv2::Jp2Image:: Creating JPEG2000 image to memory" << '\n';
  104|       |#endif
  105|      0|    IoCloser closer(*io_);
  106|      0|    if (io_->write(Jp2Blank.data(), Jp2Blank.size()) != Jp2Blank.size()) {
  ------------------
  |  Branch (106:9): [True: 0, False: 0]
  ------------------
  107|       |#ifdef EXIV2_DEBUG_MESSAGES
  108|       |      std::cerr << "Exiv2::Jp2Image:: Failed to create JPEG2000 image on memory" << '\n';
  109|       |#endif
  110|      0|    }
  111|      0|  }
  112|  1.21k|}
_ZNK5Exiv28Jp2Image8mimeTypeEv:
  124|  1.14k|std::string Jp2Image::mimeType() const {
  125|  1.14k|  if (brand_ == Internal::brandJph)
  ------------------
  |  Branch (125:7): [True: 3, False: 1.13k]
  ------------------
  126|      3|    return "image/jph";
  127|  1.13k|  return "image/jp2";
  128|  1.14k|}
_ZN5Exiv28Jp2Image12readMetadataEv:
  134|  1.20k|void Jp2Image::readMetadata() {
  135|       |#ifdef EXIV2_DEBUG_MESSAGES
  136|       |  std::cerr << "Exiv2::Jp2Image::readMetadata: Reading JPEG-2000 file " << io_->path() << '\n';
  137|       |#endif
  138|  1.20k|  if (io_->open() != 0) {
  ------------------
  |  Branch (138:7): [True: 0, False: 1.20k]
  ------------------
  139|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  140|      0|  }
  141|  1.20k|  IoCloser closer(*io_);
  142|  1.20k|  if (!isJp2Type(*io_, false)) {
  ------------------
  |  Branch (142:7): [True: 0, False: 1.20k]
  ------------------
  143|      0|    throw Error(ErrorCode::kerNotAnImage, "JPEG-2000");
  144|      0|  }
  145|       |
  146|  1.20k|  Internal::Jp2BoxHeader box = {0, 0};
  147|  1.20k|  Internal::Jp2BoxHeader subBox = {0, 0};
  148|  1.20k|  Internal::Jp2ImageHeaderBox ihdr = {0, 0, 0, 0, 0, 0, 0};
  149|  1.20k|  Internal::Jp2UuidBox uuid = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
  150|  1.20k|  size_t boxesCount = 0;
  151|  1.20k|  const size_t boxem = 1000;  // boxes max
  152|  1.20k|  uint32_t lastBoxTypeRead = 0;
  153|  1.20k|  bool boxSignatureFound = false;
  154|  1.20k|  bool boxFileTypeFound = false;
  155|       |
  156|  8.47k|  while (io_->read(reinterpret_cast<byte*>(&box), boxHSize) == boxHSize) {
  ------------------
  |  Branch (156:10): [True: 8.09k, False: 376]
  ------------------
  157|  8.09k|    boxes_check(boxesCount++, boxem);
  158|  8.09k|    const size_t position = io_->tell();
  159|  8.09k|    box.length = getULong(reinterpret_cast<byte*>(&box.length), bigEndian);
  160|  8.09k|    box.type = getULong(reinterpret_cast<byte*>(&box.type), bigEndian);
  161|       |#ifdef EXIV2_DEBUG_MESSAGES
  162|       |    std::cout << "Exiv2::Jp2Image::readMetadata: Position: " << position << " box type: " << toAscii(box.type)
  163|       |              << " length: " << box.length << '\n';
  164|       |#endif
  165|  8.09k|    Internal::enforce(box.length <= boxHSize + io_->size() - io_->tell(), ErrorCode::kerCorruptedMetadata);
  166|       |
  167|  8.09k|    if (box.length == 0)
  ------------------
  |  Branch (167:9): [True: 28, False: 8.06k]
  ------------------
  168|     28|      return;
  169|       |
  170|  8.06k|    if (box.length == 1) {
  ------------------
  |  Branch (170:9): [True: 10, False: 8.05k]
  ------------------
  171|       |      /// \todo In this case, the real box size is given in XLBox (bytes 8-15)
  172|     10|    }
  173|       |
  174|  8.06k|    switch (box.type) {
  175|  1.22k|      case kJp2BoxType::Signature: {
  ------------------
  |  Branch (175:7): [True: 1.22k, False: 6.84k]
  ------------------
  176|  1.22k|        if (boxSignatureFound)  // Only one is allowed
  ------------------
  |  Branch (176:13): [True: 15, False: 1.20k]
  ------------------
  177|     15|          throw Error(ErrorCode::kerCorruptedMetadata);
  178|  1.20k|        boxSignatureFound = true;
  179|  1.20k|        break;
  180|  1.22k|      }
  181|    246|      case kJp2BoxType::FileTypeBox: {
  ------------------
  |  Branch (181:7): [True: 246, False: 7.82k]
  ------------------
  182|       |        // This box shall immediately follow the JPEG 2000 Signature box
  183|    246|        if (boxFileTypeFound || lastBoxTypeRead != kJp2BoxType::Signature) {  // Only one is allowed
  ------------------
  |  Branch (183:13): [True: 13, False: 233]
  |  Branch (183:33): [True: 10, False: 223]
  ------------------
  184|     23|          throw Error(ErrorCode::kerCorruptedMetadata);
  185|     23|        }
  186|    223|        boxFileTypeFound = true;
  187|    223|        Blob boxData(box.length - boxHSize);
  188|    223|        io_->readOrThrow(boxData.data(), boxData.size(), ErrorCode::kerCorruptedMetadata);
  189|    223|        if (!Internal::isValidBoxFileType(boxData))
  ------------------
  |  Branch (189:13): [True: 196, False: 27]
  ------------------
  190|    196|          throw Error(ErrorCode::kerCorruptedMetadata);
  191|     27|        brand_ = getULong(boxData.data(), bigEndian);
  192|     27|        break;
  193|    223|      }
  194|  1.18k|      case kJp2BoxType::Header: {
  ------------------
  |  Branch (194:7): [True: 1.18k, False: 6.88k]
  ------------------
  195|       |#ifdef EXIV2_DEBUG_MESSAGES
  196|       |        std::cout << "Exiv2::Jp2Image::readMetadata: JP2Header box found\n";
  197|       |#endif
  198|  1.18k|        size_t restore = io_->tell();
  199|       |
  200|  3.73k|        while (io_->read(reinterpret_cast<byte*>(&subBox), boxHSize) == boxHSize && subBox.length) {
  ------------------
  |  Branch (200:16): [True: 3.69k, False: 39]
  |  Branch (200:85): [True: 2.68k, False: 1.00k]
  ------------------
  201|  2.68k|          boxes_check(boxesCount++, boxem);
  202|  2.68k|          subBox.length = getULong(reinterpret_cast<byte*>(&subBox.length), bigEndian);
  203|  2.68k|          subBox.type = getULong(reinterpret_cast<byte*>(&subBox.type), bigEndian);
  204|  2.68k|          if (subBox.length > io_->size()) {
  ------------------
  |  Branch (204:15): [True: 75, False: 2.60k]
  ------------------
  205|     75|            throw Error(ErrorCode::kerCorruptedMetadata);
  206|     75|          }
  207|       |#ifdef EXIV2_DEBUG_MESSAGES
  208|       |          std::cout << "Exiv2::Jp2Image::readMetadata: "
  209|       |                    << "subBox = " << toAscii(subBox.type) << " length = " << subBox.length << '\n';
  210|       |#endif
  211|  2.60k|          if (subBox.type == kJp2BoxType::ColorSpec && subBox.length != 15) {
  ------------------
  |  Branch (211:15): [True: 147, False: 2.46k]
  |  Branch (211:56): [True: 119, False: 28]
  ------------------
  212|       |#ifdef EXIV2_DEBUG_MESSAGES
  213|       |            std::cout << "Exiv2::Jp2Image::readMetadata: "
  214|       |                      << "Color data found" << '\n';
  215|       |#endif
  216|       |
  217|    119|            const size_t pad = 3;  // 3 padding bytes 2 0 0
  218|    119|            const size_t data_length = Safe::add(subBox.length, 8u);
  219|       |            // data_length makes no sense if it is larger than the rest of the file
  220|    119|            if (data_length > io_->size() - io_->tell()) {
  ------------------
  |  Branch (220:17): [True: 16, False: 103]
  ------------------
  221|     16|              throw Error(ErrorCode::kerCorruptedMetadata);
  222|     16|            }
  223|    103|            DataBuf data(data_length);
  224|    103|            io_->read(data.data(), data.size());
  225|    103|            const size_t iccLength = data.read_uint32(pad, bigEndian);
  226|       |            // subtracting pad from data.size() is safe:
  227|       |            // data.size() is at least 8 and pad = 3
  228|    103|            if (iccLength > data.size() - pad) {
  ------------------
  |  Branch (228:17): [True: 24, False: 79]
  ------------------
  229|     24|              throw Error(ErrorCode::kerCorruptedMetadata);
  230|     24|            }
  231|     79|            DataBuf icc(iccLength);
  232|     79|            std::copy_n(data.begin() + pad, icc.size(), icc.begin());
  233|       |#ifdef EXIV2_DEBUG_MESSAGES
  234|       |            const char* iccPath = "/tmp/libexiv2_jp2.icc";
  235|       |            if (auto f = std::ofstream(iccPath, std::ios::binary)) {
  236|       |              f.write(reinterpret_cast<const char*>(icc.c_data()), static_cast<std::streamsize>(icc.size()));
  237|       |              f.close();
  238|       |              std::cout << "Exiv2::Jp2Image::readMetadata: wrote iccProfile " << icc.size() << " bytes to " << iccPath
  239|       |                        << '\n';
  240|       |            }
  241|       |#endif
  242|     79|            setIccProfile(std::move(icc));
  243|     79|          }
  244|       |
  245|  2.56k|          if (subBox.type == kJp2BoxType::ImageHeader) {
  ------------------
  |  Branch (245:15): [True: 9, False: 2.55k]
  ------------------
  246|      9|            io_->read(reinterpret_cast<byte*>(&ihdr), sizeof(ihdr));
  247|       |#ifdef EXIV2_DEBUG_MESSAGES
  248|       |            std::cout << "Exiv2::Jp2Image::readMetadata: Ihdr data found" << '\n';
  249|       |#endif
  250|      9|            ihdr.imageHeight = getULong(reinterpret_cast<byte*>(&ihdr.imageHeight), bigEndian);
  251|      9|            ihdr.imageWidth = getULong(reinterpret_cast<byte*>(&ihdr.imageWidth), bigEndian);
  252|      9|            ihdr.componentCount = getShort(reinterpret_cast<byte*>(&ihdr.componentCount), bigEndian);
  253|      9|            Internal::enforce(ihdr.c == 7, ErrorCode::kerCorruptedMetadata);
  254|       |
  255|      9|            pixelWidth_ = ihdr.imageWidth;
  256|      9|            pixelHeight_ = ihdr.imageHeight;
  257|      9|          }
  258|       |
  259|  2.56k|          io_->seek(restore, BasicIo::beg);
  260|  2.56k|          if (io_->seek(subBox.length, BasicIo::cur) != 0) {
  ------------------
  |  Branch (260:15): [True: 22, False: 2.54k]
  ------------------
  261|     22|            throw Error(ErrorCode::kerCorruptedMetadata);
  262|     22|          }
  263|  2.54k|          restore = io_->tell();
  264|  2.54k|        }
  265|  1.04k|        break;
  266|  1.18k|      }
  267|       |
  268|  3.37k|      case kJp2BoxType::Uuid: {
  ------------------
  |  Branch (268:7): [True: 3.37k, False: 4.69k]
  ------------------
  269|       |#ifdef EXIV2_DEBUG_MESSAGES
  270|       |        std::cout << "Exiv2::Jp2Image::readMetadata: UUID box found" << '\n';
  271|       |#endif
  272|       |
  273|  3.37k|        if (io_->read(reinterpret_cast<byte*>(&uuid), sizeof(uuid)) == sizeof(uuid)) {
  ------------------
  |  Branch (273:13): [True: 3.36k, False: 4]
  ------------------
  274|  3.36k|          DataBuf rawData;
  275|  3.36k|          size_t bufRead;
  276|  3.36k|          bool bIsExif = uuid.uuid == kJp2UuidExif;
  277|  3.36k|          bool bIsIPTC = uuid.uuid == kJp2UuidIptc;
  278|  3.36k|          bool bIsXMP = uuid.uuid == kJp2UuidXmp;
  279|       |
  280|  3.36k|          if (bIsExif) {
  ------------------
  |  Branch (280:15): [True: 665, False: 2.70k]
  ------------------
  281|       |#ifdef EXIV2_DEBUG_MESSAGES
  282|       |            std::cout << "Exiv2::Jp2Image::readMetadata: Exif data found" << '\n';
  283|       |#endif
  284|    665|            Internal::enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
  285|    665|            rawData.alloc(box.length - (boxHSize + sizeof(uuid)));
  286|    665|            bufRead = io_->read(rawData.data(), rawData.size());
  287|    665|            if (io_->error())
  ------------------
  |  Branch (287:17): [True: 0, False: 665]
  ------------------
  288|      0|              throw Error(ErrorCode::kerFailedToReadImageData);
  289|    665|            if (bufRead != rawData.size())
  ------------------
  |  Branch (289:17): [True: 0, False: 665]
  ------------------
  290|      0|              throw Error(ErrorCode::kerInputDataReadFailed);
  291|       |
  292|    665|            if (rawData.size() > 8)  // "II*\0long"
  ------------------
  |  Branch (292:17): [True: 434, False: 231]
  ------------------
  293|    434|            {
  294|       |              // Find the position of Exif header in bytes array.
  295|    434|              const char a = rawData.read_uint8(0);
  296|    434|              const char b = rawData.read_uint8(1);
  297|    434|              const size_t notfound = std::numeric_limits<size_t>::max();
  298|    434|              size_t pos = (a == b && (a == 'I' || a == 'M')) ? 0 : notfound;
  ------------------
  |  Branch (298:29): [True: 264, False: 170]
  |  Branch (298:40): [True: 35, False: 229]
  |  Branch (298:52): [True: 66, False: 163]
  ------------------
  299|       |
  300|       |              // #1242  Forgive having Exif\0\0 in rawData.pData_
  301|    434|              std::array<byte, 6> exifHeader{0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
  302|  56.8k|              for (size_t i = 0; pos == notfound && i < (rawData.size() - exifHeader.size()); i++) {
  ------------------
  |  Branch (302:34): [True: 56.6k, False: 113]
  |  Branch (302:53): [True: 56.3k, False: 321]
  ------------------
  303|  56.3k|                if (rawData.cmpBytes(i, exifHeader.data(), exifHeader.size()) == 0) {
  ------------------
  |  Branch (303:21): [True: 12, False: 56.3k]
  ------------------
  304|     12|                  pos = i + sizeof(exifHeader);
  305|     12|#ifndef SUPPRESS_WARNINGS
  306|     12|                  EXV_WARNING << "Reading non-standard UUID-EXIF_bad box in " << io_->path() << '\n';
  ------------------
  |  |  138|     12|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 12]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     12|  LogMsg(LogMsg::warn).os()
  ------------------
  307|     12|#endif
  308|     12|                }
  309|  56.3k|              }
  310|       |
  311|       |              // If found it, store only these data at from this place.
  312|    434|              if (pos != notfound) {
  ------------------
  |  Branch (312:19): [True: 113, False: 321]
  ------------------
  313|       |#ifdef EXIV2_DEBUG_MESSAGES
  314|       |                std::cout << "Exiv2::Jp2Image::readMetadata: Exif header found at position " << pos << '\n';
  315|       |#endif
  316|    113|                ByteOrder bo =
  317|    113|                    TiffParser::decode(exifData(), iptcData(), xmpData(), rawData.c_data(pos), rawData.size() - pos);
  318|    113|                setByteOrder(bo);
  319|    113|              }
  320|    434|            } else {
  321|    231|#ifndef SUPPRESS_WARNINGS
  322|    231|              EXV_WARNING << "Failed to decode Exif metadata." << '\n';
  ------------------
  |  |  138|    231|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 231]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    231|  LogMsg(LogMsg::warn).os()
  ------------------
  323|    231|#endif
  324|    231|              exifData_.clear();
  325|    231|            }
  326|    665|          }
  327|       |
  328|  3.36k|          if (bIsIPTC) {
  ------------------
  |  Branch (328:15): [True: 1.10k, False: 2.26k]
  ------------------
  329|       |#ifdef EXIV2_DEBUG_MESSAGES
  330|       |            std::cout << "Exiv2::Jp2Image::readMetadata: Iptc data found" << '\n';
  331|       |#endif
  332|  1.10k|            Internal::enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
  333|  1.10k|            rawData.alloc(box.length - (boxHSize + sizeof(uuid)));
  334|  1.10k|            bufRead = io_->read(rawData.data(), rawData.size());
  335|  1.10k|            if (io_->error())
  ------------------
  |  Branch (335:17): [True: 0, False: 1.10k]
  ------------------
  336|      0|              throw Error(ErrorCode::kerFailedToReadImageData);
  337|  1.10k|            if (bufRead != rawData.size())
  ------------------
  |  Branch (337:17): [True: 0, False: 1.10k]
  ------------------
  338|      0|              throw Error(ErrorCode::kerInputDataReadFailed);
  339|       |
  340|  1.10k|            if (IptcParser::decode(iptcData_, rawData.c_data(), rawData.size())) {
  ------------------
  |  Branch (340:17): [True: 569, False: 537]
  ------------------
  341|    569|#ifndef SUPPRESS_WARNINGS
  342|    569|              EXV_WARNING << "Failed to decode IPTC metadata." << '\n';
  ------------------
  |  |  138|    569|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 569]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    569|  LogMsg(LogMsg::warn).os()
  ------------------
  343|    569|#endif
  344|    569|              iptcData_.clear();
  345|    569|            }
  346|  1.10k|          }
  347|       |
  348|  3.36k|          if (bIsXMP) {
  ------------------
  |  Branch (348:15): [True: 1.26k, False: 2.10k]
  ------------------
  349|       |#ifdef EXIV2_DEBUG_MESSAGES
  350|       |            std::cout << "Exiv2::Jp2Image::readMetadata: Xmp data found" << '\n';
  351|       |#endif
  352|  1.26k|            Internal::enforce(box.length >= boxHSize + sizeof(uuid), ErrorCode::kerCorruptedMetadata);
  353|  1.26k|            rawData.alloc(box.length - (boxHSize + sizeof(uuid)));
  354|  1.26k|            bufRead = io_->read(rawData.data(), rawData.size());
  355|  1.26k|            if (io_->error())
  ------------------
  |  Branch (355:17): [True: 0, False: 1.26k]
  ------------------
  356|      0|              throw Error(ErrorCode::kerFailedToReadImageData);
  357|  1.26k|            if (bufRead != rawData.size())
  ------------------
  |  Branch (357:17): [True: 0, False: 1.26k]
  ------------------
  358|      0|              throw Error(ErrorCode::kerInputDataReadFailed);
  359|  1.26k|            xmpPacket_.assign(rawData.c_str(), rawData.size());
  360|       |
  361|  1.26k|            if (auto idx = xmpPacket_.find_first_of('<'); idx != std::string::npos && idx > 0) {
  ------------------
  |  Branch (361:59): [True: 121, False: 1.14k]
  |  Branch (361:87): [True: 103, False: 18]
  ------------------
  362|    103|#ifndef SUPPRESS_WARNINGS
  363|    103|              EXV_WARNING << "Removing " << static_cast<uint32_t>(idx)
  ------------------
  |  |  138|    103|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 103]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    103|  LogMsg(LogMsg::warn).os()
  ------------------
  364|      0|                          << " characters from the beginning of the XMP packet" << '\n';
  365|    103|#endif
  366|    103|              xmpPacket_ = xmpPacket_.substr(idx);
  367|    103|            }
  368|       |
  369|  1.26k|            if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) {
  ------------------
  |  Branch (369:17): [True: 209, False: 1.05k]
  |  Branch (369:40): [True: 192, False: 17]
  ------------------
  370|    192|#ifndef SUPPRESS_WARNINGS
  371|    192|              EXV_WARNING << "Failed to decode XMP metadata." << '\n';
  ------------------
  |  |  138|    192|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 192]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    192|  LogMsg(LogMsg::warn).os()
  ------------------
  372|    192|#endif
  373|    192|            }
  374|  1.26k|          }
  375|  3.36k|        }
  376|  3.37k|        break;
  377|  3.37k|      }
  378|       |
  379|  3.37k|      default:
  ------------------
  |  Branch (379:7): [True: 1.71k, False: 6.35k]
  ------------------
  380|  1.71k|        break;
  381|  8.06k|    }
  382|  7.26k|    lastBoxTypeRead = box.type;
  383|       |
  384|       |    // Move to the next box.
  385|  7.26k|    io_->seek(static_cast<int64_t>(position - boxHSize + box.length), BasicIo::beg);
  386|  7.26k|    if (io_->error())
  ------------------
  |  Branch (386:9): [True: 0, False: 7.26k]
  ------------------
  387|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  388|  7.26k|  }
  389|       |
  390|  1.20k|}  // Jp2Image::readMetadata
_ZN5Exiv214newJp2InstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  867|  1.21k|Image::UniquePtr newJp2Instance(BasicIo::UniquePtr io, bool create) {
  868|  1.21k|  auto image = std::make_unique<Jp2Image>(std::move(io), create);
  869|  1.21k|  if (!image->good()) {
  ------------------
  |  Branch (869:7): [True: 10, False: 1.20k]
  ------------------
  870|     10|    return nullptr;
  871|     10|  }
  872|  1.20k|  return image;
  873|  1.21k|}
_ZN5Exiv29isJp2TypeERNS_7BasicIoEb:
  875|  16.3k|bool isJp2Type(BasicIo& iIo, bool advance) {
  876|  16.3k|  std::array<byte, Jp2Signature.size()> buf;
  877|  16.3k|  const size_t bytesRead = iIo.read(buf.data(), Jp2Signature.size());
  878|  16.3k|  if (iIo.error() || iIo.eof() || bytesRead != Jp2Signature.size()) {
  ------------------
  |  Branch (878:7): [True: 0, False: 16.3k]
  |  Branch (878:22): [True: 320, False: 16.0k]
  |  Branch (878:35): [True: 0, False: 16.0k]
  ------------------
  879|    320|    return false;
  880|    320|  }
  881|  16.0k|  bool matched = buf == Jp2Signature;
  882|  16.0k|  if (!advance || !matched) {
  ------------------
  |  Branch (882:7): [True: 16.0k, False: 0]
  |  Branch (882:19): [True: 0, False: 0]
  ------------------
  883|  16.0k|    iIo.seek(-static_cast<int64_t>(Jp2Signature.size()), BasicIo::cur);  // Return to original position
  884|  16.0k|  }
  885|  16.0k|  return matched;
  886|  16.3k|}
jp2image.cpp:_ZN5Exiv212_GLOBAL__N_111boxes_checkEmm:
   89|  10.7k|void boxes_check(size_t b, size_t m) {
   90|  10.7k|  if (b > m) {
  ------------------
  |  Branch (90:7): [True: 2, False: 10.7k]
  ------------------
   91|       |#ifdef EXIV2_DEBUG_MESSAGES
   92|       |    std::cout << "Exiv2::Jp2Image::readMetadata box maximum exceeded" << '\n';
   93|       |#endif
   94|      2|    throw Error(ErrorCode::kerCorruptedMetadata);
   95|      2|  }
   96|  10.7k|}

_ZN5Exiv28Internal18isValidBoxFileTypeERKNSt3__16vectorIhNS1_9allocatorIhEEEE:
   13|    221|bool isValidBoxFileType(const std::vector<uint8_t>& boxData) {
   14|       |  // BR & MinV are obligatory (4 + 4 bytes). Afterwards we have N compatibility lists (of size 4)
   15|    221|  if (boxData.size() < 8 || ((boxData.size() - 8u) % 4u) != 0) {
  ------------------
  |  Branch (15:7): [True: 11, False: 210]
  |  Branch (15:29): [True: 12, False: 198]
  ------------------
   16|     23|    return false;
   17|     23|  }
   18|       |
   19|    198|  const size_t N = (boxData.size() - 8u) / 4u;
   20|    198|  const uint32_t brand = getULong(boxData.data(), bigEndian);
   21|    198|  const uint32_t minorVersion = getULong(boxData.data() + 4, bigEndian);
   22|       |
   23|    198|  bool clWithRightBrand = false;
   24|  7.83k|  for (size_t i = 0; i < N; i++) {
  ------------------
  |  Branch (24:22): [True: 7.67k, False: 158]
  ------------------
   25|  7.67k|    uint32_t compatibilityList = getULong(boxData.data() + 8 + (i * 4), bigEndian);
   26|  7.67k|    if ((brand == brandJp2 && compatibilityList == brandJp2) || (brand == brandJph && compatibilityList == brandJph)) {
  ------------------
  |  Branch (26:10): [True: 686, False: 6.99k]
  |  Branch (26:31): [True: 23, False: 663]
  |  Branch (26:66): [True: 225, False: 7.43k]
  |  Branch (26:87): [True: 17, False: 208]
  ------------------
   27|     40|      clWithRightBrand = true;
   28|     40|      break;
   29|     40|    }
   30|  7.67k|  }
   31|    198|  return (minorVersion == 0 && clWithRightBrand);
  ------------------
  |  Branch (31:11): [True: 47, False: 151]
  |  Branch (31:32): [True: 25, False: 22]
  ------------------
   32|    221|}

_ZN5Exiv28JpegBaseC2ENS_9ImageTypeENSt3__110unique_ptrINS_7BasicIoENS2_14default_deleteIS4_EEEEbPKhm:
  116|  1.08k|    Image(type, mdExif | mdIptc | mdXmp | mdComment, std::move(io)) {
  117|  1.08k|  if (create) {
  ------------------
  |  Branch (117:7): [True: 0, False: 1.08k]
  ------------------
  118|      0|    initImage(initData, dataSize);
  119|      0|  }
  120|  1.08k|}
_ZNK5Exiv28JpegBase15advanceToMarkerENS_9ErrorCodeE:
  133|  22.3k|byte JpegBase::advanceToMarker(ErrorCode err) const {
  134|  22.3k|  int c = -1;
  135|       |  // Skips potential padding between markers
  136|   341k|  while ((c = io_->getb()) != 0xff) {
  ------------------
  |  Branch (136:10): [True: 319k, False: 21.8k]
  ------------------
  137|   319k|    if (c == EOF)
  ------------------
  |  Branch (137:9): [True: 538, False: 318k]
  ------------------
  138|    538|      throw Error(err);
  139|   319k|  }
  140|       |
  141|       |  // Markers can start with any number of 0xff
  142|  24.5k|  while ((c = io_->getb()) == 0xff) {
  ------------------
  |  Branch (142:10): [True: 2.66k, False: 21.8k]
  ------------------
  143|  2.66k|  }
  144|  21.8k|  if (c == EOF)
  ------------------
  |  Branch (144:7): [True: 38, False: 21.8k]
  ------------------
  145|     38|    throw Error(err);
  146|       |
  147|  21.8k|  return static_cast<byte>(c);
  148|  21.8k|}
_ZN5Exiv28JpegBase12readMetadataEv:
  150|  1.08k|void JpegBase::readMetadata() {
  151|  1.08k|  int rc = 0;  // Todo: this should be the return value
  152|       |
  153|  1.08k|  if (io_->open() != 0)
  ------------------
  |  Branch (153:7): [True: 0, False: 1.08k]
  ------------------
  154|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  155|  1.08k|  IoCloser closer(*io_);
  156|       |  // Ensure that this is the correct image type
  157|  1.08k|  if (!isThisType(*io_, true)) {
  ------------------
  |  Branch (157:7): [True: 78, False: 1.00k]
  ------------------
  158|     78|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (158:9): [True: 0, False: 78]
  |  Branch (158:25): [True: 0, False: 78]
  ------------------
  159|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  160|     78|    throw Error(ErrorCode::kerNotAJpeg);
  161|     78|  }
  162|  1.00k|  clearMetadata();
  163|  1.00k|  int search = 6;  // Exif, ICC, XMP, Comment, IPTC, SOF
  164|  1.00k|  Blob psBlob;
  165|  1.00k|  bool foundCompletePsData = false;
  166|  1.00k|  bool foundExifData = false;
  167|  1.00k|  bool foundXmpData = false;
  168|  1.00k|  bool foundIccData = false;
  169|       |
  170|       |  // Read section marker
  171|  1.00k|  byte marker = advanceToMarker(ErrorCode::kerNotAJpeg);
  172|       |
  173|  21.8k|  while (marker != sos_ && marker != eoi_ && search > 0) {
  ------------------
  |  Branch (173:10): [True: 21.7k, False: 96]
  |  Branch (173:28): [True: 21.7k, False: 14]
  |  Branch (173:46): [True: 21.7k, False: 6]
  ------------------
  174|  21.7k|    const auto [sizebuf, size] = readSegmentSize(marker, *io_);
  175|       |
  176|       |    // Read the rest of the segment.
  177|  21.7k|    DataBuf buf(size);
  178|       |    // check if the segment is not empty
  179|  21.7k|    if (size > 2) {
  ------------------
  |  Branch (179:9): [True: 18.9k, False: 2.82k]
  ------------------
  180|  18.9k|      io_->readOrThrow(buf.data(2), size - 2, ErrorCode::kerFailedToReadImageData);
  181|  18.9k|      std::copy(sizebuf.begin(), sizebuf.end(), buf.begin());
  182|  18.9k|    }
  183|       |
  184|  21.7k|    if (auto itSofMarker = Exiv2::find(jpegProcessMarkerTags, marker)) {
  ------------------
  |  Branch (184:14): [True: 4.66k, False: 17.0k]
  ------------------
  185|  4.66k|      sof_encoding_process_ = itSofMarker->label_;
  186|  4.66k|      if (size >= 7 && buf.c_data(7)) {
  ------------------
  |  Branch (186:11): [True: 3.84k, False: 823]
  |  Branch (186:24): [True: 3.61k, False: 229]
  ------------------
  187|  3.61k|        num_color_components_ = *buf.c_data(7);
  188|  3.61k|      }
  189|  4.66k|    }
  190|       |
  191|  21.7k|    if (!foundExifData && marker == app1_ && size >= 8  // prevent out-of-bounds read in memcmp on next line
  ------------------
  |  Branch (191:9): [True: 21.0k, False: 645]
  |  Branch (191:27): [True: 755, False: 20.3k]
  |  Branch (191:46): [True: 534, False: 221]
  ------------------
  192|    534|        && buf.cmpBytes(2, exifId_.data(), 6) == 0) {
  ------------------
  |  Branch (192:12): [True: 57, False: 477]
  ------------------
  193|     57|      ByteOrder bo = ExifParser::decode(exifData_, buf.c_data(8), size - 8);
  194|     57|      setByteOrder(bo);
  195|     57|      if (size > 8 && byteOrder() == invalidByteOrder) {
  ------------------
  |  Branch (195:11): [True: 27, False: 30]
  |  Branch (195:23): [True: 0, False: 27]
  ------------------
  196|      0|#ifndef SUPPRESS_WARNINGS
  197|      0|        EXV_WARNING << "Failed to decode Exif metadata.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  198|      0|#endif
  199|      0|        exifData_.clear();
  200|      0|      }
  201|     57|      --search;
  202|     57|      foundExifData = true;
  203|  21.6k|    } else if (!foundXmpData && marker == app1_ && size >= 31  // prevent out-of-bounds read in memcmp on next line
  ------------------
  |  Branch (203:16): [True: 21.1k, False: 517]
  |  Branch (203:33): [True: 715, False: 20.4k]
  |  Branch (203:52): [True: 290, False: 425]
  ------------------
  204|    290|               && buf.cmpBytes(2, xmpId_.data(), 29) == 0) {
  ------------------
  |  Branch (204:19): [True: 52, False: 238]
  ------------------
  205|     52|      xmpPacket_.assign(buf.c_str(31), size - 31);
  206|     52|      if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) {
  ------------------
  |  Branch (206:11): [True: 42, False: 10]
  |  Branch (206:34): [True: 29, False: 13]
  ------------------
  207|     29|#ifndef SUPPRESS_WARNINGS
  208|     29|        EXV_WARNING << "Failed to decode XMP metadata.\n";
  ------------------
  |  |  138|     29|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 29]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     29|  LogMsg(LogMsg::warn).os()
  ------------------
  209|     29|#endif
  210|     29|      }
  211|     52|      --search;
  212|     52|      foundXmpData = true;
  213|  21.6k|    } else if (!foundCompletePsData && marker == app13_ &&
  ------------------
  |  Branch (213:16): [True: 21.1k, False: 478]
  |  Branch (213:40): [True: 9.12k, False: 12.0k]
  ------------------
  214|  9.12k|               size >= 16  // prevent out-of-bounds read in memcmp on next line
  ------------------
  |  Branch (214:16): [True: 8.89k, False: 231]
  ------------------
  215|  8.89k|               && buf.cmpBytes(2, Photoshop::ps3Id_, 14) == 0) {
  ------------------
  |  Branch (215:19): [True: 7.79k, False: 1.09k]
  ------------------
  216|       |#ifdef EXIV2_DEBUG_MESSAGES
  217|       |      std::cerr << "Found app13 segment, size = " << size << "\n";
  218|       |#endif
  219|  7.79k|      if (buf.size() > 16) {  // Append to psBlob
  ------------------
  |  Branch (219:11): [True: 7.19k, False: 605]
  ------------------
  220|  7.19k|        append(psBlob, buf.c_data(16), size - 16);
  221|  7.19k|      }
  222|       |      // Check whether psBlob is complete
  223|  7.79k|      if (!psBlob.empty() && Photoshop::valid(psBlob.data(), psBlob.size())) {
  ------------------
  |  Branch (223:11): [True: 7.56k, False: 233]
  |  Branch (223:30): [True: 112, False: 7.45k]
  ------------------
  224|    112|        --search;
  225|    112|        foundCompletePsData = true;
  226|    112|      }
  227|  13.8k|    } else if (marker == com_ && comment_.empty()) {
  ------------------
  |  Branch (227:16): [True: 661, False: 13.1k]
  |  Branch (227:34): [True: 202, False: 459]
  ------------------
  228|       |      // JPEGs can have multiple comments, but for now only read
  229|       |      // the first one (most jpegs only have one anyway). Comments
  230|       |      // are simple single byte ISO-8859-1 strings.
  231|    202|      comment_.assign(buf.c_str(2), size - 2);
  232|  1.01k|      while (!comment_.empty() && comment_.back() == '\0') {
  ------------------
  |  Branch (232:14): [True: 881, False: 132]
  |  Branch (232:35): [True: 811, False: 70]
  ------------------
  233|    811|        comment_.pop_back();
  234|    811|      }
  235|    202|      --search;
  236|  13.6k|    } else if (marker == app2_ && size >= 13  // prevent out-of-bounds read in memcmp on next line
  ------------------
  |  Branch (236:16): [True: 3.29k, False: 10.3k]
  |  Branch (236:35): [True: 3.08k, False: 210]
  ------------------
  237|  3.08k|               && buf.cmpBytes(2, iccId_, 11) == 0) {
  ------------------
  |  Branch (237:19): [True: 2.18k, False: 893]
  ------------------
  238|  2.18k|      if (size < 2 + 14 + 4) {
  ------------------
  |  Branch (238:11): [True: 10, False: 2.17k]
  ------------------
  239|     10|        rc = 8;
  240|     10|        break;
  241|     10|      }
  242|       |      // ICC profile
  243|  2.17k|      if (!foundIccData) {
  ------------------
  |  Branch (243:11): [True: 104, False: 2.07k]
  ------------------
  244|    104|        foundIccData = true;
  245|    104|        --search;
  246|    104|      }
  247|  2.17k|      auto chunk = static_cast<int>(buf.read_uint8(2 + 12));
  248|  2.17k|      auto chunks = static_cast<int>(buf.read_uint8(2 + 13));
  249|       |      // ICC1v43_2010-12.pdf header is 14 bytes
  250|       |      // header = "ICC_PROFILE\0" (12 bytes)
  251|       |      // chunk/chunks are a single byte
  252|       |      // Spec 7.2 Profile bytes 0-3 size
  253|  2.17k|      uint32_t s = buf.read_uint32(2 + 14, bigEndian);
  254|       |#ifdef EXIV2_DEBUG_MESSAGES
  255|       |      std::cerr << "Found ICC Profile chunk " << chunk << " of " << chunks << (chunk == 1 ? " size: " : "")
  256|       |                << (chunk == 1 ? s : 0) << '\n';
  257|       |#endif
  258|       |      // #1286 profile can be padded
  259|  2.17k|      size_t icc_size = size - 2 - 14;
  260|  2.17k|      if (chunk == 1 && chunks == 1) {
  ------------------
  |  Branch (260:11): [True: 1.85k, False: 326]
  |  Branch (260:25): [True: 1.54k, False: 306]
  ------------------
  261|  1.54k|        enforce(s <= static_cast<uint32_t>(icc_size), ErrorCode::kerInvalidIccProfile);
  262|  1.54k|        icc_size = s;
  263|  1.54k|      }
  264|       |
  265|  2.17k|      appendIccProfile(buf.c_data(2 + 14), icc_size, chunk == chunks);
  266|  11.4k|    } else if (pixelHeight_ == 0 && inRange2(marker, sof0_, sof3_, sof5_, sof15_)) {
  ------------------
  |  Branch (266:16): [True: 7.21k, False: 4.23k]
  |  Branch (266:37): [True: 1.68k, False: 5.53k]
  ------------------
  267|       |      // We hit a SOFn (start-of-frame) marker
  268|  1.68k|      if (size < 8) {
  ------------------
  |  Branch (268:11): [True: 35, False: 1.65k]
  ------------------
  269|     35|        rc = 7;
  270|     35|        break;
  271|     35|      }
  272|  1.65k|      pixelHeight_ = buf.read_uint16(3, bigEndian);
  273|  1.65k|      pixelWidth_ = buf.read_uint16(5, bigEndian);
  274|  1.65k|      if (pixelHeight_ != 0)
  ------------------
  |  Branch (274:11): [True: 177, False: 1.47k]
  ------------------
  275|    177|        --search;
  276|  1.65k|    }
  277|       |
  278|       |    // Read the beginning of the next segment
  279|  21.6k|    try {
  280|  21.6k|      marker = advanceToMarker(ErrorCode::kerFailedToReadImageData);
  281|  21.6k|    } catch (const Error&) {
  282|    530|      rc = 5;
  283|    530|      break;
  284|    530|    }
  285|  21.6k|  }  // while there are segments to process
  286|       |
  287|    691|  if (!psBlob.empty()) {
  ------------------
  |  Branch (287:7): [True: 193, False: 498]
  ------------------
  288|       |    // Find actual IPTC data within the psBlob
  289|    193|    Blob iptcBlob;
  290|    193|    const byte* record = nullptr;
  291|    193|    uint32_t sizeIptc = 0;
  292|    193|    uint32_t sizeHdr = 0;
  293|    193|    const byte* pCur = psBlob.data();
  294|    193|    const byte* pEnd = pCur + psBlob.size();
  295|    327|    while (pCur < pEnd && 0 == Photoshop::locateIptcIrb(pCur, pEnd - pCur, &record, sizeHdr, sizeIptc)) {
  ------------------
  |  Branch (295:12): [True: 312, False: 15]
  |  Branch (295:27): [True: 134, False: 178]
  ------------------
  296|       |#ifdef EXIV2_DEBUG_MESSAGES
  297|       |      std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n";
  298|       |#endif
  299|    134|      if (sizeIptc) {
  ------------------
  |  Branch (299:11): [True: 98, False: 36]
  ------------------
  300|     98|        append(iptcBlob, record + sizeHdr, sizeIptc);
  301|     98|      }
  302|    134|      pCur = record + sizeHdr + sizeIptc + (sizeIptc & 1);
  303|    134|    }
  304|    193|    if (!iptcBlob.empty() && IptcParser::decode(iptcData_, iptcBlob.data(), iptcBlob.size())) {
  ------------------
  |  Branch (304:9): [True: 96, False: 97]
  |  Branch (304:30): [True: 38, False: 58]
  ------------------
  305|     38|#ifndef SUPPRESS_WARNINGS
  306|     38|      EXV_WARNING << "Failed to decode IPTC metadata.\n";
  ------------------
  |  |  138|     38|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 38]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     38|  LogMsg(LogMsg::warn).os()
  ------------------
  307|     38|#endif
  308|     38|      iptcData_.clear();
  309|     38|    }
  310|    193|  }
  311|       |
  312|    691|  if (rc != 0) {
  ------------------
  |  Branch (312:7): [True: 574, False: 117]
  ------------------
  313|    574|#ifndef SUPPRESS_WARNINGS
  314|    574|    EXV_WARNING << "JPEG format error, rc = " << rc << "\n";
  ------------------
  |  |  138|    574|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 574]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    574|  LogMsg(LogMsg::warn).os()
  ------------------
  315|    574|#endif
  316|    574|  }
  317|    691|}  // JpegBase::readMetadata
_ZN5Exiv29JpegImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
  968|  1.00k|    JpegBase(ImageType::jpeg, std::move(io), create, blank_, sizeof(blank_)) {
  969|  1.00k|}
_ZNK5Exiv29JpegImage8mimeTypeEv:
  971|  1.42k|std::string JpegImage::mimeType() const {
  972|  1.42k|  return "image/jpeg";
  973|  1.42k|}
_ZNK5Exiv29JpegImage10isThisTypeERNS_7BasicIoEb:
  987|  1.00k|bool JpegImage::isThisType(BasicIo& iIo, bool advance) const {
  988|  1.00k|  return isJpegType(iIo, advance);
  989|  1.00k|}
_ZN5Exiv215newJpegInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  991|    915|Image::UniquePtr newJpegInstance(BasicIo::UniquePtr io, bool create) {
  992|    915|  auto image = std::make_unique<JpegImage>(std::move(io), create);
  993|    915|  if (!image->good()) {
  ------------------
  |  Branch (993:7): [True: 0, False: 915]
  ------------------
  994|      0|    return nullptr;
  995|      0|  }
  996|    915|  return image;
  997|    915|}
_ZN5Exiv210isJpegTypeERNS_7BasicIoEb:
  999|  34.7k|bool isJpegType(BasicIo& iIo, bool advance) {
 1000|  34.7k|  bool result = true;
 1001|  34.7k|  byte tmpBuf[2];
 1002|  34.7k|  iIo.read(tmpBuf, 2);
 1003|  34.7k|  if (iIo.error() || iIo.eof())
  ------------------
  |  Branch (1003:7): [True: 0, False: 34.7k]
  |  Branch (1003:22): [True: 25, False: 34.6k]
  ------------------
 1004|     25|    return false;
 1005|       |
 1006|  34.6k|  if (0xff != tmpBuf[0] || soi_ != tmpBuf[1]) {
  ------------------
  |  Branch (1006:7): [True: 31.6k, False: 3.04k]
  |  Branch (1006:28): [True: 292, False: 2.75k]
  ------------------
 1007|  31.9k|    result = false;
 1008|  31.9k|  }
 1009|  34.6k|  if (!advance || !result)
  ------------------
  |  Branch (1009:7): [True: 33.6k, False: 1.00k]
  |  Branch (1009:19): [True: 78, False: 922]
  ------------------
 1010|  33.7k|    iIo.seek(-2, BasicIo::cur);
 1011|  34.6k|  return result;
 1012|  34.7k|}
_ZN5Exiv28ExvImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
 1015|     84|    JpegBase(ImageType::exv, std::move(io), create, blank_, sizeof(blank_)) {
 1016|     84|}
_ZNK5Exiv28ExvImage8mimeTypeEv:
 1018|      9|std::string ExvImage::mimeType() const {
 1019|      9|  return "image/x-exv";
 1020|      9|}
_ZNK5Exiv28ExvImage10isThisTypeERNS_7BasicIoEb:
 1033|     84|bool ExvImage::isThisType(BasicIo& iIo, bool advance) const {
 1034|     84|  return isExvType(iIo, advance);
 1035|     84|}
_ZN5Exiv214newExvInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
 1037|     84|Image::UniquePtr newExvInstance(BasicIo::UniquePtr io, bool create) {
 1038|     84|  auto image = std::make_unique<ExvImage>(std::move(io), create);
 1039|     84|  if (!image->good())
  ------------------
  |  Branch (1039:7): [True: 0, False: 84]
  ------------------
 1040|      0|    return nullptr;
 1041|     84|  return image;
 1042|     84|}
_ZN5Exiv29isExvTypeERNS_7BasicIoEb:
 1044|  32.0k|bool isExvType(BasicIo& iIo, bool advance) {
 1045|  32.0k|  bool result = true;
 1046|  32.0k|  byte tmpBuf[7];
 1047|  32.0k|  iIo.read(tmpBuf, 7);
 1048|  32.0k|  if (iIo.error() || iIo.eof())
  ------------------
  |  Branch (1048:7): [True: 0, False: 32.0k]
  |  Branch (1048:22): [True: 80, False: 31.9k]
  ------------------
 1049|     80|    return false;
 1050|       |
 1051|  31.9k|  if (0xff != tmpBuf[0] || 0x01 != tmpBuf[1] || memcmp(tmpBuf + 2, ExvImage::exiv2Id_, 5) != 0) {
  ------------------
  |  Branch (1051:7): [True: 31.5k, False: 415]
  |  Branch (1051:28): [True: 148, False: 267]
  |  Branch (1051:49): [True: 15, False: 252]
  ------------------
 1052|  31.7k|    result = false;
 1053|  31.7k|  }
 1054|  31.9k|  if (!advance || !result)
  ------------------
  |  Branch (1054:7): [True: 31.8k, False: 84]
  |  Branch (1054:19): [True: 0, False: 84]
  ------------------
 1055|  31.8k|    iIo.seek(-7, BasicIo::cur);
 1056|  31.9k|  return result;
 1057|  32.0k|}
jpgimage.cpp:_ZN5Exiv212_GLOBAL__N_115readSegmentSizeEhRNS_7BasicIoE:
  103|  21.7k|std::pair<std::array<byte, 2>, uint16_t> readSegmentSize(const byte marker, BasicIo& io) {
  104|  21.7k|  std::array<byte, 2> buf{0, 0};  // 2-byte buffer for reading the size.
  105|  21.7k|  uint16_t size{0};               // Size of the segment, including the 2-byte size field
  106|  21.7k|  if (markerHasLength(marker)) {
  ------------------
  |  Branch (106:7): [True: 19.9k, False: 1.79k]
  ------------------
  107|  19.9k|    io.readOrThrow(buf.data(), buf.size(), ErrorCode::kerFailedToReadImageData);
  108|  19.9k|    size = getUShort(buf.data(), bigEndian);
  109|  19.9k|    enforce(size >= 2, ErrorCode::kerFailedToReadImageData);
  110|  19.9k|  }
  111|  21.7k|  return {buf, size};
  112|  21.7k|}
jpgimage.cpp:_ZN5Exiv212_GLOBAL__N_18inRange2Eiiiii:
   91|  7.21k|constexpr bool inRange2(int value, int lo1, int hi1, int lo2, int hi2) {
   92|  7.21k|  return inRange(lo1, value, hi1) || inRange(lo2, value, hi2);
  ------------------
  |  Branch (92:10): [True: 1.03k, False: 6.18k]
  |  Branch (92:38): [True: 650, False: 5.53k]
  ------------------
   93|  7.21k|}
jpgimage.cpp:_ZN5Exiv212_GLOBAL__N_17inRangeEiii:
   87|  13.4k|constexpr bool inRange(int lo, int value, int hi) {
   88|  13.4k|  return lo <= value && value <= hi;
  ------------------
  |  Branch (88:10): [True: 12.1k, False: 1.25k]
  |  Branch (88:25): [True: 1.68k, False: 10.4k]
  ------------------
   89|  13.4k|}
jpgimage.cpp:_ZN5Exiv212_GLOBAL__N_115markerHasLengthEh:
   98|  21.7k|bool markerHasLength(byte m) {
   99|  21.7k|  bool markerWithoutLength = m >= rst1_ && m <= eoi_;
  ------------------
  |  Branch (99:30): [True: 16.0k, False: 5.72k]
  |  Branch (99:44): [True: 1.79k, False: 14.2k]
  ------------------
  100|  21.7k|  return !markerWithoutLength;
  101|  21.7k|}

_ZNK5Exiv28Internal14TiffMnRegistryeqENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
  133|   189k|bool TiffMnRegistry::operator==(std::string_view key) const {
  134|   189k|  if (!key.empty() && key.front() == '-')
  ------------------
  |  Branch (134:7): [True: 134k, False: 54.5k]
  |  Branch (134:23): [True: 11.4k, False: 123k]
  ------------------
  135|  11.4k|    return false;
  136|   177k|  return key.starts_with(make_);
  137|   189k|}
_ZN5Exiv28Internal13TiffMnCreator6createEtNS_5IfdIdENSt3__117basic_string_viewIcNS3_11char_traitsIcEEEEPKhmNS_9ByteOrderE:
  144|  11.3k|                                                        const byte* pData, size_t size, ByteOrder byteOrder) {
  145|  11.3k|  if (auto tmr = Exiv2::find(registry_, make))
  ------------------
  |  Branch (145:12): [True: 6.02k, False: 5.29k]
  ------------------
  146|  6.02k|    return tmr->newMnFct_(tag, group, tmr->mnGroup_, pData, size, byteOrder);
  147|  5.29k|  return nullptr;
  148|  11.3k|}  // TiffMnCreator::create
_ZNK5Exiv28Internal8MnHeader9ifdOffsetEv:
  163|    167|size_t MnHeader::ifdOffset() const {
  164|    167|  return 0;
  165|    167|}
_ZNK5Exiv28Internal8MnHeader9byteOrderEv:
  167|  2.27k|ByteOrder MnHeader::byteOrder() const {
  168|  2.27k|  return invalidByteOrder;
  169|  2.27k|}
_ZNK5Exiv28Internal8MnHeader10baseOffsetEm:
  171|    749|size_t MnHeader::baseOffset(size_t /*mnOffset*/) const {
  172|    749|  return 0;
  173|    749|}
_ZN5Exiv28Internal15OlympusMnHeader15sizeOfSignatureEv:
  177|  1.53k|size_t OlympusMnHeader::sizeOfSignature() {
  178|  1.53k|  return sizeof(signature_);
  179|  1.53k|}
_ZN5Exiv28Internal15OlympusMnHeaderC2Ev:
  181|    146|OlympusMnHeader::OlympusMnHeader() {
  182|    146|  read(signature_, sizeOfSignature(), invalidByteOrder);
  183|    146|}
_ZNK5Exiv28Internal15OlympusMnHeader9ifdOffsetEv:
  189|     69|size_t OlympusMnHeader::ifdOffset() const {
  190|     69|  return sizeOfSignature();
  191|     69|}
_ZN5Exiv28Internal15OlympusMnHeader4readEPKhmNS_9ByteOrderE:
  193|    292|bool OlympusMnHeader::read(const byte* pData, size_t size, ByteOrder) {
  194|    292|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (194:7): [True: 0, False: 292]
  |  Branch (194:17): [True: 0, False: 292]
  ------------------
  195|      0|    return false;
  196|    292|  header_.alloc(sizeOfSignature());
  197|    292|  std::copy_n(pData, header_.size(), header_.begin());
  198|    292|  return header_.size() >= sizeOfSignature() && 0 == header_.cmpBytes(0, signature_, 6);
  ------------------
  |  Branch (198:10): [True: 292, False: 0]
  |  Branch (198:49): [True: 215, False: 77]
  ------------------
  199|    292|}
_ZN5Exiv28Internal16Olympus2MnHeader15sizeOfSignatureEv:
  208|  1.75k|size_t Olympus2MnHeader::sizeOfSignature() {
  209|  1.75k|  return sizeof(signature_);
  210|  1.75k|}
_ZN5Exiv28Internal16Olympus2MnHeaderC2Ev:
  212|    191|Olympus2MnHeader::Olympus2MnHeader() {
  213|    191|  read(signature_, sizeOfSignature(), invalidByteOrder);
  214|    191|}
_ZNK5Exiv28Internal16Olympus2MnHeader9ifdOffsetEv:
  220|    191|size_t Olympus2MnHeader::ifdOffset() const {
  221|    191|  return sizeOfSignature();
  222|    191|}
_ZNK5Exiv28Internal16Olympus2MnHeader10baseOffsetEm:
  224|    191|size_t Olympus2MnHeader::baseOffset(size_t mnOffset) const {
  225|    191|  return mnOffset;
  226|    191|}
_ZN5Exiv28Internal16Olympus2MnHeader4readEPKhmNS_9ByteOrderE:
  228|    382|bool Olympus2MnHeader::read(const byte* pData, size_t size, ByteOrder) {
  229|    382|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (229:7): [True: 0, False: 382]
  |  Branch (229:17): [True: 0, False: 382]
  ------------------
  230|      0|    return false;
  231|    382|  header_.alloc(sizeOfSignature());
  232|    382|  std::copy_n(pData, header_.size(), header_.begin());
  233|    382|  return header_.size() >= sizeOfSignature() && 0 == header_.cmpBytes(0, signature_, 10);
  ------------------
  |  Branch (233:10): [True: 382, False: 0]
  |  Branch (233:49): [True: 382, False: 0]
  ------------------
  234|    382|}
_ZN5Exiv28Internal16OMSystemMnHeader15sizeOfSignatureEv:
  244|  1.36k|size_t OMSystemMnHeader::sizeOfSignature() {
  245|  1.36k|  return sizeof(signature_);
  246|  1.36k|}
_ZN5Exiv28Internal16OMSystemMnHeaderC2Ev:
  248|    116|OMSystemMnHeader::OMSystemMnHeader() {
  249|    116|  read(signature_, sizeOfSignature(), invalidByteOrder);
  250|    116|}
_ZNK5Exiv28Internal16OMSystemMnHeader9ifdOffsetEv:
  256|     45|size_t OMSystemMnHeader::ifdOffset() const {
  257|     45|  return sizeOfSignature();
  258|     45|}
_ZNK5Exiv28Internal16OMSystemMnHeader10baseOffsetEm:
  260|     45|size_t OMSystemMnHeader::baseOffset(size_t mnOffset) const {
  261|     45|  return mnOffset;
  262|     45|}
_ZN5Exiv28Internal16OMSystemMnHeader4readEPKhmNS_9ByteOrderE:
  264|    232|bool OMSystemMnHeader::read(const byte* pData, size_t size, ByteOrder) {
  265|    232|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (265:7): [True: 0, False: 232]
  |  Branch (265:17): [True: 0, False: 232]
  ------------------
  266|      0|    return false;
  267|    232|  header_.alloc(sizeOfSignature());
  268|    232|  std::copy_n(pData, header_.size(), header_.begin());
  269|    232|  return header_.size() >= sizeOfSignature() && 0 == header_.cmpBytes(0, signature_, sizeOfSignature() - 2);
  ------------------
  |  Branch (269:10): [True: 232, False: 0]
  |  Branch (269:49): [True: 161, False: 71]
  ------------------
  270|    232|}
_ZN5Exiv28Internal12FujiMnHeader15sizeOfSignatureEv:
  280|  1.72k|size_t FujiMnHeader::sizeOfSignature() {
  281|  1.72k|  return sizeof(signature_);
  282|  1.72k|}
_ZN5Exiv28Internal12FujiMnHeaderC2Ev:
  284|    188|FujiMnHeader::FujiMnHeader() {
  285|    188|  read(signature_, sizeOfSignature(), byteOrder_);
  286|    188|}
_ZNK5Exiv28Internal12FujiMnHeader9ifdOffsetEv:
  292|    101|size_t FujiMnHeader::ifdOffset() const {
  293|    101|  return start_;
  294|    101|}
_ZNK5Exiv28Internal12FujiMnHeader9byteOrderEv:
  296|    382|ByteOrder FujiMnHeader::byteOrder() const {
  297|    382|  return byteOrder_;
  298|    382|}
_ZNK5Exiv28Internal12FujiMnHeader10baseOffsetEm:
  300|    101|size_t FujiMnHeader::baseOffset(size_t mnOffset) const {
  301|    101|  return mnOffset;
  302|    101|}
_ZN5Exiv28Internal12FujiMnHeader4readEPKhmNS_9ByteOrderE:
  304|    376|bool FujiMnHeader::read(const byte* pData, size_t size, ByteOrder) {
  305|    376|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (305:7): [True: 0, False: 376]
  |  Branch (305:17): [True: 0, False: 376]
  ------------------
  306|      0|    return false;
  307|    376|  header_.alloc(sizeOfSignature());
  308|    376|  std::copy_n(pData, header_.size(), header_.begin());
  309|       |  // Read offset to the IFD relative to the start of the makernote
  310|       |  // from the header. Note that we ignore the byteOrder argument
  311|    376|  start_ = header_.read_uint32(8, byteOrder_);
  312|    376|  return header_.size() >= sizeOfSignature() && 0 == header_.cmpBytes(0, signature_, 8);
  ------------------
  |  Branch (312:10): [True: 376, False: 0]
  |  Branch (312:49): [True: 289, False: 87]
  ------------------
  313|    376|}
_ZN5Exiv28Internal14Nikon2MnHeader15sizeOfSignatureEv:
  322|    992|size_t Nikon2MnHeader::sizeOfSignature() {
  323|    992|  return sizeof(signature_);
  324|    992|}
_ZN5Exiv28Internal14Nikon2MnHeaderC2Ev:
  326|    116|Nikon2MnHeader::Nikon2MnHeader() {
  327|    116|  read(signature_, sizeOfSignature(), invalidByteOrder);
  328|    116|}
_ZNK5Exiv28Internal14Nikon2MnHeader9ifdOffsetEv:
  334|    116|size_t Nikon2MnHeader::ifdOffset() const {
  335|    116|  return start_;
  336|    116|}
_ZN5Exiv28Internal14Nikon2MnHeader4readEPKhmNS_9ByteOrderE:
  338|    232|bool Nikon2MnHeader::read(const byte* pData, size_t size, ByteOrder) {
  339|    232|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (339:7): [True: 0, False: 232]
  |  Branch (339:17): [True: 0, False: 232]
  ------------------
  340|      0|    return false;
  341|    232|  if (0 != memcmp(pData, signature_, 6))
  ------------------
  |  Branch (341:7): [True: 0, False: 232]
  ------------------
  342|      0|    return false;
  343|    232|  buf_.alloc(sizeOfSignature());
  344|    232|  std::copy_n(pData, buf_.size(), buf_.begin());
  345|    232|  start_ = sizeOfSignature();
  346|    232|  return true;
  347|    232|}  // Nikon2MnHeader::read
_ZN5Exiv28Internal14Nikon3MnHeader15sizeOfSignatureEv:
  357|  1.80k|size_t Nikon3MnHeader::sizeOfSignature() {
  358|  1.80k|  return sizeof(signature_);
  359|  1.80k|}
_ZN5Exiv28Internal14Nikon3MnHeaderC2Ev:
  361|    359|Nikon3MnHeader::Nikon3MnHeader() : start_(sizeOfSignature()) {
  362|    359|  buf_.alloc(sizeOfSignature());
  363|    359|  std::copy_n(signature_, buf_.size(), buf_.begin());
  364|    359|}
_ZNK5Exiv28Internal14Nikon3MnHeader9ifdOffsetEv:
  370|    359|size_t Nikon3MnHeader::ifdOffset() const {
  371|    359|  return start_;
  372|    359|}
_ZNK5Exiv28Internal14Nikon3MnHeader9byteOrderEv:
  374|  1.43k|ByteOrder Nikon3MnHeader::byteOrder() const {
  375|  1.43k|  return byteOrder_;
  376|  1.43k|}
_ZNK5Exiv28Internal14Nikon3MnHeader10baseOffsetEm:
  378|    359|size_t Nikon3MnHeader::baseOffset(size_t mnOffset) const {
  379|    359|  return Safe::add<size_t>(mnOffset, 10);
  380|    359|}
_ZN5Exiv28Internal14Nikon3MnHeader4readEPKhmNS_9ByteOrderE:
  382|    359|bool Nikon3MnHeader::read(const byte* pData, size_t size, ByteOrder) {
  383|    359|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (383:7): [True: 0, False: 359]
  |  Branch (383:17): [True: 0, False: 359]
  ------------------
  384|      0|    return false;
  385|    359|  if (0 != memcmp(pData, signature_, 6))
  ------------------
  |  Branch (385:7): [True: 0, False: 359]
  ------------------
  386|      0|    return false;
  387|    359|  buf_.alloc(sizeOfSignature());
  388|    359|  std::copy_n(pData, buf_.size(), buf_.begin());
  389|    359|  TiffHeader th;
  390|    359|  if (!th.read(buf_.data(10), 8))
  ------------------
  |  Branch (390:7): [True: 0, False: 359]
  ------------------
  391|      0|    return false;
  392|    359|  byteOrder_ = th.byteOrder();
  393|    359|  start_ = 10 + th.offset();
  394|    359|  return true;
  395|    359|}  // Nikon3MnHeader::read
_ZN5Exiv28Internal17PanasonicMnHeader15sizeOfSignatureEv:
  412|    925|size_t PanasonicMnHeader::sizeOfSignature() {
  413|    925|  return sizeof(signature_);
  414|    925|}
_ZN5Exiv28Internal17PanasonicMnHeaderC2Ev:
  416|    124|PanasonicMnHeader::PanasonicMnHeader() {
  417|    124|  read(signature_, sizeOfSignature(), invalidByteOrder);
  418|    124|}
_ZNK5Exiv28Internal17PanasonicMnHeader9ifdOffsetEv:
  424|     29|size_t PanasonicMnHeader::ifdOffset() const {
  425|     29|  return start_;
  426|     29|}
_ZN5Exiv28Internal17PanasonicMnHeader4readEPKhmNS_9ByteOrderE:
  428|    248|bool PanasonicMnHeader::read(const byte* pData, size_t size, ByteOrder) {
  429|    248|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (429:7): [True: 0, False: 248]
  |  Branch (429:17): [True: 0, False: 248]
  ------------------
  430|      0|    return false;
  431|    248|  if (0 != memcmp(pData, signature_, 9))
  ------------------
  |  Branch (431:7): [True: 95, False: 153]
  ------------------
  432|     95|    return false;
  433|    153|  buf_.alloc(sizeOfSignature());
  434|    153|  std::copy_n(pData, buf_.size(), buf_.begin());
  435|    153|  start_ = sizeOfSignature();
  436|    153|  return true;
  437|    248|}  // PanasonicMnHeader::read
_ZN5Exiv28Internal17PentaxDngMnHeader15sizeOfSignatureEv:
  446|    738|size_t PentaxDngMnHeader::sizeOfSignature() {
  447|    738|  return sizeof(signature_);
  448|    738|}
_ZN5Exiv28Internal17PentaxDngMnHeaderC2Ev:
  450|     78|PentaxDngMnHeader::PentaxDngMnHeader() {
  451|     78|  read(signature_, sizeOfSignature(), invalidByteOrder);
  452|     78|}
_ZNK5Exiv28Internal17PentaxDngMnHeader10baseOffsetEm:
  458|     78|size_t PentaxDngMnHeader::baseOffset(size_t mnOffset) const {
  459|     78|  return mnOffset;
  460|     78|}
_ZNK5Exiv28Internal17PentaxDngMnHeader9ifdOffsetEv:
  462|     78|size_t PentaxDngMnHeader::ifdOffset() const {
  463|     78|  return sizeOfSignature();
  464|     78|}
_ZN5Exiv28Internal17PentaxDngMnHeader4readEPKhmNS_9ByteOrderE:
  466|    156|bool PentaxDngMnHeader::read(const byte* pData, size_t size, ByteOrder) {
  467|    156|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (467:7): [True: 0, False: 156]
  |  Branch (467:17): [True: 0, False: 156]
  ------------------
  468|      0|    return false;
  469|    156|  header_.alloc(sizeOfSignature());
  470|    156|  std::copy_n(pData, header_.size(), header_.begin());
  471|    156|  return header_.size() >= sizeOfSignature() && 0 == header_.cmpBytes(0, signature_, 7);
  ------------------
  |  Branch (471:10): [True: 156, False: 0]
  |  Branch (471:49): [True: 156, False: 0]
  ------------------
  472|    156|}
_ZN5Exiv28Internal14PentaxMnHeader15sizeOfSignatureEv:
  481|  1.58k|size_t PentaxMnHeader::sizeOfSignature() {
  482|  1.58k|  return sizeof(signature_);
  483|  1.58k|}
_ZN5Exiv28Internal14PentaxMnHeaderC2Ev:
  485|    165|PentaxMnHeader::PentaxMnHeader() {
  486|    165|  read(signature_, sizeOfSignature(), invalidByteOrder);
  487|    165|}
_ZNK5Exiv28Internal14PentaxMnHeader9ifdOffsetEv:
  493|    165|size_t PentaxMnHeader::ifdOffset() const {
  494|    165|  return sizeOfSignature();
  495|    165|}
_ZN5Exiv28Internal14PentaxMnHeader4readEPKhmNS_9ByteOrderE:
  497|    330|bool PentaxMnHeader::read(const byte* pData, size_t size, ByteOrder) {
  498|    330|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (498:7): [True: 0, False: 330]
  |  Branch (498:17): [True: 0, False: 330]
  ------------------
  499|      0|    return false;
  500|    330|  header_.alloc(sizeOfSignature());
  501|    330|  std::copy_n(pData, header_.size(), header_.begin());
  502|    330|  return header_.size() >= sizeOfSignature() && 0 == header_.cmpBytes(0, signature_, 3);
  ------------------
  |  Branch (502:10): [True: 330, False: 0]
  |  Branch (502:49): [True: 330, False: 0]
  ------------------
  503|    330|}
_ZN5Exiv28Internal15SamsungMnHeaderC2Ev:
  510|    167|SamsungMnHeader::SamsungMnHeader() {
  511|    167|  read(nullptr, 0, invalidByteOrder);
  512|    167|}
_ZNK5Exiv28Internal15SamsungMnHeader10baseOffsetEm:
  518|    167|size_t SamsungMnHeader::baseOffset(size_t mnOffset) const {
  519|    167|  return mnOffset;
  520|    167|}
_ZN5Exiv28Internal15SamsungMnHeader4readEPKhmNS_9ByteOrderE:
  522|    334|bool SamsungMnHeader::read(const byte* /*pData*/, size_t /*size*/, ByteOrder) {
  523|    334|  return true;
  524|    334|}  // SamsungMnHeader::read
_ZN5Exiv28Internal13SigmaMnHeader15sizeOfSignatureEv:
  533|  1.49k|size_t SigmaMnHeader::sizeOfSignature() {
  534|  1.49k|  return sizeof(signature1_);
  535|  1.49k|}
_ZN5Exiv28Internal13SigmaMnHeaderC2Ev:
  537|    179|SigmaMnHeader::SigmaMnHeader() {
  538|    179|  read(signature1_, sizeOfSignature(), invalidByteOrder);
  539|    179|}
_ZNK5Exiv28Internal13SigmaMnHeader9ifdOffsetEv:
  545|     97|size_t SigmaMnHeader::ifdOffset() const {
  546|     97|  return start_;
  547|     97|}
_ZN5Exiv28Internal13SigmaMnHeader4readEPKhmNS_9ByteOrderE:
  549|    358|bool SigmaMnHeader::read(const byte* pData, size_t size, ByteOrder) {
  550|    358|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (550:7): [True: 0, False: 358]
  |  Branch (550:17): [True: 0, False: 358]
  ------------------
  551|      0|    return false;
  552|    358|  if (0 != memcmp(pData, signature1_, 8) && 0 != memcmp(pData, signature2_, 8))
  ------------------
  |  Branch (552:7): [True: 104, False: 254]
  |  Branch (552:45): [True: 82, False: 22]
  ------------------
  553|     82|    return false;
  554|    276|  buf_.alloc(sizeOfSignature());
  555|    276|  std::copy_n(pData, buf_.size(), buf_.begin());
  556|    276|  start_ = sizeOfSignature();
  557|    276|  return true;
  558|    358|}  // SigmaMnHeader::read
_ZN5Exiv28Internal12SonyMnHeader15sizeOfSignatureEv:
  567|  2.02k|size_t SonyMnHeader::sizeOfSignature() {
  568|  2.02k|  return sizeof(signature_);
  569|  2.02k|}
_ZN5Exiv28Internal12SonyMnHeaderC2Ev:
  571|    199|SonyMnHeader::SonyMnHeader() {
  572|    199|  read(signature_, sizeOfSignature(), invalidByteOrder);
  573|    199|}
_ZNK5Exiv28Internal12SonyMnHeader9ifdOffsetEv:
  579|    199|size_t SonyMnHeader::ifdOffset() const {
  580|    199|  return start_;
  581|    199|}
_ZN5Exiv28Internal12SonyMnHeader4readEPKhmNS_9ByteOrderE:
  583|    398|bool SonyMnHeader::read(const byte* pData, size_t size, ByteOrder) {
  584|    398|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (584:7): [True: 0, False: 398]
  |  Branch (584:17): [True: 0, False: 398]
  ------------------
  585|      0|    return false;
  586|    398|  if (0 != memcmp(pData, signature_, sizeOfSignature()))
  ------------------
  |  Branch (586:7): [True: 0, False: 398]
  ------------------
  587|      0|    return false;
  588|    398|  buf_.alloc(sizeOfSignature());
  589|    398|  std::copy_n(pData, buf_.size(), buf_.begin());
  590|    398|  start_ = sizeOfSignature();
  591|    398|  return true;
  592|    398|}  // SonyMnHeader::read
_ZN5Exiv28Internal14Casio2MnHeader15sizeOfSignatureEv:
  602|    666|size_t Casio2MnHeader::sizeOfSignature() {
  603|    666|  return sizeof(signature_);
  604|    666|}
_ZN5Exiv28Internal14Casio2MnHeaderC2Ev:
  606|     74|Casio2MnHeader::Casio2MnHeader() {
  607|     74|  read(signature_, sizeOfSignature(), invalidByteOrder);
  608|     74|}
_ZNK5Exiv28Internal14Casio2MnHeader9ifdOffsetEv:
  614|     74|size_t Casio2MnHeader::ifdOffset() const {
  615|     74|  return start_;
  616|     74|}
_ZNK5Exiv28Internal14Casio2MnHeader9byteOrderEv:
  618|    296|ByteOrder Casio2MnHeader::byteOrder() const {
  619|    296|  return byteOrder_;
  620|    296|}
_ZN5Exiv28Internal14Casio2MnHeader4readEPKhmNS_9ByteOrderE:
  622|    148|bool Casio2MnHeader::read(const byte* pData, size_t size, ByteOrder) {
  623|    148|  if (!pData || size < sizeOfSignature())
  ------------------
  |  Branch (623:7): [True: 0, False: 148]
  |  Branch (623:17): [True: 0, False: 148]
  ------------------
  624|      0|    return false;
  625|    148|  if (0 != memcmp(pData, signature_, sizeOfSignature()))
  ------------------
  |  Branch (625:7): [True: 0, False: 148]
  ------------------
  626|      0|    return false;
  627|    148|  buf_.alloc(sizeOfSignature());
  628|    148|  std::copy_n(pData, buf_.size(), buf_.begin());
  629|    148|  start_ = sizeOfSignature();
  630|    148|  return true;
  631|    148|}  // Casio2MnHeader::read
_ZN5Exiv28Internal8newIfdMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  642|    200|                                           ByteOrder) {
  643|       |  // Require at least an IFD with 1 entry, but not necessarily a next pointer
  644|    200|  if (size < 14)
  ------------------
  |  Branch (644:7): [True: 77, False: 123]
  ------------------
  645|     77|    return nullptr;
  646|    123|  return newIfdMn2(tag, group, mnGroup);
  647|    200|}
_ZN5Exiv28Internal9newIfdMn2EtNS_5IfdIdES1_:
  649|    296|std::unique_ptr<TiffIfdMakernote> newIfdMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  650|    296|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, nullptr);
  651|    296|}
_ZN5Exiv28Internal12newOlympusMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  654|    781|                                               ByteOrder) {
  655|       |  // FIXME: workaround for overwritten OM System header in Olympus files (https://github.com/Exiv2/exiv2/issues/2542)
  656|    781|  if (size >= 14 && std::string(reinterpret_cast<const char*>(pData), 14) == std::string("OM SYSTEM\0\0\0II", 14)) {
  ------------------
  |  Branch (656:7): [True: 487, False: 294]
  |  Branch (656:7): [True: 111, False: 670]
  |  Branch (656:21): [True: 111, False: 376]
  ------------------
  657|       |    // Require at least the header and an IFD with 1 entry
  658|    111|    if (size < OMSystemMnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (658:9): [True: 66, False: 45]
  ------------------
  659|     66|      return nullptr;
  660|     45|    return newOMSystemMn2(tag, group, IfdId::olympus2Id);
  661|    111|  }
  662|    670|  if (size < 10 || std::string(reinterpret_cast<const char*>(pData), 10) != std::string("OLYMPUS\0II", 10)) {
  ------------------
  |  Branch (662:7): [True: 227, False: 443]
  |  Branch (662:7): [True: 445, False: 225]
  |  Branch (662:20): [True: 218, False: 225]
  ------------------
  663|       |    // Require at least the header and an IFD with 1 entry
  664|    445|    if (size < OlympusMnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (664:9): [True: 299, False: 146]
  ------------------
  665|    299|      return nullptr;
  666|    146|    return newOlympusMn2(tag, group, IfdId::olympusId);
  667|    445|  }
  668|       |  // Require at least the header and an IFD with 1 entry
  669|    225|  if (size < Olympus2MnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (669:7): [True: 34, False: 191]
  ------------------
  670|     34|    return nullptr;
  671|    191|  return newOlympus2Mn2(tag, group, IfdId::olympus2Id);
  672|    225|}
_ZN5Exiv28Internal13newOlympusMn2EtNS_5IfdIdES1_:
  674|    146|std::unique_ptr<TiffIfdMakernote> newOlympusMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  675|    146|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<OlympusMnHeader>());
  676|    146|}
_ZN5Exiv28Internal14newOlympus2Mn2EtNS_5IfdIdES1_:
  678|    191|std::unique_ptr<TiffIfdMakernote> newOlympus2Mn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  679|    191|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<Olympus2MnHeader>());
  680|    191|}
_ZN5Exiv28Internal13newOMSystemMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  683|    162|                                                ByteOrder) {
  684|       |  // Require at least the header and an IFD with 1 entry
  685|    162|  if (size < OMSystemMnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (685:7): [True: 91, False: 71]
  ------------------
  686|     91|    return nullptr;
  687|     71|  return newOMSystemMn2(tag, group, mnGroup);
  688|    162|}
_ZN5Exiv28Internal14newOMSystemMn2EtNS_5IfdIdES1_:
  690|    116|std::unique_ptr<TiffIfdMakernote> newOMSystemMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  691|    116|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<OMSystemMnHeader>());
  692|    116|}
_ZN5Exiv28Internal9newFujiMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  695|    410|                                            ByteOrder) {
  696|       |  // Require at least the header and an IFD with 1 entry
  697|    410|  if (size < FujiMnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (697:7): [True: 222, False: 188]
  ------------------
  698|    222|    return nullptr;
  699|    188|  return newFujiMn2(tag, group, mnGroup);
  700|    410|}
_ZN5Exiv28Internal10newFujiMn2EtNS_5IfdIdES1_:
  702|    188|std::unique_ptr<TiffIfdMakernote> newFujiMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  703|    188|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<FujiMnHeader>());
  704|    188|}
_ZN5Exiv28Internal10newNikonMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  707|  1.38k|                                             ByteOrder) {
  708|       |  // If there is no "Nikon" string it must be Nikon1 format
  709|  1.38k|  if (size < 6 || std::string(reinterpret_cast<const char*>(pData), 6) != std::string("Nikon\0", 6)) {
  ------------------
  |  Branch (709:7): [True: 668, False: 712]
  |  Branch (709:7): [True: 830, False: 550]
  |  Branch (709:19): [True: 162, False: 550]
  ------------------
  710|       |    // Require at least an IFD with 1 entry
  711|    830|    if (size < 18)
  ------------------
  |  Branch (711:9): [True: 734, False: 96]
  ------------------
  712|    734|      return nullptr;
  713|     96|    return newIfdMn2(tag, group, IfdId::nikon1Id);
  714|    830|  }
  715|       |  // If the "Nikon" string is not followed by a TIFF header, we assume
  716|       |  // Nikon2 format
  717|    550|  TiffHeader tiffHeader;
  718|    550|  if (size < 18 || !tiffHeader.read(pData + 10, size - 10) || tiffHeader.tag() != 0x002a) {
  ------------------
  |  Branch (718:7): [True: 34, False: 516]
  |  Branch (718:20): [True: 109, False: 407]
  |  Branch (718:63): [True: 37, False: 370]
  ------------------
  719|       |    // Require at least the header and an IFD with 1 entry
  720|    180|    if (size < Nikon2MnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (720:9): [True: 64, False: 116]
  ------------------
  721|     64|      return nullptr;
  722|    116|    return newNikon2Mn2(tag, group, IfdId::nikon2Id);
  723|    180|  }
  724|       |  // Else we have a Nikon3 makernote
  725|       |  // Require at least the header and an IFD with 1 entry
  726|    370|  if (size < Nikon3MnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (726:7): [True: 11, False: 359]
  ------------------
  727|     11|    return nullptr;
  728|    359|  return newNikon3Mn2(tag, group, IfdId::nikon3Id);
  729|    370|}
_ZN5Exiv28Internal12newNikon2Mn2EtNS_5IfdIdES1_:
  731|    116|std::unique_ptr<TiffIfdMakernote> newNikon2Mn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  732|    116|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<Nikon2MnHeader>());
  733|    116|}
_ZN5Exiv28Internal12newNikon3Mn2EtNS_5IfdIdES1_:
  735|    359|std::unique_ptr<TiffIfdMakernote> newNikon3Mn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  736|    359|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<Nikon3MnHeader>());
  737|    359|}
_ZN5Exiv28Internal14newPanasonicMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  740|    247|                                                 ByteOrder) {
  741|       |  // Require at least the header and an IFD with 1 entry, but without a next pointer
  742|    247|  if (size < PanasonicMnHeader::sizeOfSignature() + 14)
  ------------------
  |  Branch (742:7): [True: 123, False: 124]
  ------------------
  743|    123|    return nullptr;
  744|    124|  return newPanasonicMn2(tag, group, mnGroup);
  745|    247|}
_ZN5Exiv28Internal15newPanasonicMn2EtNS_5IfdIdES1_:
  747|    124|std::unique_ptr<TiffIfdMakernote> newPanasonicMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  748|    124|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<PanasonicMnHeader>(), false);
  749|    124|}
_ZN5Exiv28Internal11newPentaxMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  752|    565|                                              ByteOrder) {
  753|    565|  if (size > 8 && std::string(reinterpret_cast<const char*>(pData), 8) == std::string("PENTAX \0", 8)) {
  ------------------
  |  Branch (753:7): [True: 342, False: 223]
  |  Branch (753:7): [True: 114, False: 451]
  |  Branch (753:19): [True: 114, False: 228]
  ------------------
  754|       |    // Require at least the header and an IFD with 1 entry
  755|    114|    if (size < PentaxDngMnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (755:9): [True: 36, False: 78]
  ------------------
  756|     36|      return nullptr;
  757|     78|    return newPentaxDngMn2(tag, group, (tag == 0xc634 ? IfdId::pentaxDngId : IfdId::pentaxId));
  ------------------
  |  Branch (757:41): [True: 78, False: 0]
  ------------------
  758|    114|  }
  759|    451|  if (size > 4 && std::string(reinterpret_cast<const char*>(pData), 4) == std::string("AOC\0", 4)) {
  ------------------
  |  Branch (759:7): [True: 238, False: 213]
  |  Branch (759:7): [True: 160, False: 291]
  |  Branch (759:19): [True: 160, False: 78]
  ------------------
  760|       |    // Require at least the header and an IFD with 1 entry
  761|    160|    if (size < PentaxMnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (761:9): [True: 68, False: 92]
  ------------------
  762|     68|      return nullptr;
  763|     92|    return newPentaxMn2(tag, group, IfdId::pentaxId);
  764|    160|  }
  765|    291|  return nullptr;
  766|    451|}
_ZN5Exiv28Internal12newPentaxMn2EtNS_5IfdIdES1_:
  768|    165|std::unique_ptr<TiffIfdMakernote> newPentaxMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  769|    165|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<PentaxMnHeader>());
  770|    165|}
_ZN5Exiv28Internal15newPentaxDngMn2EtNS_5IfdIdES1_:
  772|     78|std::unique_ptr<TiffIfdMakernote> newPentaxDngMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  773|     78|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<PentaxDngMnHeader>());
  774|     78|}
_ZN5Exiv28Internal12newSamsungMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  777|    534|                                               ByteOrder) {
  778|    534|  if (size > 4 && std::string(reinterpret_cast<const char*>(pData), 4) == std::string("AOC\0", 4)) {
  ------------------
  |  Branch (778:7): [True: 313, False: 221]
  |  Branch (778:7): [True: 107, False: 427]
  |  Branch (778:19): [True: 107, False: 206]
  ------------------
  779|       |    // Samsung branded Pentax camera:
  780|       |    // Require at least the header and an IFD with 1 entry
  781|    107|    if (size < PentaxMnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (781:9): [True: 34, False: 73]
  ------------------
  782|     34|      return nullptr;
  783|     73|    return newPentaxMn2(tag, group, IfdId::pentaxId);
  784|    107|  }
  785|       |  // Genuine Samsung camera:
  786|       |  // Require at least an IFD with 1 entry
  787|    427|  if (size < 18)
  ------------------
  |  Branch (787:7): [True: 260, False: 167]
  ------------------
  788|    260|    return nullptr;
  789|    167|  return newSamsungMn2(tag, group, mnGroup);
  790|    427|}
_ZN5Exiv28Internal13newSamsungMn2EtNS_5IfdIdES1_:
  792|    167|std::unique_ptr<TiffIfdMakernote> newSamsungMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  793|    167|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<SamsungMnHeader>());
  794|    167|}
_ZN5Exiv28Internal10newSigmaMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  797|    401|                                             ByteOrder) {
  798|       |  // Require at least the header and an IFD with 1 entry
  799|    401|  if (size < SigmaMnHeader::sizeOfSignature() + 18)
  ------------------
  |  Branch (799:7): [True: 222, False: 179]
  ------------------
  800|    222|    return nullptr;
  801|    179|  return newSigmaMn2(tag, group, mnGroup);
  802|    401|}
_ZN5Exiv28Internal11newSigmaMn2EtNS_5IfdIdES1_:
  804|    179|std::unique_ptr<TiffIfdMakernote> newSigmaMn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  805|    179|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<SigmaMnHeader>());
  806|    179|}
_ZN5Exiv28Internal9newSonyMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  809|    924|                                            ByteOrder) {
  810|       |  // If there is no "SONY DSC " string we assume it's a simple IFD Makernote
  811|    924|  if (size < 12 || std::string(reinterpret_cast<const char*>(pData), 12) != std::string("SONY DSC \0\0\0", 12)) {
  ------------------
  |  Branch (811:7): [True: 233, False: 691]
  |  Branch (811:7): [True: 690, False: 234]
  |  Branch (811:20): [True: 457, False: 234]
  ------------------
  812|       |    // Require at least an IFD with 1 entry
  813|    690|    if (size < 18)
  ------------------
  |  Branch (813:9): [True: 299, False: 391]
  ------------------
  814|    299|      return nullptr;
  815|    391|    return newSony2Mn2(tag, group, IfdId::sony2Id);
  816|    690|  }
  817|       |  // Require at least the header and an IFD with 1 entry, but without a next pointer
  818|    234|  if (size < SonyMnHeader::sizeOfSignature() + 14)
  ------------------
  |  Branch (818:7): [True: 35, False: 199]
  ------------------
  819|     35|    return nullptr;
  820|    199|  return newSony1Mn2(tag, group, IfdId::sony1Id);
  821|    234|}
_ZN5Exiv28Internal11newSony1Mn2EtNS_5IfdIdES1_:
  823|    199|std::unique_ptr<TiffIfdMakernote> newSony1Mn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  824|    199|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<SonyMnHeader>(), false);
  825|    199|}
_ZN5Exiv28Internal11newSony2Mn2EtNS_5IfdIdES1_:
  827|    391|std::unique_ptr<TiffIfdMakernote> newSony2Mn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  828|    391|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, nullptr, true);
  829|    391|}
_ZN5Exiv28Internal10newCasioMnEtNS_5IfdIdES1_PKhmNS_9ByteOrderE:
  832|    416|                                             ByteOrder) {
  833|    416|  if (size > 6 && std::string(reinterpret_cast<const char*>(pData), 6) == std::string("QVC\0\0\0", 6))
  ------------------
  |  Branch (833:7): [True: 192, False: 224]
  |  Branch (833:7): [True: 74, False: 342]
  |  Branch (833:19): [True: 74, False: 118]
  ------------------
  834|     74|    return newCasio2Mn2(tag, group, IfdId::casio2Id);
  835|       |  // Require at least an IFD with 1 entry, but not necessarily a next pointer
  836|    342|  if (size < 14)
  ------------------
  |  Branch (836:7): [True: 265, False: 77]
  ------------------
  837|    265|    return nullptr;
  838|     77|  return newIfdMn2(tag, group, IfdId::casioId);
  839|    342|}
_ZN5Exiv28Internal12newCasio2Mn2EtNS_5IfdIdES1_:
  841|     74|std::unique_ptr<TiffIfdMakernote> newCasio2Mn2(uint16_t tag, IfdId group, IfdId mnGroup) {
  842|     74|  return std::make_unique<TiffIfdMakernote>(tag, group, mnGroup, std::make_unique<Casio2MnHeader>());
  843|     74|}
_ZN5Exiv28Internal13nikonSelectorEtPKhmPNS0_13TiffComponentE:
  910|    252|int nikonSelector(uint16_t tag, const byte* pData, size_t size, TiffComponent* /*pRoot*/) {
  911|    252|  if (size < 4)
  ------------------
  |  Branch (911:7): [True: 8, False: 244]
  ------------------
  912|      8|    return -1;
  913|       |
  914|    244|  auto ix = NikonArrayIdx::Key{tag, reinterpret_cast<const char*>(pData), size};
  915|    244|  if (auto it = Exiv2::find(nikonArrayIdx, ix))
  ------------------
  |  Branch (915:12): [True: 105, False: 139]
  ------------------
  916|    105|    return it->idx_;
  917|    139|  return -1;
  918|    244|}
_ZN5Exiv28Internal10nikonCryptEtPKhmPNS0_13TiffComponentE:
  920|     66|DataBuf nikonCrypt(uint16_t tag, const byte* pData, size_t size, TiffComponent* pRoot) {
  921|     66|  DataBuf buf;
  922|       |
  923|     66|  if (size < 4)
  ------------------
  |  Branch (923:7): [True: 0, False: 66]
  ------------------
  924|      0|    return buf;
  925|     66|  auto nci = Exiv2::find(nikonArrayIdx, NikonArrayIdx::Key{tag, reinterpret_cast<const char*>(pData), size});
  926|     66|  if (!nci || nci->start_ == NA || size <= nci->start_)
  ------------------
  |  |  865|    132|#define NA std::numeric_limits<uint32_t>::max()
  ------------------
  |  Branch (926:7): [True: 0, False: 66]
  |  Branch (926:15): [True: 5, False: 61]
  |  Branch (926:36): [True: 3, False: 58]
  ------------------
  927|      8|    return buf;
  928|       |
  929|       |  // Find Exif.Nikon3.ShutterCount
  930|     58|  TiffFinder finder(0x00a7, IfdId::nikon3Id);
  931|     58|  pRoot->accept(finder);
  932|     58|  auto te = dynamic_cast<const TiffEntryBase*>(finder.result());
  933|     58|  if (!te || !te->pValue() || te->pValue()->count() == 0)
  ------------------
  |  Branch (933:7): [True: 19, False: 39]
  |  Branch (933:14): [True: 4, False: 35]
  |  Branch (933:31): [True: 20, False: 15]
  ------------------
  934|     43|    return buf;
  935|     15|  auto count = te->pValue()->toUint32();
  936|       |
  937|       |  // Find Exif.Nikon3.SerialNumber
  938|     15|  finder.init(0x001d, IfdId::nikon3Id);
  939|     15|  pRoot->accept(finder);
  940|     15|  te = dynamic_cast<const TiffEntryBase*>(finder.result());
  941|     15|  if (!te || !te->pValue() || te->pValue()->count() == 0)
  ------------------
  |  Branch (941:7): [True: 1, False: 14]
  |  Branch (941:14): [True: 1, False: 13]
  |  Branch (941:31): [True: 1, False: 12]
  ------------------
  942|      3|    return buf;
  943|     12|  bool ok(false);
  944|     12|  auto serial = stringTo<uint32_t>(te->pValue()->toString(), ok);
  945|     12|  if (!ok) {
  ------------------
  |  Branch (945:7): [True: 7, False: 5]
  ------------------
  946|      7|    std::string model = getExifModel(pRoot);
  947|      7|    if (model.empty())
  ------------------
  |  Branch (947:9): [True: 3, False: 4]
  ------------------
  948|      3|      return buf;
  949|      4|    if (Internal::contains(model, "D50")) {
  ------------------
  |  Branch (949:9): [True: 0, False: 4]
  ------------------
  950|      0|      serial = 0x22;
  951|      4|    } else {
  952|      4|      serial = 0x60;
  953|      4|    }
  954|      4|  }
  955|      9|  buf.alloc(size);
  956|      9|  std::copy_n(pData, buf.size(), buf.begin());
  957|      9|  ncrypt(buf.data(nci->start_), static_cast<uint32_t>(buf.size()) - nci->start_, count, serial);
  958|      9|  return buf;
  959|     12|}
_ZN5Exiv28Internal14sonyCsSelectorEtPKhmPNS0_13TiffComponentE:
  961|     75|int sonyCsSelector(uint16_t /*tag*/, const byte* /*pData*/, size_t /*size*/, TiffComponent* pRoot) {
  962|     75|  std::string model = getExifModel(pRoot);
  963|     75|  if (model.empty())
  ------------------
  |  Branch (963:7): [True: 35, False: 40]
  ------------------
  964|     35|    return -1;
  965|     40|  int idx = 0;
  966|     40|  if (Internal::contains(model, "DSLR-A330") || Internal::contains(model, "DSLR-A380")) {
  ------------------
  |  Branch (966:7): [True: 9, False: 31]
  |  Branch (966:49): [True: 4, False: 27]
  ------------------
  967|     13|    idx = 1;
  968|     13|  }
  969|     40|  return idx;
  970|     75|}
_ZN5Exiv28Internal17sony2010eSelectorEtPKhmPNS0_13TiffComponentE:
  971|     21|int sony2010eSelector(uint16_t /*tag*/, const byte* /*pData*/, size_t /*size*/, TiffComponent* pRoot) {
  972|     21|  static constexpr const char* models[] = {
  973|     21|      "SLT-A58",   "SLT-A99",  "ILCE-3000", "ILCE-3500", "NEX-3N",    "NEX-5R",   "NEX-5T",
  974|     21|      "NEX-6",     "VG30E",    "VG900",     "DSC-RX100", "DSC-RX1",   "DSC-RX1R", "DSC-HX300",
  975|     21|      "DSC-HX50V", "DSC-TX30", "DSC-WX60",  "DSC-WX200", "DSC-WX300",
  976|     21|  };
  977|     21|  return Exiv2::find(models, getExifModel(pRoot)) ? 0 : -1;
  ------------------
  |  Branch (977:10): [True: 0, False: 21]
  ------------------
  978|     21|}
_ZN5Exiv28Internal15sony2FpSelectorEtPKhmPNS0_13TiffComponentE:
  980|     47|int sony2FpSelector(uint16_t /*tag*/, const byte* /*pData*/, size_t /*size*/, TiffComponent* pRoot) {
  981|       |  // Not valid for models beginning
  982|     47|  std::string model = getExifModel(pRoot);
  983|     47|  for (auto str : {"SLT-", "HV", "ILCA-"})
  ------------------
  |  Branch (983:17): [True: 139, False: 46]
  ------------------
  984|    139|    if (model.starts_with(str))
  ------------------
  |  Branch (984:9): [True: 1, False: 138]
  ------------------
  985|      1|      return -1;
  986|     46|  return 0;
  987|     47|}
_ZN5Exiv28Internal18sonyMisc2bSelectorEtPKhmPNS0_13TiffComponentE:
  989|     93|int sonyMisc2bSelector(uint16_t /*tag*/, const byte* /*pData*/, size_t /*size*/, TiffComponent* pRoot) {
  990|       |  // From Exiftool: https://github.com/exiftool/exiftool/blob/master/lib/Image/ExifTool/Sony.pm
  991|       |  // >  First byte must be 9 or 12 or 13 or 15 or 16 and 4th byte must be 2 (deciphered)
  992|       |
  993|       |  // Get the value from the image format that is being used
  994|     93|  auto value = getExifValue(pRoot, 0x9404, Exiv2::IfdId::sony1Id);
  995|     93|  if (!value) {
  ------------------
  |  Branch (995:7): [True: 74, False: 19]
  ------------------
  996|     74|    value = getExifValue(pRoot, 0x9404, Exiv2::IfdId::sony2Id);
  997|     74|    if (!value)
  ------------------
  |  Branch (997:9): [True: 0, False: 74]
  ------------------
  998|      0|      return -1;
  999|     74|  }
 1000|       |
 1001|     93|  if (value->count() < 4)
  ------------------
  |  Branch (1001:7): [True: 10, False: 83]
  ------------------
 1002|     10|    return -1;
 1003|       |
 1004|     83|  switch (value->toInt64(0)) {                 // Using encrypted values
 1005|     10|    case 231:                                  // 231 == 9
  ------------------
  |  Branch (1005:5): [True: 10, False: 73]
  ------------------
 1006|     19|    case 234:                                  // 234 == 12
  ------------------
  |  Branch (1006:5): [True: 9, False: 74]
  ------------------
 1007|     30|    case 205:                                  // 205 == 13
  ------------------
  |  Branch (1007:5): [True: 11, False: 72]
  ------------------
 1008|     42|    case 138:                                  // 138 == 15
  ------------------
  |  Branch (1008:5): [True: 12, False: 71]
  ------------------
 1009|     53|    case 112:                                  // 112 == 16
  ------------------
  |  Branch (1009:5): [True: 11, False: 72]
  ------------------
 1010|     53|      return value->toInt64(3) == 8 ? 0 : -1;  // 8   == 2
  ------------------
  |  Branch (1010:14): [True: 9, False: 44]
  ------------------
 1011|     30|    default:
  ------------------
  |  Branch (1011:5): [True: 30, False: 53]
  ------------------
 1012|     30|      break;
 1013|     83|  }
 1014|     30|  return -1;
 1015|     83|}
_ZN5Exiv28Internal18sonyMisc3cSelectorEtPKhmPNS0_13TiffComponentE:
 1016|    111|int sonyMisc3cSelector(uint16_t /*tag*/, const byte* /*pData*/, size_t /*size*/, TiffComponent* pRoot) {
 1017|       |  // For condition, see Exiftool (Tag 9400c):
 1018|       |  // https://github.com/exiftool/exiftool/blob/5a8b6b6ead12b39e3f32f978a4efd0233facbb01/lib/Image/ExifTool/Sony.pm#L1807
 1019|       |
 1020|       |  // Get the value from the image format that is being used
 1021|    111|  auto value = getExifValue(pRoot, 0x9400, Exiv2::IfdId::sony1Id);
 1022|    111|  if (!value) {
  ------------------
  |  Branch (1022:7): [True: 78, False: 33]
  ------------------
 1023|     78|    value = getExifValue(pRoot, 0x9400, Exiv2::IfdId::sony2Id);
 1024|     78|    if (!value)
  ------------------
  |  Branch (1024:9): [True: 0, False: 78]
  ------------------
 1025|      0|      return -1;
 1026|     78|  }
 1027|       |
 1028|    111|  if (value->count() < 1)
  ------------------
  |  Branch (1028:7): [True: 2, False: 109]
  ------------------
 1029|      2|    return -1;
 1030|       |
 1031|    109|  switch (value->toInt64()) {
 1032|     16|    case 35:  // 0x23 for DSC-RX10/HX60V/HX350/HX400V/WX220/WX350, ILCE-7/7R/5000/6000, ILCA-68/77M2
  ------------------
  |  Branch (1032:5): [True: 16, False: 93]
  ------------------
 1033|     19|    case 36:  // 0x24 for ILCA-99M2,ILCE-5100/6300/6500/7M2/7RM2/7S/7SM2/QX1,
  ------------------
  |  Branch (1033:5): [True: 3, False: 106]
  ------------------
 1034|       |              // DSC-HX80/HX90V/QX30/RX0/RX100M3/RX100M4/RX100M5/RX10M2/RX10M3/RX1RM2/WX500
 1035|     29|    case 38:  // 0x26 for ILCE-6100/6400/6600/7M3/7RM3/9, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/HX95/HX99
  ------------------
  |  Branch (1035:5): [True: 10, False: 99]
  ------------------
 1036|     35|    case 40:  // 0x28 for ILCE-7RM4/9M2, DSC-RX100M7, ZV-1/1F/1M2/E10
  ------------------
  |  Branch (1036:5): [True: 6, False: 103]
  ------------------
 1037|     45|    case 49:  // 0x31 for ILCE-1/7M4/7SM3, ILME-FX3
  ------------------
  |  Branch (1037:5): [True: 10, False: 99]
  ------------------
 1038|     56|    case 50:  // 0x32 for ILCE-7RM5, ILME-FX30
  ------------------
  |  Branch (1038:5): [True: 11, False: 98]
  ------------------
 1039|     69|    case 51:  // 0x33 for ILCE-6700/7CM2/7CR/9M3, ZV-E1
  ------------------
  |  Branch (1039:5): [True: 13, False: 96]
  ------------------
 1040|     80|    case 65:  // 0x41 for ILCE-7M5
  ------------------
  |  Branch (1040:5): [True: 11, False: 98]
  ------------------
 1041|     80|      return 0;
 1042|     29|    default:
  ------------------
  |  Branch (1042:5): [True: 29, False: 80]
  ------------------
 1043|     29|      break;
 1044|    109|  }
 1045|     29|  return -1;
 1046|    109|}
makernote_int.cpp:_ZN12_GLOBAL__N_112getExifValueEPN5Exiv28Internal13TiffComponentEtNS0_5IfdIdE:
 1052|    506|const Exiv2::Value* getExifValue(Exiv2::Internal::TiffComponent* pRoot, uint16_t tag, Exiv2::IfdId group) {
 1053|    506|  Exiv2::Internal::TiffFinder finder(tag, group);
 1054|    506|  if (!pRoot)
  ------------------
  |  Branch (1054:7): [True: 0, False: 506]
  ------------------
 1055|      0|    return nullptr;
 1056|    506|  pRoot->accept(finder);
 1057|    506|  auto te = dynamic_cast<const Exiv2::Internal::TiffEntryBase*>(finder.result());
 1058|    506|  return (!te || !te->pValue()) ? nullptr : te->pValue();
  ------------------
  |  Branch (1058:11): [True: 194, False: 312]
  |  Branch (1058:18): [True: 15, False: 297]
  ------------------
 1059|    506|}
makernote_int.cpp:_ZN12_GLOBAL__N_112getExifModelEPN5Exiv28Internal13TiffComponentE:
 1061|    150|std::string getExifModel(Exiv2::Internal::TiffComponent* pRoot) {
 1062|       |  // Lookup the Exif.Image.Model tag
 1063|    150|  const auto value = getExifValue(pRoot, 0x0110, Exiv2::IfdId::ifd0Id);
 1064|    150|  return (!value || value->count() == 0) ? std::string() : value->toString();
  ------------------
  |  Branch (1064:11): [True: 57, False: 93]
  |  Branch (1064:21): [True: 16, False: 77]
  ------------------
 1065|    150|}
makernote_int.cpp:_ZN12_GLOBAL__N_16ncryptEPhjjj:
 1067|      9|void ncrypt(Exiv2::byte* pData, uint32_t size, uint32_t count, uint32_t serial) {
 1068|      9|  static const Exiv2::byte xlat[2][256] = {
 1069|      9|      {0xc1, 0xbf, 0x6d, 0x0d, 0x59, 0xc5, 0x13, 0x9d, 0x83, 0x61, 0x6b, 0x4f, 0xc7, 0x7f, 0x3d, 0x3d, 0x53, 0x59, 0xe3,
 1070|      9|       0xc7, 0xe9, 0x2f, 0x95, 0xa7, 0x95, 0x1f, 0xdf, 0x7f, 0x2b, 0x29, 0xc7, 0x0d, 0xdf, 0x07, 0xef, 0x71, 0x89, 0x3d,
 1071|      9|       0x13, 0x3d, 0x3b, 0x13, 0xfb, 0x0d, 0x89, 0xc1, 0x65, 0x1f, 0xb3, 0x0d, 0x6b, 0x29, 0xe3, 0xfb, 0xef, 0xa3, 0x6b,
 1072|      9|       0x47, 0x7f, 0x95, 0x35, 0xa7, 0x47, 0x4f, 0xc7, 0xf1, 0x59, 0x95, 0x35, 0x11, 0x29, 0x61, 0xf1, 0x3d, 0xb3, 0x2b,
 1073|      9|       0x0d, 0x43, 0x89, 0xc1, 0x9d, 0x9d, 0x89, 0x65, 0xf1, 0xe9, 0xdf, 0xbf, 0x3d, 0x7f, 0x53, 0x97, 0xe5, 0xe9, 0x95,
 1074|      9|       0x17, 0x1d, 0x3d, 0x8b, 0xfb, 0xc7, 0xe3, 0x67, 0xa7, 0x07, 0xf1, 0x71, 0xa7, 0x53, 0xb5, 0x29, 0x89, 0xe5, 0x2b,
 1075|      9|       0xa7, 0x17, 0x29, 0xe9, 0x4f, 0xc5, 0x65, 0x6d, 0x6b, 0xef, 0x0d, 0x89, 0x49, 0x2f, 0xb3, 0x43, 0x53, 0x65, 0x1d,
 1076|      9|       0x49, 0xa3, 0x13, 0x89, 0x59, 0xef, 0x6b, 0xef, 0x65, 0x1d, 0x0b, 0x59, 0x13, 0xe3, 0x4f, 0x9d, 0xb3, 0x29, 0x43,
 1077|      9|       0x2b, 0x07, 0x1d, 0x95, 0x59, 0x59, 0x47, 0xfb, 0xe5, 0xe9, 0x61, 0x47, 0x2f, 0x35, 0x7f, 0x17, 0x7f, 0xef, 0x7f,
 1078|      9|       0x95, 0x95, 0x71, 0xd3, 0xa3, 0x0b, 0x71, 0xa3, 0xad, 0x0b, 0x3b, 0xb5, 0xfb, 0xa3, 0xbf, 0x4f, 0x83, 0x1d, 0xad,
 1079|      9|       0xe9, 0x2f, 0x71, 0x65, 0xa3, 0xe5, 0x07, 0x35, 0x3d, 0x0d, 0xb5, 0xe9, 0xe5, 0x47, 0x3b, 0x9d, 0xef, 0x35, 0xa3,
 1080|      9|       0xbf, 0xb3, 0xdf, 0x53, 0xd3, 0x97, 0x53, 0x49, 0x71, 0x07, 0x35, 0x61, 0x71, 0x2f, 0x43, 0x2f, 0x11, 0xdf, 0x17,
 1081|      9|       0x97, 0xfb, 0x95, 0x3b, 0x7f, 0x6b, 0xd3, 0x25, 0xbf, 0xad, 0xc7, 0xc5, 0xc5, 0xb5, 0x8b, 0xef, 0x2f, 0xd3, 0x07,
 1082|      9|       0x6b, 0x25, 0x49, 0x95, 0x25, 0x49, 0x6d, 0x71, 0xc7},
 1083|      9|      {0xa7, 0xbc, 0xc9, 0xad, 0x91, 0xdf, 0x85, 0xe5, 0xd4, 0x78, 0xd5, 0x17, 0x46, 0x7c, 0x29, 0x4c, 0x4d, 0x03, 0xe9,
 1084|      9|       0x25, 0x68, 0x11, 0x86, 0xb3, 0xbd, 0xf7, 0x6f, 0x61, 0x22, 0xa2, 0x26, 0x34, 0x2a, 0xbe, 0x1e, 0x46, 0x14, 0x68,
 1085|      9|       0x9d, 0x44, 0x18, 0xc2, 0x40, 0xf4, 0x7e, 0x5f, 0x1b, 0xad, 0x0b, 0x94, 0xb6, 0x67, 0xb4, 0x0b, 0xe1, 0xea, 0x95,
 1086|      9|       0x9c, 0x66, 0xdc, 0xe7, 0x5d, 0x6c, 0x05, 0xda, 0xd5, 0xdf, 0x7a, 0xef, 0xf6, 0xdb, 0x1f, 0x82, 0x4c, 0xc0, 0x68,
 1087|      9|       0x47, 0xa1, 0xbd, 0xee, 0x39, 0x50, 0x56, 0x4a, 0xdd, 0xdf, 0xa5, 0xf8, 0xc6, 0xda, 0xca, 0x90, 0xca, 0x01, 0x42,
 1088|      9|       0x9d, 0x8b, 0x0c, 0x73, 0x43, 0x75, 0x05, 0x94, 0xde, 0x24, 0xb3, 0x80, 0x34, 0xe5, 0x2c, 0xdc, 0x9b, 0x3f, 0xca,
 1089|      9|       0x33, 0x45, 0xd0, 0xdb, 0x5f, 0xf5, 0x52, 0xc3, 0x21, 0xda, 0xe2, 0x22, 0x72, 0x6b, 0x3e, 0xd0, 0x5b, 0xa8, 0x87,
 1090|      9|       0x8c, 0x06, 0x5d, 0x0f, 0xdd, 0x09, 0x19, 0x93, 0xd0, 0xb9, 0xfc, 0x8b, 0x0f, 0x84, 0x60, 0x33, 0x1c, 0x9b, 0x45,
 1091|      9|       0xf1, 0xf0, 0xa3, 0x94, 0x3a, 0x12, 0x77, 0x33, 0x4d, 0x44, 0x78, 0x28, 0x3c, 0x9e, 0xfd, 0x65, 0x57, 0x16, 0x94,
 1092|      9|       0x6b, 0xfb, 0x59, 0xd0, 0xc8, 0x22, 0x36, 0xdb, 0xd2, 0x63, 0x98, 0x43, 0xa1, 0x04, 0x87, 0x86, 0xf7, 0xa6, 0x26,
 1093|      9|       0xbb, 0xd6, 0x59, 0x4d, 0xbf, 0x6a, 0x2e, 0xaa, 0x2b, 0xef, 0xe6, 0x78, 0xb6, 0x4e, 0xe0, 0x2f, 0xdc, 0x7c, 0xbe,
 1094|      9|       0x57, 0x19, 0x32, 0x7e, 0x2a, 0xd0, 0xb8, 0xba, 0x29, 0x00, 0x3c, 0x52, 0x7d, 0xa8, 0x49, 0x3b, 0x2d, 0xeb, 0x25,
 1095|      9|       0x49, 0xfa, 0xa3, 0xaa, 0x39, 0xa7, 0xc5, 0xa7, 0x50, 0x11, 0x36, 0xfb, 0xc6, 0x67, 0x4a, 0xf5, 0xa5, 0x12, 0x65,
 1096|      9|       0x7e, 0xb0, 0xdf, 0xaf, 0x4e, 0xb3, 0x61, 0x7f, 0x2f},
 1097|      9|  };
 1098|      9|  Exiv2::byte key = 0;
 1099|     45|  for (int i = 0; i < 4; ++i) {
  ------------------
  |  Branch (1099:19): [True: 36, False: 9]
  ------------------
 1100|     36|    key ^= static_cast<Exiv2::byte>(count >> (i * 8));
 1101|     36|  }
 1102|      9|  Exiv2::byte ci = xlat[0][serial & 0xff];
 1103|      9|  Exiv2::byte cj = xlat[1][key];
 1104|      9|  Exiv2::byte ck = 0x60;
 1105|    318|  for (uint32_t i = 0; i < size; ++i) {
  ------------------
  |  Branch (1105:24): [True: 309, False: 9]
  ------------------
 1106|    309|    cj += ci * ck++;
 1107|    309|    pData[i] ^= cj;
 1108|    309|  }
 1109|      9|}
_ZNK5Exiv28Internal13NikonArrayIdxeqERKNS1_3KeyE:
  854|  6.89k|  bool operator==(const Key& key) const {
  855|  6.89k|    return key.tag_ == tag_ && 0 == strncmp(key.ver_, ver_, strlen(ver_)) && (size_ == 0 || key.size_ == size_);
  ------------------
  |  Branch (855:12): [True: 1.85k, False: 5.04k]
  |  Branch (855:32): [True: 184, False: 1.67k]
  |  Branch (855:79): [True: 171, False: 13]
  |  Branch (855:93): [True: 0, False: 13]
  ------------------
  856|  6.89k|  }

_ZN5Exiv28Internal8MnHeaderC2Ev:
   99|  2.10k|  MnHeader() = default;
_ZN5Exiv28Internal8MnHeaderD2Ev:
  101|  2.10k|  virtual ~MnHeader() = default;

_ZN5Exiv213MatroskaVideoC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
  599|  3.26k|MatroskaVideo::MatroskaVideo(BasicIo::UniquePtr io) : Image(ImageType::mkv, mdNone, std::move(io)) {
  600|  3.26k|}  // MatroskaVideo::MatroskaVideo
_ZNK5Exiv213MatroskaVideo8mimeTypeEv:
  602|  10.2k|std::string MatroskaVideo::mimeType() const {
  603|  10.2k|  return "video/matroska";
  604|  10.2k|}
_ZN5Exiv213MatroskaVideo12readMetadataEv:
  609|  3.26k|void MatroskaVideo::readMetadata() {
  610|  3.26k|  if (io_->open() != 0)
  ------------------
  |  Branch (610:7): [True: 0, False: 3.26k]
  ------------------
  611|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  612|       |
  613|       |  // Ensure that this is the correct image type
  614|  3.26k|  if (!isMkvType(*io_, false)) {
  ------------------
  |  Branch (614:7): [True: 0, False: 3.26k]
  ------------------
  615|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (615:9): [True: 0, False: 0]
  |  Branch (615:25): [True: 0, False: 0]
  ------------------
  616|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  617|      0|    throw Error(ErrorCode::kerNotAnImage, "Matroska");
  618|      0|  }
  619|       |
  620|  3.26k|  IoCloser closer(*io_);
  621|  3.26k|  clearMetadata();
  622|  3.26k|  continueTraversing_ = true;
  623|  3.26k|  height_ = width_ = 1;
  624|       |
  625|  3.26k|  xmpData_["Xmp.video.FileSize"] = io_->size() / bytesMB;
  626|  3.26k|  xmpData_["Xmp.video.MimeType"] = mimeType();
  627|       |
  628|  85.9k|  while (continueTraversing_)
  ------------------
  |  Branch (628:10): [True: 82.7k, False: 3.26k]
  ------------------
  629|  82.7k|    decodeBlock();
  630|       |
  631|  3.26k|  xmpData_["Xmp.video.AspectRatio"] = getAspectRatio(width_, height_);
  632|  3.26k|}
_ZN5Exiv213MatroskaVideo11decodeBlockEv:
  634|  82.7k|void MatroskaVideo::decodeBlock() {
  635|  82.7k|  byte buf[8];
  636|  82.7k|  io_->read(buf, 1);
  637|       |
  638|  82.7k|  if (io_->eof()) {
  ------------------
  |  Branch (638:7): [True: 1.49k, False: 81.2k]
  ------------------
  639|  1.49k|    continueTraversing_ = false;
  640|  1.49k|    return;
  641|  1.49k|  }
  642|       |
  643|  81.2k|  uint32_t block_size = findBlockSize(buf[0]);  // 0-8
  644|  81.2k|  if (block_size > 0)
  ------------------
  |  Branch (644:7): [True: 80.9k, False: 313]
  ------------------
  645|  80.9k|    io_->read(buf + 1, block_size - 1);
  646|       |
  647|  81.2k|  auto tag_id = returnTagValue(buf, block_size);
  648|  81.2k|  const MatroskaTag* tag = Exiv2::find(matroskaTags, tag_id);
  649|       |
  650|  81.2k|  if (!tag) {
  ------------------
  |  Branch (650:7): [True: 999, False: 80.2k]
  ------------------
  651|    999|    continueTraversing_ = false;
  652|    999|    return;
  653|    999|  }
  654|       |
  655|       |  // tag->dump(std::cout);
  656|       |
  657|  80.2k|  if (tag->_id == Cues || tag->_id == Cluster) {
  ------------------
  |  Branch (657:7): [True: 319, False: 79.9k]
  |  Branch (657:27): [True: 1, False: 79.9k]
  ------------------
  658|      7|    continueTraversing_ = false;
  659|      7|    return;
  660|      7|  }
  661|       |
  662|  80.2k|  io_->read(buf, 1);
  663|  80.2k|  block_size = findBlockSize(buf[0]);  // 0-8
  664|       |
  665|  80.2k|  if (block_size > 0)
  ------------------
  |  Branch (665:7): [True: 79.8k, False: 385]
  ------------------
  666|  79.8k|    io_->read(buf + 1, block_size - 1);
  667|  80.2k|  size_t size = returnTagValue(buf, block_size);
  668|       |
  669|  80.2k|  if (tag->isComposite() && !tag->isSkipped())
  ------------------
  |  Branch (669:7): [True: 45.5k, False: 34.6k]
  |  Branch (669:29): [True: 45.5k, False: 0]
  ------------------
  670|  45.5k|    return;
  671|       |
  672|  34.6k|  const size_t bufMaxSize = 200;
  673|       |
  674|  34.6k|#ifndef SUPPRESS_WARNINGS
  675|  34.6k|  if (!tag->isSkipped() && size > bufMaxSize) {
  ------------------
  |  Branch (675:7): [True: 33.0k, False: 1.63k]
  |  Branch (675:28): [True: 114, False: 32.9k]
  ------------------
  676|    114|    EXV_WARNING << "Size " << size << " of Matroska tag 0x" << std::hex << tag->_id << std::dec << " is greater than "
  ------------------
  |  |  138|    114|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 114]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    114|  LogMsg(LogMsg::warn).os()
  ------------------
  677|      0|                << bufMaxSize << ": ignoring it.\n";
  678|    114|  }
  679|  34.6k|#endif
  680|  34.6k|  if (tag->isSkipped() || size > bufMaxSize) {
  ------------------
  |  Branch (680:7): [True: 1.63k, False: 33.0k]
  |  Branch (680:27): [True: 114, False: 32.9k]
  ------------------
  681|  1.36k|    io_->seek(size, BasicIo::cur);
  682|  1.36k|    return;
  683|  1.36k|  }
  684|       |
  685|  33.3k|  DataBuf buf2(bufMaxSize + 1);
  686|  33.3k|  io_->read(buf2.data(), size);
  687|  33.3k|  switch (tag->_type) {
  688|  9.15k|    case InternalField:
  ------------------
  |  Branch (688:5): [True: 9.15k, False: 24.1k]
  ------------------
  689|  9.15k|      decodeInternalTags(tag, buf2.data());
  690|  9.15k|      break;
  691|  1.88k|    case String:
  ------------------
  |  Branch (691:5): [True: 1.88k, False: 31.4k]
  ------------------
  692|  1.88k|    case Utf8:
  ------------------
  |  Branch (692:5): [True: 0, False: 33.3k]
  ------------------
  693|  1.88k|      decodeStringTags(tag, buf2.data());
  694|  1.88k|      break;
  695|  2.27k|    case Integer:
  ------------------
  |  Branch (695:5): [True: 2.27k, False: 31.0k]
  ------------------
  696|  3.58k|    case UInteger:
  ------------------
  |  Branch (696:5): [True: 1.30k, False: 31.9k]
  ------------------
  697|  3.58k|      decodeIntegerTags(tag, buf2.data());
  698|  3.58k|      break;
  699|  15.9k|    case Boolean:
  ------------------
  |  Branch (699:5): [True: 15.9k, False: 17.3k]
  ------------------
  700|  15.9k|      decodeBooleanTags(tag, buf2.data());
  701|  15.9k|      break;
  702|  1.05k|    case Date:
  ------------------
  |  Branch (702:5): [True: 1.05k, False: 32.2k]
  ------------------
  703|  1.05k|      decodeDateTags(tag, buf2.data(), size);
  704|  1.05k|      break;
  705|  1.26k|    case Float:
  ------------------
  |  Branch (705:5): [True: 1.26k, False: 32.0k]
  ------------------
  706|  1.26k|      decodeFloatTags(tag, buf2.data());
  707|  1.26k|      break;
  708|      0|    case Binary:
  ------------------
  |  Branch (708:5): [True: 0, False: 33.3k]
  ------------------
  709|      0|      break;
  710|      0|    case Master:
  ------------------
  |  Branch (710:5): [True: 0, False: 33.3k]
  ------------------
  711|      0|      break;
  712|      0|    default:
  ------------------
  |  Branch (712:5): [True: 0, False: 33.3k]
  ------------------
  713|      0|      break;
  714|  33.3k|  }
  715|  33.3k|}  // MatroskaVideo::decodeBlock
_ZN5Exiv213MatroskaVideo18decodeInternalTagsEPKNS_8Internal11MatroskaTagEPKh:
  717|  9.15k|void MatroskaVideo::decodeInternalTags(const MatroskaTag* tag, const byte* buf) {
  718|  9.15k|  uint64_t key = getULongLong(buf, bigEndian);
  719|  9.15k|  if (!key)
  ------------------
  |  Branch (719:7): [True: 171, False: 8.98k]
  ------------------
  720|    171|    return;
  721|       |
  722|  8.98k|  auto internalMt = [=]() -> const MatroskaTag* {
  723|  8.98k|    switch (tag->_id) {
  724|  8.98k|      case Xmp_video_VideoScanTpye:
  725|  8.98k|        return Exiv2::find(videoScanType, key);
  726|  8.98k|      case Xmp_audio_ChannelType:
  727|  8.98k|        return Exiv2::find(audioChannels, key);
  728|  8.98k|      case Xmp_video_ContentCompressAlgo:
  729|  8.98k|        return Exiv2::find(compressionAlgorithm, key);
  730|  8.98k|      case Xmp_video_ContentEncryptAlgo:
  731|  8.98k|        return Exiv2::find(encryptionAlgorithm, key);
  732|  8.98k|      case Xmp_video_ContentSignAlgo_1:
  733|  8.98k|      case Xmp_video_ContentSignAlgo_2:
  734|  8.98k|        return Exiv2::find(contentSignatureAlgorithm, key);
  735|  8.98k|      case Xmp_video_ContentSignHashAlgo_1:
  736|  8.98k|      case Xmp_video_ContentSignHashAlgo_2:
  737|  8.98k|        return Exiv2::find(contentSignatureHashAlgorithm, key);
  738|  8.98k|      case Xmp_video_ContentEncodingType:
  739|  8.98k|        return Exiv2::find(encodingType, key);
  740|  8.98k|      case Xmp_video_DisplayUnit:
  741|  8.98k|        return Exiv2::find(displayUnit, key);
  742|  8.98k|      case Xmp_video_AspectRatioType:
  743|  8.98k|        return Exiv2::find(aspectRatioType, key);
  744|  8.98k|      case Xmp_video_PhysicalEquivalent:
  745|  8.98k|        return Exiv2::find(chapterPhysicalEquivalent, key);
  746|  8.98k|      case Xmp_video_TranslateCodec:
  747|  8.98k|        return Exiv2::find(chapterTranslateCodec, key);
  748|  8.98k|      case Video_Audio_CodecID:
  749|  8.98k|        return Exiv2::find(trackCodec, key);
  750|  8.98k|      case Video_Audio_CodecName:
  751|  8.98k|        return Exiv2::find(codecInfo, key);
  752|  8.98k|      case CodecDownloadURL:
  753|  8.98k|      case CodecInfoURL:
  754|  8.98k|        return Exiv2::find(codecDownloadUrl, key);
  755|  8.98k|    }
  756|  8.98k|    return nullptr;
  757|  8.98k|  }();
  758|  8.98k|  if (internalMt) {
  ------------------
  |  Branch (758:7): [True: 3.54k, False: 5.44k]
  ------------------
  759|  3.54k|    xmpData_[tag->_label] = internalMt->_label;
  760|  5.44k|  } else {
  761|  5.44k|    xmpData_[tag->_label] = key;
  762|  5.44k|  }
  763|  8.98k|}
_ZN5Exiv213MatroskaVideo16decodeStringTagsEPKNS_8Internal11MatroskaTagEPKh:
  765|  1.88k|void MatroskaVideo::decodeStringTags(const MatroskaTag* tag, const byte* buf) {
  766|  1.88k|  if (tag->_id == TrackNumber) {
  ------------------
  |  Branch (766:7): [True: 247, False: 1.63k]
  ------------------
  767|    247|    track_count_++;
  768|    247|    xmpData_[tag->_label] = track_count_;
  769|  1.63k|  } else {
  770|  1.63k|    xmpData_[tag->_label] = buf;
  771|  1.63k|  }
  772|  1.88k|}
_ZN5Exiv213MatroskaVideo17decodeIntegerTagsEPKNS_8Internal11MatroskaTagEPKh:
  774|  3.58k|void MatroskaVideo::decodeIntegerTags(const MatroskaTag* tag, const byte* buf) {
  775|  3.58k|  uint64_t value = getULongLong(buf, bigEndian);
  776|  3.58k|  if (!value)
  ------------------
  |  Branch (776:7): [True: 479, False: 3.10k]
  ------------------
  777|    479|    return;
  778|       |
  779|  3.10k|  if (tag->_id == Xmp_video_Width_1 || tag->_id == Xmp_video_Width_2)
  ------------------
  |  Branch (779:7): [True: 1.28k, False: 1.81k]
  |  Branch (779:40): [True: 70, False: 1.74k]
  ------------------
  780|  1.35k|    width_ = value;
  781|  3.10k|  if (tag->_id == Xmp_video_Height_1 || tag->_id == Xmp_video_Height_2)
  ------------------
  |  Branch (781:7): [True: 753, False: 2.35k]
  |  Branch (781:41): [True: 472, False: 1.88k]
  ------------------
  782|  1.22k|    height_ = value;
  783|  3.10k|  xmpData_[tag->_label] = value;
  784|  3.10k|}
_ZN5Exiv213MatroskaVideo17decodeBooleanTagsEPKNS_8Internal11MatroskaTagEPKh:
  786|  15.9k|void MatroskaVideo::decodeBooleanTags(const MatroskaTag* tag, const byte* buf) {
  787|  15.9k|  const MatroskaTag* internalMt = nullptr;
  788|  15.9k|  uint64_t key = getULongLong(buf, bigEndian);
  789|  15.9k|  if (!key)
  ------------------
  |  Branch (789:7): [True: 470, False: 15.5k]
  ------------------
  790|    470|    return;
  791|       |
  792|  15.5k|  switch (tag->_id) {
  793|  3.79k|    case TrackType:  // this tags is used internally only to deduce the type of track (video or audio)
  ------------------
  |  Branch (793:5): [True: 3.79k, False: 11.7k]
  ------------------
  794|  3.79k|      if (auto f = Exiv2::find(matroskaTrackType, key)) {
  ------------------
  |  Branch (794:16): [True: 783, False: 3.01k]
  ------------------
  795|    783|        stream_ = f->_id;
  796|    783|      }
  797|  3.79k|      break;
  798|    893|    case TrackUsed:
  ------------------
  |  Branch (798:5): [True: 893, False: 14.6k]
  ------------------
  799|    893|      internalMt = Exiv2::find(trackEnable, key);
  800|    893|      break;
  801|  6.89k|    case TrackDefault:
  ------------------
  |  Branch (801:5): [True: 6.89k, False: 8.60k]
  ------------------
  802|  6.89k|      internalMt = Exiv2::find(defaultOn, key);
  803|  6.89k|      break;
  804|    958|    case TrackForced:
  ------------------
  |  Branch (804:5): [True: 958, False: 14.5k]
  ------------------
  805|    958|      internalMt = Exiv2::find(trackForced, key);
  806|    958|      break;
  807|  1.36k|    case TrackLacing:
  ------------------
  |  Branch (807:5): [True: 1.36k, False: 14.1k]
  ------------------
  808|  1.36k|      internalMt = Exiv2::find(trackLacing, key);
  809|  1.36k|      break;
  810|  1.31k|    case CodecDecodeAll:
  ------------------
  |  Branch (810:5): [True: 1.31k, False: 14.1k]
  ------------------
  811|  1.31k|      internalMt = Exiv2::find(codecDecodeAll, key);
  812|  1.31k|      break;
  813|    216|    case CodecSettings:
  ------------------
  |  Branch (813:5): [True: 216, False: 15.2k]
  ------------------
  814|    216|      internalMt = Exiv2::find(codecSettings, key);
  815|    216|      break;
  816|     66|    case Xmp_video_TagDefault:
  ------------------
  |  Branch (816:5): [True: 66, False: 15.4k]
  ------------------
  817|     66|      internalMt = tag;
  818|     66|      break;
  819|      0|    default:
  ------------------
  |  Branch (819:5): [True: 0, False: 15.5k]
  ------------------
  820|      0|      break;
  821|  15.5k|  }
  822|       |
  823|  15.5k|  if (internalMt) {
  ------------------
  |  Branch (823:7): [True: 2.43k, False: 13.0k]
  ------------------
  824|  2.43k|    xmpData_[internalMt->_label] = "Yes";
  825|  2.43k|  }
  826|  15.5k|}
_ZN5Exiv213MatroskaVideo14decodeDateTagsEPKNS_8Internal11MatroskaTagEPKhm:
  828|  1.05k|void MatroskaVideo::decodeDateTags(const MatroskaTag* tag, const byte* buf, size_t size) {
  829|  1.05k|  int64_t duration_in_ms = 0;
  830|  1.05k|  uint64_t value;
  831|  1.05k|  switch (tag->_id) {
  832|    287|    case Xmp_video_Duration:
  ------------------
  |  Branch (832:5): [True: 287, False: 771]
  ------------------
  833|    287|      if (size <= 4) {
  ------------------
  |  Branch (833:11): [True: 87, False: 200]
  ------------------
  834|     87|        duration_in_ms = std::llround(getFloat(buf, bigEndian) * time_code_scale_ * 1000.0);
  835|    200|      } else {
  836|    200|        duration_in_ms = std::llround(getDouble(buf, bigEndian) * time_code_scale_ * 1000);
  837|    200|      }
  838|    287|      xmpData_[tag->_label] = duration_in_ms;
  839|    287|      break;
  840|    348|    case Xmp_video_DateUTC:
  ------------------
  |  Branch (840:5): [True: 348, False: 710]
  ------------------
  841|    348|      value = getULongLong(buf, bigEndian);
  842|    348|      if (!value)
  ------------------
  |  Branch (842:11): [True: 207, False: 141]
  ------------------
  843|    207|        return;
  844|    141|      duration_in_ms = value / 1000000000;
  845|    141|      xmpData_[tag->_label] = duration_in_ms;
  846|    141|      break;
  847|       |
  848|    423|    case TimecodeScale:
  ------------------
  |  Branch (848:5): [True: 423, False: 635]
  ------------------
  849|    423|      value = getULongLong(buf, bigEndian);
  850|    423|      if (!value)
  ------------------
  |  Branch (850:11): [True: 323, False: 100]
  ------------------
  851|    323|        return;
  852|    100|      time_code_scale_ = static_cast<double>(value) / static_cast<double>(1000000000);
  853|    100|      xmpData_[tag->_label] = time_code_scale_;
  854|    100|      break;
  855|      0|    default:
  ------------------
  |  Branch (855:5): [True: 0, False: 1.05k]
  ------------------
  856|      0|      break;
  857|  1.05k|  }
  858|  1.05k|}
_ZN5Exiv213MatroskaVideo15decodeFloatTagsEPKNS_8Internal11MatroskaTagEPKh:
  860|  1.26k|void MatroskaVideo::decodeFloatTags(const MatroskaTag* tag, const byte* buf) {
  861|  1.26k|  xmpData_[tag->_label] = getFloat(buf, bigEndian);
  862|       |
  863|  1.26k|  switch (tag->_id) {
  864|    276|    case Xmp_audio_SampleRate:
  ------------------
  |  Branch (864:5): [True: 276, False: 987]
  ------------------
  865|    344|    case Xmp_audio_OutputSampleRate:
  ------------------
  |  Branch (865:5): [True: 68, False: 1.19k]
  ------------------
  866|    344|      xmpData_[tag->_label] = getFloat(buf, bigEndian);
  867|    344|      break;
  868|      0|    case VideoFrameRate_DefaultDuration:
  ------------------
  |  Branch (868:5): [True: 0, False: 1.26k]
  ------------------
  869|    919|    case Xmp_video_FrameRate: {
  ------------------
  |  Branch (869:5): [True: 919, False: 344]
  ------------------
  870|    919|      uint64_t key = getULongLong(buf, bigEndian);
  871|    919|      if (!key)
  ------------------
  |  Branch (871:11): [True: 373, False: 546]
  ------------------
  872|    373|        return;
  873|    546|      if (auto internalMt = Exiv2::find(streamRate, key)) {
  ------------------
  |  Branch (873:16): [True: 349, False: 197]
  ------------------
  874|    349|        double frame_rate = 0;
  875|    349|        switch (stream_) {
  876|     67|          case 1:  // video
  ------------------
  |  Branch (876:11): [True: 67, False: 282]
  ------------------
  877|     67|            frame_rate = 1000000000.0 / static_cast<double>(key);
  878|     67|            break;
  879|    196|          case 2:  // audio
  ------------------
  |  Branch (879:11): [True: 196, False: 153]
  ------------------
  880|    196|            frame_rate = static_cast<double>(key) / 1000;
  881|    196|            break;
  882|     86|          default:
  ------------------
  |  Branch (882:11): [True: 86, False: 263]
  ------------------
  883|     86|            break;
  884|    349|        }
  885|    349|        if (std::isgreater(frame_rate, 0.0))
  ------------------
  |  Branch (885:13): [True: 263, False: 86]
  ------------------
  886|    263|          xmpData_[internalMt->_label] = frame_rate;
  887|    349|      } else
  888|    197|        xmpData_[tag->_label] = "Variable Bit Rate";
  889|    546|    } break;
  890|    546|    default:
  ------------------
  |  Branch (890:5): [True: 0, False: 1.26k]
  ------------------
  891|      0|      xmpData_[tag->_label] = getFloat(buf, bigEndian);
  892|      0|      break;
  893|  1.26k|  }
  894|  1.26k|}
_ZN5Exiv213MatroskaVideo13findBlockSizeEh:
  896|   161k|uint32_t MatroskaVideo::findBlockSize(byte b) {
  897|   161k|  if (b & 128)
  ------------------
  |  Branch (897:7): [True: 138k, False: 23.0k]
  ------------------
  898|   138k|    return 1;
  899|  23.0k|  if (b & 64)
  ------------------
  |  Branch (899:7): [True: 12.2k, False: 10.7k]
  ------------------
  900|  12.2k|    return 2;
  901|  10.7k|  if (b & 32)
  ------------------
  |  Branch (901:7): [True: 1.57k, False: 9.19k]
  ------------------
  902|  1.57k|    return 3;
  903|  9.19k|  if (b & 16)
  ------------------
  |  Branch (903:7): [True: 5.14k, False: 4.05k]
  ------------------
  904|  5.14k|    return 4;
  905|  4.05k|  if (b & 8)
  ------------------
  |  Branch (905:7): [True: 434, False: 3.62k]
  ------------------
  906|    434|    return 5;
  907|  3.62k|  if (b & 4)
  ------------------
  |  Branch (907:7): [True: 815, False: 2.80k]
  ------------------
  908|    815|    return 6;
  909|  2.80k|  if (b & 2)
  ------------------
  |  Branch (909:7): [True: 860, False: 1.94k]
  ------------------
  910|    860|    return 7;
  911|  1.94k|  if (b & 1)
  ------------------
  |  Branch (911:7): [True: 1.56k, False: 385]
  ------------------
  912|  1.56k|    return 8;
  913|    385|  return 0;
  914|  1.94k|}
_ZN5Exiv214newMkvInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  916|  3.26k|Image::UniquePtr newMkvInstance(BasicIo::UniquePtr io, bool /*create*/) {
  917|  3.26k|  auto image = std::make_unique<MatroskaVideo>(std::move(io));
  918|  3.26k|  if (!image->good()) {
  ------------------
  |  Branch (918:7): [True: 0, False: 3.26k]
  ------------------
  919|      0|    return nullptr;
  920|      0|  }
  921|  3.26k|  return image;
  922|  3.26k|}
_ZN5Exiv29isMkvTypeERNS_7BasicIoEb:
  924|  13.9k|bool isMkvType(BasicIo& iIo, bool advance) {
  925|  13.9k|  bool result = true;
  926|  13.9k|  byte tmpBuf[4];
  927|  13.9k|  iIo.read(tmpBuf, 4);
  928|       |
  929|  13.9k|  if (iIo.error() || iIo.eof())
  ------------------
  |  Branch (929:7): [True: 0, False: 13.9k]
  |  Branch (929:22): [True: 320, False: 13.6k]
  ------------------
  930|    320|    return false;
  931|       |
  932|  13.6k|  if (0x1a != tmpBuf[0] || 0x45 != tmpBuf[1] || 0xdf != tmpBuf[2] || 0xa3 != tmpBuf[3]) {
  ------------------
  |  Branch (932:7): [True: 3.78k, False: 9.83k]
  |  Branch (932:28): [True: 17, False: 9.81k]
  |  Branch (932:49): [True: 15, False: 9.80k]
  |  Branch (932:70): [True: 18, False: 9.78k]
  ------------------
  933|  3.83k|    result = false;
  934|  3.83k|  }
  935|       |
  936|  13.6k|  if (!advance || !result)
  ------------------
  |  Branch (936:7): [True: 13.6k, False: 0]
  |  Branch (936:19): [True: 0, False: 0]
  ------------------
  937|  13.6k|    iIo.seek(0, BasicIo::beg);
  938|  13.6k|  return result;
  939|  13.9k|}
matroskavideo.cpp:_ZN5Exiv28InternalL14returnTagValueEPKhm:
  582|   161k|[[nodiscard]] static size_t returnTagValue(const byte* buf, size_t size) {
  583|   161k|  enforce(size > 0 && size <= 8, Exiv2::ErrorCode::kerCorruptedMetadata);
  ------------------
  |  Branch (583:11): [True: 160k, False: 385]
  |  Branch (583:23): [True: 160k, False: 0]
  ------------------
  584|       |
  585|   161k|  size_t b0 = buf[0] & (0xff >> size);
  586|   161k|  size_t tag = b0 << ((size - 1) * 8);
  587|   213k|  for (size_t i = 1; i < size; ++i) {
  ------------------
  |  Branch (587:22): [True: 52.7k, False: 161k]
  ------------------
  588|  52.7k|    tag |= static_cast<size_t>(buf[i]) << ((size - i - 1) * 8);
  589|  52.7k|  }
  590|       |
  591|   161k|  return tag;
  592|   161k|}
matroskavideo.cpp:_ZZN5Exiv213MatroskaVideo18decodeInternalTagsEPKNS_8Internal11MatroskaTagEPKhENK3$_0clEv:
  722|  8.98k|  auto internalMt = [=]() -> const MatroskaTag* {
  723|  8.98k|    switch (tag->_id) {
  ------------------
  |  Branch (723:13): [True: 8.98k, False: 0]
  ------------------
  724|  1.29k|      case Xmp_video_VideoScanTpye:
  ------------------
  |  Branch (724:7): [True: 1.29k, False: 7.69k]
  ------------------
  725|  1.29k|        return Exiv2::find(videoScanType, key);
  726|  1.23k|      case Xmp_audio_ChannelType:
  ------------------
  |  Branch (726:7): [True: 1.23k, False: 7.74k]
  ------------------
  727|  1.23k|        return Exiv2::find(audioChannels, key);
  728|    351|      case Xmp_video_ContentCompressAlgo:
  ------------------
  |  Branch (728:7): [True: 351, False: 8.63k]
  ------------------
  729|    351|        return Exiv2::find(compressionAlgorithm, key);
  730|  1.10k|      case Xmp_video_ContentEncryptAlgo:
  ------------------
  |  Branch (730:7): [True: 1.10k, False: 7.88k]
  ------------------
  731|  1.10k|        return Exiv2::find(encryptionAlgorithm, key);
  732|    857|      case Xmp_video_ContentSignAlgo_1:
  ------------------
  |  Branch (732:7): [True: 857, False: 8.12k]
  ------------------
  733|  1.06k|      case Xmp_video_ContentSignAlgo_2:
  ------------------
  |  Branch (733:7): [True: 211, False: 8.77k]
  ------------------
  734|  1.06k|        return Exiv2::find(contentSignatureAlgorithm, key);
  735|    787|      case Xmp_video_ContentSignHashAlgo_1:
  ------------------
  |  Branch (735:7): [True: 787, False: 8.19k]
  ------------------
  736|  1.01k|      case Xmp_video_ContentSignHashAlgo_2:
  ------------------
  |  Branch (736:7): [True: 226, False: 8.75k]
  ------------------
  737|  1.01k|        return Exiv2::find(contentSignatureHashAlgorithm, key);
  738|    399|      case Xmp_video_ContentEncodingType:
  ------------------
  |  Branch (738:7): [True: 399, False: 8.58k]
  ------------------
  739|    399|        return Exiv2::find(encodingType, key);
  740|  1.10k|      case Xmp_video_DisplayUnit:
  ------------------
  |  Branch (740:7): [True: 1.10k, False: 7.88k]
  ------------------
  741|  1.10k|        return Exiv2::find(displayUnit, key);
  742|    467|      case Xmp_video_AspectRatioType:
  ------------------
  |  Branch (742:7): [True: 467, False: 8.51k]
  ------------------
  743|    467|        return Exiv2::find(aspectRatioType, key);
  744|    401|      case Xmp_video_PhysicalEquivalent:
  ------------------
  |  Branch (744:7): [True: 401, False: 8.58k]
  ------------------
  745|    401|        return Exiv2::find(chapterPhysicalEquivalent, key);
  746|    285|      case Xmp_video_TranslateCodec:
  ------------------
  |  Branch (746:7): [True: 285, False: 8.70k]
  ------------------
  747|    285|        return Exiv2::find(chapterTranslateCodec, key);
  748|      0|      case Video_Audio_CodecID:
  ------------------
  |  Branch (748:7): [True: 0, False: 8.98k]
  ------------------
  749|      0|        return Exiv2::find(trackCodec, key);
  750|    138|      case Video_Audio_CodecName:
  ------------------
  |  Branch (750:7): [True: 138, False: 8.84k]
  ------------------
  751|    138|        return Exiv2::find(codecInfo, key);
  752|      1|      case CodecDownloadURL:
  ------------------
  |  Branch (752:7): [True: 1, False: 8.98k]
  ------------------
  753|    128|      case CodecInfoURL:
  ------------------
  |  Branch (753:7): [True: 127, False: 8.85k]
  ------------------
  754|    128|        return Exiv2::find(codecDownloadUrl, key);
  755|  8.98k|    }
  756|      0|    return nullptr;
  757|  8.98k|  }();

_ZN5Exiv23KeyD2Ev:
    9|  5.76M|Key::~Key() = default;
_ZN5Exiv29MetadatumD2Ev:
   15|  2.86M|Metadatum::~Metadatum() = default;
_ZNK5Exiv29Metadatum8toUint32Em:
   23|   106k|uint32_t Metadatum::toUint32(size_t n) const {
   24|   106k|  return static_cast<uint32_t>(toInt64(n));
   25|   106k|}

_ZN5Exiv28Internal16MinoltaMakerNote7tagListEv:
   25|   100k|  static constexpr auto tagList() {
   26|   100k|    return tagInfo_;
   27|   100k|  }
_ZN5Exiv28Internal16MinoltaMakerNote11tagListCs5DEv:
   37|    398|  static constexpr auto tagListCs5D() {
   38|    398|    return tagInfoCs5D_;
   39|    398|  }
_ZN5Exiv28Internal16MinoltaMakerNote11tagListCs7DEv:
   33|    248|  static constexpr auto tagListCs7D() {
   34|    248|    return tagInfoCs7D_;
   35|    248|  }
_ZN5Exiv28Internal16MinoltaMakerNote12tagListCsStdEv:
   29|  7.87k|  static constexpr auto tagListCsStd() {
   30|  7.87k|    return tagInfoCsStd_;
   31|  7.87k|  }

_ZN5Exiv28MrwImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   24|    252|    Image(ImageType::mrw, mdExif | mdIptc | mdXmp, std::move(io)) {
   25|    252|}
_ZNK5Exiv28MrwImage8mimeTypeEv:
   27|      6|std::string MrwImage::mimeType() const {
   28|      6|  return "image/x-minolta-mrw";
   29|      6|}
_ZNK5Exiv28MrwImage10pixelWidthEv:
   31|     10|uint32_t MrwImage::pixelWidth() const {
   32|     10|  auto imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth"));
   33|     10|  if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
  ------------------
  |  Branch (33:7): [True: 0, False: 10]
  |  Branch (33:7): [True: 0, False: 10]
  |  Branch (33:40): [True: 0, False: 0]
  ------------------
   34|      0|    return imageWidth->toUint32();
   35|      0|  }
   36|     10|  return 0;
   37|     10|}
_ZNK5Exiv28MrwImage11pixelHeightEv:
   39|     10|uint32_t MrwImage::pixelHeight() const {
   40|     10|  auto imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageLength"));
   41|     10|  if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
  ------------------
  |  Branch (41:7): [True: 0, False: 10]
  |  Branch (41:7): [True: 0, False: 10]
  |  Branch (41:41): [True: 0, False: 0]
  ------------------
   42|      0|    return imageHeight->toUint32();
   43|      0|  }
   44|     10|  return 0;
   45|     10|}
_ZN5Exiv28MrwImage12readMetadataEv:
   62|    252|void MrwImage::readMetadata() {
   63|       |#ifdef EXIV2_DEBUG_MESSAGES
   64|       |  std::cerr << "Reading MRW file " << io_->path() << "\n";
   65|       |#endif
   66|    252|  if (io_->open() != 0) {
  ------------------
  |  Branch (66:7): [True: 0, False: 252]
  ------------------
   67|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   68|      0|  }
   69|    252|  IoCloser closer(*io_);
   70|       |  // Ensure that this is the correct image type
   71|    252|  if (!isMrwType(*io_, false)) {
  ------------------
  |  Branch (71:7): [True: 0, False: 252]
  ------------------
   72|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (72:9): [True: 0, False: 0]
  |  Branch (72:25): [True: 0, False: 0]
  ------------------
   73|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   74|      0|    throw Error(ErrorCode::kerNotAnImage, "MRW");
   75|      0|  }
   76|    252|  clearMetadata();
   77|       |
   78|       |  // Find the TTW block and read it into a buffer
   79|    252|  uint32_t const len = 8;
   80|    252|  byte tmp[len];
   81|    252|  io_->read(tmp, len);
   82|    252|  uint32_t pos = len;
   83|    252|  uint32_t const end = getULong(tmp + 4, bigEndian);
   84|       |
   85|    252|  pos += len;
   86|    252|  Internal::enforce(pos <= end, ErrorCode::kerFailedToReadImageData);
   87|    252|  io_->read(tmp, len);
   88|    252|  if (io_->error() || io_->eof())
  ------------------
  |  Branch (88:7): [True: 12, False: 240]
  |  Branch (88:23): [True: 0, False: 240]
  ------------------
   89|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
   90|       |
   91|    869|  while (memcmp(tmp + 1, "TTW", 3) != 0) {
  ------------------
  |  Branch (91:10): [True: 617, False: 252]
  ------------------
   92|    617|    uint32_t const siz = getULong(tmp + 4, bigEndian);
   93|    617|    Internal::enforce(siz <= end - pos, ErrorCode::kerFailedToReadImageData);
   94|    617|    pos += siz;
   95|    617|    io_->seek(siz, BasicIo::cur);
   96|    617|    Internal::enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (96:23): [True: 590, False: 27]
  |  Branch (96:40): [True: 518, False: 72]
  ------------------
   97|       |
   98|    617|    Internal::enforce(len <= end - pos, ErrorCode::kerFailedToReadImageData);
   99|    617|    pos += len;
  100|    617|    io_->read(tmp, len);
  101|    617|    Internal::enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (101:23): [True: 506, False: 111]
  |  Branch (101:40): [True: 447, False: 59]
  ------------------
  102|    617|  }
  103|       |
  104|    252|  const uint32_t siz = getULong(tmp + 4, bigEndian);
  105|       |  // First do an approximate bounds check of siz, so that we don't
  106|       |  // get DOS-ed by a 4GB allocation on the next line. If siz is
  107|       |  // greater than io_->size() then it is definitely invalid. But the
  108|       |  // exact bounds checking is done by the call to io_->read, which
  109|       |  // will fail if there are fewer than siz bytes left to read.
  110|    252|  Internal::enforce(siz <= io_->size(), ErrorCode::kerFailedToReadImageData);
  111|    252|  DataBuf buf(siz);
  112|    252|  io_->read(buf.data(), buf.size());
  113|    252|  Internal::enforce(!io_->error() && !io_->eof(), ErrorCode::kerFailedToReadImageData);
  ------------------
  |  Branch (113:21): [True: 36, False: 216]
  |  Branch (113:38): [True: 27, False: 9]
  ------------------
  114|       |
  115|    252|  ByteOrder bo = TiffParser::decode(exifData_, iptcData_, xmpData_, buf.c_data(), buf.size());
  116|    252|  setByteOrder(bo);
  117|    252|}  // MrwImage::readMetadata
_ZN5Exiv214newMrwInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  126|    252|Image::UniquePtr newMrwInstance(BasicIo::UniquePtr io, bool create) {
  127|    252|  auto image = std::make_unique<MrwImage>(std::move(io), create);
  128|    252|  if (!image->good()) {
  ------------------
  |  Branch (128:7): [True: 0, False: 252]
  ------------------
  129|      0|    return nullptr;
  130|      0|  }
  131|    252|  return image;
  132|    252|}
_ZN5Exiv29isMrwTypeERNS_7BasicIoEb:
  134|  31.6k|bool isMrwType(BasicIo& iIo, bool advance) {
  135|  31.6k|  const int32_t len = 4;
  136|  31.6k|  const std::array<byte, len> MrwId{0x0, 0x4d, 0x52, 0x4d};
  137|  31.6k|  std::array<byte, len> buf;
  138|  31.6k|  iIo.read(buf.data(), len);
  139|  31.6k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (139:7): [True: 0, False: 31.6k]
  |  Branch (139:22): [True: 154, False: 31.4k]
  ------------------
  140|    154|    return false;
  141|    154|  }
  142|  31.4k|  bool rc = buf == MrwId;
  143|  31.4k|  if (!advance || !rc) {
  ------------------
  |  Branch (143:7): [True: 31.4k, False: 0]
  |  Branch (143:19): [True: 0, False: 0]
  ------------------
  144|  31.4k|    iIo.seek(-len, BasicIo::cur);
  145|  31.4k|  }
  146|  31.4k|  return rc;
  147|  31.6k|}

_ZN5Exiv28Internal15Nikon1MakerNote7tagListEv:
   38|    194|  static constexpr auto tagList() {
   39|    194|    return tagInfo_;
   40|    194|  }
_ZN5Exiv28Internal15Nikon2MakerNote7tagListEv:
   71|    836|  static constexpr auto tagList() {
   72|    836|    return tagInfo_;
   73|    836|  }
_ZN5Exiv28Internal15Nikon3MakerNote7tagListEv:
   91|  8.28k|  static constexpr auto tagList() {
   92|  8.28k|    return tagInfo_;
   93|  8.28k|  }
_ZN5Exiv28Internal15Nikon3MakerNote9tagListVrEv:
   95|    309|  static constexpr auto tagListVr() {
   96|    309|    return tagInfoVr_;
   97|    309|  }
_ZN5Exiv28Internal15Nikon3MakerNote9tagListPcEv:
   99|    222|  static constexpr auto tagListPc() {
  100|    222|    return tagInfoPc_;
  101|    222|  }
_ZN5Exiv28Internal15Nikon3MakerNote9tagListWtEv:
  103|    391|  static constexpr auto tagListWt() {
  104|    391|    return tagInfoWt_;
  105|    391|  }
_ZN5Exiv28Internal15Nikon3MakerNote9tagListIiEv:
  107|    310|  static constexpr auto tagListIi() {
  108|    310|    return tagInfoIi_;
  109|    310|  }
_ZN5Exiv28Internal15Nikon3MakerNote9tagListAfEv:
  111|    410|  static constexpr auto tagListAf() {
  112|    410|    return tagInfoAf_;
  113|    410|  }
_ZN5Exiv28Internal15Nikon3MakerNote11tagListAf21Ev:
  115|    340|  static constexpr auto tagListAf21() {
  116|    340|    return tagInfoAf21_;
  117|    340|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListAFTEv:
  123|     10|  static constexpr auto tagListAFT() {
  124|     10|    return tagInfoAFT_;
  125|     10|  }
_ZN5Exiv28Internal15Nikon3MakerNote9tagListFiEv:
  127|     11|  static constexpr auto tagListFi() {
  128|     11|    return tagInfoFi_;
  129|     11|  }
_ZN5Exiv28Internal15Nikon3MakerNote9tagListMeEv:
  131|     11|  static constexpr auto tagListMe() {
  132|     11|    return tagInfoMe_;
  133|     11|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListFl1Ev:
  135|     22|  static constexpr auto tagListFl1() {
  136|     22|    return tagInfoFl1_;
  137|     22|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListFl2Ev:
  139|     20|  static constexpr auto tagListFl2() {
  140|     20|    return tagInfoFl2_;
  141|     20|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListFl3Ev:
  143|     25|  static constexpr auto tagListFl3() {
  144|     25|    return tagInfoFl3_;
  145|     25|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListFl6Ev:
  147|     43|  static constexpr auto tagListFl6() {
  148|     43|    return tagInfoFl6_;
  149|     43|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListFl7Ev:
  151|     76|  static constexpr auto tagListFl7() {
  152|     76|    return tagInfoFl7_;
  153|     76|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListSi1Ev:
  155|     13|  static constexpr auto tagListSi1() {
  156|     13|    return tagInfoSi1_;
  157|     13|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListSi2Ev:
  159|     24|  static constexpr auto tagListSi2() {
  160|     24|    return tagInfoSi2_;
  161|     24|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListSi5Ev:
  171|    192|  static constexpr auto tagListSi5() {
  172|    192|    return tagInfoSi5_;
  173|    192|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListCb1Ev:
  175|      9|  static constexpr auto tagListCb1() {
  176|      9|    return tagInfoCb1_;
  177|      9|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListCb2Ev:
  179|      7|  static constexpr auto tagListCb2() {
  180|      7|    return tagInfoCb2_;
  181|      7|  }
_ZN5Exiv28Internal15Nikon3MakerNote11tagListCb2aEv:
  183|     19|  static constexpr auto tagListCb2a() {
  184|     19|    return tagInfoCb2a_;
  185|     19|  }
_ZN5Exiv28Internal15Nikon3MakerNote11tagListCb2bEv:
  187|     27|  static constexpr auto tagListCb2b() {
  188|     27|    return tagInfoCb2b_;
  189|     27|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListCb3Ev:
  191|     13|  static constexpr auto tagListCb3() {
  192|     13|    return tagInfoCb3_;
  193|     13|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListCb4Ev:
  195|     10|  static constexpr auto tagListCb4() {
  196|     10|    return tagInfoCb4_;
  197|     10|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListLd1Ev:
  199|    352|  static constexpr auto tagListLd1() {
  200|    352|    return tagInfoLd1_;
  201|    352|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListLd2Ev:
  203|    356|  static constexpr auto tagListLd2() {
  204|    356|    return tagInfoLd2_;
  205|    356|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListLd3Ev:
  207|    393|  static constexpr auto tagListLd3() {
  208|    393|    return tagInfoLd3_;
  209|    393|  }
_ZN5Exiv28Internal15Nikon3MakerNote10tagListLd4Ev:
  211|    329|  static constexpr auto tagListLd4() {
  212|    329|    return tagInfoLd4_;
  213|    329|  }

_ZN5Exiv28Internal16OlympusMakerNote7tagListEv:
   33|  68.4k|  static constexpr auto tagList() {
   34|  68.4k|    return tagInfo_;
   35|  68.4k|  }
_ZN5Exiv28Internal16OlympusMakerNote9tagListCsEv:
   37|  65.5k|  static constexpr auto tagListCs() {
   38|  65.5k|    return tagInfoCs_;
   39|  65.5k|  }

_ZN5Exiv28OrfImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   25|     70|    TiffImage(/*ImageType::orf, mdExif | mdIptc | mdXmp,*/ std::move(io), create) {
   26|     70|  setTypeSupported(ImageType::orf, mdExif | mdIptc | mdXmp);
   27|     70|}  // OrfImage::OrfImage
_ZNK5Exiv28OrfImage8mimeTypeEv:
   29|     26|std::string OrfImage::mimeType() const {
   30|     26|  return "image/x-olympus-orf";
   31|     26|}
_ZNK5Exiv28OrfImage10pixelWidthEv:
   33|     45|uint32_t OrfImage::pixelWidth() const {
   34|     45|  auto imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageWidth"));
   35|     45|  if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
  ------------------
  |  Branch (35:7): [True: 25, False: 20]
  |  Branch (35:7): [True: 12, False: 33]
  |  Branch (35:40): [True: 12, False: 13]
  ------------------
   36|     12|    return imageWidth->toUint32();
   37|     12|  }
   38|     33|  return 0;
   39|     45|}
_ZNK5Exiv28OrfImage11pixelHeightEv:
   41|     45|uint32_t OrfImage::pixelHeight() const {
   42|     45|  auto imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Image.ImageLength"));
   43|     45|  if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
  ------------------
  |  Branch (43:7): [True: 21, False: 24]
  |  Branch (43:7): [True: 10, False: 35]
  |  Branch (43:41): [True: 10, False: 11]
  ------------------
   44|     10|    return imageHeight->toUint32();
   45|     10|  }
   46|     35|  return 0;
   47|     45|}
_ZN5Exiv28OrfImage12readMetadataEv:
   70|     70|void OrfImage::readMetadata() {
   71|       |#ifdef EXIV2_DEBUG_MESSAGES
   72|       |  std::cerr << "Reading ORF file " << io_->path() << "\n";
   73|       |#endif
   74|     70|  if (io_->open() != 0) {
  ------------------
  |  Branch (74:7): [True: 0, False: 70]
  ------------------
   75|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   76|      0|  }
   77|     70|  IoCloser closer(*io_);
   78|       |  // Ensure that this is the correct image type
   79|     70|  if (!isOrfType(*io_, false)) {
  ------------------
  |  Branch (79:7): [True: 0, False: 70]
  ------------------
   80|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (80:9): [True: 0, False: 0]
  |  Branch (80:25): [True: 0, False: 0]
  ------------------
   81|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   82|      0|    throw Error(ErrorCode::kerNotAnImage, "ORF");
   83|      0|  }
   84|     70|  clearMetadata();
   85|     70|  ByteOrder bo = OrfParser::decode(exifData_, iptcData_, xmpData_, io_->mmap(), io_->size());
   86|     70|  setByteOrder(bo);
   87|     70|}
_ZN5Exiv29OrfParser6decodeERNS_8ExifDataERNS_8IptcDataERNS_7XmpDataEPKhm:
  113|     70|ByteOrder OrfParser::decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size) {
  114|     70|  OrfHeader orfHeader;
  115|     70|  return TiffParserWorker::decode(exifData, iptcData, xmpData, pData, size, Tag::root, TiffMapping::findDecoder,
  116|     70|                                  &orfHeader);
  117|     70|}
_ZN5Exiv214newOrfInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  139|     70|Image::UniquePtr newOrfInstance(BasicIo::UniquePtr io, bool create) {
  140|     70|  auto image = std::make_unique<OrfImage>(std::move(io), create);
  141|     70|  if (!image->good()) {
  ------------------
  |  Branch (141:7): [True: 0, False: 70]
  ------------------
  142|      0|    return nullptr;
  143|      0|  }
  144|     70|  return image;
  145|     70|}
_ZN5Exiv29isOrfTypeERNS_7BasicIoEb:
  147|  22.1k|bool isOrfType(BasicIo& iIo, bool advance) {
  148|  22.1k|  const int32_t len = 8;
  149|  22.1k|  byte buf[len];
  150|  22.1k|  iIo.read(buf, len);
  151|  22.1k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (151:7): [True: 0, False: 22.1k]
  |  Branch (151:22): [True: 233, False: 21.9k]
  ------------------
  152|    233|    return false;
  153|    233|  }
  154|  21.9k|  OrfHeader orfHeader;
  155|  21.9k|  bool rc = orfHeader.read(buf, len);
  156|  21.9k|  if (!advance || !rc) {
  ------------------
  |  Branch (156:7): [True: 21.9k, False: 0]
  |  Branch (156:19): [True: 0, False: 0]
  ------------------
  157|  21.9k|    iIo.seek(-len, BasicIo::cur);
  158|  21.9k|  }
  159|  21.9k|  return rc;
  160|  22.1k|}

_ZN5Exiv28Internal9OrfHeaderC2ENS_9ByteOrderE:
    6|  22.0k|OrfHeader::OrfHeader(ByteOrder byteOrder) : TiffHeaderBase(0x4f52, 8, byteOrder, 0x00000008) {
    7|  22.0k|}
_ZN5Exiv28Internal9OrfHeader4readEPKhm:
    9|  22.0k|bool OrfHeader::read(const byte* pData, size_t size) {
   10|  22.0k|  if (size < 8)
  ------------------
  |  Branch (10:7): [True: 0, False: 22.0k]
  ------------------
   11|      0|    return false;
   12|       |
   13|  22.0k|  if (pData[0] == 'I' && pData[0] == pData[1]) {
  ------------------
  |  Branch (13:7): [True: 87, False: 21.9k]
  |  Branch (13:26): [True: 70, False: 17]
  ------------------
   14|     70|    setByteOrder(littleEndian);
   15|  21.9k|  } else if (pData[0] == 'M' && pData[0] == pData[1]) {
  ------------------
  |  Branch (15:14): [True: 303, False: 21.6k]
  |  Branch (15:33): [True: 275, False: 28]
  ------------------
   16|    275|    setByteOrder(bigEndian);
   17|  21.6k|  } else {
   18|  21.6k|    return false;
   19|  21.6k|  }
   20|       |
   21|    345|  uint16_t sig = getUShort(pData + 2, byteOrder());
   22|    345|  if (tag() != sig && 0x5352 != sig)
  ------------------
  |  Branch (22:7): [True: 297, False: 48]
  |  Branch (22:23): [True: 65, False: 232]
  ------------------
   23|     65|    return false;  // #658: Added 0x5352 "SR" for SP-560UZ
   24|    280|  sig_ = sig;
   25|    280|  setOffset(getULong(pData + 4, byteOrder()));
   26|    280|  return true;
   27|    345|}

_ZN5Exiv28Internal18PanasonicMakerNote10tagListRawEv:
   29|    824|  static constexpr auto tagListRaw() {
   30|    824|    return tagInfoRaw_;
   31|    824|  }
_ZN5Exiv28Internal18PanasonicMakerNote7tagListEv:
   25|    196|  static constexpr auto tagList() {
   26|    196|    return tagInfo_;
   27|    196|  }

_ZN5Exiv28Internal15PentaxMakerNote7tagListEv:
   23|  67.4k|  static constexpr auto tagList() {
   24|  67.4k|    return tagInfo_;
   25|  67.4k|  }

_ZN5Exiv28PgfImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   53|    405|    Image(ImageType::pgf, mdExif | mdIptc | mdXmp | mdComment, std::move(io)), bSwap_(isBigEndianPlatform()) {
   54|    405|  if (create && io_->open() == 0) {
  ------------------
  |  Branch (54:7): [True: 0, False: 405]
  |  Branch (54:17): [True: 0, False: 0]
  ------------------
   55|       |#ifdef EXIV2_DEBUG_MESSAGES
   56|       |    std::cerr << "Exiv2::PgfImage:: Creating PGF image to memory\n";
   57|       |#endif
   58|      0|    IoCloser closer(*io_);
   59|      0|    if (io_->write(pgfBlank, sizeof(pgfBlank)) != sizeof(pgfBlank)) {
  ------------------
  |  Branch (59:9): [True: 0, False: 0]
  ------------------
   60|       |#ifdef EXIV2_DEBUG_MESSAGES
   61|       |      std::cerr << "Exiv2::PgfImage:: Failed to create PGF image on memory\n";
   62|       |#endif
   63|      0|    }
   64|      0|  }
   65|    405|}  // PgfImage::PgfImage
_ZN5Exiv28PgfImage12readMetadataEv:
   67|    405|void PgfImage::readMetadata() {
   68|       |#ifdef EXIV2_DEBUG_MESSAGES
   69|       |  std::cerr << "Exiv2::PgfImage::readMetadata: Reading PGF file " << io_->path() << "\n";
   70|       |#endif
   71|    405|  if (io_->open() != 0) {
  ------------------
  |  Branch (71:7): [True: 0, False: 405]
  ------------------
   72|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   73|      0|  }
   74|    405|  IoCloser closer(*io_);
   75|       |  // Ensure that this is the correct image type
   76|    405|  if (!isPgfType(*io_, true)) {
  ------------------
  |  Branch (76:7): [True: 0, False: 405]
  ------------------
   77|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (77:9): [True: 0, False: 0]
  |  Branch (77:25): [True: 0, False: 0]
  ------------------
   78|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   79|      0|    throw Error(ErrorCode::kerNotAnImage, "PGF");
   80|      0|  }
   81|    405|  clearMetadata();
   82|       |
   83|    405|  readPgfMagicNumber(*io_);
   84|       |
   85|    405|  size_t headerSize = readPgfHeaderSize(*io_);
   86|    405|  readPgfHeaderStructure(*io_, pixelWidth_, pixelHeight_);
   87|       |
   88|       |  // And now, the most interesting, the user data byte array where metadata are stored as small image.
   89|       |
   90|    405|  Internal::enforce(headerSize <= std::numeric_limits<size_t>::max() - 8, ErrorCode::kerCorruptedMetadata);
   91|    405|  size_t size = headerSize + 8 - io_->tell();
   92|       |
   93|       |#ifdef EXIV2_DEBUG_MESSAGES
   94|       |  std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n";
   95|       |#endif
   96|       |
   97|    405|  if (size > io_->size())
  ------------------
  |  Branch (97:7): [True: 96, False: 309]
  ------------------
   98|     96|    throw Error(ErrorCode::kerInputDataReadFailed);
   99|    309|  if (size == 0)
  ------------------
  |  Branch (99:7): [True: 11, False: 298]
  ------------------
  100|     11|    return;
  101|       |
  102|    298|  DataBuf imgData(size);
  103|    298|  const size_t bufRead = io_->read(imgData.data(), imgData.size());
  104|    298|  if (io_->error())
  ------------------
  |  Branch (104:7): [True: 0, False: 298]
  ------------------
  105|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  106|    298|  if (bufRead != imgData.size())
  ------------------
  |  Branch (106:7): [True: 21, False: 277]
  ------------------
  107|     21|    throw Error(ErrorCode::kerInputDataReadFailed);
  108|       |
  109|    277|  auto image = Exiv2::ImageFactory::open(imgData.c_data(), imgData.size());
  110|    277|  image->readMetadata();
  111|    277|  exifData() = image->exifData();
  112|    277|  iptcData() = image->iptcData();
  113|    277|  xmpData() = image->xmpData();
  114|    277|}
_ZN5Exiv28PgfImage18readPgfMagicNumberERNS_7BasicIoE:
  218|    405|byte PgfImage::readPgfMagicNumber(BasicIo& iIo) {
  219|    405|  auto b = static_cast<byte>(iIo.getb());
  220|    405|  if (iIo.error())
  ------------------
  |  Branch (220:7): [True: 0, False: 405]
  ------------------
  221|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  222|       |
  223|    405|  if (b < 0x36)  // 0x36 = '6'.
  ------------------
  |  Branch (223:7): [True: 165, False: 240]
  ------------------
  224|    165|  {
  225|       |    // Not right Magick version.
  226|       |#ifdef EXIV2_DEBUG_MESSAGES
  227|       |    std::cout << "Exiv2::PgfImage::readMetadata: wrong Magick number\n";
  228|       |#endif
  229|    165|  }
  230|       |
  231|    405|  return b;
  232|    405|}  // PgfImage::readPgfMagicNumber
_ZNK5Exiv28PgfImage17readPgfHeaderSizeERNS_7BasicIoE:
  234|    405|size_t PgfImage::readPgfHeaderSize(BasicIo& iIo) const {
  235|    405|  DataBuf buffer(4);
  236|    405|  const size_t bufRead = iIo.read(buffer.data(), buffer.size());
  237|    405|  if (iIo.error())
  ------------------
  |  Branch (237:7): [True: 0, False: 405]
  ------------------
  238|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  239|    405|  if (bufRead != buffer.size())
  ------------------
  |  Branch (239:7): [True: 0, False: 405]
  ------------------
  240|      0|    throw Error(ErrorCode::kerInputDataReadFailed);
  241|       |
  242|    405|  auto headerSize = static_cast<size_t>(byteSwap_(buffer, 0, bSwap_));
  243|    405|  if (headerSize == 0)
  ------------------
  |  Branch (243:7): [True: 10, False: 395]
  ------------------
  244|     10|    throw Error(ErrorCode::kerNoImageInInputData);
  245|       |
  246|       |#ifdef EXIV2_DEBUG_MESSAGES
  247|       |  std::cout << "Exiv2::PgfImage: PGF header size : " << headerSize << " bytes\n";
  248|       |#endif
  249|       |
  250|    395|  return headerSize;
  251|    405|}
_ZNK5Exiv28PgfImage22readPgfHeaderStructureERNS_7BasicIoERjS3_:
  253|    395|DataBuf PgfImage::readPgfHeaderStructure(BasicIo& iIo, uint32_t& width, uint32_t& height) const {
  254|    395|  DataBuf header(16);
  255|    395|  size_t bufRead = iIo.read(header.data(), header.size());
  256|    395|  if (iIo.error())
  ------------------
  |  Branch (256:7): [True: 0, False: 395]
  ------------------
  257|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  258|    395|  if (bufRead != header.size())
  ------------------
  |  Branch (258:7): [True: 0, False: 395]
  ------------------
  259|      0|    throw Error(ErrorCode::kerInputDataReadFailed);
  260|       |
  261|    395|  DataBuf work(header.data(), 8);  // don't disturb the binary data - doWriteMetadata reuses it
  262|    395|  width = byteSwap_(work, 0, bSwap_);
  263|    395|  height = byteSwap_(work, 4, bSwap_);
  264|       |
  265|       |  /* NOTE: properties not yet used
  266|       |  byte nLevels  = buffer.pData_[8];
  267|       |  byte quality  = buffer.pData_[9];
  268|       |  byte bpp      = buffer.pData_[10];
  269|       |  byte channels = buffer.pData_[11];
  270|       |  */
  271|       |
  272|    395|  if (header.read_uint8(12) == 2)  // Indexed color image. We pass color table (256 * 3 bytes).
  ------------------
  |  Branch (272:7): [True: 14, False: 381]
  ------------------
  273|     14|  {
  274|     14|    header.alloc(16 + (256 * 3));
  275|       |
  276|     14|    bufRead = iIo.read(header.data(16), 256 * 3);
  277|     14|    if (iIo.error())
  ------------------
  |  Branch (277:9): [True: 0, False: 14]
  ------------------
  278|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  279|     14|    if (bufRead != 256 * 3)
  ------------------
  |  Branch (279:9): [True: 13, False: 1]
  ------------------
  280|     13|      throw Error(ErrorCode::kerInputDataReadFailed);
  281|     14|  }
  282|       |
  283|    382|  return header;
  284|    395|}  // PgfImage::readPgfHeaderStructure
_ZN5Exiv214newPgfInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  288|    405|Image::UniquePtr newPgfInstance(BasicIo::UniquePtr io, bool create) {
  289|    405|  auto image = std::make_unique<PgfImage>(std::move(io), create);
  290|    405|  if (!image->good()) {
  ------------------
  |  Branch (290:7): [True: 0, False: 405]
  ------------------
  291|      0|    return nullptr;
  292|      0|  }
  293|    405|  return image;
  294|    405|}
_ZN5Exiv29isPgfTypeERNS_7BasicIoEb:
  296|  21.3k|bool isPgfType(BasicIo& iIo, bool advance) {
  297|  21.3k|  const int32_t len = 3;
  298|  21.3k|  std::array<byte, len> buf;
  299|  21.3k|  iIo.read(buf.data(), len);
  300|  21.3k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (300:7): [True: 0, False: 21.3k]
  |  Branch (300:22): [True: 0, False: 21.3k]
  ------------------
  301|      0|    return false;
  302|      0|  }
  303|  21.3k|  bool rc = buf == pgfSignature;
  304|  21.3k|  if (!advance || !rc) {
  ------------------
  |  Branch (304:7): [True: 20.9k, False: 405]
  |  Branch (304:19): [True: 0, False: 405]
  ------------------
  305|  20.9k|    iIo.seek(-len, BasicIo::cur);
  306|  20.9k|  }
  307|       |
  308|  21.3k|  return rc;
  309|  21.3k|}
pgfimage.cpp:_ZN5Exiv2L9byteSwap_ERNS_7DataBufEmb:
   39|  1.19k|static uint32_t byteSwap_(Exiv2::DataBuf& buf, size_t offset, bool bSwap) {
   40|  1.19k|  uint32_t v = 0;
   41|  1.19k|  auto p = reinterpret_cast<byte*>(&v);
   42|  1.19k|  int i;
   43|  5.97k|  for (i = 0; i < 4; i++)
  ------------------
  |  Branch (43:15): [True: 4.78k, False: 1.19k]
  ------------------
   44|  4.78k|    p[i] = buf.read_uint8(offset + i);
   45|  1.19k|  uint32_t result = Image::byteSwap(v, bSwap);
   46|  1.19k|  p = reinterpret_cast<byte*>(&result);
   47|  5.97k|  for (i = 0; i < 4; i++)
  ------------------
  |  Branch (47:15): [True: 4.78k, False: 1.19k]
  ------------------
   48|  4.78k|    buf.write_uint8(offset + i, p[i]);
   49|  1.19k|  return result;
   50|  1.19k|}

_ZN5Exiv29Photoshop5isIrbEPKh:
   17|  14.2k|bool Photoshop::isIrb(const byte* pPsData) {
   18|  14.2k|  if (pPsData == nullptr) {
  ------------------
  |  Branch (18:7): [True: 0, False: 14.2k]
  ------------------
   19|      0|    return false;
   20|      0|  }
   21|  14.2k|  return std::any_of(irbId_.begin(), irbId_.end(), [pPsData](auto id) { return memcmp(pPsData, id, 4) == 0; });
   22|  14.2k|}
_ZN5Exiv29Photoshop5validEPKhm:
   24|  7.56k|bool Photoshop::valid(const byte* pPsData, size_t sizePsData) {
   25|  7.56k|  const byte* record = nullptr;
   26|  7.56k|  uint32_t sizeIptc = 0;
   27|  7.56k|  uint32_t sizeHdr = 0;
   28|  7.56k|  const byte* pCur = pPsData;
   29|  7.56k|  const byte* pEnd = pPsData + sizePsData;
   30|  7.56k|  int ret = 0;
   31|  10.3k|  while (pCur < pEnd && 0 == (ret = Photoshop::locateIptcIrb(pCur, (pEnd - pCur), &record, sizeHdr, sizeIptc))) {
  ------------------
  |  Branch (31:10): [True: 10.3k, False: 15]
  |  Branch (31:25): [True: 2.81k, False: 7.54k]
  ------------------
   32|  2.81k|    pCur = record + sizeHdr + sizeIptc + (sizeIptc & 1);
   33|  2.81k|  }
   34|  7.56k|  return ret >= 0;
   35|  7.56k|}
_ZN5Exiv29Photoshop9locateIrbEPKhmtPS2_RjS4_:
   41|  10.8k|                         uint32_t& sizeData) {
   42|  10.8k|  if (sizePsData < 12) {
  ------------------
  |  Branch (42:7): [True: 326, False: 10.5k]
  ------------------
   43|    326|    return 3;
   44|    326|  }
   45|       |
   46|       |  // Used for error checking
   47|  10.5k|  size_t position = 0;
   48|       |#ifdef EXIV2_DEBUG_MESSAGES
   49|       |  std::cerr << "Photoshop::locateIrb: ";
   50|       |#endif
   51|       |  // Data should follow Photoshop format, if not exit
   52|  12.7k|  while (position <= (sizePsData - 12) && isIrb(pPsData + position)) {
  ------------------
  |  Branch (52:10): [True: 12.5k, False: 239]
  |  Branch (52:43): [True: 8.87k, False: 3.66k]
  ------------------
   53|  8.87k|    const byte* hrd = pPsData + position;
   54|  8.87k|    position += 4;
   55|  8.87k|    uint16_t type = getUShort(pPsData + position, bigEndian);
   56|  8.87k|    position += 2;
   57|       |#ifdef EXIV2_DEBUG_MESSAGES
   58|       |    std::cerr << "0x" << std::hex << type << std::dec << " ";
   59|       |#endif
   60|       |    // Pascal string is padded to have an even size (including size byte)
   61|  8.87k|    byte psSize = pPsData[position] + 1;
   62|  8.87k|    psSize += (psSize & 1);
   63|  8.87k|    position += psSize;
   64|  8.87k|    if (position + 4 > sizePsData) {
  ------------------
  |  Branch (64:9): [True: 294, False: 8.58k]
  ------------------
   65|       |#ifdef EXIV2_DEBUG_MESSAGES
   66|       |      std::cerr << "Warning: "
   67|       |                << "Invalid or extended Photoshop IRB\n";
   68|       |#endif
   69|    294|      return -2;
   70|    294|    }
   71|  8.58k|    uint32_t dataSize = getULong(pPsData + position, bigEndian);
   72|  8.58k|    position += 4;
   73|  8.58k|    if (dataSize > (sizePsData - position)) {
  ------------------
  |  Branch (73:9): [True: 3.41k, False: 5.17k]
  ------------------
   74|       |#ifdef EXIV2_DEBUG_MESSAGES
   75|       |      std::cerr << "Warning: "
   76|       |                << "Invalid Photoshop IRB data size " << dataSize << " or extended Photoshop IRB\n";
   77|       |#endif
   78|  3.41k|      return -2;
   79|  3.41k|    }
   80|       |#ifdef EXIV2_DEBUG_MESSAGES
   81|       |    if ((dataSize & 1) && position + dataSize == sizePsData) {
   82|       |      std::cerr << "Warning: "
   83|       |                << "Photoshop IRB data is not padded to even size\n";
   84|       |    }
   85|       |#endif
   86|  5.17k|    if (type == psTag) {
  ------------------
  |  Branch (86:9): [True: 2.94k, False: 2.22k]
  ------------------
   87|       |#ifdef EXIV2_DEBUG_MESSAGES
   88|       |      std::cerr << "ok\n";
   89|       |#endif
   90|  2.94k|      sizeData = dataSize;
   91|  2.94k|      sizeHdr = psSize + 10;
   92|  2.94k|      *record = hrd;
   93|  2.94k|      return 0;
   94|  2.94k|    }
   95|       |    // Data size is also padded to be even
   96|  2.22k|    position += dataSize + (dataSize & 1);
   97|  2.22k|  }
   98|       |#ifdef EXIV2_DEBUG_MESSAGES
   99|       |  std::cerr << "pPsData doesn't start with '8BIM'\n";
  100|       |#endif
  101|  3.90k|  if (position < sizePsData) {
  ------------------
  |  Branch (101:7): [True: 3.88k, False: 21]
  ------------------
  102|       |#ifdef EXIV2_DEBUG_MESSAGES
  103|       |    std::cerr << "Warning: "
  104|       |              << "Invalid or extended Photoshop IRB\n";
  105|       |#endif
  106|  3.88k|    return -2;
  107|  3.88k|  }
  108|     21|  return 3;
  109|  3.90k|}
_ZN5Exiv29Photoshop13locateIptcIrbEPKhmPS2_RjS4_:
  112|  10.7k|                             uint32_t& sizeData) {
  113|  10.7k|  return locateIrb(pPsData, sizePsData, iptc_, record, sizeHdr, sizeData);
  114|  10.7k|}
_ZN5Exiv29Photoshop16locatePreviewIrbEPKhmPS2_RjS4_:
  117|    114|                                uint32_t& sizeData) {
  118|    114|  return locateIrb(pPsData, sizePsData, preview_, record, sizeHdr, sizeData);
  119|    114|}
photoshop.cpp:_ZZN5Exiv29Photoshop5isIrbEPKhENK3$_0clIPKcEEDaT_:
   21|  35.4k|  return std::any_of(irbId_.begin(), irbId_.end(), [pPsData](auto id) { return memcmp(pPsData, id, 4) == 0; });

_ZN5Exiv28Internal8PngChunk15decodeIHDRChunkERKNS_7DataBufEPjS5_:
   45|     67|void PngChunk::decodeIHDRChunk(const DataBuf& data, uint32_t* outWidth, uint32_t* outHeight) {
   46|       |  // Extract image width and height from IHDR chunk.
   47|     67|  *outWidth = data.read_uint32(0, bigEndian);
   48|     67|  *outHeight = data.read_uint32(4, bigEndian);
   49|     67|}
_ZN5Exiv28Internal8PngChunk14decodeTXTChunkEPNS_5ImageERKNS_7DataBufENS1_12TxtChunkTypeE:
   51|  8.11k|void PngChunk::decodeTXTChunk(Image* pImage, const DataBuf& data, TxtChunkType type) {
   52|  8.11k|  DataBuf key = keyTXTChunk(data);
   53|  8.11k|  DataBuf arr = parseTXTChunk(data, key.size(), type);
   54|       |
   55|       |#ifdef EXIV2_DEBUG_MESSAGES
   56|       |  std::cout << "Exiv2::PngChunk::decodeTXTChunk: TXT chunk data: " << std::string(arr.c_str(), arr.size()) << '\n';
   57|       |#endif
   58|  8.11k|  if (!key.empty())
  ------------------
  |  Branch (58:7): [True: 7.79k, False: 323]
  ------------------
   59|  7.79k|    parseChunkContent(pImage, key.c_data(), key.size(), arr);
   60|  8.11k|}
_ZN5Exiv28Internal8PngChunk11keyTXTChunkERKNS_7DataBufEb:
   71|  8.11k|DataBuf PngChunk::keyTXTChunk(const DataBuf& data, bool stripHeader) {
   72|       |  // From a tEXt, zTXt, or iTXt chunk, we get the keyword which is null terminated.
   73|  8.11k|  const size_t offset = stripHeader ? 8ul : 0ul;
  ------------------
  |  Branch (73:25): [True: 0, False: 8.11k]
  ------------------
   74|  8.11k|  if (data.size() <= offset)
  ------------------
  |  Branch (74:7): [True: 12, False: 8.10k]
  ------------------
   75|     12|    throw Error(ErrorCode::kerFailedToReadImageData);
   76|       |
   77|  8.10k|  auto it = std::find(data.begin() + offset, data.end(), 0);
   78|  8.10k|  if (it == data.end())
  ------------------
  |  Branch (78:7): [True: 12, False: 8.09k]
  ------------------
   79|     12|    throw Error(ErrorCode::kerFailedToReadImageData);
   80|       |
   81|  8.09k|  return {data.c_data() + offset, std::distance(data.begin(), it) - offset};
   82|  8.10k|}
_ZN5Exiv28Internal8PngChunk13parseTXTChunkERKNS_7DataBufEmNS1_12TxtChunkTypeE:
   84|  8.09k|DataBuf PngChunk::parseTXTChunk(const DataBuf& data, size_t keysize, TxtChunkType type) {
   85|  8.09k|  DataBuf arr;
   86|       |
   87|  8.09k|  if (type == zTXt_Chunk) {
  ------------------
  |  Branch (87:7): [True: 89, False: 8.00k]
  ------------------
   88|     89|    enforce(data.size() >= Safe::add(keysize, nullSeparators), ErrorCode::kerCorruptedMetadata);
   89|       |
   90|       |    // Extract a deflate compressed Latin-1 text chunk
   91|       |
   92|       |    // we get the compression method after the key
   93|     89|    if (*data.c_data(keysize + 1) != 0x00) {
  ------------------
  |  Branch (93:9): [True: 11, False: 78]
  ------------------
   94|       |      // then it isn't zlib compressed and we are sunk
   95|       |#ifdef EXIV2_DEBUG_MESSAGES
   96|       |      std::cerr << "Exiv2::PngChunk::parseTXTChunk: Non-standard zTXt compression method.\n";
   97|       |#endif
   98|     11|      throw Error(ErrorCode::kerFailedToReadImageData);
   99|     11|    }
  100|       |
  101|       |    // compressed string after the compression technique spec
  102|     78|    size_t compressedTextSize = data.size() - keysize - nullSeparators;
  103|     78|    if (compressedTextSize) {
  ------------------
  |  Branch (103:9): [True: 31, False: 47]
  ------------------
  104|     31|      const byte* compressedText = data.c_data(keysize + nullSeparators);
  105|     31|      enforce(compressedTextSize < data.size(), ErrorCode::kerCorruptedMetadata);
  106|       |
  107|     31|      zlibUncompress(compressedText, static_cast<uint32_t>(compressedTextSize), arr);
  108|     31|    }
  109|  8.00k|  } else if (type == tEXt_Chunk) {
  ------------------
  |  Branch (109:14): [True: 2.02k, False: 5.97k]
  ------------------
  110|  2.02k|    enforce(data.size() >= Safe::add(keysize, std::size_t{1}), ErrorCode::kerCorruptedMetadata);
  111|       |    // Extract a non-compressed Latin-1 text chunk
  112|       |
  113|       |    // the text comes after the key, but isn't null terminated
  114|  2.02k|    size_t textsize = data.size() - keysize - 1;
  115|  2.02k|    if (textsize) {
  ------------------
  |  Branch (115:9): [True: 1.90k, False: 124]
  ------------------
  116|  1.90k|      const byte* text = data.c_data(keysize + 1);
  117|       |
  118|  1.90k|      arr = DataBuf(text, textsize);
  119|  1.90k|    }
  120|  5.97k|  } else if (type == iTXt_Chunk) {
  ------------------
  |  Branch (120:14): [True: 5.97k, False: 0]
  ------------------
  121|  5.97k|    enforce(data.size() > Safe::add(keysize, std::size_t{3}), ErrorCode::kerCorruptedMetadata);
  122|  5.97k|    const size_t nullCount = std::count(data.c_data(keysize + 3), data.c_data(data.size() - 1), '\0');
  123|  5.97k|    enforce(nullCount >= nullSeparators, ErrorCode::kerCorruptedMetadata);
  124|       |
  125|       |    // Extract a deflate compressed or uncompressed UTF-8 text chunk
  126|       |
  127|       |    // we get the compression flag after the key
  128|  5.97k|    const byte compressionFlag = data.read_uint8(keysize + 1);
  129|       |    // we get the compression method after the compression flag
  130|  5.97k|    const byte compressionMethod = data.read_uint8(keysize + 2);
  131|       |
  132|  5.97k|    enforce(compressionFlag == 0x00 || compressionFlag == 0x01, ErrorCode::kerCorruptedMetadata);
  ------------------
  |  Branch (132:13): [True: 5.91k, False: 59]
  |  Branch (132:40): [True: 40, False: 19]
  ------------------
  133|  5.97k|    if (compressionFlag == 0x01)
  ------------------
  |  Branch (133:9): [True: 40, False: 5.93k]
  ------------------
  134|     40|      enforce(compressionMethod == 0x00, ErrorCode::kerFailedToReadImageData);
  135|       |
  136|       |    // language description string after the compression technique spec
  137|  5.97k|    const size_t languageTextMaxSize = data.size() - keysize - 3;
  138|  5.97k|    std::string languageText = string_from_unterminated(data.c_str(keysize + 3), languageTextMaxSize);
  139|  5.97k|    const size_t languageTextSize = languageText.size();
  140|       |
  141|  5.97k|    enforce(data.size() >= Safe::add(Safe::add(keysize, std::size_t{4}), languageTextSize),
  142|  5.97k|            ErrorCode::kerCorruptedMetadata);
  143|       |    // translated keyword string after the language description
  144|  5.97k|    std::string translatedKeyText = string_from_unterminated(data.c_str(keysize + 3 + languageTextSize + 1),
  145|  5.97k|                                                             data.size() - (keysize + 3 + languageTextSize + 1));
  146|  5.97k|    const size_t translatedKeyTextSize = translatedKeyText.size();
  147|       |
  148|  5.97k|    enforce(Safe::add(keysize + 3 + languageTextSize + 1, Safe::add(translatedKeyTextSize, size_t{1})) <= data.size(),
  149|  5.97k|            ErrorCode::kerCorruptedMetadata);
  150|       |
  151|  5.97k|    const auto textsize =
  152|  5.97k|        static_cast<long>(data.size() - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1));
  153|  5.97k|    if (textsize) {
  ------------------
  |  Branch (153:9): [True: 5.90k, False: 78]
  ------------------
  154|  5.90k|      const byte* text = data.c_data(keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1);
  155|       |
  156|  5.90k|      if (compressionFlag == 0x00) {
  ------------------
  |  Branch (156:11): [True: 5.87k, False: 30]
  ------------------
  157|       |        // then it's an uncompressed iTXt chunk
  158|       |#ifdef EXIV2_DEBUG_MESSAGES
  159|       |        std::cout << "Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field\n";
  160|       |#endif
  161|  5.87k|        arr = DataBuf(text, textsize);
  162|  5.87k|      } else {
  163|       |        // then it's a zlib compressed iTXt chunk
  164|       |#ifdef EXIV2_DEBUG_MESSAGES
  165|       |        std::cout << "Exiv2::PngChunk::parseTXTChunk: We found a zlib compressed iTXt field\n";
  166|       |#endif
  167|       |
  168|       |        // the compressed text comes after the translated keyword, but isn't null terminated
  169|     30|        zlibUncompress(text, textsize, arr);
  170|     30|      }
  171|  5.90k|    }
  172|  5.97k|  } else {
  173|       |#ifdef DEBUG
  174|       |    std::cerr << "Exiv2::PngChunk::parseTXTChunk: We found a field, not expected though\n";
  175|       |#endif
  176|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  177|      0|  }
  178|       |
  179|  8.08k|  return arr;
  180|  8.09k|}
_ZN5Exiv28Internal8PngChunk17parseChunkContentEPNS_5ImageEPKhmRKNS_7DataBufE:
  182|  7.79k|void PngChunk::parseChunkContent(Image* pImage, const byte* key, size_t keySize, const DataBuf& arr) {
  183|       |  // We look if an ImageMagick EXIF raw profile exist.
  184|       |
  185|  7.79k|  if (keySize >= 21 &&
  ------------------
  |  Branch (185:7): [True: 4.00k, False: 3.78k]
  ------------------
  186|  4.00k|      (memcmp("Raw profile type exif", key, 21) == 0 || memcmp("Raw profile type APP1", key, 21) == 0) &&
  ------------------
  |  Branch (186:8): [True: 110, False: 3.89k]
  |  Branch (186:57): [True: 2.37k, False: 1.52k]
  ------------------
  187|  2.48k|      pImage->exifData().empty()) {
  ------------------
  |  Branch (187:7): [True: 2.41k, False: 70]
  ------------------
  188|  2.41k|    DataBuf exifData = readRawProfile(arr, false);
  189|  2.41k|    size_t length = exifData.size();
  190|       |
  191|  2.41k|    if (length >= 4) {  // length should have at least the size of TIFF header
  ------------------
  |  Branch (191:9): [True: 52, False: 2.36k]
  ------------------
  192|       |      // Find the position of TIFF header in bytes array.
  193|       |      // Forgives the absence of the expected Exif\0 APP1 prefix.
  194|     52|      const std::array<byte, 4> tiffHeaderLE{0x49, 0x49, 0x2A, 0x00};  // "II*\0"
  195|     52|      const std::array<byte, 4> tiffHeaderBE{0x4D, 0x4D, 0x00, 0x2A};  // "MM\0*"
  196|     52|      size_t pos = std::numeric_limits<size_t>::max();
  197|       |
  198|       |      /// \todo Find substring inside an string
  199|    316|      for (size_t i = 0; i < length - tiffHeaderLE.size(); i++) {
  ------------------
  |  Branch (199:26): [True: 264, False: 52]
  ------------------
  200|    264|        if (0 == exifData.cmpBytes(i, tiffHeaderLE.data(), tiffHeaderLE.size()) ||
  ------------------
  |  Branch (200:13): [True: 0, False: 264]
  ------------------
  201|    264|            0 == exifData.cmpBytes(i, tiffHeaderBE.data(), tiffHeaderBE.size())) {
  ------------------
  |  Branch (201:13): [True: 0, False: 264]
  ------------------
  202|      0|          pos = i;
  203|      0|          break;
  204|      0|        }
  205|    264|      }
  206|       |
  207|       |      // If found it, store only these data at from this place.
  208|       |
  209|     52|      if (pos != std::numeric_limits<size_t>::max()) {
  ------------------
  |  Branch (209:11): [True: 0, False: 52]
  ------------------
  210|       |#ifdef EXIV2_DEBUG_MESSAGES
  211|       |        std::cout << "Exiv2::PngChunk::parseChunkContent: TIFF header found at position " << pos << "\n";
  212|       |#endif
  213|      0|        ByteOrder bo = TiffParser::decode(pImage->exifData(), pImage->iptcData(), pImage->xmpData(),
  214|      0|                                          exifData.c_data(pos), length - pos);
  215|      0|        pImage->setByteOrder(bo);
  216|     52|      } else {
  217|     52|#ifndef SUPPRESS_WARNINGS
  218|     52|        EXV_WARNING << "Failed to decode Exif metadata.\n";
  ------------------
  |  |  138|     52|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 52]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     52|  LogMsg(LogMsg::warn).os()
  ------------------
  219|     52|#endif
  220|     52|        pImage->exifData().clear();
  221|     52|      }
  222|     52|    }
  223|  2.41k|  }
  224|       |
  225|       |  // We look if an ImageMagick IPTC raw profile exist.
  226|       |
  227|  7.79k|  if (keySize >= 21 && memcmp("Raw profile type iptc", key, 21) == 0 && pImage->iptcData().empty()) {
  ------------------
  |  Branch (227:7): [True: 4.00k, False: 3.78k]
  |  Branch (227:24): [True: 306, False: 3.70k]
  |  Branch (227:73): [True: 287, False: 19]
  ------------------
  228|    287|    DataBuf psData = readRawProfile(arr, false);
  229|    287|    if (!psData.empty()) {
  ------------------
  |  Branch (229:9): [True: 57, False: 230]
  ------------------
  230|     57|      Blob iptcBlob;
  231|     57|      const byte* record = nullptr;
  232|     57|      uint32_t sizeIptc = 0;
  233|     57|      uint32_t sizeHdr = 0;
  234|       |
  235|     57|      const byte* pEnd = psData.c_data(psData.size() - 1);
  236|     57|      const byte* pCur = psData.c_data();
  237|     57|      while (pCur < pEnd && 0 == Photoshop::locateIptcIrb(pCur, pEnd - pCur, &record, sizeHdr, sizeIptc)) {
  ------------------
  |  Branch (237:14): [True: 37, False: 20]
  |  Branch (237:29): [True: 0, False: 37]
  ------------------
  238|      0|        if (sizeIptc) {
  ------------------
  |  Branch (238:13): [True: 0, False: 0]
  ------------------
  239|       |#ifdef EXIV2_DEBUG_MESSAGES
  240|       |          std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n";
  241|       |#endif
  242|      0|          append(iptcBlob, record + sizeHdr, sizeIptc);
  243|      0|        }
  244|      0|        pCur = record + sizeHdr + sizeIptc;
  245|      0|        pCur += (sizeIptc & 1);
  246|      0|      }
  247|     57|      if (!iptcBlob.empty() && IptcParser::decode(pImage->iptcData(), iptcBlob.data(), iptcBlob.size())) {
  ------------------
  |  Branch (247:11): [True: 0, False: 57]
  |  Branch (247:32): [True: 0, False: 0]
  ------------------
  248|      0|#ifndef SUPPRESS_WARNINGS
  249|      0|        EXV_WARNING << "Failed to decode IPTC metadata.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  250|      0|#endif
  251|      0|        pImage->clearIptcData();
  252|      0|      }
  253|       |      // If there is no IRB, try to decode the complete chunk data
  254|     57|      if (iptcBlob.empty() && IptcParser::decode(pImage->iptcData(), psData.c_data(), psData.size())) {
  ------------------
  |  Branch (254:11): [True: 57, False: 0]
  |  Branch (254:31): [True: 10, False: 47]
  ------------------
  255|     10|#ifndef SUPPRESS_WARNINGS
  256|     10|        EXV_WARNING << "Failed to decode IPTC metadata.\n";
  ------------------
  |  |  138|     10|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 10]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     10|  LogMsg(LogMsg::warn).os()
  ------------------
  257|     10|#endif
  258|     10|        pImage->clearIptcData();
  259|     10|      }
  260|     57|    }  // if (psData.size() > 0)
  261|    287|  }
  262|       |
  263|       |  // We look if an ImageMagick XMP raw profile exist.
  264|       |
  265|  7.79k|  if (keySize >= 20 && memcmp("Raw profile type xmp", key, 20) == 0 && pImage->xmpData().empty()) {
  ------------------
  |  Branch (265:7): [True: 4.08k, False: 3.71k]
  |  Branch (265:24): [True: 544, False: 3.53k]
  |  Branch (265:72): [True: 544, False: 0]
  ------------------
  266|    544|    DataBuf xmpBuf = readRawProfile(arr, false);
  267|    544|    size_t length = xmpBuf.size();
  268|       |
  269|    544|    if (length > 0) {
  ------------------
  |  Branch (269:9): [True: 136, False: 408]
  ------------------
  270|    136|      std::string& xmpPacket = pImage->xmpPacket();
  271|    136|      xmpPacket.assign(xmpBuf.c_str(), length);
  272|    136|      if (auto idx = xmpPacket.find_first_of('<'); idx != std::string::npos && idx > 0) {
  ------------------
  |  Branch (272:52): [True: 81, False: 55]
  |  Branch (272:80): [True: 30, False: 51]
  ------------------
  273|     30|#ifndef SUPPRESS_WARNINGS
  274|     30|        EXV_WARNING << "Removing " << idx << " characters from the beginning of the XMP packet\n";
  ------------------
  |  |  138|     30|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 30]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     30|  LogMsg(LogMsg::warn).os()
  ------------------
  275|     30|#endif
  276|     30|        xmpPacket = xmpPacket.substr(idx);
  277|     30|      }
  278|    136|      if (XmpParser::decode(pImage->xmpData(), xmpPacket)) {
  ------------------
  |  Branch (278:11): [True: 136, False: 0]
  ------------------
  279|    136|#ifndef SUPPRESS_WARNINGS
  280|    136|        EXV_WARNING << "Failed to decode XMP metadata.\n";
  ------------------
  |  |  138|    136|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 136]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    136|  LogMsg(LogMsg::warn).os()
  ------------------
  281|    136|#endif
  282|    136|      }
  283|    136|    }
  284|    544|  }
  285|       |
  286|       |  // We look if an Adobe XMP string exist.
  287|       |
  288|  7.79k|  if (keySize >= 17 && memcmp("XML:com.adobe.xmp", key, 17) == 0 && pImage->xmpData().empty() && !arr.empty()) {
  ------------------
  |  Branch (288:7): [True: 6.19k, False: 1.60k]
  |  Branch (288:24): [True: 2.47k, False: 3.72k]
  |  Branch (288:69): [True: 2.47k, False: 0]
  |  Branch (288:98): [True: 2.45k, False: 18]
  ------------------
  289|  2.45k|    std::string& xmpPacket = pImage->xmpPacket();
  290|  2.45k|    xmpPacket.assign(arr.c_str(), arr.size());
  291|  2.45k|    if (auto idx = xmpPacket.find_first_of('<'); idx != std::string::npos && idx > 0) {
  ------------------
  |  Branch (291:50): [True: 2.29k, False: 158]
  |  Branch (291:78): [True: 1.05k, False: 1.23k]
  ------------------
  292|  1.05k|#ifndef SUPPRESS_WARNINGS
  293|  1.05k|      EXV_WARNING << "Removing " << idx << " characters "
  ------------------
  |  |  138|  1.05k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 1.05k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  1.05k|  LogMsg(LogMsg::warn).os()
  ------------------
  294|      0|                  << "from the beginning of the XMP packet\n";
  295|  1.05k|#endif
  296|  1.05k|      xmpPacket = xmpPacket.substr(idx);
  297|  1.05k|    }
  298|  2.45k|    if (XmpParser::decode(pImage->xmpData(), xmpPacket)) {
  ------------------
  |  Branch (298:9): [True: 475, False: 1.97k]
  ------------------
  299|    475|#ifndef SUPPRESS_WARNINGS
  300|    475|      EXV_WARNING << "Failed to decode XMP metadata.\n";
  ------------------
  |  |  138|    475|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 475]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    475|  LogMsg(LogMsg::warn).os()
  ------------------
  301|    475|#endif
  302|    475|    }
  303|  2.45k|  }
  304|       |
  305|       |  // We look if a comments string exist. Note than we use only 'Description' keyword which
  306|       |  // is dedicated to store long comments. 'Comment' keyword is ignored.
  307|       |
  308|  7.79k|  if (keySize >= 11 && memcmp("Description", key, 11) == 0 && pImage->comment().empty()) {
  ------------------
  |  Branch (308:7): [True: 6.89k, False: 898]
  |  Branch (308:7): [True: 92, False: 7.70k]
  |  Branch (308:24): [True: 855, False: 6.03k]
  |  Branch (308:63): [True: 92, False: 763]
  ------------------
  309|     92|    pImage->setComment(std::string(arr.c_str(), arr.size()));
  310|     92|  }
  311|       |
  312|  7.79k|}  // PngChunk::parseChunkContent
_ZN5Exiv28Internal8PngChunk14zlibUncompressEPKhjRNS_7DataBufE:
  335|     61|void PngChunk::zlibUncompress(const byte* compressedText, unsigned int compressedTextSize, DataBuf& arr) {
  336|     61|  uLongf uncompressedLen = compressedTextSize * 2;  // just a starting point
  337|     61|  int zlibResult = Z_BUF_ERROR;
  338|     61|  int dos = 0;
  339|       |
  340|     83|  while (zlibResult == Z_BUF_ERROR) {
  ------------------
  |  Branch (340:10): [True: 83, False: 0]
  ------------------
  341|     83|    arr.alloc(uncompressedLen);
  342|     83|    zlibResult = uncompress(arr.data(), &uncompressedLen, compressedText, compressedTextSize);
  343|     83|    if (zlibResult == Z_OK) {
  ------------------
  |  Branch (343:9): [True: 0, False: 83]
  ------------------
  344|      0|      arr.resize(uncompressedLen);
  345|     83|    } else if (zlibResult == Z_BUF_ERROR) {
  ------------------
  |  Branch (345:16): [True: 22, False: 61]
  ------------------
  346|       |      // the uncompressedArray needs to be larger
  347|     22|      uncompressedLen *= 2;
  348|       |      // DoS protection. can't be bigger than 64k
  349|     22|      if (uncompressedLen > 131072) {
  ------------------
  |  Branch (349:11): [True: 0, False: 22]
  ------------------
  350|      0|        if (++dos > 1)
  ------------------
  |  Branch (350:13): [True: 0, False: 0]
  ------------------
  351|      0|          break;
  352|      0|        uncompressedLen = 131072;
  353|      0|      }
  354|     61|    } else {
  355|       |      // something bad happened
  356|     61|      throw Error(ErrorCode::kerFailedToReadImageData);
  357|     61|    }
  358|     83|  }
  359|       |
  360|      0|  if (zlibResult != Z_OK) {
  ------------------
  |  Branch (360:7): [True: 0, False: 0]
  ------------------
  361|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  362|      0|  }
  363|      0|}  // PngChunk::zlibUncompress
_ZN5Exiv28Internal8PngChunk14readRawProfileERKNS_7DataBufEb:
  469|  3.24k|DataBuf PngChunk::readRawProfile(const DataBuf& text, bool iTXt) {
  470|  3.24k|  DataBuf info;
  471|  3.24k|  if (text.size() <= 1) {
  ------------------
  |  Branch (471:7): [True: 10, False: 3.23k]
  ------------------
  472|     10|    return info;
  473|     10|  }
  474|       |
  475|  3.23k|  const unsigned char unhex[103] = {
  476|  3.23k|      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0,
  477|  3.23k|      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0,
  478|  3.23k|      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15,
  479|  3.23k|  };
  480|       |
  481|  3.23k|  if (iTXt) {
  ------------------
  |  Branch (481:7): [True: 0, False: 3.23k]
  ------------------
  482|      0|    info.alloc(text.size());
  483|      0|    std::copy(text.begin(), text.end(), info.begin());
  484|      0|    return info;
  485|      0|  }
  486|       |
  487|  3.23k|  const char* sp = text.c_str(1);                 // current byte (space pointer)
  488|  3.23k|  const char* eot = text.c_str(text.size() - 1);  // end of text
  489|       |
  490|  3.23k|  if (sp >= eot) {
  ------------------
  |  Branch (490:7): [True: 15, False: 3.22k]
  ------------------
  491|     15|    return info;
  492|     15|  }
  493|       |
  494|       |  // Look for newline
  495|  66.9k|  while (*sp != '\n') {
  ------------------
  |  Branch (495:10): [True: 63.8k, False: 3.08k]
  ------------------
  496|  63.8k|    sp++;
  497|  63.8k|    if (sp == eot) {
  ------------------
  |  Branch (497:9): [True: 136, False: 63.6k]
  ------------------
  498|    136|      return info;
  499|    136|    }
  500|  63.8k|  }
  501|  3.08k|  sp++;  // step over '\n'
  502|  3.08k|  if (sp == eot) {
  ------------------
  |  Branch (502:7): [True: 84, False: 3.00k]
  ------------------
  503|     84|    return info;
  504|     84|  }
  505|       |
  506|       |  // Look for length
  507|   108k|  while (*sp == '\0' || *sp == ' ' || *sp == '\n') {
  ------------------
  |  Branch (507:10): [True: 5.59k, False: 102k]
  |  Branch (507:25): [True: 84.6k, False: 18.2k]
  |  Branch (507:39): [True: 15.2k, False: 2.95k]
  ------------------
  508|   105k|    sp++;
  509|   105k|    if (sp == eot) {
  ------------------
  |  Branch (509:9): [True: 47, False: 105k]
  ------------------
  510|     47|      return info;
  511|     47|    }
  512|   105k|  }
  513|       |
  514|       |  // Parse the length.
  515|  2.95k|  size_t length = 0;
  516|  6.16k|  while ('0' <= *sp && *sp <= '9') {
  ------------------
  |  Branch (516:10): [True: 3.72k, False: 2.44k]
  |  Branch (516:24): [True: 3.34k, False: 371]
  ------------------
  517|       |    // Compute the new length using unsigned long, so that we can check for overflow.
  518|  3.34k|    const size_t newlength = (10 * length) + (*sp - '0');
  519|  3.34k|    length = newlength;
  520|  3.34k|    sp++;
  521|  3.34k|    if (sp == eot) {
  ------------------
  |  Branch (521:9): [True: 137, False: 3.21k]
  ------------------
  522|    137|      return info;
  523|    137|    }
  524|  3.34k|  }
  525|  2.81k|  sp++;  // step over '\n'
  526|  2.81k|  if (sp == eot) {
  ------------------
  |  Branch (526:7): [True: 569, False: 2.24k]
  ------------------
  527|    569|    return info;
  528|    569|  }
  529|       |
  530|  2.24k|  enforce(length <= static_cast<size_t>(eot - sp) / 2, Exiv2::ErrorCode::kerCorruptedMetadata);
  531|       |
  532|       |  // Allocate space
  533|  2.24k|  if (length == 0) {
  ------------------
  |  Branch (533:7): [True: 1.28k, False: 967]
  ------------------
  534|       |#ifdef EXIV2_DEBUG_MESSAGES
  535|       |    std::cerr << "Exiv2::PngChunk::readRawProfile: Unable To Copy Raw Profile: invalid profile length\n";
  536|       |#endif
  537|  1.28k|  }
  538|  2.24k|  info.alloc(length);
  539|  2.24k|  if (info.size() != length) {
  ------------------
  |  Branch (539:7): [True: 0, False: 2.24k]
  ------------------
  540|       |#ifdef EXIV2_DEBUG_MESSAGES
  541|       |    std::cerr << "Exiv2::PngChunk::readRawProfile: Unable To Copy Raw Profile: cannot allocate memory\n";
  542|       |#endif
  543|      0|    return info;
  544|      0|  }
  545|       |
  546|  2.24k|  if (info.empty())  // Early return
  ------------------
  |  Branch (546:7): [True: 1.28k, False: 967]
  ------------------
  547|  1.28k|    return info;
  548|       |
  549|       |  // Copy profile, skipping white space and column 1 "=" signs
  550|    967|  unsigned char* dp = info.data();  // decode pointer
  551|    967|  size_t nibbles = length * 2;
  552|       |
  553|  4.23k|  for (size_t i = 0; i < nibbles; i++) {
  ------------------
  |  Branch (553:22): [True: 3.84k, False: 391]
  ------------------
  554|  3.84k|    enforce(sp < eot, Exiv2::ErrorCode::kerCorruptedMetadata);
  555|  11.7k|    while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f') {
  ------------------
  |  Branch (555:12): [True: 3.73k, False: 8.05k]
  |  Branch (555:26): [True: 5.90k, False: 2.15k]
  |  Branch (555:39): [True: 2.57k, False: 3.33k]
  |  Branch (555:53): [True: 2.25k, False: 3.23k]
  ------------------
  556|  8.53k|      if (*sp == '\0') {
  ------------------
  |  Branch (556:11): [True: 576, False: 7.95k]
  ------------------
  557|       |#ifdef EXIV2_DEBUG_MESSAGES
  558|       |        std::cerr << "Exiv2::PngChunk::readRawProfile: Unable To Copy Raw Profile: ran out of data\n";
  559|       |#endif
  560|    576|        return {};
  561|    576|      }
  562|       |
  563|  7.95k|      sp++;
  564|  7.95k|      enforce(sp < eot, Exiv2::ErrorCode::kerCorruptedMetadata);
  565|  7.95k|    }
  566|       |
  567|  3.26k|    if (i % 2 == 0)
  ------------------
  |  Branch (567:9): [True: 1.63k, False: 1.62k]
  ------------------
  568|  1.63k|      *dp = static_cast<unsigned char>(16 * unhex[static_cast<size_t>(*sp++)]);
  569|  1.62k|    else
  570|  1.62k|      (*dp++) += unhex[static_cast<size_t>(*sp++)];
  571|  3.26k|  }
  572|       |
  573|    391|  return info;
  574|       |
  575|    967|}  // PngChunk::readRawProfile

_ZN5Exiv28PngImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   56|  1.16k|    Image(ImageType::png, mdExif | mdIptc | mdXmp | mdComment, std::move(io)) {
   57|  1.16k|  if (create && io_->open() == 0) {
  ------------------
  |  Branch (57:7): [True: 0, False: 1.16k]
  |  Branch (57:17): [True: 0, False: 0]
  ------------------
   58|       |#ifdef EXIV2_DEBUG_MESSAGES
   59|       |    std::cerr << "Exiv2::PngImage:: Creating PNG image to memory\n";
   60|       |#endif
   61|      0|    IoCloser closer(*io_);
   62|      0|    if (io_->write(pngBlank, sizeof(pngBlank)) != sizeof(pngBlank)) {
  ------------------
  |  Branch (62:9): [True: 0, False: 0]
  ------------------
   63|       |#ifdef EXIV2_DEBUG_MESSAGES
   64|       |      std::cerr << "Exiv2::PngImage:: Failed to create PNG image on memory\n";
   65|       |#endif
   66|      0|    }
   67|      0|  }
   68|  1.16k|}
_ZNK5Exiv28PngImage8mimeTypeEv:
   70|      3|std::string PngImage::mimeType() const {
   71|      3|  return "image/png";
   72|      3|}
_ZN5Exiv28PngImage12readMetadataEv:
  392|  1.16k|void PngImage::readMetadata() {
  393|       |#ifdef EXIV2_DEBUG_MESSAGES
  394|       |  std::cerr << "Exiv2::PngImage::readMetadata: Reading PNG file " << io_->path() << '\n';
  395|       |#endif
  396|  1.16k|  if (io_->open() != 0) {
  ------------------
  |  Branch (396:7): [True: 0, False: 1.16k]
  ------------------
  397|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  398|      0|  }
  399|  1.16k|  IoCloser closer(*io_);
  400|  1.16k|  if (!isPngType(*io_, true)) {
  ------------------
  |  Branch (400:7): [True: 0, False: 1.16k]
  ------------------
  401|      0|    throw Error(ErrorCode::kerNotAnImage, "PNG");
  402|      0|  }
  403|  1.16k|  clearMetadata();
  404|       |
  405|  1.16k|  const size_t imgSize = io_->size();
  406|  1.16k|  DataBuf cheaderBuf(8);  // Chunk header: 4 bytes (data size) + 4 bytes (chunk type).
  407|       |
  408|  27.3k|  while (!io_->eof()) {
  ------------------
  |  Branch (408:10): [True: 26.8k, False: 505]
  ------------------
  409|  26.8k|    readChunk(cheaderBuf, *io_);  // Read chunk header.
  410|       |
  411|       |    // Decode chunk data length.
  412|  26.8k|    uint32_t chunkLength = cheaderBuf.read_uint32(0, Exiv2::bigEndian);
  413|  26.8k|    if (chunkLength > imgSize - io_->tell()) {
  ------------------
  |  Branch (413:9): [True: 279, False: 26.6k]
  ------------------
  414|    279|      throw Exiv2::Error(ErrorCode::kerFailedToReadImageData);
  415|    279|    }
  416|       |
  417|  26.6k|    std::string chunkType(cheaderBuf.c_str(4), 4);
  418|       |#ifdef EXIV2_DEBUG_MESSAGES
  419|       |    std::cout << "Exiv2::PngImage::readMetadata: chunk type: " << chunkType << " length: " << chunkLength << '\n';
  420|       |#endif
  421|       |
  422|       |    /// \todo analyse remaining chunks of the standard
  423|       |    // Perform a chunk triage for item that we need.
  424|  26.6k|    if (chunkType == "IEND" || chunkType == "IHDR" || chunkType == "tEXt" || chunkType == "zTXt" ||
  ------------------
  |  Branch (424:9): [True: 147, False: 26.4k]
  |  Branch (424:32): [True: 85, False: 26.3k]
  |  Branch (424:55): [True: 2.03k, False: 24.3k]
  |  Branch (424:78): [True: 91, False: 24.2k]
  ------------------
  425|  24.2k|        chunkType == "eXIf" || chunkType == "iTXt" || chunkType == "iCCP") {
  ------------------
  |  Branch (425:9): [True: 146, False: 24.0k]
  |  Branch (425:32): [True: 5.98k, False: 18.1k]
  |  Branch (425:55): [True: 509, False: 17.6k]
  ------------------
  426|  8.86k|      DataBuf chunkData(chunkLength);
  427|  8.86k|      if (chunkLength > 0) {
  ------------------
  |  Branch (427:11): [True: 8.71k, False: 154]
  ------------------
  428|  8.71k|        readChunk(chunkData, *io_);  // Extract chunk data.
  429|  8.71k|      }
  430|       |
  431|  8.86k|      if (chunkType == "IEND") {
  ------------------
  |  Branch (431:11): [True: 11, False: 8.85k]
  ------------------
  432|     11|        return;  // Last chunk found: we stop parsing.
  433|     11|      }
  434|  8.85k|      if (chunkType == "IHDR" && chunkData.size() >= 8) {
  ------------------
  |  Branch (434:11): [True: 85, False: 8.77k]
  |  Branch (434:34): [True: 67, False: 18]
  ------------------
  435|     67|        PngChunk::decodeIHDRChunk(chunkData, &pixelWidth_, &pixelHeight_);
  436|  8.78k|      } else if (chunkType == "tEXt") {
  ------------------
  |  Branch (436:18): [True: 2.03k, False: 6.75k]
  ------------------
  437|  2.03k|        PngChunk::decodeTXTChunk(this, chunkData, PngChunk::tEXt_Chunk);
  438|  6.75k|      } else if (chunkType == "zTXt") {
  ------------------
  |  Branch (438:18): [True: 91, False: 6.66k]
  ------------------
  439|     91|        PngChunk::decodeTXTChunk(this, chunkData, PngChunk::zTXt_Chunk);
  440|  6.66k|      } else if (chunkType == "iTXt") {
  ------------------
  |  Branch (440:18): [True: 5.98k, False: 673]
  ------------------
  441|  5.98k|        PngChunk::decodeTXTChunk(this, chunkData, PngChunk::iTXt_Chunk);
  442|  5.98k|      } else if (chunkType == "eXIf") {
  ------------------
  |  Branch (442:18): [True: 146, False: 527]
  ------------------
  443|    146|        ByteOrder bo = TiffParser::decode(exifData(), iptcData(), xmpData(), chunkData.c_data(), chunkData.size());
  444|    146|        setByteOrder(bo);
  445|    527|      } else if (chunkType == "iCCP") {
  ------------------
  |  Branch (445:18): [True: 509, False: 18]
  ------------------
  446|       |        // The ICC profile name can vary from 1-79 characters.
  447|    509|        uint32_t iccOffset = 0;
  448|  6.38k|        do {
  449|  6.38k|          enforce(iccOffset < 80 && iccOffset < chunkLength, Exiv2::ErrorCode::kerCorruptedMetadata);
  ------------------
  |  Branch (449:19): [True: 6.37k, False: 11]
  |  Branch (449:37): [True: 6.36k, False: 12]
  ------------------
  450|  6.38k|        } while (chunkData.read_uint8(iccOffset++) != 0x00);
  ------------------
  |  Branch (450:18): [True: 5.88k, False: 509]
  ------------------
  451|       |
  452|    509|        profileName_ = std::string(chunkData.c_str(), iccOffset - 1);
  453|    509|        ++iccOffset;  // +1 = 'compressed' flag
  454|    509|        enforce(iccOffset <= chunkLength, Exiv2::ErrorCode::kerCorruptedMetadata);
  455|       |
  456|    509|        zlibToDataBuf(chunkData.c_data(iccOffset), static_cast<uLongf>(chunkLength - iccOffset), iccProfile_);
  457|       |#ifdef EXIV2_DEBUG_MESSAGES
  458|       |        std::cout << "Exiv2::PngImage::readMetadata: profile name: " << profileName_ << '\n';
  459|       |        std::cout << "Exiv2::PngImage::readMetadata: iccProfile.size_ (uncompressed) : " << iccProfile_.size() << '\n';
  460|       |#endif
  461|    509|      }
  462|       |
  463|       |      // Set chunkLength to 0 in case we have read a supported chunk type. Otherwise, we need to seek the
  464|       |      // file to the next chunk position.
  465|  8.85k|      chunkLength = 0;
  466|  8.85k|    }
  467|       |
  468|       |    // Move to the next chunk: chunk data size + 4 CRC bytes.
  469|       |#ifdef EXIV2_DEBUG_MESSAGES
  470|       |    std::cout << "Exiv2::PngImage::readMetadata: Seek to offset: " << chunkLength + 4 << '\n';
  471|       |#endif
  472|  26.5k|    io_->seek(chunkLength + 4, BasicIo::cur);
  473|  26.5k|    if (io_->error() || io_->eof()) {
  ------------------
  |  Branch (473:9): [True: 505, False: 26.0k]
  |  Branch (473:25): [True: 373, False: 25.7k]
  ------------------
  474|    373|      throw Error(ErrorCode::kerFailedToReadImageData);
  475|    373|    }
  476|  26.5k|  }
  477|  1.16k|}  // PngImage::readMetadata
_ZN5Exiv214newPngInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  684|  1.16k|Image::UniquePtr newPngInstance(BasicIo::UniquePtr io, bool create) {
  685|  1.16k|  auto image = std::make_unique<PngImage>(std::move(io), create);
  686|  1.16k|  if (!image->good()) {
  ------------------
  |  Branch (686:7): [True: 0, False: 1.16k]
  ------------------
  687|      0|    return nullptr;
  688|      0|  }
  689|  1.16k|  return image;
  690|  1.16k|}
_ZN5Exiv29isPngTypeERNS_7BasicIoEb:
  692|  24.3k|bool isPngType(BasicIo& iIo, bool advance) {
  693|  24.3k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (693:7): [True: 0, False: 24.3k]
  |  Branch (693:22): [True: 233, False: 24.0k]
  ------------------
  694|    233|    throw Error(ErrorCode::kerInputDataReadFailed);
  695|    233|  }
  696|  24.0k|  const int32_t len = 8;
  697|  24.0k|  std::array<byte, len> buf;
  698|  24.0k|  iIo.read(buf.data(), len);
  699|  24.0k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (699:7): [True: 0, False: 24.0k]
  |  Branch (699:22): [True: 0, False: 24.0k]
  ------------------
  700|      0|    return false;
  701|      0|  }
  702|  24.0k|  bool rc = buf == pngSignature;
  703|  24.0k|  if (!advance || !rc) {
  ------------------
  |  Branch (703:7): [True: 22.9k, False: 1.16k]
  |  Branch (703:19): [True: 0, False: 1.16k]
  ------------------
  704|  22.9k|    iIo.seek(-len, BasicIo::cur);
  705|  22.9k|  }
  706|       |
  707|  24.0k|  return rc;
  708|  24.0k|}
pngimage.cpp:_ZN5Exiv2L13zlibToDataBufEPKhmRNS_7DataBufE:
   74|    479|static bool zlibToDataBuf(const byte* bytes, uLongf length, DataBuf& result) {
   75|    479|  uLongf uncompressedLen = length;  // just a starting point
   76|    479|  int zlibResult = Z_BUF_ERROR;
   77|       |
   78|  1.26k|  while (zlibResult == Z_BUF_ERROR) {
  ------------------
  |  Branch (78:10): [True: 781, False: 479]
  ------------------
   79|    781|    result.alloc(uncompressedLen);
   80|    781|    zlibResult = uncompress(result.data(), &uncompressedLen, bytes, length);
   81|       |    // if result buffer is large than necessary, redo to fit perfectly.
   82|    781|    if (zlibResult == Z_OK && uncompressedLen < result.size()) {
  ------------------
  |  Branch (82:9): [True: 0, False: 781]
  |  Branch (82:31): [True: 0, False: 0]
  ------------------
   83|      0|      result.reset();
   84|       |
   85|      0|      result.alloc(uncompressedLen);
   86|      0|      zlibResult = uncompress(result.data(), &uncompressedLen, bytes, length);
   87|      0|    }
   88|    781|    if (zlibResult == Z_BUF_ERROR) {
  ------------------
  |  Branch (88:9): [True: 302, False: 479]
  ------------------
   89|       |      // the uncompressed buffer needs to be larger
   90|    302|      result.reset();
   91|       |
   92|       |      // Sanity - never bigger than 16mb
   93|    302|      if (uncompressedLen > 16 * 1024 * 1024)
  ------------------
  |  Branch (93:11): [True: 0, False: 302]
  ------------------
   94|      0|        zlibResult = Z_DATA_ERROR;
   95|    302|      else
   96|    302|        uncompressedLen *= 2;
   97|    302|    }
   98|    781|  }
   99|       |
  100|       |  return zlibResult == Z_OK;
  101|    479|}
pngimage.cpp:_ZN5Exiv2L9readChunkERNS_7DataBufERNS_7BasicIoE:
  379|  35.5k|static void readChunk(DataBuf& buffer, BasicIo& io) {
  380|       |#ifdef EXIV2_DEBUG_MESSAGES
  381|       |  std::cout << "Exiv2::PngImage::readMetadata: Position: " << io.tell() << '\n';
  382|       |#endif
  383|  35.5k|  const size_t bufRead = io.read(buffer.data(), buffer.size());
  384|  35.5k|  if (io.error()) {
  ------------------
  |  Branch (384:7): [True: 0, False: 35.5k]
  ------------------
  385|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  386|      0|  }
  387|  35.5k|  if (bufRead != buffer.size()) {
  ------------------
  |  Branch (387:7): [True: 136, False: 35.4k]
  ------------------
  388|    136|    throw Error(ErrorCode::kerInputDataReadFailed);
  389|    136|  }
  390|  35.5k|}

_ZN5Exiv214PreviewManagerC2ERKNS_5ImageE:
 1008|  16.5k|PreviewManager::PreviewManager(const Image& image) : image_(image) {
 1009|  16.5k|}
_ZNK5Exiv214PreviewManager20getPreviewPropertiesEv:
 1011|  16.5k|PreviewPropertiesList PreviewManager::getPreviewProperties() const {
 1012|  16.5k|  PreviewPropertiesList list;
 1013|       |  // go through the loader table and store all successfully created loaders in the list
 1014|   577k|  for (PreviewId id = 0; id < Loader::getNumLoaders(); ++id) {
  ------------------
  |  Branch (1014:26): [True: 560k, False: 16.5k]
  ------------------
 1015|   560k|    auto loader = Loader::create(id, image_);
 1016|   560k|    if (loader && loader->readDimensions()) {
  ------------------
  |  Branch (1016:9): [True: 13.3k, False: 547k]
  |  Branch (1016:19): [True: 9.15k, False: 4.23k]
  ------------------
 1017|  9.15k|      PreviewProperties props = loader->getProperties();
 1018|  9.15k|      DataBuf buf = loader->getData();  // #16 getPreviewImage()
 1019|  9.15k|      props.size_ = buf.size();         //     update the size
 1020|  9.15k|      list.push_back(std::move(props));
 1021|  9.15k|    }
 1022|   560k|  }
 1023|  16.5k|  std::sort(list.begin(), list.end(),
 1024|  16.5k|            [](const auto& lhs, const auto& rhs) { return lhs.width_ * lhs.height_ < rhs.width_ * rhs.height_; });
 1025|       |
 1026|  16.5k|  return list;
 1027|  16.5k|}
preview.cpp:_ZN12_GLOBAL__N_16Loader13getNumLoadersEv:
  341|  1.13M|PreviewId Loader::getNumLoaders() {
  342|  1.13M|  return PreviewId{std::size(loaderList_)};
  343|  1.13M|}
preview.cpp:_ZN12_GLOBAL__N_118createLoaderNativeEiRKN5Exiv25ImageEi:
  359|  66.2k|Loader::UniquePtr createLoaderNative(PreviewId id, const Image& image, int parIdx) {
  360|  66.2k|  return std::make_unique<LoaderNative>(id, image, parIdx);
  361|  66.2k|}
preview.cpp:_ZN12_GLOBAL__N_112LoaderNativeC2EiRKN5Exiv25ImageEi:
  345|  66.2k|LoaderNative::LoaderNative(PreviewId id, const Image& image, int parIdx) : Loader(id, image) {
  346|  66.2k|  if (0 > parIdx || static_cast<size_t>(parIdx) >= image.nativePreviews().size())
  ------------------
  |  Branch (346:7): [True: 0, False: 66.2k]
  |  Branch (346:21): [True: 63.4k, False: 2.85k]
  ------------------
  347|  63.4k|    return;
  348|  2.85k|  nativePreview_ = image.nativePreviews()[parIdx];
  349|  2.85k|  width_ = nativePreview_.width_;
  350|  2.85k|  height_ = nativePreview_.height_;
  351|  2.85k|  valid_ = true;
  352|  2.85k|  if (nativePreview_.filter_.empty()) {
  ------------------
  |  Branch (352:7): [True: 2.80k, False: 57]
  ------------------
  353|  2.80k|    size_ = nativePreview_.size_;
  354|  2.80k|  } else {
  355|     57|    size_ = getData().size();
  356|     57|  }
  357|  2.85k|}
preview.cpp:_ZN12_GLOBAL__N_16LoaderC2EiRKN5Exiv25ImageE:
  334|   511k|Loader::Loader(PreviewId id, const Image& image) : id_(id), image_(image) {
  335|   511k|}
preview.cpp:_ZNK12_GLOBAL__N_16Loader13getPropertiesEv:
  337|  9.15k|PreviewProperties Loader::getProperties() const {
  338|  9.15k|  return {"", "", size_, width_, height_, id_};
  339|  9.15k|}
preview.cpp:_ZN12_GLOBAL__N_16Loader14readDimensionsEv:
   68|  4.47k|  virtual bool readDimensions() {
   69|  4.47k|    return true;
   70|  4.47k|  }
preview.cpp:_ZN12_GLOBAL__N_16LoaderD2Ev:
   45|   511k|  virtual ~Loader() = default;
preview.cpp:_ZNK12_GLOBAL__N_16Loader5validEv:
   57|   526k|  [[nodiscard]] virtual bool valid() const {
   58|   526k|    return valid_;
   59|   526k|  }
preview.cpp:_ZNK12_GLOBAL__N_112LoaderNative13getPropertiesEv:
  363|  2.72k|PreviewProperties LoaderNative::getProperties() const {
  364|  2.72k|  PreviewProperties prop = Loader::getProperties();
  365|  2.72k|  prop.mimeType_ = nativePreview_.mimeType_;
  366|  2.72k|  if (nativePreview_.mimeType_ == "image/jpeg") {
  ------------------
  |  Branch (366:7): [True: 2.41k, False: 309]
  ------------------
  367|  2.41k|    prop.extension_ = ".jpg";
  368|  2.41k|  } else if (nativePreview_.mimeType_ == "image/tiff") {
  ------------------
  |  Branch (368:14): [True: 0, False: 309]
  ------------------
  369|      0|    prop.extension_ = ".tif";
  370|    309|  } else if (nativePreview_.mimeType_ == "image/x-wmf") {
  ------------------
  |  Branch (370:14): [True: 0, False: 309]
  ------------------
  371|      0|    prop.extension_ = ".wmf";
  372|    309|  } else if (nativePreview_.mimeType_ == "image/x-portable-anymap") {
  ------------------
  |  Branch (372:14): [True: 0, False: 309]
  ------------------
  373|      0|    prop.extension_ = ".pnm";
  374|    309|  } else {
  375|    309|#ifndef SUPPRESS_WARNINGS
  376|    309|    EXV_WARNING << "Unknown native preview format: " << nativePreview_.mimeType_ << "\n";
  ------------------
  |  |  138|    309|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 309]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    309|  LogMsg(LogMsg::warn).os()
  ------------------
  377|    309|#endif
  378|    309|    prop.extension_ = ".dat";
  379|    309|  }
  380|  2.72k|  return prop;
  381|  2.72k|}
preview.cpp:_ZNK12_GLOBAL__N_112LoaderNative7getDataEv:
  383|  3.57k|DataBuf LoaderNative::getData() const {
  384|  3.57k|  if (!valid())
  ------------------
  |  Branch (384:7): [True: 0, False: 3.57k]
  ------------------
  385|      0|    return {};
  386|       |
  387|  3.57k|  BasicIo& io = image_.io();
  388|  3.57k|  if (io.open() != 0) {
  ------------------
  |  Branch (388:7): [True: 0, False: 3.57k]
  ------------------
  389|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io.path(), strError());
  390|      0|  }
  391|  3.57k|  IoCloser closer(io);
  392|  3.57k|  const byte* data = io.mmap();
  393|  3.57k|  if (io.size() < nativePreview_.position_ + nativePreview_.size_) {
  ------------------
  |  Branch (393:7): [True: 1.01k, False: 2.55k]
  ------------------
  394|  1.01k|#ifndef SUPPRESS_WARNINGS
  395|  1.01k|    EXV_WARNING << "Invalid native preview position or size.\n";
  ------------------
  |  |  138|  1.01k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 1.01k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  1.01k|  LogMsg(LogMsg::warn).os()
  ------------------
  396|  1.01k|#endif
  397|  1.01k|    return {};
  398|  1.01k|  }
  399|  2.55k|  if (nativePreview_.filter_.empty()) {
  ------------------
  |  Branch (399:7): [True: 2.44k, False: 114]
  ------------------
  400|  2.44k|    return {data + nativePreview_.position_, nativePreview_.size_};
  401|  2.44k|  }
  402|    114|  if (nativePreview_.filter_ == "hex-ai7thumbnail-pnm") {
  ------------------
  |  Branch (402:7): [True: 0, False: 114]
  ------------------
  403|      0|    const DataBuf ai7thumbnail = decodeHex(data + nativePreview_.position_, nativePreview_.size_);
  404|      0|    const DataBuf rgb = decodeAi7Thumbnail(ai7thumbnail);
  405|      0|    return makePnm(width_, height_, rgb);
  406|      0|  }
  407|    114|  if (nativePreview_.filter_ == "hex-irb") {
  ------------------
  |  Branch (407:7): [True: 114, False: 0]
  ------------------
  408|    114|    const DataBuf psData = decodeHex(data + nativePreview_.position_, nativePreview_.size_);
  409|    114|    const byte* record;
  410|    114|    uint32_t sizeHdr = 0;
  411|    114|    uint32_t sizeData = 0;
  412|    114|    if (Photoshop::locatePreviewIrb(psData.c_data(), psData.size(), &record, sizeHdr, sizeData) != 0) {
  ------------------
  |  Branch (412:9): [True: 114, False: 0]
  ------------------
  413|    114|#ifndef SUPPRESS_WARNINGS
  414|    114|      EXV_WARNING << "Missing preview IRB in Photoshop EPS preview.\n";
  ------------------
  |  |  138|    114|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 114]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    114|  LogMsg(LogMsg::warn).os()
  ------------------
  415|    114|#endif
  416|    114|      return {};
  417|    114|    }
  418|      0|    Internal::enforce(sizeData >= 28, ErrorCode::kerCorruptedMetadata);
  419|      0|    return {record + sizeHdr + 28, sizeData - 28};
  420|    114|  }
  421|      0|  throw Error(ErrorCode::kerErrorMessage, "Invalid native preview filter: ", nativePreview_.filter_);
  422|    114|}
preview.cpp:_ZN12_GLOBAL__N_19decodeHexEPKhm:
  812|    114|DataBuf decodeHex(const byte* src, size_t srcSize) {
  813|       |  // create decoding table
  814|    114|  byte invalid = 16;
  815|    114|  std::array<byte, 256> decodeHexTable;
  816|    114|  decodeHexTable.fill(invalid);
  817|  1.25k|  for (byte i = 0; i < 10; i++)
  ------------------
  |  Branch (817:20): [True: 1.14k, False: 114]
  ------------------
  818|  1.14k|    decodeHexTable[static_cast<byte>('0') + i] = i;
  819|    798|  for (byte i = 0; i < 6; i++)
  ------------------
  |  Branch (819:20): [True: 684, False: 114]
  ------------------
  820|    684|    decodeHexTable[static_cast<byte>('A') + i] = i + 10;
  821|    798|  for (byte i = 0; i < 6; i++)
  ------------------
  |  Branch (821:20): [True: 684, False: 114]
  ------------------
  822|    684|    decodeHexTable[static_cast<byte>('a') + i] = i + 10;
  823|       |
  824|       |  // calculate dest size
  825|    114|  long validSrcSize = 0;
  826|   570k|  for (size_t srcPos = 0; srcPos < srcSize; srcPos++) {
  ------------------
  |  Branch (826:27): [True: 570k, False: 114]
  ------------------
  827|   570k|    if (decodeHexTable[src[srcPos]] != invalid)
  ------------------
  |  Branch (827:9): [True: 86.5k, False: 484k]
  ------------------
  828|  86.5k|      validSrcSize++;
  829|   570k|  }
  830|    114|  const size_t destSize = validSrcSize / 2;
  831|       |
  832|       |  // allocate dest buffer
  833|    114|  DataBuf dest(destSize);
  834|       |
  835|       |  // decode
  836|  43.3k|  for (size_t srcPos = 0, destPos = 0; destPos < destSize; destPos++) {
  ------------------
  |  Branch (836:40): [True: 43.2k, False: 114]
  ------------------
  837|  43.2k|    byte buffer = 0;
  838|   612k|    for (int bufferPos = 1; bufferPos >= 0 && srcPos < srcSize; srcPos++) {
  ------------------
  |  Branch (838:29): [True: 569k, False: 43.2k]
  |  Branch (838:47): [True: 569k, False: 0]
  ------------------
  839|   569k|      byte srcValue = decodeHexTable[src[srcPos]];
  840|   569k|      if (srcValue == invalid)
  ------------------
  |  Branch (840:11): [True: 482k, False: 86.4k]
  ------------------
  841|   482k|        continue;
  842|  86.4k|      buffer |= srcValue << (bufferPos * 4);
  843|  86.4k|      bufferPos--;
  844|  86.4k|    }
  845|  43.2k|    dest.write_uint8(destPos, buffer);
  846|  43.2k|  }
  847|    114|  return dest;
  848|    114|}
preview.cpp:_ZN12_GLOBAL__N_112LoaderNative14readDimensionsEv:
  424|  2.85k|bool LoaderNative::readDimensions() {
  425|  2.85k|  if (!valid())
  ------------------
  |  Branch (425:7): [True: 0, False: 2.85k]
  ------------------
  426|      0|    return false;
  427|  2.85k|  if (width_ != 0 || height_ != 0)
  ------------------
  |  Branch (427:7): [True: 1.60k, False: 1.25k]
  |  Branch (427:22): [True: 467, False: 790]
  ------------------
  428|  2.06k|    return true;
  429|       |
  430|    790|  const DataBuf data = getData();
  431|    790|  if (data.empty())
  ------------------
  |  Branch (431:7): [True: 80, False: 710]
  ------------------
  432|     80|    return false;
  433|       |
  434|    710|  try {
  435|    710|    auto image = ImageFactory::open(data.c_data(), data.size());
  436|    710|    if (!image)
  ------------------
  |  Branch (436:9): [True: 0, False: 710]
  ------------------
  437|      0|      return false;
  438|    710|    image->readMetadata();
  439|       |
  440|    710|    width_ = image->pixelWidth();
  441|    710|    height_ = image->pixelHeight();
  442|    710|  } catch (const Error& /* error */) {
  443|     49|#ifndef SUPPRESS_WARNINGS
  444|     49|    EXV_WARNING << "Invalid native preview image.\n";
  ------------------
  |  |  138|     49|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 49]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     49|  LogMsg(LogMsg::warn).os()
  ------------------
  445|     49|#endif
  446|     49|    return false;
  447|     49|  }
  448|    657|  return true;
  449|    710|}
preview.cpp:_ZN12_GLOBAL__N_124createLoaderExifDataJpegEiRKN5Exiv25ImageEi:
  552|   182k|Loader::UniquePtr createLoaderExifDataJpeg(PreviewId id, const Image& image, int parIdx) {
  553|   182k|  return std::make_unique<LoaderExifDataJpeg>(id, image, parIdx);
  554|   182k|}
preview.cpp:_ZN12_GLOBAL__N_118LoaderExifDataJpegC2EiRKN5Exiv25ImageEi:
  539|   182k|    Loader(id, image), dataKey_(param_[parIdx].dataKey_) {
  540|   182k|  if (auto pos = image_.exifData().findKey(dataKey_); pos != image_.exifData().end()) {
  ------------------
  |  Branch (540:55): [True: 607, False: 181k]
  ------------------
  541|    607|    size_ = pos->sizeDataArea();  // indirect data
  542|    607|    if (size_ == 0 && pos->typeId() == undefined)
  ------------------
  |  Branch (542:9): [True: 464, False: 143]
  |  Branch (542:23): [True: 20, False: 444]
  ------------------
  543|     20|      size_ = pos->size();  // direct data
  544|    607|  }
  545|       |
  546|   182k|  if (size_ == 0)
  ------------------
  |  Branch (546:7): [True: 182k, False: 160]
  ------------------
  547|   182k|    return;
  548|       |
  549|    160|  valid_ = true;
  550|    160|}
preview.cpp:_ZNK12_GLOBAL__N_118LoaderExifDataJpeg13getPropertiesEv:
  556|     10|PreviewProperties LoaderExifDataJpeg::getProperties() const {
  557|     10|  PreviewProperties prop = Loader::getProperties();
  558|     10|  prop.mimeType_ = "image/jpeg";
  559|     10|  prop.extension_ = ".jpg";
  560|     10|  return prop;
  561|     10|}
preview.cpp:_ZNK12_GLOBAL__N_118LoaderExifDataJpeg7getDataEv:
  563|    170|DataBuf LoaderExifDataJpeg::getData() const {
  564|    170|  DataBuf buf;
  565|       |
  566|    170|  if (!valid())
  ------------------
  |  Branch (566:7): [True: 0, False: 170]
  ------------------
  567|      0|    return buf;
  568|       |
  569|    170|  if (auto pos = image_.exifData().findKey(dataKey_); pos != image_.exifData().end()) {
  ------------------
  |  Branch (569:55): [True: 170, False: 0]
  ------------------
  570|    170|    buf = pos->dataArea();  // indirect data
  571|       |
  572|    170|    if (buf.empty()) {  // direct data
  ------------------
  |  Branch (572:9): [True: 17, False: 153]
  ------------------
  573|     17|      buf = DataBuf(pos->size());
  574|     17|      pos->copy(buf.data(), invalidByteOrder);
  575|     17|    }
  576|       |
  577|    170|    buf.write_uint8(0, 0xff);  // fix Minolta thumbnails with invalid jpeg header
  578|    170|    return buf;
  579|    170|  }
  580|       |
  581|      0|  return buf;
  582|    170|}
preview.cpp:_ZN12_GLOBAL__N_118LoaderExifDataJpeg14readDimensionsEv:
  584|    160|bool LoaderExifDataJpeg::readDimensions() {
  585|    160|  if (!valid())
  ------------------
  |  Branch (585:7): [True: 0, False: 160]
  ------------------
  586|      0|    return false;
  587|       |
  588|    160|  DataBuf buf = getData();
  589|    160|  if (buf.empty())
  ------------------
  |  Branch (589:7): [True: 0, False: 160]
  ------------------
  590|      0|    return false;
  591|       |
  592|    160|  try {
  593|    160|    auto image = ImageFactory::open(buf.c_data(), buf.size());
  594|    160|    if (!image)
  ------------------
  |  Branch (594:9): [True: 0, False: 160]
  ------------------
  595|      0|      return false;
  596|    160|    image->readMetadata();
  597|       |
  598|    160|    width_ = image->pixelWidth();
  599|    160|    height_ = image->pixelHeight();
  600|    160|  } catch (const Error& /* error */) {
  601|    150|    return false;
  602|    150|  }
  603|       |
  604|     10|  return true;
  605|    160|}
preview.cpp:_ZN12_GLOBAL__N_116createLoaderTiffEiRKN5Exiv25ImageEi:
  665|   115k|Loader::UniquePtr createLoaderTiff(PreviewId id, const Image& image, int parIdx) {
  666|   115k|  return std::make_unique<LoaderTiff>(id, image, parIdx);
  667|   115k|}
preview.cpp:_ZN12_GLOBAL__N_110LoaderTiffC2EiRKN5Exiv25ImageEi:
  608|   115k|    Loader(id, image), group_(param_[parIdx].group_) {
  609|   115k|  const ExifData& exifData = image_.exifData();
  610|       |
  611|   115k|  size_t offsetCount = 0;
  612|   115k|  ExifData::const_iterator pos;
  613|       |
  614|       |  // check if the group_ contains a preview image
  615|   115k|  if (param_[parIdx].checkTag_) {
  ------------------
  |  Branch (615:7): [True: 98.9k, False: 16.5k]
  ------------------
  616|  98.9k|    pos = exifData.findKey(ExifKey(param_[parIdx].checkTag_));
  617|  98.9k|    if (pos == exifData.end())
  ------------------
  |  Branch (617:9): [True: 93.9k, False: 5.00k]
  ------------------
  618|  93.9k|      return;
  619|  5.00k|    if (param_[parIdx].checkValue_ && pos->toString() != param_[parIdx].checkValue_)
  ------------------
  |  Branch (619:9): [True: 5.00k, False: 0]
  |  Branch (619:9): [True: 667, False: 4.33k]
  |  Branch (619:39): [True: 667, False: 4.33k]
  ------------------
  620|    667|      return;
  621|  5.00k|  }
  622|       |
  623|  20.8k|  pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".StripOffsets"));
  624|  20.8k|  if (pos != exifData.end()) {
  ------------------
  |  Branch (624:7): [True: 4.54k, False: 16.3k]
  ------------------
  625|  4.54k|    offsetTag_ = "StripOffsets";
  626|  4.54k|    sizeTag_ = "StripByteCounts";
  627|  4.54k|    offsetCount = pos->value().count();
  628|  16.3k|  } else {
  629|  16.3k|    pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".TileOffsets"));
  630|  16.3k|    if (pos == exifData.end())
  ------------------
  |  Branch (630:9): [True: 15.9k, False: 353]
  ------------------
  631|  15.9k|      return;
  632|    353|    offsetTag_ = "TileOffsets";
  633|    353|    sizeTag_ = "TileByteCounts";
  634|    353|    offsetCount = pos->value().count();
  635|    353|  }
  636|       |
  637|  4.89k|  pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + '.' + sizeTag_));
  638|  4.89k|  if (pos == exifData.end())
  ------------------
  |  Branch (638:7): [True: 155, False: 4.74k]
  ------------------
  639|    155|    return;
  640|  4.74k|  if (offsetCount != pos->value().count())
  ------------------
  |  Branch (640:7): [True: 47, False: 4.69k]
  ------------------
  641|     47|    return;
  642|  23.0k|  for (size_t i = 0; i < offsetCount; i++) {
  ------------------
  |  Branch (642:22): [True: 18.3k, False: 4.69k]
  ------------------
  643|  18.3k|    size_ += pos->toUint32(i);
  644|  18.3k|  }
  645|       |
  646|  4.69k|  if (size_ == 0)
  ------------------
  |  Branch (646:7): [True: 73, False: 4.62k]
  ------------------
  647|     73|    return;
  648|       |
  649|  4.62k|  pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".ImageWidth"));
  650|  4.62k|  if (pos != exifData.end() && pos->count() > 0) {
  ------------------
  |  Branch (650:7): [True: 4.56k, False: 58]
  |  Branch (650:7): [True: 4.52k, False: 99]
  |  Branch (650:32): [True: 4.52k, False: 41]
  ------------------
  651|  4.52k|    width_ = pos->toUint32();
  652|  4.52k|  }
  653|       |
  654|  4.62k|  pos = exifData.findKey(ExifKey(std::string("Exif.") + group_ + ".ImageLength"));
  655|  4.62k|  if (pos != exifData.end() && pos->count() > 0) {
  ------------------
  |  Branch (655:7): [True: 4.57k, False: 50]
  |  Branch (655:7): [True: 4.54k, False: 82]
  |  Branch (655:32): [True: 4.54k, False: 32]
  ------------------
  656|  4.54k|    height_ = pos->toUint32();
  657|  4.54k|  }
  658|       |
  659|  4.62k|  if (width_ == 0 || height_ == 0)
  ------------------
  |  Branch (659:7): [True: 111, False: 4.51k]
  |  Branch (659:22): [True: 34, False: 4.47k]
  ------------------
  660|    145|    return;
  661|       |
  662|  4.47k|  valid_ = true;
  663|  4.47k|}
preview.cpp:_ZNK12_GLOBAL__N_110LoaderTiff13getPropertiesEv:
  669|  4.47k|PreviewProperties LoaderTiff::getProperties() const {
  670|  4.47k|  PreviewProperties prop = Loader::getProperties();
  671|  4.47k|  prop.mimeType_ = "image/tiff";
  672|  4.47k|  prop.extension_ = ".tif";
  673|  4.47k|  return prop;
  674|  4.47k|}
preview.cpp:_ZNK12_GLOBAL__N_110LoaderTiff7getDataEv:
  676|  4.47k|DataBuf LoaderTiff::getData() const {
  677|  4.47k|  const ExifData& exifData = image_.exifData();
  678|       |
  679|  4.47k|  ExifData preview;
  680|       |
  681|       |  // copy tags
  682|   757k|  for (auto&& pos : exifData) {
  ------------------
  |  Branch (682:19): [True: 757k, False: 4.47k]
  ------------------
  683|   757k|    if (pos.groupName() == group_) {
  ------------------
  |  Branch (683:9): [True: 229k, False: 528k]
  ------------------
  684|       |      /*
  685|       |         Write only the necessary TIFF image tags
  686|       |         tags that especially could cause problems are:
  687|       |         "NewSubfileType" - the result is no longer a thumbnail, it is a standalone image
  688|       |         "Orientation" - this tag typically appears only in the "Image" group. Deleting it ensures
  689|       |                         consistent result for all previews, including JPEG
  690|       |      */
  691|   229k|      uint16_t tag = pos.tag();
  692|   229k|      if (tag != 0x00fe && tag != 0x00ff && Internal::isTiffImageTag(tag, IfdId::ifd0Id)) {
  ------------------
  |  Branch (692:11): [True: 223k, False: 5.38k]
  |  Branch (692:28): [True: 223k, False: 423]
  |  Branch (692:45): [True: 143k, False: 80.2k]
  ------------------
  693|   143k|        preview.add(ExifKey(tag, "Image"), &pos.value());
  694|   143k|      }
  695|   229k|    }
  696|   757k|  }
  697|       |
  698|  4.47k|  auto& dataValue = const_cast<Value&>(preview["Exif.Image." + offsetTag_].value());
  699|       |
  700|  4.47k|  if (dataValue.sizeDataArea() == 0) {
  ------------------
  |  Branch (700:7): [True: 4.34k, False: 132]
  ------------------
  701|       |    // image data are not available via exifData, read them from image_.io()
  702|  4.34k|    BasicIo& io = image_.io();
  703|       |
  704|  4.34k|    if (io.open() != 0) {
  ------------------
  |  Branch (704:9): [True: 0, False: 4.34k]
  ------------------
  705|      0|      throw Error(ErrorCode::kerDataSourceOpenFailed, io.path(), strError());
  706|      0|    }
  707|  4.34k|    IoCloser closer(io);
  708|       |
  709|  4.34k|    const Exiv2::byte* base = io.mmap();
  710|       |
  711|  4.34k|    const Value& sizes = preview["Exif.Image." + sizeTag_].value();
  712|       |
  713|  4.34k|    if (sizes.count() == dataValue.count()) {
  ------------------
  |  Branch (713:9): [True: 4.34k, False: 0]
  ------------------
  714|  4.34k|      if (sizes.count() == 1) {
  ------------------
  |  Branch (714:11): [True: 4.12k, False: 222]
  ------------------
  715|       |        // this saves one copying of the buffer
  716|  4.12k|        uint32_t offset = dataValue.toUint32(0);
  717|  4.12k|        uint32_t size = sizes.toUint32(0);
  718|  4.12k|        if (Safe::add(offset, size) <= static_cast<uint32_t>(io.size()))
  ------------------
  |  Branch (718:13): [True: 2.41k, False: 1.71k]
  ------------------
  719|  2.41k|          dataValue.setDataArea(base + offset, size);
  720|  4.12k|      } else {
  721|       |        // FIXME: the buffer is probably copied twice, it should be optimized
  722|    222|        Internal::enforce(size_ <= io.size(), ErrorCode::kerCorruptedMetadata);
  723|    222|        DataBuf buf(size_);
  724|    222|        uint32_t idxBuf = 0;
  725|  6.74k|        for (size_t i = 0; i < sizes.count(); i++) {
  ------------------
  |  Branch (725:28): [True: 6.52k, False: 222]
  ------------------
  726|  6.52k|          uint32_t offset = dataValue.toUint32(i);
  727|  6.52k|          uint32_t size = sizes.toUint32(i);
  728|       |
  729|       |          // the size_ parameter is originally computed by summing all values inside sizes
  730|       |          // see the constructor of LoaderTiff
  731|       |          // But e.g in malicious files some of these values could be negative
  732|       |          // That's why we check again for each step here to really make sure we don't overstep
  733|  6.52k|          Internal::enforce(Safe::add(idxBuf, size) <= size_, ErrorCode::kerCorruptedMetadata);
  734|  6.52k|          if (size != 0 && Safe::add(offset, size) <= static_cast<uint32_t>(io.size())) {
  ------------------
  |  Branch (734:15): [True: 3.23k, False: 3.29k]
  |  Branch (734:28): [True: 2.75k, False: 475]
  ------------------
  735|  2.75k|            std::copy_n(base + offset, size, buf.begin() + idxBuf);
  736|  2.75k|          }
  737|       |
  738|  6.52k|          idxBuf += size;
  739|  6.52k|        }
  740|    222|        dataValue.setDataArea(buf.c_data(), buf.size());
  741|    222|      }
  742|  4.34k|    }
  743|  4.34k|  }
  744|       |
  745|       |  // Fix compression value in the CR2 IFD2 image
  746|  4.47k|  if (0 == strcmp(group_, "Image2") && image_.mimeType() == "image/x-canon-cr2") {
  ------------------
  |  Branch (746:7): [True: 3, False: 4.47k]
  |  Branch (746:7): [True: 3, False: 4.47k]
  |  Branch (746:40): [True: 3, False: 0]
  ------------------
  747|      3|    preview["Exif.Image.Compression"] = std::uint16_t{1};
  748|      3|  }
  749|       |
  750|       |  // write new image
  751|  4.47k|  MemIo mio;
  752|  4.47k|  IptcData emptyIptc;
  753|  4.47k|  XmpData emptyXmp;
  754|  4.47k|  TiffParser::encode(mio, nullptr, 0, Exiv2::littleEndian, preview, emptyIptc, emptyXmp);
  755|  4.47k|  return {mio.mmap(), mio.size()};
  756|  4.47k|}
preview.cpp:_ZN12_GLOBAL__N_120createLoaderExifJpegEiRKN5Exiv25ImageEi:
  480|   131k|Loader::UniquePtr createLoaderExifJpeg(PreviewId id, const Image& image, int parIdx) {
  481|   131k|  return std::make_unique<LoaderExifJpeg>(id, image, parIdx);
  482|   131k|}
preview.cpp:_ZN12_GLOBAL__N_114LoaderExifJpegC2EiRKN5Exiv25ImageEi:
  451|   131k|LoaderExifJpeg::LoaderExifJpeg(PreviewId id, const Image& image, int parIdx) : Loader(id, image) {
  452|   131k|  const ExifData& exifData = image_.exifData();
  453|   131k|  auto pos = exifData.findKey(ExifKey(param_[parIdx].offsetKey_));
  454|   131k|  if (pos != exifData.end() && pos->count() > 0) {
  ------------------
  |  Branch (454:7): [True: 7.44k, False: 123k]
  |  Branch (454:7): [True: 6.36k, False: 124k]
  |  Branch (454:32): [True: 6.36k, False: 1.07k]
  ------------------
  455|  6.36k|    offset_ = pos->toUint32();
  456|  6.36k|  }
  457|       |
  458|   131k|  size_ = 0;
  459|   131k|  pos = exifData.findKey(ExifKey(param_[parIdx].sizeKey_));
  460|   131k|  if (pos != exifData.end() && pos->count() > 0) {
  ------------------
  |  Branch (460:7): [True: 8.75k, False: 122k]
  |  Branch (460:7): [True: 6.37k, False: 124k]
  |  Branch (460:32): [True: 6.37k, False: 2.38k]
  ------------------
  461|  6.37k|    size_ = pos->toUint32();
  462|  6.37k|  }
  463|       |
  464|   131k|  if (offset_ == 0 || size_ == 0)
  ------------------
  |  Branch (464:7): [True: 124k, False: 6.23k]
  |  Branch (464:23): [True: 185, False: 6.05k]
  ------------------
  465|   125k|    return;
  466|       |
  467|  6.05k|  if (param_[parIdx].baseOffsetKey_) {
  ------------------
  |  Branch (467:7): [True: 0, False: 6.05k]
  ------------------
  468|      0|    pos = exifData.findKey(ExifKey(param_[parIdx].baseOffsetKey_));
  469|      0|    if (pos != exifData.end() && pos->count() > 0) {
  ------------------
  |  Branch (469:9): [True: 0, False: 0]
  |  Branch (469:9): [True: 0, False: 0]
  |  Branch (469:34): [True: 0, False: 0]
  ------------------
  470|      0|      offset_ += pos->toUint32();
  471|      0|    }
  472|      0|  }
  473|       |
  474|  6.05k|  if (Safe::add(offset_, size_) > image_.io().size())
  ------------------
  |  Branch (474:7): [True: 163, False: 5.89k]
  ------------------
  475|    163|    return;
  476|       |
  477|  5.89k|  valid_ = true;
  478|  5.89k|}
preview.cpp:_ZNK12_GLOBAL__N_114LoaderExifJpeg13getPropertiesEv:
  484|  1.94k|PreviewProperties LoaderExifJpeg::getProperties() const {
  485|  1.94k|  PreviewProperties prop = Loader::getProperties();
  486|  1.94k|  prop.mimeType_ = "image/jpeg";
  487|  1.94k|  prop.extension_ = ".jpg";
  488|  1.94k|  return prop;
  489|  1.94k|}
preview.cpp:_ZNK12_GLOBAL__N_114LoaderExifJpeg7getDataEv:
  491|  1.94k|DataBuf LoaderExifJpeg::getData() const {
  492|  1.94k|  if (!valid())
  ------------------
  |  Branch (492:7): [True: 0, False: 1.94k]
  ------------------
  493|      0|    return {};
  494|  1.94k|  BasicIo& io = image_.io();
  495|       |
  496|  1.94k|  if (io.open() != 0) {
  ------------------
  |  Branch (496:7): [True: 0, False: 1.94k]
  ------------------
  497|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io.path(), strError());
  498|      0|  }
  499|  1.94k|  IoCloser closer(io);
  500|       |
  501|  1.94k|  const Exiv2::byte* base = io.mmap();
  502|       |
  503|  1.94k|  return {base + offset_, size_};
  504|  1.94k|}
preview.cpp:_ZN12_GLOBAL__N_114LoaderExifJpeg14readDimensionsEv:
  506|  5.89k|bool LoaderExifJpeg::readDimensions() {
  507|  5.89k|  if (!valid())
  ------------------
  |  Branch (507:7): [True: 0, False: 5.89k]
  ------------------
  508|      0|    return false;
  509|  5.89k|  if (width_ || height_)
  ------------------
  |  Branch (509:7): [True: 0, False: 5.89k]
  |  Branch (509:17): [True: 0, False: 5.89k]
  ------------------
  510|      0|    return true;
  511|       |
  512|  5.89k|  BasicIo& io = image_.io();
  513|       |
  514|  5.89k|  if (io.open() != 0) {
  ------------------
  |  Branch (514:7): [True: 0, False: 5.89k]
  ------------------
  515|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io.path(), strError());
  516|      0|  }
  517|  5.89k|  IoCloser closer(io);
  518|  5.89k|  const Exiv2::byte* base = io.mmap();
  519|       |
  520|  5.89k|  try {
  521|  5.89k|    auto image = ImageFactory::open(base + offset_, size_);
  522|  5.89k|    if (!image)
  ------------------
  |  Branch (522:9): [True: 0, False: 5.89k]
  ------------------
  523|      0|      return false;
  524|  5.89k|    image->readMetadata();
  525|       |
  526|  5.89k|    width_ = image->pixelWidth();
  527|  5.89k|    height_ = image->pixelHeight();
  528|  5.89k|  } catch (const Error& /* error */) {
  529|  3.94k|#ifndef SUPPRESS_WARNINGS
  530|  3.94k|    EXV_WARNING << "Invalid JPEG preview image.\n";
  ------------------
  |  |  138|  3.94k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 3.94k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  3.94k|  LogMsg(LogMsg::warn).os()
  ------------------
  531|  3.94k|#endif
  532|  3.94k|    return false;
  533|  3.94k|  }
  534|       |
  535|  1.94k|  return true;
  536|  5.89k|}
preview.cpp:_ZN12_GLOBAL__N_119createLoaderXmpJpegEiRKN5Exiv25ImageEi:
  791|  16.3k|Loader::UniquePtr createLoaderXmpJpeg(PreviewId id, const Image& image, int parIdx) {
  792|  16.3k|  return std::make_unique<LoaderXmpJpeg>(id, image, parIdx);
  793|  16.3k|}
preview.cpp:_ZN12_GLOBAL__N_113LoaderXmpJpegC2EiRKN5Exiv25ImageEi:
  758|  16.3k|LoaderXmpJpeg::LoaderXmpJpeg(PreviewId id, const Image& image, int parIdx) : Loader(id, image) {
  759|  16.3k|  (void)parIdx;
  760|       |
  761|  16.3k|  const XmpData& xmpData = image_.xmpData();
  762|       |
  763|  16.3k|  std::string prefix = "xmpGImg";
  764|  16.3k|  if (xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/xapGImg:image")) != xmpData.end()) {
  ------------------
  |  Branch (764:7): [True: 0, False: 16.3k]
  ------------------
  765|      0|    prefix = "xapGImg";
  766|      0|  }
  767|       |
  768|  16.3k|  auto imageDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":image"));
  769|  16.3k|  if (imageDatum == xmpData.end())
  ------------------
  |  Branch (769:7): [True: 16.3k, False: 0]
  ------------------
  770|  16.3k|    return;
  771|      0|  auto formatDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":format"));
  772|      0|  if (formatDatum == xmpData.end())
  ------------------
  |  Branch (772:7): [True: 0, False: 0]
  ------------------
  773|      0|    return;
  774|      0|  auto widthDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":width"));
  775|      0|  if (widthDatum == xmpData.end())
  ------------------
  |  Branch (775:7): [True: 0, False: 0]
  ------------------
  776|      0|    return;
  777|      0|  auto heightDatum = xmpData.findKey(XmpKey("Xmp.xmp.Thumbnails[1]/" + prefix + ":height"));
  778|      0|  if (heightDatum == xmpData.end())
  ------------------
  |  Branch (778:7): [True: 0, False: 0]
  ------------------
  779|      0|    return;
  780|       |
  781|      0|  if (formatDatum->toString() != "JPEG")
  ------------------
  |  Branch (781:7): [True: 0, False: 0]
  ------------------
  782|      0|    return;
  783|       |
  784|      0|  width_ = widthDatum->toUint32();
  785|      0|  height_ = heightDatum->toUint32();
  786|      0|  preview_ = decodeBase64(imageDatum->toString());
  787|      0|  size_ = preview_.size();
  788|      0|  valid_ = true;
  789|      0|}
preview.cpp:_ZN12_GLOBAL__N_16Loader6createEiRKN5Exiv25ImageE:
  319|   560k|Loader::UniquePtr Loader::create(PreviewId id, const Image& image) {
  320|   560k|  Loader::UniquePtr loader;
  321|   560k|  if (id < 0 || id >= Loader::getNumLoaders())
  ------------------
  |  Branch (321:7): [True: 0, False: 560k]
  |  Branch (321:17): [True: 0, False: 560k]
  ------------------
  322|      0|    return loader;
  323|       |
  324|   560k|  if (loaderList_[id].imageMimeType_ && std::string(loaderList_[id].imageMimeType_) != image.mimeType())
  ------------------
  |  Branch (324:7): [True: 49.3k, False: 511k]
  |  Branch (324:7): [True: 49.1k, False: 511k]
  |  Branch (324:41): [True: 49.1k, False: 196]
  ------------------
  325|  49.1k|    return loader;
  326|       |
  327|   511k|  loader = loaderList_[id].create_(id, image, loaderList_[id].parIdx_);
  328|   511k|  if (!loader->valid())
  ------------------
  |  Branch (328:7): [True: 498k, False: 13.3k]
  ------------------
  329|   498k|    loader = nullptr;
  330|       |
  331|   511k|  return loader;
  332|   560k|}
preview.cpp:_ZZNK5Exiv214PreviewManager20getPreviewPropertiesEvENK3$_0clINS_17PreviewPropertiesES3_EEDaRKT_RKT0_:
 1024|  8.06k|            [](const auto& lhs, const auto& rhs) { return lhs.width_ * lhs.height_ < rhs.width_ * rhs.height_; });

_ZNK5Exiv29XmpNsInfoeqERKNS0_2NsE:
 4939|   202k|bool XmpNsInfo::operator==(const XmpNsInfo::Ns& ns) const {
 4940|   202k|  return ns_ == ns.ns_;
 4941|   202k|}
_ZNK5Exiv29XmpNsInfoeqERKNS0_6PrefixE:
 4943|  48.8M|bool XmpNsInfo::operator==(const XmpNsInfo::Prefix& prefix) const {
 4944|  48.8M|  return prefix_ == prefix.prefix_;
 4945|  48.8M|}
_ZN5Exiv213XmpProperties8getMutexEv:
 4952|  1.76M|std::mutex& XmpProperties::getMutex() {
 4953|  1.76M|  static std::mutex m;
 4954|  1.76M|  return m;
 4955|  1.76M|}
_ZN5Exiv213XmpProperties24lookupNsRegistryUnlockedERKNS_9XmpNsInfo6PrefixERKNS0_7XmpLockE:
 4963|  1.79M|const XmpNsInfo* XmpProperties::lookupNsRegistryUnlocked(const XmpNsInfo::Prefix& prefix, const XmpLock&) {
 4964|  23.4M|  for (const auto& [_, p] : nsRegistry_) {
  ------------------
  |  Branch (4964:27): [True: 23.4M, False: 1.72M]
  ------------------
 4965|  23.4M|    if (p == prefix)
  ------------------
  |  Branch (4965:9): [True: 74.0k, False: 23.4M]
  ------------------
 4966|  74.0k|      return &p;
 4967|  23.4M|  }
 4968|  1.72M|  return nullptr;
 4969|  1.79M|}
_ZN5Exiv213XmpProperties18registerNsUnlockedERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_RKNS0_7XmpLockE:
 4976|  2.80k|void XmpProperties::registerNsUnlocked(const std::string& ns, const std::string& prefix, const XmpLock& lock) {
 4977|  2.80k|  if (ns.empty())
  ------------------
  |  Branch (4977:7): [True: 0, False: 2.80k]
  ------------------
 4978|      0|    return;
 4979|  2.80k|  std::string ns2 = ns;
 4980|  2.80k|  if (ns2.back() != '/' && ns2.back() != '#')
  ------------------
  |  Branch (4980:7): [True: 1.51k, False: 1.29k]
  |  Branch (4980:28): [True: 941, False: 575]
  ------------------
 4981|    941|    ns2 += '/';
 4982|       |
 4983|       |  // 1. Check if this URI is already registered with this exact prefix
 4984|  2.80k|  auto it = nsRegistry_.find(ns2);
 4985|  2.80k|  if (it != nsRegistry_.end() && std::strcmp(it->second.prefix_, prefix.c_str()) == 0) {
  ------------------
  |  Branch (4985:7): [True: 0, False: 2.80k]
  |  Branch (4985:7): [True: 0, False: 2.80k]
  |  Branch (4985:34): [True: 0, False: 0]
  ------------------
 4986|      0|    return;  // Already registered with this prefix
 4987|      0|  }
 4988|       |
 4989|       |  // 2. Check if this prefix is already registered with a DIFFERENT URI
 4990|  2.80k|  if (auto xnp = lookupNsRegistryUnlocked(XmpNsInfo::Prefix{prefix}, lock)) {
  ------------------
  |  Branch (4990:12): [True: 2.78k, False: 21]
  ------------------
 4991|  2.78k|#ifndef SUPPRESS_WARNINGS
 4992|  2.78k|    if (ns2 != xnp->ns_)
  ------------------
  |  Branch (4992:9): [True: 2.78k, False: 0]
  ------------------
 4993|  2.78k|      EXV_WARNING << "Updating namespace URI for " << prefix << " from " << xnp->ns_ << " to " << ns2 << "\n";
  ------------------
  |  |  138|  2.78k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 2.78k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  2.78k|  LogMsg(LogMsg::warn).os()
  ------------------
 4994|  2.78k|#endif
 4995|  2.78k|    unregisterNsUnlocked(xnp->ns_, lock);
 4996|  2.78k|  }
 4997|       |
 4998|       |  // 3. Ensure the URI is unregistered if it's currently used with a different prefix
 4999|       |  // (This handles the case where prefix changed for the same URI, preventing memory leak)
 5000|  2.80k|  unregisterNsUnlocked(ns2, lock);
 5001|       |  // Allocated memory is freed when the namespace is unregistered.
 5002|       |  // Using malloc/free for better system compatibility in case
 5003|       |  // users don't unregister their namespaces explicitly.
 5004|  2.80k|  XmpNsInfo xn;
 5005|  2.80k|  auto c = new char[ns2.size() + 1];
 5006|  2.80k|  std::strcpy(c, ns2.c_str());
 5007|  2.80k|  xn.ns_ = c;
 5008|  2.80k|  c = new char[prefix.size() + 1];
 5009|  2.80k|  std::strcpy(c, prefix.c_str());
 5010|  2.80k|  xn.prefix_ = c;
 5011|  2.80k|  xn.xmpPropertyInfo_ = nullptr;
 5012|  2.80k|  xn.desc_ = "";
 5013|  2.80k|  nsRegistry_[ns2] = xn;
 5014|  2.80k|}
_ZN5Exiv213XmpProperties20unregisterNsUnlockedERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS0_7XmpLockE:
 5021|  5.59k|void XmpProperties::unregisterNsUnlocked(const std::string& ns, const XmpLock&) {
 5022|  5.59k|  unregisterNsNoLock(ns, LifetimeKey{});
 5023|  5.59k|}
_ZN5Exiv213XmpProperties18unregisterNsNoLockERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS0_11LifetimeKeyE:
 5025|  5.61k|void XmpProperties::unregisterNsNoLock(const std::string& ns, LifetimeKey) {
 5026|  5.61k|  auto i = nsRegistry_.find(ns);
 5027|  5.61k|  if (i != nsRegistry_.end()) {
  ------------------
  |  Branch (5027:7): [True: 2.80k, False: 2.80k]
  ------------------
 5028|  2.80k|    delete[] i->second.prefix_;
 5029|  2.80k|    delete[] i->second.ns_;
 5030|  2.80k|    nsRegistry_.erase(i);
 5031|  2.80k|  }
 5032|  5.61k|}
_ZN5Exiv213XmpProperties21unregisterAllNsNoLockENS0_11LifetimeKeyE:
 5042|      1|void XmpProperties::unregisterAllNsNoLock(LifetimeKey) {
 5043|       |  /// \todo check if we are not unregistering the first NS
 5044|      1|  auto i = nsRegistry_.begin();
 5045|     22|  while (i != nsRegistry_.end()) {
  ------------------
  |  Branch (5045:10): [True: 21, False: 1]
  ------------------
 5046|     21|    auto kill = i++;
 5047|     21|    unregisterNsNoLock(kill->first, LifetimeKey{});
 5048|     21|  }
 5049|      1|}
_ZN5Exiv213XmpProperties14prefixUnlockedERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS0_7XmpLockE:
 5056|  62.7k|std::string XmpProperties::prefixUnlocked(const std::string& ns, const XmpLock&) {
 5057|  62.7k|  std::string ns2 = ns;
 5058|  62.7k|  if (ns2.back() != '/' && ns2.back() != '#')
  ------------------
  |  Branch (5058:7): [True: 33.4k, False: 29.3k]
  |  Branch (5058:28): [True: 28.3k, False: 5.08k]
  ------------------
 5059|  28.3k|    ns2 += '/';
 5060|       |
 5061|  62.7k|  auto i = nsRegistry_.find(ns2);
 5062|  62.7k|  std::string p;
 5063|  62.7k|  if (i != nsRegistry_.end())
  ------------------
  |  Branch (5063:7): [True: 35.3k, False: 27.3k]
  ------------------
 5064|  35.3k|    p = i->second.prefix_;
 5065|  27.3k|  else if (auto xn = Exiv2::find(xmpNsInfo, XmpNsInfo::Ns{std::move(ns2)}))
  ------------------
  |  Branch (5065:17): [True: 24.5k, False: 2.80k]
  ------------------
 5066|  24.5k|    p = std::string(xn->prefix_);
 5067|  62.7k|  return p;
 5068|  62.7k|}
_ZN5Exiv213XmpProperties10nsUnlockedERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS0_7XmpLockE:
 5075|   910k|std::string XmpProperties::nsUnlocked(const std::string& prefix, const XmpLock& lock) {
 5076|   910k|  if (auto xn = lookupNsRegistryUnlocked(XmpNsInfo::Prefix{prefix}, lock))
  ------------------
  |  Branch (5076:12): [True: 71.3k, False: 839k]
  ------------------
 5077|  71.3k|    return xn->ns_;
 5078|   839k|  return nsInfoUnlocked(prefix, lock)->ns_;
 5079|   910k|}
_ZN5Exiv213XmpProperties20propertyTypeUnlockedERKNS_6XmpKeyERKNS0_7XmpLockE:
 5106|  44.4k|TypeId XmpProperties::propertyTypeUnlocked(const XmpKey& key, const XmpLock& lock) {
 5107|  44.4k|  const XmpPropertyInfo* pi = propertyInfoUnlocked(key, lock);
 5108|  44.4k|  return pi ? pi->typeId_ : xmpText;
  ------------------
  |  Branch (5108:10): [True: 43.1k, False: 1.23k]
  ------------------
 5109|  44.4k|}
_ZN5Exiv213XmpProperties20propertyInfoUnlockedERKNS_6XmpKeyERKNS0_7XmpLockE:
 5116|  44.4k|const XmpPropertyInfo* XmpProperties::propertyInfoUnlocked(const XmpKey& key, const XmpLock& lock) {
 5117|  44.4k|  std::string prefix = key.groupName();
 5118|  44.4k|  std::string property = key.tagName();
 5119|       |  // If property is a path for a nested property, determines the innermost element
 5120|  44.4k|  if (auto i = property.find_last_of('/'); i != std::string::npos) {
  ------------------
  |  Branch (5120:44): [True: 0, False: 44.4k]
  ------------------
 5121|      0|    i = std::distance(property.begin(), std::find_if(property.begin() + i, property.end(), isalpha));
 5122|      0|    property = property.substr(i);
 5123|      0|    i = property.find_first_of(':');
 5124|      0|    if (i != std::string::npos) {
  ------------------
  |  Branch (5124:9): [True: 0, False: 0]
  ------------------
 5125|      0|      prefix = property.substr(0, i);
 5126|      0|      property = property.substr(i + 1);
 5127|      0|    }
 5128|       |#ifdef EXIV2_DEBUG_MESSAGES
 5129|       |    std::cout << "Nested key: " << key.key() << ", prefix: " << prefix << ", property: " << property << "\n";
 5130|       |#endif
 5131|      0|  }
 5132|  44.4k|  if (auto pl = propertyListUnlocked(prefix, lock)) {
  ------------------
  |  Branch (5132:12): [True: 44.4k, False: 0]
  ------------------
 5133|  5.85M|    for (size_t j = 0; pl[j].name_; ++j) {
  ------------------
  |  Branch (5133:24): [True: 5.85M, False: 1.23k]
  ------------------
 5134|  5.85M|      if (property == pl[j].name_) {
  ------------------
  |  Branch (5134:11): [True: 43.1k, False: 5.81M]
  ------------------
 5135|  43.1k|        return pl + j;
 5136|  43.1k|      }
 5137|  5.85M|    }
 5138|  44.4k|  }
 5139|  1.23k|  return nullptr;
 5140|  44.4k|}
_ZN5Exiv213XmpProperties20propertyListUnlockedERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS0_7XmpLockE:
 5157|  44.4k|const XmpPropertyInfo* XmpProperties::propertyListUnlocked(const std::string& prefix, const XmpLock& lock) {
 5158|  44.4k|  return nsInfoUnlocked(prefix, lock)->xmpPropertyInfo_;
 5159|  44.4k|}
_ZN5Exiv213XmpProperties14nsInfoUnlockedERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS0_7XmpLockE:
 5166|   883k|const XmpNsInfo* XmpProperties::nsInfoUnlocked(const std::string& prefix, const XmpLock& lock) {
 5167|   883k|  const auto pf = XmpNsInfo::Prefix{prefix};
 5168|   883k|  const XmpNsInfo* xn = lookupNsRegistryUnlocked(pf, lock);
 5169|   883k|  if (!xn)
  ------------------
  |  Branch (5169:7): [True: 883k, False: 0]
  ------------------
 5170|   883k|    xn = Exiv2::find(xmpNsInfo, pf);
 5171|   883k|  if (!xn)
  ------------------
  |  Branch (5171:7): [True: 0, False: 883k]
  ------------------
 5172|      0|    throw Error(ErrorCode::kerNoNamespaceInfoForXmpPrefix, prefix);
 5173|   883k|  return xn;
 5174|   883k|}
_ZN5Exiv26XmpKey4ImplC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_RKNS_13XmpProperties7XmpLockE:
 5245|  54.0k|XmpKey::Impl::Impl(const std::string& prefix, const std::string& property, const XmpProperties::XmpLock& lock) {
 5246|       |  // Validate prefix unlocked (must hold lock)
 5247|  54.0k|  if (XmpProperties::nsUnlocked(prefix, lock).empty())
  ------------------
  |  Branch (5247:7): [True: 0, False: 54.0k]
  ------------------
 5248|      0|    throw Error(ErrorCode::kerNoNamespaceForPrefix, prefix);
 5249|       |
 5250|  54.0k|  property_ = property;
 5251|  54.0k|  prefix_ = prefix;
 5252|  54.0k|}
_ZN5Exiv26XmpKeyC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 5254|   196k|XmpKey::XmpKey(const std::string& key) : p_(std::make_unique<Impl>()) {
 5255|   196k|  p_->decomposeKey(key);
 5256|   196k|}
_ZN5Exiv26XmpKeyC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS_13XmpProperties7XmpLockE:
 5258|   660k|XmpKey::XmpKey(const std::string& key, const XmpProperties::XmpLock& lock) : p_(std::make_unique<Impl>()) {
 5259|   660k|  p_->decomposeKeyUnlocked(key, lock);
 5260|   660k|}
_ZN5Exiv26XmpKeyC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_RKNS_13XmpProperties7XmpLockE:
 5266|  54.0k|    p_(std::make_unique<Impl>(prefix, property, lock)) {
 5267|  54.0k|}
_ZN5Exiv26XmpKeyD2Ev:
 5269|  1.16M|XmpKey::~XmpKey() = default;
_ZN5Exiv26XmpKeyC2ERKS0_:
 5271|   251k|XmpKey::XmpKey(const XmpKey& rhs) : p_(std::make_unique<Impl>(*rhs.p_)) {
 5272|   251k|}
_ZNK5Exiv26XmpKey5cloneEv:
 5281|   251k|XmpKey::UniquePtr XmpKey::clone() const {
 5282|   251k|  return UniquePtr(clone_());
 5283|   251k|}
_ZNK5Exiv26XmpKey6clone_Ev:
 5285|   251k|XmpKey* XmpKey::clone_() const {
 5286|   251k|  return new XmpKey(*this);
 5287|   251k|}
_ZNK5Exiv26XmpKey3keyEv:
 5289|  7.38M|std::string XmpKey::key() const {
 5290|  7.38M|  return std::string(Exiv2::XmpKey::Impl::familyName_) + "." + p_->prefix_ + "." + p_->property_;
 5291|  7.38M|}
_ZNK5Exiv26XmpKey9groupNameEv:
 5297|  44.4k|std::string XmpKey::groupName() const {
 5298|  44.4k|  return p_->prefix_;
 5299|  44.4k|}
_ZNK5Exiv26XmpKey7tagNameEv:
 5301|  44.4k|std::string XmpKey::tagName() const {
 5302|  44.4k|  return p_->property_;
 5303|  44.4k|}
_ZN5Exiv26XmpKey4Impl12decomposeKeyERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 5331|   196k|void XmpKey::Impl::decomposeKey(const std::string& key) {
 5332|   196k|  XmpProperties::XmpLock lock;
 5333|   196k|  decomposeKeyUnlocked(key, lock);
 5334|   196k|}  // XmpKey::Impl::decomposeKey
_ZN5Exiv26XmpKey4Impl20decomposeKeyUnlockedERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_13XmpProperties7XmpLockE:
 5336|   856k|void XmpKey::Impl::decomposeKeyUnlocked(const std::string& key, const XmpProperties::XmpLock& lock) {
 5337|       |  // Get the family name, prefix and property name parts of the key
 5338|   856k|  if (!key.starts_with(familyName_))
  ------------------
  |  Branch (5338:7): [True: 266, False: 856k]
  ------------------
 5339|    266|    throw Error(ErrorCode::kerInvalidKey, key);
 5340|   856k|  std::string::size_type pos1 = key.find('.');
 5341|   856k|  std::string::size_type pos0 = pos1 + 1;
 5342|   856k|  pos1 = key.find('.', pos0);
 5343|   856k|  if (pos1 == std::string::npos)
  ------------------
  |  Branch (5343:7): [True: 0, False: 856k]
  ------------------
 5344|      0|    throw Error(ErrorCode::kerInvalidKey, key);
 5345|   856k|  std::string prefix = key.substr(pos0, pos1 - pos0);
 5346|   856k|  if (prefix.empty())
  ------------------
  |  Branch (5346:7): [True: 0, False: 856k]
  ------------------
 5347|      0|    throw Error(ErrorCode::kerInvalidKey, key);
 5348|   856k|  std::string property = key.substr(pos1 + 1);
 5349|   856k|  if (property.empty())
  ------------------
  |  Branch (5349:7): [True: 0, False: 856k]
  ------------------
 5350|      0|    throw Error(ErrorCode::kerInvalidKey, key);
 5351|       |
 5352|       |  // Validate prefix unlocked (must hold lock)
 5353|   856k|  if (XmpProperties::nsUnlocked(prefix, lock).empty())
  ------------------
  |  Branch (5353:7): [True: 0, False: 856k]
  ------------------
 5354|      0|    throw Error(ErrorCode::kerNoNamespaceForPrefix, prefix);
 5355|       |
 5356|   856k|  property_ = std::move(property);
 5357|   856k|  prefix_ = std::move(prefix);
 5358|   856k|}  // XmpKey::Impl::decomposeKeyUnlocked
_ZN5Exiv26XmpKey4ImplC2Ev:
 5219|   856k|  Impl() = default;                                                                             //!< Default constructor

_ZN5Exiv28PsdImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
  100|    703|PsdImage::PsdImage(BasicIo::UniquePtr io) : Image(ImageType::psd, mdExif | mdIptc | mdXmp, std::move(io)) {
  101|    703|}  // PsdImage::PsdImage
_ZNK5Exiv28PsdImage8mimeTypeEv:
  103|    948|std::string PsdImage::mimeType() const {
  104|    948|  return "image/x-photoshop";
  105|    948|}
_ZN5Exiv28PsdImage12readMetadataEv:
  112|    693|void PsdImage::readMetadata() {
  113|       |#ifdef EXIV2_DEBUG_MESSAGES
  114|       |  std::cerr << "Exiv2::PsdImage::readMetadata: Reading Photoshop file " << io_->path() << "\n";
  115|       |#endif
  116|    693|  if (io_->open() != 0) {
  ------------------
  |  Branch (116:7): [True: 0, False: 693]
  ------------------
  117|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  118|      0|  }
  119|    693|  IoCloser closer(*io_);
  120|       |  // Ensure that this is the correct image type
  121|    693|  if (!isPsdType(*io_, false)) {
  ------------------
  |  Branch (121:7): [True: 0, False: 693]
  ------------------
  122|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (122:9): [True: 0, False: 0]
  |  Branch (122:25): [True: 0, False: 0]
  ------------------
  123|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  124|      0|    throw Error(ErrorCode::kerNotAnImage, "Photoshop");
  125|      0|  }
  126|    693|  clearMetadata();
  127|       |
  128|       |  /*
  129|       |    The Photoshop header goes as follows -- all numbers are in big-endian byte order:
  130|       |
  131|       |    offset  length   name       description
  132|       |    ======  =======  =========  =========
  133|       |     0      4 bytes  signature  always '8BPS'
  134|       |     4      2 bytes  version    always equal to 1
  135|       |     6      6 bytes  reserved   must be zero
  136|       |    12      2 bytes  channels   number of channels in the image, including alpha channels (1 to 24)
  137|       |    14      4 bytes  rows       the height of the image in pixels
  138|       |    18      4 bytes  columns    the width of the image in pixels
  139|       |    22      2 bytes  depth      the number of bits per channel
  140|       |    24      2 bytes  mode       the color mode of the file; Supported values are: Bitmap=0; Grayscale=1;
  141|       |    Indexed=2; RGB=3; CMYK=4; Multichannel=7; Duotone=8; Lab=9
  142|       |  */
  143|    693|  byte buf[26];
  144|    693|  if (io_->read(buf, 26) != 26) {
  ------------------
  |  Branch (144:7): [True: 0, False: 693]
  ------------------
  145|      0|    throw Error(ErrorCode::kerNotAnImage, "Photoshop");
  146|      0|  }
  147|    693|  pixelWidth_ = getLong(buf + 18, bigEndian);
  148|    693|  pixelHeight_ = getLong(buf + 14, bigEndian);
  149|       |
  150|       |  // immediately following the image header is the color mode data section,
  151|       |  // the first four bytes of which specify the byte size of the whole section
  152|    693|  if (io_->read(buf, 4) != 4) {
  ------------------
  |  Branch (152:7): [True: 0, False: 693]
  ------------------
  153|      0|    throw Error(ErrorCode::kerNotAnImage, "Photoshop");
  154|      0|  }
  155|       |
  156|       |  // skip it
  157|    693|  if (io_->seek(getULong(buf, bigEndian), BasicIo::cur)) {
  ------------------
  |  Branch (157:7): [True: 11, False: 682]
  ------------------
  158|     11|    throw Error(ErrorCode::kerNotAnImage, "Photoshop");
  159|     11|  }
  160|       |
  161|       |  // after the color data section, comes a list of resource blocks, preceded by the total byte size
  162|    682|  if (io_->read(buf, 4) != 4) {
  ------------------
  |  Branch (162:7): [True: 10, False: 672]
  ------------------
  163|     10|    throw Error(ErrorCode::kerNotAnImage, "Photoshop");
  164|     10|  }
  165|    672|  uint32_t resourcesLength = getULong(buf, bigEndian);
  166|    672|  Internal::enforce(resourcesLength < io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  167|       |
  168|  2.03k|  while (resourcesLength > 0) {
  ------------------
  |  Branch (168:10): [True: 1.75k, False: 272]
  ------------------
  169|  1.75k|    Internal::enforce(resourcesLength >= 8, Exiv2::ErrorCode::kerCorruptedMetadata);
  170|  1.75k|    resourcesLength -= 8;
  171|  1.75k|    if (io_->read(buf, 8) != 8) {
  ------------------
  |  Branch (171:9): [True: 35, False: 1.72k]
  ------------------
  172|     35|      throw Error(ErrorCode::kerNotAnImage, "Photoshop");
  173|     35|    }
  174|       |
  175|  1.72k|    if (!Photoshop::isIrb(buf)) {
  ------------------
  |  Branch (175:9): [True: 355, False: 1.36k]
  ------------------
  176|    355|      break;  // bad resource type
  177|    355|    }
  178|  1.36k|    uint16_t resourceId = getUShort(buf + 4, bigEndian);
  179|  1.36k|    uint32_t resourceNameLength = buf[6] & ~1;
  180|       |
  181|       |    // skip the resource name, plus any padding
  182|  1.36k|    Internal::enforce(resourceNameLength <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
  183|  1.36k|    resourcesLength -= resourceNameLength;
  184|  1.36k|    io_->seek(resourceNameLength, BasicIo::cur);
  185|       |
  186|       |    // read resource size
  187|  1.36k|    Internal::enforce(resourcesLength >= 4, Exiv2::ErrorCode::kerCorruptedMetadata);
  188|  1.36k|    resourcesLength -= 4;
  189|  1.36k|    if (io_->read(buf, 4) != 4) {
  ------------------
  |  Branch (189:9): [True: 10, False: 1.35k]
  ------------------
  190|     10|      throw Error(ErrorCode::kerNotAnImage, "Photoshop");
  191|     10|    }
  192|  1.35k|    uint32_t resourceSize = getULong(buf, bigEndian);
  193|  1.35k|    const size_t curOffset = io_->tell();
  194|       |
  195|       |#ifdef EXIV2_DEBUG_MESSAGES
  196|       |    std::cerr << std::hex << "resourceId: " << resourceId << std::dec << " length: " << resourceSize << std::hex
  197|       |              << "\n";
  198|       |#endif
  199|       |
  200|  1.35k|    Internal::enforce(resourceSize <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
  201|  1.35k|    readResourceBlock(resourceId, resourceSize);
  202|  1.35k|    resourceSize = (resourceSize + 1) & ~1;  // pad to even
  203|  1.35k|    Internal::enforce(resourceSize <= resourcesLength, Exiv2::ErrorCode::kerCorruptedMetadata);
  204|  1.35k|    resourcesLength -= resourceSize;
  205|  1.35k|    io_->seek(curOffset + resourceSize, BasicIo::beg);
  206|  1.35k|  }
  207|       |
  208|    672|}  // PsdImage::readMetadata
_ZN5Exiv28PsdImage17readResourceBlockEtj:
  210|  1.29k|void PsdImage::readResourceBlock(uint16_t resourceId, uint32_t resourceSize) {
  211|  1.29k|  switch (resourceId) {
  212|    114|    case kPhotoshopResourceID::IPTC_NAA: {
  ------------------
  |  Branch (212:5): [True: 114, False: 1.17k]
  ------------------
  213|    114|      DataBuf rawIPTC(resourceSize);
  214|    114|      io_->read(rawIPTC.data(), rawIPTC.size());
  215|    114|      if (io_->error() || io_->eof())
  ------------------
  |  Branch (215:11): [True: 0, False: 114]
  |  Branch (215:27): [True: 11, False: 103]
  ------------------
  216|     11|        throw Error(ErrorCode::kerFailedToReadImageData);
  217|    103|      if (IptcParser::decode(iptcData_, rawIPTC.c_data(), rawIPTC.size())) {
  ------------------
  |  Branch (217:11): [True: 48, False: 55]
  ------------------
  218|     48|#ifndef SUPPRESS_WARNINGS
  219|     48|        EXV_WARNING << "Failed to decode IPTC metadata.\n";
  ------------------
  |  |  138|     48|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 48]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     48|  LogMsg(LogMsg::warn).os()
  ------------------
  220|     48|#endif
  221|     48|        iptcData_.clear();
  222|     48|      }
  223|    103|      break;
  224|    114|    }
  225|       |
  226|    102|    case kPhotoshopResourceID::ExifInfo: {
  ------------------
  |  Branch (226:5): [True: 102, False: 1.19k]
  ------------------
  227|    102|      DataBuf rawExif(resourceSize);
  228|    102|      io_->read(rawExif.data(), rawExif.size());
  229|    102|      if (io_->error() || io_->eof())
  ------------------
  |  Branch (229:11): [True: 0, False: 102]
  |  Branch (229:27): [True: 10, False: 92]
  ------------------
  230|     10|        throw Error(ErrorCode::kerFailedToReadImageData);
  231|     92|      ByteOrder bo = ExifParser::decode(exifData_, rawExif.c_data(), rawExif.size());
  232|     92|      setByteOrder(bo);
  233|     92|      if (!rawExif.empty() && byteOrder() == invalidByteOrder) {
  ------------------
  |  Branch (233:11): [True: 8, False: 84]
  |  Branch (233:31): [True: 0, False: 8]
  ------------------
  234|      0|#ifndef SUPPRESS_WARNINGS
  235|      0|        EXV_WARNING << "Failed to decode Exif metadata.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  236|      0|#endif
  237|      0|        exifData_.clear();
  238|      0|      }
  239|     92|      break;
  240|    102|    }
  241|       |
  242|     64|    case kPhotoshopResourceID::XMPPacket: {
  ------------------
  |  Branch (242:5): [True: 64, False: 1.22k]
  ------------------
  243|     64|      DataBuf xmpPacket(resourceSize);
  244|     64|      io_->read(xmpPacket.data(), xmpPacket.size());
  245|     64|      if (io_->error() || io_->eof())
  ------------------
  |  Branch (245:11): [True: 0, False: 64]
  |  Branch (245:27): [True: 6, False: 58]
  ------------------
  246|      6|        throw Error(ErrorCode::kerFailedToReadImageData);
  247|     58|      xmpPacket_.assign(xmpPacket.c_str(), xmpPacket.size());
  248|     58|      if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) {
  ------------------
  |  Branch (248:11): [True: 35, False: 23]
  |  Branch (248:34): [True: 35, False: 0]
  ------------------
  249|     35|#ifndef SUPPRESS_WARNINGS
  250|     35|        EXV_WARNING << "Failed to decode XMP metadata.\n";
  ------------------
  |  |  138|     35|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 35]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     35|  LogMsg(LogMsg::warn).os()
  ------------------
  251|     35|#endif
  252|     35|      }
  253|     58|      break;
  254|     64|    }
  255|       |
  256|       |    // - PS 4.0 preview data is fetched from ThumbnailResource
  257|       |    // - PS >= 5.0 preview data is fetched from ThumbnailResource2
  258|    879|    case kPhotoshopResourceID::ThumbnailResource:
  ------------------
  |  Branch (258:5): [True: 879, False: 414]
  ------------------
  259|    916|    case kPhotoshopResourceID::ThumbnailResource2: {
  ------------------
  |  Branch (259:5): [True: 37, False: 1.25k]
  ------------------
  260|       |      /*
  261|       |        Photoshop thumbnail resource header
  262|       |
  263|       |        offset  length    name            description
  264|       |        ======  ========  ====            ===========
  265|       |         0      4 bytes   format          = 1 (kJpegRGB). Also supports kRawRGB (0).
  266|       |         4      4 bytes   width           Width of thumbnail in pixels.
  267|       |         8      4 bytes   height          Height of thumbnail in pixels.
  268|       |        12      4 bytes   widthbytes      Padded row bytes as (width * bitspixel + 31) / 32 * 4.
  269|       |        16      4 bytes   size            Total size as widthbytes * height * planes
  270|       |        20      4 bytes   compressedsize  Size after compression. Used for consistency check.
  271|       |        24      2 bytes   bitspixel       = 24. Bits per pixel.
  272|       |        26      2 bytes   planes          = 1. Number of planes.
  273|       |        28      variable  data            JFIF data in RGB format.
  274|       |                                          Note: For resource ID 1033 the data is in BGR format.
  275|       |      */
  276|    916|      byte buf[28];
  277|    916|      if (io_->read(buf, 28) != 28) {
  ------------------
  |  Branch (277:11): [True: 9, False: 907]
  ------------------
  278|      9|        throw Error(ErrorCode::kerNotAnImage, "Photoshop");
  279|      9|      }
  280|    907|      NativePreview nativePreview;
  281|    907|      nativePreview.position_ = io_->tell();
  282|    907|      nativePreview.size_ = getLong(buf + 20, bigEndian);  // compressedsize
  283|    907|      nativePreview.width_ = getLong(buf + 4, bigEndian);
  284|    907|      nativePreview.height_ = getLong(buf + 8, bigEndian);
  285|    907|      const uint32_t format = getLong(buf + 0, bigEndian);
  286|       |
  287|    907|      Internal::enforce(nativePreview.size_ <= static_cast<size_t>(std::numeric_limits<long>::max()),
  288|    907|                        Exiv2::ErrorCode::kerCorruptedMetadata);
  289|       |
  290|    907|      if (nativePreview.size_ > 0 && nativePreview.position_ > 0) {
  ------------------
  |  Branch (290:11): [True: 813, False: 94]
  |  Branch (290:38): [True: 813, False: 0]
  ------------------
  291|    813|        io_->seek(static_cast<long>(nativePreview.size_), BasicIo::cur);
  292|    813|        if (io_->error() || io_->eof())
  ------------------
  |  Branch (292:13): [True: 0, False: 813]
  |  Branch (292:29): [True: 44, False: 769]
  ------------------
  293|     44|          throw Error(ErrorCode::kerFailedToReadImageData);
  294|       |
  295|       |        // unsupported format of native preview
  296|    769|        if (format != 1)
  ------------------
  |  Branch (296:13): [True: 48, False: 721]
  ------------------
  297|     48|          break;
  298|    721|        nativePreview.filter_ = "";
  299|    721|        nativePreview.mimeType_ = "image/jpeg";
  300|    721|        nativePreviews_.push_back(std::move(nativePreview));
  301|    721|      }
  302|    815|      break;
  303|    907|    }
  304|       |
  305|    815|    default:
  ------------------
  |  Branch (305:5): [True: 97, False: 1.19k]
  ------------------
  306|     97|      break;
  307|  1.29k|  }
  308|  1.29k|}  // PsdImage::readResourceBlock
_ZN5Exiv214newPsdInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  674|    703|Image::UniquePtr newPsdInstance(BasicIo::UniquePtr io, bool /*create*/) {
  675|    703|  auto image = std::make_unique<PsdImage>(std::move(io));
  676|    703|  if (!image->good()) {
  ------------------
  |  Branch (676:7): [True: 10, False: 693]
  ------------------
  677|     10|    return nullptr;
  678|     10|  }
  679|    693|  return image;
  680|    703|}
_ZN5Exiv29isPsdTypeERNS_7BasicIoEb:
  682|  16.6k|bool isPsdType(BasicIo& iIo, bool advance) {
  683|  16.6k|  const int32_t len = 6;
  684|  16.6k|  const std::array<byte, len> PsdHeader{'8', 'B', 'P', 'S', 0, 1};
  685|  16.6k|  std::array<byte, len> buf;
  686|  16.6k|  iIo.read(buf.data(), len);
  687|  16.6k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (687:7): [True: 0, False: 16.6k]
  |  Branch (687:22): [True: 330, False: 16.3k]
  ------------------
  688|    330|    return false;
  689|    330|  }
  690|  16.3k|  bool matched = buf == PsdHeader;
  691|  16.3k|  if (!advance || !matched) {
  ------------------
  |  Branch (691:7): [True: 16.3k, False: 0]
  |  Branch (691:19): [True: 0, False: 0]
  ------------------
  692|  16.3k|    iIo.seek(-len, BasicIo::cur);
  693|  16.3k|  }
  694|       |
  695|  16.3k|  return matched;
  696|  16.6k|}

_ZN5Exiv214QuickTimeVideoC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEm:
  540|  4.09k|    Image(ImageType::qtime, mdNone, std::move(io)),
  541|  4.09k|    mvhdTimeScale_(1),
  542|  4.09k|    mdhdTimeScale_(1),
  543|  4.09k|    currentStream_(Null),
  544|  4.09k|    max_recursion_depth_(max_recursion_depth) {
  545|  4.09k|}  // QuickTimeVideo::QuickTimeVideo
_ZNK5Exiv214QuickTimeVideo8mimeTypeEv:
  547|  5.24k|std::string QuickTimeVideo::mimeType() const {
  548|  5.24k|  return "video/quicktime";
  549|  5.24k|}
_ZN5Exiv214QuickTimeVideo12readMetadataEv:
  554|  4.07k|void QuickTimeVideo::readMetadata() {
  555|  4.07k|  if (io_->open() != 0)
  ------------------
  |  Branch (555:7): [True: 0, False: 4.07k]
  ------------------
  556|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  557|       |
  558|       |  // Ensure that this is the correct image type
  559|  4.07k|  if (!isQTimeType(*io_, false)) {
  ------------------
  |  Branch (559:7): [True: 0, False: 4.07k]
  ------------------
  560|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (560:9): [True: 0, False: 0]
  |  Branch (560:25): [True: 0, False: 0]
  ------------------
  561|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  562|      0|    throw Error(ErrorCode::kerNotAnImage, "QuickTime");
  563|      0|  }
  564|       |
  565|  4.07k|  IoCloser closer(*io_);
  566|  4.07k|  clearMetadata();
  567|  4.07k|  continueTraversing_ = true;
  568|  4.07k|  height_ = width_ = 1;
  569|       |
  570|  4.07k|  xmpData_["Xmp.video.FileSize"] = static_cast<double>(io_->size()) / 1048576.0;
  571|  4.07k|  xmpData_["Xmp.video.MimeType"] = mimeType();
  572|       |
  573|  46.3k|  while (continueTraversing_)
  ------------------
  |  Branch (573:10): [True: 42.2k, False: 4.07k]
  ------------------
  574|  42.2k|    decodeBlock(0);
  575|       |
  576|  4.07k|  xmpData_["Xmp.video.AspectRatio"] = getAspectRatio(width_, height_);
  577|  4.07k|}  // QuickTimeVideo::readMetadata
_ZN5Exiv214QuickTimeVideo11decodeBlockEmRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  579|   408k|void QuickTimeVideo::decodeBlock(size_t recursion_depth, std::string const& entered_from) {
  580|   408k|  enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata);
  581|       |
  582|   408k|  const long bufMinSize = 4;
  583|   408k|  DataBuf buf(bufMinSize + 1);
  584|   408k|  uint64_t size = 0;
  585|   408k|  buf.data()[4] = '\0';
  586|       |
  587|   408k|  io_->read(buf.data(), 4);
  588|   408k|  if (io_->eof()) {
  ------------------
  |  Branch (588:7): [True: 404, False: 408k]
  ------------------
  589|    404|    continueTraversing_ = false;
  590|    404|    return;
  591|    404|  }
  592|       |
  593|   408k|  size = buf.read_uint32(0, bigEndian);
  594|       |
  595|   408k|  io_->readOrThrow(buf.data(), 4);
  596|       |
  597|       |  // we have read 2x 4 bytes
  598|   408k|  size_t hdrsize = 8;
  599|       |
  600|   408k|  if (size == 1) {
  ------------------
  |  Branch (600:7): [True: 149, False: 408k]
  ------------------
  601|       |    // The box size is encoded as a uint64_t, so we need to read another 8 bytes.
  602|    149|    DataBuf data(8);
  603|    149|    hdrsize += 8;
  604|    149|    io_->readOrThrow(data.data(), data.size());
  605|    149|    size = data.read_uint64(0, bigEndian);
  606|   408k|  } else if (size == 0 && entered_from == "meta") {
  ------------------
  |  Branch (606:14): [True: 446, False: 407k]
  |  Branch (606:27): [True: 329, False: 117]
  ------------------
  607|    329|    size = buf.read_uint32(0, bigEndian);
  608|    329|    io_->readOrThrow(buf.data(), 4, Exiv2::ErrorCode::kerCorruptedMetadata);
  609|    329|  }
  610|       |
  611|   408k|  enforce(size >= hdrsize, Exiv2::ErrorCode::kerCorruptedMetadata);
  612|   408k|  enforce(size - hdrsize <= io_->size() - io_->tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
  613|   408k|  enforce(size - hdrsize <= std::numeric_limits<size_t>::max(), Exiv2::ErrorCode::kerCorruptedMetadata);
  614|       |
  615|       |  // std::cerr<<"Tag=>"<<buf.data()<<"     size=>"<<size-hdrsize << '\n';
  616|   408k|  const auto newsize = static_cast<size_t>(size - hdrsize);
  617|   408k|  if (ignoreList(buf)) {
  ------------------
  |  Branch (617:7): [True: 1.22k, False: 407k]
  ------------------
  618|  1.22k|    discard(newsize);
  619|  1.22k|    return;
  620|  1.22k|  }
  621|   407k|  if (newsize > buf.size()) {
  ------------------
  |  Branch (621:7): [True: 386k, False: 20.9k]
  ------------------
  622|   386k|    buf.resize(newsize);
  623|   386k|  }
  624|   407k|  tagDecoder(buf, newsize, recursion_depth + 1);
  625|   407k|}  // QuickTimeVideo::decodeBlock
_ZN5Exiv214QuickTimeVideo10tagDecoderERNS_7DataBufEmm:
  635|   742k|void QuickTimeVideo::tagDecoder(Exiv2::DataBuf& buf, size_t size, size_t recursion_depth) {
  636|   742k|  enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata);
  637|   742k|  assert(buf.size() > 4);
  638|       |
  639|   742k|  if (ignoreList(buf))
  ------------------
  |  Branch (639:7): [True: 0, False: 742k]
  ------------------
  640|      0|    discard(size);
  641|       |
  642|   742k|  else if (dataIgnoreList(buf)) {
  ------------------
  |  Branch (642:12): [True: 362k, False: 380k]
  ------------------
  643|   362k|    decodeBlock(recursion_depth + 1, Exiv2::toString(buf.data()));
  644|   380k|  } else if (equalsQTimeTag(buf, "ftyp"))
  ------------------
  |  Branch (644:14): [True: 12.2k, False: 368k]
  ------------------
  645|  12.2k|    fileTypeDecoder(size);
  646|       |
  647|   368k|  else if (equalsQTimeTag(buf, "trak"))
  ------------------
  |  Branch (647:12): [True: 2.65k, False: 365k]
  ------------------
  648|  2.65k|    setMediaStream();
  649|       |
  650|   365k|  else if (equalsQTimeTag(buf, "mvhd"))
  ------------------
  |  Branch (650:12): [True: 215, False: 365k]
  ------------------
  651|    215|    movieHeaderDecoder(size);
  652|       |
  653|   365k|  else if (equalsQTimeTag(buf, "tkhd"))
  ------------------
  |  Branch (653:12): [True: 750, False: 364k]
  ------------------
  654|    750|    trackHeaderDecoder(size);
  655|       |
  656|   364k|  else if (equalsQTimeTag(buf, "mdhd"))
  ------------------
  |  Branch (656:12): [True: 1.25k, False: 363k]
  ------------------
  657|  1.25k|    mediaHeaderDecoder(size);
  658|       |
  659|   363k|  else if (equalsQTimeTag(buf, "hdlr"))
  ------------------
  |  Branch (659:12): [True: 2.17k, False: 361k]
  ------------------
  660|  2.17k|    handlerDecoder(size);
  661|       |
  662|   361k|  else if (equalsQTimeTag(buf, "vmhd"))
  ------------------
  |  Branch (662:12): [True: 5.23k, False: 355k]
  ------------------
  663|  5.23k|    videoHeaderDecoder(size);
  664|       |
  665|   355k|  else if (equalsQTimeTag(buf, "udta"))
  ------------------
  |  Branch (665:12): [True: 301k, False: 54.6k]
  ------------------
  666|   301k|    userDataDecoder(size, recursion_depth + 1);
  667|       |
  668|  54.6k|  else if (equalsQTimeTag(buf, "dref"))
  ------------------
  |  Branch (668:12): [True: 1.95k, False: 52.7k]
  ------------------
  669|  1.95k|    multipleEntriesDecoder(recursion_depth + 1);
  670|       |
  671|  52.7k|  else if (equalsQTimeTag(buf, "stsd"))
  ------------------
  |  Branch (671:12): [True: 1.94k, False: 50.7k]
  ------------------
  672|  1.94k|    sampleDesc(size);
  673|       |
  674|  50.7k|  else if (equalsQTimeTag(buf, "stts"))
  ------------------
  |  Branch (674:12): [True: 930, False: 49.8k]
  ------------------
  675|    930|    timeToSampleDecoder();
  676|       |
  677|  49.8k|  else if (equalsQTimeTag(buf, "pnot"))
  ------------------
  |  Branch (677:12): [True: 653, False: 49.2k]
  ------------------
  678|    653|    previewTagDecoder(size);
  679|       |
  680|  49.2k|  else if (equalsQTimeTag(buf, "tapt"))
  ------------------
  |  Branch (680:12): [True: 1.10k, False: 48.0k]
  ------------------
  681|  1.10k|    trackApertureTagDecoder(size);
  682|       |
  683|  48.0k|  else if (equalsQTimeTag(buf, "keys"))
  ------------------
  |  Branch (683:12): [True: 393, False: 47.7k]
  ------------------
  684|    393|    keysTagDecoder(size);
  685|       |
  686|  47.7k|  else if (equalsQTimeTag(buf, "url ")) {
  ------------------
  |  Branch (686:12): [True: 365, False: 47.3k]
  ------------------
  687|    365|    if (currentStream_ == Video)
  ------------------
  |  Branch (687:9): [True: 105, False: 260]
  ------------------
  688|    105|      xmpData_["Xmp.video.URL"] = readString(*io_, size);
  689|    260|    else if (currentStream_ == Audio)
  ------------------
  |  Branch (689:14): [True: 48, False: 212]
  ------------------
  690|     48|      xmpData_["Xmp.audio.URL"] = readString(*io_, size);
  691|    212|    else
  692|    212|      discard(size);
  693|    365|  }
  694|       |
  695|  47.3k|  else if (equalsQTimeTag(buf, "urn ")) {
  ------------------
  |  Branch (695:12): [True: 605, False: 46.7k]
  ------------------
  696|    605|    if (currentStream_ == Video)
  ------------------
  |  Branch (696:9): [True: 242, False: 363]
  ------------------
  697|    242|      xmpData_["Xmp.video.URN"] = readString(*io_, size);
  698|    363|    else if (currentStream_ == Audio)
  ------------------
  |  Branch (698:14): [True: 102, False: 261]
  ------------------
  699|    102|      xmpData_["Xmp.audio.URN"] = readString(*io_, size);
  700|    261|    else
  701|    261|      discard(size);
  702|    605|  }
  703|       |
  704|  46.7k|  else if (equalsQTimeTag(buf, "dcom")) {
  ------------------
  |  Branch (704:12): [True: 156, False: 46.5k]
  ------------------
  705|    156|    xmpData_["Xmp.video.Compressor"] = readString(*io_, size);
  706|    156|  }
  707|       |
  708|  46.5k|  else if (equalsQTimeTag(buf, "smhd")) {
  ------------------
  |  Branch (708:12): [True: 33, False: 46.5k]
  ------------------
  709|     33|    io_->readOrThrow(buf.data(), 4);
  710|     33|    io_->readOrThrow(buf.data(), 4);
  711|     33|    xmpData_["Xmp.audio.Balance"] = buf.read_uint16(0, bigEndian);
  712|     33|  }
  713|       |
  714|  46.5k|  else {
  715|  46.5k|    discard(size);
  716|  46.5k|  }
  717|   742k|}  // QuickTimeVideo::tagDecoder
_ZN5Exiv214QuickTimeVideo7discardEm:
  719|  48.2k|void QuickTimeVideo::discard(size_t size) {
  720|  48.2k|  size_t cur_pos = io_->tell();
  721|  48.2k|  io_->seek(cur_pos + size, BasicIo::beg);
  722|  48.2k|}  // QuickTimeVideo::discard
_ZN5Exiv214QuickTimeVideo17previewTagDecoderEm:
  724|    653|void QuickTimeVideo::previewTagDecoder(size_t size) {
  725|    653|  DataBuf buf(4);
  726|    653|  size_t cur_pos = io_->tell();
  727|    653|  io_->readOrThrow(buf.data(), 4);
  728|    653|  xmpData_["Xmp.video.PreviewDate"] = buf.read_uint32(0, bigEndian);
  729|    653|  io_->readOrThrow(buf.data(), 2);
  730|    653|  xmpData_["Xmp.video.PreviewVersion"] = getShort(buf.data(), bigEndian);
  731|       |
  732|    653|  io_->readOrThrow(buf.data(), 4);
  733|    653|  if (equalsQTimeTag(buf, "PICT"))
  ------------------
  |  Branch (733:7): [True: 10, False: 643]
  ------------------
  734|     10|    xmpData_["Xmp.video.PreviewAtomType"] = "QuickDraw Picture";
  735|    643|  else
  736|    643|    xmpData_["Xmp.video.PreviewAtomType"] = std::string{buf.c_str(), 4};
  737|       |
  738|    653|  io_->seek(cur_pos + size, BasicIo::beg);
  739|    653|}  // QuickTimeVideo::previewTagDecoder
_ZN5Exiv214QuickTimeVideo14keysTagDecoderEm:
  741|    393|void QuickTimeVideo::keysTagDecoder(size_t size) {
  742|    393|  DataBuf buf(4);
  743|    393|  size_t cur_pos = io_->tell();
  744|    393|  io_->readOrThrow(buf.data(), 4);
  745|    393|  xmpData_["Xmp.video.PreviewDate"] = buf.read_uint32(0, bigEndian);
  746|    393|  io_->readOrThrow(buf.data(), 2);
  747|    393|  xmpData_["Xmp.video.PreviewVersion"] = getShort(buf.data(), bigEndian);
  748|       |
  749|    393|  io_->readOrThrow(buf.data(), 4);
  750|    393|  if (equalsQTimeTag(buf, "PICT"))
  ------------------
  |  Branch (750:7): [True: 21, False: 372]
  ------------------
  751|     21|    xmpData_["Xmp.video.PreviewAtomType"] = "QuickDraw Picture";
  752|    372|  else
  753|    372|    xmpData_["Xmp.video.PreviewAtomType"] = std::string{buf.c_str(), 4};
  754|       |
  755|    393|  io_->seek(cur_pos + size, BasicIo::beg);
  756|    393|}  // QuickTimeVideo::keysTagDecoder
_ZN5Exiv214QuickTimeVideo23trackApertureTagDecoderEm:
  758|  1.10k|void QuickTimeVideo::trackApertureTagDecoder(size_t size) {
  759|  1.10k|  DataBuf buf(4);
  760|  1.10k|  DataBuf buf2(2);
  761|  1.10k|  size_t cur_pos = io_->tell();
  762|  1.10k|  byte n = 3;
  763|       |
  764|  4.42k|  while (n--) {
  ------------------
  |  Branch (764:10): [True: 3.31k, False: 1.10k]
  ------------------
  765|  3.31k|    io_->seek(4L, BasicIo::cur);
  766|  3.31k|    io_->readOrThrow(buf.data(), 4);
  767|       |
  768|  3.31k|    if (equalsQTimeTag(buf, "clef")) {
  ------------------
  |  Branch (768:9): [True: 497, False: 2.82k]
  ------------------
  769|    497|      io_->seek(4L, BasicIo::cur);
  770|    497|      io_->readOrThrow(buf.data(), 2);
  771|    497|      io_->readOrThrow(buf2.data(), 2);
  772|    497|      xmpData_["Xmp.video.CleanApertureWidth"] =
  773|    497|          stringFormat("{}.{}", buf.read_uint16(0, bigEndian), buf2.read_uint16(0, bigEndian));
  ------------------
  |  |   18|    497|#define stringFormat std::format
  ------------------
  774|    497|      io_->readOrThrow(buf.data(), 2);
  775|    497|      io_->readOrThrow(buf2.data(), 2);
  776|    497|      xmpData_["Xmp.video.CleanApertureHeight"] =
  777|    497|          stringFormat("{}.{}", buf.read_uint16(0, bigEndian), buf2.read_uint16(0, bigEndian));
  ------------------
  |  |   18|    497|#define stringFormat std::format
  ------------------
  778|    497|    }
  779|       |
  780|  2.82k|    else if (equalsQTimeTag(buf, "prof")) {
  ------------------
  |  Branch (780:14): [True: 81, False: 2.74k]
  ------------------
  781|     81|      io_->seek(4L, BasicIo::cur);
  782|     81|      io_->readOrThrow(buf.data(), 2);
  783|     81|      io_->readOrThrow(buf2.data(), 2);
  784|     81|      xmpData_["Xmp.video.ProductionApertureWidth"] =
  785|     81|          stringFormat("{}.{}", buf.read_uint16(0, bigEndian), buf2.read_uint16(0, bigEndian));
  ------------------
  |  |   18|     81|#define stringFormat std::format
  ------------------
  786|     81|      io_->readOrThrow(buf.data(), 2);
  787|     81|      io_->readOrThrow(buf2.data(), 2);
  788|     81|      xmpData_["Xmp.video.ProductionApertureHeight"] =
  789|     81|          stringFormat("{}.{}", buf.read_uint16(0, bigEndian), buf2.read_uint16(0, bigEndian));
  ------------------
  |  |   18|     81|#define stringFormat std::format
  ------------------
  790|     81|    }
  791|       |
  792|  2.74k|    else if (equalsQTimeTag(buf, "enof")) {
  ------------------
  |  Branch (792:14): [True: 18, False: 2.72k]
  ------------------
  793|     18|      io_->seek(4L, BasicIo::cur);
  794|     18|      io_->readOrThrow(buf.data(), 2);
  795|     18|      io_->readOrThrow(buf2.data(), 2);
  796|     18|      xmpData_["Xmp.video.EncodedPixelsWidth"] =
  797|     18|          stringFormat("{}.{}", buf.read_uint16(0, bigEndian), buf2.read_uint16(0, bigEndian));
  ------------------
  |  |   18|     18|#define stringFormat std::format
  ------------------
  798|     18|      io_->readOrThrow(buf.data(), 2);
  799|     18|      io_->readOrThrow(buf2.data(), 2);
  800|     18|      xmpData_["Xmp.video.EncodedPixelsHeight"] =
  801|     18|          stringFormat("{}.{}", buf.read_uint16(0, bigEndian), buf2.read_uint16(0, bigEndian));
  ------------------
  |  |   18|     18|#define stringFormat std::format
  ------------------
  802|     18|    }
  803|  3.31k|  }
  804|  1.10k|  io_->seek(cur_pos + size, BasicIo::beg);
  805|  1.10k|}  // QuickTimeVideo::trackApertureTagDecoder
_ZN5Exiv214QuickTimeVideo17CameraTagsDecoderEm:
  807|  4.12k|void QuickTimeVideo::CameraTagsDecoder(size_t size) {
  808|  4.12k|  size_t cur_pos = io_->tell();
  809|  4.12k|  DataBuf buf(50);
  810|  4.12k|  DataBuf buf2(4);
  811|       |
  812|  4.12k|  io_->readOrThrow(buf.data(), 4);
  813|  4.12k|  if (equalsQTimeTag(buf, "NIKO")) {
  ------------------
  |  Branch (813:7): [True: 3.08k, False: 1.03k]
  ------------------
  814|  3.08k|    io_->seek(cur_pos, BasicIo::beg);
  815|       |
  816|  3.08k|    io_->readOrThrow(buf.data(), 24);
  817|  3.08k|    xmpData_["Xmp.video.Make"] = buf.data();
  818|  3.08k|    io_->readOrThrow(buf.data(), 14);
  819|  3.08k|    xmpData_["Xmp.video.Model"] = buf.data();
  820|  3.08k|    io_->readOrThrow(buf.data(), 4);
  821|  3.08k|    xmpData_["Xmp.video.ExposureTime"] = stringFormat("1/{}", std::ceil(buf.read_uint32(0, littleEndian) / 10.0));
  ------------------
  |  |   18|  3.08k|#define stringFormat std::format
  ------------------
  822|  3.08k|    io_->readOrThrow(buf.data(), 4);
  823|  3.08k|    io_->readOrThrow(buf2.data(), 4);
  824|  3.08k|    xmpData_["Xmp.video.FNumber"] =
  825|  3.08k|        buf.read_uint32(0, littleEndian) / static_cast<double>(buf2.read_uint32(0, littleEndian));
  826|  3.08k|    io_->readOrThrow(buf.data(), 4);
  827|  3.08k|    io_->readOrThrow(buf2.data(), 4);
  828|  3.08k|    xmpData_["Xmp.video.ExposureCompensation"] =
  829|  3.08k|        buf.read_uint32(0, littleEndian) / static_cast<double>(buf2.read_uint32(0, littleEndian));
  830|  3.08k|    io_->readOrThrow(buf.data(), 10);
  831|  3.08k|    io_->readOrThrow(buf.data(), 4);
  832|  3.08k|    if (auto td = Exiv2::find(whiteBalance, buf.read_uint32(0, littleEndian)))
  ------------------
  |  Branch (832:14): [True: 2.11k, False: 973]
  ------------------
  833|  2.11k|      xmpData_["Xmp.video.WhiteBalance"] = _(td->label_);
  ------------------
  |  |   40|  2.11k|#define _(String) (String)
  ------------------
  834|  3.08k|    io_->readOrThrow(buf.data(), 4);
  835|  3.08k|    io_->readOrThrow(buf2.data(), 4);
  836|  3.08k|    xmpData_["Xmp.video.FocalLength"] =
  837|  3.08k|        buf.read_uint32(0, littleEndian) / static_cast<double>(buf2.read_uint32(0, littleEndian));
  838|  3.08k|    io_->seek(95L, BasicIo::cur);
  839|  3.08k|    io_->readOrThrow(buf.data(), 48);
  840|  3.08k|    buf.write_uint8(48, 0);
  841|  3.08k|    xmpData_["Xmp.video.Software"] = buf.data();
  842|  3.08k|    io_->readOrThrow(buf.data(), 4);
  843|  3.08k|    xmpData_["Xmp.video.ISO"] = buf.read_uint32(0, littleEndian);
  844|  3.08k|  }
  845|       |
  846|  4.12k|  io_->seek(cur_pos + size, BasicIo::beg);
  847|  4.12k|}  // QuickTimeVideo::CameraTagsDecoder
_ZN5Exiv214QuickTimeVideo15userDataDecoderEmm:
  849|   301k|void QuickTimeVideo::userDataDecoder(size_t outer_size, size_t recursion_depth) {
  850|   301k|  enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata);
  851|   301k|  size_t cur_pos = io_->tell();
  852|   301k|  const TagVocabulary* td;
  853|   301k|  const TagVocabulary* tv;
  854|   301k|  const TagVocabulary* tv_internal;
  855|       |
  856|   301k|  const long bufMinSize = 100;
  857|   301k|  DataBuf buf(bufMinSize);
  858|   301k|  size_t size_internal = outer_size;
  859|   301k|  std::memset(buf.data(), 0x0, buf.size());
  860|       |
  861|   678k|  while ((size_internal / 4 != 0) && (size_internal > 0)) {
  ------------------
  |  Branch (861:10): [True: 669k, False: 8.93k]
  |  Branch (861:38): [True: 669k, False: 0]
  ------------------
  862|   669k|    buf.data()[4] = '\0';
  863|   669k|    io_->readOrThrow(buf.data(), 4);
  864|   669k|    const size_t size = buf.read_uint32(0, bigEndian);
  865|   669k|    if (size > size_internal)
  ------------------
  |  Branch (865:9): [True: 287k, False: 381k]
  ------------------
  866|   287k|      break;
  867|   381k|    size_internal -= size;
  868|   381k|    io_->readOrThrow(buf.data(), 4);
  869|       |
  870|   381k|    if (buf.data()[0] == 169)
  ------------------
  |  Branch (870:9): [True: 194, False: 381k]
  ------------------
  871|    194|      buf.data()[0] = ' ';
  872|   381k|    td = Exiv2::find(userDatatags, Exiv2::toString(buf.data()));
  873|       |
  874|   381k|    tv = Exiv2::find(userDataReferencetags, Exiv2::toString(buf.data()));
  875|       |
  876|   381k|    if (size <= 12)
  ------------------
  |  Branch (876:9): [True: 4.55k, False: 376k]
  ------------------
  877|  4.55k|      break;
  878|       |
  879|   376k|    if (equalsQTimeTag(buf, "DcMD") || equalsQTimeTag(buf, "NCDT"))
  ------------------
  |  Branch (879:9): [True: 81, False: 376k]
  |  Branch (879:40): [True: 195, False: 376k]
  ------------------
  880|    261|      userDataDecoder(size - 8, recursion_depth + 1);
  881|       |
  882|   376k|    else if (equalsQTimeTag(buf, "NCTG"))
  ------------------
  |  Branch (882:14): [True: 8.03k, False: 368k]
  ------------------
  883|  8.03k|      NikonTagsDecoder(size - 8);
  884|       |
  885|   368k|    else if (equalsQTimeTag(buf, "TAGS"))
  ------------------
  |  Branch (885:14): [True: 4.12k, False: 364k]
  ------------------
  886|  4.12k|      CameraTagsDecoder(size - 8);
  887|       |
  888|   364k|    else if (equalsQTimeTag(buf, "CNCV") || equalsQTimeTag(buf, "CNFV") || equalsQTimeTag(buf, "CNMN") ||
  ------------------
  |  Branch (888:14): [True: 633, False: 363k]
  |  Branch (888:45): [True: 393, False: 363k]
  |  Branch (888:76): [True: 239, False: 363k]
  ------------------
  889|   363k|             equalsQTimeTag(buf, "NCHD") || equalsQTimeTag(buf, "FFMV")) {
  ------------------
  |  Branch (889:14): [True: 224, False: 362k]
  |  Branch (889:45): [True: 196, False: 362k]
  ------------------
  890|  1.67k|      enforce(tv, Exiv2::ErrorCode::kerCorruptedMetadata);
  891|  1.67k|      xmpData_[_(tv->label_)] = readString(*io_, size - 8);
  ------------------
  |  |   40|  1.67k|#define _(String) (String)
  ------------------
  892|  1.67k|    }
  893|       |
  894|   362k|    else if (equalsQTimeTag(buf, "CMbo") || equalsQTimeTag(buf, "Cmbo")) {
  ------------------
  |  Branch (894:14): [True: 576, False: 362k]
  |  Branch (894:45): [True: 0, False: 362k]
  ------------------
  895|    561|      enforce(tv, Exiv2::ErrorCode::kerCorruptedMetadata);
  896|    561|      io_->readOrThrow(buf.data(), 2);
  897|    561|      buf.data()[2] = '\0';
  898|    561|      tv_internal = Exiv2::find(cameraByteOrderTags, Exiv2::toString(buf.data()));
  899|       |
  900|    561|      if (tv_internal)
  ------------------
  |  Branch (900:11): [True: 310, False: 251]
  ------------------
  901|    310|        xmpData_[_(tv->label_)] = _(tv_internal->label_);
  ------------------
  |  |   40|    310|#define _(String) (String)
  ------------------
                      xmpData_[_(tv->label_)] = _(tv_internal->label_);
  ------------------
  |  |   40|    310|#define _(String) (String)
  ------------------
  902|    251|      else
  903|    251|        xmpData_[_(tv->label_)] = buf.data();
  ------------------
  |  |   40|    251|#define _(String) (String)
  ------------------
  904|    561|    }
  905|       |
  906|   362k|    else if (tv) {
  ------------------
  |  Branch (906:14): [True: 754, False: 361k]
  ------------------
  907|    754|      io_->readOrThrow(buf.data(), 4);
  908|    754|      xmpData_[_(tv->label_)] = readString(*io_, size - 12);
  ------------------
  |  |   40|    754|#define _(String) (String)
  ------------------
  909|    754|    }
  910|       |
  911|   361k|    else if (td)
  ------------------
  |  Branch (911:14): [True: 337k, False: 23.7k]
  ------------------
  912|   337k|      tagDecoder(buf, size - 8, recursion_depth + 1);
  913|   376k|  }
  914|       |
  915|   301k|  io_->seek(cur_pos + outer_size, BasicIo::beg);
  916|   301k|}  // QuickTimeVideo::userDataDecoder
_ZN5Exiv214QuickTimeVideo16NikonTagsDecoderEm:
  918|  8.03k|void QuickTimeVideo::NikonTagsDecoder(size_t size) {
  919|  8.03k|  size_t cur_pos = io_->tell();
  920|  8.03k|  DataBuf buf(201);
  921|  8.03k|  DataBuf buf2(4 + 1);
  922|  8.03k|  uint32_t TagID = 0;
  923|  8.03k|  uint16_t dataLength = 0;
  924|  8.03k|  uint16_t dataType = 2;
  925|  8.03k|  const TagDetails* td;
  926|  8.03k|  const TagDetails* td2;
  927|       |
  928|   742k|  for (int i = 0; i < 100; i++) {
  ------------------
  |  Branch (928:19): [True: 734k, False: 8.03k]
  ------------------
  929|   734k|    io_->readOrThrow(buf.data(), 4);
  930|   734k|    TagID = buf.read_uint32(0, bigEndian);
  931|   734k|    td = Exiv2::find(NikonNCTGTags, TagID);
  932|       |
  933|   734k|    io_->readOrThrow(buf.data(), 2);
  934|   734k|    dataType = buf.read_uint16(0, bigEndian);
  935|       |
  936|   734k|    std::memset(buf.data(), 0x0, buf.size());
  937|   734k|    io_->readOrThrow(buf.data(), 2);
  938|       |
  939|   734k|    if (TagID == 0x2000023) {
  ------------------
  |  Branch (939:9): [True: 13.3k, False: 720k]
  ------------------
  940|  13.3k|      size_t local_pos = io_->tell();
  941|  13.3k|      dataLength = buf.read_uint16(0, bigEndian);
  942|  13.3k|      std::memset(buf.data(), 0x0, buf.size());
  943|       |
  944|  13.3k|      io_->readOrThrow(buf.data(), 4);
  945|  13.3k|      xmpData_["Xmp.video.PictureControlVersion"] = buf.data();
  946|  13.3k|      io_->readOrThrow(buf.data(), 20);
  947|  13.3k|      xmpData_["Xmp.video.PictureControlName"] = buf.data();
  948|  13.3k|      io_->readOrThrow(buf.data(), 20);
  949|  13.3k|      xmpData_["Xmp.video.PictureControlBase"] = buf.data();
  950|  13.3k|      io_->readOrThrow(buf.data(), 4);
  951|  13.3k|      std::memset(buf.data(), 0x0, buf.size());
  952|       |
  953|  13.3k|      io_->readOrThrow(buf.data(), 1);
  954|  13.3k|      td2 = Exiv2::find(PictureControlAdjust, static_cast<int>(buf.data()[0]) & 7);
  955|  13.3k|      if (td2)
  ------------------
  |  Branch (955:11): [True: 8.61k, False: 4.72k]
  ------------------
  956|  8.61k|        xmpData_["Xmp.video.PictureControlAdjust"] = _(td2->label_);
  ------------------
  |  |   40|  8.61k|#define _(String) (String)
  ------------------
  957|  4.72k|      else
  958|  4.72k|        xmpData_["Xmp.video.PictureControlAdjust"] = static_cast<int>(buf.data()[0]) & 7;
  959|       |
  960|  13.3k|      io_->readOrThrow(buf.data(), 1);
  961|  13.3k|      td2 = Exiv2::find(NormalSoftHard, static_cast<int>(buf.data()[0]) & 7);
  962|  13.3k|      if (td2)
  ------------------
  |  Branch (962:11): [True: 8.94k, False: 4.39k]
  ------------------
  963|  8.94k|        xmpData_["Xmp.video.PictureControlQuickAdjust"] = _(td2->label_);
  ------------------
  |  |   40|  8.94k|#define _(String) (String)
  ------------------
  964|       |
  965|  13.3k|      io_->readOrThrow(buf.data(), 1);
  966|  13.3k|      td2 = Exiv2::find(NormalSoftHard, static_cast<int>(buf.data()[0]) & 7);
  967|  13.3k|      if (td2)
  ------------------
  |  Branch (967:11): [True: 10.0k, False: 3.30k]
  ------------------
  968|  10.0k|        xmpData_["Xmp.video.Sharpness"] = _(td2->label_);
  ------------------
  |  |   40|  10.0k|#define _(String) (String)
  ------------------
  969|  3.30k|      else
  970|  3.30k|        xmpData_["Xmp.video.Sharpness"] = static_cast<int>(buf.data()[0]) & 7;
  971|       |
  972|  13.3k|      io_->readOrThrow(buf.data(), 1);
  973|  13.3k|      td2 = Exiv2::find(NormalSoftHard, static_cast<int>(buf.data()[0]) & 7);
  974|  13.3k|      if (td2)
  ------------------
  |  Branch (974:11): [True: 8.59k, False: 4.74k]
  ------------------
  975|  8.59k|        xmpData_["Xmp.video.Contrast"] = _(td2->label_);
  ------------------
  |  |   40|  8.59k|#define _(String) (String)
  ------------------
  976|  4.74k|      else
  977|  4.74k|        xmpData_["Xmp.video.Contrast"] = static_cast<int>(buf.data()[0]) & 7;
  978|       |
  979|  13.3k|      io_->readOrThrow(buf.data(), 1);
  980|  13.3k|      td2 = Exiv2::find(NormalSoftHard, static_cast<int>(buf.data()[0]) & 7);
  981|  13.3k|      if (td2)
  ------------------
  |  Branch (981:11): [True: 9.84k, False: 3.49k]
  ------------------
  982|  9.84k|        xmpData_["Xmp.video.Brightness"] = _(td2->label_);
  ------------------
  |  |   40|  9.84k|#define _(String) (String)
  ------------------
  983|  3.49k|      else
  984|  3.49k|        xmpData_["Xmp.video.Brightness"] = static_cast<int>(buf.data()[0]) & 7;
  985|       |
  986|  13.3k|      io_->readOrThrow(buf.data(), 1);
  987|  13.3k|      td2 = Exiv2::find(Saturation, static_cast<int>(buf.data()[0]) & 7);
  988|  13.3k|      if (td2)
  ------------------
  |  Branch (988:11): [True: 8.80k, False: 4.53k]
  ------------------
  989|  8.80k|        xmpData_["Xmp.video.Saturation"] = _(td2->label_);
  ------------------
  |  |   40|  8.80k|#define _(String) (String)
  ------------------
  990|  4.53k|      else
  991|  4.53k|        xmpData_["Xmp.video.Saturation"] = static_cast<int>(buf.data()[0]) & 7;
  992|       |
  993|  13.3k|      io_->readOrThrow(buf.data(), 1);
  994|  13.3k|      xmpData_["Xmp.video.HueAdjustment"] = static_cast<int>(buf.data()[0]) & 7;
  995|       |
  996|  13.3k|      io_->readOrThrow(buf.data(), 1);
  997|  13.3k|      td2 = Exiv2::find(FilterEffect, static_cast<int>(buf.data()[0]));
  998|  13.3k|      if (td2)
  ------------------
  |  Branch (998:11): [True: 1.85k, False: 11.4k]
  ------------------
  999|  1.85k|        xmpData_["Xmp.video.FilterEffect"] = _(td2->label_);
  ------------------
  |  |   40|  1.85k|#define _(String) (String)
  ------------------
 1000|  11.4k|      else
 1001|  11.4k|        xmpData_["Xmp.video.FilterEffect"] = static_cast<int>(buf.data()[0]);
 1002|       |
 1003|  13.3k|      io_->readOrThrow(buf.data(), 1);
 1004|  13.3k|      td2 = Exiv2::find(ToningEffect, static_cast<int>(buf.data()[0]));
 1005|  13.3k|      if (td2)
  ------------------
  |  Branch (1005:11): [True: 3.50k, False: 9.83k]
  ------------------
 1006|  3.50k|        xmpData_["Xmp.video.ToningEffect"] = _(td2->label_);
  ------------------
  |  |   40|  3.50k|#define _(String) (String)
  ------------------
 1007|  9.83k|      else
 1008|  9.83k|        xmpData_["Xmp.video.ToningEffect"] = static_cast<int>(buf.data()[0]);
 1009|       |
 1010|  13.3k|      io_->readOrThrow(buf.data(), 1);
 1011|  13.3k|      xmpData_["Xmp.video.ToningSaturation"] = static_cast<int>(buf.data()[0]);
 1012|       |
 1013|  13.3k|      io_->seek(local_pos + dataLength, BasicIo::beg);
 1014|  13.3k|    }
 1015|       |
 1016|   720k|    else if (TagID == 0x2000024) {
  ------------------
  |  Branch (1016:14): [True: 4.72k, False: 716k]
  ------------------
 1017|  4.72k|      size_t local_pos = io_->tell();
 1018|  4.72k|      dataLength = buf.read_uint16(0, bigEndian);
 1019|  4.72k|      std::memset(buf.data(), 0x0, buf.size());
 1020|       |
 1021|  4.72k|      io_->readOrThrow(buf.data(), 2);
 1022|  4.72k|      xmpData_["Xmp.video.TimeZone"] = Exiv2::getShort(buf.data(), bigEndian);
 1023|  4.72k|      io_->readOrThrow(buf.data(), 1);
 1024|  4.72k|      td2 = Exiv2::find(YesNo, static_cast<int>(buf.data()[0]));
 1025|  4.72k|      if (td2)
  ------------------
  |  Branch (1025:11): [True: 3.92k, False: 800]
  ------------------
 1026|  3.92k|        xmpData_["Xmp.video.DayLightSavings"] = _(td2->label_);
  ------------------
  |  |   40|  3.92k|#define _(String) (String)
  ------------------
 1027|       |
 1028|  4.72k|      io_->readOrThrow(buf.data(), 1);
 1029|  4.72k|      td2 = Exiv2::find(DateDisplayFormat, static_cast<int>(buf.data()[0]));
 1030|  4.72k|      if (td2)
  ------------------
  |  Branch (1030:11): [True: 1.25k, False: 3.46k]
  ------------------
 1031|  1.25k|        xmpData_["Xmp.video.DateDisplayFormat"] = _(td2->label_);
  ------------------
  |  |   40|  1.25k|#define _(String) (String)
  ------------------
 1032|       |
 1033|  4.72k|      io_->seek(local_pos + dataLength, BasicIo::beg);
 1034|  4.72k|    }
 1035|       |
 1036|   716k|    else if (dataType == 2 || dataType == 7) {
  ------------------
  |  Branch (1036:14): [True: 8.60k, False: 707k]
  |  Branch (1036:31): [True: 1.19k, False: 706k]
  ------------------
 1037|  9.08k|      dataLength = buf.read_uint16(0, bigEndian);
 1038|  9.08k|      std::memset(buf.data(), 0x0, buf.size());
 1039|       |
 1040|       |      // Sanity check with an "unreasonably" large number
 1041|  9.08k|      if (dataLength >= buf.size()) {
  ------------------
  |  Branch (1041:11): [True: 3.30k, False: 5.78k]
  ------------------
 1042|  3.30k|#ifndef SUPPRESS_WARNINGS
 1043|  3.30k|        EXV_ERROR << "Xmp.video Nikon Tags, dataLength was found to be larger than 200."
  ------------------
  |  |  142|  3.30k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 3.30k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  3.30k|  LogMsg(LogMsg::error).os()
  ------------------
 1044|      0|                  << " Entries considered invalid. Not Processed.\n";
 1045|  3.30k|#endif
 1046|  3.30k|        io_->seek(io_->tell() + dataLength, BasicIo::beg);
 1047|  3.30k|        buf.data()[0] = '\0';
 1048|  5.78k|      } else {
 1049|  5.78k|        io_->readOrThrow(buf.data(), dataLength);
 1050|  5.78k|        buf.data()[dataLength] = '\0';
 1051|  5.78k|      }
 1052|       |
 1053|  9.08k|      if (td) {
  ------------------
  |  Branch (1053:11): [True: 1.22k, False: 7.86k]
  ------------------
 1054|  1.22k|        xmpData_[_(td->label_)] = buf.data();
  ------------------
  |  |   40|  1.22k|#define _(String) (String)
  ------------------
 1055|  1.22k|      }
 1056|   706k|    } else if (dataType == 4) {
  ------------------
  |  Branch (1056:16): [True: 7.75k, False: 699k]
  ------------------
 1057|  7.75k|      dataLength = buf.read_uint16(0, bigEndian) * 4;
 1058|  7.75k|      std::memset(buf.data(), 0x0, buf.size());
 1059|  7.75k|      io_->readOrThrow(buf.data(), 4);
 1060|  7.75k|      if (td)
  ------------------
  |  Branch (1060:11): [True: 521, False: 7.23k]
  ------------------
 1061|    521|        xmpData_[_(td->label_)] = buf.read_uint32(0, bigEndian);
  ------------------
  |  |   40|    521|#define _(String) (String)
  ------------------
 1062|       |
 1063|       |      // Sanity check with an "unreasonably" large number
 1064|  7.75k|      if (dataLength > 200 || dataLength < 4) {
  ------------------
  |  Branch (1064:11): [True: 2.02k, False: 5.72k]
  |  Branch (1064:31): [True: 5.41k, False: 318]
  ------------------
 1065|  7.43k|#ifndef SUPPRESS_WARNINGS
 1066|  7.43k|        EXV_ERROR << "Xmp.video Nikon Tags, dataLength was found to be of inappropriate size."
  ------------------
  |  |  142|  7.43k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 7.43k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  7.43k|  LogMsg(LogMsg::error).os()
  ------------------
 1067|      0|                  << " Entries considered invalid. Not Processed.\n";
 1068|  7.43k|#endif
 1069|  7.43k|        io_->seek(io_->tell() + dataLength - 4, BasicIo::beg);
 1070|  7.43k|      } else
 1071|    319|        io_->readOrThrow(buf.data(), dataLength - 4);
 1072|   699k|    } else if (dataType == 3) {
  ------------------
  |  Branch (1072:16): [True: 2.74k, False: 696k]
  ------------------
 1073|  2.74k|      dataLength = buf.read_uint16(0, bigEndian) * 2;
 1074|  2.74k|      std::memset(buf.data(), 0x0, buf.size());
 1075|  2.74k|      io_->readOrThrow(buf.data(), 2);
 1076|  2.74k|      if (td)
  ------------------
  |  Branch (1076:11): [True: 625, False: 2.11k]
  ------------------
 1077|    625|        xmpData_[_(td->label_)] = buf.read_uint16(0, bigEndian);
  ------------------
  |  |   40|    625|#define _(String) (String)
  ------------------
 1078|       |
 1079|       |      // Sanity check with an "unreasonably" large number
 1080|  2.74k|      if (dataLength > 200 || dataLength < 2) {
  ------------------
  |  Branch (1080:11): [True: 1.04k, False: 1.69k]
  |  Branch (1080:31): [True: 1.18k, False: 507]
  ------------------
 1081|  2.23k|#ifndef SUPPRESS_WARNINGS
 1082|  2.23k|        EXV_ERROR << "Xmp.video Nikon Tags, dataLength was found to be of inappropriate size."
  ------------------
  |  |  142|  2.23k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 2.23k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  2.23k|  LogMsg(LogMsg::error).os()
  ------------------
 1083|      0|                  << " Entries considered invalid. Not Processed.\n";
 1084|  2.23k|#endif
 1085|  2.23k|        io_->seek(io_->tell() + dataLength - 2, BasicIo::beg);
 1086|  2.23k|      } else
 1087|    507|        io_->readOrThrow(buf.data(), dataLength - 2);
 1088|   696k|    } else if (dataType == 5) {
  ------------------
  |  Branch (1088:16): [True: 3.24k, False: 693k]
  ------------------
 1089|  3.24k|      dataLength = buf.read_uint16(0, bigEndian) * 8;
 1090|  3.24k|      std::memset(buf.data(), 0x0, buf.size());
 1091|  3.24k|      io_->readOrThrow(buf.data(), 4);
 1092|  3.24k|      io_->readOrThrow(buf2.data(), 4);
 1093|  3.24k|      if (td)
  ------------------
  |  Branch (1093:11): [True: 1.16k, False: 2.07k]
  ------------------
 1094|  1.16k|        xmpData_[_(td->label_)] =
  ------------------
  |  |   40|  1.16k|#define _(String) (String)
  ------------------
 1095|  1.16k|            static_cast<double>(buf.read_uint32(0, bigEndian)) / static_cast<double>(buf2.read_uint32(0, bigEndian));
 1096|       |
 1097|       |      // Sanity check with an "unreasonably" large number
 1098|  3.24k|      if (dataLength > 200 || dataLength < 8) {
  ------------------
  |  Branch (1098:11): [True: 1.65k, False: 1.59k]
  |  Branch (1098:31): [True: 1.17k, False: 416]
  ------------------
 1099|  2.82k|#ifndef SUPPRESS_WARNINGS
 1100|  2.82k|        EXV_ERROR << "Xmp.video Nikon Tags, dataLength was found to be of inappropriate size."
  ------------------
  |  |  142|  2.82k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 2.82k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  2.82k|  LogMsg(LogMsg::error).os()
  ------------------
 1101|      0|                  << " Entries considered invalid. Not Processed.\n";
 1102|  2.82k|#endif
 1103|  2.82k|        io_->seek(io_->tell() + dataLength - 8, BasicIo::beg);
 1104|  2.82k|      } else
 1105|    417|        io_->readOrThrow(buf.data(), dataLength - 8);
 1106|   693k|    } else if (dataType == 8) {
  ------------------
  |  Branch (1106:16): [True: 8.18k, False: 685k]
  ------------------
 1107|  8.18k|      dataLength = buf.read_uint16(0, bigEndian) * 2;
 1108|  8.18k|      std::memset(buf.data(), 0x0, buf.size());
 1109|  8.18k|      io_->readOrThrow(buf.data(), 2);
 1110|  8.18k|      io_->readOrThrow(buf2.data(), 2);
 1111|  8.18k|      if (td)
  ------------------
  |  Branch (1111:11): [True: 4.86k, False: 3.31k]
  ------------------
 1112|  4.86k|        xmpData_[_(td->label_)] = stringFormat("{}.{}", buf.read_uint16(0, bigEndian), buf2.read_uint16(0, bigEndian));
  ------------------
  |  |   40|  4.86k|#define _(String) (String)
  ------------------
                      xmpData_[_(td->label_)] = stringFormat("{}.{}", buf.read_uint16(0, bigEndian), buf2.read_uint16(0, bigEndian));
  ------------------
  |  |   18|  4.86k|#define stringFormat std::format
  ------------------
 1113|       |
 1114|       |      // Sanity check with an "unreasonably" large number
 1115|  8.18k|      if (dataLength > 200 || dataLength < 4) {
  ------------------
  |  Branch (1115:11): [True: 1.64k, False: 6.54k]
  |  Branch (1115:31): [True: 6.30k, False: 238]
  ------------------
 1116|  7.94k|#ifndef SUPPRESS_WARNINGS
 1117|  7.94k|        EXV_ERROR << "Xmp.video Nikon Tags, dataLength was found to be of inappropriate size."
  ------------------
  |  |  142|  7.94k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 7.94k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  7.94k|  LogMsg(LogMsg::error).os()
  ------------------
 1118|      0|                  << " Entries considered invalid. Not Processed.\n";
 1119|  7.94k|#endif
 1120|  7.94k|        io_->seek(io_->tell() + dataLength - 4, BasicIo::beg);
 1121|  7.94k|      } else
 1122|    239|        io_->readOrThrow(buf.data(), dataLength - 4);
 1123|  8.18k|    }
 1124|   734k|  }
 1125|       |
 1126|  8.03k|  io_->seek(cur_pos + size, BasicIo::beg);
 1127|  8.03k|}  // QuickTimeVideo::NikonTagsDecoder
_ZN5Exiv214QuickTimeVideo14setMediaStreamEv:
 1129|  2.65k|void QuickTimeVideo::setMediaStream() {
 1130|  2.65k|  size_t current_position = io_->tell();
 1131|  2.65k|  DataBuf buf(4 + 1);
 1132|       |
 1133|  7.05M|  while (!io_->eof()) {
  ------------------
  |  Branch (1133:10): [True: 7.05M, False: 24]
  ------------------
 1134|  7.05M|    io_->readOrThrow(buf.data(), 4);
 1135|  7.05M|    if (equalsQTimeTag(buf, "hdlr")) {
  ------------------
  |  Branch (1135:9): [True: 2.62k, False: 7.05M]
  ------------------
 1136|  2.62k|      io_->readOrThrow(buf.data(), 4);
 1137|  2.62k|      io_->readOrThrow(buf.data(), 4);
 1138|  2.62k|      io_->readOrThrow(buf.data(), 4);
 1139|       |
 1140|  2.62k|      if (equalsQTimeTag(buf, "vide"))
  ------------------
  |  Branch (1140:11): [True: 270, False: 2.35k]
  ------------------
 1141|    270|        currentStream_ = Video;
 1142|  2.35k|      else if (equalsQTimeTag(buf, "soun"))
  ------------------
  |  Branch (1142:16): [True: 473, False: 1.88k]
  ------------------
 1143|    473|        currentStream_ = Audio;
 1144|  1.88k|      else if (equalsQTimeTag(buf, "hint"))
  ------------------
  |  Branch (1144:16): [True: 68, False: 1.81k]
  ------------------
 1145|     68|        currentStream_ = Hint;
 1146|  1.81k|      else
 1147|  1.81k|        currentStream_ = GenMediaHeader;
 1148|  2.62k|      break;
 1149|  2.62k|    }
 1150|  7.05M|  }
 1151|       |
 1152|  2.65k|  io_->seek(current_position, BasicIo::beg);
 1153|  2.65k|}  // QuickTimeVideo::setMediaStream
_ZN5Exiv214QuickTimeVideo19timeToSampleDecoderEv:
 1155|    930|void QuickTimeVideo::timeToSampleDecoder() {
 1156|    930|  DataBuf buf(4 + 1);
 1157|    930|  io_->readOrThrow(buf.data(), 4);
 1158|    930|  io_->readOrThrow(buf.data(), 4);
 1159|    930|  uint64_t totalframes = 0;
 1160|    930|  uint64_t timeOfFrames = 0;
 1161|    930|  const uint32_t noOfEntries = buf.read_uint32(0, bigEndian);
 1162|       |
 1163|  2.35k|  for (uint32_t i = 0; i < noOfEntries; i++) {
  ------------------
  |  Branch (1163:24): [True: 1.42k, False: 930]
  ------------------
 1164|  1.42k|    io_->readOrThrow(buf.data(), 4);
 1165|  1.42k|    const uint64_t temp = buf.read_uint32(0, bigEndian);
 1166|  1.42k|    totalframes = Safe::add(totalframes, temp);
 1167|  1.42k|    io_->readOrThrow(buf.data(), 4);
 1168|  1.42k|    timeOfFrames = Safe::add(timeOfFrames, temp * buf.read_uint32(0, bigEndian));
 1169|  1.42k|  }
 1170|    930|  if (currentStream_ == Video) {
  ------------------
  |  Branch (1170:7): [True: 617, False: 313]
  ------------------
 1171|    617|    if (timeOfFrames == 0)
  ------------------
  |  Branch (1171:9): [True: 30, False: 587]
  ------------------
 1172|     30|      timeOfFrames = 1;
 1173|    617|    xmpData_["Xmp.video.FrameRate"] =
 1174|    617|        static_cast<double>(totalframes) * static_cast<double>(mdhdTimeScale_) / static_cast<double>(timeOfFrames);
 1175|    617|  }
 1176|    930|}  // QuickTimeVideo::timeToSampleDecoder
_ZN5Exiv214QuickTimeVideo10sampleDescEm:
 1178|  1.94k|void QuickTimeVideo::sampleDesc(size_t size) {
 1179|  1.94k|  DataBuf buf(100);
 1180|  1.94k|  size_t cur_pos = io_->tell();
 1181|  1.94k|  io_->readOrThrow(buf.data(), 4);
 1182|  1.94k|  io_->readOrThrow(buf.data(), 4);
 1183|  1.94k|  const uint32_t noOfEntries = buf.read_uint32(0, bigEndian);
 1184|       |
 1185|  63.0k|  for (uint32_t i = 0; i < noOfEntries; i++) {
  ------------------
  |  Branch (1185:24): [True: 61.1k, False: 1.83k]
  ------------------
 1186|  61.1k|    if (currentStream_ == Video)
  ------------------
  |  Branch (1186:9): [True: 34.1k, False: 27.0k]
  ------------------
 1187|  34.1k|      imageDescDecoder();
 1188|  27.0k|    else if (currentStream_ == Audio)
  ------------------
  |  Branch (1188:14): [True: 26.9k, False: 114]
  ------------------
 1189|  26.9k|      audioDescDecoder();
 1190|    114|    else
 1191|    114|      break;
 1192|  61.1k|  }
 1193|  1.94k|  io_->seek(Safe::add(cur_pos, size), BasicIo::beg);
 1194|  1.94k|}  // QuickTimeVideo::sampleDesc
_ZN5Exiv214QuickTimeVideo16audioDescDecoderEv:
 1196|  26.9k|void QuickTimeVideo::audioDescDecoder() {
 1197|  26.9k|  DataBuf buf(40);
 1198|  26.9k|  std::memset(buf.data(), 0x0, buf.size());
 1199|  26.9k|  buf.data()[4] = '\0';
 1200|  26.9k|  io_->readOrThrow(buf.data(), 4);
 1201|  26.9k|  size_t size = 82;
 1202|       |
 1203|  26.9k|  const TagVocabulary* td;
 1204|       |
 1205|   563k|  for (int i = 0; size / 4 != 0; size -= 4, i++) {
  ------------------
  |  Branch (1205:19): [True: 537k, False: 26.8k]
  ------------------
 1206|   537k|    io_->readOrThrow(buf.data(), 4);
 1207|   537k|    switch (i) {
 1208|  26.8k|      case AudioFormat:
  ------------------
  |  Branch (1208:7): [True: 26.8k, False: 510k]
  ------------------
 1209|  26.8k|        td = Exiv2::find(qTimeFileType, Exiv2::toString(buf.data()));
 1210|  26.8k|        if (td)
  ------------------
  |  Branch (1210:13): [True: 339, False: 26.5k]
  ------------------
 1211|    339|          xmpData_["Xmp.audio.Compressor"] = _(td->label_);
  ------------------
  |  |   40|    339|#define _(String) (String)
  ------------------
 1212|  26.5k|        else
 1213|  26.5k|          xmpData_["Xmp.audio.Compressor"] = buf.data();
 1214|  26.8k|        break;
 1215|  26.8k|      case AudioVendorID:
  ------------------
  |  Branch (1215:7): [True: 26.8k, False: 510k]
  ------------------
 1216|  26.8k|        td = Exiv2::find(vendorIDTags, Exiv2::toString(buf.data()));
 1217|  26.8k|        if (td)
  ------------------
  |  Branch (1217:13): [True: 628, False: 26.2k]
  ------------------
 1218|    628|          xmpData_["Xmp.audio.VendorID"] = _(td->label_);
  ------------------
  |  |   40|    628|#define _(String) (String)
  ------------------
 1219|  26.8k|        break;
 1220|  26.8k|      case AudioChannels:
  ------------------
  |  Branch (1220:7): [True: 26.8k, False: 510k]
  ------------------
 1221|  26.8k|        xmpData_["Xmp.audio.ChannelType"] = buf.read_uint16(0, bigEndian);
 1222|  26.8k|        xmpData_["Xmp.audio.BitsPerSample"] = ((buf.data()[2] * 256) + buf.data()[3]);
 1223|  26.8k|        break;
 1224|  26.8k|      case AudioSampleRate:
  ------------------
  |  Branch (1224:7): [True: 26.8k, False: 510k]
  ------------------
 1225|  26.8k|        xmpData_["Xmp.audio.SampleRate"] =
 1226|  26.8k|            buf.read_uint16(0, bigEndian) + ((buf.data()[2] * 256 + buf.data()[3]) * 0.01);
 1227|  26.8k|        break;
 1228|   429k|      default:
  ------------------
  |  Branch (1228:7): [True: 429k, False: 107k]
  ------------------
 1229|   429k|        break;
 1230|   537k|    }
 1231|   537k|  }
 1232|  26.8k|  io_->readOrThrow(buf.data(), static_cast<long>(size % 4));  // cause size is so small, this cast should be right.
 1233|  26.8k|}  // QuickTimeVideo::audioDescDecoder
_ZN5Exiv214QuickTimeVideo16imageDescDecoderEv:
 1235|  34.1k|void QuickTimeVideo::imageDescDecoder() {
 1236|  34.1k|  DataBuf buf(40);
 1237|  34.1k|  std::memset(buf.data(), 0x0, buf.size());
 1238|  34.1k|  buf.data()[4] = '\0';
 1239|  34.1k|  io_->readOrThrow(buf.data(), 4);
 1240|  34.1k|  size_t size = 82;
 1241|       |
 1242|  34.1k|  const TagVocabulary* td;
 1243|       |
 1244|   409k|  for (int i = 0; size / 4 != 0; size -= 4, i++) {
  ------------------
  |  Branch (1244:19): [True: 375k, False: 34.0k]
  ------------------
 1245|   375k|    io_->readOrThrow(buf.data(), 4);
 1246|       |
 1247|   375k|    switch (i) {
 1248|  34.1k|      case codec:
  ------------------
  |  Branch (1248:7): [True: 34.1k, False: 341k]
  ------------------
 1249|  34.1k|        td = Exiv2::find(qTimeFileType, Exiv2::toString(buf.data()));
 1250|  34.1k|        if (td)
  ------------------
  |  Branch (1250:13): [True: 2.52k, False: 31.6k]
  ------------------
 1251|  2.52k|          xmpData_["Xmp.video.Codec"] = _(td->label_);
  ------------------
  |  |   40|  2.52k|#define _(String) (String)
  ------------------
 1252|  31.6k|        else
 1253|  31.6k|          xmpData_["Xmp.video.Codec"] = buf.data();
 1254|  34.1k|        break;
 1255|  34.1k|      case VendorID:
  ------------------
  |  Branch (1255:7): [True: 34.1k, False: 341k]
  ------------------
 1256|  34.1k|        td = Exiv2::find(vendorIDTags, Exiv2::toString(buf.data()));
 1257|  34.1k|        if (td)
  ------------------
  |  Branch (1257:13): [True: 619, False: 33.4k]
  ------------------
 1258|    619|          xmpData_["Xmp.video.VendorID"] = _(td->label_);
  ------------------
  |  |   40|    619|#define _(String) (String)
  ------------------
 1259|  34.1k|        break;
 1260|  34.1k|      case SourceImageWidth_Height:
  ------------------
  |  Branch (1260:7): [True: 34.1k, False: 341k]
  ------------------
 1261|  34.1k|        xmpData_["Xmp.video.SourceImageWidth"] = buf.read_uint16(0, bigEndian);
 1262|  34.1k|        xmpData_["Xmp.video.SourceImageHeight"] = ((buf.data()[2] * 256) + buf.data()[3]);
 1263|  34.1k|        break;
 1264|  34.0k|      case XResolution:
  ------------------
  |  Branch (1264:7): [True: 34.0k, False: 341k]
  ------------------
 1265|  34.0k|        xmpData_["Xmp.video.XResolution"] =
 1266|  34.0k|            buf.read_uint16(0, bigEndian) + ((buf.data()[2] * 256 + buf.data()[3]) * 0.01);
 1267|  34.0k|        break;
 1268|  34.0k|      case YResolution:
  ------------------
  |  Branch (1268:7): [True: 34.0k, False: 341k]
  ------------------
 1269|  34.0k|        xmpData_["Xmp.video.YResolution"] =
 1270|  34.0k|            buf.read_uint16(0, bigEndian) + ((buf.data()[2] * 256 + buf.data()[3]) * 0.01);
 1271|  34.0k|        io_->readOrThrow(buf.data(), 3);
 1272|  34.0k|        size -= 3;
 1273|  34.0k|        break;
 1274|  34.0k|      case CompressorName:
  ------------------
  |  Branch (1274:7): [True: 34.0k, False: 341k]
  ------------------
 1275|  34.0k|        io_->readOrThrow(buf.data(), 32);
 1276|  34.0k|        size -= 32;
 1277|  34.0k|        xmpData_["Xmp.video.Compressor"] = buf.data();
 1278|  34.0k|        break;
 1279|   170k|      default:
  ------------------
  |  Branch (1279:7): [True: 170k, False: 204k]
  ------------------
 1280|   170k|        break;
 1281|   375k|    }
 1282|   375k|  }
 1283|  34.0k|  io_->readOrThrow(buf.data(), static_cast<long>(size % 4));
 1284|  34.0k|  xmpData_["Xmp.video.BitDepth"] = static_cast<int>(buf.read_uint8(0));
 1285|  34.0k|}  // QuickTimeVideo::imageDescDecoder
_ZN5Exiv214QuickTimeVideo22multipleEntriesDecoderEm:
 1287|  1.95k|void QuickTimeVideo::multipleEntriesDecoder(size_t recursion_depth) {
 1288|  1.95k|  enforce(recursion_depth < max_recursion_depth_, Exiv2::ErrorCode::kerCorruptedMetadata);
 1289|  1.95k|  DataBuf buf(4 + 1);
 1290|  1.95k|  io_->readOrThrow(buf.data(), 4);
 1291|  1.95k|  io_->readOrThrow(buf.data(), 4);
 1292|  1.95k|  uint32_t noOfEntries;
 1293|       |
 1294|  1.95k|  noOfEntries = buf.read_uint32(0, bigEndian);
 1295|       |
 1296|  6.18k|  for (uint32_t i = 0; i < noOfEntries && continueTraversing_; i++) {
  ------------------
  |  Branch (1296:24): [True: 4.46k, False: 1.71k]
  |  Branch (1296:43): [True: 4.22k, False: 240]
  ------------------
 1297|  4.22k|    decodeBlock(recursion_depth + 1);
 1298|  4.22k|  }
 1299|  1.95k|}  // QuickTimeVideo::multipleEntriesDecoder
_ZN5Exiv214QuickTimeVideo18videoHeaderDecoderEm:
 1301|  5.23k|void QuickTimeVideo::videoHeaderDecoder(size_t size) {
 1302|  5.23k|  DataBuf buf(3);
 1303|  5.23k|  std::memset(buf.data(), 0x0, buf.size());
 1304|  5.23k|  buf.data()[2] = '\0';
 1305|  5.23k|  currentStream_ = Video;
 1306|       |
 1307|  5.23k|  const TagDetails* td;
 1308|       |
 1309|  35.6k|  for (int i = 0; size / 2 != 0; size -= 2, i++) {
  ------------------
  |  Branch (1309:19): [True: 30.4k, False: 5.23k]
  ------------------
 1310|  30.4k|    io_->readOrThrow(buf.data(), 2);
 1311|       |
 1312|  30.4k|    switch (i) {
 1313|  4.97k|      case GraphicsMode:
  ------------------
  |  Branch (1313:7): [True: 4.97k, False: 25.4k]
  ------------------
 1314|  4.97k|        td = Exiv2::find(graphicsModetags, buf.read_uint16(0, bigEndian));
 1315|  4.97k|        if (td)
  ------------------
  |  Branch (1315:13): [True: 3.75k, False: 1.22k]
  ------------------
 1316|  3.75k|          xmpData_["Xmp.video.GraphicsMode"] = _(td->label_);
  ------------------
  |  |   40|  3.75k|#define _(String) (String)
  ------------------
 1317|  4.97k|        break;
 1318|  3.29k|      case OpColor:
  ------------------
  |  Branch (1318:7): [True: 3.29k, False: 27.1k]
  ------------------
 1319|  3.29k|        xmpData_["Xmp.video.OpColor"] = buf.read_uint16(0, bigEndian);
 1320|  3.29k|        break;
 1321|  22.1k|      default:
  ------------------
  |  Branch (1321:7): [True: 22.1k, False: 8.27k]
  ------------------
 1322|  22.1k|        break;
 1323|  30.4k|    }
 1324|  30.4k|  }
 1325|  5.23k|  io_->readOrThrow(buf.data(), size % 2);
 1326|  5.23k|}  // QuickTimeVideo::videoHeaderDecoder
_ZN5Exiv214QuickTimeVideo14handlerDecoderEm:
 1328|  2.17k|void QuickTimeVideo::handlerDecoder(size_t size) {
 1329|  2.17k|  size_t cur_pos = io_->tell();
 1330|  2.17k|  DataBuf buf(100);
 1331|  2.17k|  std::memset(buf.data(), 0x0, buf.size());
 1332|  2.17k|  buf.data()[4] = '\0';
 1333|       |
 1334|  2.17k|  const TagVocabulary* tv;
 1335|       |
 1336|  13.0k|  for (int i = 0; i < 5; i++) {
  ------------------
  |  Branch (1336:19): [True: 10.8k, False: 2.16k]
  ------------------
 1337|  10.8k|    io_->readOrThrow(buf.data(), 4);
 1338|       |
 1339|  10.8k|    switch (i) {
  ------------------
  |  Branch (1339:13): [True: 6.51k, False: 4.34k]
  ------------------
 1340|  2.17k|      case HandlerClass:
  ------------------
  |  Branch (1340:7): [True: 2.17k, False: 8.68k]
  ------------------
 1341|  2.17k|        tv = Exiv2::find(handlerClassTags, Exiv2::toString(buf.data()));
 1342|  2.17k|        if (tv) {
  ------------------
  |  Branch (1342:13): [True: 516, False: 1.65k]
  ------------------
 1343|    516|          if (currentStream_ == Video)
  ------------------
  |  Branch (1343:15): [True: 233, False: 283]
  ------------------
 1344|    233|            xmpData_["Xmp.video.HandlerClass"] = _(tv->label_);
  ------------------
  |  |   40|    233|#define _(String) (String)
  ------------------
 1345|    283|          else if (currentStream_ == Audio)
  ------------------
  |  Branch (1345:20): [True: 10, False: 273]
  ------------------
 1346|     10|            xmpData_["Xmp.audio.HandlerClass"] = _(tv->label_);
  ------------------
  |  |   40|     10|#define _(String) (String)
  ------------------
 1347|    516|        }
 1348|  2.17k|        break;
 1349|  2.17k|      case HandlerType:
  ------------------
  |  Branch (1349:7): [True: 2.17k, False: 8.68k]
  ------------------
 1350|  2.17k|        tv = Exiv2::find(handlerTypeTags, Exiv2::toString(buf.data()));
 1351|  2.17k|        if (tv) {
  ------------------
  |  Branch (1351:13): [True: 1.28k, False: 886]
  ------------------
 1352|  1.28k|          if (currentStream_ == Video)
  ------------------
  |  Branch (1352:15): [True: 208, False: 1.07k]
  ------------------
 1353|    208|            xmpData_["Xmp.video.HandlerType"] = _(tv->label_);
  ------------------
  |  |   40|    208|#define _(String) (String)
  ------------------
 1354|  1.07k|          else if (currentStream_ == Audio)
  ------------------
  |  Branch (1354:20): [True: 18, False: 1.05k]
  ------------------
 1355|     18|            xmpData_["Xmp.audio.HandlerType"] = _(tv->label_);
  ------------------
  |  |   40|     18|#define _(String) (String)
  ------------------
 1356|  1.28k|        }
 1357|  2.17k|        break;
 1358|  2.16k|      case HandlerVendorID:
  ------------------
  |  Branch (1358:7): [True: 2.16k, False: 8.68k]
  ------------------
 1359|  2.16k|        tv = Exiv2::find(vendorIDTags, Exiv2::toString(buf.data()));
 1360|  2.16k|        if (tv) {
  ------------------
  |  Branch (1360:13): [True: 937, False: 1.23k]
  ------------------
 1361|    937|          if (currentStream_ == Video)
  ------------------
  |  Branch (1361:15): [True: 92, False: 845]
  ------------------
 1362|     92|            xmpData_["Xmp.video.HandlerVendorID"] = _(tv->label_);
  ------------------
  |  |   40|     92|#define _(String) (String)
  ------------------
 1363|    845|          else if (currentStream_ == Audio)
  ------------------
  |  Branch (1363:20): [True: 8, False: 837]
  ------------------
 1364|      8|            xmpData_["Xmp.audio.HandlerVendorID"] = _(tv->label_);
  ------------------
  |  |   40|      8|#define _(String) (String)
  ------------------
 1365|    937|        }
 1366|  2.16k|        break;
 1367|  10.8k|    }
 1368|  10.8k|  }
 1369|  2.16k|  io_->seek(cur_pos + size, BasicIo::beg);
 1370|  2.16k|}  // QuickTimeVideo::handlerDecoder
_ZN5Exiv214QuickTimeVideo15fileTypeDecoderEm:
 1372|  12.2k|void QuickTimeVideo::fileTypeDecoder(size_t size) {
 1373|  12.2k|  DataBuf buf(5);
 1374|  12.2k|  std::memset(buf.data(), 0x0, buf.size());
 1375|  12.2k|  buf.data()[4] = '\0';
 1376|  12.2k|  Exiv2::Value::UniquePtr v = Exiv2::Value::create(Exiv2::xmpSeq);
 1377|  12.2k|  const TagVocabulary* td;
 1378|       |
 1379|  98.6k|  for (int i = 0; size / 4 != 0; size -= 4, i++) {
  ------------------
  |  Branch (1379:19): [True: 86.4k, False: 12.2k]
  ------------------
 1380|  86.4k|    io_->readOrThrow(buf.data(), 4);
 1381|  86.4k|    td = Exiv2::find(qTimeFileType, Exiv2::toString(buf.data()));
 1382|       |
 1383|  86.4k|    switch (i) {
 1384|  11.9k|      case 0:
  ------------------
  |  Branch (1384:7): [True: 11.9k, False: 74.4k]
  ------------------
 1385|  11.9k|        if (td)
  ------------------
  |  Branch (1385:13): [True: 7.84k, False: 4.10k]
  ------------------
 1386|  7.84k|          xmpData_["Xmp.video.MajorBrand"] = _(td->label_);
  ------------------
  |  |   40|  7.84k|#define _(String) (String)
  ------------------
 1387|  11.9k|        break;
 1388|  6.03k|      case 1:
  ------------------
  |  Branch (1388:7): [True: 6.03k, False: 80.3k]
  ------------------
 1389|  6.03k|        xmpData_["Xmp.video.MinorVersion"] = buf.read_uint32(0, bigEndian);
 1390|  6.03k|        break;
 1391|  68.4k|      default:
  ------------------
  |  Branch (1391:7): [True: 68.4k, False: 17.9k]
  ------------------
 1392|  68.4k|        if (td)
  ------------------
  |  Branch (1392:13): [True: 1.69k, False: 66.7k]
  ------------------
 1393|  1.69k|          v->read(_(td->label_));
  ------------------
  |  |   40|  1.69k|#define _(String) (String)
  ------------------
 1394|  66.7k|        else
 1395|  66.7k|          v->read(Exiv2::toString(buf.data()));
 1396|  68.4k|        break;
 1397|  86.4k|    }
 1398|  86.4k|  }
 1399|  12.2k|  xmpData_.add(Exiv2::XmpKey("Xmp.video.CompatibleBrands"), v.get());
 1400|  12.2k|  io_->readOrThrow(buf.data(), size % 4);
 1401|  12.2k|}  // QuickTimeVideo::fileTypeDecoder
_ZN5Exiv214QuickTimeVideo18mediaHeaderDecoderEm:
 1403|  1.25k|void QuickTimeVideo::mediaHeaderDecoder(size_t size) {
 1404|  1.25k|  DataBuf buf(5);
 1405|  1.25k|  std::memset(buf.data(), 0x0, buf.size());
 1406|  1.25k|  buf.data()[4] = '\0';
 1407|  1.25k|  int64_t time_scale = 1;
 1408|       |
 1409|  5.79k|  for (int i = 0; size / 4 != 0; size -= 4, i++) {
  ------------------
  |  Branch (1409:19): [True: 4.53k, False: 1.25k]
  ------------------
 1410|  4.53k|    io_->readOrThrow(buf.data(), 4);
 1411|       |
 1412|  4.53k|    switch (i) {
 1413|  1.18k|      case MediaHeaderVersion:
  ------------------
  |  Branch (1413:7): [True: 1.18k, False: 3.35k]
  ------------------
 1414|  1.18k|        if (currentStream_ == Video)
  ------------------
  |  Branch (1414:13): [True: 552, False: 630]
  ------------------
 1415|    552|          xmpData_["Xmp.video.MediaHeaderVersion"] = static_cast<int>(buf.read_uint8(0));
 1416|    630|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1416:18): [True: 100, False: 530]
  ------------------
 1417|    100|          xmpData_["Xmp.audio.MediaHeaderVersion"] = static_cast<int>(buf.read_uint8(0));
 1418|  1.18k|        break;
 1419|    439|      case MediaCreateDate:
  ------------------
  |  Branch (1419:7): [True: 439, False: 4.10k]
  ------------------
 1420|       |        // A 32-bit integer that specifies (in seconds since midnight, January 1, 1904) when the movie atom was created.
 1421|    439|        if (currentStream_ == Video)
  ------------------
  |  Branch (1421:13): [True: 49, False: 390]
  ------------------
 1422|     49|          xmpData_["Xmp.video.MediaCreateDate"] = buf.read_uint32(0, bigEndian);
 1423|    390|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1423:18): [True: 66, False: 324]
  ------------------
 1424|     66|          xmpData_["Xmp.audio.MediaCreateDate"] = buf.read_uint32(0, bigEndian);
 1425|    439|        break;
 1426|    438|      case MediaModifyDate:
  ------------------
  |  Branch (1426:7): [True: 438, False: 4.10k]
  ------------------
 1427|       |        // A 32-bit integer that specifies (in seconds since midnight, January 1, 1904) when the movie atom was created.
 1428|    438|        if (currentStream_ == Video)
  ------------------
  |  Branch (1428:13): [True: 48, False: 390]
  ------------------
 1429|     48|          xmpData_["Xmp.video.MediaModifyDate"] = buf.read_uint32(0, bigEndian);
 1430|    390|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1430:18): [True: 66, False: 324]
  ------------------
 1431|     66|          xmpData_["Xmp.audio.MediaModifyDate"] = buf.read_uint32(0, bigEndian);
 1432|    438|        break;
 1433|    435|      case MediaTimeScale:
  ------------------
  |  Branch (1433:7): [True: 435, False: 4.10k]
  ------------------
 1434|    435|        if (currentStream_ == Video)
  ------------------
  |  Branch (1434:13): [True: 46, False: 389]
  ------------------
 1435|     46|          xmpData_["Xmp.video.MediaTimeScale"] = buf.read_uint32(0, bigEndian);
 1436|    389|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1436:18): [True: 66, False: 323]
  ------------------
 1437|     66|          xmpData_["Xmp.audio.MediaTimeScale"] = buf.read_uint32(0, bigEndian);
 1438|    435|        time_scale = std::max(1U, buf.read_uint32(0, bigEndian));
 1439|    435|        mdhdTimeScale_ = time_scale;
 1440|    435|        break;
 1441|    434|      case MediaDuration:
  ------------------
  |  Branch (1441:7): [True: 434, False: 4.10k]
  ------------------
 1442|    434|        if (currentStream_ == Video)
  ------------------
  |  Branch (1442:13): [True: 46, False: 388]
  ------------------
 1443|     46|          xmpData_["Xmp.video.MediaDuration"] = time_scale ? buf.read_uint32(0, bigEndian) / time_scale : 0;
  ------------------
  |  Branch (1443:49): [True: 46, False: 0]
  ------------------
 1444|    388|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1444:18): [True: 66, False: 322]
  ------------------
 1445|     66|          xmpData_["Xmp.audio.MediaDuration"] = time_scale ? buf.read_uint32(0, bigEndian) / time_scale : 0;
  ------------------
  |  Branch (1445:49): [True: 66, False: 0]
  ------------------
 1446|    434|        break;
 1447|    434|      case MediaLanguageCode:
  ------------------
  |  Branch (1447:7): [True: 434, False: 4.10k]
  ------------------
 1448|    434|        if (currentStream_ == Video)
  ------------------
  |  Branch (1448:13): [True: 46, False: 388]
  ------------------
 1449|     46|          xmpData_["Xmp.video.MediaLangCode"] = buf.read_uint16(0, bigEndian);
 1450|    388|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1450:18): [True: 66, False: 322]
  ------------------
 1451|     66|          xmpData_["Xmp.audio.MediaLangCode"] = buf.read_uint16(0, bigEndian);
 1452|    434|        break;
 1453|       |
 1454|  1.17k|      default:
  ------------------
  |  Branch (1454:7): [True: 1.17k, False: 3.36k]
  ------------------
 1455|  1.17k|        break;
 1456|  4.53k|    }
 1457|  4.53k|  }
 1458|  1.25k|  io_->readOrThrow(buf.data(), size % 4);
 1459|  1.25k|}  // QuickTimeVideo::mediaHeaderDecoder
_ZN5Exiv214QuickTimeVideo18trackHeaderDecoderEm:
 1461|    750|void QuickTimeVideo::trackHeaderDecoder(size_t size) {
 1462|    750|  DataBuf buf(5);
 1463|    750|  std::memset(buf.data(), 0x0, buf.size());
 1464|    750|  buf.data()[4] = '\0';
 1465|    750|  int64_t temp = 0;
 1466|       |
 1467|  15.5k|  for (int i = 0; size / 4 != 0; size -= 4, i++) {
  ------------------
  |  Branch (1467:19): [True: 14.7k, False: 750]
  ------------------
 1468|  14.7k|    io_->readOrThrow(buf.data(), 4);
 1469|       |
 1470|  14.7k|    switch (i) {
 1471|    471|      case TrackHeaderVersion:
  ------------------
  |  Branch (1471:7): [True: 471, False: 14.2k]
  ------------------
 1472|    471|        if (currentStream_ == Video)
  ------------------
  |  Branch (1472:13): [True: 221, False: 250]
  ------------------
 1473|    221|          xmpData_["Xmp.video.TrackHeaderVersion"] = static_cast<int>(buf.read_uint8(0));
 1474|    250|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1474:18): [True: 34, False: 216]
  ------------------
 1475|     34|          xmpData_["Xmp.audio.TrackHeaderVersion"] = static_cast<int>(buf.read_uint8(0));
 1476|    471|        break;
 1477|    468|      case TrackCreateDate:
  ------------------
  |  Branch (1477:7): [True: 468, False: 14.2k]
  ------------------
 1478|       |        // A 32-bit integer that specifies (in seconds since midnight, January 1, 1904) when the movie atom was created.
 1479|    468|        if (currentStream_ == Video)
  ------------------
  |  Branch (1479:13): [True: 221, False: 247]
  ------------------
 1480|    221|          xmpData_["Xmp.video.TrackCreateDate"] = buf.read_uint32(0, bigEndian);
 1481|    247|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1481:18): [True: 34, False: 213]
  ------------------
 1482|     34|          xmpData_["Xmp.audio.TrackCreateDate"] = buf.read_uint32(0, bigEndian);
 1483|    468|        break;
 1484|    467|      case TrackModifyDate:
  ------------------
  |  Branch (1484:7): [True: 467, False: 14.2k]
  ------------------
 1485|       |        // A 32-bit integer that specifies (in seconds since midnight, January 1, 1904) when the movie atom was created.
 1486|    467|        if (currentStream_ == Video)
  ------------------
  |  Branch (1486:13): [True: 221, False: 246]
  ------------------
 1487|    221|          xmpData_["Xmp.video.TrackModifyDate"] = buf.read_uint32(0, bigEndian);
 1488|    246|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1488:18): [True: 34, False: 212]
  ------------------
 1489|     34|          xmpData_["Xmp.audio.TrackModifyDate"] = buf.read_uint32(0, bigEndian);
 1490|    467|        break;
 1491|    466|      case TrackID:
  ------------------
  |  Branch (1491:7): [True: 466, False: 14.2k]
  ------------------
 1492|    466|        if (currentStream_ == Video)
  ------------------
  |  Branch (1492:13): [True: 221, False: 245]
  ------------------
 1493|    221|          xmpData_["Xmp.video.TrackID"] = buf.read_uint32(0, bigEndian);
 1494|    245|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1494:18): [True: 34, False: 211]
  ------------------
 1495|     34|          xmpData_["Xmp.audio.TrackID"] = buf.read_uint32(0, bigEndian);
 1496|    466|        break;
 1497|    465|      case TrackDuration:
  ------------------
  |  Branch (1497:7): [True: 465, False: 14.2k]
  ------------------
 1498|    465|        if (currentStream_ == Video)
  ------------------
  |  Branch (1498:13): [True: 221, False: 244]
  ------------------
 1499|    221|          xmpData_["Xmp.video.TrackDuration"] = mvhdTimeScale_ ? buf.read_uint32(0, bigEndian) / mvhdTimeScale_ : 0;
  ------------------
  |  Branch (1499:49): [True: 221, False: 0]
  ------------------
 1500|    244|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1500:18): [True: 34, False: 210]
  ------------------
 1501|     34|          xmpData_["Xmp.audio.TrackDuration"] = mvhdTimeScale_ ? buf.read_uint32(0, bigEndian) / mvhdTimeScale_ : 0;
  ------------------
  |  Branch (1501:49): [True: 34, False: 0]
  ------------------
 1502|    465|        break;
 1503|    463|      case TrackLayer:
  ------------------
  |  Branch (1503:7): [True: 463, False: 14.2k]
  ------------------
 1504|    463|        if (currentStream_ == Video)
  ------------------
  |  Branch (1504:13): [True: 221, False: 242]
  ------------------
 1505|    221|          xmpData_["Xmp.video.TrackLayer"] = buf.read_uint16(0, bigEndian);
 1506|    242|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1506:18): [True: 34, False: 208]
  ------------------
 1507|     34|          xmpData_["Xmp.audio.TrackLayer"] = buf.read_uint16(0, bigEndian);
 1508|    463|        break;
 1509|    460|      case TrackVolume:
  ------------------
  |  Branch (1509:7): [True: 460, False: 14.2k]
  ------------------
 1510|    460|        if (currentStream_ == Video)
  ------------------
  |  Branch (1510:13): [True: 221, False: 239]
  ------------------
 1511|    221|          xmpData_["Xmp.video.TrackVolume"] = (static_cast<int>(buf.read_uint8(0)) + (buf.data()[2] * 0.1)) * 100;
 1512|    239|        else if (currentStream_ == Audio)
  ------------------
  |  Branch (1512:18): [True: 34, False: 205]
  ------------------
 1513|     34|          xmpData_["Xmp.video.TrackVolume"] = (static_cast<int>(buf.read_uint8(0)) + (buf.data()[2] * 0.1)) * 100;
 1514|    460|        break;
 1515|    186|      case ImageWidth:
  ------------------
  |  Branch (1515:7): [True: 186, False: 14.5k]
  ------------------
 1516|    186|        if (currentStream_ == Video) {
  ------------------
  |  Branch (1516:13): [True: 85, False: 101]
  ------------------
 1517|     85|          temp = buf.read_uint16(0, bigEndian) + static_cast<int64_t>((buf.data()[2] * 256 + buf.data()[3]) * 0.01);
 1518|     85|          xmpData_["Xmp.video.Width"] = temp;
 1519|     85|          width_ = temp;
 1520|     85|        }
 1521|    186|        break;
 1522|    185|      case ImageHeight:
  ------------------
  |  Branch (1522:7): [True: 185, False: 14.5k]
  ------------------
 1523|    185|        if (currentStream_ == Video) {
  ------------------
  |  Branch (1523:13): [True: 85, False: 100]
  ------------------
 1524|     85|          temp = buf.read_uint16(0, bigEndian) + static_cast<int64_t>((buf.data()[2] * 256 + buf.data()[3]) * 0.01);
 1525|     85|          xmpData_["Xmp.video.Height"] = temp;
 1526|     85|          height_ = temp;
 1527|     85|        }
 1528|    185|        break;
 1529|  11.1k|      default:
  ------------------
  |  Branch (1529:7): [True: 11.1k, False: 3.63k]
  ------------------
 1530|  11.1k|        break;
 1531|  14.7k|    }
 1532|  14.7k|  }
 1533|    750|  io_->readOrThrow(buf.data(), size % 4);
 1534|    750|}  // QuickTimeVideo::trackHeaderDecoder
_ZN5Exiv214QuickTimeVideo18movieHeaderDecoderEm:
 1536|    215|void QuickTimeVideo::movieHeaderDecoder(size_t size) {
 1537|    215|  DataBuf buf(5);
 1538|    215|  std::memset(buf.data(), 0x0, buf.size());
 1539|    215|  buf.data()[4] = '\0';
 1540|       |
 1541|  2.14k|  for (int i = 0; size / 4 != 0; size -= 4, i++) {
  ------------------
  |  Branch (1541:19): [True: 1.92k, False: 215]
  ------------------
 1542|  1.92k|    io_->readOrThrow(buf.data(), 4);
 1543|       |
 1544|  1.92k|    switch (i) {
 1545|    133|      case MovieHeaderVersion:
  ------------------
  |  Branch (1545:7): [True: 133, False: 1.79k]
  ------------------
 1546|    133|        xmpData_["Xmp.video.MovieHeaderVersion"] = static_cast<int>(buf.read_uint8(0));
 1547|    133|        break;
 1548|    116|      case CreateDate:
  ------------------
  |  Branch (1548:7): [True: 116, False: 1.81k]
  ------------------
 1549|       |        // A 32-bit integer that specifies (in seconds since midnight, January 1, 1904) when the movie atom was created.
 1550|    116|        xmpData_["Xmp.video.DateUTC"] = buf.read_uint32(0, bigEndian);
 1551|    116|        break;
 1552|    112|      case ModifyDate:
  ------------------
  |  Branch (1552:7): [True: 112, False: 1.81k]
  ------------------
 1553|       |        // A 32-bit integer that specifies (in seconds since midnight, January 1, 1904) when the movie atom was created.
 1554|    112|        xmpData_["Xmp.video.ModificationDate"] = buf.read_uint32(0, bigEndian);
 1555|    112|        break;
 1556|    106|      case TimeScale:
  ------------------
  |  Branch (1556:7): [True: 106, False: 1.82k]
  ------------------
 1557|    106|        xmpData_["Xmp.video.TimeScale"] = buf.read_uint32(0, bigEndian);
 1558|    106|        mvhdTimeScale_ = std::max(1U, buf.read_uint32(0, bigEndian));
 1559|    106|        break;
 1560|    105|      case Duration:
  ------------------
  |  Branch (1560:7): [True: 105, False: 1.82k]
  ------------------
 1561|    105|        if (mvhdTimeScale_ != 0) {  // To prevent division by zero
  ------------------
  |  Branch (1561:13): [True: 105, False: 0]
  ------------------
 1562|    105|          xmpData_["Xmp.video.Duration"] = buf.read_uint32(0, bigEndian) * 1000 / mvhdTimeScale_;
 1563|    105|        }
 1564|    105|        break;
 1565|    105|      case PreferredRate:
  ------------------
  |  Branch (1565:7): [True: 105, False: 1.82k]
  ------------------
 1566|    105|        xmpData_["Xmp.video.PreferredRate"] =
 1567|    105|            buf.read_uint16(0, bigEndian) + ((buf.data()[2] * 256 + buf.data()[3]) * 0.01);
 1568|    105|        break;
 1569|    105|      case PreferredVolume:
  ------------------
  |  Branch (1569:7): [True: 105, False: 1.82k]
  ------------------
 1570|    105|        xmpData_["Xmp.video.PreferredVolume"] = (static_cast<int>(buf.read_uint8(0)) + (buf.data()[2] * 0.1)) * 100;
 1571|    105|        break;
 1572|     44|      case PreviewTime:
  ------------------
  |  Branch (1572:7): [True: 44, False: 1.88k]
  ------------------
 1573|     44|        xmpData_["Xmp.video.PreviewTime"] = buf.read_uint32(0, bigEndian);
 1574|     44|        break;
 1575|     44|      case PreviewDuration:
  ------------------
  |  Branch (1575:7): [True: 44, False: 1.88k]
  ------------------
 1576|     44|        xmpData_["Xmp.video.PreviewDuration"] = buf.read_uint32(0, bigEndian);
 1577|     44|        break;
 1578|     40|      case PosterTime:
  ------------------
  |  Branch (1578:7): [True: 40, False: 1.88k]
  ------------------
 1579|     40|        xmpData_["Xmp.video.PosterTime"] = buf.read_uint32(0, bigEndian);
 1580|     40|        break;
 1581|     39|      case SelectionTime:
  ------------------
  |  Branch (1581:7): [True: 39, False: 1.88k]
  ------------------
 1582|     39|        xmpData_["Xmp.video.SelectionTime"] = buf.read_uint32(0, bigEndian);
 1583|     39|        break;
 1584|     39|      case SelectionDuration:
  ------------------
  |  Branch (1584:7): [True: 39, False: 1.88k]
  ------------------
 1585|     39|        xmpData_["Xmp.video.SelectionDuration"] = buf.read_uint32(0, bigEndian);
 1586|     39|        break;
 1587|     39|      case CurrentTime:
  ------------------
  |  Branch (1587:7): [True: 39, False: 1.88k]
  ------------------
 1588|     39|        xmpData_["Xmp.video.CurrentTime"] = buf.read_uint32(0, bigEndian);
 1589|     39|        break;
 1590|     38|      case NextTrackID:
  ------------------
  |  Branch (1590:7): [True: 38, False: 1.88k]
  ------------------
 1591|     38|        xmpData_["Xmp.video.NextTrackID"] = buf.read_uint32(0, bigEndian);
 1592|     38|        break;
 1593|    862|      default:
  ------------------
  |  Branch (1593:7): [True: 862, False: 1.06k]
  ------------------
 1594|    862|        break;
 1595|  1.92k|    }
 1596|  1.92k|  }
 1597|    215|  io_->readOrThrow(buf.data(), size % 4);
 1598|    215|}  // QuickTimeVideo::movieHeaderDecoder
_ZN5Exiv216newQTimeInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
 1600|  4.09k|Image::UniquePtr newQTimeInstance(BasicIo::UniquePtr io, bool /*create*/) {
 1601|  4.09k|  auto image = std::make_unique<QuickTimeVideo>(std::move(io));
 1602|  4.09k|  if (!image->good()) {
  ------------------
  |  Branch (1602:7): [True: 12, False: 4.07k]
  ------------------
 1603|     12|    return nullptr;
 1604|     12|  }
 1605|  4.07k|  return image;
 1606|  4.09k|}
_ZN5Exiv211isQTimeTypeERNS_7BasicIoEb:
 1608|  20.8k|bool isQTimeType(BasicIo& iIo, bool advance) {
 1609|  20.8k|  auto buf = DataBuf(12);
 1610|  20.8k|  iIo.read(buf.data(), 12);
 1611|       |
 1612|  20.8k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (1612:7): [True: 0, False: 20.8k]
  |  Branch (1612:22): [True: 320, False: 20.5k]
  ------------------
 1613|    320|    return false;
 1614|    320|  }
 1615|  20.5k|  auto qTimeTags = std::array{"PICT", "free", "ftyp", "junk", "mdat", "moov", "pict", "pnot", "skip", "uuid", "wide"};
 1616|       |
 1617|  20.5k|  bool matched = false;
 1618|       |
 1619|   102k|  for (auto const& tag : qTimeTags) {
  ------------------
  |  Branch (1619:24): [True: 102k, False: 4.82k]
  ------------------
 1620|   102k|    auto tmp = buf.cmpBytes(4, tag, 4);
 1621|   102k|    if (tmp == 0) {
  ------------------
  |  Branch (1621:9): [True: 15.7k, False: 87.2k]
  ------------------
 1622|       |      // we only match if we actually know the video type. This is done
 1623|       |      // to avoid matching just on ftyp because bmffimage also has that
 1624|       |      // header.
 1625|  15.7k|      if (Exiv2::find(qTimeFileType, std::string{buf.c_str(8), 4})) {
  ------------------
  |  Branch (1625:11): [True: 12.2k, False: 3.45k]
  ------------------
 1626|  12.2k|        matched = true;
 1627|  12.2k|      }
 1628|  15.7k|      break;
 1629|  15.7k|    }
 1630|   102k|  }
 1631|       |
 1632|  20.5k|  if (!advance || !matched) {
  ------------------
  |  Branch (1632:7): [True: 20.5k, False: 0]
  |  Branch (1632:19): [True: 0, False: 0]
  ------------------
 1633|  20.5k|    iIo.seek(0L, BasicIo::beg);
 1634|  20.5k|  }
 1635|       |
 1636|  20.5k|  return matched;
 1637|  20.8k|}
quicktimevideo.cpp:_ZN5Exiv28InternalL10ignoreListERNS_7DataBufE:
  503|  1.14M|static bool ignoreList(Exiv2::DataBuf& buf) {
  504|  1.14M|  const char ignoreList[13][5] = {
  505|  1.14M|      "mdat", "edts", "junk", "iods", "alis", "stsc", "stsz", "stco", "ctts", "stss", "skip", "wide", "cmvd",
  506|  1.14M|  };
  507|       |
  508|  1.14M|  for (auto i : ignoreList)
  ------------------
  |  Branch (508:15): [True: 14.9M, False: 1.14M]
  ------------------
  509|  14.9M|    if (equalsQTimeTag(buf, i))
  ------------------
  |  Branch (509:9): [True: 1.22k, False: 14.9M]
  ------------------
  510|  1.22k|      return true;
  511|       |
  512|  1.14M|  return false;
  513|  1.14M|}
quicktimevideo.cpp:_ZN5Exiv28InternalL14dataIgnoreListERNS_7DataBufE:
  522|   742k|static bool dataIgnoreList(Exiv2::DataBuf& buf) {
  523|   742k|  const char ignoreList[8][5] = {
  524|   742k|      "moov", "mdia", "minf", "dinf", "alis", "stbl", "cmov", "meta",
  525|   742k|  };
  526|       |
  527|   742k|  for (auto i : ignoreList)
  ------------------
  |  Branch (527:15): [True: 5.92M, False: 380k]
  ------------------
  528|  5.92M|    if (equalsQTimeTag(buf, i))
  ------------------
  |  Branch (528:9): [True: 362k, False: 5.56M]
  ------------------
  529|   362k|      return true;
  530|       |
  531|   380k|  return false;
  532|   742k|}
quicktimevideo.cpp:_ZN5Exiv28InternalL14equalsQTimeTagERNS_7DataBufEPKc:
  492|  35.3M|static bool equalsQTimeTag(Exiv2::DataBuf& buf, const char str[5]) {
  493|  35.3M|  return std::equal(buf.begin(), buf.begin() + 4, str,
  494|  35.3M|                    [](auto b, auto s) { return std::tolower(b) == std::tolower(s); });
  495|  35.3M|}
quicktimevideo.cpp:_ZZN5Exiv28InternalL14equalsQTimeTagERNS_7DataBufEPKcENK3$_0clIhcEEDaT_T0_:
  494|  39.3M|                    [](auto b, auto s) { return std::tolower(b) == std::tolower(s); });
quicktimevideo.cpp:_ZN5Exiv2L10readStringERNS_7BasicIoEm:
  627|  3.06k|static std::string readString(BasicIo& io, size_t size) {
  628|  3.06k|  enforce(size <= io.size() - io.tell(), Exiv2::ErrorCode::kerCorruptedMetadata);
  629|  3.06k|  Exiv2::DataBuf str(size + 1);
  630|  3.06k|  io.readOrThrow(str.data(), size);
  631|  3.06k|  str.write_uint8(size, 0);  // nul-terminate string
  632|  3.06k|  return Exiv2::toString(str.data());
  633|  3.06k|}

_ZN5Exiv28RafImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   25|    182|    Image(ImageType::raf, mdExif | mdIptc | mdXmp, std::move(io)) {
   26|    182|}  // RafImage::RafImage
_ZNK5Exiv28RafImage8mimeTypeEv:
   28|     29|std::string RafImage::mimeType() const {
   29|     29|  return "image/x-fuji-raf";
   30|     29|}
_ZNK5Exiv28RafImage10pixelWidthEv:
   32|     10|uint32_t RafImage::pixelWidth() const {
   33|     10|  if (pixelWidth_ != 0)
  ------------------
  |  Branch (33:7): [True: 0, False: 10]
  ------------------
   34|      0|    return pixelWidth_;
   35|       |
   36|     10|  auto widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Fujifilm.RawImageFullWidth"));
   37|     10|  if (widthIter == exifData_.end() || widthIter->count() == 0)
  ------------------
  |  Branch (37:7): [True: 10, False: 0]
  |  Branch (37:7): [True: 10, False: 0]
  |  Branch (37:39): [True: 0, False: 0]
  ------------------
   38|     10|    return 0;
   39|      0|  return widthIter->toUint32();
   40|     10|}
_ZNK5Exiv28RafImage11pixelHeightEv:
   42|     10|uint32_t RafImage::pixelHeight() const {
   43|     10|  if (pixelHeight_ != 0)
  ------------------
  |  Branch (43:7): [True: 0, False: 10]
  ------------------
   44|      0|    return pixelHeight_;
   45|       |
   46|     10|  auto heightIter = exifData_.findKey(Exiv2::ExifKey("Exif.Fujifilm.RawImageFullHeight"));
   47|     10|  if (heightIter == exifData_.end() || heightIter->count() == 0)
  ------------------
  |  Branch (47:7): [True: 10, False: 0]
  |  Branch (47:7): [True: 10, False: 0]
  |  Branch (47:40): [True: 0, False: 0]
  ------------------
   48|     10|    return 0;
   49|      0|  return heightIter->toUint32();
   50|     10|}
_ZN5Exiv28RafImage12readMetadataEv:
  252|    182|void RafImage::readMetadata() {
  253|       |#ifdef EXIV2_DEBUG_MESSAGES
  254|       |  std::cerr << "Reading RAF file " << io_->path() << "\n";
  255|       |#endif
  256|    182|  if (io_->open() != 0)
  ------------------
  |  Branch (256:7): [True: 0, False: 182]
  ------------------
  257|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  258|    182|  IoCloser closer(*io_);
  259|       |  // Ensure that this is the correct image type
  260|    182|  if (!isRafType(*io_, false)) {
  ------------------
  |  Branch (260:7): [True: 0, False: 182]
  ------------------
  261|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (261:9): [True: 0, False: 0]
  |  Branch (261:25): [True: 0, False: 0]
  ------------------
  262|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  263|      0|    throw Error(ErrorCode::kerNotAnImage, "RAF");
  264|      0|  }
  265|       |
  266|    182|  clearMetadata();
  267|       |
  268|    182|  if (io_->seek(84, BasicIo::beg) != 0)
  ------------------
  |  Branch (268:7): [True: 11, False: 171]
  ------------------
  269|     11|    throw Error(ErrorCode::kerFailedToReadImageData);
  270|    171|  byte jpg_img_offset[4];
  271|    171|  if (io_->read(jpg_img_offset, 4) != 4)
  ------------------
  |  Branch (271:7): [True: 10, False: 161]
  ------------------
  272|     10|    throw Error(ErrorCode::kerFailedToReadImageData);
  273|    161|  byte jpg_img_length[4];
  274|    161|  if (io_->read(jpg_img_length, 4) != 4)
  ------------------
  |  Branch (274:7): [True: 10, False: 151]
  ------------------
  275|     10|    throw Error(ErrorCode::kerFailedToReadImageData);
  276|    151|  uint32_t jpg_img_off_u32 = Exiv2::getULong(jpg_img_offset, bigEndian);
  277|    151|  uint32_t jpg_img_len_u32 = Exiv2::getULong(jpg_img_length, bigEndian);
  278|       |
  279|    151|  Internal::enforce(Safe::add(jpg_img_off_u32, jpg_img_len_u32) <= io_->size(), ErrorCode::kerCorruptedMetadata);
  280|       |
  281|    151|  auto jpg_img_off = static_cast<long>(jpg_img_off_u32);
  282|    151|  auto jpg_img_len = static_cast<long>(jpg_img_len_u32);
  283|       |
  284|    151|  Internal::enforce(jpg_img_len >= 12, ErrorCode::kerCorruptedMetadata);
  285|       |
  286|    151|  DataBuf jpg_buf(jpg_img_len);
  287|    151|  if (io_->seek(jpg_img_off, BasicIo::beg) != 0)
  ------------------
  |  Branch (287:7): [True: 0, False: 151]
  ------------------
  288|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  289|       |
  290|    151|  if (!jpg_buf.empty()) {
  ------------------
  |  Branch (290:7): [True: 85, False: 66]
  ------------------
  291|     85|    io_->read(jpg_buf.data(), jpg_buf.size());
  292|     85|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (292:9): [True: 0, False: 85]
  |  Branch (292:25): [True: 0, False: 85]
  ------------------
  293|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  294|     85|  }
  295|       |
  296|       |  // Retrieve metadata from embedded JPEG preview image.
  297|    151|  try {
  298|    151|    auto jpg_io = std::make_unique<Exiv2::MemIo>(jpg_buf.data(), jpg_buf.size());
  299|    151|    auto jpg_img = JpegImage(std::move(jpg_io), false);
  300|    151|    jpg_img.readMetadata();
  301|    151|    setByteOrder(jpg_img.byteOrder());
  302|    151|    xmpData_ = jpg_img.xmpData();
  303|    151|    exifData_ = jpg_img.exifData();
  304|    151|    iptcData_ = jpg_img.iptcData();
  305|    151|    comment_ = jpg_img.comment();
  306|    151|  } catch (const Exiv2::Error&) {
  307|     80|  }
  308|       |
  309|    151|  exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(jpg_img_offset, bigEndian);
  310|     85|  exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(jpg_img_length, bigEndian);
  311|       |
  312|       |  // Todo: parse the proprietary metadata structure
  313|       |  //       at offset 92 for pixelWidth_ & pixelHeight_
  314|       |  // See https://libopenraw.freedesktop.org/formats/raf/
  315|       |  // and https://exiftool.org/TagNames/FujiFilm.html#RAF
  316|       |
  317|       |  // parse the tiff
  318|     85|  std::array<byte, 4> readBuff;
  319|     85|  if (io_->seek(100, BasicIo::beg) != 0)
  ------------------
  |  Branch (319:7): [True: 14, False: 71]
  ------------------
  320|     14|    throw Error(ErrorCode::kerFailedToReadImageData);
  321|     71|  if (io_->read(readBuff.data(), 4) != 4)
  ------------------
  |  Branch (321:7): [True: 11, False: 60]
  ------------------
  322|     11|    throw Error(ErrorCode::kerFailedToReadImageData);
  323|     60|  uint32_t tiffOffset = Exiv2::getULong(readBuff.data(), bigEndian);
  324|       |
  325|     60|  if (io_->read(readBuff.data(), 4) != 4)
  ------------------
  |  Branch (325:7): [True: 10, False: 50]
  ------------------
  326|     10|    throw Error(ErrorCode::kerFailedToReadImageData);
  327|     50|  uint32_t tiffLength = Exiv2::getULong(readBuff.data(), bigEndian);
  328|       |
  329|       |  // sanity check.  Does tiff lie inside the file?
  330|     50|  Internal::enforce(Safe::add(tiffOffset, tiffLength) <= io_->size(), ErrorCode::kerCorruptedMetadata);
  331|       |
  332|     50|  if (io_->seek(tiffOffset, BasicIo::beg) != 0)
  ------------------
  |  Branch (332:7): [True: 0, False: 50]
  ------------------
  333|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
  334|       |
  335|       |  // Check if this really is a tiff and then call the tiff parser.
  336|       |  // Check is needed because some older models just embed a raw bitstream.
  337|       |  // For those files we skip the parsing step.
  338|     50|  if (io_->read(readBuff.data(), 4) != 4) {
  ------------------
  |  Branch (338:7): [True: 10, False: 40]
  ------------------
  339|     10|    throw Error(ErrorCode::kerFailedToReadImageData);
  340|     10|  }
  341|     40|  io_->seek(-4, BasicIo::cur);
  342|     40|  const std::array<byte, 4> Id1{0x49, 0x49, 0x2A, 0x00};
  343|     40|  const std::array<byte, 4> Id2{0x4D, 0x4D, 0x00, 0x2A};
  344|     40|  if (readBuff == Id1 || readBuff == Id2) {
  ------------------
  |  Branch (344:7): [True: 21, False: 19]
  |  Branch (344:26): [True: 0, False: 19]
  ------------------
  345|      2|    DataBuf tiff(tiffLength);
  346|      2|    io_->read(tiff.data(), tiff.size());
  347|       |
  348|      2|    if (!io_->error() && !io_->eof()) {
  ------------------
  |  Branch (348:9): [True: 2, False: 0]
  |  Branch (348:26): [True: 2, False: 0]
  ------------------
  349|      2|      TiffParser::decode(exifData_, iptcData_, xmpData_, tiff.c_data(), tiff.size());
  350|      2|    }
  351|      2|  }
  352|     40|}
_ZN5Exiv214newRafInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  361|    182|Image::UniquePtr newRafInstance(BasicIo::UniquePtr io, bool create) {
  362|    182|  auto image = std::make_unique<RafImage>(std::move(io), create);
  363|    182|  if (!image->good()) {
  ------------------
  |  Branch (363:7): [True: 0, False: 182]
  ------------------
  364|      0|    return nullptr;
  365|      0|  }
  366|    182|  return image;
  367|    182|}
_ZN5Exiv29isRafTypeERNS_7BasicIoEb:
  369|  20.5k|bool isRafType(BasicIo& iIo, bool advance) {
  370|  20.5k|  const int32_t len = 8;
  371|  20.5k|  constexpr std::array<byte, len> RafId{'F', 'U', 'J', 'I', 'F', 'I', 'L', 'M'};
  372|  20.5k|  std::array<byte, len> buf;
  373|  20.5k|  iIo.read(buf.data(), len);
  374|  20.5k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (374:7): [True: 0, False: 20.5k]
  |  Branch (374:22): [True: 0, False: 20.5k]
  ------------------
  375|      0|    return false;
  376|      0|  }
  377|  20.5k|  bool rc = buf == RafId;
  378|  20.5k|  if (!advance || !rc) {
  ------------------
  |  Branch (378:7): [True: 20.5k, False: 0]
  |  Branch (378:19): [True: 0, False: 0]
  ------------------
  379|  20.5k|    iIo.seek(-len, BasicIo::cur);
  380|  20.5k|  }
  381|  20.5k|  return rc;
  382|  20.5k|}

_ZN5Exiv29RiffVideoC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
  364|    782|RiffVideo::RiffVideo(BasicIo::UniquePtr io) : Image(ImageType::riff, mdNone, std::move(io)) {
  365|    782|}  // RiffVideo::RiffVideo
_ZNK5Exiv29RiffVideo8mimeTypeEv:
  367|    875|std::string RiffVideo::mimeType() const {
  368|    875|  return "video/riff";
  369|    875|}
_ZN5Exiv29RiffVideo12readMetadataEv:
  374|    782|void RiffVideo::readMetadata() {
  375|    782|  if (io_->open() != 0)
  ------------------
  |  Branch (375:7): [True: 0, False: 782]
  ------------------
  376|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  377|       |
  378|       |  // Ensure that this is the correct image type
  379|    782|  if (!isRiffType(*io_, false)) {
  ------------------
  |  Branch (379:7): [True: 0, False: 782]
  ------------------
  380|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (380:9): [True: 0, False: 0]
  |  Branch (380:25): [True: 0, False: 0]
  ------------------
  381|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  382|      0|    throw Error(ErrorCode::kerNotAnImage, "RIFF");
  383|      0|  }
  384|       |
  385|    782|  IoCloser closer(*io_);
  386|    782|  clearMetadata();
  387|       |
  388|    782|  xmpData_["Xmp.video.FileSize"] = io_->size();
  389|    782|  xmpData_["Xmp.video.MimeType"] = mimeType();
  390|       |
  391|    782|  HeaderReader header(io_);
  392|    782|  xmpData_["Xmp.video.Container"] = header.getId();
  393|       |
  394|    782|  xmpData_["Xmp.video.FileType"] = readStringTag(io_);
  395|       |
  396|    782|  decodeBlocks();
  397|    782|}  // RiffVideo::readMetadata
_ZN5Exiv29RiffVideo12HeaderReaderC2ERKNSt3__110unique_ptrINS_7BasicIoENS2_14default_deleteIS4_EEEE:
  399|  11.7k|RiffVideo::HeaderReader::HeaderReader(const BasicIo::UniquePtr& io) {
  400|  11.7k|  Internal::enforce(io->size() > io->tell() + DWORD + DWORD, Exiv2::ErrorCode::kerCorruptedMetadata);
  401|  11.7k|  id_ = readStringTag(io);
  402|  11.7k|  size_ = readDWORDTag(io);
  403|  11.7k|}
_ZN5Exiv29RiffVideo5equalERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
  405|  77.9k|bool RiffVideo::equal(const std::string& str1, const std::string& str2) {
  406|  77.9k|  if (str1.size() != str2.size())
  ------------------
  |  Branch (406:7): [True: 49.1k, False: 28.8k]
  ------------------
  407|  49.1k|    return false;
  408|       |
  409|  28.8k|  return Internal::upper(str1) == str2;
  410|  77.9k|}
_ZN5Exiv29RiffVideo8readListERKNS0_12HeaderReaderE:
  412|  1.46k|void RiffVideo::readList(const HeaderReader& header_) {
  413|  1.46k|  std::string chunk_type = readStringTag(io_);
  414|       |
  415|       |#ifdef EXIV2_DEBUG_MESSAGES
  416|       |  EXV_INFO << "-> Reading list : id= " << header_.getId() << "  type= " << chunk_type << " size= " << header_.getSize()
  417|       |           << "(" << io_->tell() << "/" << io_->size() << ")" << '\n';
  418|       |#endif
  419|       |
  420|  1.46k|  if (equal(chunk_type, CHUNK_ID_INFO))
  ------------------
  |  Branch (420:7): [True: 527, False: 933]
  ------------------
  421|    527|    readInfoListChunk(header_.getSize());
  422|    933|  else if (equal(chunk_type, CHUNK_ID_MOVI)) {
  ------------------
  |  Branch (422:12): [True: 212, False: 721]
  ------------------
  423|    212|    readMoviList(header_.getSize());
  424|    212|  }
  425|  1.46k|}
_ZN5Exiv29RiffVideo9readChunkERKNS0_12HeaderReaderE:
  427|  9.35k|void RiffVideo::readChunk(const HeaderReader& header_) {
  428|       |#ifdef EXIV2_DEBUG_MESSAGES
  429|       |  if (header_.getSize())
  430|       |    EXV_INFO << "--> Reading Chunk : [" << header_.getId() << "] size= " << header_.getSize() << "(" << io_->tell()
  431|       |             << "/" << io_->size() << ")" << '\n';
  432|       |#endif
  433|       |
  434|  9.35k|  if (equal(header_.getId(), CHUNK_ID_AVIH))
  ------------------
  |  Branch (434:7): [True: 1.00k, False: 8.34k]
  ------------------
  435|  1.00k|    readAviHeader();
  436|  8.34k|  else if (equal(header_.getId(), CHUNK_ID_STRH))
  ------------------
  |  Branch (436:12): [True: 849, False: 7.49k]
  ------------------
  437|    849|    readStreamHeader();
  438|  7.49k|  else if (equal(header_.getId(), CHUNK_ID_STRF))
  ------------------
  |  Branch (438:12): [True: 873, False: 6.62k]
  ------------------
  439|    873|    readStreamFormat(header_.getSize());
  440|  6.62k|  else if (equal(header_.getId(), CHUNK_ID_FMT)) {
  ------------------
  |  Branch (440:12): [True: 898, False: 5.72k]
  ------------------
  441|    898|    streamType_ = Audio;
  442|    898|    readStreamFormat(header_.getSize());
  443|  5.72k|  } else if (equal(header_.getId(), CHUNK_ID_STRD))
  ------------------
  |  Branch (443:14): [True: 190, False: 5.53k]
  ------------------
  444|    190|    readStreamData(header_.getSize());
  445|  5.53k|  else if (equal(header_.getId(), CHUNK_ID_STRN))
  ------------------
  |  Branch (445:12): [True: 72, False: 5.46k]
  ------------------
  446|     72|    StreamName(header_.getSize());
  447|  5.46k|  else if (equal(header_.getId(), CHUNK_ID_VPRP))
  ------------------
  |  Branch (447:12): [True: 202, False: 5.26k]
  ------------------
  448|    202|    readVPRPChunk(header_.getSize());
  449|  5.26k|  else if (equal(header_.getId(), CHUNK_ID_IDX1))
  ------------------
  |  Branch (449:12): [True: 153, False: 5.11k]
  ------------------
  450|    153|    readIndexChunk(header_.getSize());
  451|  5.11k|  else if (equal(header_.getId(), CHUNK_ID_DATA))
  ------------------
  |  Branch (451:12): [True: 136, False: 4.97k]
  ------------------
  452|    136|    readDataChunk(header_.getSize());
  453|  4.97k|  else if (equal(header_.getId(), CHUNK_ID_JUNK))
  ------------------
  |  Branch (453:12): [True: 73, False: 4.90k]
  ------------------
  454|     73|    readJunk(header_.getSize());
  455|  4.90k|  else {
  456|       |#ifdef EXIV2_DEBUG_MESSAGES
  457|       |    if (header_.getSize())
  458|       |      EXV_WARNING << "--> Ignoring Chunk : " << header_.getId() << "] size= " << header_.getSize() << "(" << io_->tell()
  459|       |                  << "/" << io_->size() << ")" << '\n';
  460|       |#endif
  461|  4.90k|    io_->seekOrThrow(io_->tell() + header_.getSize(), BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  462|  4.90k|  }
  463|  9.35k|}
_ZN5Exiv29RiffVideo12decodeBlocksEv:
  465|    782|void RiffVideo::decodeBlocks() {
  466|  11.0k|  do {
  467|  11.0k|    if (HeaderReader header(io_); equal(header.getId(), CHUNK_ID_LIST)) {
  ------------------
  |  Branch (467:35): [True: 1.46k, False: 9.54k]
  ------------------
  468|  1.46k|      readList(header);
  469|  9.54k|    } else {
  470|  9.54k|      readChunk(header);
  471|  9.54k|    }
  472|  11.0k|  } while (!io_->eof() && io_->tell() < io_->size());
  ------------------
  |  Branch (472:12): [True: 10.2k, False: 742]
  |  Branch (472:27): [True: 10.2k, False: 40]
  ------------------
  473|    782|}  // RiffVideo::decodeBlock
_ZN5Exiv29RiffVideo13readAviHeaderEv:
  475|  1.00k|void RiffVideo::readAviHeader() {
  476|       |#ifdef EXIV2_DEBUG_MESSAGES
  477|       |  EXV_INFO << "--> dwMicroSecPerFrame    = " << readDWORDTag(io_) << '\n';
  478|       |  EXV_INFO << "--> dwMaxBytesPerSec      = " << readDWORDTag(io_) << '\n';
  479|       |  EXV_INFO << "--> dwPaddingGranularity  = " << readDWORDTag(io_) << '\n';
  480|       |  EXV_INFO << "--> dwFlags               = " << readDWORDTag(io_) << '\n';
  481|       |  EXV_INFO << "--> dwTotalFrames         = " << readDWORDTag(io_) << '\n';
  482|       |  EXV_INFO << "--> dwInitialFrames       = " << readDWORDTag(io_) << '\n';
  483|       |  EXV_INFO << "--> dwStreams             = " << readDWORDTag(io_) << '\n';
  484|       |  EXV_INFO << "--> dwSuggestedBufferSize = " << readDWORDTag(io_) << '\n';
  485|       |  EXV_INFO << "--> dwWidth               = " << readDWORDTag(io_) << '\n';
  486|       |  EXV_INFO << "--> dwHeight              = " << readDWORDTag(io_) << '\n';
  487|       |  EXV_INFO << "--> dwReserved1           = " << readDWORDTag(io_) << '\n';
  488|       |  EXV_INFO << "--> dwReserved2           = " << readDWORDTag(io_) << '\n';
  489|       |  EXV_INFO << "--> dwReserved3           = " << readDWORDTag(io_) << '\n';
  490|       |  EXV_INFO << "--> dwReserved4           = " << readDWORDTag(io_) << '\n';
  491|       |  if (LogMsg::info >= LogMsg::level() && LogMsg::handler())
  492|       |    io_->seekOrThrow(io_->tell() - DWORD * 14, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  493|       |#endif
  494|       |
  495|  1.00k|  uint32_t TimeBetweenFrames = readDWORDTag(io_);
  496|  1.00k|  xmpData_["Xmp.video.MicroSecPerFrame"] = TimeBetweenFrames;
  497|  1.00k|  double frame_rate = 1000000. / TimeBetweenFrames;
  498|       |
  499|  1.00k|  xmpData_["Xmp.video.MaxDataRate"] = readDWORDTag(io_);  // MaximumDataRate
  500|       |
  501|  1.00k|  io_->seekOrThrow(io_->tell() + (DWORD * 2), BasicIo::beg,
  502|  1.00k|                   ErrorCode::kerFailedToReadImageData);  // ignore PaddingGranularity and Flags
  503|       |
  504|  1.00k|  uint32_t frame_count = readDWORDTag(io_);  // TotalNumberOfFrames
  505|  1.00k|  xmpData_["Xmp.video.FrameCount"] = frame_count;
  506|       |
  507|  1.00k|  io_->seekOrThrow(io_->tell() + DWORD, BasicIo::beg,
  508|  1.00k|                   ErrorCode::kerFailedToReadImageData);  // ignore NumberOfInitialFrames
  509|       |
  510|  1.00k|  xmpData_["Xmp.audio.ChannelType"] = getStreamType(readDWORDTag(io_));  // NumberOfStreams
  511|       |
  512|  1.00k|  xmpData_["Xmp.video.StreamCount"] = readDWORDTag(io_);  // SuggestedBufferSize
  513|       |
  514|  1.00k|  uint32_t width = readDWORDTag(io_);
  515|  1.00k|  xmpData_["Xmp.video.Width"] = width;
  516|       |
  517|  1.00k|  uint32_t height = readDWORDTag(io_);
  518|  1.00k|  xmpData_["Xmp.video.Height"] = height;
  519|       |
  520|  1.00k|  io_->seekOrThrow(io_->tell() + (DWORD * 4), BasicIo::beg,
  521|  1.00k|                   ErrorCode::kerFailedToReadImageData);  // TimeScale, DataRate, StartTime, DataLength
  522|       |
  523|  1.00k|  xmpData_["Xmp.video.AspectRatio"] = getAspectRatio(width, height);
  524|       |
  525|  1.00k|  fillDuration(frame_rate, frame_count);
  526|  1.00k|}
_ZN5Exiv29RiffVideo16readStreamHeaderEv:
  528|    849|void RiffVideo::readStreamHeader() {
  529|    849|  std::string stream = readStringTag(io_);
  530|    849|  streamType_ = (equal(stream, "VIDS")) ? Video : Audio;
  ------------------
  |  Branch (530:17): [True: 200, False: 649]
  ------------------
  531|       |
  532|       |#ifdef EXIV2_DEBUG_MESSAGES
  533|       |  EXV_INFO << "--> fccType                = " << stream << '\n';
  534|       |  EXV_INFO << "--> fccHandler             = " << readStringTag(io_) << '\n';
  535|       |  EXV_INFO << "--> dwFlags                = " << readDWORDTag(io_) << '\n';
  536|       |  EXV_INFO << "--> wPriority              = " << readWORDTag(io_) << '\n';
  537|       |  EXV_INFO << "--> wLanguage              = " << readWORDTag(io_) << '\n';
  538|       |  EXV_INFO << "--> dwInitialFrames        = " << readDWORDTag(io_) << '\n';  // 20
  539|       |  EXV_INFO << "--> dwScale                = " << readDWORDTag(io_) << '\n';
  540|       |  EXV_INFO << "--> dwRate                 = " << readDWORDTag(io_) << '\n';
  541|       |  EXV_INFO << "--> dwStart                = " << readDWORDTag(io_) << '\n';
  542|       |  EXV_INFO << "--> dwLength               = " << readDWORDTag(io_) << '\n';
  543|       |  EXV_INFO << "--> dwSuggestedBufferSize  = " << readDWORDTag(io_) << '\n';  // 40
  544|       |  EXV_INFO << "--> dwSampleSize           = " << readDWORDTag(io_) << '\n';
  545|       |  EXV_INFO << "--> Left                   = " << readWORDTag(io_) << '\n';
  546|       |  EXV_INFO << "--> top                    = " << readWORDTag(io_) << '\n';
  547|       |  EXV_INFO << "--> right                  = " << readWORDTag(io_) << '\n';
  548|       |  EXV_INFO << "--> bottom                 = " << readWORDTag(io_) << '\n';
  549|       |  EXV_INFO << "--> XXXXXX                 = " << readDWORDTag(io_) << '\n';  // 56
  550|       |  if (LogMsg::info >= LogMsg::level() && LogMsg::handler())
  551|       |    io_->seekOrThrow(io_->tell() - DWORD * 13, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  552|       |#endif
  553|       |
  554|    849|  xmpData_["Xmp.video.Codec"] = readStringTag(io_);  // DataHandler
  555|       |
  556|    849|  io_->seekOrThrow(io_->tell() + (DWORD * 2) + (WORD * 2), BasicIo::beg,
  557|    849|                   ErrorCode::kerFailedToReadImageData);  // dwFlags, wPriority, wLanguage, dwInitialFrames
  558|       |
  559|    849|  uint32_t divisor = readDWORDTag(io_);  // TimeScale
  560|       |
  561|    849|  if (divisor) {
  ------------------
  |  Branch (561:7): [True: 310, False: 539]
  ------------------
  562|    310|    auto rate = static_cast<double>(readDWORDTag(io_)) / divisor;
  563|    310|    xmpData_[(streamType_ == Video) ? "Xmp.video.FrameRate" : "Xmp.audio.SampleRate"] = rate;
  ------------------
  |  Branch (563:14): [True: 133, False: 177]
  ------------------
  564|    310|  }
  565|    849|  io_->seekOrThrow(io_->tell() + DWORD, BasicIo::beg, ErrorCode::kerFailedToReadImageData);  // dwStart
  566|       |
  567|    849|  if (divisor) {
  ------------------
  |  Branch (567:7): [True: 298, False: 551]
  ------------------
  568|    298|    auto frame_count = static_cast<double>(readDWORDTag(io_)) / divisor;  // DataLength
  569|    298|    xmpData_[(streamType_ == Video) ? "Xmp.video.FrameCount" : "Xmp.audio.FrameCount"] = frame_count;
  ------------------
  |  Branch (569:14): [True: 132, False: 166]
  ------------------
  570|    298|  }
  571|       |
  572|    849|  io_->seekOrThrow(io_->tell() + DWORD, BasicIo::beg, ErrorCode::kerFailedToReadImageData);  // dwSuggestedBufferSize
  573|       |
  574|    849|  xmpData_[(streamType_ == Video) ? "Xmp.video.VideoQuality" : "Xmp.video.StreamQuality"] = readDWORDTag(io_);
  ------------------
  |  Branch (574:12): [True: 196, False: 653]
  ------------------
  575|       |
  576|    849|  xmpData_[(streamType_ == Video) ? "Xmp.video.VideoSampleSize" : "Xmp.video.StreamSampleSize"] = readDWORDTag(io_);
  ------------------
  |  Branch (576:12): [True: 194, False: 655]
  ------------------
  577|    849|  io_->seekOrThrow(io_->tell() + (DWORD * 2), BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  578|    849|}
_ZN5Exiv29RiffVideo16readStreamFormatEm:
  580|  1.77k|void RiffVideo::readStreamFormat(uint64_t size_) {
  581|       |  // The structure of the strf chunk depends on the media type. Video streams use the BITMAPINFOHEADER structure,
  582|       |  // whereas audio streams use the WAVEFORMATEX structure.
  583|       |
  584|       |#ifdef EXIV2_DEBUG_MESSAGES
  585|       |  if (streamType_ == Audio) {
  586|       |    EXV_INFO << "--> wFormatTag      = " << readWORDTag(io_) << '\n';
  587|       |    EXV_INFO << "--> nChannels       = " << readWORDTag(io_) << '\n';
  588|       |    EXV_INFO << "--> nSamplesPerSec  = " << readDWORDTag(io_) << '\n';
  589|       |    EXV_INFO << "--> nAvgBytesPerSec = " << readDWORDTag(io_) << '\n';
  590|       |    EXV_INFO << "--> nBlockAlign     = " << readWORDTag(io_) << '\n';
  591|       |    EXV_INFO << "--> wBitsPerSample  = " << readWORDTag(io_) << '\n';
  592|       |    if (LogMsg::info >= LogMsg::level() && LogMsg::handler())
  593|       |      io_->seekOrThrow(io_->tell() - DWORD * 4, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  594|       |  } else if (streamType_ == Video) {
  595|       |    EXV_INFO << "--> biSize            = " << readDWORDTag(io_) << '\n';
  596|       |    EXV_INFO << "--> biWidth           = " << readDWORDTag(io_) << '\n';
  597|       |    EXV_INFO << "--> biHeight          = " << readDWORDTag(io_) << '\n';
  598|       |    EXV_INFO << "--> biPlanes          = " << readWORDTag(io_) << '\n';
  599|       |    EXV_INFO << "--> biBitCount        = " << readWORDTag(io_) << '\n';
  600|       |    EXV_INFO << "--> biCompression     = " << readDWORDTag(io_) << '\n';
  601|       |    EXV_INFO << "--> biSizeImage       = " << readDWORDTag(io_) << '\n';
  602|       |    EXV_INFO << "--> biXPelsPerMeter   = " << readDWORDTag(io_) << '\n';
  603|       |    EXV_INFO << "--> biYPelsPerMeter   = " << readDWORDTag(io_) << '\n';
  604|       |    EXV_INFO << "--> biClrUsed         = " << readDWORDTag(io_) << '\n';
  605|       |    EXV_INFO << "--> biClrImportant    = " << readDWORDTag(io_) << '\n';
  606|       |    if (LogMsg::info >= LogMsg::level() && LogMsg::handler())
  607|       |      io_->seekOrThrow(io_->tell() - DWORD * 10, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  608|       |  }
  609|       |#endif
  610|       |
  611|  1.77k|  if (streamType_ == Video) {
  ------------------
  |  Branch (611:7): [True: 798, False: 973]
  ------------------
  612|    798|    io_->seekOrThrow(io_->tell() + (DWORD * 3), BasicIo::beg,
  613|    798|                     ErrorCode::kerFailedToReadImageData);  // ignore biSize, biWidth, biHeight
  614|    798|    xmpData_["Xmp.video.Planes"] = readWORDTag(io_);
  615|    798|    xmpData_["Xmp.video.PixelDepth"] = readWORDTag(io_);
  616|    798|    xmpData_["Xmp.video.Compressor"] = readStringTag(io_);
  617|    798|    xmpData_["Xmp.video.ImageLength"] = readDWORDTag(io_);
  618|    798|    xmpData_["Xmp.video.PixelPerMeterX"] = readQWORDTag(io_);
  619|    798|    xmpData_["Xmp.video.PixelPerMeterY"] = readQWORDTag(io_);
  620|    798|    if (uint32_t NumOfColours = readDWORDTag(io_))
  ------------------
  |  Branch (620:18): [True: 534, False: 264]
  ------------------
  621|    534|      xmpData_["Xmp.video.NumOfColours"] = NumOfColours;
  622|    264|    else
  623|    264|      xmpData_["Xmp.video.NumOfColours"] = "Unspecified";
  624|    798|    if (uint32_t NumIfImpColours = readDWORDTag(io_))
  ------------------
  |  Branch (624:18): [True: 160, False: 638]
  ------------------
  625|    160|      xmpData_["Xmp.video.NumIfImpColours"] = NumIfImpColours;
  626|    638|    else
  627|    638|      xmpData_["Xmp.video.NumIfImpColours"] = "All";
  628|    973|  } else if (streamType_ == Audio) {
  ------------------
  |  Branch (628:14): [True: 901, False: 72]
  ------------------
  629|    901|    uint16_t format_tag = readWORDTag(io_);
  630|    901|    if (auto it = Internal::audioEncodingValues.find(format_tag); it != Internal::audioEncodingValues.end())
  ------------------
  |  Branch (630:67): [True: 324, False: 577]
  ------------------
  631|    324|      xmpData_["Xmp.audio.Compressor"] = it->second;
  632|    577|    else
  633|    577|      xmpData_["Xmp.audio.Compressor"] = format_tag;
  634|       |
  635|    901|    xmpData_["Xmp.audio.ChannelType"] = getStreamType(readDWORDTag(io_));
  636|    901|    xmpData_["Xmp.audio.SampleRate"] = readDWORDTag(io_);                                      // nSamplesPerSec
  637|    901|    io_->seekOrThrow(io_->tell() + DWORD, BasicIo::beg, ErrorCode::kerFailedToReadImageData);  // nAvgBytesPerSec
  638|    901|    xmpData_["Xmp.audio.SampleType"] = readDWORDTag(io_);                                      // nBlockAlign
  639|    901|    xmpData_["Xmp.audio.BitsPerSample"] = readDWORDTag(io_);                                   // wBitsPerSample
  640|    901|    if (xmpData_["Xmp.video.FileType"].toString() == "AVI ")
  ------------------
  |  Branch (640:9): [True: 88, False: 813]
  ------------------
  641|     88|      io_->seekOrThrow(io_->tell() + DWORD, BasicIo::beg, ErrorCode::kerFailedToReadImageData);  // cbSize
  642|    901|  } else {
  643|     72|    io_->seekOrThrow(io_->tell() + size_, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  644|     72|  }
  645|  1.77k|}
_ZNK5Exiv29RiffVideo14readStreamDataEm:
  647|    190|void RiffVideo::readStreamData(uint64_t size_) const {
  648|    190|  io_->seekOrThrow(io_->tell() + size_, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  649|    190|}
_ZNK5Exiv29RiffVideo10StreamNameEm:
  651|     72|void RiffVideo::StreamName(uint64_t size_) const {
  652|       |  // This element contains a name for the stream. That stream name should only use plain ASCII, especially not UTF-8.
  653|     72|  io_->seekOrThrow(io_->tell() + size_, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  654|     72|}
_ZN5Exiv29RiffVideo17readInfoListChunkEm:
  656|    527|void RiffVideo::readInfoListChunk(uint64_t size_) {
  657|    527|  uint64_t current_size = DWORD;
  658|  3.74k|  while (current_size < size_) {
  ------------------
  |  Branch (658:10): [True: 3.21k, False: 527]
  ------------------
  659|  3.21k|    std::string type = readStringTag(io_);
  660|  3.21k|    size_t size = readDWORDTag(io_);
  661|  3.21k|    std::string content = readStringTag(io_, size);
  662|  3.21k|    if (auto it = Internal::infoTags.find(type); it != Internal::infoTags.end())
  ------------------
  |  Branch (662:50): [True: 220, False: 2.99k]
  ------------------
  663|    220|      xmpData_[it->second] = content;
  664|  3.21k|    current_size += DWORD * 2;
  665|  3.21k|    current_size += size;
  666|  3.21k|  }
  667|    527|}
_ZNK5Exiv29RiffVideo12readMoviListEm:
  669|    212|void RiffVideo::readMoviList(uint64_t size_) const {
  670|    212|  io_->seekOrThrow(io_->tell() + size_ - DWORD, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  671|    212|}
_ZNK5Exiv29RiffVideo13readVPRPChunkEm:
  673|    202|void RiffVideo::readVPRPChunk(uint64_t size_) const {
  674|       |#ifdef EXIV2_DEBUG_MESSAGES
  675|       |  EXV_INFO << "--> VideoFormatToken         = " << readDWORDTag(io_) << '\n';
  676|       |  EXV_INFO << "--> VideoStandard            = " << readDWORDTag(io_) << '\n';
  677|       |  EXV_INFO << "--> VerticalRefreshRate      = " << readDWORDTag(io_) << '\n';
  678|       |  EXV_INFO << "--> HTotalInT                = " << readDWORDTag(io_) << '\n';
  679|       |  EXV_INFO << "--> VTotalInLines            = " << readDWORDTag(io_) << '\n';
  680|       |  EXV_INFO << "--> FrameAspectRatio Height  = " << readWORDTag(io_) << '\n';
  681|       |  EXV_INFO << "--> FrameAspectRatio Width   = " << readWORDTag(io_) << '\n';
  682|       |  EXV_INFO << "--> FrameWidthInPixels       = " << readDWORDTag(io_) << '\n';
  683|       |  EXV_INFO << "--> FrameHeightInLines       = " << readDWORDTag(io_) << '\n';
  684|       |  EXV_INFO << "--> CompressedBMHeight       = " << readDWORDTag(io_) << '\n';
  685|       |  EXV_INFO << "--> FieldPerFrame            = " << readDWORDTag(io_) << '\n';
  686|       |  EXV_INFO << "--> CompressedBMWidth        = " << readDWORDTag(io_) << '\n';
  687|       |  EXV_INFO << "--> ValidBMHeight            = " << readDWORDTag(io_) << '\n';
  688|       |  EXV_INFO << "--> ValidBMWidth             = " << readDWORDTag(io_) << '\n';
  689|       |  EXV_INFO << "--> ValidBMXOffset           = " << readDWORDTag(io_) << '\n';
  690|       |  EXV_INFO << "--> ValidBMYOffset           = " << readDWORDTag(io_) << '\n';
  691|       |  EXV_INFO << "--> VideoXOffsetInT          = " << readDWORDTag(io_) << '\n';
  692|       |  EXV_INFO << "--> VideoYValidStartLine     = " << readDWORDTag(io_) << '\n';
  693|       |  if (LogMsg::info >= LogMsg::level() && LogMsg::handler())
  694|       |    io_->seekOrThrow(io_->tell() - DWORD * 17, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  695|       |#endif
  696|    202|  io_->seekOrThrow(io_->tell() + size_, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  697|    202|}
_ZNK5Exiv29RiffVideo14readIndexChunkEm:
  699|    153|void RiffVideo::readIndexChunk(uint64_t size_) const {
  700|       |#ifdef EXIV2_DEBUG_MESSAGES
  701|       |  uint64_t current_size = 0;
  702|       |  while (current_size < size_) {
  703|       |    EXV_DEBUG << "--> Identifier               = " << readStringTag(io_) << "\t(" << current_size << "/" << size_ << ")"
  704|       |              << '\n';
  705|       |    EXV_DEBUG << "--> Flags                    = " << readDWORDTag(io_) << "\t(" << current_size << "/" << size_ << ")"
  706|       |              << '\n';
  707|       |    EXV_DEBUG << "--> Offset                   = " << readDWORDTag(io_) << "\t(" << current_size << "/" << size_ << ")"
  708|       |              << '\n';
  709|       |    EXV_DEBUG << "--> Length                   = " << readDWORDTag(io_) << "\t(" << current_size << "/" << size_ << ")"
  710|       |              << '\n';
  711|       |    current_size += DWORD * 4;
  712|       |  }
  713|       |  if (LogMsg::debug >= LogMsg::level() && LogMsg::handler())
  714|       |    io_->seekOrThrow(io_->tell() - size_, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  715|       |#endif
  716|    153|  io_->seekOrThrow(io_->tell() + size_, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  717|    153|}
_ZNK5Exiv29RiffVideo13readDataChunkEm:
  719|    136|void RiffVideo::readDataChunk(uint64_t size_) const {
  720|       |#ifdef EXIV2_DEBUG_MESSAGES
  721|       |  EXV_INFO << "--> Data               = " << readStringTag(io_, static_cast<size_t>(size_)) << '\n';
  722|       |  uint64_t readed_size = size_;
  723|       |  if (size_ % 2 != 0) {
  724|       |    EXV_INFO << "--> pad byte          = " << readStringTag(io_, 1) << '\n';
  725|       |    readed_size += 1;
  726|       |  }
  727|       |  if (LogMsg::info >= LogMsg::level() && LogMsg::handler())
  728|       |    io_->seekOrThrow(io_->tell() - readed_size, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  729|       |#endif
  730|    136|  io_->seekOrThrow(io_->tell() + size_, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  731|    136|  if (size_ % 2 != 0)
  ------------------
  |  Branch (731:7): [True: 69, False: 67]
  ------------------
  732|     69|    io_->seekOrThrow(io_->tell() + 1, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  733|    136|}
_ZNK5Exiv29RiffVideo8readJunkEm:
  735|     73|void RiffVideo::readJunk(uint64_t size_) const {
  736|     73|  io_->seekOrThrow(io_->tell() + size_, BasicIo::beg, ErrorCode::kerFailedToReadImageData);
  737|     73|}
_ZN5Exiv29RiffVideo13getStreamTypeEj:
  739|  1.88k|std::string RiffVideo::getStreamType(uint32_t stream) {
  740|  1.88k|  if (stream == 1)
  ------------------
  |  Branch (740:7): [True: 266, False: 1.62k]
  ------------------
  741|    266|    return "Mono";
  742|  1.62k|  if (stream == 2)
  ------------------
  |  Branch (742:7): [True: 126, False: 1.49k]
  ------------------
  743|    126|    return "Stereo";
  744|  1.49k|  if (stream == 5)
  ------------------
  |  Branch (744:7): [True: 95, False: 1.39k]
  ------------------
  745|     95|    return "5.1 Surround Sound";
  746|  1.39k|  if (stream == 7)
  ------------------
  |  Branch (746:7): [True: 559, False: 840]
  ------------------
  747|    559|    return "7.1 Surround Sound";
  748|    840|  return "Mono";
  749|  1.39k|}
_ZN5Exiv29RiffVideo12fillDurationEdm:
  751|    966|void RiffVideo::fillDuration(double frame_rate, size_t frame_count) {
  752|    966|  if (frame_rate == 0)
  ------------------
  |  Branch (752:7): [True: 0, False: 966]
  ------------------
  753|      0|    return;
  754|       |
  755|    966|  auto duration = static_cast<uint64_t>(frame_count * 1000. / frame_rate);
  756|    966|  xmpData_["Xmp.video.FileDataRate"] = io_->size() / (1048576. * duration);
  757|    966|  xmpData_["Xmp.video.Duration"] = duration;  // Duration in number of seconds
  758|    966|}  // RiffVideo::fillDuration
_ZN5Exiv215newRiffInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  760|    782|Image::UniquePtr newRiffInstance(BasicIo::UniquePtr io, bool /*create*/) {
  761|    782|  auto image = std::make_unique<RiffVideo>(std::move(io));
  762|    782|  if (!image->good()) {
  ------------------
  |  Branch (762:7): [True: 0, False: 782]
  ------------------
  763|      0|    return nullptr;
  764|      0|  }
  765|    782|  return image;
  766|    782|}
_ZN5Exiv210isRiffTypeERNS_7BasicIoEb:
  768|  9.76k|bool isRiffType(BasicIo& iIo, bool advance) {
  769|  9.76k|  constexpr int len = 4;
  770|  9.76k|  const std::array<byte, len> RiffVideoId{'R', 'I', 'F', 'F'};
  771|  9.76k|  std::array<byte, len> buf;
  772|  9.76k|  iIo.read(buf.data(), len);
  773|  9.76k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (773:7): [True: 0, False: 9.76k]
  |  Branch (773:22): [True: 320, False: 9.44k]
  ------------------
  774|    320|    return false;
  775|    320|  }
  776|  9.44k|  bool matched = buf == RiffVideoId;
  777|  9.44k|  if (!advance || !matched) {
  ------------------
  |  Branch (777:7): [True: 9.44k, False: 0]
  |  Branch (777:19): [True: 0, False: 0]
  ------------------
  778|  9.44k|    iIo.seek(-1 * len, BasicIo::cur);
  779|  9.44k|  }
  780|  9.44k|  return matched;
  781|  9.76k|}

_ZN5Exiv28Rw2ImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
   29|     92|Rw2Image::Rw2Image(BasicIo::UniquePtr io) : Image(ImageType::rw2, mdExif | mdIptc | mdXmp, std::move(io)) {
   30|     92|}  // Rw2Image::Rw2Image
_ZNK5Exiv28Rw2Image8mimeTypeEv:
   32|    291|std::string Rw2Image::mimeType() const {
   33|    291|  return "image/x-panasonic-rw2";
   34|    291|}
_ZNK5Exiv28Rw2Image10pixelWidthEv:
   36|     62|uint32_t Rw2Image::pixelWidth() const {
   37|     62|  auto imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.PanasonicRaw.SensorWidth"));
   38|     62|  if (imageWidth == exifData_.end() || imageWidth->count() == 0)
  ------------------
  |  Branch (38:7): [True: 38, False: 24]
  |  Branch (38:7): [True: 49, False: 13]
  |  Branch (38:40): [True: 11, False: 13]
  ------------------
   39|     49|    return 0;
   40|     13|  return imageWidth->toUint32();
   41|     62|}
_ZNK5Exiv28Rw2Image11pixelHeightEv:
   43|     62|uint32_t Rw2Image::pixelHeight() const {
   44|     62|  auto imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.PanasonicRaw.SensorHeight"));
   45|     62|  if (imageHeight == exifData_.end() || imageHeight->count() == 0)
  ------------------
  |  Branch (45:7): [True: 42, False: 20]
  |  Branch (45:7): [True: 52, False: 10]
  |  Branch (45:41): [True: 10, False: 10]
  ------------------
   46|     52|    return 0;
   47|     10|  return imageHeight->toUint32();
   48|     62|}
_ZN5Exiv28Rw2Image12readMetadataEv:
   81|     92|void Rw2Image::readMetadata() {
   82|       |#ifdef EXIV2_DEBUG_MESSAGES
   83|       |  std::cerr << "Reading RW2 file " << io_->path() << "\n";
   84|       |#endif
   85|     92|  if (io_->open() != 0) {
  ------------------
  |  Branch (85:7): [True: 0, False: 92]
  ------------------
   86|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   87|      0|  }
   88|     92|  IoCloser closer(*io_);
   89|       |  // Ensure that this is the correct image type
   90|     92|  if (!isRw2Type(*io_, false)) {
  ------------------
  |  Branch (90:7): [True: 0, False: 92]
  ------------------
   91|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (91:9): [True: 0, False: 0]
  |  Branch (91:25): [True: 0, False: 0]
  ------------------
   92|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   93|      0|    throw Error(ErrorCode::kerNotAnImage, "RW2");
   94|      0|  }
   95|     92|  clearMetadata();
   96|     92|  ByteOrder bo = Rw2Parser::decode(exifData_, iptcData_, xmpData_, io_->mmap(), io_->size());
   97|     92|  setByteOrder(bo);
   98|       |
   99|       |  // A lot more metadata is hidden in the embedded preview image
  100|       |  // Todo: This should go into the Rw2Parser, but for that it needs the Image
  101|     92|  PreviewManager loader(*this);
  102|     92|  PreviewPropertiesList list = loader.getPreviewProperties();
  103|       |  // Todo: What if there are more preview images?
  104|     92|  if (list.size() > 1) {
  ------------------
  |  Branch (104:7): [True: 0, False: 92]
  ------------------
  105|      0|#ifndef SUPPRESS_WARNINGS
  106|      0|    EXV_WARNING << "RW2 image contains more than one preview. None used.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  107|      0|#endif
  108|      0|  }
  109|     92|  if (list.size() != 1)
  ------------------
  |  Branch (109:7): [True: 81, False: 11]
  ------------------
  110|     81|    return;
  111|     11|  ExifData exifData;
  112|     11|  PreviewImage preview = loader.getPreviewImage(*list.begin());
  113|     11|  auto image = ImageFactory::open(preview.pData(), preview.size());
  114|     11|  if (!image) {
  ------------------
  |  Branch (114:7): [True: 0, False: 11]
  ------------------
  115|      0|#ifndef SUPPRESS_WARNINGS
  116|      0|    EXV_WARNING << "Failed to open RW2 preview image.\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  117|      0|#endif
  118|      0|    return;
  119|      0|  }
  120|     11|  image->readMetadata();
  121|     11|  ExifData& prevData = image->exifData();
  122|     11|  if (!prevData.empty()) {
  ------------------
  |  Branch (122:7): [True: 0, False: 11]
  ------------------
  123|       |    // Filter duplicate tags
  124|      0|    for (const auto& pos : exifData_) {
  ------------------
  |  Branch (124:26): [True: 0, False: 0]
  ------------------
  125|      0|      if (pos.ifdId() == IfdId::panaRawId)
  ------------------
  |  Branch (125:11): [True: 0, False: 0]
  ------------------
  126|      0|        continue;
  127|      0|      auto dup = prevData.findKey(ExifKey(pos.key()));
  128|      0|      if (dup != prevData.end()) {
  ------------------
  |  Branch (128:11): [True: 0, False: 0]
  ------------------
  129|       |#ifdef EXIV2_DEBUG_MESSAGES
  130|       |        std::cerr << "Filtering duplicate tag " << pos.key() << " (values '" << pos.value() << "' and '" << dup->value()
  131|       |                  << "')\n";
  132|       |#endif
  133|      0|        prevData.erase(dup);
  134|      0|      }
  135|      0|    }
  136|      0|  }
  137|       |  // Remove tags not applicable for raw images
  138|     11|  static constexpr auto filteredTags = std::array{
  139|     11|      "Exif.Photo.ComponentsConfiguration",
  140|     11|      "Exif.Photo.CompressedBitsPerPixel",
  141|     11|      "Exif.Panasonic.ColorEffect",
  142|     11|      "Exif.Panasonic.Contrast",
  143|     11|      "Exif.Panasonic.NoiseReduction",
  144|     11|      "Exif.Panasonic.ColorMode",
  145|     11|      "Exif.Panasonic.OpticalZoomMode",
  146|     11|      "Exif.Panasonic.Contrast",
  147|     11|      "Exif.Panasonic.Saturation",
  148|     11|      "Exif.Panasonic.Sharpness",
  149|     11|      "Exif.Panasonic.FilmMode",
  150|     11|      "Exif.Panasonic.SceneMode",
  151|     11|      "Exif.Panasonic.WBRedLevel",
  152|     11|      "Exif.Panasonic.WBGreenLevel",
  153|     11|      "Exif.Panasonic.WBBlueLevel",
  154|     11|      "Exif.Photo.ColorSpace",
  155|     11|      "Exif.Photo.PixelXDimension",
  156|     11|      "Exif.Photo.PixelYDimension",
  157|     11|      "Exif.Photo.SceneType",
  158|     11|      "Exif.Photo.CustomRendered",
  159|     11|      "Exif.Photo.DigitalZoomRatio",
  160|     11|      "Exif.Photo.SceneCaptureType",
  161|     11|      "Exif.Photo.GainControl",
  162|     11|      "Exif.Photo.Contrast",
  163|     11|      "Exif.Photo.Saturation",
  164|     11|      "Exif.Photo.Sharpness",
  165|     11|      "Exif.Image.PrintImageMatching",
  166|     11|      "Exif.Image.YCbCrPositioning",
  167|     11|  };
  168|     11|  for (auto&& filteredTag : filteredTags) {
  ------------------
  |  Branch (168:27): [True: 0, False: 11]
  ------------------
  169|      0|    auto pos = prevData.findKey(ExifKey(filteredTag));
  170|      0|    if (pos != prevData.end()) {
  ------------------
  |  Branch (170:9): [True: 0, False: 0]
  ------------------
  171|       |#ifdef EXIV2_DEBUG_MESSAGES
  172|       |      std::cerr << "Exif tag " << pos->key() << " removed\n";
  173|       |#endif
  174|      0|      prevData.erase(pos);
  175|      0|    }
  176|      0|  }
  177|       |
  178|       |  // Add the remaining tags
  179|     11|  for (const auto& pos : prevData) {
  ------------------
  |  Branch (179:24): [True: 0, False: 11]
  ------------------
  180|      0|    exifData_.add(pos);
  181|      0|  }
  182|       |
  183|     11|}  // Rw2Image::readMetadata
_ZN5Exiv29Rw2Parser6decodeERNS_8ExifDataERNS_8IptcDataERNS_7XmpDataEPKhm:
  190|     92|ByteOrder Rw2Parser::decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size) {
  191|     92|  Rw2Header rw2Header;
  192|     92|  return TiffParserWorker::decode(exifData, iptcData, xmpData, pData, size, Tag::pana, TiffMapping::findDecoder,
  193|     92|                                  &rw2Header);
  194|     92|}
_ZN5Exiv214newRw2InstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  198|     92|Image::UniquePtr newRw2Instance(BasicIo::UniquePtr io, bool /*create*/) {
  199|     92|  auto image = std::make_unique<Rw2Image>(std::move(io));
  200|     92|  if (!image->good()) {
  ------------------
  |  Branch (200:7): [True: 0, False: 92]
  ------------------
  201|      0|    return nullptr;
  202|      0|  }
  203|     92|  return image;
  204|     92|}
_ZN5Exiv29isRw2TypeERNS_7BasicIoEb:
  206|  22.3k|bool isRw2Type(BasicIo& iIo, bool advance) {
  207|  22.3k|  const int32_t len = 24;
  208|  22.3k|  byte buf[len];
  209|  22.3k|  iIo.read(buf, len);
  210|  22.3k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (210:7): [True: 0, False: 22.3k]
  |  Branch (210:22): [True: 233, False: 22.0k]
  ------------------
  211|    233|    return false;
  212|    233|  }
  213|  22.0k|  Rw2Header header;
  214|  22.0k|  bool rc = header.read(buf, len);
  215|  22.0k|  if (!advance || !rc) {
  ------------------
  |  Branch (215:7): [True: 22.0k, False: 0]
  |  Branch (215:19): [True: 0, False: 0]
  ------------------
  216|  22.0k|    iIo.seek(-len, BasicIo::cur);
  217|  22.0k|  }
  218|  22.0k|  return rc;
  219|  22.3k|}

_ZN5Exiv28Internal9Rw2HeaderC2Ev:
    6|  22.1k|Rw2Header::Rw2Header() : TiffHeaderBase(0x0055, 24, littleEndian, 0x00000018) {
    7|  22.1k|}

_ZN4Safe3addIjEET_S1_S1_:
  137|  14.5k|T add(T summand_1, T summand_2) {
  138|  14.5k|  T res = 0;
  139|  14.5k|  if (Internal::builtin_add_overflow(summand_1, summand_2, res)) {
  ------------------
  |  Branch (139:7): [True: 27, False: 14.5k]
  ------------------
  140|     27|    throw std::overflow_error("Overflow in addition");
  141|     27|  }
  142|  14.5k|  return res;
  143|  14.5k|}
_ZN4Safe8Internal20builtin_add_overflowIjEEbT_S2_RS2_:
   96|  14.5k|bool builtin_add_overflow(T summand_1, T summand_2, T& result) {
   97|  14.5k|#if (defined(__GNUC__) || defined(__clang__)) && (__GNUC__ >= 5 || __clang_major__ >= 3)
   98|       |  if constexpr (std::is_same_v<T, int>)
   99|       |    return __builtin_sadd_overflow(summand_1, summand_2, &result);
  100|       |  else if constexpr (std::is_same_v<T, long>)
  101|       |    return __builtin_saddl_overflow(summand_1, summand_2, &result);
  102|       |  else if constexpr (std::is_same_v<T, long long>)
  103|       |    return __builtin_saddll_overflow(summand_1, summand_2, &result);
  104|       |  else if constexpr (std::is_same_v<T, unsigned int>)
  105|  14.5k|    return __builtin_uadd_overflow(summand_1, summand_2, &result);
  106|       |  else if constexpr (std::is_same_v<T, unsigned long>)
  107|       |    return __builtin_uaddl_overflow(summand_1, summand_2, &result);
  108|       |  else if constexpr (std::is_same_v<T, unsigned long long>)
  109|       |    return __builtin_uaddll_overflow(summand_1, summand_2, &result);
  110|       |  else
  111|       |#endif
  112|       |    return fallback_add_overflow(summand_1, summand_2, result);
  113|  14.5k|}
_ZN4Safe3addImEET_S1_S1_:
  137|   689k|T add(T summand_1, T summand_2) {
  138|   689k|  T res = 0;
  139|   689k|  if (Internal::builtin_add_overflow(summand_1, summand_2, res)) {
  ------------------
  |  Branch (139:7): [True: 1, False: 689k]
  ------------------
  140|      1|    throw std::overflow_error("Overflow in addition");
  141|      1|  }
  142|   689k|  return res;
  143|   689k|}
_ZN4Safe8Internal20builtin_add_overflowImEEbT_S2_RS2_:
   96|   689k|bool builtin_add_overflow(T summand_1, T summand_2, T& result) {
   97|   689k|#if (defined(__GNUC__) || defined(__clang__)) && (__GNUC__ >= 5 || __clang_major__ >= 3)
   98|       |  if constexpr (std::is_same_v<T, int>)
   99|       |    return __builtin_sadd_overflow(summand_1, summand_2, &result);
  100|       |  else if constexpr (std::is_same_v<T, long>)
  101|       |    return __builtin_saddl_overflow(summand_1, summand_2, &result);
  102|       |  else if constexpr (std::is_same_v<T, long long>)
  103|       |    return __builtin_saddll_overflow(summand_1, summand_2, &result);
  104|       |  else if constexpr (std::is_same_v<T, unsigned int>)
  105|       |    return __builtin_uadd_overflow(summand_1, summand_2, &result);
  106|       |  else if constexpr (std::is_same_v<T, unsigned long>)
  107|   689k|    return __builtin_uaddl_overflow(summand_1, summand_2, &result);
  108|       |  else if constexpr (std::is_same_v<T, unsigned long long>)
  109|       |    return __builtin_uaddll_overflow(summand_1, summand_2, &result);
  110|       |  else
  111|       |#endif
  112|       |    return fallback_add_overflow(summand_1, summand_2, result);
  113|   689k|}

_ZN5Exiv28Internal17Samsung2MakerNote7tagListEv:
   19|    522|  static constexpr auto tagList() {
   20|    522|    return tagInfo_;
   21|    522|  }
_ZN5Exiv28Internal17Samsung2MakerNote9tagListPwEv:
   23|     14|  static constexpr auto tagListPw() {
   24|     14|    return tagInfoPw_;
   25|     14|  }

_ZN5Exiv28Internal14SigmaMakerNote7tagListEv:
   25|    209|  static constexpr auto tagList() {
   26|    209|    return tagInfo_;
   27|    209|  }

_ZN5Exiv28Internal15sonyTagDecipherEtPKhmPNS0_13TiffComponentE:
 2331|    143|DataBuf sonyTagDecipher(uint16_t tag, const byte* bytes, size_t size, TiffComponent* object) {
 2332|    143|  return sonyTagCipher(tag, bytes, size, object, true);
 2333|    143|}
sonymn_int.cpp:_ZN5Exiv28InternalL13sonyTagCipherEtPKhmPKNS0_13TiffComponentEb:
 2307|    143|                             bool bDecipher) {
 2308|    143|  DataBuf b(bytes, size);  // copy the data
 2309|       |
 2310|       |  // initialize the code table
 2311|    143|  byte code[256];
 2312|  35.7k|  for (uint32_t i = 0; i < 249; i++) {
  ------------------
  |  Branch (2312:24): [True: 35.6k, False: 143]
  ------------------
 2313|  35.6k|    if (bDecipher) {
  ------------------
  |  Branch (2313:9): [True: 35.6k, False: 0]
  ------------------
 2314|  35.6k|      code[(i * i * i) % 249] = static_cast<byte>(i);
 2315|  35.6k|    } else {
 2316|      0|      code[i] = (i * i * i) % 249;
 2317|      0|    }
 2318|  35.6k|  }
 2319|  1.14k|  for (uint32_t i = 249; i < 256; i++) {
  ------------------
  |  Branch (2319:26): [True: 1.00k, False: 143]
  ------------------
 2320|  1.00k|    code[i] = static_cast<byte>(i);
 2321|  1.00k|  }
 2322|       |
 2323|       |  // code byte-by-byte
 2324|  12.9k|  for (uint32_t i = 0; i < size; i++) {
  ------------------
  |  Branch (2324:24): [True: 12.8k, False: 143]
  ------------------
 2325|  12.8k|    b.write_uint8(i, code[bytes[i]]);
 2326|  12.8k|  }
 2327|       |
 2328|    143|  return b;
 2329|    143|}

_ZN5Exiv28Internal13SonyMakerNote7tagListEv:
   29|  5.02k|  static constexpr auto tagList() {
   30|  5.02k|    return tagInfo_;
   31|  5.02k|  }
_ZN5Exiv28Internal13SonyMakerNote9tagListCsEv:
   33|  1.24k|  static constexpr auto tagListCs() {
   34|  1.24k|    return tagInfoCs_;
   35|  1.24k|  }
_ZN5Exiv28Internal13SonyMakerNote10tagListCs2Ev:
   37|    452|  static constexpr auto tagListCs2() {
   38|    452|    return tagInfoCs2_;
   39|    452|  }
_ZN5Exiv28Internal13SonyMakerNote9tagListFpEv:
   41|  2.48k|  static constexpr auto tagListFp() {
   42|  2.48k|    return tagInfoFp_;
   43|  2.48k|  }
_ZN5Exiv28Internal13SonyMakerNote16tagListSonyMisc1Ev:
   45|    274|  static constexpr auto tagListSonyMisc1() {
   46|    274|    return tagInfoSonyMisc1_;
   47|    274|  }
_ZN5Exiv28Internal13SonyMakerNote17tagListSonyMisc2bEv:
   49|  1.03k|  static constexpr auto tagListSonyMisc2b() {
   50|  1.03k|    return tagInfoSonyMisc2b_;
   51|  1.03k|  }
_ZN5Exiv28Internal13SonyMakerNote17tagListSonyMisc3cEv:
   53|  8.47k|  static constexpr auto tagListSonyMisc3c() {
   54|  8.47k|    return tagInfoSonyMisc3c_;
   55|  8.47k|  }
_ZN5Exiv28Internal13SonyMakerNote17tagListSonySInfo1Ev:
   57|    858|  static constexpr auto tagListSonySInfo1() {
   58|    858|    return tagInfoSonySInfo1_;
   59|    858|  }

_ZNK5Exiv28Internal13TagVocabularyeqENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
   48|  48.4M|bool TagVocabulary::operator==(std::string_view key) const {
   49|  48.4M|  return key.ends_with(voc_);
   50|  48.4M|}
_ZNK5Exiv29GroupInfoeqENS_5IfdIdE:
   68|   123M|bool GroupInfo::operator==(IfdId ifdId) const {
   69|   123M|  return ifdId_ == ifdId;
   70|   123M|}
_ZNK5Exiv29GroupInfoeqERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   72|  44.6M|bool GroupInfo::operator==(const GroupName& groupName) const {
   73|  44.6M|  return groupName == groupName_;
   74|  44.6M|}
_ZN5Exiv28ExifTags7tagListERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  108|  8.41k|const TagInfo* ExifTags::tagList(const std::string& groupName) {
  109|  8.41k|  return Internal::tagList(groupName);
  110|  8.41k|}
_ZNK5Exiv27ExifKey4Impl7tagNameEv:
  177|  1.96M|std::string ExifKey::Impl::tagName() const {
  178|  1.96M|  if (tagInfo_ && tagInfo_->tag_ != 0xffff) {
  ------------------
  |  Branch (178:7): [True: 1.96M, False: 0]
  |  Branch (178:19): [True: 1.16M, False: 801k]
  ------------------
  179|  1.16M|    return tagInfo_->name_;
  180|  1.16M|  }
  181|   801k|  return stringFormat("0x{:04x}", tag_);
  ------------------
  |  |   18|   801k|#define stringFormat std::format
  ------------------
  182|  1.96M|}
_ZN5Exiv27ExifKey4Impl12decomposeKeyERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  184|   751k|void ExifKey::Impl::decomposeKey(const std::string& key) {
  185|       |  // Get the family name, IFD name and tag name parts of the key
  186|   751k|  std::string::size_type pos1 = key.find('.');
  187|   751k|  if (pos1 == std::string::npos)
  ------------------
  |  Branch (187:7): [True: 0, False: 751k]
  ------------------
  188|      0|    throw Error(ErrorCode::kerInvalidKey, key);
  189|   751k|  std::string familyName = key.substr(0, pos1);
  190|   751k|  if (familyName != familyName_)
  ------------------
  |  Branch (190:7): [True: 0, False: 751k]
  ------------------
  191|      0|    throw Error(ErrorCode::kerInvalidKey, key);
  192|   751k|  std::string::size_type pos0 = pos1 + 1;
  193|   751k|  pos1 = key.find('.', pos0);
  194|   751k|  if (pos1 == std::string::npos)
  ------------------
  |  Branch (194:7): [True: 0, False: 751k]
  ------------------
  195|      0|    throw Error(ErrorCode::kerInvalidKey, key);
  196|   751k|  std::string groupName = key.substr(pos0, pos1 - pos0);
  197|   751k|  if (groupName.empty())
  ------------------
  |  Branch (197:7): [True: 0, False: 751k]
  ------------------
  198|      0|    throw Error(ErrorCode::kerInvalidKey, key);
  199|   751k|  std::string tn = key.substr(pos1 + 1);
  200|   751k|  if (tn.empty())
  ------------------
  |  Branch (200:7): [True: 0, False: 751k]
  ------------------
  201|      0|    throw Error(ErrorCode::kerInvalidKey, key);
  202|       |
  203|       |  // Find IfdId
  204|   751k|  IfdId ifdId = groupId(groupName);
  205|   751k|  if (ifdId == IfdId::ifdIdNotSet)
  ------------------
  |  Branch (205:7): [True: 0, False: 751k]
  ------------------
  206|      0|    throw Error(ErrorCode::kerInvalidKey, key);
  207|   751k|  if (!Internal::isExifIfd(ifdId) && !Internal::isMakerIfd(ifdId)) {
  ------------------
  |  Branch (207:7): [True: 211k, False: 539k]
  |  Branch (207:38): [True: 0, False: 211k]
  ------------------
  208|      0|    throw Error(ErrorCode::kerInvalidKey, key);
  209|      0|  }
  210|       |  // Convert tag
  211|   751k|  uint16_t tag = tagNumber(tn, ifdId);
  212|       |  // Get tag info
  213|   751k|  tagInfo_ = tagInfo(tag, ifdId);
  214|   751k|  if (!tagInfo_)
  ------------------
  |  Branch (214:7): [True: 0, False: 751k]
  ------------------
  215|      0|    throw Error(ErrorCode::kerInvalidKey, key);
  216|       |
  217|   751k|  tag_ = tag;
  218|   751k|  ifdId_ = ifdId;
  219|   751k|  groupName_ = groupName;
  220|       |  // tagName() translates hex tag name (0xabcd) to a real tag name if there is one
  221|   751k|  key_ = familyName + "." + groupName + "." + tagName();
  222|   751k|}
_ZN5Exiv27ExifKey4Impl7makeKeyEtNS_5IfdIdEPKNS_7TagInfoE:
  224|  1.21M|void ExifKey::Impl::makeKey(uint16_t tag, IfdId ifdId, const TagInfo* tagInfo) {
  225|  1.21M|  tagInfo_ = tagInfo;
  226|  1.21M|  tag_ = tag;
  227|  1.21M|  ifdId_ = ifdId;
  228|  1.21M|  key_ = std::string(familyName_) + "." + groupName_ + "." + tagName();
  229|  1.21M|}
_ZN5Exiv27ExifKeyC2EtRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  231|  1.21M|ExifKey::ExifKey(uint16_t tag, const std::string& groupName) : p_(std::make_unique<Impl>()) {
  232|  1.21M|  IfdId ifdId = groupId(groupName);
  233|       |  // Todo: Test if this condition can be removed
  234|  1.21M|  if (!Internal::isExifIfd(ifdId) && !Internal::isMakerIfd(ifdId)) {
  ------------------
  |  Branch (234:7): [True: 601k, False: 613k]
  |  Branch (234:38): [True: 0, False: 601k]
  ------------------
  235|      0|    throw Error(ErrorCode::kerInvalidIfdId, ifdId);
  236|      0|  }
  237|  1.21M|  if (auto ti = tagInfo(tag, ifdId)) {
  ------------------
  |  Branch (237:12): [True: 1.21M, False: 0]
  ------------------
  238|  1.21M|    p_->groupName_ = groupName;
  239|  1.21M|    p_->makeKey(tag, ifdId, ti);
  240|  1.21M|    return;
  241|  1.21M|  }
  242|      0|  throw Error(ErrorCode::kerInvalidIfdId, ifdId);
  243|  1.21M|}
_ZN5Exiv27ExifKeyC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  254|   751k|ExifKey::ExifKey(const std::string& key) : p_(std::make_unique<Impl>()) {
  255|   751k|  p_->decomposeKey(key);
  256|   751k|}
_ZN5Exiv27ExifKeyC2ERKS0_:
  258|  2.54M|ExifKey::ExifKey(const ExifKey& rhs) : p_(std::make_unique<Impl>(*rhs.p_)) {
  259|  2.54M|}
_ZN5Exiv27ExifKeyD2Ev:
  261|  4.51M|ExifKey::~ExifKey() = default;
_ZNK5Exiv27ExifKey6setIdxEi:
  270|  1.05M|void ExifKey::setIdx(int idx) const {
  271|  1.05M|  p_->idx_ = idx;
  272|  1.05M|}
_ZNK5Exiv27ExifKey3keyEv:
  274|  41.4M|std::string ExifKey::key() const {
  275|  41.4M|  return p_->key_;
  276|  41.4M|}
_ZNK5Exiv27ExifKey9groupNameEv:
  282|   900k|std::string ExifKey::groupName() const {
  283|   900k|  return p_->groupName_;
  284|   900k|}
_ZNK5Exiv27ExifKey13defaultTypeIdEv:
  302|  1.23k|TypeId ExifKey::defaultTypeId() const {
  303|  1.23k|  if (!p_->tagInfo_)
  ------------------
  |  Branch (303:7): [True: 0, False: 1.23k]
  ------------------
  304|      0|    return unknownTag.typeId_;
  305|  1.23k|  return p_->tagInfo_->typeId_;
  306|  1.23k|}
_ZNK5Exiv27ExifKey3tagEv:
  308|   657k|uint16_t ExifKey::tag() const {
  309|   657k|  return p_->tag_;
  310|   657k|}
_ZNK5Exiv27ExifKey5cloneEv:
  312|  2.54M|ExifKey::UniquePtr ExifKey::clone() const {
  313|  2.54M|  return UniquePtr(clone_());
  314|  2.54M|}
_ZNK5Exiv27ExifKey6clone_Ev:
  316|  2.54M|ExifKey* ExifKey::clone_() const {
  317|  2.54M|  return new ExifKey(*this);
  318|  2.54M|}
_ZNK5Exiv27ExifKey5ifdIdEv:
  320|   142k|IfdId ExifKey::ifdId() const {
  321|   142k|  return p_->ifdId_;
  322|   142k|}
_ZNK5Exiv27ExifKey3idxEv:
  324|   142k|int ExifKey::idx() const {
  325|   142k|  return p_->idx_;
  326|   142k|}

_ZN5Exiv28Internal10ifdTagListEv:
 1767|  1.74M|const TagInfo* ifdTagList() {
 1768|  1.74M|  return ifdTagInfo;
 1769|  1.74M|}
_ZN5Exiv28Internal11exifTagListEv:
 2166|  10.9k|const TagInfo* exifTagList() {
 2167|  10.9k|  return exifTagInfo;
 2168|  10.9k|}
_ZN5Exiv28Internal10gpsTagListEv:
 2382|  2.43k|const TagInfo* gpsTagList() {
 2383|  2.43k|  return gpsTagInfo;
 2384|  2.43k|}
_ZN5Exiv28Internal10iopTagListEv:
 2457|    275|const TagInfo* iopTagList() {
 2458|    275|  return iopTagInfo;
 2459|    275|}
_ZN5Exiv28Internal9mnTagListEv:
 2473|  9.30k|const TagInfo* mnTagList() {
 2474|  9.30k|  return mnTagInfo;
 2475|  9.30k|}
_ZN5Exiv28Internal10isMakerIfdENS_5IfdIdE:
 2477|   813k|bool isMakerIfd(IfdId ifdId) {
 2478|   813k|  if (auto ii = Exiv2::find(groupInfo, ifdId))
  ------------------
  |  Branch (2478:12): [True: 813k, False: 0]
  ------------------
 2479|   813k|    return std::string_view("Makernote") == ii->ifdName_;
 2480|      0|  return false;
 2481|   813k|}
_ZN5Exiv28Internal9isExifIfdENS_5IfdIdE:
 2483|  1.96M|bool isExifIfd(IfdId ifdId) {
 2484|  1.96M|  switch (ifdId) {
 2485|   428k|    case IfdId::ifd0Id:
  ------------------
  |  Branch (2485:5): [True: 428k, False: 1.53M]
  ------------------
 2486|   435k|    case IfdId::exifId:
  ------------------
  |  Branch (2486:5): [True: 7.39k, False: 1.95M]
  ------------------
 2487|   437k|    case IfdId::gpsId:
  ------------------
  |  Branch (2487:5): [True: 1.87k, False: 1.96M]
  ------------------
 2488|   437k|    case IfdId::iopId:
  ------------------
  |  Branch (2488:5): [True: 275, False: 1.96M]
  ------------------
 2489|   532k|    case IfdId::ifd1Id:
  ------------------
  |  Branch (2489:5): [True: 94.1k, False: 1.87M]
  ------------------
 2490|   566k|    case IfdId::ifd2Id:
  ------------------
  |  Branch (2490:5): [True: 34.3k, False: 1.93M]
  ------------------
 2491|   566k|    case IfdId::ifd3Id:
  ------------------
  |  Branch (2491:5): [True: 495, False: 1.96M]
  ------------------
 2492|   566k|    case IfdId::mpfId:
  ------------------
  |  Branch (2492:5): [True: 0, False: 1.96M]
  ------------------
 2493|   729k|    case IfdId::subImage1Id:
  ------------------
  |  Branch (2493:5): [True: 162k, False: 1.80M]
  ------------------
 2494|   794k|    case IfdId::subImage2Id:
  ------------------
  |  Branch (2494:5): [True: 64.9k, False: 1.90M]
  ------------------
 2495|   913k|    case IfdId::subImage3Id:
  ------------------
  |  Branch (2495:5): [True: 119k, False: 1.84M]
  ------------------
 2496|  1.04M|    case IfdId::subImage4Id:
  ------------------
  |  Branch (2496:5): [True: 129k, False: 1.83M]
  ------------------
 2497|  1.05M|    case IfdId::subImage5Id:
  ------------------
  |  Branch (2497:5): [True: 15.6k, False: 1.95M]
  ------------------
 2498|  1.07M|    case IfdId::subImage6Id:
  ------------------
  |  Branch (2498:5): [True: 12.3k, False: 1.95M]
  ------------------
 2499|  1.08M|    case IfdId::subImage7Id:
  ------------------
  |  Branch (2499:5): [True: 11.2k, False: 1.95M]
  ------------------
 2500|  1.09M|    case IfdId::subImage8Id:
  ------------------
  |  Branch (2500:5): [True: 9.20k, False: 1.95M]
  ------------------
 2501|  1.10M|    case IfdId::subImage9Id:
  ------------------
  |  Branch (2501:5): [True: 9.65k, False: 1.95M]
  ------------------
 2502|  1.15M|    case IfdId::subThumb1Id:
  ------------------
  |  Branch (2502:5): [True: 51.1k, False: 1.91M]
  ------------------
 2503|  1.15M|    case IfdId::panaRawId:
  ------------------
  |  Branch (2503:5): [True: 603, False: 1.96M]
  ------------------
 2504|  1.15M|      return true;
 2505|   813k|    default:
  ------------------
  |  Branch (2505:5): [True: 813k, False: 1.15M]
  ------------------
 2506|   813k|      return false;
 2507|  1.96M|  }
 2508|  1.96M|}
_ZN5Exiv28Internal7tagListENS_5IfdIdE:
 2518|  2.71M|const TagInfo* tagList(IfdId ifdId) {
 2519|  2.71M|  if (auto ii = Exiv2::find(groupInfo, ifdId))
  ------------------
  |  Branch (2519:12): [True: 2.71M, False: 0]
  ------------------
 2520|  2.71M|    if (ii->tagList_)
  ------------------
  |  Branch (2520:9): [True: 2.71M, False: 0]
  ------------------
 2521|  2.71M|      return ii->tagList_();
 2522|      0|  return nullptr;
 2523|  2.71M|}  // tagList
_ZN5Exiv28Internal7tagInfoEtNS_5IfdIdE:
 2525|  1.96M|const TagInfo* tagInfo(uint16_t tag, IfdId ifdId) {
 2526|  1.96M|  if (auto ti = tagList(ifdId)) {
  ------------------
  |  Branch (2526:12): [True: 1.96M, False: 0]
  ------------------
 2527|  1.96M|    int idx = 0;
 2528|   103M|    for (idx = 0; ti[idx].tag_ != 0xffff; ++idx) {
  ------------------
  |  Branch (2528:19): [True: 102M, False: 801k]
  ------------------
 2529|   102M|      if (ti[idx].tag_ == tag)
  ------------------
  |  Branch (2529:11): [True: 1.16M, False: 101M]
  ------------------
 2530|  1.16M|        break;
 2531|   102M|    }
 2532|  1.96M|    return ti + idx;
 2533|  1.96M|  }
 2534|      0|  return nullptr;
 2535|  1.96M|}  // tagInfo
_ZN5Exiv28Internal7tagInfoERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_5IfdIdE:
 2537|   751k|const TagInfo* tagInfo(const std::string& tagName, IfdId ifdId) {
 2538|   751k|  if (tagName.empty())
  ------------------
  |  Branch (2538:7): [True: 0, False: 751k]
  ------------------
 2539|      0|    return nullptr;
 2540|   751k|  if (auto ti = tagList(ifdId)) {
  ------------------
  |  Branch (2540:12): [True: 751k, False: 0]
  ------------------
 2541|  24.4M|    for (int idx = 0; ti[idx].tag_ != 0xffff; ++idx) {
  ------------------
  |  Branch (2541:23): [True: 24.4M, False: 0]
  ------------------
 2542|  24.4M|      if (tagName == ti[idx].name_) {
  ------------------
  |  Branch (2542:11): [True: 751k, False: 23.6M]
  ------------------
 2543|   751k|        return ti + idx;
 2544|   751k|      }
 2545|  24.4M|    }
 2546|   751k|  }
 2547|      0|  return nullptr;
 2548|   751k|}  // tagInfo
_ZN5Exiv28Internal7groupIdERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 2550|  2.10M|IfdId groupId(const std::string& groupName) {
 2551|  2.10M|  if (auto ii = Exiv2::find(groupInfo, groupName))
  ------------------
  |  Branch (2551:12): [True: 2.10M, False: 0]
  ------------------
 2552|  2.10M|    return IfdId{ii->ifdId_};
 2553|      0|  return IfdId::ifdIdNotSet;
 2554|  2.10M|}
_ZN5Exiv28Internal9groupNameENS_5IfdIdE:
 2562|  1.07M|const char* groupName(IfdId ifdId) {
 2563|  1.07M|  if (auto ii = Exiv2::find(groupInfo, ifdId))
  ------------------
  |  Branch (2563:12): [True: 1.07M, False: 0]
  ------------------
 2564|  1.07M|    return ii->groupName_;
 2565|      0|  return groupInfo[0].groupName_;
 2566|  1.07M|}
_ZN5Exiv28Internal7fnumberEf:
 2597|     11|float fnumber(float apertureValue) {
 2598|     11|  float result = std::exp2(apertureValue / 2.F);
 2599|     11|  if (std::abs(result - 3.5F) < 0.1F) {
  ------------------
  |  Branch (2599:7): [True: 0, False: 11]
  ------------------
 2600|      0|    result = 3.5F;
 2601|      0|  }
 2602|     11|  return result;
 2603|     11|}
_ZN5Exiv28Internal12exposureTimeEf:
 2605|     11|URational exposureTime(float shutterSpeedValue) {
 2606|     11|  URational ur(1, 1);
 2607|     11|  const double tmp = std::exp2(shutterSpeedValue);
 2608|     11|  if (tmp > 1) {
  ------------------
  |  Branch (2608:7): [True: 0, False: 11]
  ------------------
 2609|      0|    const double x = std::round(tmp);
 2610|       |    // Check that x is within the range of a uint32_t before casting.
 2611|      0|    if (x <= std::numeric_limits<uint32_t>::max()) {
  ------------------
  |  Branch (2611:9): [True: 0, False: 0]
  ------------------
 2612|      0|      ur.second = static_cast<uint32_t>(x);
 2613|      0|    }
 2614|     11|  } else {
 2615|     11|    const double x = std::round(1 / tmp);
 2616|       |    // Check that x is within the range of a uint32_t before casting.
 2617|     11|    if (0 <= x && x <= std::numeric_limits<uint32_t>::max()) {
  ------------------
  |  Branch (2617:9): [True: 11, False: 0]
  |  Branch (2617:19): [True: 11, False: 0]
  ------------------
 2618|     11|      ur.first = static_cast<uint32_t>(x);
 2619|     11|    }
 2620|     11|  }
 2621|     11|  return ur;
 2622|     11|}
_ZN5Exiv28Internal9tagNumberERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_5IfdIdE:
 2624|   751k|uint16_t tagNumber(const std::string& tagName, IfdId ifdId) {
 2625|   751k|  auto ti = tagInfo(tagName, ifdId);
 2626|   751k|  if (ti && ti->tag_ != 0xffff)
  ------------------
  |  Branch (2626:7): [True: 751k, False: 0]
  |  Branch (2626:13): [True: 751k, False: 0]
  ------------------
 2627|   751k|    return ti->tag_;
 2628|      0|  if (!isHex(tagName, 4, "0x"))
  ------------------
  |  Branch (2628:7): [True: 0, False: 0]
  ------------------
 2629|      0|    throw Error(ErrorCode::kerInvalidTag, tagName, ifdId);
 2630|      0|  return static_cast<uint16_t>(std::stoi(tagName, nullptr, 16));
 2631|      0|}  // tagNumber
_ZN5Exiv28Internal7tagListERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 3244|  8.41k|const TagInfo* tagList(const std::string& groupName) {
 3245|  8.41k|  auto ii = Exiv2::find(groupInfo, groupName);
 3246|  8.41k|  if (!ii || !ii->tagList_) {
  ------------------
  |  Branch (3246:7): [True: 0, False: 8.41k]
  |  Branch (3246:14): [True: 0, False: 8.41k]
  ------------------
 3247|      0|    return nullptr;
 3248|      0|  }
 3249|  8.41k|  return ii->tagList_();
 3250|  8.41k|}

_ZNK5Exiv28Internal10TagDetailseqEl:
   50|  29.7M|  bool operator==(int64_t key) const {
   51|  29.7M|    return key == val_;
   52|  29.7M|  }

_ZN5Exiv28TgaImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
   21|     10|TgaImage::TgaImage(BasicIo::UniquePtr io) : Image(ImageType::tga, mdNone, std::move(io)) {
   22|     10|}
_ZN5Exiv214newTgaInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
   95|     10|Image::UniquePtr newTgaInstance(BasicIo::UniquePtr io, bool /*create*/) {
   96|     10|  auto image = std::make_unique<TgaImage>(std::move(io));
   97|     10|  if (!image->good()) {
  ------------------
  |  Branch (97:7): [True: 10, False: 0]
  ------------------
   98|     10|    return nullptr;
   99|     10|  }
  100|      0|  return image;
  101|     10|}
_ZN5Exiv29isTgaTypeERNS_7BasicIoEb:
  103|  14.5k|bool isTgaType(BasicIo& iIo, bool /*advance*/) {
  104|       |  // not all TARGA files have a signature string, so first just try to match the file name extension
  105|  14.5k|  const std::string& path = iIo.path();
  106|  14.5k|  if (path.ends_with(".tga") || path.ends_with(".TGA")) {
  ------------------
  |  Branch (106:7): [True: 0, False: 14.5k]
  |  Branch (106:33): [True: 0, False: 14.5k]
  ------------------
  107|      0|    return true;
  108|      0|  }
  109|  14.5k|  byte buf[26];
  110|  14.5k|  const size_t curPos = iIo.tell();
  111|  14.5k|  if (curPos < 26)
  ------------------
  |  Branch (111:7): [True: 14.4k, False: 171]
  ------------------
  112|  14.4k|    return false;
  113|       |
  114|    171|  iIo.seek(-26, BasicIo::end);
  115|    171|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (115:7): [True: 0, False: 171]
  |  Branch (115:22): [True: 0, False: 171]
  ------------------
  116|      0|    return false;
  117|      0|  }
  118|    171|  iIo.read(buf, sizeof(buf));
  119|    171|  if (iIo.error()) {
  ------------------
  |  Branch (119:7): [True: 0, False: 171]
  ------------------
  120|      0|    return false;
  121|      0|  }
  122|       |  // some TARGA files, but not all, have a signature string at the end
  123|    171|  bool matched = (memcmp(buf + 8, "TRUEVISION-XFILE", 16) == 0);
  124|    171|  iIo.seek(curPos, BasicIo::beg);
  125|    171|  return matched;
  126|    171|}

_ZNK5Exiv28Internal15TiffMappingInfoeqERKNS1_3KeyE:
   41|  5.96M|bool TiffMappingInfo::operator==(const TiffMappingInfo::Key& key) const {
   42|  5.96M|  return (make_ == "*" || key.m_.starts_with(make_)) && (Tag::all == extendedTag_ || key.e_ == extendedTag_) &&
  ------------------
  |  Branch (42:11): [True: 5.96M, False: 0]
  |  Branch (42:27): [True: 0, False: 0]
  |  Branch (42:58): [True: 1.19M, False: 4.77M]
  |  Branch (42:86): [True: 8.72k, False: 4.76M]
  ------------------
   43|  1.20M|         key.g_ == group_;
  ------------------
  |  Branch (43:10): [True: 8.24k, False: 1.19M]
  ------------------
   44|  5.96M|}
_ZN5Exiv28Internal9IoWrapperC2ERNS_7BasicIoEPKhmPNS0_12OffsetWriterE:
   47|  4.40k|    io_(io), pHeader_(pHeader), size_(size), pow_(pow) {
   48|  4.40k|  if (!pHeader_ || size_ == 0)
  ------------------
  |  Branch (48:7): [True: 0, False: 4.40k]
  |  Branch (48:20): [True: 0, False: 4.40k]
  ------------------
   49|      0|    wroteHeader_ = true;
   50|  4.40k|}
_ZN5Exiv28Internal9IoWrapper5writeEPKhm:
   52|   325k|size_t IoWrapper::write(const byte* pData, size_t wcount) {
   53|   325k|  if (!wroteHeader_ && wcount > 0) {
  ------------------
  |  Branch (53:7): [True: 4.40k, False: 320k]
  |  Branch (53:24): [True: 4.40k, False: 0]
  ------------------
   54|  4.40k|    io_.write(pHeader_, size_);
   55|  4.40k|    wroteHeader_ = true;
   56|  4.40k|  }
   57|   325k|  return io_.write(pData, wcount);
   58|   325k|}
_ZN5Exiv28Internal9IoWrapper4putbEh:
   60|  2.19k|int IoWrapper::putb(byte data) {
   61|  2.19k|  if (!wroteHeader_) {
  ------------------
  |  Branch (61:7): [True: 0, False: 2.19k]
  ------------------
   62|      0|    io_.write(pHeader_, size_);
   63|      0|    wroteHeader_ = true;
   64|      0|  }
   65|  2.19k|  return io_.putb(data);
   66|  2.19k|}
_ZN5Exiv28Internal13TiffDirectoryC2EtNS_5IfdIdEb:
   76|  43.3k|TiffDirectory::TiffDirectory(uint16_t tag, IfdId group, bool hasNext) : TiffComponent(tag, group), hasNext_(hasNext) {
   77|  43.3k|}
_ZN5Exiv28Internal10TiffSubIfdC2EtNS_5IfdIdES2_:
   80|  8.48k|    TiffEntryBase(tag, group, ttUnsignedLong), newGroup_(newGroup) {
   81|  8.48k|}
_ZN5Exiv28Internal16TiffIfdMakernoteC2EtNS_5IfdIdES2_NSt3__110unique_ptrINS0_8MnHeaderENS3_14default_deleteIS5_EEEEb:
   85|  2.78k|    TiffComponent(tag, group), pHeader_(std::move(pHeader)), ifd_(tag, mnGroup, hasNext) {
   86|  2.78k|}
_ZN5Exiv28Internal16TiffIfdMakernoteD2Ev:
   88|  2.78k|TiffIfdMakernote::~TiffIfdMakernote() = default;
_ZN5Exiv28Internal15TiffBinaryArrayC2EtNS_5IfdIdERKNS0_8ArrayCfgEPKNS0_8ArrayDefEm:
   92|  3.95k|    TiffEntryBase(tag, group, arrayCfg.elTiffType_), arrayCfg_(&arrayCfg), arrayDef_(arrayDef), defSize_(defSize) {
   93|  3.95k|}
_ZN5Exiv28Internal15TiffBinaryArrayC2EtNS_5IfdIdEPKNS0_8ArraySetEmPFitPKhmPNS0_13TiffComponentEE:
   97|  1.07k|    TiffEntryBase(tag, group),  // Todo: Does it make a difference that there is no type?
   98|  1.07k|    cfgSelFct_(cfgSelFct),
   99|  1.07k|    arraySet_(arraySet),
  100|  1.07k|    setSize_(setSize) {
  101|       |  // We'll figure out the correct cfg later
  102|  1.07k|}
_ZN5Exiv28Internal13TiffEntryBaseC2EtNS_5IfdIdENS0_8TiffTypeE:
  118|  1.55M|    TiffComponent(tag, group), tiffType_(tiffType) {
  119|  1.55M|}
_ZN5Exiv28Internal13TiffEntryBaseD2Ev:
  121|  1.55M|TiffEntryBase::~TiffEntryBase() = default;
_ZN5Exiv28Internal17TiffDataEntryBaseC2EtNS_5IfdIdEtS2_:
  142|  58.5k|    TiffEntryBase(tag, group), szTag_(szTag), szGroup_(szGroup) {
  143|  58.5k|}
_ZN5Exiv28Internal13TiffSizeEntryC2EtNS_5IfdIdEtS2_:
  148|  73.1k|    TiffEntryBase(tag, group), dtTag_(dtTag), dtGroup_(dtGroup) {
  149|  73.1k|}
_ZN5Exiv28Internal11TiffMnEntryC2EtNS_5IfdIdES2_:
  152|  11.8k|    TiffEntryBase(tag, group, ttUndefined), mnGroup_(mnGroup) {
  153|  11.8k|}
_ZN5Exiv28Internal11TiffMnEntryD2Ev:
  155|  11.8k|TiffMnEntry::~TiffMnEntry() = default;
_ZNK5Exiv28Internal13TiffEntryBase3idxEv:
  205|  2.99M|int TiffEntryBase::idx() const {
  206|  2.99M|  return idx_;
  207|  2.99M|}
_ZN5Exiv28Internal13TiffEntryBase7setDataENSt3__110shared_ptrINS_7DataBufEEE:
  209|  32.3k|void TiffEntryBase::setData(std::shared_ptr<DataBuf> buf) {
  210|  32.3k|  storage_ = std::move(buf);
  211|  32.3k|  pData_ = storage_->data();
  212|  32.3k|  size_ = storage_->size();
  213|  32.3k|}
_ZN5Exiv28Internal13TiffEntryBase7setDataEPhmNSt3__110shared_ptrINS_7DataBufEEE:
  215|  1.05M|void TiffEntryBase::setData(byte* pData, size_t size, std::shared_ptr<DataBuf> storage) {
  216|  1.05M|  pData_ = pData;
  217|  1.05M|  size_ = size;
  218|  1.05M|  storage_ = std::move(storage);
  219|  1.05M|  if (!pData_)
  ------------------
  |  Branch (219:7): [True: 0, False: 1.05M]
  ------------------
  220|      0|    size_ = 0;
  221|  1.05M|}
_ZN5Exiv28Internal13TiffEntryBase11updateValueENSt3__110unique_ptrINS_5ValueENS2_14default_deleteIS4_EEEENS_9ByteOrderE:
  223|   134k|void TiffEntryBase::updateValue(Value::UniquePtr value, ByteOrder byteOrder) {
  224|   134k|  if (!value)
  ------------------
  |  Branch (224:7): [True: 0, False: 134k]
  ------------------
  225|      0|    return;
  226|   134k|  if (size_t newSize = value->size(); newSize > size_) {
  ------------------
  |  Branch (226:39): [True: 32.2k, False: 101k]
  ------------------
  227|  32.2k|    auto d = std::make_shared<DataBuf>(newSize);
  228|  32.2k|    setData(std::move(d));
  229|  32.2k|  }
  230|   134k|  if (pData_) {
  ------------------
  |  Branch (230:7): [True: 32.2k, False: 101k]
  ------------------
  231|  32.2k|    memset(pData_, 0x0, size_);
  232|  32.2k|  }
  233|   134k|  size_ = value->copy(pData_, byteOrder);
  234|   134k|  setValue(std::move(value));
  235|   134k|}
_ZN5Exiv28Internal13TiffEntryBase8setValueENSt3__110unique_ptrINS_5ValueENS2_14default_deleteIS4_EEEE:
  237|  1.19M|void TiffEntryBase::setValue(Value::UniquePtr value) {
  238|  1.19M|  if (!value)
  ------------------
  |  Branch (238:7): [True: 0, False: 1.19M]
  ------------------
  239|      0|    return;
  240|  1.19M|  tiffType_ = toTiffType(value->typeId());
  241|  1.19M|  count_ = value->count();
  242|  1.19M|  pValue_ = std::move(value);
  243|  1.19M|}
_ZN5Exiv28Internal13TiffDataEntry9setStripsEPKNS_5ValueEPKhmm:
  245|  9.37k|void TiffDataEntry::setStrips(const Value* pSize, const byte* pData, size_t sizeData, size_t baseOffset) {
  246|  9.37k|  if (!pValue() || !pSize) {
  ------------------
  |  Branch (246:7): [True: 498, False: 8.87k]
  |  Branch (246:20): [True: 445, False: 8.42k]
  ------------------
  247|    943|#ifndef SUPPRESS_WARNINGS
  248|    943|    EXV_WARNING << "Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|    943|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 943]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    943|  LogMsg(LogMsg::warn).os()
  ------------------
  249|      0|                << tag() << ": Size or data offset value not set, ignoring them.\n";
  250|    943|#endif
  251|    943|    return;
  252|    943|  }
  253|  8.42k|  if (pValue()->count() == 0) {
  ------------------
  |  Branch (253:7): [True: 1.18k, False: 7.24k]
  ------------------
  254|  1.18k|#ifndef SUPPRESS_WARNINGS
  255|  1.18k|    EXV_WARNING << "Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|  1.18k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 1.18k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  1.18k|  LogMsg(LogMsg::warn).os()
  ------------------
  256|      0|                << tag() << ": Data offset entry value is empty, ignoring it.\n";
  257|  1.18k|#endif
  258|  1.18k|    return;
  259|  1.18k|  }
  260|  7.24k|  if (pValue()->count() != pSize->count()) {
  ------------------
  |  Branch (260:7): [True: 894, False: 6.34k]
  ------------------
  261|    894|#ifndef SUPPRESS_WARNINGS
  262|    894|    EXV_WARNING << "Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|    894|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 894]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    894|  LogMsg(LogMsg::warn).os()
  ------------------
  263|      0|                << tag() << ": Size and data offset entries have different"
  264|      0|                << " number of components, ignoring them.\n";
  265|    894|#endif
  266|    894|    return;
  267|    894|  }
  268|  6.34k|  size_t size = 0;
  269|  22.3k|  for (size_t i = 0; i < pSize->count(); ++i) {
  ------------------
  |  Branch (269:22): [True: 15.9k, False: 6.34k]
  ------------------
  270|  15.9k|    size = Safe::add<size_t>(size, pSize->toUint32(i));
  271|  15.9k|  }
  272|  6.34k|  const size_t offset = pValue()->toUint32(0);
  273|  6.34k|  if (size > sizeData || offset > sizeData - size || baseOffset > sizeData - size - offset) {
  ------------------
  |  Branch (273:7): [True: 512, False: 5.83k]
  |  Branch (273:26): [True: 256, False: 5.57k]
  |  Branch (273:54): [True: 14, False: 5.56k]
  ------------------
  274|    782|#ifndef SUPPRESS_WARNINGS
  275|    782|    EXV_WARNING << "Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|    782|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 782]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    782|  LogMsg(LogMsg::warn).os()
  ------------------
  276|      0|                << tag() << ": Data area exceeds data buffer, ignoring it.\n";
  277|    782|#endif
  278|    782|    return;
  279|    782|  }
  280|       |  // Todo: Remove limitation of JPEG writer: strips must be contiguous
  281|       |  // Until then we check: last offset + last size - first offset == size?
  282|  5.56k|  if (pValue()->toUint32(pValue()->count() - 1) + pSize->toUint32(pSize->count() - 1) != size + offset) {
  ------------------
  |  Branch (282:7): [True: 250, False: 5.31k]
  ------------------
  283|    250|#ifndef SUPPRESS_WARNINGS
  284|    250|    EXV_WARNING << "Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|    250|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 250]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    250|  LogMsg(LogMsg::warn).os()
  ------------------
  285|      0|                << tag() << ": Data area is not contiguous, ignoring it.\n";
  286|    250|#endif
  287|    250|    return;
  288|    250|  }
  289|  5.31k|  pDataArea_ = const_cast<byte*>(pData) + baseOffset + offset;
  290|  5.31k|  sizeDataArea_ = size;
  291|  5.31k|  const_cast<Value*>(pValue())->setDataArea(pDataArea_, sizeDataArea_);
  292|  5.31k|}  // TiffDataEntry::setStrips
_ZN5Exiv28Internal14TiffImageEntry9setStripsEPKNS_5ValueEPKhmm:
  294|  28.4k|void TiffImageEntry::setStrips(const Value* pSize, const byte* pData, size_t sizeData, size_t baseOffset) {
  295|  28.4k|  if (!pValue() || !pSize) {
  ------------------
  |  Branch (295:7): [True: 957, False: 27.5k]
  |  Branch (295:20): [True: 957, False: 26.5k]
  ------------------
  296|  1.91k|#ifndef SUPPRESS_WARNINGS
  297|  1.91k|    EXV_WARNING << "Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|  1.91k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 1.91k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  1.91k|  LogMsg(LogMsg::warn).os()
  ------------------
  298|      0|                << tag() << ": Size or data offset value not set, ignoring them.\n";
  299|  1.91k|#endif
  300|  1.91k|    return;
  301|  1.91k|  }
  302|  26.5k|  if (pValue()->count() != pSize->count()) {
  ------------------
  |  Branch (302:7): [True: 2.54k, False: 24.0k]
  ------------------
  303|  2.54k|#ifndef SUPPRESS_WARNINGS
  304|  2.54k|    EXV_WARNING << "Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|  2.54k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 2.54k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  2.54k|  LogMsg(LogMsg::warn).os()
  ------------------
  305|      0|                << tag() << ": Size and data offset entries have different"
  306|      0|                << " number of components, ignoring them.\n";
  307|  2.54k|#endif
  308|  2.54k|    return;
  309|  2.54k|  }
  310|  80.5k|  for (size_t i = 0; i < pValue()->count(); ++i) {
  ------------------
  |  Branch (310:22): [True: 56.5k, False: 24.0k]
  ------------------
  311|  56.5k|    const size_t offset = pValue()->toUint32(i);
  312|  56.5k|    const size_t size = pSize->toUint32(i);
  313|       |
  314|  56.5k|    if (size > sizeData || offset > sizeData - size || baseOffset > sizeData - size - offset) {
  ------------------
  |  Branch (314:9): [True: 7.41k, False: 49.1k]
  |  Branch (314:28): [True: 5.26k, False: 43.8k]
  |  Branch (314:56): [True: 10, False: 43.8k]
  ------------------
  315|  12.6k|#ifndef SUPPRESS_WARNINGS
  316|  12.6k|      EXV_WARNING << "Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|  12.6k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 12.6k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  12.6k|  LogMsg(LogMsg::warn).os()
  ------------------
  317|      0|                  << tag() << ": Strip " << std::dec << i << " is outside of the data area; ignored.\n";
  318|  12.6k|#endif
  319|  43.8k|    } else if (size != 0) {
  ------------------
  |  Branch (319:16): [True: 23.4k, False: 20.3k]
  ------------------
  320|  23.4k|      const byte* pStrip = pData + baseOffset + offset;
  321|  23.4k|      strips_.emplace_back(pStrip, size);
  322|  23.4k|    }
  323|  56.5k|  }
  324|  24.0k|}  // TiffImageEntry::setStrips
_ZNK5Exiv28Internal16TiffIfdMakernote9ifdOffsetEv:
  326|  2.37k|size_t TiffIfdMakernote::ifdOffset() const {
  327|  2.37k|  if (!pHeader_)
  ------------------
  |  Branch (327:7): [True: 687, False: 1.69k]
  ------------------
  328|    687|    return 0;
  329|  1.69k|  return pHeader_->ifdOffset();
  330|  2.37k|}
_ZNK5Exiv28Internal16TiffIfdMakernote9byteOrderEv:
  332|  4.70k|ByteOrder TiffIfdMakernote::byteOrder() const {
  333|  4.70k|  if (!pHeader_ || pHeader_->byteOrder() == invalidByteOrder) {
  ------------------
  |  Branch (333:7): [True: 1.37k, False: 3.33k]
  |  Branch (333:20): [True: 2.27k, False: 1.05k]
  ------------------
  334|  3.64k|    return imageByteOrder_;
  335|  3.64k|  }
  336|  1.05k|  return pHeader_->byteOrder();
  337|  4.70k|}
_ZNK5Exiv28Internal16TiffIfdMakernote8mnOffsetEv:
  339|  2.32k|size_t TiffIfdMakernote::mnOffset() const {
  340|  2.32k|  return mnOffset_;
  341|  2.32k|}
_ZNK5Exiv28Internal16TiffIfdMakernote10baseOffsetEv:
  343|  2.37k|size_t TiffIfdMakernote::baseOffset() const {
  344|  2.37k|  if (!pHeader_)
  ------------------
  |  Branch (344:7): [True: 687, False: 1.69k]
  ------------------
  345|    687|    return 0;
  346|  1.69k|  return pHeader_->baseOffset(mnOffset_);
  347|  2.37k|}
_ZN5Exiv28Internal16TiffIfdMakernote10readHeaderEPKhmNS_9ByteOrderE:
  349|  2.78k|bool TiffIfdMakernote::readHeader(const byte* pData, size_t size, ByteOrder byteOrder) {
  350|  2.78k|  if (!pHeader_)
  ------------------
  |  Branch (350:7): [True: 687, False: 2.10k]
  ------------------
  351|    687|    return true;
  352|  2.10k|  return pHeader_->read(pData, size, byteOrder);
  353|  2.78k|}
_ZNK5Exiv28Internal8ArrayDef4sizeEtNS_5IfdIdE:
  372|  1.13M|size_t ArrayDef::size(uint16_t tag, IfdId group) const {
  373|  1.13M|  TypeId typeId = toTypeId(tiffType_, tag, group);
  374|  1.13M|  return count_ * TypeInfo::typeSize(typeId);
  375|  1.13M|}
_ZN5Exiv28Internal15TiffBinaryArray10initializeEPNS0_13TiffComponentE:
  392|  1.14k|bool TiffBinaryArray::initialize(TiffComponent* pRoot) {
  393|  1.14k|  if (!cfgSelFct_)
  ------------------
  |  Branch (393:7): [True: 547, False: 599]
  ------------------
  394|    547|    return true;  // Not a complex array
  395|       |
  396|    599|  int idx = cfgSelFct_(tag(), pData(), TiffEntryBase::doSize(), pRoot);
  397|    599|  if (idx > -1) {
  ------------------
  |  Branch (397:7): [True: 280, False: 319]
  ------------------
  398|    280|    arrayCfg_ = &arraySet_[idx].cfg_;
  399|    280|    arrayDef_ = arraySet_[idx].def_;
  400|    280|    defSize_ = arraySet_[idx].defSize_;
  401|    280|  }
  402|    599|  return idx > -1;
  403|  1.14k|}
_ZN5Exiv28Internal15TiffBinaryArray14iniOrigDataBufEv:
  405|  5.02k|void TiffBinaryArray::iniOrigDataBuf() {
  406|  5.02k|  origData_ = const_cast<byte*>(pData());
  407|  5.02k|  origSize_ = TiffEntryBase::doSize();
  408|  5.02k|}
_ZN5Exiv28Internal15TiffBinaryArray10addElementEmRKNS0_8ArrayDefE:
  419|   567k|size_t TiffBinaryArray::addElement(size_t idx, const ArrayDef& def) {
  420|   567k|  auto tag = static_cast<uint16_t>(idx / cfg()->tagStep());
  421|   567k|  auto sz = std::min<size_t>(def.size(tag, cfg()->group_), TiffEntryBase::doSize() - idx);
  422|   567k|  auto tc = TiffCreator::create(tag, cfg()->group_);
  423|   567k|  auto tp = dynamic_cast<TiffBinaryElement*>(tc.get());
  424|   567k|  if (!tp)
  ------------------
  |  Branch (424:7): [True: 0, False: 567k]
  ------------------
  425|      0|    return 0;
  426|       |  // The assertion typically fails if a component is not configured in
  427|       |  // the TIFF structure table (TiffCreator::tiffTreeStruct_)
  428|   567k|  tp->setStart(pData() + idx);
  429|   567k|  auto s = storage();
  430|   567k|  tp->setData(const_cast<byte*>(pData() + idx), sz, std::move(s));
  431|   567k|  tp->setElDef(def);
  432|   567k|  tp->setElByteOrder(cfg()->byteOrder_);
  433|   567k|  addChild(std::move(tc));
  434|   567k|  return sz;
  435|   567k|}  // TiffBinaryArray::addElement
_ZN5Exiv28Internal13TiffComponent7addPathEtRNSt3__15stackINS0_12TiffPathItemENS2_5dequeIS4_NS2_9allocatorIS4_EEEEEEPS1_NS2_10unique_ptrIS1_NS2_14default_deleteIS1_EEEE:
  438|   285k|                                      TiffComponent::UniquePtr object) {
  439|   285k|  return doAddPath(tag, tiffPath, pRoot, std::move(object));
  440|   285k|}  // TiffComponent::addPath
_ZN5Exiv28Internal13TiffComponent9doAddPathEtRNSt3__15stackINS0_12TiffPathItemENS2_5dequeIS4_NS2_9allocatorIS4_EEEEEEPS1_NS2_10unique_ptrIS1_NS2_14default_deleteIS1_EEEE:
  443|   142k|                                        TiffComponent::UniquePtr /*object*/) {
  444|   142k|  return this;
  445|   142k|}  // TiffComponent::doAddPath
_ZN5Exiv28Internal13TiffDirectory9doAddPathEtRNSt3__15stackINS0_12TiffPathItemENS2_5dequeIS4_NS2_9allocatorIS4_EEEEEEPNS0_13TiffComponentENS2_10unique_ptrISB_NS2_14default_deleteISB_EEEE:
  448|   142k|                                        TiffComponent::UniquePtr object) {
  449|   142k|  tiffPath.pop();
  450|   142k|  const TiffPathItem tpi = tiffPath.top();
  451|       |
  452|   142k|  TiffComponent* tc = nullptr;
  453|       |  // Try to use an existing component if there is still at least one
  454|       |  // composite tag on the stack or the tag to add is the MakerNote tag.
  455|       |  // This is used to prevent duplicate entries. Sub-IFDs also, but the > 1
  456|       |  // condition takes care of them, see below.
  457|   142k|  if (tiffPath.size() > 1 || (tpi.extendedTag() == 0x927c && tpi.group() == IfdId::exifId)) {
  ------------------
  |  Branch (457:7): [True: 0, False: 142k]
  |  Branch (457:31): [True: 0, False: 142k]
  |  Branch (457:62): [True: 0, False: 0]
  ------------------
  458|      0|    if (tpi.extendedTag() == Tag::next) {
  ------------------
  |  Branch (458:9): [True: 0, False: 0]
  ------------------
  459|      0|      tc = pNext_.get();
  460|      0|    } else {
  461|      0|      for (auto&& component : components_) {
  ------------------
  |  Branch (461:29): [True: 0, False: 0]
  ------------------
  462|      0|        if (component->tag() == tpi.tag() && component->group() == tpi.group()) {
  ------------------
  |  Branch (462:13): [True: 0, False: 0]
  |  Branch (462:46): [True: 0, False: 0]
  ------------------
  463|      0|          tc = component.get();
  464|      0|          break;
  465|      0|        }
  466|      0|      }
  467|      0|    }
  468|      0|  }
  469|       |
  470|   142k|  if (tc)
  ------------------
  |  Branch (470:7): [True: 0, False: 142k]
  ------------------
  471|      0|    return tc->addPath(tag, tiffPath, pRoot, std::move(object));
  472|       |
  473|   142k|  auto atc = [&] {
  474|   142k|    if (tiffPath.size() == 1 && object) {
  475|   142k|      return std::move(object);
  476|   142k|    }
  477|   142k|    return TiffCreator::create(tpi.extendedTag(), tpi.group());
  478|   142k|  }();
  479|       |
  480|       |  // Prevent dangling sub-IFD tags: Do not add a sub-IFD component without children.
  481|       |  // Todo: How to check before creating the component?
  482|   142k|  if (tiffPath.size() == 1 && dynamic_cast<const TiffSubIfd*>(atc.get()))
  ------------------
  |  Branch (482:7): [True: 142k, False: 0]
  |  Branch (482:31): [True: 0, False: 142k]
  ------------------
  483|      0|    return nullptr;
  484|       |
  485|   142k|  tc = [&] {
  486|   142k|    if (tpi.extendedTag() == Tag::next)
  487|   142k|      return this->addNext(std::move(atc));
  488|   142k|    return this->addChild(std::move(atc));
  489|   142k|  }();
  490|   142k|  return tc->addPath(tag, tiffPath, pRoot, nullptr);
  491|   142k|}  // TiffDirectory::doAddPath
_ZN5Exiv28Internal13TiffComponent8addChildENSt3__110shared_ptrIS1_EE:
  571|  1.57M|TiffComponent* TiffComponent::addChild(TiffComponent::SharedPtr tiffComponent) {
  572|  1.57M|  return doAddChild(std::move(tiffComponent));
  573|  1.57M|}  // TiffComponent::addChild
_ZN5Exiv28Internal13TiffDirectory10doAddChildENSt3__110shared_ptrINS0_13TiffComponentEEE:
  579|   990k|TiffComponent* TiffDirectory::doAddChild(TiffComponent::SharedPtr tiffComponent) {
  580|   990k|  return components_.emplace_back(std::move(tiffComponent)).get();
  581|   990k|}  // TiffDirectory::doAddChild
_ZN5Exiv28Internal10TiffSubIfd10doAddChildENSt3__110shared_ptrINS0_13TiffComponentEEE:
  583|  20.4k|TiffComponent* TiffSubIfd::doAddChild(TiffComponent::SharedPtr tiffComponent) {
  584|  20.4k|  auto d = std::dynamic_pointer_cast<TiffDirectory>(std::move(tiffComponent));
  585|  20.4k|  if (!d)
  ------------------
  |  Branch (585:7): [True: 0, False: 20.4k]
  ------------------
  586|      0|    throw Error(ErrorCode::kerErrorMessage, "dynamic_pointer_cast to TiffDirectory failed");
  587|       |
  588|  20.4k|  return ifds_.emplace_back(std::move(d)).get();
  589|  20.4k|}  // TiffSubIfd::doAddChild
_ZN5Exiv28Internal15TiffBinaryArray10doAddChildENSt3__110shared_ptrINS0_13TiffComponentEEE:
  602|   567k|TiffComponent* TiffBinaryArray::doAddChild(TiffComponent::SharedPtr tiffComponent) {
  603|   567k|  setDecoded(true);
  604|   567k|  return elements_.emplace_back(std::move(tiffComponent)).get();
  605|   567k|}  // TiffBinaryArray::doAddChild
_ZN5Exiv28Internal13TiffComponent7addNextENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE:
  607|  2.21k|TiffComponent* TiffComponent::addNext(TiffComponent::UniquePtr tiffComponent) {
  608|  2.21k|  return doAddNext(std::move(tiffComponent));
  609|  2.21k|}  // TiffComponent::addNext
_ZN5Exiv28Internal13TiffDirectory9doAddNextENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEE:
  615|  2.21k|TiffComponent* TiffDirectory::doAddNext(TiffComponent::UniquePtr tiffComponent) {
  616|  2.21k|  if (hasNext_) {
  ------------------
  |  Branch (616:7): [True: 2.21k, False: 0]
  ------------------
  617|  2.21k|    pNext_ = std::move(tiffComponent);
  618|  2.21k|    return pNext_.get();
  619|  2.21k|  }
  620|      0|  return nullptr;
  621|  2.21k|}  // TiffDirectory::doAddNext
_ZN5Exiv28Internal13TiffComponent6acceptERNS0_11TiffVisitorE:
  634|  22.0M|void TiffComponent::accept(TiffVisitor& visitor) {
  635|  22.0M|  if (visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (635:7): [True: 22.0M, False: 12.2k]
  ------------------
  636|  22.0M|    doAccept(visitor);  // one for NVI :)
  637|  22.0M|}  // TiffComponent::accept
_ZN5Exiv28Internal9TiffEntry8doAcceptERNS0_11TiffVisitorE:
  639|  13.3M|void TiffEntry::doAccept(TiffVisitor& visitor) {
  640|  13.3M|  visitor.visitEntry(this);
  641|  13.3M|}  // TiffEntry::doAccept
_ZN5Exiv28Internal13TiffDataEntry8doAcceptERNS0_11TiffVisitorE:
  643|  83.6k|void TiffDataEntry::doAccept(TiffVisitor& visitor) {
  644|  83.6k|  visitor.visitDataEntry(this);
  645|  83.6k|}  // TiffDataEntry::doAccept
_ZN5Exiv28Internal14TiffImageEntry8doAcceptERNS0_11TiffVisitorE:
  647|  2.24M|void TiffImageEntry::doAccept(TiffVisitor& visitor) {
  648|  2.24M|  visitor.visitImageEntry(this);
  649|  2.24M|}  // TiffImageEntry::doAccept
_ZN5Exiv28Internal13TiffSizeEntry8doAcceptERNS0_11TiffVisitorE:
  651|  2.76M|void TiffSizeEntry::doAccept(TiffVisitor& visitor) {
  652|  2.76M|  visitor.visitSizeEntry(this);
  653|  2.76M|}  // TiffSizeEntry::doAccept
_ZN5Exiv28Internal13TiffDirectory8doAcceptERNS0_11TiffVisitorE:
  655|   568k|void TiffDirectory::doAccept(TiffVisitor& visitor) {
  656|   568k|  visitor.visitDirectory(this);
  657|  18.8M|  for (auto&& component : components_) {
  ------------------
  |  Branch (657:25): [True: 18.8M, False: 447k]
  ------------------
  658|  18.8M|    if (!visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (658:9): [True: 121k, False: 18.6M]
  ------------------
  659|   121k|      break;
  660|  18.6M|    component->accept(visitor);
  661|  18.6M|  }
  662|   568k|  if (visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (662:7): [True: 445k, False: 123k]
  ------------------
  663|   445k|    visitor.visitDirectoryNext(this);
  664|   568k|  if (pNext_)
  ------------------
  |  Branch (664:7): [True: 45.5k, False: 522k]
  ------------------
  665|  45.5k|    pNext_->accept(visitor);
  666|   568k|  if (visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (666:7): [True: 432k, False: 136k]
  ------------------
  667|   432k|    visitor.visitDirectoryEnd(this);
  668|   568k|}  // TiffDirectory::doAccept
_ZN5Exiv28Internal10TiffSubIfd8doAcceptERNS0_11TiffVisitorE:
  670|   130k|void TiffSubIfd::doAccept(TiffVisitor& visitor) {
  671|   130k|  visitor.visitSubIfd(this);
  672|   403k|  for (auto&& ifd : ifds_) {
  ------------------
  |  Branch (672:19): [True: 403k, False: 105k]
  ------------------
  673|   403k|    if (!visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (673:9): [True: 24.6k, False: 378k]
  ------------------
  674|  24.6k|      break;
  675|   378k|    ifd->accept(visitor);
  676|   378k|  }
  677|   130k|}  // TiffSubIfd::doAccept
_ZN5Exiv28Internal11TiffMnEntry8doAcceptERNS0_11TiffVisitorE:
  679|  59.9k|void TiffMnEntry::doAccept(TiffVisitor& visitor) {
  680|  59.9k|  visitor.visitMnEntry(this);
  681|  59.9k|  if (mn_)
  ------------------
  |  Branch (681:7): [True: 9.30k, False: 50.6k]
  ------------------
  682|  9.30k|    mn_->accept(visitor);
  683|  59.9k|  if (!visitor.go(TiffVisitor::geKnownMakernote)) {
  ------------------
  |  Branch (683:7): [True: 840, False: 59.1k]
  ------------------
  684|    840|    mn_ = nullptr;
  685|    840|  }
  686|       |
  687|  59.9k|}  // TiffMnEntry::doAccept
_ZN5Exiv28Internal16TiffIfdMakernote8doAcceptERNS0_11TiffVisitorE:
  689|  9.30k|void TiffIfdMakernote::doAccept(TiffVisitor& visitor) {
  690|  9.30k|  if (visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (690:7): [True: 9.30k, False: 0]
  ------------------
  691|  9.30k|    visitor.visitIfdMakernote(this);
  692|  9.30k|  if (visitor.go(TiffVisitor::geKnownMakernote))
  ------------------
  |  Branch (692:7): [True: 8.84k, False: 459]
  ------------------
  693|  8.84k|    ifd_.accept(visitor);
  694|  9.30k|  if (visitor.go(TiffVisitor::geKnownMakernote) && visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (694:7): [True: 8.84k, False: 459]
  |  Branch (694:52): [True: 6.09k, False: 2.74k]
  ------------------
  695|  6.09k|    visitor.visitIfdMakernoteEnd(this);
  696|  9.30k|}
_ZN5Exiv28Internal15TiffBinaryArray8doAcceptERNS0_11TiffVisitorE:
  698|  31.5k|void TiffBinaryArray::doAccept(TiffVisitor& visitor) {
  699|  31.5k|  visitor.visitBinaryArray(this);
  700|  2.77M|  for (auto&& element : elements_) {
  ------------------
  |  Branch (700:23): [True: 2.77M, False: 30.8k]
  ------------------
  701|  2.77M|    if (!visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (701:9): [True: 707, False: 2.76M]
  ------------------
  702|    707|      break;
  703|  2.76M|    element->accept(visitor);
  704|  2.76M|  }
  705|  31.5k|  if (visitor.go(TiffVisitor::geTraverse))
  ------------------
  |  Branch (705:7): [True: 26.3k, False: 5.23k]
  ------------------
  706|  26.3k|    visitor.visitBinaryArrayEnd(this);
  707|  31.5k|}
_ZN5Exiv28Internal17TiffBinaryElement8doAcceptERNS0_11TiffVisitorE:
  709|  2.78M|void TiffBinaryElement::doAccept(TiffVisitor& visitor) {
  710|  2.78M|  visitor.visitBinaryElement(this);
  711|  2.78M|}
_ZN5Exiv28Internal13TiffEntryBase6encodeERNS0_11TiffEncoderEPKNS_9ExifdatumE:
  713|   142k|void TiffEntryBase::encode(TiffEncoder& encoder, const Exifdatum* datum) {
  714|   142k|  doEncode(encoder, datum);
  715|   142k|}
_ZN5Exiv28Internal9TiffEntry8doEncodeERNS0_11TiffEncoderEPKNS_9ExifdatumE:
  729|   106k|void TiffEntry::doEncode(TiffEncoder& encoder, const Exifdatum* datum) {
  730|   106k|  encoder.encodeTiffEntry(this, datum);
  731|   106k|}
_ZN5Exiv28Internal14TiffImageEntry8doEncodeERNS0_11TiffEncoderEPKNS_9ExifdatumE:
  733|  16.3k|void TiffImageEntry::doEncode(TiffEncoder& encoder, const Exifdatum* datum) {
  734|  16.3k|  encoder.encodeImageEntry(this, datum);
  735|  16.3k|}
_ZN5Exiv28Internal13TiffSizeEntry8doEncodeERNS0_11TiffEncoderEPKNS_9ExifdatumE:
  741|  20.1k|void TiffSizeEntry::doEncode(TiffEncoder& encoder, const Exifdatum* datum) {
  742|  20.1k|  encoder.encodeSizeEntry(this, datum);
  743|  20.1k|}
_ZNK5Exiv28Internal13TiffComponent5countEv:
  749|   180k|size_t TiffComponent::count() const {
  750|   180k|  return doCount();
  751|   180k|}
_ZNK5Exiv28Internal13TiffDirectory7doCountEv:
  753|  4.40k|size_t TiffDirectory::doCount() const {
  754|  4.40k|  return components_.size();
  755|  4.40k|}
_ZNK5Exiv28Internal13TiffEntryBase7doCountEv:
  757|   175k|size_t TiffEntryBase::doCount() const {
  758|   175k|  return count_;
  759|   175k|}
_ZN5Exiv28Internal13TiffComponent5writeERNS0_9IoWrapperENS_9ByteOrderEmmmRm:
  806|   146k|                            size_t& imageIdx) {
  807|   146k|  return doWrite(ioWrapper, byteOrder, offset, valueIdx, dataIdx, imageIdx);
  808|   146k|}  // TiffComponent::write
_ZN5Exiv28Internal13TiffDirectory7doWriteERNS0_9IoWrapperENS_9ByteOrderEmmmRm:
  811|  4.40k|                              size_t& imageIdx) {
  812|  4.40k|  bool isRootDir = (imageIdx == std::string::npos);
  813|       |
  814|       |  // Number of components to write
  815|  4.40k|  const size_t compCount = count();
  816|  4.40k|  if (compCount > 0xffff)
  ------------------
  |  Branch (816:7): [True: 0, False: 4.40k]
  ------------------
  817|      0|    throw Error(ErrorCode::kerTooManyTiffDirectoryEntries, groupName(group()));
  818|       |
  819|       |  // Size of next IFD, if any
  820|  4.40k|  size_t sizeNext = 0;
  821|  4.40k|  if (pNext_)
  ------------------
  |  Branch (821:7): [True: 0, False: 4.40k]
  ------------------
  822|      0|    sizeNext = pNext_->size();
  823|       |
  824|       |  // Nothing to do if there are no entries and the size of the next IFD is 0
  825|  4.40k|  if (compCount == 0 && sizeNext == 0)
  ------------------
  |  Branch (825:7): [True: 0, False: 4.40k]
  |  Branch (825:25): [True: 0, False: 0]
  ------------------
  826|      0|    return 0;
  827|       |
  828|       |  // Remember the offset of the CR2 RAW IFD
  829|  4.40k|  if (group() == IfdId::ifd3Id) {
  ------------------
  |  Branch (829:7): [True: 0, False: 4.40k]
  ------------------
  830|       |#ifdef EXIV2_DEBUG_MESSAGES
  831|       |    std::cerr << "Directory " << groupName(group()) << " offset is 0x" << std::setw(8) << std::setfill('0') << std::hex
  832|       |              << offset << std::dec << "\n";
  833|       |#endif
  834|      0|    ioWrapper.setTarget(OffsetWriter::cr2RawIfdOffset, offset);
  835|      0|  }
  836|       |  // Size of all directory entries, without values and additional data
  837|  4.40k|  const size_t sizeDir = 2 + (12 * compCount) + (hasNext_ ? 4 : 0);
  ------------------
  |  Branch (837:50): [True: 4.40k, False: 0]
  ------------------
  838|       |
  839|       |  // TIFF standard requires IFD entries to be sorted in ascending order by tag.
  840|       |  // Not sorting makernote directories sometimes preserves them better.
  841|  4.40k|  if (group() < IfdId::mnId) {
  ------------------
  |  Branch (841:7): [True: 4.40k, False: 0]
  ------------------
  842|  4.40k|    std::sort(components_.begin(), components_.end(), cmpTagLt);
  843|  4.40k|  }
  844|       |  // Size of IFD values and additional data
  845|  4.40k|  size_t sizeValue = 0;
  846|  4.40k|  size_t sizeData = 0;
  847|   142k|  for (auto&& component : components_) {
  ------------------
  |  Branch (847:25): [True: 142k, False: 4.40k]
  ------------------
  848|   142k|    if (size_t sv = component->size(); sv > 4) {
  ------------------
  |  Branch (848:40): [True: 7.47k, False: 135k]
  ------------------
  849|  7.47k|      sv += sv & 1;  // Align value to word boundary
  850|  7.47k|      sizeValue += sv;
  851|  7.47k|    }
  852|       |    // Also add the size of data, but only if needed
  853|   142k|    if (isRootDir) {
  ------------------
  |  Branch (853:9): [True: 142k, False: 0]
  ------------------
  854|   142k|      auto sd = component->sizeData();
  855|   142k|      sd += sd & 1;  // Align data to word boundary
  856|   142k|      sizeData += sd;
  857|   142k|    }
  858|   142k|  }
  859|       |
  860|  4.40k|  size_t idx = 0;                 // Current IFD index / bytes written
  861|  4.40k|  valueIdx = sizeDir;             // Offset to the current IFD value
  862|  4.40k|  dataIdx = sizeDir + sizeValue;  // Offset to the entry's data area
  863|  4.40k|  if (isRootDir) {                // Absolute offset to the image data
  ------------------
  |  Branch (863:7): [True: 4.40k, False: 0]
  ------------------
  864|  4.40k|    imageIdx = offset + dataIdx + sizeData + sizeNext;
  865|  4.40k|    imageIdx += imageIdx & 1;  // Align image data to word boundary
  866|  4.40k|  }
  867|       |
  868|       |  // 1st: Write the IFD, a) Number of directory entries
  869|  4.40k|  byte buf[4];
  870|  4.40k|  us2Data(buf, static_cast<uint16_t>(compCount), byteOrder);
  871|  4.40k|  ioWrapper.write(buf, 2);
  872|  4.40k|  idx += 2;
  873|       |  // b) Directory entries - may contain pointers to the value or data
  874|   142k|  for (auto&& component : components_) {
  ------------------
  |  Branch (874:25): [True: 142k, False: 4.40k]
  ------------------
  875|   142k|    idx += writeDirEntry(ioWrapper, byteOrder, offset, component.get(), valueIdx, dataIdx, imageIdx);
  876|   142k|    if (size_t sv = component->size(); sv > 4) {
  ------------------
  |  Branch (876:40): [True: 7.46k, False: 134k]
  ------------------
  877|  7.46k|      sv += sv & 1;  // Align value to word boundary
  878|  7.46k|      valueIdx += sv;
  879|  7.46k|    }
  880|   142k|    auto sd = component->sizeData();
  881|   142k|    sd += sd & 1;  // Align data to word boundary
  882|   142k|    dataIdx += sd;
  883|   142k|  }
  884|       |  // c) Pointer to the next IFD
  885|  4.40k|  if (hasNext_) {
  ------------------
  |  Branch (885:7): [True: 4.36k, False: 37]
  ------------------
  886|  4.36k|    memset(buf, 0x0, 4);
  887|  4.36k|    if (pNext_ && sizeNext) {
  ------------------
  |  Branch (887:9): [True: 0, False: 4.36k]
  |  Branch (887:19): [True: 0, False: 0]
  ------------------
  888|      0|      l2Data(buf, static_cast<uint32_t>(offset + dataIdx), byteOrder);
  889|      0|    }
  890|  4.36k|    ioWrapper.write(buf, 4);
  891|  4.36k|    idx += 4;
  892|  4.36k|  }
  893|       |
  894|       |  // 2nd: Write IFD values - may contain pointers to additional data
  895|  4.40k|  valueIdx = sizeDir;
  896|  4.40k|  dataIdx = sizeDir + sizeValue;
  897|   141k|  for (auto&& component : components_) {
  ------------------
  |  Branch (897:25): [True: 141k, False: 4.40k]
  ------------------
  898|   141k|    if (size_t sv = component->size(); sv > 4) {
  ------------------
  |  Branch (898:40): [True: 7.34k, False: 134k]
  ------------------
  899|  7.34k|      size_t d = component->write(ioWrapper, byteOrder, offset, valueIdx, dataIdx, imageIdx);
  900|  7.34k|      enforce(sv == d, ErrorCode::kerImageWriteFailed);
  901|  7.34k|      if ((sv & 1) == 1) {
  ------------------
  |  Branch (901:11): [True: 1.76k, False: 5.58k]
  ------------------
  902|  1.76k|        ioWrapper.putb(0x0);  // Align value to word boundary
  903|  1.76k|        sv += 1;
  904|  1.76k|      }
  905|  7.34k|      idx += sv;
  906|  7.34k|      valueIdx += sv;
  907|  7.34k|    }
  908|   141k|    auto sd = component->sizeData();
  909|   141k|    sd += sd & 1;  // Align data to word boundary
  910|   141k|    dataIdx += sd;
  911|   141k|  }
  912|       |
  913|       |  // 3rd: Write data - may contain offsets too (eg sub-IFD)
  914|  4.40k|  dataIdx = sizeDir + sizeValue;
  915|  4.40k|  idx += writeData(ioWrapper, byteOrder, offset, dataIdx, imageIdx);
  916|       |
  917|       |  // 4th: Write next-IFD
  918|  4.40k|  if (pNext_ && sizeNext) {
  ------------------
  |  Branch (918:7): [True: 0, False: 4.40k]
  |  Branch (918:17): [True: 0, False: 0]
  ------------------
  919|      0|    idx += pNext_->write(ioWrapper, byteOrder, offset + idx, std::string::npos, std::string::npos, imageIdx);
  920|      0|  }
  921|       |
  922|       |  // 5th, at the root directory level only: write image data
  923|  4.40k|  if (isRootDir) {
  ------------------
  |  Branch (923:7): [True: 4.30k, False: 101]
  ------------------
  924|  4.30k|    idx += writeImage(ioWrapper, byteOrder);
  925|  4.30k|  }
  926|       |
  927|  4.40k|  return idx;
  928|  4.40k|}
_ZN5Exiv28Internal13TiffDirectory13writeDirEntryERNS0_9IoWrapperENS_9ByteOrderEmPNS0_13TiffComponentEmmRm:
  931|   142k|                                    TiffComponent* pTiffComponent, size_t valueIdx, size_t dataIdx, size_t& imageIdx) {
  932|   142k|  auto pDirEntry = dynamic_cast<TiffEntryBase*>(pTiffComponent);
  933|   142k|  if (!pDirEntry)
  ------------------
  |  Branch (933:7): [True: 0, False: 142k]
  ------------------
  934|      0|    return 0;
  935|   142k|  byte buf[8];
  936|   142k|  us2Data(buf, pDirEntry->tag(), byteOrder);
  937|   142k|  us2Data(buf + 2, pDirEntry->tiffType(), byteOrder);
  938|   142k|  ul2Data(buf + 4, static_cast<uint32_t>(pDirEntry->count()), byteOrder);
  939|   142k|  ioWrapper.write(buf, 8);
  940|   142k|  if (pDirEntry->size() > 4) {
  ------------------
  |  Branch (940:7): [True: 7.46k, False: 134k]
  ------------------
  941|  7.46k|    pDirEntry->setOffset(Safe::add<size_t>(offset, valueIdx));
  942|  7.46k|    ul2Data(buf, static_cast<uint32_t>(pDirEntry->offset()), byteOrder);
  943|  7.46k|    ioWrapper.write(buf, 4);
  944|   134k|  } else {
  945|   134k|    const size_t len = pDirEntry->write(ioWrapper, byteOrder, offset, valueIdx, dataIdx, imageIdx);
  946|   134k|#ifndef SUPPRESS_WARNINGS
  947|   134k|    if (len > 4) {
  ------------------
  |  Branch (947:9): [True: 0, False: 134k]
  ------------------
  948|      0|      EXV_ERROR << "Unexpected length in TiffDirectory::writeDirEntry(): len == " << len << ".\n";
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
  949|      0|    }
  950|   134k|#endif
  951|   134k|    if (len < 4) {
  ------------------
  |  Branch (951:9): [True: 125k, False: 8.82k]
  ------------------
  952|   125k|      memset(buf, 0x0, 4);
  953|   125k|      ioWrapper.write(buf, 4 - len);
  954|   125k|    }
  955|   134k|  }
  956|   142k|  return 12;
  957|   142k|}  // TiffDirectory::writeDirEntry
_ZN5Exiv28Internal13TiffEntryBase7doWriteERNS0_9IoWrapperENS_9ByteOrderEmmmRm:
  960|   126k|                              size_t /*dataIdx*/, size_t& /*imageIdx*/) {
  961|   126k|  if (!pValue_ || pValue_->size() == 0)
  ------------------
  |  Branch (961:7): [True: 0, False: 126k]
  |  Branch (961:19): [True: 101k, False: 24.0k]
  ------------------
  962|   101k|    return 0;
  963|       |
  964|  24.0k|  DataBuf buf(pValue_->size());
  965|  24.0k|  pValue_->copy(buf.data(), byteOrder);
  966|  24.0k|  ioWrapper.write(buf.c_data(), buf.size());
  967|  24.0k|  return buf.size();
  968|   126k|}  // TiffEntryBase::doWrite
_ZN5Exiv28Internal13TiffEntryBase11writeOffsetEPhmNS0_8TiffTypeENS_9ByteOrderE:
  970|  56.5k|size_t TiffEntryBase::writeOffset(byte* buf, size_t offset, TiffType tiffType, ByteOrder byteOrder) {
  971|  56.5k|  size_t rc = 0;
  972|  56.5k|  switch (tiffType) {
  973|  2.04k|    case ttUnsignedShort:
  ------------------
  |  Branch (973:5): [True: 2.04k, False: 54.5k]
  ------------------
  974|  3.96k|    case ttSignedShort:
  ------------------
  |  Branch (974:5): [True: 1.92k, False: 54.6k]
  ------------------
  975|  3.96k|      if (offset > std::numeric_limits<uint16_t>::max())
  ------------------
  |  Branch (975:11): [True: 37, False: 3.92k]
  ------------------
  976|     37|        throw Error(ErrorCode::kerOffsetOutOfRange);
  977|  3.92k|      rc = us2Data(buf, static_cast<uint16_t>(offset), byteOrder);
  978|  3.92k|      break;
  979|  50.1k|    case ttUnsignedLong:
  ------------------
  |  Branch (979:5): [True: 50.1k, False: 6.37k]
  ------------------
  980|  52.5k|    case ttSignedLong:
  ------------------
  |  Branch (980:5): [True: 2.34k, False: 54.2k]
  ------------------
  981|  52.5k|      rc = l2Data(buf, static_cast<uint32_t>(offset), byteOrder);
  982|  52.5k|      break;
  983|     64|    default:
  ------------------
  |  Branch (983:5): [True: 64, False: 56.4k]
  ------------------
  984|     64|      throw Error(ErrorCode::kerUnsupportedDataAreaOffsetType);
  985|  56.5k|  }
  986|  56.4k|  return rc;
  987|  56.5k|}  // TiffEntryBase::writeOffset
_ZN5Exiv28Internal14TiffImageEntry7doWriteERNS0_9IoWrapperENS_9ByteOrderEmmmRm:
 1008|  16.0k|                               size_t dataIdx, size_t& imageIdx) {
 1009|  16.0k|  size_t o2 = imageIdx;
 1010|       |  // For makernotes, write TIFF image data to the data area
 1011|  16.0k|  if (group() > IfdId::mnId)
  ------------------
  |  Branch (1011:7): [True: 0, False: 16.0k]
  ------------------
 1012|      0|    o2 = Safe::add<size_t>(offset, dataIdx);
 1013|       |#ifdef EXIV2_DEBUG_MESSAGES
 1014|       |  std::cerr << "TiffImageEntry, Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0')
 1015|       |            << std::hex << tag() << std::dec << ": Writing offset " << o2 << "\n";
 1016|       |#endif
 1017|  16.0k|  DataBuf buf(strips_.size() * 4);
 1018|  16.0k|  size_t idx = 0;
 1019|  56.5k|  for (const auto& [_, off] : strips_) {
  ------------------
  |  Branch (1019:29): [True: 56.5k, False: 16.0k]
  ------------------
 1020|  56.5k|    idx += writeOffset(buf.data(idx), o2, tiffType(), byteOrder);
 1021|       |    // Align strip data to word boundary
 1022|  56.5k|    const auto sz = Safe::add(off, off & 1);
 1023|  56.5k|    o2 = Safe::add(o2, sz);
 1024|  56.5k|    if (group() <= IfdId::mnId)
  ------------------
  |  Branch (1024:9): [True: 56.4k, False: 101]
  ------------------
 1025|  56.4k|      imageIdx = Safe::add(imageIdx, sz);
 1026|  56.5k|  }
 1027|  16.0k|  ioWrapper.write(buf.c_data(), buf.size());
 1028|  16.0k|  return buf.size();
 1029|  16.0k|}  // TiffImageEntry::doWrite
_ZNK5Exiv28Internal13TiffComponent9writeDataERNS0_9IoWrapperENS_9ByteOrderEmmRm:
 1134|   144k|                                size_t& imageIdx) const {
 1135|   144k|  return doWriteData(ioWrapper, byteOrder, offset, dataIdx, imageIdx);
 1136|   144k|}  // TiffComponent::writeData
_ZNK5Exiv28Internal13TiffDirectory11doWriteDataERNS0_9IoWrapperENS_9ByteOrderEmmRm:
 1139|  4.30k|                                  size_t& imageIdx) const {
 1140|  4.30k|  size_t len = 0;
 1141|   140k|  for (auto&& component : components_) {
  ------------------
  |  Branch (1141:25): [True: 140k, False: 4.30k]
  ------------------
 1142|   140k|    len += component->writeData(ioWrapper, byteOrder, offset, dataIdx + len, imageIdx);
 1143|   140k|  }
 1144|  4.30k|  return len;
 1145|  4.30k|}  // TiffDirectory::doWriteData
_ZNK5Exiv28Internal13TiffEntryBase11doWriteDataERNS0_9IoWrapperENS_9ByteOrderEmmRm:
 1148|   124k|                                  size_t /*dataIdx*/, size_t& /*imageIdx*/) const {
 1149|   124k|  return 0;
 1150|   124k|}  // TiffEntryBase::doWriteData
_ZNK5Exiv28Internal14TiffImageEntry11doWriteDataERNS0_9IoWrapperENS_9ByteOrderEmmRm:
 1153|  15.8k|                                   size_t& /*imageIdx*/) const {
 1154|  15.8k|  size_t len = 0;
 1155|       |  // For makernotes, write TIFF image data to the data area
 1156|  15.8k|  if (group() > IfdId::mnId) {  // Todo: FIX THIS HACK!!!
  ------------------
  |  Branch (1156:7): [True: 0, False: 15.8k]
  ------------------
 1157|      0|    len = writeImage(ioWrapper, byteOrder);
 1158|      0|  }
 1159|  15.8k|  return len;
 1160|  15.8k|}  // TiffImageEntry::doWriteData
_ZNK5Exiv28Internal13TiffComponent10writeImageERNS0_9IoWrapperENS_9ByteOrderE:
 1197|   144k|size_t TiffComponent::writeImage(IoWrapper& ioWrapper, ByteOrder byteOrder) const {
 1198|   144k|  return doWriteImage(ioWrapper, byteOrder);
 1199|   144k|}  // TiffComponent::writeImage
_ZNK5Exiv28Internal13TiffDirectory12doWriteImageERNS0_9IoWrapperENS_9ByteOrderE:
 1201|  4.30k|size_t TiffDirectory::doWriteImage(IoWrapper& ioWrapper, ByteOrder byteOrder) const {
 1202|  4.30k|  size_t len = 0;
 1203|  4.30k|  const TiffComponent* pSubIfd = nullptr;
 1204|   140k|  for (const auto& component : components_) {
  ------------------
  |  Branch (1204:30): [True: 140k, False: 4.30k]
  ------------------
 1205|   140k|    if (component->tag() == 0x014a) {
  ------------------
  |  Branch (1205:9): [True: 0, False: 140k]
  ------------------
 1206|       |      // Hack: delay writing of sub-IFD image data to get the order correct
 1207|      0|#ifndef SUPPRESS_WARNINGS
 1208|      0|      if (pSubIfd) {
  ------------------
  |  Branch (1208:11): [True: 0, False: 0]
  ------------------
 1209|      0|        EXV_ERROR << "Multiple sub-IFD image data tags found\n";
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
 1210|      0|      }
 1211|      0|#endif
 1212|      0|      pSubIfd = component.get();
 1213|      0|      continue;
 1214|      0|    }
 1215|   140k|    len += component->writeImage(ioWrapper, byteOrder);
 1216|   140k|  }
 1217|  4.30k|  if (pSubIfd) {
  ------------------
  |  Branch (1217:7): [True: 0, False: 4.30k]
  ------------------
 1218|      0|    len += pSubIfd->writeImage(ioWrapper, byteOrder);
 1219|      0|  }
 1220|  4.30k|  if (pNext_) {
  ------------------
  |  Branch (1220:7): [True: 0, False: 4.30k]
  ------------------
 1221|      0|    len += pNext_->writeImage(ioWrapper, byteOrder);
 1222|      0|  }
 1223|  4.30k|  return len;
 1224|  4.30k|}  // TiffDirectory::doWriteImage
_ZNK5Exiv28Internal13TiffEntryBase12doWriteImageERNS0_9IoWrapperENS_9ByteOrderE:
 1226|   124k|size_t TiffEntryBase::doWriteImage(IoWrapper& /*ioWrapper*/, ByteOrder /*byteOrder*/) const {
 1227|   124k|  return 0;
 1228|   124k|}  // TiffEntryBase::doWriteImage
_ZNK5Exiv28Internal14TiffImageEntry12doWriteImageERNS0_9IoWrapperENS_9ByteOrderE:
 1243|  15.8k|size_t TiffImageEntry::doWriteImage(IoWrapper& ioWrapper, ByteOrder /*byteOrder*/) const {
 1244|  15.8k|  if (!pValue())
  ------------------
  |  Branch (1244:7): [True: 0, False: 15.8k]
  ------------------
 1245|      0|    throw Error(ErrorCode::kerImageWriteFailed);  // #1296
 1246|       |
 1247|  15.8k|  size_t len = pValue()->sizeDataArea();
 1248|  15.8k|  if (len > 0) {
  ------------------
  |  Branch (1248:7): [True: 1.04k, False: 14.7k]
  ------------------
 1249|       |#ifdef EXIV2_DEBUG_MESSAGES
 1250|       |    std::cerr << "TiffImageEntry, Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0')
 1251|       |              << std::hex << tag() << std::dec << ": Writing data area, size = " << len;
 1252|       |#endif
 1253|  1.04k|    DataBuf buf = pValue()->dataArea();
 1254|  1.04k|    ioWrapper.write(buf.c_data(), buf.size());
 1255|  1.04k|    size_t align = len & 1;  // Align image data to word boundary
 1256|  1.04k|    if (align)
  ------------------
  |  Branch (1256:9): [True: 430, False: 617]
  ------------------
 1257|    430|      ioWrapper.putb(0x0);
 1258|  1.04k|    len += align;
 1259|  14.7k|  } else {
 1260|       |#ifdef EXIV2_DEBUG_MESSAGES
 1261|       |    std::cerr << "TiffImageEntry, Directory " << groupName(group()) << ", entry 0x" << std::setw(4) << std::setfill('0')
 1262|       |              << std::hex << tag() << std::dec << ": Writing " << strips_.size() << " strips";
 1263|       |#endif
 1264|  14.7k|    len = 0;
 1265|  14.7k|    for (auto&& [f, s] : strips_) {
  ------------------
  |  Branch (1265:24): [True: 0, False: 14.7k]
  ------------------
 1266|      0|      ioWrapper.write(f, s);
 1267|      0|      len += s;
 1268|      0|      size_t align = s & 1;  // Align strip data to word boundary
 1269|      0|      if (align)
  ------------------
  |  Branch (1269:11): [True: 0, False: 0]
  ------------------
 1270|      0|        ioWrapper.putb(0x0);
 1271|      0|      len += align;
 1272|      0|    }
 1273|  14.7k|  }
 1274|       |#ifdef EXIV2_DEBUG_MESSAGES
 1275|       |  std::cerr << ", len = " << len << " bytes\n";
 1276|       |#endif
 1277|  15.8k|  return len;
 1278|  15.8k|}  // TiffImageEntry::doWriteImage
_ZNK5Exiv28Internal13TiffComponent4sizeEv:
 1280|   575k|size_t TiffComponent::size() const {
 1281|   575k|  return doSize();
 1282|   575k|}
_ZNK5Exiv28Internal13TiffEntryBase6doSizeEv:
 1310|  2.22M|size_t TiffEntryBase::doSize() const {
 1311|  2.22M|  return size_;
 1312|  2.22M|}
_ZNK5Exiv28Internal14TiffImageEntry6doSizeEv:
 1314|  64.3k|size_t TiffImageEntry::doSize() const {
 1315|  64.3k|  return strips_.size() * 4;
 1316|  64.3k|}
_ZNK5Exiv28Internal13TiffComponent8sizeDataEv:
 1369|   426k|size_t TiffComponent::sizeData() const {
 1370|   426k|  return doSizeData();
 1371|   426k|}
_ZNK5Exiv28Internal13TiffEntryBase10doSizeDataEv:
 1377|   377k|size_t TiffEntryBase::doSizeData() const {
 1378|   377k|  return 0;
 1379|   377k|}
_ZNK5Exiv28Internal14TiffImageEntry10doSizeDataEv:
 1381|  48.2k|size_t TiffImageEntry::doSizeData() const {
 1382|  48.2k|  size_t len = 0;
 1383|       |  // For makernotes, TIFF image data is written to the data area
 1384|  48.2k|  if (group() > IfdId::mnId) {  // Todo: Fix this hack!!
  ------------------
  |  Branch (1384:7): [True: 0, False: 48.2k]
  ------------------
 1385|      0|    len = sizeImage();
 1386|      0|  }
 1387|  48.2k|  return len;
 1388|  48.2k|}
_ZN5Exiv28Internal8toTypeIdENS0_8TiffTypeEtNS_5IfdIdE:
 1452|  2.55M|TypeId toTypeId(TiffType tiffType, uint16_t tag, IfdId group) {
 1453|  2.55M|  auto ti = static_cast<TypeId>(tiffType);
 1454|       |  // On the fly type conversion for Exif.Photo.UserComment, Exif.GPSProcessingMethod, GPSAreaInformation
 1455|  2.55M|  if (const TagInfo* pTag = ti == undefined ? findTagInfo(tag, group) : nullptr) {
  ------------------
  |  Branch (1455:22): [True: 722, False: 2.55M]
  ------------------
 1456|    722|    if (pTag->typeId_ == comment) {
  ------------------
  |  Branch (1456:9): [True: 350, False: 372]
  ------------------
 1457|    350|      ti = comment;
 1458|    350|    }
 1459|    722|  }
 1460|       |  // http://dev.exiv2.org/boards/3/topics/1337 change unsignedByte to signedByte
 1461|       |  // Exif.NikonAFT.AFFineTuneAdj || Exif.Pentax.Temperature
 1462|  2.55M|  if (ti == Exiv2::unsignedByte &&
  ------------------
  |  Branch (1462:7): [True: 697k, False: 1.85M]
  ------------------
 1463|   697k|      ((tag == 0x0002 && group == IfdId::nikonAFTId) || (tag == 0x0047 && group == IfdId::pentaxId))) {
  ------------------
  |  Branch (1463:9): [True: 430, False: 697k]
  |  Branch (1463:26): [True: 4, False: 426]
  |  Branch (1463:58): [True: 184, False: 697k]
  |  Branch (1463:75): [True: 42, False: 142]
  ------------------
 1464|     46|    ti = Exiv2::signedByte;
 1465|     46|  }
 1466|  2.55M|  return ti;
 1467|  2.55M|}
_ZN5Exiv28Internal10toTiffTypeENS_6TypeIdE:
 1469|  1.19M|TiffType toTiffType(TypeId typeId) {
 1470|  1.19M|  if (static_cast<uint32_t>(typeId) > 0xffff) {
  ------------------
  |  Branch (1470:7): [True: 0, False: 1.19M]
  ------------------
 1471|      0|#ifndef SUPPRESS_WARNINGS
 1472|      0|    EXV_ERROR << "'" << TypeInfo::typeName(typeId) << "' is not a valid Exif (TIFF) type; using type '"
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
 1473|      0|              << TypeInfo::typeName(undefined) << "'.\n";
 1474|      0|#endif
 1475|      0|    return ttUndefined;
 1476|      0|  }
 1477|  1.19M|  return static_cast<TiffType>(typeId);
 1478|  1.19M|}
_ZN5Exiv28Internal8cmpTagLtERKNSt3__110shared_ptrINS0_13TiffComponentEEES6_:
 1480|  1.40M|bool cmpTagLt(const TiffComponent::SharedPtr& lhs, const TiffComponent::SharedPtr& rhs) {
 1481|  1.40M|  if (lhs->tag() != rhs->tag())
  ------------------
  |  Branch (1481:7): [True: 435k, False: 966k]
  ------------------
 1482|   435k|    return lhs->tag() < rhs->tag();
 1483|   966k|  return lhs->idx() < rhs->idx();
 1484|  1.40M|}
_ZN5Exiv28Internal12newTiffEntryEtNS_5IfdIdE:
 1486|   832k|TiffComponent::UniquePtr newTiffEntry(uint16_t tag, IfdId group) {
 1487|   832k|  return std::make_unique<TiffEntry>(tag, group);
 1488|   832k|}
_ZN5Exiv28Internal14newTiffMnEntryEtNS_5IfdIdE:
 1490|  11.8k|TiffComponent::UniquePtr newTiffMnEntry(uint16_t tag, IfdId group) {
 1491|  11.8k|  return std::make_unique<TiffMnEntry>(tag, group, IfdId::mnId);
 1492|  11.8k|}
_ZN5Exiv28Internal20newTiffBinaryElementEtNS_5IfdIdE:
 1494|   569k|TiffComponent::UniquePtr newTiffBinaryElement(uint16_t tag, IfdId group) {
 1495|   569k|  return std::make_unique<TiffBinaryElement>(tag, group);
 1496|   569k|}
tiffcomposite_int.cpp:_ZZN5Exiv28Internal13TiffDirectory9doAddPathEtRNSt3__15stackINS0_12TiffPathItemENS2_5dequeIS4_NS2_9allocatorIS4_EEEEEEPNS0_13TiffComponentENS2_10unique_ptrISB_NS2_14default_deleteISB_EEEEENK3$_0clEv:
  473|   142k|  auto atc = [&] {
  474|   142k|    if (tiffPath.size() == 1 && object) {
  ------------------
  |  Branch (474:9): [True: 142k, False: 0]
  |  Branch (474:33): [True: 0, False: 142k]
  ------------------
  475|      0|      return std::move(object);
  476|      0|    }
  477|   142k|    return TiffCreator::create(tpi.extendedTag(), tpi.group());
  478|   142k|  }();
tiffcomposite_int.cpp:_ZZN5Exiv28Internal13TiffDirectory9doAddPathEtRNSt3__15stackINS0_12TiffPathItemENS2_5dequeIS4_NS2_9allocatorIS4_EEEEEEPNS0_13TiffComponentENS2_10unique_ptrISB_NS2_14default_deleteISB_EEEEENK3$_1clEv:
  485|   142k|  tc = [&] {
  486|   142k|    if (tpi.extendedTag() == Tag::next)
  ------------------
  |  Branch (486:9): [True: 0, False: 142k]
  ------------------
  487|      0|      return this->addNext(std::move(atc));
  488|   142k|    return this->addChild(std::move(atc));
  489|   142k|  }();
tiffcomposite_int.cpp:_ZN5Exiv28InternalL11findTagInfoEtNS_5IfdIdE:
 1437|  4.32k|static const TagInfo* findTagInfo(uint16_t tag, IfdId group) {
 1438|  4.32k|  const TagInfo* tags = [=] {
 1439|  4.32k|    if (group == IfdId::gpsId)
 1440|  4.32k|      return Internal::gpsTagList();
 1441|  4.32k|    return group == IfdId::exifId ? Internal::exifTagList() : nullptr;
 1442|  4.32k|  }();
 1443|  4.32k|  if (tags)
  ------------------
  |  Branch (1443:7): [True: 1.22k, False: 3.10k]
  ------------------
 1444|  58.3k|    for (size_t idx = 0; tags[idx].tag_ != 0xffff; ++idx)
  ------------------
  |  Branch (1444:26): [True: 57.8k, False: 500]
  ------------------
 1445|  57.8k|      if (tags[idx].tag_ == tag)
  ------------------
  |  Branch (1445:11): [True: 722, False: 57.1k]
  ------------------
 1446|    722|        return tags + idx;
 1447|  3.60k|  return nullptr;
 1448|  4.32k|}
tiffcomposite_int.cpp:_ZZN5Exiv28InternalL11findTagInfoEtNS_5IfdIdEENK3$_0clEv:
 1438|  4.32k|  const TagInfo* tags = [=] {
 1439|  4.32k|    if (group == IfdId::gpsId)
  ------------------
  |  Branch (1439:9): [True: 554, False: 3.76k]
  ------------------
 1440|    554|      return Internal::gpsTagList();
 1441|  3.76k|    return group == IfdId::exifId ? Internal::exifTagList() : nullptr;
  ------------------
  |  Branch (1441:12): [True: 668, False: 3.10k]
  ------------------
 1442|  4.32k|  }();

_ZN5Exiv28Internal12TiffPathItemC2EjNS_5IfdIdE:
   74|   285k|  constexpr TiffPathItem(uint32_t extendedTag, IfdId group) : extendedTag_(extendedTag), group_(group) {
   75|   285k|  }
_ZNK5Exiv28Internal12TiffPathItem11extendedTagEv:
   85|   428k|  [[nodiscard]] uint32_t extendedTag() const {
   86|   428k|    return extendedTag_;
   87|   428k|  }
_ZNK5Exiv28Internal12TiffPathItem5groupEv:
   89|   142k|  [[nodiscard]] IfdId group() const {
   90|   142k|    return group_;
   91|   142k|  }
_ZN5Exiv28Internal13TiffComponentC2EtNS_5IfdIdE:
  170|  1.60M|  constexpr TiffComponent(uint16_t tag, IfdId group) : tag_(tag), group_(group) {
  171|  1.60M|  }
_ZN5Exiv28Internal13TiffComponent8setStartEPKh:
  216|  1.45M|  void setStart(const byte* pStart) {
  217|  1.45M|    pStart_ = const_cast<byte*>(pStart);
  218|  1.45M|  }
_ZNK5Exiv28Internal13TiffComponent3tagEv:
  240|  27.2M|  [[nodiscard]] uint16_t tag() const {
  241|  27.2M|    return tag_;
  242|  27.2M|  }
_ZNK5Exiv28Internal13TiffComponent5groupEv:
  244|  6.32M|  [[nodiscard]] IfdId group() const {
  245|  6.32M|    return group_;
  246|  6.32M|  }
_ZNK5Exiv28Internal13TiffComponent5startEv:
  248|  1.49M|  [[nodiscard]] byte* start() const {
  249|  1.49M|    return pStart_;
  250|  1.49M|  }
_ZN5Exiv28Internal13TiffEntryBase9setOffsetEm:
  416|  1.06M|  void setOffset(size_t offset) {
  417|  1.06M|    offset_ = offset;
  418|  1.06M|  }
_ZNK5Exiv28Internal13TiffEntryBase8tiffTypeEv:
  458|   210k|  [[nodiscard]] TiffType tiffType() const {
  459|   210k|    return tiffType_;
  460|   210k|  }
_ZNK5Exiv28Internal13TiffEntryBase6offsetEv:
  465|  7.46k|  [[nodiscard]] size_t offset() const {
  466|  7.46k|    return offset_;
  467|  7.46k|  }
_ZNK5Exiv28Internal13TiffEntryBase5pDataEv:
  476|  1.17M|  [[nodiscard]] const byte* pData() const {
  477|  1.17M|    return pData_;
  478|  1.17M|  }
_ZNK5Exiv28Internal13TiffEntryBase6pValueEv:
  480|  3.27M|  [[nodiscard]] const Value* pValue() const {
  481|  3.27M|    return pValue_.get();
  482|  3.27M|  }
_ZN5Exiv28Internal13TiffEntryBase6setIdxEi:
  501|  1.05M|  void setIdx(int idx) {
  502|  1.05M|    idx_ = idx;
  503|  1.05M|  }
_ZNK5Exiv28Internal13TiffEntryBase7storageEv:
  540|   567k|  [[nodiscard]] std::shared_ptr<DataBuf> storage() const {
  541|   567k|    return storage_;
  542|   567k|  }
_ZNK5Exiv28Internal17TiffDataEntryBase5szTagEv:
  623|  43.6k|  [[nodiscard]] uint16_t szTag() const {
  624|  43.6k|    return szTag_;
  625|  43.6k|  }
_ZNK5Exiv28Internal17TiffDataEntryBase7szGroupEv:
  627|  43.6k|  [[nodiscard]] IfdId szGroup() const {
  628|  43.6k|    return szGroup_;
  629|  43.6k|  }
_ZNK5Exiv28Internal13TiffSizeEntry5dtTagEv:
  789|  52.9k|  [[nodiscard]] uint16_t dtTag() const {
  790|  52.9k|    return dtTag_;
  791|  52.9k|  }
_ZNK5Exiv28Internal13TiffSizeEntry7dtGroupEv:
  793|  52.9k|  [[nodiscard]] IfdId dtGroup() const {
  794|  52.9k|    return dtGroup_;
  795|  52.9k|  }
_ZNK5Exiv28Internal13TiffDirectory7hasNextEv:
  842|  13.4k|  [[nodiscard]] bool hasNext() const {
  843|  13.4k|    return hasNext_;
  844|  13.4k|  }
_ZN5Exiv28Internal16TiffIfdMakernote17setImageByteOrderENS_9ByteOrderE:
 1106|  2.78k|  void setImageByteOrder(ByteOrder byteOrder) {
 1107|  2.78k|    imageByteOrder_ = byteOrder;
 1108|  2.78k|  }
_ZNK5Exiv28Internal8ArrayDefeqEm:
 1217|   577k|  bool operator==(size_t idx) const {
 1218|   577k|    return idx_ == idx;
 1219|   577k|  }
_ZNK5Exiv28Internal8ArrayCfg7tagStepEv:
 1234|   568k|  [[nodiscard]] size_t tagStep() const {
 1235|   568k|    return elDefaultDef_.size(0, group_);
 1236|   568k|  }
_ZN5Exiv28Internal15TiffBinaryArray10setDecodedEb:
 1310|   569k|  void setDecoded(bool decoded) {
 1311|   569k|    decoded_ = decoded;
 1312|   569k|  }
_ZNK5Exiv28Internal15TiffBinaryArray3cfgEv:
 1318|  2.27M|  [[nodiscard]] const ArrayCfg* cfg() const {
 1319|  2.27M|    return arrayCfg_;
 1320|  2.27M|  }
_ZNK5Exiv28Internal15TiffBinaryArray3defEv:
 1322|    827|  [[nodiscard]] const ArrayDef* def() const {
 1323|    827|    return arrayDef_;
 1324|    827|  }
_ZNK5Exiv28Internal15TiffBinaryArray7defSizeEv:
 1326|    827|  [[nodiscard]] size_t defSize() const {
 1327|    827|    return defSize_;
 1328|    827|  }
_ZNK5Exiv28Internal15TiffBinaryArray7decodedEv:
 1330|  4.23k|  [[nodiscard]] bool decoded() const {
 1331|  4.23k|    return decoded_;
 1332|  4.23k|  }
_ZN5Exiv28Internal17TiffBinaryElement8setElDefERKNS0_8ArrayDefE:
 1404|   567k|  void setElDef(const ArrayDef& def) {
 1405|   567k|    elDef_ = def;
 1406|   567k|  }
_ZN5Exiv28Internal17TiffBinaryElement14setElByteOrderENS_9ByteOrderE:
 1410|   567k|  void setElByteOrder(ByteOrder byteOrder) {
 1411|   567k|    elByteOrder_ = byteOrder;
 1412|   567k|  }
_ZNK5Exiv28Internal17TiffBinaryElement5elDefEv:
 1420|   569k|  [[nodiscard]] const ArrayDef* elDef() const {
 1421|   569k|    return &elDef_;
 1422|   569k|  }
_ZNK5Exiv28Internal17TiffBinaryElement11elByteOrderEv:
 1426|   569k|  [[nodiscard]] ByteOrder elByteOrder() const {
 1427|   569k|    return elByteOrder_;
 1428|   569k|  }
_ZN5Exiv28Internal16newTiffDirectoryILNS_5IfdIdE1EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1487|  13.9k|TiffComponent::UniquePtr newTiffDirectory(uint16_t tag, IfdId /*group*/) {
 1488|  13.9k|  return std::make_unique<TiffDirectory>(tag, newGroup);
 1489|  13.9k|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE56EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     54|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     54|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     54|}
_ZN5Exiv28Internal16newTiffDirectoryILNS_5IfdIdE5EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1487|     55|TiffComponent::UniquePtr newTiffDirectory(uint16_t tag, IfdId /*group*/) {
 1488|     55|  return std::make_unique<TiffDirectory>(tag, newGroup);
 1489|     55|}
_ZN5Exiv28Internal16newTiffDirectoryILNS_5IfdIdE21EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1487|    593|TiffComponent::UniquePtr newTiffDirectory(uint16_t tag, IfdId /*group*/) {
 1488|    593|  return std::make_unique<TiffDirectory>(tag, newGroup);
 1489|    593|}
_ZN5Exiv28Internal16newTiffDirectoryILNS_5IfdIdE6EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1487|     59|TiffComponent::UniquePtr newTiffDirectory(uint16_t tag, IfdId /*group*/) {
 1488|     59|  return std::make_unique<TiffDirectory>(tag, newGroup);
 1489|     59|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE5EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    202|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    202|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    202|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE6EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    265|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    265|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    265|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE1EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  8.70k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  8.70k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  8.70k|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE1EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|  7.02k|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|  7.02k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|  7.02k|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE1EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  2.28k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  2.28k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  2.28k|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE1EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    983|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    983|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    983|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE1EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  12.8k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  12.8k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  12.8k|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE1EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|  23.0k|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|  23.0k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|  23.0k|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE9EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|  5.71k|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|  5.71k|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|  5.71k|}
_ZN5Exiv28Internal16newTiffDirectoryILNS_5IfdIdE2EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1487|  4.97k|TiffComponent::UniquePtr newTiffDirectory(uint16_t tag, IfdId /*group*/) {
 1488|  4.97k|  return std::make_unique<TiffDirectory>(tag, newGroup);
 1489|  4.97k|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE9EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  2.64k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  2.64k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  2.64k|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE9EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|  1.86k|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|  1.86k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|  1.86k|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE9EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  1.36k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  1.36k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  1.36k|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE9EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    576|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    576|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    576|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE9EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  5.38k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  5.38k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  5.38k|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE9EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|  8.17k|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|  8.17k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|  8.17k|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE10EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    673|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    673|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    673|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE10EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    318|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    318|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    318|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE10EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    308|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    308|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    308|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE10EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    131|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    131|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    131|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE10EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    661|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    661|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    661|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE10EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    557|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    557|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    557|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE11EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  2.40k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  2.40k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  2.40k|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE11EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|  1.70k|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|  1.70k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|  1.70k|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE11EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    707|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    707|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    707|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE11EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    549|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    549|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    549|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE11EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  3.76k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  3.76k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  3.76k|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE11EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|  4.76k|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|  4.76k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|  4.76k|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE12EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  2.21k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  2.21k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  2.21k|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE12EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|  1.79k|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|  1.79k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|  1.79k|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE12EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  1.09k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  1.09k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  1.09k|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE12EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    551|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    551|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    551|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE12EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|  3.35k|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|  3.35k|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|  3.35k|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE12EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|  5.46k|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|  5.46k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|  5.46k|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE13EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    503|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    503|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    503|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE13EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    234|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    234|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    234|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE13EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    386|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    386|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    386|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE13EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    264|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    264|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    264|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE13EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    346|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    346|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    346|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE13EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    982|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    982|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    982|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE14EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    281|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    281|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    281|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE14EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    109|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    109|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    109|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE14EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    272|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    272|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    272|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE14EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    257|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    257|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    257|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE14EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    325|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    325|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    325|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE14EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    795|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    795|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    795|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE15EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    313|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    313|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    313|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE15EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|     69|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|     69|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|     69|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE15EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    210|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    210|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    210|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE15EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    209|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    209|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    209|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE15EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    236|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    236|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    236|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE15EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    657|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    657|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    657|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE16EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    243|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    243|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    243|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE16EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|     71|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|     71|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|     71|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE16EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    214|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    214|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    214|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE16EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|     68|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|     68|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|     68|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE16EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    110|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    110|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    110|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE16EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    326|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    326|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    326|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE17EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|     69|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|     69|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|     69|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE17EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|     79|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|     79|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|     79|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE17EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    139|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    139|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    139|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE17EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    106|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    106|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    106|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE17EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|     77|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|     77|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|     77|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE17EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    427|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    427|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    427|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE7EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     58|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     58|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     58|}
_ZN5Exiv28Internal16newTiffThumbDataILt279ELNS_5IfdIdE2EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1519|  2.33k|TiffComponent::UniquePtr newTiffThumbData(uint16_t tag, IfdId group) {
 1520|  2.33k|  return std::make_unique<TiffDataEntry>(tag, group, szTag, szGroup);
 1521|  2.33k|}
_ZN5Exiv28Internal16newTiffThumbSizeILt273ELNS_5IfdIdE2EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1525|  1.42k|TiffComponent::UniquePtr newTiffThumbSize(uint16_t tag, IfdId group) {
 1526|  1.42k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1527|  1.42k|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE2EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    379|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    379|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    379|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE2EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    388|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    388|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    388|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE18EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    496|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    496|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    496|}
_ZN5Exiv28Internal16newTiffThumbDataILt514ELNS_5IfdIdE2EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1519|  2.25k|TiffComponent::UniquePtr newTiffThumbData(uint16_t tag, IfdId group) {
 1520|  2.25k|  return std::make_unique<TiffDataEntry>(tag, group, szTag, szGroup);
 1521|  2.25k|}
_ZN5Exiv28Internal16newTiffThumbSizeILt513ELNS_5IfdIdE2EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1525|  7.57k|TiffComponent::UniquePtr newTiffThumbSize(uint16_t tag, IfdId group) {
 1526|  7.57k|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1527|  7.57k|}
_ZN5Exiv28Internal16newTiffDirectoryILNS_5IfdIdE3EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1487|    380|TiffComponent::UniquePtr newTiffDirectory(uint16_t tag, IfdId /*group*/) {
 1488|    380|  return std::make_unique<TiffDirectory>(tag, newGroup);
 1489|    380|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE18EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    151|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    151|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    151|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE18EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|     99|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|     99|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|     99|}
_ZN5Exiv28Internal16newTiffImageDataILt325ELNS_5IfdIdE18EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    227|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    227|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    227|}
_ZN5Exiv28Internal16newTiffImageSizeILt324ELNS_5IfdIdE18EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    141|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    141|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    141|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE18EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|     75|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|     75|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|     75|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE18EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    254|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    254|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    254|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE3EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    200|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    200|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    200|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE3EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    197|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    197|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    197|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE3EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    242|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    242|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    242|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE3EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    241|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    241|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    241|}
_ZN5Exiv28Internal16newTiffDirectoryILNS_5IfdIdE4EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1487|     53|TiffComponent::UniquePtr newTiffDirectory(uint16_t tag, IfdId /*group*/) {
 1488|     53|  return std::make_unique<TiffDirectory>(tag, newGroup);
 1489|     53|}
_ZN5Exiv28Internal16newTiffImageDataILt279ELNS_5IfdIdE4EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|    214|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|    214|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|    214|}
_ZN5Exiv28Internal16newTiffImageSizeILt273ELNS_5IfdIdE4EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|     73|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|     73|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|     73|}
_ZN5Exiv28Internal16newTiffImageDataILt514ELNS_5IfdIdE4EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1531|     71|TiffComponent::UniquePtr newTiffImageData(uint16_t tag, IfdId group) {
 1532|     71|  return std::make_unique<TiffImageEntry>(tag, group, szTag, szGroup);
 1533|     71|}
_ZN5Exiv28Internal16newTiffImageSizeILt513ELNS_5IfdIdE4EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1537|    206|TiffComponent::UniquePtr newTiffImageSize(uint16_t tag, IfdId group) {
 1538|       |  // Todo: Same as newTiffThumbSize - consolidate (rename)?
 1539|    206|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1540|    206|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10minoCsoCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    159|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    159|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    159|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10minoCsnCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    104|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    104|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    104|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE100EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     28|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     28|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     28|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE99EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    311|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    311|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    311|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE101EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     78|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     78|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     78|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE102EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     78|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     78|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     78|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE103EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     34|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     34|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     34|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE104EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     41|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     41|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     41|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE105EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     33|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     33|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     33|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE106EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     73|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     73|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     73|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE107EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     23|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     23|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     23|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE108EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    111|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    111|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    111|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE109EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    110|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    110|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    110|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE110EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     81|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     81|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     81|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE111EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     40|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     40|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     40|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE112EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    224|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    224|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    224|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE113EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    170|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    170|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    170|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE114EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     75|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     75|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     75|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10canonCsCfgEELm1ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10canonCsDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|    819|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|    819|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|    819|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|    819|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10canonSiCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    150|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    150|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    150|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10canonPaCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    326|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    326|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    326|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10canonCfCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|     58|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|     58|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|     58|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10canonPiCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|     87|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|     87|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|     87|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10canonTiCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|     81|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|     81|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|     81|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10canonFiCfgEELm1ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10canonFiDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|    113|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|    113|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|    113|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|    113|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10canonPrCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    139|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    139|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    139|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L15canonAfMiAdjCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    233|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    233|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    233|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L15canonVigCor2CfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|     70|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|     70|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|     70|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L12canonLiOpCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    207|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    207|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    207|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10canonLeCfgEELm2ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10canonLeDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     93|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     93|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     93|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     93|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10canonAmCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|     44|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|     44|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|     44|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L10canonMeCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|     93|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|     93|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|     93|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L11canonFilCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    124|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    124|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    124|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L11canonHdrCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|    152|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|    152|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|    152|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L11canonAfCCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|     87|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|     87|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|     87|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray1IL_ZNS0_L12canonRawBCfgEEEENSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEEtNS_5IfdIdE:
 1506|     45|TiffComponent::UniquePtr newTiffBinaryArray1(uint16_t tag, IfdId group) {
 1507|     45|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, nullptr, 0);
 1508|     45|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE65EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|    113|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|    113|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|    113|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10nikonVrCfgEELm2ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10nikonVrDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     29|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     29|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     29|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     29|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10nikonPcCfgEELm13ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10nikonPcDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     51|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     51|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     51|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     51|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10nikonWtCfgEELm3ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10nikonWtDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     90|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     90|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     90|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     90|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10nikonIiCfgEELm5ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10nikonIiDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     50|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     50|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     50|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     50|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10nikonAfCfgEELm3ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10nikonAfDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|    112|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|    112|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|    112|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|    112|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm6ETnRAT__KNS0_8ArraySetEL_ZNS0_L10nikonSiSetEEXadL_ZNS0_13nikonSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|    100|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|    100|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|    100|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|    100|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm6ETnRAT__KNS0_8ArraySetEL_ZNS0_L10nikonCbSetEEXadL_ZNS0_13nikonSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|    121|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|    121|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|    121|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|    121|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm4ETnRAT__KNS0_8ArraySetEL_ZNS0_L10nikonLdSetEEXadL_ZNS0_13nikonSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|     81|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|     81|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|     81|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|     81|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm5ETnRAT__KNS0_8ArraySetEL_ZNS0_L10nikonFlSetEEXadL_ZNS0_13nikonSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|     41|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|     41|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|     41|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|     41|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10nikonMeCfgEELm4ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10nikonMeDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     37|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     37|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     37|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     37|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm2ETnRAT__KNS0_8ArraySetEL_ZNS0_L11nikonAf2SetEEXadL_ZNS0_13nikonSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|     26|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|     26|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|     26|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|     26|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10nikonFiCfgEELm3ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10nikonFiDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     25|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     25|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     25|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     25|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L11nikonAFTCfgEELm3ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L11nikonAFTDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     39|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     39|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     39|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     39|}
_ZN5Exiv28Internal16newTiffThumbDataILt514ELNS_5IfdIdE65EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1519|     42|TiffComponent::UniquePtr newTiffThumbData(uint16_t tag, IfdId group) {
 1520|     42|  return std::make_unique<TiffDataEntry>(tag, group, szTag, szGroup);
 1521|     42|}
_ZN5Exiv28Internal16newTiffThumbSizeILt513ELNS_5IfdIdE65EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1525|    145|TiffComponent::UniquePtr newTiffThumbSize(uint16_t tag, IfdId group) {
 1526|    145|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1527|    145|}
_ZN5Exiv28Internal16newTiffThumbSizeILt4ELNS_5IfdIdE117EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1525|     40|TiffComponent::UniquePtr newTiffThumbSize(uint16_t tag, IfdId group) {
 1526|     40|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1527|     40|}
_ZN5Exiv28Internal16newTiffThumbDataILt3ELNS_5IfdIdE117EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1519|     74|TiffComponent::UniquePtr newTiffThumbData(uint16_t tag, IfdId group) {
 1520|     74|  return std::make_unique<TiffDataEntry>(tag, group, szTag, szGroup);
 1521|     74|}
_ZN5Exiv28Internal16newTiffThumbSizeILt4ELNS_5IfdIdE116EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1525|    108|TiffComponent::UniquePtr newTiffThumbSize(uint16_t tag, IfdId group) {
 1526|    108|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1527|    108|}
_ZN5Exiv28Internal16newTiffThumbDataILt3ELNS_5IfdIdE116EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1519|     88|TiffComponent::UniquePtr newTiffThumbData(uint16_t tag, IfdId group) {
 1520|     88|  return std::make_unique<TiffDataEntry>(tag, group, szTag, szGroup);
 1521|     88|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L12samsungPwCfgEELm5ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L12samsungPwDefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     70|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     70|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     70|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     70|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE119EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     34|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     34|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     34|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm1ETnRAT__KNS0_8ArraySetEL_ZNS0_L12sony2010eSetEEXadL_ZNS0_17sony2010eSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|     57|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|     57|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|     57|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|     57|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm1ETnRAT__KNS0_8ArraySetEL_ZNS0_L10sony2FpSetEEXadL_ZNS0_15sony2FpSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|     72|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|     72|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|     72|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|     72|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm1ETnRAT__KNS0_8ArraySetEL_ZNS0_L13sonyMisc2bSetEEXadL_ZNS0_18sonyMisc2bSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|    178|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|    178|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|    178|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|    178|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm1ETnRAT__KNS0_8ArraySetEL_ZNS0_L13sonyMisc3cSetEEXadL_ZNS0_18sonyMisc3cSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|    250|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|    250|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|    250|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|    250|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L12sonyMisc1CfgEELm1ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L12sonyMisc1DefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     25|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     25|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     25|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     25|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L13sonySInfo1CfgEELm5ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L13sonySInfo1DefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|    117|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|    117|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|    117|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|    117|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm2ETnRAT__KNS0_8ArraySetEL_ZNS0_L10sony1CsSetEEXadL_ZNS0_14sonyCsSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|     57|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|     57|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|     57|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|     57|}
_ZN5Exiv28Internal13newTiffSubIfdILNS_5IfdIdE124EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1493|     35|TiffComponent::UniquePtr newTiffSubIfd(uint16_t tag, IfdId group) {
 1494|     35|  return std::make_unique<TiffSubIfd>(tag, group, newGroup);
 1495|     35|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray2ILm2ETnRAT__KNS0_8ArraySetEL_ZNS0_L10sony2CsSetEEXadL_ZNS0_14sonyCsSelectorEtPKhmPNS0_13TiffComponentEEEEENSt3__110unique_ptrIS8_NSA_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1512|     88|TiffComponent::UniquePtr newTiffBinaryArray2(uint16_t tag, IfdId group) {
 1513|     88|  static_assert(N > 0, "Passed zero length newTiffBinaryArray2");
 1514|     88|  return std::make_unique<TiffBinaryArray>(tag, group, arraySet, N, cfgSelFct);
 1515|     88|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10minoCs7CfgEELm2ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10minoCs7DefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     97|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     97|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     97|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     97|}
_ZN5Exiv28Internal16newTiffThumbDataILt137ELNS_5IfdIdE57EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1519|     21|TiffComponent::UniquePtr newTiffThumbData(uint16_t tag, IfdId group) {
 1520|     21|  return std::make_unique<TiffDataEntry>(tag, group, szTag, szGroup);
 1521|     21|}
_ZN5Exiv28Internal16newTiffThumbSizeILt136ELNS_5IfdIdE57EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1525|     38|TiffComponent::UniquePtr newTiffThumbSize(uint16_t tag, IfdId group) {
 1526|     38|  return std::make_unique<TiffSizeEntry>(tag, group, dtTag, dtGroup);
 1527|     38|}
tiffimage_int.cpp:_ZN5Exiv28Internal19newTiffBinaryArray0IL_ZNS0_L10minoCs5CfgEELm1ETnRAT0__KNS0_8ArrayDefEL_ZNS0_L10minoCs5DefEEEENSt3__110unique_ptrINS0_13TiffComponentENS6_14default_deleteIS8_EEEEtNS_5IfdIdE:
 1499|     26|TiffComponent::UniquePtr newTiffBinaryArray0(uint16_t tag, IfdId group) {
 1500|     26|  static_assert(N > 0, "Passed zero length newTiffBinaryArray0");
 1501|     26|  return std::make_unique<TiffBinaryArray>(tag, group, arrayCfg, arrayDef, N);
 1502|     26|}
_ZN5Exiv28Internal16newTiffDirectoryILNS_5IfdIdE19EEENSt3__110unique_ptrINS0_13TiffComponentENS3_14default_deleteIS5_EEEEtS2_:
 1487|     81|TiffComponent::UniquePtr newTiffDirectory(uint16_t tag, IfdId /*group*/) {
 1488|     81|  return std::make_unique<TiffDirectory>(tag, newGroup);
 1489|     81|}
_ZN5Exiv28Internal13TiffComponentD2Ev:
  173|  1.60M|  virtual ~TiffComponent() = default;
_ZN5Exiv28Internal13TiffDirectoryD2Ev:
  830|  43.3k|  ~TiffDirectory() override = default;
_ZN5Exiv28Internal10TiffSubIfdD2Ev:
  937|  8.48k|  ~TiffSubIfd() override = default;
_ZN5Exiv28Internal15TiffBinaryArrayD2Ev:
 1269|  5.02k|  ~TiffBinaryArray() override = default;

_ZN5Exiv29TiffImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   44|  8.42k|    Image(ImageType::tiff, mdExif | mdIptc | mdXmp, std::move(io)) {
   45|  8.42k|}  // TiffImage::TiffImage
_ZNK5Exiv29TiffImage8mimeTypeEv:
   61|  21.5k|std::string TiffImage::mimeType() const {
   62|  21.5k|  if (!mimeType_.empty())
  ------------------
  |  Branch (62:7): [True: 14.2k, False: 7.27k]
  ------------------
   63|  14.2k|    return mimeType_;
   64|       |
   65|  7.27k|  mimeType_ = std::string("image/tiff");
   66|  7.27k|  std::string key = "Exif." + primaryGroup() + ".Compression";
   67|  7.27k|  auto md = exifData_.findKey(ExifKey(key));
   68|  7.27k|  if (md != exifData_.end() && md->count() > 0) {
  ------------------
  |  Branch (68:7): [True: 146, False: 7.12k]
  |  Branch (68:7): [True: 113, False: 7.15k]
  |  Branch (68:32): [True: 113, False: 33]
  ------------------
   69|    113|    auto mt = Exiv2::find(mimeTypeList, static_cast<int>(md->toInt64()));
   70|    113|    if (mt)
  ------------------
  |  Branch (70:9): [True: 5, False: 108]
  ------------------
   71|      5|      mimeType_ = mt->type;
   72|    113|  }
   73|  7.27k|  return mimeType_;
   74|  21.5k|}
_ZNK5Exiv29TiffImage12primaryGroupEv:
   76|  8.25k|std::string TiffImage::primaryGroup() const {
   77|  8.25k|  if (!primaryGroup_.empty())
  ------------------
  |  Branch (77:7): [True: 491, False: 7.76k]
  ------------------
   78|    491|    return primaryGroup_;
   79|       |
   80|  7.76k|  static constexpr auto keys = std::array{
   81|  7.76k|      "Exif.Image.NewSubfileType",     "Exif.SubImage1.NewSubfileType", "Exif.SubImage2.NewSubfileType",
   82|  7.76k|      "Exif.SubImage3.NewSubfileType", "Exif.SubImage4.NewSubfileType", "Exif.SubImage5.NewSubfileType",
   83|  7.76k|      "Exif.SubImage6.NewSubfileType", "Exif.SubImage7.NewSubfileType", "Exif.SubImage8.NewSubfileType",
   84|  7.76k|      "Exif.SubImage9.NewSubfileType",
   85|  7.76k|  };
   86|       |  // Find the group of the primary image, default to "Image"
   87|  7.76k|  primaryGroup_ = std::string("Image");
   88|  77.0k|  for (auto i : keys) {
  ------------------
  |  Branch (88:15): [True: 77.0k, False: 7.68k]
  ------------------
   89|  77.0k|    auto md = exifData_.findKey(ExifKey(i));
   90|       |    // Is it the primary image?
   91|  77.0k|    if (md != exifData_.end() && md->count() > 0 && md->toInt64() == 0) {
  ------------------
  |  Branch (91:9): [True: 4.73k, False: 72.2k]
  |  Branch (91:9): [True: 142, False: 76.8k]
  |  Branch (91:34): [True: 4.47k, False: 253]
  |  Branch (91:53): [True: 142, False: 4.33k]
  ------------------
   92|       |      // Sometimes there is a JPEG primary image; that's not our first choice
   93|    142|      primaryGroup_ = md->groupName();
   94|    142|      std::string key = "Exif." + primaryGroup_ + ".JPEGInterchangeFormat";
   95|    142|      if (exifData_.findKey(ExifKey(key)) == exifData_.end())
  ------------------
  |  Branch (95:11): [True: 76, False: 66]
  ------------------
   96|     76|        break;
   97|    142|    }
   98|  77.0k|  }
   99|  7.76k|  return primaryGroup_;
  100|  8.25k|}
_ZNK5Exiv29TiffImage10pixelWidthEv:
  102|    491|uint32_t TiffImage::pixelWidth() const {
  103|    491|  if (pixelWidthPrimary_ != 0) {
  ------------------
  |  Branch (103:7): [True: 0, False: 491]
  ------------------
  104|      0|    return pixelWidthPrimary_;
  105|      0|  }
  106|       |
  107|    491|  ExifKey key(std::string("Exif.") + primaryGroup() + std::string(".ImageWidth"));
  108|    491|  auto imageWidth = exifData_.findKey(key);
  109|    491|  if (imageWidth != exifData_.end() && imageWidth->count() > 0) {
  ------------------
  |  Branch (109:7): [True: 44, False: 447]
  |  Branch (109:7): [True: 26, False: 465]
  |  Branch (109:40): [True: 26, False: 18]
  ------------------
  110|     26|    pixelWidthPrimary_ = imageWidth->toUint32();
  111|     26|  }
  112|    491|  return pixelWidthPrimary_;
  113|    491|}
_ZNK5Exiv29TiffImage11pixelHeightEv:
  115|    491|uint32_t TiffImage::pixelHeight() const {
  116|    491|  if (pixelHeightPrimary_ != 0) {
  ------------------
  |  Branch (116:7): [True: 0, False: 491]
  ------------------
  117|      0|    return pixelHeightPrimary_;
  118|      0|  }
  119|       |
  120|    491|  ExifKey key(std::string("Exif.") + primaryGroup() + std::string(".ImageLength"));
  121|    491|  auto imageHeight = exifData_.findKey(key);
  122|    491|  if (imageHeight != exifData_.end() && imageHeight->count() > 0) {
  ------------------
  |  Branch (122:7): [True: 34, False: 457]
  |  Branch (122:7): [True: 12, False: 479]
  |  Branch (122:41): [True: 12, False: 22]
  ------------------
  123|     12|    pixelHeightPrimary_ = imageHeight->toUint32();
  124|     12|  }
  125|    491|  return pixelHeightPrimary_;
  126|    491|}
_ZN5Exiv29TiffImage12readMetadataEv:
  133|  8.35k|void TiffImage::readMetadata() {
  134|       |#ifdef EXIV2_DEBUG_MESSAGES
  135|       |  std::cerr << "Reading TIFF file " << io_->path() << "\n";
  136|       |#endif
  137|  8.35k|  if (io_->open() != 0) {
  ------------------
  |  Branch (137:7): [True: 0, False: 8.35k]
  ------------------
  138|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  139|      0|  }
  140|       |
  141|  8.35k|  IoCloser closer(*io_);
  142|       |  // Ensure that this is the correct image type
  143|  8.35k|  if (!isTiffType(*io_, false)) {
  ------------------
  |  Branch (143:7): [True: 0, False: 8.35k]
  ------------------
  144|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (144:9): [True: 0, False: 0]
  |  Branch (144:25): [True: 0, False: 0]
  ------------------
  145|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  146|      0|    throw Error(ErrorCode::kerNotAnImage, "TIFF");
  147|      0|  }
  148|  8.35k|  clearMetadata();
  149|       |
  150|  8.35k|  ByteOrder bo = TiffParser::decode(exifData_, iptcData_, xmpData_, io_->mmap(), io_->size());
  151|  8.35k|  setByteOrder(bo);
  152|       |
  153|       |  // read profile from the metadata
  154|  8.35k|  Exiv2::ExifKey key("Exif.Image.InterColorProfile");
  155|  8.35k|  auto pos = exifData_.findKey(key);
  156|  8.35k|  if (pos != exifData_.end()) {
  ------------------
  |  Branch (156:7): [True: 540, False: 7.81k]
  ------------------
  157|    540|    size_t size = pos->count() * pos->typeSize();
  158|    540|    if (size == 0) {
  ------------------
  |  Branch (158:9): [True: 450, False: 90]
  ------------------
  159|    450|      throw Error(ErrorCode::kerFailedToReadImageData);
  160|    450|    }
  161|     90|    iccProfile_.alloc(size);
  162|     90|    pos->copy(iccProfile_.data(), bo);
  163|     90|  }
  164|  8.35k|}
_ZN5Exiv210TiffParser6decodeERNS_8ExifDataERNS_8IptcDataERNS_7XmpDataEPKhm:
  209|  8.94k|ByteOrder TiffParser::decode(ExifData& exifData, IptcData& iptcData, XmpData& xmpData, const byte* pData, size_t size) {
  210|  8.94k|  uint32_t root = Tag::root;
  211|       |
  212|       |  // #1402  Fujifilm RAF. Change root when parsing embedded tiff
  213|  8.94k|  Exiv2::ExifKey key("Exif.Image.Make");
  214|  8.94k|  if (exifData.findKey(key) != exifData.end() && exifData.findKey(key)->toString() == "FUJIFILM") {
  ------------------
  |  Branch (214:7): [True: 21, False: 8.92k]
  |  Branch (214:7): [True: 0, False: 8.94k]
  |  Branch (214:50): [True: 0, False: 21]
  ------------------
  215|      0|    root = Tag::fuji;
  216|      0|  }
  217|       |
  218|  8.94k|  return TiffParserWorker::decode(exifData, iptcData, xmpData, pData, size, root, TiffMapping::findDecoder);
  219|  8.94k|}  // TiffParser::decode
_ZN5Exiv210TiffParser6encodeERNS_7BasicIoEPKhmNS_9ByteOrderERNS_8ExifDataERKNS_8IptcDataERKNS_7XmpDataE:
  222|  4.40k|                               const IptcData& iptcData, const XmpData& xmpData) {
  223|       |  // Delete IFDs which do not occur in TIFF images
  224|  4.40k|  static constexpr auto filteredIfds = std::array{
  225|  4.40k|      IfdId::panaRawId,
  226|  4.40k|  };
  227|  4.40k|  for (auto filteredIfd : filteredIfds) {
  ------------------
  |  Branch (227:25): [True: 4.40k, False: 4.40k]
  ------------------
  228|       |#ifdef EXIV2_DEBUG_MESSAGES
  229|       |    std::cerr << "Warning: Exif IFD " << filteredIfd << " not encoded\n";
  230|       |#endif
  231|  4.40k|    exifData.erase(std::remove_if(exifData.begin(), exifData.end(), FindExifdatum(filteredIfd)), exifData.end());
  232|  4.40k|  }
  233|       |
  234|  4.40k|  TiffHeader header(byteOrder);
  235|  4.40k|  return TiffParserWorker::encode(io, pData, size, exifData, iptcData, xmpData, Tag::root, TiffMapping::findEncoder,
  236|  4.40k|                                  &header, nullptr);
  237|  4.40k|}  // TiffParser::encode
_ZN5Exiv215newTiffInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  241|  8.35k|Image::UniquePtr newTiffInstance(BasicIo::UniquePtr io, bool create) {
  242|  8.35k|  auto image = std::make_unique<TiffImage>(std::move(io), create);
  243|  8.35k|  if (!image->good()) {
  ------------------
  |  Branch (243:7): [True: 0, False: 8.35k]
  ------------------
  244|      0|    return nullptr;
  245|      0|  }
  246|  8.35k|  return image;
  247|  8.35k|}
_ZN5Exiv210isTiffTypeERNS_7BasicIoEb:
  249|   180k|bool isTiffType(BasicIo& iIo, bool advance) {
  250|   180k|  const int32_t len = 8;
  251|   180k|  byte buf[len];
  252|   180k|  iIo.read(buf, len);
  253|   180k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (253:7): [True: 0, False: 180k]
  |  Branch (253:22): [True: 1.18k, False: 179k]
  ------------------
  254|  1.18k|    return false;
  255|  1.18k|  }
  256|   179k|  TiffHeader tiffHeader;
  257|   179k|  bool rc = tiffHeader.read(buf, len);
  258|   179k|  if (!advance || !rc) {
  ------------------
  |  Branch (258:7): [True: 179k, False: 0]
  |  Branch (258:19): [True: 0, False: 0]
  ------------------
  259|   179k|    iIo.seek(-len, BasicIo::cur);
  260|   179k|  }
  261|   179k|  return rc;
  262|   180k|}
_ZNK5Exiv28mimeTypeeqEi:
   53|    664|  bool operator==(int c) const {
   54|    664|    return comp == c;
   55|    664|  }

_ZNK5Exiv28Internal13FindExifdatumclERKNS_9ExifdatumE:
   29|   142k|bool FindExifdatum::operator()(const Exiv2::Exifdatum& md) const {
   30|   142k|  return ifdId_ == md.ifdId();
   31|   142k|}
_ZN5Exiv28Internal11TiffMapping11findDecoderENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEjNS_5IfdIdE:
 1991|  1.05M|DecoderFct TiffMapping::findDecoder(std::string_view make, uint32_t extendedTag, IfdId group) {
 1992|  1.05M|  DecoderFct decoderFct = &TiffDecoder::decodeStdTiffEntry;
 1993|  1.05M|  if (auto td = Exiv2::find(tiffMappingInfo_, TiffMappingInfo::Key{make, extendedTag, group})) {
  ------------------
  |  Branch (1993:12): [True: 8.24k, False: 1.04M]
  ------------------
 1994|       |    // This may set decoderFct to 0, meaning that the tag should not be decoded
 1995|  8.24k|    decoderFct = td->decoderFct_;
 1996|  8.24k|  }
 1997|  1.05M|  return decoderFct;
 1998|  1.05M|}
_ZN5Exiv28Internal11TiffMapping11findEncoderENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEjNS_5IfdIdE:
 2000|   142k|EncoderFct TiffMapping::findEncoder(std::string_view make, uint32_t extendedTag, IfdId group) {
 2001|   142k|  EncoderFct encoderFct = nullptr;
 2002|   142k|  if (auto td = Exiv2::find(tiffMappingInfo_, TiffMappingInfo::Key{make, extendedTag, group})) {
  ------------------
  |  Branch (2002:12): [True: 0, False: 142k]
  ------------------
 2003|       |    // Returns 0 if no special encoder function is found
 2004|      0|    encoderFct = td->encoderFct_;
 2005|      0|  }
 2006|   142k|  return encoderFct;
 2007|   142k|}
_ZN5Exiv28Internal11TiffCreator6createEjNS_5IfdIdE:
 2009|  1.58M|TiffComponent::UniquePtr TiffCreator::create(uint32_t extendedTag, IfdId group) {
 2010|  1.58M|  auto tag = static_cast<uint16_t>(extendedTag);
 2011|  1.58M|  auto i = tiffGroupTable_.find(TiffGroupKey(extendedTag, group));
 2012|       |  // If the lookup failed then try again with Tag::all.
 2013|  1.58M|  if (i == tiffGroupTable_.end()) {
  ------------------
  |  Branch (2013:7): [True: 1.40M, False: 184k]
  ------------------
 2014|  1.40M|    i = tiffGroupTable_.find(TiffGroupKey(Tag::all, group));
 2015|  1.40M|  }
 2016|  1.58M|  if (i != tiffGroupTable_.end() && i->second) {
  ------------------
  |  Branch (2016:7): [True: 1.58M, False: 200]
  |  Branch (2016:7): [True: 1.57M, False: 7.54k]
  |  Branch (2016:37): [True: 1.57M, False: 7.34k]
  ------------------
 2017|  1.57M|    return i->second(tag, group);
 2018|  1.57M|  }
 2019|       |#ifdef EXIV2_DEBUG_MESSAGES
 2020|       |  if (i == tiffGroupTable_.end())
 2021|       |    std::cerr << "Warning: No TIFF structure entry found for ";
 2022|       |  else
 2023|       |    std::cerr << "Warning: No TIFF component creator found for ";
 2024|       |  std::cerr << "extended tag 0x" << std::setw(4) << std::setfill('0') << std::hex << std::right << extendedTag
 2025|       |            << ", group " << groupName(group) << "\n";
 2026|       |#endif
 2027|  7.54k|  return nullptr;
 2028|  1.58M|}  // TiffCreator::create
_ZN5Exiv28Internal11TiffCreator7getPathEjNS_5IfdIdEj:
 2030|   142k|TiffPath TiffCreator::getPath(uint32_t extendedTag, IfdId group, uint32_t root) {
 2031|   142k|  TiffPath ret;
 2032|   285k|  while (true) {
  ------------------
  |  Branch (2032:10): [True: 285k, Folded]
  ------------------
 2033|   285k|    ret.emplace(extendedTag, group);
 2034|   285k|    const auto ts = tiffTreeTable_.find(TiffGroupKey(root, group));
 2035|   285k|    assert(ts != tiffTreeTable_.end());
 2036|   285k|    extendedTag = ts->second.second;
 2037|   285k|    group = ts->second.first;
 2038|   285k|    if (ts->first == TiffGroupKey(root, IfdId::ifdIdNotSet)) {
  ------------------
  |  Branch (2038:9): [True: 142k, False: 142k]
  ------------------
 2039|   142k|      break;
 2040|   142k|    }
 2041|   285k|  }
 2042|   142k|  return ret;
 2043|   142k|}
_ZN5Exiv28Internal16TiffParserWorker6decodeERNS_8ExifDataERNS_8IptcDataERNS_7XmpDataEPKhmjPFMNS0_11TiffDecoderEFvPKNS0_13TiffEntryBaseEENSt3__117basic_string_viewIcNSG_11char_traitsIcEEEEjNS_5IfdIdEEPNS0_14TiffHeaderBaseE:
 2046|  10.8k|                                   size_t size, uint32_t root, FindDecoderFct findDecoderFct, TiffHeaderBase* pHeader) {
 2047|       |  // Create standard TIFF header if necessary
 2048|  10.8k|  std::unique_ptr<TiffHeaderBase> ph;
 2049|  10.8k|  if (!pHeader) {
  ------------------
  |  Branch (2049:7): [True: 10.5k, False: 254]
  ------------------
 2050|  10.5k|    ph = std::make_unique<TiffHeader>();
 2051|  10.5k|    pHeader = ph.get();
 2052|  10.5k|  }
 2053|       |
 2054|  10.8k|  if (auto rootDir = parse(pData, size, root, pHeader)) {
  ------------------
  |  Branch (2054:12): [True: 10.3k, False: 498]
  ------------------
 2055|  10.3k|    auto decoder = TiffDecoder(exifData, iptcData, xmpData, rootDir.get(), findDecoderFct);
 2056|  10.3k|    rootDir->accept(decoder);
 2057|  10.3k|  }
 2058|  10.8k|  return pHeader->byteOrder();
 2059|       |
 2060|  10.8k|}  // TiffParserWorker::decode
_ZN5Exiv28Internal16TiffParserWorker6encodeERNS_7BasicIoEPKhmRKNS_8ExifDataERKNS_8IptcDataERKNS_7XmpDataEjPFMNS0_11TiffEncoderEFvPNS0_13TiffEntryBaseEPKNS_9ExifdatumEENSt3__117basic_string_viewIcNSN_11char_traitsIcEEEEjNS_5IfdIdEEPNS0_14TiffHeaderBaseEPNS0_12OffsetWriterE:
 2065|  4.40k|                                     OffsetWriter* pOffsetWriter) {
 2066|       |  /*
 2067|       |     1) parse the binary image, if one is provided, and
 2068|       |     2) attempt updating the parsed tree in-place ("non-intrusive writing")
 2069|       |     3) else, create a new tree and write a new TIFF structure ("intrusive
 2070|       |        writing"). If there is a parsed tree, it is only used to access the
 2071|       |        image data in this case.
 2072|       |   */
 2073|  4.40k|  WriteMethod writeMethod = wmIntrusive;
 2074|  4.40k|  auto parsedTree = parse(pData, size, root, pHeader);
 2075|  4.40k|  auto primaryGroups = findPrimaryGroups(parsedTree);
 2076|  4.40k|  if (parsedTree) {
  ------------------
  |  Branch (2076:7): [True: 0, False: 4.40k]
  ------------------
 2077|       |    // Attempt to update existing TIFF components based on metadata entries
 2078|      0|    TiffEncoder encoder(exifData, iptcData, xmpData, parsedTree.get(), false, primaryGroups, pHeader, findEncoderFct);
 2079|      0|    parsedTree->accept(encoder);
 2080|      0|    if (!encoder.dirty())
  ------------------
  |  Branch (2080:9): [True: 0, False: 0]
  ------------------
 2081|      0|      writeMethod = wmNonIntrusive;
 2082|      0|  }
 2083|  4.40k|  if (writeMethod == wmIntrusive) {
  ------------------
  |  Branch (2083:7): [True: 4.40k, False: 0]
  ------------------
 2084|  4.40k|    auto createdTree = TiffCreator::create(root, IfdId::ifdIdNotSet);
 2085|  4.40k|    if (parsedTree) {
  ------------------
  |  Branch (2085:9): [True: 0, False: 4.40k]
  ------------------
 2086|       |      // Copy image tags from the original image to the composite
 2087|      0|      TiffCopier copier(createdTree.get(), root, pHeader, primaryGroups);
 2088|      0|      parsedTree->accept(copier);
 2089|      0|    }
 2090|       |    // Add entries from metadata to composite
 2091|  4.40k|    TiffEncoder encoder(exifData, iptcData, xmpData, createdTree.get(), !parsedTree, std::move(primaryGroups), pHeader,
 2092|  4.40k|                        findEncoderFct);
 2093|  4.40k|    encoder.add(createdTree.get(), std::move(parsedTree), root);
 2094|       |    // Write binary representation from the composite tree
 2095|  4.40k|    DataBuf header = pHeader->write();
 2096|  4.40k|    auto tempIo = MemIo();
 2097|  4.40k|    IoWrapper ioWrapper(tempIo, header.c_data(), header.size(), pOffsetWriter);
 2098|  4.40k|    auto imageIdx(std::string::npos);
 2099|  4.40k|    createdTree->write(ioWrapper, pHeader->byteOrder(), header.size(), std::string::npos, std::string::npos, imageIdx);
 2100|  4.40k|    if (pOffsetWriter)
  ------------------
  |  Branch (2100:9): [True: 0, False: 4.40k]
  ------------------
 2101|      0|      pOffsetWriter->writeOffsets(tempIo);
 2102|  4.40k|    io.transfer(tempIo);  // may throw
 2103|  4.40k|#ifndef SUPPRESS_WARNINGS
 2104|  4.40k|    EXV_INFO << "Write strategy: Intrusive\n";
  ------------------
  |  |  134|  4.40k|  if (LogMsg::info >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (134:7): [True: 0, False: 4.40k]
  |  |  |  Branch (134:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  135|  4.40k|  LogMsg(LogMsg::info).os()
  ------------------
 2105|  4.40k|#endif
 2106|  4.40k|  }
 2107|      0|#ifndef SUPPRESS_WARNINGS
 2108|      0|  else {
 2109|      0|    EXV_INFO << "Write strategy: Non-intrusive\n";
  ------------------
  |  |  134|      0|  if (LogMsg::info >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (134:7): [True: 0, False: 0]
  |  |  |  Branch (134:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  135|      0|  LogMsg(LogMsg::info).os()
  ------------------
 2110|      0|  }
 2111|  4.40k|#endif
 2112|  4.40k|  return writeMethod;
 2113|  4.40k|}  // TiffParserWorker::encode
_ZN5Exiv28Internal16TiffParserWorker5parseEPKhmjPNS0_14TiffHeaderBaseE:
 2116|  15.2k|                                                 TiffHeaderBase* pHeader) {
 2117|  15.2k|  TiffComponent::UniquePtr rootDir;
 2118|  15.2k|  if (!pData || size == 0)
  ------------------
  |  Branch (2118:7): [True: 4.63k, False: 10.5k]
  |  Branch (2118:17): [True: 0, False: 10.5k]
  ------------------
 2119|  4.63k|    return rootDir;
 2120|  10.5k|  if (!pHeader->read(pData, size) || pHeader->offset() >= size) {
  ------------------
  |  Branch (2120:7): [True: 146, False: 10.4k]
  |  Branch (2120:38): [True: 115, False: 10.3k]
  ------------------
 2121|    261|    throw Error(ErrorCode::kerNotAnImage, "TIFF");
 2122|    261|  }
 2123|  10.3k|  rootDir = TiffCreator::create(root, IfdId::ifdIdNotSet);
 2124|  10.3k|  if (rootDir) {
  ------------------
  |  Branch (2124:7): [True: 10.3k, False: 0]
  ------------------
 2125|  10.3k|    rootDir->setStart(pData + pHeader->offset());
 2126|  10.3k|    auto state = TiffRwState{pHeader->byteOrder(), 0};
 2127|  10.3k|    auto reader = TiffReader{pData, size, rootDir.get(), state};
 2128|  10.3k|    rootDir->accept(reader);
 2129|  10.3k|    reader.postProcess();
 2130|  10.3k|  }
 2131|  10.3k|  return rootDir;
 2132|       |
 2133|  10.5k|}  // TiffParserWorker::parse
_ZN5Exiv28Internal16TiffParserWorker17findPrimaryGroupsERKNSt3__110unique_ptrINS0_13TiffComponentENS2_14default_deleteIS4_EEEE:
 2135|  4.40k|PrimaryGroups TiffParserWorker::findPrimaryGroups(const TiffComponent::UniquePtr& pSourceDir) {
 2136|  4.40k|  PrimaryGroups ret;
 2137|  4.40k|  if (!pSourceDir)
  ------------------
  |  Branch (2137:7): [True: 4.40k, False: 0]
  ------------------
 2138|  4.40k|    return ret;
 2139|       |
 2140|      0|  static constexpr auto imageGroups = std::array{
 2141|      0|      IfdId::ifd0Id,      IfdId::ifd1Id,      IfdId::ifd2Id,      IfdId::ifd3Id,      IfdId::subImage1Id,
 2142|      0|      IfdId::subImage2Id, IfdId::subImage3Id, IfdId::subImage4Id, IfdId::subImage5Id, IfdId::subImage6Id,
 2143|      0|      IfdId::subImage7Id, IfdId::subImage8Id, IfdId::subImage9Id,
 2144|      0|  };
 2145|       |
 2146|      0|  for (auto imageGroup : imageGroups) {
  ------------------
  |  Branch (2146:24): [True: 0, False: 0]
  ------------------
 2147|      0|    TiffFinder finder(0x00fe, imageGroup);
 2148|      0|    pSourceDir->accept(finder);
 2149|      0|    auto te = dynamic_cast<const TiffEntryBase*>(finder.result());
 2150|      0|    if (!te)
  ------------------
  |  Branch (2150:9): [True: 0, False: 0]
  ------------------
 2151|      0|      continue;
 2152|      0|    const Value* pV = te->pValue();
 2153|      0|    if (pV && pV->typeId() == unsignedLong && pV->count() == 1 && (pV->toInt64() & 1) == 0) {
  ------------------
  |  Branch (2153:9): [True: 0, False: 0]
  |  Branch (2153:15): [True: 0, False: 0]
  |  Branch (2153:47): [True: 0, False: 0]
  |  Branch (2153:67): [True: 0, False: 0]
  ------------------
 2154|      0|      ret.push_back(te->group());
 2155|      0|    }
 2156|      0|  }
 2157|      0|  return ret;
 2158|  4.40k|}  // TiffParserWorker::findPrimaryGroups
_ZN5Exiv28Internal14TiffHeaderBaseC2EtjNS_9ByteOrderEj:
 2161|   271k|    tag_(tag), size_(size), byteOrder_(byteOrder), offset_(offset) {
 2162|   271k|}
_ZN5Exiv28Internal14TiffHeaderBase4readEPKhm:
 2164|   212k|bool TiffHeaderBase::read(const byte* pData, size_t size) {
 2165|   212k|  if (!pData || size < 8)
  ------------------
  |  Branch (2165:7): [True: 0, False: 212k]
  |  Branch (2165:17): [True: 61, False: 212k]
  ------------------
 2166|     61|    return false;
 2167|       |
 2168|   212k|  if (pData[0] == 'I' && pData[0] == pData[1]) {
  ------------------
  |  Branch (2168:7): [True: 15.1k, False: 197k]
  |  Branch (2168:26): [True: 14.8k, False: 215]
  ------------------
 2169|  14.8k|    byteOrder_ = littleEndian;
 2170|   197k|  } else if (pData[0] == 'M' && pData[0] == pData[1]) {
  ------------------
  |  Branch (2170:14): [True: 23.6k, False: 173k]
  |  Branch (2170:33): [True: 23.3k, False: 287]
  ------------------
 2171|  23.3k|    byteOrder_ = bigEndian;
 2172|   174k|  } else {
 2173|   174k|    return false;
 2174|   174k|  }
 2175|  38.2k|  uint16_t t = getUShort(pData + 2, byteOrder_);
 2176|  38.2k|  if (t != 444 && t != 17234 && tag_ != t)
  ------------------
  |  Branch (2176:7): [True: 38.2k, False: 17]
  |  Branch (2176:19): [True: 38.1k, False: 94]
  |  Branch (2176:33): [True: 1.87k, False: 36.2k]
  ------------------
 2177|  1.87k|    return false;  // 444 is for the JPEG-XR; 17234 is for DCP
 2178|  36.3k|  tag_ = t;
 2179|  36.3k|  offset_ = getULong(pData + 4, byteOrder_);
 2180|       |
 2181|  36.3k|  return true;
 2182|  38.2k|}
_ZNK5Exiv28Internal14TiffHeaderBase5writeEv:
 2184|  4.40k|DataBuf TiffHeaderBase::write() const {
 2185|  4.40k|  DataBuf buf(8);
 2186|  4.40k|  switch (byteOrder_) {
  ------------------
  |  Branch (2186:11): [True: 4.40k, False: 0]
  ------------------
 2187|  4.40k|    case littleEndian:
  ------------------
  |  Branch (2187:5): [True: 4.40k, False: 0]
  ------------------
 2188|  4.40k|      buf.write_uint8(0, 'I');
 2189|  4.40k|      break;
 2190|      0|    case bigEndian:
  ------------------
  |  Branch (2190:5): [True: 0, False: 4.40k]
  ------------------
 2191|      0|      buf.write_uint8(0, 'M');
 2192|      0|      break;
 2193|      0|    case invalidByteOrder:
  ------------------
  |  Branch (2193:5): [True: 0, False: 4.40k]
  ------------------
 2194|      0|      break;
 2195|  4.40k|  }
 2196|  4.40k|  buf.write_uint8(1, buf.read_uint8(0));
 2197|  4.40k|  buf.write_uint16(2, tag_, byteOrder_);
 2198|  4.40k|  buf.write_uint32(4, 0x00000008, byteOrder_);
 2199|  4.40k|  return buf;
 2200|  4.40k|}
_ZNK5Exiv28Internal14TiffHeaderBase9byteOrderEv:
 2218|  49.3k|ByteOrder TiffHeaderBase::byteOrder() const {
 2219|  49.3k|  return byteOrder_;
 2220|  49.3k|}
_ZN5Exiv28Internal14TiffHeaderBase12setByteOrderENS_9ByteOrderE:
 2222|  9.91k|void TiffHeaderBase::setByteOrder(ByteOrder byteOrder) {
 2223|  9.91k|  byteOrder_ = byteOrder;
 2224|  9.91k|}
_ZNK5Exiv28Internal14TiffHeaderBase6offsetEv:
 2226|  21.1k|uint32_t TiffHeaderBase::offset() const {
 2227|  21.1k|  return offset_;
 2228|  21.1k|}
_ZN5Exiv28Internal14TiffHeaderBase9setOffsetEj:
 2230|  9.00k|void TiffHeaderBase::setOffset(uint32_t offset) {
 2231|  9.00k|  offset_ = offset;
 2232|  9.00k|}
_ZNK5Exiv28Internal14TiffHeaderBase3tagEv:
 2238|  10.3k|uint16_t TiffHeaderBase::tag() const {
 2239|  10.3k|  return tag_;
 2240|  10.3k|}
_ZN5Exiv28Internal14isTiffImageTagEtNS_5IfdIdE:
 2324|   223k|bool isTiffImageTag(uint16_t tag, IfdId group) {
 2325|   223k|  const bool result = isTiffImageTagLookup(tag, group);
 2326|       |#ifdef EXIV2_DEBUG_MESSAGES
 2327|       |  if (result) {
 2328|       |    ExifKey key(tag, groupName(group));
 2329|       |    std::cerr << "Image tag: " << key << " (3)\n";
 2330|       |  } else {
 2331|       |    std::cerr << "Not an image tag: " << tag << " (4)\n";
 2332|       |  }
 2333|       |#endif
 2334|   223k|  return result;
 2335|   223k|}
_ZN5Exiv28Internal10TiffHeaderC2ENS_9ByteOrderEjb:
 2338|   194k|    TiffHeaderBase(42, 8, byteOrder, offset), hasImageTags_(hasImageTags) {
 2339|   194k|}
tiffimage_int.cpp:_ZN5Exiv28InternalL20isTiffImageTagLookupEtNS_5IfdIdE:
 2246|   223k|static bool isTiffImageTagLookup(uint16_t tag, IfdId group) {
 2247|   223k|  if (group != IfdId::ifd0Id) {
  ------------------
  |  Branch (2247:7): [True: 0, False: 223k]
  ------------------
 2248|      0|    return false;
 2249|      0|  }
 2250|       |  //! List of TIFF image tags
 2251|   223k|  switch (tag) {
 2252|      0|    case 0x00fe:  // Exif.Image.NewSubfileType
  ------------------
  |  Branch (2252:5): [True: 0, False: 223k]
  ------------------
 2253|      0|    case 0x00ff:  // Exif.Image.SubfileType
  ------------------
  |  Branch (2253:5): [True: 0, False: 223k]
  ------------------
 2254|  9.33k|    case 0x0100:  // Exif.Image.ImageWidth
  ------------------
  |  Branch (2254:5): [True: 9.33k, False: 214k]
  ------------------
 2255|  88.5k|    case 0x0101:  // Exif.Image.ImageLength
  ------------------
  |  Branch (2255:5): [True: 79.2k, False: 144k]
  ------------------
 2256|  96.0k|    case 0x0102:  // Exif.Image.BitsPerSample
  ------------------
  |  Branch (2256:5): [True: 7.43k, False: 216k]
  ------------------
 2257|  96.2k|    case 0x0103:  // Exif.Image.Compression
  ------------------
  |  Branch (2257:5): [True: 257, False: 223k]
  ------------------
 2258|  96.5k|    case 0x0106:  // Exif.Image.PhotometricInterpretation
  ------------------
  |  Branch (2258:5): [True: 289, False: 223k]
  ------------------
 2259|  96.7k|    case 0x010a:  // Exif.Image.FillOrder
  ------------------
  |  Branch (2259:5): [True: 221, False: 223k]
  ------------------
 2260|   104k|    case 0x0111:  // Exif.Image.StripOffsets
  ------------------
  |  Branch (2260:5): [True: 7.66k, False: 215k]
  ------------------
 2261|   104k|    case 0x0115:  // Exif.Image.SamplesPerPixel
  ------------------
  |  Branch (2261:5): [True: 130, False: 223k]
  ------------------
 2262|   104k|    case 0x0116:  // Exif.Image.RowsPerStrip
  ------------------
  |  Branch (2262:5): [True: 133, False: 223k]
  ------------------
 2263|   110k|    case 0x0117:  // Exif.Image.StripByteCounts
  ------------------
  |  Branch (2263:5): [True: 6.14k, False: 217k]
  ------------------
 2264|   111k|    case 0x011a:  // Exif.Image.XResolution
  ------------------
  |  Branch (2264:5): [True: 759, False: 222k]
  ------------------
 2265|   111k|    case 0x011b:  // Exif.Image.YResolution
  ------------------
  |  Branch (2265:5): [True: 135, False: 223k]
  ------------------
 2266|   112k|    case 0x011c:  // Exif.Image.PlanarConfiguration
  ------------------
  |  Branch (2266:5): [True: 270, False: 223k]
  ------------------
 2267|   112k|    case 0x0122:  // Exif.Image.GrayResponseUnit
  ------------------
  |  Branch (2267:5): [True: 173, False: 223k]
  ------------------
 2268|   112k|    case 0x0123:  // Exif.Image.GrayResponseCurve
  ------------------
  |  Branch (2268:5): [True: 130, False: 223k]
  ------------------
 2269|   112k|    case 0x0124:  // Exif.Image.T4Options
  ------------------
  |  Branch (2269:5): [True: 78, False: 223k]
  ------------------
 2270|   112k|    case 0x0125:  // Exif.Image.T6Options
  ------------------
  |  Branch (2270:5): [True: 94, False: 223k]
  ------------------
 2271|   112k|    case 0x0128:  // Exif.Image.ResolutionUnit
  ------------------
  |  Branch (2271:5): [True: 158, False: 223k]
  ------------------
 2272|   112k|    case 0x0129:  // Exif.Image.PageNumber
  ------------------
  |  Branch (2272:5): [True: 86, False: 223k]
  ------------------
 2273|   112k|    case 0x012d:  // Exif.Image.TransferFunction
  ------------------
  |  Branch (2273:5): [True: 67, False: 223k]
  ------------------
 2274|   112k|    case 0x013d:  // Exif.Image.Predictor
  ------------------
  |  Branch (2274:5): [True: 103, False: 223k]
  ------------------
 2275|   112k|    case 0x013e:  // Exif.Image.WhitePoint
  ------------------
  |  Branch (2275:5): [True: 78, False: 223k]
  ------------------
 2276|   113k|    case 0x013f:  // Exif.Image.PrimaryChromaticities
  ------------------
  |  Branch (2276:5): [True: 66, False: 223k]
  ------------------
 2277|   113k|    case 0x0140:  // Exif.Image.ColorMap
  ------------------
  |  Branch (2277:5): [True: 104, False: 223k]
  ------------------
 2278|   113k|    case 0x0141:  // Exif.Image.HalftoneHints
  ------------------
  |  Branch (2278:5): [True: 165, False: 223k]
  ------------------
 2279|   113k|    case 0x0142:  // Exif.Image.TileWidth
  ------------------
  |  Branch (2279:5): [True: 78, False: 223k]
  ------------------
 2280|   113k|    case 0x0143:  // Exif.Image.TileLength
  ------------------
  |  Branch (2280:5): [True: 68, False: 223k]
  ------------------
 2281|   114k|    case 0x0144:  // Exif.Image.TileOffsets
  ------------------
  |  Branch (2281:5): [True: 1.34k, False: 222k]
  ------------------
 2282|   115k|    case 0x0145:  // Exif.Image.TileByteCounts
  ------------------
  |  Branch (2282:5): [True: 814, False: 222k]
  ------------------
 2283|   115k|    case 0x014c:  // Exif.Image.InkSet
  ------------------
  |  Branch (2283:5): [True: 111, False: 223k]
  ------------------
 2284|   116k|    case 0x014d:  // Exif.Image.InkNames
  ------------------
  |  Branch (2284:5): [True: 383, False: 223k]
  ------------------
 2285|   116k|    case 0x014e:  // Exif.Image.NumberOfInks
  ------------------
  |  Branch (2285:5): [True: 132, False: 223k]
  ------------------
 2286|   116k|    case 0x0150:  // Exif.Image.DotRange
  ------------------
  |  Branch (2286:5): [True: 70, False: 223k]
  ------------------
 2287|   116k|    case 0x0151:  // Exif.Image.TargetPrinter
  ------------------
  |  Branch (2287:5): [True: 685, False: 222k]
  ------------------
 2288|   117k|    case 0x0152:  // Exif.Image.ExtraSamples
  ------------------
  |  Branch (2288:5): [True: 133, False: 223k]
  ------------------
 2289|   117k|    case 0x0153:  // Exif.Image.SampleFormat
  ------------------
  |  Branch (2289:5): [True: 110, False: 223k]
  ------------------
 2290|   117k|    case 0x0154:  // Exif.Image.SMinSampleValue
  ------------------
  |  Branch (2290:5): [True: 231, False: 223k]
  ------------------
 2291|   117k|    case 0x0155:  // Exif.Image.SMaxSampleValue
  ------------------
  |  Branch (2291:5): [True: 246, False: 223k]
  ------------------
 2292|   117k|    case 0x0156:  // Exif.Image.TransferRange
  ------------------
  |  Branch (2292:5): [True: 112, False: 223k]
  ------------------
 2293|   117k|    case 0x0157:  // Exif.Image.ClipPath
  ------------------
  |  Branch (2293:5): [True: 76, False: 223k]
  ------------------
 2294|   118k|    case 0x0158:  // Exif.Image.XClipPathUnits
  ------------------
  |  Branch (2294:5): [True: 115, False: 223k]
  ------------------
 2295|   118k|    case 0x0159:  // Exif.Image.YClipPathUnits
  ------------------
  |  Branch (2295:5): [True: 98, False: 223k]
  ------------------
 2296|   118k|    case 0x015a:  // Exif.Image.Indexed
  ------------------
  |  Branch (2296:5): [True: 65, False: 223k]
  ------------------
 2297|   118k|    case 0x015b:  // Exif.Image.JPEGTables
  ------------------
  |  Branch (2297:5): [True: 421, False: 223k]
  ------------------
 2298|   120k|    case 0x0200:  // Exif.Image.JPEGProc
  ------------------
  |  Branch (2298:5): [True: 2.32k, False: 221k]
  ------------------
 2299|   128k|    case 0x0201:  // Exif.Image.JPEGInterchangeFormat
  ------------------
  |  Branch (2299:5): [True: 7.46k, False: 216k]
  ------------------
 2300|   141k|    case 0x0202:  // Exif.Image.JPEGInterchangeFormatLength
  ------------------
  |  Branch (2300:5): [True: 13.4k, False: 210k]
  ------------------
 2301|   142k|    case 0x0203:  // Exif.Image.JPEGRestartInterval
  ------------------
  |  Branch (2301:5): [True: 200, False: 223k]
  ------------------
 2302|   142k|    case 0x0205:  // Exif.Image.JPEGLosslessPredictors
  ------------------
  |  Branch (2302:5): [True: 80, False: 223k]
  ------------------
 2303|   142k|    case 0x0206:  // Exif.Image.JPEGPointTransforms
  ------------------
  |  Branch (2303:5): [True: 315, False: 223k]
  ------------------
 2304|   142k|    case 0x0207:  // Exif.Image.JPEGQTables
  ------------------
  |  Branch (2304:5): [True: 150, False: 223k]
  ------------------
 2305|   142k|    case 0x0208:  // Exif.Image.JPEGDCTables
  ------------------
  |  Branch (2305:5): [True: 74, False: 223k]
  ------------------
 2306|   142k|    case 0x0209:  // Exif.Image.JPEGACTables
  ------------------
  |  Branch (2306:5): [True: 122, False: 223k]
  ------------------
 2307|   142k|    case 0x0211:  // Exif.Image.YCbCrCoefficients
  ------------------
  |  Branch (2307:5): [True: 67, False: 223k]
  ------------------
 2308|   142k|    case 0x0212:  // Exif.Image.YCbCrSubSampling
  ------------------
  |  Branch (2308:5): [True: 76, False: 223k]
  ------------------
 2309|   142k|    case 0x0213:  // Exif.Image.YCbCrPositioning
  ------------------
  |  Branch (2309:5): [True: 97, False: 223k]
  ------------------
 2310|   143k|    case 0x0214:  // Exif.Image.ReferenceBlackWhite
  ------------------
  |  Branch (2310:5): [True: 55, False: 223k]
  ------------------
 2311|   143k|    case 0x828d:  // Exif.Image.CFARepeatPatternDim
  ------------------
  |  Branch (2311:5): [True: 66, False: 223k]
  ------------------
 2312|   143k|    case 0x828e:  // Exif.Image.CFAPattern
  ------------------
  |  Branch (2312:5): [True: 36, False: 223k]
  ------------------
 2313|       |    // case 0x8773:  // Exif.Image.InterColorProfile
 2314|   143k|    case 0x8824:  // Exif.Image.SpectralSensitivity
  ------------------
  |  Branch (2314:5): [True: 34, False: 223k]
  ------------------
 2315|   143k|    case 0x8828:  // Exif.Image.OECF
  ------------------
  |  Branch (2315:5): [True: 72, False: 223k]
  ------------------
 2316|   143k|    case 0x9102:  // Exif.Image.CompressedBitsPerPixel
  ------------------
  |  Branch (2316:5): [True: 40, False: 223k]
  ------------------
 2317|   143k|    case 0x9217:  // Exif.Image.SensingMethod
  ------------------
  |  Branch (2317:5): [True: 34, False: 223k]
  ------------------
 2318|   143k|      return true;
 2319|  80.2k|    default:
  ------------------
  |  Branch (2319:5): [True: 80.2k, False: 143k]
  ------------------
 2320|  80.2k|      return false;
 2321|   223k|  }
 2322|   223k|}

_ZN5Exiv28Internal13FindExifdatumC2ENS_5IfdIdE:
  358|  4.40k|  explicit FindExifdatum(Exiv2::IfdId ifdId) : ifdId_(ifdId) {
  359|  4.40k|  }
_ZNK5Exiv28Internal17TiffGroupKey_hashclENSt3__14pairIjNS_5IfdIdEEE:
  151|  3.27M|  std::size_t operator()(TiffGroupKey pair) const noexcept {
  152|  3.27M|    return std::hash<uint64_t>{}(static_cast<uint64_t>(pair.first) << 32 | static_cast<uint64_t>(pair.second));
  153|  3.27M|  }
_ZN5Exiv28Internal14TiffHeaderBaseD2Ev:
   49|  10.5k|  virtual ~TiffHeaderBase() = default;

_ZN5Exiv28Internal11TiffVisitor5setGoENS1_7GoEventEb:
   61|   114k|void TiffVisitor::setGo(GoEvent event, bool go) {
   62|   114k|  go_[event] = go;
   63|   114k|}
_ZNK5Exiv28Internal11TiffVisitor2goENS1_7GoEventE:
   65|  45.3M|bool TiffVisitor::go(GoEvent event) const {
   66|  45.3M|  return go_[event];
   67|  45.3M|}
_ZN5Exiv28Internal11TiffVisitor18visitDirectoryNextEPNS0_13TiffDirectoryE:
   69|   445k|void TiffVisitor::visitDirectoryNext(TiffDirectory* /*object*/) {
   70|   445k|}
_ZN5Exiv28Internal11TiffVisitor17visitDirectoryEndEPNS0_13TiffDirectoryE:
   72|   432k|void TiffVisitor::visitDirectoryEnd(TiffDirectory* /*object*/) {
   73|   432k|}
_ZN5Exiv28Internal11TiffVisitor20visitIfdMakernoteEndEPNS0_16TiffIfdMakernoteE:
   75|  3.76k|void TiffVisitor::visitIfdMakernoteEnd(TiffIfdMakernote* /*object*/) {
   76|  3.76k|}
_ZN5Exiv28Internal11TiffVisitor19visitBinaryArrayEndEPNS0_15TiffBinaryArrayE:
   78|  26.3k|void TiffVisitor::visitBinaryArrayEnd(TiffBinaryArray* /*object*/) {
   79|  26.3k|}
_ZN5Exiv28Internal10TiffFinder4initEtNS_5IfdIdE:
   81|     15|void TiffFinder::init(uint16_t tag, IfdId group) {
   82|     15|  tag_ = tag;
   83|     15|  group_ = group;
   84|     15|  tiffComponent_ = nullptr;
   85|     15|  setGo(geTraverse, true);
   86|     15|}
_ZN5Exiv28Internal10TiffFinder10findObjectEPNS0_13TiffComponentE:
   88|  19.1M|void TiffFinder::findObject(TiffComponent* object) {
   89|  19.1M|  if (object->tag() == tag_ && object->group() == group_) {
  ------------------
  |  Branch (89:7): [True: 379k, False: 18.7M]
  |  Branch (89:32): [True: 81.5k, False: 298k]
  ------------------
   90|  81.5k|    tiffComponent_ = object;
   91|  81.5k|    setGo(geTraverse, false);
   92|  81.5k|  }
   93|  19.1M|}
_ZN5Exiv28Internal10TiffFinder10visitEntryEPNS0_9TiffEntryE:
   95|  11.9M|void TiffFinder::visitEntry(TiffEntry* object) {
   96|  11.9M|  findObject(object);
   97|  11.9M|}
_ZN5Exiv28Internal10TiffFinder14visitDataEntryEPNS0_13TiffDataEntryE:
   99|  73.9k|void TiffFinder::visitDataEntry(TiffDataEntry* object) {
  100|  73.9k|  findObject(object);
  101|  73.9k|}
_ZN5Exiv28Internal10TiffFinder15visitImageEntryEPNS0_14TiffImageEntryE:
  103|  2.16M|void TiffFinder::visitImageEntry(TiffImageEntry* object) {
  104|  2.16M|  findObject(object);
  105|  2.16M|}
_ZN5Exiv28Internal10TiffFinder14visitSizeEntryEPNS0_13TiffSizeEntryE:
  107|  2.65M|void TiffFinder::visitSizeEntry(TiffSizeEntry* object) {
  108|  2.65M|  findObject(object);
  109|  2.65M|}
_ZN5Exiv28Internal10TiffFinder14visitDirectoryEPNS0_13TiffDirectoryE:
  111|   497k|void TiffFinder::visitDirectory(TiffDirectory* object) {
  112|   497k|  findObject(object);
  113|   497k|}
_ZN5Exiv28Internal10TiffFinder11visitSubIfdEPNS0_10TiffSubIfdE:
  115|   113k|void TiffFinder::visitSubIfd(TiffSubIfd* object) {
  116|   113k|  findObject(object);
  117|   113k|}
_ZN5Exiv28Internal10TiffFinder12visitMnEntryEPNS0_11TiffMnEntryE:
  119|  36.2k|void TiffFinder::visitMnEntry(TiffMnEntry* object) {
  120|  36.2k|  findObject(object);
  121|  36.2k|}
_ZN5Exiv28Internal10TiffFinder17visitIfdMakernoteEPNS0_16TiffIfdMakernoteE:
  123|  4.18k|void TiffFinder::visitIfdMakernote(TiffIfdMakernote* object) {
  124|  4.18k|  findObject(object);
  125|  4.18k|}
_ZN5Exiv28Internal10TiffFinder16visitBinaryArrayEPNS0_15TiffBinaryArrayE:
  127|  16.4k|void TiffFinder::visitBinaryArray(TiffBinaryArray* object) {
  128|  16.4k|  findObject(object);
  129|  16.4k|}
_ZN5Exiv28Internal10TiffFinder18visitBinaryElementEPNS0_17TiffBinaryElementE:
  131|  1.64M|void TiffFinder::visitBinaryElement(TiffBinaryElement* object) {
  132|  1.64M|  findObject(object);
  133|  1.64M|}
_ZN5Exiv28Internal11TiffDecoderC2ERNS_8ExifDataERNS_8IptcDataERNS_7XmpDataEPNS0_13TiffComponentEPFMS1_FvPKNS0_13TiffEntryBaseEENSt3__117basic_string_viewIcNSF_11char_traitsIcEEEEjNS_5IfdIdEE:
  195|  10.3k|    exifData_(exifData), iptcData_(iptcData), xmpData_(xmpData), pRoot_(pRoot), findDecoderFct_(findDecoderFct) {
  196|       |  // #1402 Fujifilm RAF. Search for the make
  197|       |  // Find camera make in existing metadata (read from the JPEG)
  198|  10.3k|  ExifKey key("Exif.Image.Make");
  199|  10.3k|  if (exifData_.findKey(key) != exifData_.end()) {
  ------------------
  |  Branch (199:7): [True: 72, False: 10.2k]
  ------------------
  200|     72|    make_ = exifData_.findKey(key)->toString();
  201|  10.2k|  } else {
  202|       |    // Find camera make by looking for tag 0x010f in IFD0
  203|  10.2k|    TiffFinder finder(0x010f, IfdId::ifd0Id);
  204|  10.2k|    pRoot_->accept(finder);
  205|  10.2k|    auto te = dynamic_cast<const TiffEntryBase*>(finder.result());
  206|  10.2k|    if (te && te->pValue()) {
  ------------------
  |  Branch (206:9): [True: 1.80k, False: 8.45k]
  |  Branch (206:15): [True: 1.76k, False: 36]
  ------------------
  207|  1.76k|      make_ = te->pValue()->toString();
  208|  1.76k|    }
  209|  10.2k|  }
  210|  10.3k|}
_ZN5Exiv28Internal11TiffDecoder10visitEntryEPNS0_9TiffEntryE:
  212|   724k|void TiffDecoder::visitEntry(TiffEntry* object) {
  213|   724k|  decodeTiffEntry(object);
  214|   724k|}
_ZN5Exiv28Internal11TiffDecoder14visitDataEntryEPNS0_13TiffDataEntryE:
  216|  4.81k|void TiffDecoder::visitDataEntry(TiffDataEntry* object) {
  217|  4.81k|  decodeTiffEntry(object);
  218|  4.81k|}
_ZN5Exiv28Internal11TiffDecoder15visitImageEntryEPNS0_14TiffImageEntryE:
  220|  37.3k|void TiffDecoder::visitImageEntry(TiffImageEntry* object) {
  221|  37.3k|  decodeTiffEntry(object);
  222|  37.3k|}
_ZN5Exiv28Internal11TiffDecoder14visitSizeEntryEPNS0_13TiffSizeEntryE:
  224|  52.9k|void TiffDecoder::visitSizeEntry(TiffSizeEntry* object) {
  225|  52.9k|  decodeTiffEntry(object);
  226|  52.9k|}
_ZN5Exiv28Internal11TiffDecoder14visitDirectoryEPNS0_13TiffDirectoryE:
  228|  35.2k|void TiffDecoder::visitDirectory(TiffDirectory* /* object */) {
  229|       |  // Nothing to do
  230|  35.2k|}
_ZN5Exiv28Internal11TiffDecoder11visitSubIfdEPNS0_10TiffSubIfdE:
  232|  8.47k|void TiffDecoder::visitSubIfd(TiffSubIfd* object) {
  233|  8.47k|  decodeTiffEntry(object);
  234|  8.47k|}
_ZN5Exiv28Internal11TiffDecoder12visitMnEntryEPNS0_11TiffMnEntryE:
  236|  11.8k|void TiffDecoder::visitMnEntry(TiffMnEntry* object) {
  237|       |  // Always decode binary makernote tag
  238|  11.8k|  decodeTiffEntry(object);
  239|  11.8k|}
_ZN5Exiv28Internal11TiffDecoder17visitIfdMakernoteEPNS0_16TiffIfdMakernoteE:
  241|  2.32k|void TiffDecoder::visitIfdMakernote(TiffIfdMakernote* object) {
  242|  2.32k|  exifData_["Exif.MakerNote.Offset"] = static_cast<uint32_t>(object->mnOffset());
  243|  2.32k|  switch (object->byteOrder()) {
  ------------------
  |  Branch (243:11): [True: 2.32k, False: 0]
  ------------------
  244|  2.21k|    case littleEndian:
  ------------------
  |  Branch (244:5): [True: 2.21k, False: 115]
  ------------------
  245|  2.21k|      exifData_["Exif.MakerNote.ByteOrder"] = "II";
  246|  2.21k|      break;
  247|    115|    case bigEndian:
  ------------------
  |  Branch (247:5): [True: 115, False: 2.21k]
  ------------------
  248|    115|      exifData_["Exif.MakerNote.ByteOrder"] = "MM";
  249|    115|      break;
  250|      0|    case invalidByteOrder:
  ------------------
  |  Branch (250:5): [True: 0, False: 2.32k]
  ------------------
  251|      0|      break;
  252|  2.32k|  }
  253|  2.32k|}
_ZN5Exiv28Internal11TiffDecoder10getObjDataERPKhRmtNS_5IfdIdEPKNS0_13TiffEntryBaseE:
  255|  6.65k|void TiffDecoder::getObjData(const byte*& pData, size_t& size, uint16_t tag, IfdId group, const TiffEntryBase* object) {
  256|  6.65k|  if (object && object->tag() == tag && object->group() == group) {
  ------------------
  |  Branch (256:7): [True: 6.65k, False: 0]
  |  Branch (256:17): [True: 6.56k, False: 90]
  |  Branch (256:41): [True: 6.56k, False: 0]
  ------------------
  257|  6.56k|    pData = object->pData();
  258|  6.56k|    size = object->size();
  259|  6.56k|    return;
  260|  6.56k|  }
  261|     90|  TiffFinder finder(tag, group);
  262|     90|  pRoot_->accept(finder);
  263|     90|  if (auto te = dynamic_cast<const TiffEntryBase*>(finder.result())) {
  ------------------
  |  Branch (263:12): [True: 12, False: 78]
  ------------------
  264|     12|    pData = te->pData();
  265|     12|    size = te->size();
  266|     12|    return;
  267|     12|  }
  268|     90|}
_ZN5Exiv28Internal11TiffDecoder9decodeXmpEPKNS0_13TiffEntryBaseE:
  270|  6.41k|void TiffDecoder::decodeXmp(const TiffEntryBase* object) {
  271|       |  // add Exif tag anyway
  272|  6.41k|  decodeStdTiffEntry(object);
  273|       |
  274|  6.41k|  const byte* pData = nullptr;
  275|  6.41k|  size_t size = 0;
  276|  6.41k|  getObjData(pData, size, 0x02bc, IfdId::ifd0Id, object);
  277|  6.41k|  if (pData) {
  ------------------
  |  Branch (277:7): [True: 6.41k, False: 0]
  ------------------
  278|  6.41k|    std::string xmpPacket;
  279|  6.41k|    xmpPacket.assign(reinterpret_cast<const char*>(pData), size);
  280|  6.41k|    std::string::size_type idx = xmpPacket.find_first_of('<');
  281|  6.41k|    if (idx != std::string::npos && idx > 0) {
  ------------------
  |  Branch (281:9): [True: 5.52k, False: 887]
  |  Branch (281:37): [True: 5.47k, False: 44]
  ------------------
  282|  5.47k|#ifndef SUPPRESS_WARNINGS
  283|  5.47k|      EXV_WARNING << "Removing " << idx << " characters from the beginning of the XMP packet\n";
  ------------------
  |  |  138|  5.47k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 5.47k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  5.47k|  LogMsg(LogMsg::warn).os()
  ------------------
  284|  5.47k|#endif
  285|  5.47k|      xmpPacket = xmpPacket.substr(idx);
  286|  5.47k|    }
  287|  6.41k|    if (XmpParser::decode(xmpData_, xmpPacket)) {
  ------------------
  |  Branch (287:9): [True: 1.90k, False: 4.50k]
  ------------------
  288|  1.90k|#ifndef SUPPRESS_WARNINGS
  289|  1.90k|      EXV_WARNING << "Failed to decode XMP metadata.\n";
  ------------------
  |  |  138|  1.90k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 1.90k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  1.90k|  LogMsg(LogMsg::warn).os()
  ------------------
  290|  1.90k|#endif
  291|  1.90k|    }
  292|  6.41k|  }
  293|  6.41k|}  // TiffDecoder::decodeXmp
_ZN5Exiv28Internal11TiffDecoder10decodeIptcEPKNS0_13TiffEntryBaseE:
  295|    297|void TiffDecoder::decodeIptc(const TiffEntryBase* object) {
  296|       |  // add Exif tag anyway
  297|    297|  decodeStdTiffEntry(object);
  298|       |
  299|       |  // All tags are read at this point, so the first time we come here,
  300|       |  // find the relevant IPTC tag and decode IPTC if found
  301|    297|  if (decodedIptc_) {
  ------------------
  |  Branch (301:7): [True: 144, False: 153]
  ------------------
  302|    144|    return;
  303|    144|  }
  304|    153|  decodedIptc_ = true;
  305|       |  // 1st choice: IPTCNAA
  306|    153|  const byte* pData = nullptr;
  307|    153|  size_t size = 0;
  308|    153|  getObjData(pData, size, 0x83bb, IfdId::ifd0Id, object);
  309|    153|  if (pData) {
  ------------------
  |  Branch (309:7): [True: 100, False: 53]
  ------------------
  310|    100|    if (0 == IptcParser::decode(iptcData_, pData, size)) {
  ------------------
  |  Branch (310:9): [True: 39, False: 61]
  ------------------
  311|     39|      return;
  312|     39|    }
  313|     61|#ifndef SUPPRESS_WARNINGS
  314|     61|    EXV_WARNING << "Failed to decode IPTC block found in " << "Directory Image, entry 0x83bb\n";
  ------------------
  |  |  138|     61|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 61]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     61|  LogMsg(LogMsg::warn).os()
  ------------------
  315|       |
  316|     61|#endif
  317|     61|  }
  318|       |
  319|       |  // 2nd choice if no IPTCNAA record found or failed to decode it:
  320|       |  // ImageResources
  321|    114|  pData = nullptr;
  322|    114|  size = 0;
  323|    114|  getObjData(pData, size, 0x8649, IfdId::ifd0Id, object);
  324|    114|  if (pData) {
  ------------------
  |  Branch (324:7): [True: 58, False: 56]
  ------------------
  325|     58|    const byte* record = nullptr;
  326|     58|    uint32_t sizeHdr = 0;
  327|     58|    uint32_t sizeData = 0;
  328|     58|    if (0 != Photoshop::locateIptcIrb(pData, size, &record, sizeHdr, sizeData)) {
  ------------------
  |  Branch (328:9): [True: 58, False: 0]
  ------------------
  329|     58|      return;
  330|     58|    }
  331|      0|    if (0 == IptcParser::decode(iptcData_, record + sizeHdr, sizeData)) {
  ------------------
  |  Branch (331:9): [True: 0, False: 0]
  ------------------
  332|      0|      return;
  333|      0|    }
  334|      0|#ifndef SUPPRESS_WARNINGS
  335|      0|    EXV_WARNING << "Failed to decode IPTC block found in " << "Directory Image, entry 0x8649\n";
  ------------------
  |  |  138|      0|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 0]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|      0|  LogMsg(LogMsg::warn).os()
  ------------------
  336|       |
  337|      0|#endif
  338|      0|  }
  339|    114|}  // TiffMetadataDecoder::decodeIptc
_ZN5Exiv28Internal11TiffDecoder17decodeCanonAFInfoEPKNS0_13TiffEntryBaseE:
  347|  1.53k|void TiffDecoder::decodeCanonAFInfo(const TiffEntryBase* object) {
  348|       |  // report Exif.Canon.AFInfo as usual
  349|  1.53k|  TiffDecoder::decodeStdTiffEntry(object);
  350|  1.53k|  if (object->pValue()->count() < 3 || object->pValue()->typeId() != unsignedShort)
  ------------------
  |  Branch (350:7): [True: 269, False: 1.26k]
  |  Branch (350:40): [True: 104, False: 1.16k]
  ------------------
  351|    373|    return;  // insufficient data
  352|       |
  353|       |  // create vector of signedShorts from unsignedShorts in Exif.Canon.AFInfo
  354|  1.16k|  std::vector<int16_t> ints;
  355|  1.16k|  std::vector<uint16_t> uint;
  356|   128k|  for (size_t i = 0; i < object->pValue()->count(); i++) {
  ------------------
  |  Branch (356:22): [True: 127k, False: 1.16k]
  ------------------
  357|   127k|    ints.push_back(object->pValue()->toInt64(i));
  358|   127k|    uint.push_back(object->pValue()->toUint32(i));
  359|   127k|  }
  360|       |  // Check this is AFInfo2 (ints[0] = bytes in object)
  361|  1.16k|  if (ints.front() != static_cast<int16_t>(object->pValue()->count()) * 2)
  ------------------
  |  Branch (361:7): [True: 107, False: 1.05k]
  ------------------
  362|    107|    return;
  363|       |
  364|  1.05k|  std::string familyGroup(std::string("Exif.") + groupName(object->group()) + ".");
  365|       |
  366|  1.05k|  const uint16_t nPoints = uint.at(2);
  367|  1.05k|  const uint16_t nMasks = (nPoints + 15) / (sizeof(uint16_t) * 8);
  368|  1.05k|  int nStart = 0;
  369|       |
  370|  1.05k|  const std::tuple<uint16_t, uint16_t, bool> records[] = {
  371|  1.05k|      {0x2600, 1, true},        // AFInfoSize
  372|  1.05k|      {0x2601, 1, true},        // AFAreaMode
  373|  1.05k|      {0x2602, 1, true},        // AFNumPoints
  374|  1.05k|      {0x2603, 1, true},        // AFValidPoints
  375|  1.05k|      {0x2604, 1, true},        // AFCanonImageWidth
  376|  1.05k|      {0x2605, 1, true},        // AFCanonImageHeight
  377|  1.05k|      {0x2606, 1, true},        // AFImageWidth"
  378|  1.05k|      {0x2607, 1, true},        // AFImageHeight
  379|  1.05k|      {0x2608, nPoints, true},  // AFAreaWidths
  380|  1.05k|      {0x2609, nPoints, true},  // AFAreaHeights
  381|  1.05k|      {0x260a, nPoints, true},  // AFXPositions
  382|  1.05k|      {0x260b, nPoints, true},  // AFYPositions
  383|  1.05k|      {0x260c, nMasks, false},  // AFPointsInFocus
  384|  1.05k|      {0x260d, nMasks, false},  // AFPointsSelected
  385|  1.05k|      {0x260e, nMasks, false},  // AFPointsUnusable
  386|  1.05k|  };
  387|       |  // check we have enough data!
  388|  1.05k|  uint16_t count = 0;
  389|  13.6k|  for (const auto& [tag, size, bSigned] : records) {
  ------------------
  |  Branch (389:41): [True: 13.6k, False: 561]
  ------------------
  390|  13.6k|    count += size;
  391|  13.6k|    if (count > ints.size())
  ------------------
  |  Branch (391:9): [True: 495, False: 13.1k]
  ------------------
  392|    495|      return;
  393|  13.6k|  }
  394|       |
  395|  8.41k|  for (const auto& [tag, size, bSigned] : records) {
  ------------------
  |  Branch (395:41): [True: 8.41k, False: 561]
  ------------------
  396|  8.41k|    auto pTags = ExifTags::tagList("Canon");
  397|  8.41k|    if (auto pTag = findTag(pTags, tag)) {
  ------------------
  |  Branch (397:14): [True: 8.41k, False: 0]
  ------------------
  398|  8.41k|      auto v = Exiv2::Value::create(bSigned ? Exiv2::signedShort : Exiv2::unsignedShort);
  ------------------
  |  Branch (398:37): [True: 6.73k, False: 1.68k]
  ------------------
  399|  8.41k|      std::string s;
  400|  8.41k|      if (bSigned) {
  ------------------
  |  Branch (400:11): [True: 6.73k, False: 1.68k]
  ------------------
  401|  23.7k|        for (uint16_t k = 0; k < size; k++)
  ------------------
  |  Branch (401:30): [True: 16.9k, False: 6.73k]
  ------------------
  402|  16.9k|          s += stringFormat(" {}", ints.at(nStart++));
  ------------------
  |  |   18|  16.9k|#define stringFormat std::format
  ------------------
  403|  6.73k|      } else {
  404|  2.46k|        for (uint16_t k = 0; k < size; k++)
  ------------------
  |  Branch (404:30): [True: 780, False: 1.68k]
  ------------------
  405|    780|          s += stringFormat(" {}", uint.at(nStart++));
  ------------------
  |  |   18|    780|#define stringFormat std::format
  ------------------
  406|  1.68k|      }
  407|       |
  408|  8.41k|      v->read(s);
  409|  8.41k|      exifData_[familyGroup + pTag->name_] = *v;
  410|  8.41k|    }
  411|  8.41k|  }
  412|    561|}
_ZN5Exiv28Internal11TiffDecoder15decodeTiffEntryEPKNS0_13TiffEntryBaseE:
  414|  1.41M|void TiffDecoder::decodeTiffEntry(const TiffEntryBase* object) {
  415|       |  // Don't decode the entry if value is not set
  416|  1.41M|  if (!object->pValue())
  ------------------
  |  Branch (416:7): [True: 358k, False: 1.05M]
  ------------------
  417|   358k|    return;
  418|       |
  419|       |  // skip decoding if decoderFct == 0
  420|  1.05M|  if (auto decoderFct = findDecoderFct_(make_, object->tag(), object->group()))
  ------------------
  |  Branch (420:12): [True: 1.05M, False: 0]
  ------------------
  421|  1.05M|    std::invoke(decoderFct, *this, object);
  422|  1.05M|}  // TiffDecoder::decodeTiffEntry
_ZN5Exiv28Internal11TiffDecoder18decodeStdTiffEntryEPKNS0_13TiffEntryBaseE:
  424|  1.05M|void TiffDecoder::decodeStdTiffEntry(const TiffEntryBase* object) {
  425|  1.05M|  ExifKey key(object->tag(), groupName(object->group()));
  426|  1.05M|  key.setIdx(object->idx());
  427|  1.05M|  exifData_.add(key, object->pValue());
  428|       |
  429|  1.05M|}  // TiffDecoder::decodeTiffEntry
_ZN5Exiv28Internal11TiffDecoder16visitBinaryArrayEPNS0_15TiffBinaryArrayE:
  431|  5.02k|void TiffDecoder::visitBinaryArray(TiffBinaryArray* object) {
  432|  5.02k|  if (!object->cfg() || !object->decoded()) {
  ------------------
  |  Branch (432:7): [True: 791, False: 4.23k]
  |  Branch (432:25): [True: 3.40k, False: 827]
  ------------------
  433|  4.19k|    decodeTiffEntry(object);
  434|  4.19k|  }
  435|  5.02k|}
_ZN5Exiv28Internal11TiffDecoder18visitBinaryElementEPNS0_17TiffBinaryElementE:
  437|   569k|void TiffDecoder::visitBinaryElement(TiffBinaryElement* object) {
  438|   569k|  decodeTiffEntry(object);
  439|   569k|}
_ZN5Exiv28Internal11TiffEncoderC2ENS_8ExifDataERKNS_8IptcDataERKNS_7XmpDataEPNS0_13TiffComponentEbNSt3__16vectorINS_5IfdIdENSB_9allocatorISD_EEEEPKNS0_14TiffHeaderBaseEPFMS1_FvPNS0_13TiffEntryBaseEPKNS_9ExifdatumEENSB_17basic_string_viewIcNSB_11char_traitsIcEEEEjSD_E:
  444|  4.40k|    exifData_(std::move(exifData)),
  445|  4.40k|    iptcData_(iptcData),
  446|  4.40k|    xmpData_(xmpData),
  447|  4.40k|    pHeader_(pHeader),
  448|  4.40k|    pRoot_(pRoot),
  449|  4.40k|    isNewImage_(isNewImage),
  450|  4.40k|    pPrimaryGroups_(std::move(pPrimaryGroups)),
  451|  4.40k|    byteOrder_(pHeader->byteOrder()),
  452|  4.40k|    origByteOrder_(byteOrder_),
  453|  4.40k|    findEncoderFct_(findEncoderFct) {
  454|  4.40k|  encodeIptc();
  455|  4.40k|  encodeXmp();
  456|       |
  457|       |  // Find camera make
  458|  4.40k|  ExifKey key("Exif.Image.Make");
  459|  4.40k|  if (auto pos = exifData_.findKey(key); pos != exifData_.end()) {
  ------------------
  |  Branch (459:42): [True: 0, False: 4.40k]
  ------------------
  460|      0|    make_ = pos->toString();
  461|      0|  }
  462|  4.40k|  if (make_.empty() && pRoot_) {
  ------------------
  |  Branch (462:7): [True: 4.40k, False: 0]
  |  Branch (462:24): [True: 4.40k, False: 0]
  ------------------
  463|  4.40k|    TiffFinder finder(0x010f, IfdId::ifd0Id);
  464|  4.40k|    pRoot_->accept(finder);
  465|  4.40k|    auto te = dynamic_cast<const TiffEntryBase*>(finder.result());
  466|  4.40k|    if (te && te->pValue()) {
  ------------------
  |  Branch (466:9): [True: 0, False: 4.40k]
  |  Branch (466:15): [True: 0, False: 0]
  ------------------
  467|      0|      make_ = te->pValue()->toString();
  468|      0|    }
  469|  4.40k|  }
  470|  4.40k|}
_ZN5Exiv28Internal11TiffEncoder10encodeIptcEv:
  472|  4.40k|void TiffEncoder::encodeIptc() {
  473|       |  // Update IPTCNAA Exif tag, if it exists. Delete the tag if there
  474|       |  // is no IPTC data anymore.
  475|       |  // If there is new IPTC data and Exif.Image.ImageResources does
  476|       |  // not exist, create a new IPTCNAA Exif tag.
  477|  4.40k|  bool del = false;
  478|  4.40k|  ExifKey iptcNaaKey("Exif.Image.IPTCNAA");
  479|  4.40k|  auto pos = exifData_.findKey(iptcNaaKey);
  480|  4.40k|  if (pos != exifData_.end()) {
  ------------------
  |  Branch (480:7): [True: 0, False: 4.40k]
  ------------------
  481|      0|    iptcNaaKey.setIdx(pos->idx());
  482|      0|    exifData_.erase(pos);
  483|      0|    del = true;
  484|      0|  }
  485|  4.40k|  DataBuf rawIptc = IptcParser::encode(iptcData_);
  486|  4.40k|  ExifKey irbKey("Exif.Image.ImageResources");
  487|  4.40k|  pos = exifData_.findKey(irbKey);
  488|  4.40k|  if (pos != exifData_.end()) {
  ------------------
  |  Branch (488:7): [True: 0, False: 4.40k]
  ------------------
  489|      0|    irbKey.setIdx(pos->idx());
  490|      0|  }
  491|  4.40k|  if (!rawIptc.empty() && (del || pos == exifData_.end())) {
  ------------------
  |  Branch (491:7): [True: 0, False: 4.40k]
  |  Branch (491:7): [True: 0, False: 4.40k]
  |  Branch (491:28): [True: 0, False: 0]
  |  Branch (491:35): [True: 0, False: 0]
  ------------------
  492|      0|    auto value = Value::create(unsignedLong);
  493|      0|    DataBuf buf;
  494|      0|    if (rawIptc.size() % 4 != 0) {
  ------------------
  |  Branch (494:9): [True: 0, False: 0]
  ------------------
  495|       |      // Pad the last unsignedLong value with 0s
  496|      0|      buf.alloc(((rawIptc.size() / 4) * 4) + 4);
  497|      0|      std::move(rawIptc.begin(), rawIptc.end(), buf.begin());
  498|      0|    } else {
  499|      0|      buf = std::move(rawIptc);  // Note: This resets rawIptc
  500|      0|    }
  501|      0|    value->read(buf.data(), buf.size(), byteOrder_);
  502|      0|    Exifdatum iptcDatum(iptcNaaKey, value.get());
  503|      0|    exifData_.add(iptcDatum);
  504|      0|    pos = exifData_.findKey(irbKey);  // needed after add()
  505|      0|  }
  506|       |  // Also update IPTC IRB in Exif.Image.ImageResources if it exists,
  507|       |  // but don't create it if not.
  508|  4.40k|  if (pos != exifData_.end()) {
  ------------------
  |  Branch (508:7): [True: 0, False: 4.40k]
  ------------------
  509|      0|    DataBuf irbBuf(pos->value().size());
  510|      0|    pos->value().copy(irbBuf.data(), invalidByteOrder);
  511|      0|    irbBuf = Photoshop::setIptcIrb(irbBuf.c_data(), irbBuf.size(), iptcData_);
  512|      0|    exifData_.erase(pos);
  513|      0|    if (!irbBuf.empty()) {
  ------------------
  |  Branch (513:9): [True: 0, False: 0]
  ------------------
  514|      0|      auto value = Value::create(unsignedByte);
  515|      0|      value->read(irbBuf.data(), irbBuf.size(), invalidByteOrder);
  516|      0|      Exifdatum iptcDatum(irbKey, value.get());
  517|      0|      exifData_.add(iptcDatum);
  518|      0|    }
  519|      0|  }
  520|  4.40k|}  // TiffEncoder::encodeIptc
_ZN5Exiv28Internal11TiffEncoder9encodeXmpEv:
  522|  4.40k|void TiffEncoder::encodeXmp() {
  523|  4.40k|#ifdef EXV_HAVE_XMP_TOOLKIT
  524|  4.40k|  ExifKey xmpKey("Exif.Image.XMLPacket");
  525|       |  // Remove any existing XMP Exif tag
  526|  4.40k|  if (auto pos = exifData_.findKey(xmpKey); pos != exifData_.end()) {
  ------------------
  |  Branch (526:45): [True: 0, False: 4.40k]
  ------------------
  527|      0|    xmpKey.setIdx(pos->idx());
  528|      0|    exifData_.erase(pos);
  529|      0|  }
  530|  4.40k|  std::string xmpPacket;
  531|  4.40k|  if (xmpData_.usePacket()) {
  ------------------
  |  Branch (531:7): [True: 0, False: 4.40k]
  ------------------
  532|      0|    xmpPacket = xmpData_.xmpPacket();
  533|  4.40k|  } else {
  534|  4.40k|    if (XmpParser::encode(xmpPacket, xmpData_) > 1) {
  ------------------
  |  Branch (534:9): [True: 0, False: 4.40k]
  ------------------
  535|      0|#ifndef SUPPRESS_WARNINGS
  536|      0|      EXV_ERROR << "Failed to encode XMP metadata.\n";
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
  537|      0|#endif
  538|      0|    }
  539|  4.40k|  }
  540|  4.40k|  if (!xmpPacket.empty()) {
  ------------------
  |  Branch (540:7): [True: 0, False: 4.40k]
  ------------------
  541|       |    // Set the XMP Exif tag to the new value
  542|      0|    auto value = Value::create(unsignedByte);
  543|      0|    value->read(reinterpret_cast<const byte*>(xmpPacket.data()), xmpPacket.size(), invalidByteOrder);
  544|      0|    Exifdatum xmpDatum(xmpKey, value.get());
  545|      0|    exifData_.add(xmpDatum);
  546|      0|  }
  547|  4.40k|#endif
  548|  4.40k|}  // TiffEncoder::encodeXmp
_ZN5Exiv28Internal11TiffEncoder8setDirtyEb:
  550|  32.2k|void TiffEncoder::setDirty(bool flag) {
  551|  32.2k|  dirty_ = flag;
  552|  32.2k|  setGo(geTraverse, !flag);
  553|  32.2k|}
_ZNK5Exiv28Internal11TiffEncoder10isImageTagEtNS_5IfdIdE:
  700|   285k|bool TiffEncoder::isImageTag(uint16_t tag, IfdId group) const {
  701|   285k|  return !isNewImage_ && pHeader_->isImageTag(tag, group, pPrimaryGroups_);
  ------------------
  |  Branch (701:10): [True: 0, False: 285k]
  |  Branch (701:26): [True: 0, False: 0]
  ------------------
  702|   285k|}
_ZN5Exiv28Internal11TiffEncoder19encodeTiffComponentEPNS0_13TiffEntryBaseEPKNS_9ExifdatumE:
  704|   142k|void TiffEncoder::encodeTiffComponent(TiffEntryBase* object, const Exifdatum* datum) {
  705|   142k|  auto pos = exifData_.end();
  706|   142k|  const Exifdatum* ed = datum;
  707|   142k|  if (!ed) {
  ------------------
  |  Branch (707:7): [True: 0, False: 142k]
  ------------------
  708|       |    // Non-intrusive writing: find matching tag
  709|      0|    ExifKey key(object->tag(), groupName(object->group()));
  710|      0|    pos = exifData_.findKey(key);
  711|      0|    if (pos != exifData_.end()) {
  ------------------
  |  Branch (711:9): [True: 0, False: 0]
  ------------------
  712|      0|      ed = &(*pos);
  713|      0|      if (object->idx() != pos->idx()) {
  ------------------
  |  Branch (713:11): [True: 0, False: 0]
  ------------------
  714|       |        // Try to find exact match (in case of duplicate tags)
  715|      0|        auto pos2 = std::find_if(exifData_.begin(), exifData_.end(), FindExifdatum2(object->group(), object->idx()));
  716|      0|        if (pos2 != exifData_.end() && pos2->key() == key.key()) {
  ------------------
  |  Branch (716:13): [True: 0, False: 0]
  |  Branch (716:13): [True: 0, False: 0]
  |  Branch (716:40): [True: 0, False: 0]
  ------------------
  717|      0|          ed = &(*pos2);
  718|      0|          pos = pos2;  // make sure we delete the correct tag below
  719|      0|        }
  720|      0|      }
  721|      0|    } else {
  722|      0|      setDirty();
  723|       |#ifdef EXIV2_DEBUG_MESSAGES
  724|       |      std::cerr << "DELETING          " << key << ", idx = " << object->idx() << "\n";
  725|       |#endif
  726|      0|    }
  727|   142k|  } else {
  728|       |    // For intrusive writing, the index is used to preserve the order of
  729|       |    // duplicate tags
  730|   142k|    object->idx_ = ed->idx();
  731|   142k|  }
  732|       |  // Skip encoding image tags of existing TIFF image - they were copied earlier -
  733|       |  // but encode image tags of new images (creation)
  734|   142k|  if (ed && !isImageTag(object->tag(), object->group())) {
  ------------------
  |  Branch (734:7): [True: 142k, False: 0]
  |  Branch (734:13): [True: 142k, False: 0]
  ------------------
  735|   142k|    if (auto fct = findEncoderFct_(make_, object->tag(), object->group())) {
  ------------------
  |  Branch (735:14): [True: 0, False: 142k]
  ------------------
  736|       |      // If an encoding function is registered for the tag, use it
  737|      0|      std::invoke(fct, *this, object, ed);
  738|   142k|    } else {
  739|       |      // Else use the encode function at the object (results in a double-dispatch
  740|       |      // to the appropriate encoding function of the encoder.
  741|   142k|      object->encode(*this, ed);
  742|   142k|    }
  743|   142k|  }
  744|   142k|  if (del_ && pos != exifData_.end()) {
  ------------------
  |  Branch (744:7): [True: 0, False: 142k]
  |  Branch (744:7): [True: 0, False: 142k]
  |  Branch (744:15): [True: 0, False: 0]
  ------------------
  745|      0|    exifData_.erase(pos);
  746|      0|  }
  747|       |#ifdef EXIV2_DEBUG_MESSAGES
  748|       |  std::cerr << "\n";
  749|       |#endif
  750|   142k|}  // TiffEncoder::encodeTiffComponent
_ZN5Exiv28Internal11TiffEncoder15encodeTiffEntryEPNS0_9TiffEntryEPKNS_9ExifdatumE:
  788|   106k|void TiffEncoder::encodeTiffEntry(TiffEntry* object, const Exifdatum* datum) {
  789|   106k|  encodeTiffEntryBase(object, datum);
  790|   106k|}  // TiffEncoder::encodeTiffEntry
_ZN5Exiv28Internal11TiffEncoder16encodeImageEntryEPNS0_14TiffImageEntryEPKNS_9ExifdatumE:
  792|  16.3k|void TiffEncoder::encodeImageEntry(TiffImageEntry* object, const Exifdatum* datum) {
  793|  16.3k|  encodeOffsetEntry(object, datum);
  794|       |
  795|  16.3k|  size_t sizeDataArea = object->pValue()->sizeDataArea();
  796|       |
  797|  16.3k|  if (sizeDataArea > 0 && writeMethod() == wmNonIntrusive) {
  ------------------
  |  Branch (797:7): [True: 1.50k, False: 14.8k]
  |  Branch (797:27): [True: 0, False: 1.50k]
  ------------------
  798|       |#ifdef EXIV2_DEBUG_MESSAGES
  799|       |    std::cerr << "\t DATAAREA IS SET (NON-INTRUSIVE WRITING)";
  800|       |#endif
  801|      0|    setDirty();
  802|      0|  }
  803|       |
  804|  16.3k|  if (sizeDataArea > 0 && writeMethod() == wmIntrusive) {
  ------------------
  |  Branch (804:7): [True: 1.50k, False: 14.8k]
  |  Branch (804:27): [True: 1.50k, False: 0]
  ------------------
  805|       |#ifdef EXIV2_DEBUG_MESSAGES
  806|       |    std::cerr << "\t DATAAREA IS SET (INTRUSIVE WRITING)";
  807|       |#endif
  808|       |    // Set pseudo strips (without a data pointer) from the size tag
  809|  1.50k|    ExifKey key(object->szTag(), groupName(object->szGroup()));
  810|  1.50k|    auto pos = exifData_.findKey(key);
  811|  1.50k|    const byte* zero = nullptr;
  812|  1.50k|    if (pos == exifData_.end()) {
  ------------------
  |  Branch (812:9): [True: 0, False: 1.50k]
  ------------------
  813|      0|#ifndef SUPPRESS_WARNINGS
  814|      0|      EXV_ERROR << "Size tag " << key << " not found. Writing only one strip.\n";
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
  815|      0|#endif
  816|      0|      object->strips_.clear();
  817|      0|      object->strips_.emplace_back(zero, sizeDataArea);
  818|  1.50k|    } else {
  819|  1.50k|      size_t sizeTotal = 0;
  820|  1.50k|      object->strips_.clear();
  821|  67.3k|      for (size_t i = 0; i < pos->count(); ++i) {
  ------------------
  |  Branch (821:26): [True: 65.8k, False: 1.50k]
  ------------------
  822|  65.8k|        uint32_t len = pos->toUint32(i);
  823|  65.8k|        object->strips_.emplace_back(zero, len);
  824|  65.8k|        sizeTotal += len;
  825|  65.8k|      }
  826|  1.50k|      if (sizeTotal != sizeDataArea) {
  ------------------
  |  Branch (826:11): [True: 105, False: 1.40k]
  ------------------
  827|    105|#ifndef SUPPRESS_WARNINGS
  828|    105|        ExifKey key2(object->tag(), groupName(object->group()));
  829|    105|        EXV_ERROR << "Sum of all sizes of " << key << " != data size of " << key2 << ". "
  ------------------
  |  |  142|    105|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 105]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|    105|  LogMsg(LogMsg::error).os()
  ------------------
  830|      0|                  << "This results in an invalid image.\n";
  831|    105|#endif
  832|       |        // Todo: How to fix? Write only one strip?
  833|    105|      }
  834|  1.50k|    }
  835|  1.50k|  }
  836|       |
  837|  16.3k|  if (sizeDataArea == 0 && writeMethod() == wmIntrusive) {
  ------------------
  |  Branch (837:7): [True: 14.8k, False: 1.50k]
  |  Branch (837:28): [True: 14.8k, False: 0]
  ------------------
  838|       |#ifdef EXIV2_DEBUG_MESSAGES
  839|       |    std::cerr << "\t USE STRIPS FROM SOURCE TREE IMAGE ENTRY";
  840|       |#endif
  841|       |    // Set strips from source tree
  842|  14.8k|    if (pSourceTree_) {
  ------------------
  |  Branch (842:9): [True: 0, False: 14.8k]
  ------------------
  843|      0|      TiffFinder finder(object->tag(), object->group());
  844|      0|      pSourceTree_->accept(finder);
  845|      0|      if (auto ti = dynamic_cast<const TiffImageEntry*>(finder.result())) {
  ------------------
  |  Branch (845:16): [True: 0, False: 0]
  ------------------
  846|      0|        object->strips_ = ti->strips_;
  847|      0|      }
  848|      0|    }
  849|  14.8k|#ifndef SUPPRESS_WARNINGS
  850|  14.8k|    else {
  851|  14.8k|      ExifKey key2(object->tag(), groupName(object->group()));
  852|  14.8k|      EXV_WARNING << "No image data to encode " << key2 << ".\n";
  ------------------
  |  |  138|  14.8k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 14.8k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  14.8k|  LogMsg(LogMsg::warn).os()
  ------------------
  853|  14.8k|    }
  854|  14.8k|#endif
  855|  14.8k|  }
  856|       |
  857|  16.3k|}  // TiffEncoder::encodeImageEntry
_ZN5Exiv28Internal11TiffEncoder15encodeSizeEntryEPNS0_13TiffSizeEntryEPKNS_9ExifdatumE:
  865|  20.1k|void TiffEncoder::encodeSizeEntry(TiffSizeEntry* object, const Exifdatum* datum) {
  866|  20.1k|  encodeTiffEntryBase(object, datum);
  867|  20.1k|}  // TiffEncoder::encodeSizeEntry
_ZN5Exiv28Internal11TiffEncoder19encodeTiffEntryBaseEPNS0_13TiffEntryBaseEPKNS_9ExifdatumE:
  873|   126k|void TiffEncoder::encodeTiffEntryBase(TiffEntryBase* object, const Exifdatum* datum) {
  874|       |#ifdef EXIV2_DEBUG_MESSAGES
  875|       |  bool tooLarge = false;
  876|       |#endif
  877|   126k|  if (datum->size() > object->size_) {  // value doesn't fit, encode for intrusive writing
  ------------------
  |  Branch (877:7): [True: 24.3k, False: 101k]
  ------------------
  878|  24.3k|    setDirty();
  879|       |#ifdef EXIV2_DEBUG_MESSAGES
  880|       |    tooLarge = true;
  881|       |#endif
  882|  24.3k|  }
  883|   126k|  object->updateValue(datum->getValue(), byteOrder());  // clones the value
  884|       |#ifdef EXIV2_DEBUG_MESSAGES
  885|       |  ExifKey key(object->tag(), groupName(object->group()));
  886|       |  std::cerr << "UPDATING DATA     " << key;
  887|       |  if (tooLarge) {
  888|       |    std::cerr << "\t\t\t ALLOCATED " << std::dec << object->size_ << " BYTES";
  889|       |  }
  890|       |#endif
  891|   126k|}
_ZN5Exiv28Internal11TiffEncoder17encodeOffsetEntryEPNS0_13TiffEntryBaseEPKNS_9ExifdatumE:
  893|  16.3k|void TiffEncoder::encodeOffsetEntry(TiffEntryBase* object, const Exifdatum* datum) {
  894|  16.3k|  size_t newSize = datum->size();
  895|  16.3k|  if (newSize > object->size_) {  // value doesn't fit, encode for intrusive writing
  ------------------
  |  Branch (895:7): [True: 7.89k, False: 8.48k]
  ------------------
  896|  7.89k|    setDirty();
  897|  7.89k|    object->updateValue(datum->getValue(), byteOrder());  // clones the value
  898|       |#ifdef EXIV2_DEBUG_MESSAGES
  899|       |    ExifKey key(object->tag(), groupName(object->group()));
  900|       |    std::cerr << "UPDATING DATA     " << key;
  901|       |    std::cerr << "\t\t\t ALLOCATED " << object->size() << " BYTES";
  902|       |#endif
  903|  8.48k|  } else {
  904|  8.48k|    object->setValue(datum->getValue());  // clones the value
  905|       |#ifdef EXIV2_DEBUG_MESSAGES
  906|       |    ExifKey key(object->tag(), groupName(object->group()));
  907|       |    std::cerr << "NOT UPDATING      " << key;
  908|       |    std::cerr << "\t\t\t PRESERVE VALUE DATA";
  909|       |#endif
  910|  8.48k|  }
  911|  16.3k|}
_ZN5Exiv28Internal11TiffEncoder3addEPNS0_13TiffComponentENSt3__110unique_ptrIS2_NS4_14default_deleteIS2_EEEEj:
  913|  4.40k|void TiffEncoder::add(TiffComponent* pRootDir, TiffComponent::UniquePtr pSourceDir, uint32_t root) {
  914|  4.40k|  writeMethod_ = wmIntrusive;
  915|  4.40k|  pSourceTree_ = std::move(pSourceDir);
  916|       |
  917|       |  // Ensure that the exifData_ entries are not deleted, to be able to
  918|       |  // iterate over all remaining entries.
  919|  4.40k|  del_ = false;
  920|       |
  921|  4.40k|  auto posBo = exifData_.end();
  922|   147k|  for (auto i = exifData_.begin(); i != exifData_.end(); ++i) {
  ------------------
  |  Branch (922:36): [True: 142k, False: 4.40k]
  ------------------
  923|   142k|    IfdId group = groupId(i->groupName());
  924|       |    // Skip synthesized info tags
  925|   142k|    if (group == IfdId::mnId) {
  ------------------
  |  Branch (925:9): [True: 0, False: 142k]
  ------------------
  926|      0|      if (i->tag() == 0x0002) {
  ------------------
  |  Branch (926:11): [True: 0, False: 0]
  ------------------
  927|      0|        posBo = i;
  928|      0|      }
  929|      0|      continue;
  930|      0|    }
  931|       |
  932|       |    // Skip image tags of existing TIFF image - they were copied earlier -
  933|       |    // but add and encode image tags of new images (creation)
  934|   142k|    if (isImageTag(i->tag(), group))
  ------------------
  |  Branch (934:9): [True: 0, False: 142k]
  ------------------
  935|      0|      continue;
  936|       |
  937|       |    // Assumption is that the corresponding TIFF entry doesn't exist
  938|   142k|    auto tiffPath = TiffCreator::getPath(i->tag(), group, root);
  939|   142k|    TiffComponent* tc = pRootDir->addPath(i->tag(), tiffPath, pRootDir);
  940|   142k|    auto object = dynamic_cast<TiffEntryBase*>(tc);
  941|       |#ifdef EXIV2_DEBUG_MESSAGES
  942|       |    if (!object) {
  943|       |      std::cerr << "Warning: addPath() didn't add an entry for " << i->groupName() << " tag 0x" << std::setw(4)
  944|       |                << std::setfill('0') << std::hex << i->tag() << "\n";
  945|       |    }
  946|       |#endif
  947|   142k|    if (object) {
  ------------------
  |  Branch (947:9): [True: 142k, False: 0]
  ------------------
  948|   142k|      encodeTiffComponent(object, &(*i));
  949|   142k|    }
  950|   142k|  }
  951|       |
  952|       |  /*
  953|       |    What follows is a hack. I can't think of a better way to set
  954|       |    the makernote byte order (and other properties maybe) in the
  955|       |    makernote header during intrusive writing. The thing is that
  956|       |    visit/encodeIfdMakernote is not called in this case and there
  957|       |    can't be an Exif tag which corresponds to this component.
  958|       |   */
  959|  4.40k|  if (posBo == exifData_.end())
  ------------------
  |  Branch (959:7): [True: 4.40k, False: 0]
  ------------------
  960|  4.40k|    return;
  961|       |
  962|      0|  TiffFinder finder(0x927c, IfdId::exifId);
  963|      0|  pRootDir->accept(finder);
  964|      0|  if (auto te = dynamic_cast<const TiffMnEntry*>(finder.result())) {
  ------------------
  |  Branch (964:12): [True: 0, False: 0]
  ------------------
  965|      0|    if (const auto& mn = te->mn_) {
  ------------------
  |  Branch (965:21): [True: 0, False: 0]
  ------------------
  966|       |      // Set Makernote byte order
  967|      0|      ByteOrder bo = stringToByteOrder(posBo->toString());
  968|      0|      if (bo != invalidByteOrder)
  ------------------
  |  Branch (968:11): [True: 0, False: 0]
  ------------------
  969|      0|        mn->setByteOrder(bo);
  970|      0|    }
  971|      0|  }
  972|       |
  973|      0|}  // TiffEncoder::add
_ZN5Exiv28Internal10TiffReaderC2EPKhmPNS0_13TiffComponentENS0_11TiffRwStateE:
  976|  10.3k|    pData_(pData), size_(size), pLast_(pData + size), pRoot_(pRoot), origState_(state), mnState_(state) {
  977|  10.3k|  pState_ = &origState_;
  978|       |
  979|  10.3k|}  // TiffReader::TiffReader
_ZN5Exiv28Internal10TiffReader12setOrigStateEv:
  981|  12.6k|void TiffReader::setOrigState() {
  982|  12.6k|  pState_ = &origState_;
  983|  12.6k|}
_ZN5Exiv28Internal10TiffReader10setMnStateEPKNS0_11TiffRwStateE:
  985|  12.7k|void TiffReader::setMnState(const TiffRwState* state) {
  986|  12.7k|  if (state) {
  ------------------
  |  Branch (986:7): [True: 2.37k, False: 10.3k]
  ------------------
  987|       |    // invalidByteOrder indicates 'no change'
  988|  2.37k|    if (state->byteOrder() == invalidByteOrder) {
  ------------------
  |  Branch (988:9): [True: 0, False: 2.37k]
  ------------------
  989|      0|      mnState_ = TiffRwState{origState_.byteOrder(), state->baseOffset()};
  990|  2.37k|    } else {
  991|  2.37k|      mnState_ = *state;
  992|  2.37k|    }
  993|  2.37k|  }
  994|  12.7k|  pState_ = &mnState_;
  995|  12.7k|}
_ZNK5Exiv28Internal10TiffReader9byteOrderEv:
  997|  4.14M|ByteOrder TiffReader::byteOrder() const {
  998|  4.14M|  return pState_->byteOrder();
  999|  4.14M|}
_ZNK5Exiv28Internal10TiffReader10baseOffsetEv:
 1001|   627k|size_t TiffReader::baseOffset() const {
 1002|   627k|  return pState_->baseOffset();
 1003|   627k|}
_ZN5Exiv28Internal10TiffReader17readDataEntryBaseEPNS0_17TiffDataEntryBaseE:
 1005|  42.1k|void TiffReader::readDataEntryBase(TiffDataEntryBase* object) {
 1006|  42.1k|  readTiffEntry(object);
 1007|  42.1k|  TiffFinder finder(object->szTag(), object->szGroup());
 1008|  42.1k|  pRoot_->accept(finder);
 1009|  42.1k|  auto te = dynamic_cast<const TiffEntryBase*>(finder.result());
 1010|  42.1k|  if (te && te->pValue()) {
  ------------------
  |  Branch (1010:7): [True: 30.7k, False: 11.4k]
  |  Branch (1010:13): [True: 19.1k, False: 11.5k]
  ------------------
 1011|  19.1k|    object->setStrips(te->pValue(), pData_, size_, baseOffset());
 1012|  19.1k|  }
 1013|  42.1k|}
_ZN5Exiv28Internal10TiffReader10visitEntryEPNS0_9TiffEntryE:
 1015|   725k|void TiffReader::visitEntry(TiffEntry* object) {
 1016|   725k|  readTiffEntry(object);
 1017|   725k|}
_ZN5Exiv28Internal10TiffReader14visitDataEntryEPNS0_13TiffDataEntryE:
 1019|  4.81k|void TiffReader::visitDataEntry(TiffDataEntry* object) {
 1020|  4.81k|  readDataEntryBase(object);
 1021|  4.81k|}
_ZN5Exiv28Internal10TiffReader15visitImageEntryEPNS0_14TiffImageEntryE:
 1023|  37.3k|void TiffReader::visitImageEntry(TiffImageEntry* object) {
 1024|  37.3k|  readDataEntryBase(object);
 1025|  37.3k|}
_ZN5Exiv28Internal10TiffReader14visitSizeEntryEPNS0_13TiffSizeEntryE:
 1027|  52.9k|void TiffReader::visitSizeEntry(TiffSizeEntry* object) {
 1028|  52.9k|  readTiffEntry(object);
 1029|  52.9k|  TiffFinder finder(object->dtTag(), object->dtGroup());
 1030|  52.9k|  pRoot_->accept(finder);
 1031|  52.9k|  auto te = dynamic_cast<TiffDataEntryBase*>(finder.result());
 1032|  52.9k|  if (te && te->pValue()) {
  ------------------
  |  Branch (1032:7): [True: 32.0k, False: 20.9k]
  |  Branch (1032:13): [True: 18.6k, False: 13.3k]
  ------------------
 1033|  18.6k|    te->setStrips(object->pValue(), pData_, size_, baseOffset());
 1034|  18.6k|  }
 1035|  52.9k|}
_ZN5Exiv28Internal10TiffReader17circularReferenceEPKhNS_5IfdIdE:
 1037|  35.2k|bool TiffReader::circularReference(const byte* start, IfdId group) {
 1038|  35.2k|  if (auto pos = dirList_.find(start); pos != dirList_.end()) {
  ------------------
  |  Branch (1038:40): [True: 3.84k, False: 31.4k]
  ------------------
 1039|  3.84k|#ifndef SUPPRESS_WARNINGS
 1040|  3.84k|    EXV_ERROR << groupName(group) << " pointer references previously read " << groupName(pos->second)
  ------------------
  |  |  142|  3.84k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 3.84k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  3.84k|  LogMsg(LogMsg::error).os()
  ------------------
 1041|      0|              << " directory; ignored.\n";
 1042|  3.84k|#endif
 1043|  3.84k|    return true;
 1044|  3.84k|  }
 1045|  31.4k|  dirList_[start] = group;
 1046|  31.4k|  return false;
 1047|  35.2k|}
_ZN5Exiv28Internal10TiffReader7nextIdxENS_5IfdIdE:
 1049|  1.05M|int TiffReader::nextIdx(IfdId group) {
 1050|  1.05M|  return ++idxSeq_[group];
 1051|  1.05M|}
_ZN5Exiv28Internal10TiffReader11postProcessEv:
 1053|  10.3k|void TiffReader::postProcess() {
 1054|  10.3k|  setMnState();  // All components to be post-processed must be from the Makernote
 1055|  10.3k|  postProc_ = true;
 1056|  10.3k|  for (auto pos : postList_) {
  ------------------
  |  Branch (1056:17): [True: 5.02k, False: 10.3k]
  ------------------
 1057|  5.02k|    pos->accept(*this);
 1058|  5.02k|  }
 1059|  10.3k|  postProc_ = false;
 1060|  10.3k|  setOrigState();
 1061|  10.3k|}
_ZN5Exiv28Internal10TiffReader14visitDirectoryEPNS0_13TiffDirectoryE:
 1063|  35.2k|void TiffReader::visitDirectory(TiffDirectory* object) {
 1064|  35.2k|  const byte* p = object->start();
 1065|       |
 1066|  35.2k|  if (circularReference(object->start(), object->group()))
  ------------------
  |  Branch (1066:7): [True: 3.84k, False: 31.4k]
  ------------------
 1067|  3.84k|    return;
 1068|       |
 1069|  31.4k|  if (p + 2 > pLast_) {
  ------------------
  |  Branch (1069:7): [True: 39, False: 31.4k]
  ------------------
 1070|     39|#ifndef SUPPRESS_WARNINGS
 1071|     39|    EXV_ERROR << "Directory " << groupName(object->group()) << ": IFD exceeds data buffer, cannot read entry count.\n";
  ------------------
  |  |  142|     39|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 39]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|     39|  LogMsg(LogMsg::error).os()
  ------------------
 1072|     39|#endif
 1073|     39|    return;
 1074|     39|  }
 1075|  31.4k|  const uint16_t n = getUShort(p, byteOrder());
 1076|  31.4k|  p += 2;
 1077|       |  // Sanity check with an "unreasonably" large number
 1078|  31.4k|  if (n > 256) {
  ------------------
  |  Branch (1078:7): [True: 2.89k, False: 28.5k]
  ------------------
 1079|  2.89k|#ifndef SUPPRESS_WARNINGS
 1080|  2.89k|    EXV_ERROR << "Directory " << groupName(object->group()) << " with " << n
  ------------------
  |  |  142|  2.89k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 2.89k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  2.89k|  LogMsg(LogMsg::error).os()
  ------------------
 1081|      0|              << " entries considered invalid; not read.\n";
 1082|  2.89k|#endif
 1083|  2.89k|    return;
 1084|  2.89k|  }
 1085|   876k|  for (uint16_t i = 0; i < n; ++i) {
  ------------------
  |  Branch (1085:24): [True: 863k, False: 13.4k]
  ------------------
 1086|   863k|    if (p + 12 > pLast_) {
  ------------------
  |  Branch (1086:9): [True: 15.0k, False: 848k]
  ------------------
 1087|  15.0k|#ifndef SUPPRESS_WARNINGS
 1088|  15.0k|      EXV_ERROR << "Directory " << groupName(object->group()) << ": IFD entry " << i
  ------------------
  |  |  142|  15.0k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 15.0k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  15.0k|  LogMsg(LogMsg::error).os()
  ------------------
 1089|      0|                << " lies outside of the data buffer.\n";
 1090|  15.0k|#endif
 1091|  15.0k|      return;
 1092|  15.0k|    }
 1093|   848k|    uint16_t tag = getUShort(p, byteOrder());
 1094|   848k|    if (auto tc = TiffCreator::create(tag, object->group())) {
  ------------------
  |  Branch (1094:14): [True: 848k, False: 198]
  ------------------
 1095|   848k|      tc->setStart(p);
 1096|   848k|      object->addChild(std::move(tc));
 1097|   848k|    } else {
 1098|    198|#ifndef SUPPRESS_WARNINGS
 1099|    198|      EXV_WARNING << "Unable to handle tag " << tag << ".\n";
  ------------------
  |  |  138|    198|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 198]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    198|  LogMsg(LogMsg::warn).os()
  ------------------
 1100|    198|#endif
 1101|    198|    }
 1102|   848k|    p += 12;
 1103|   848k|  }
 1104|       |
 1105|  13.4k|  if (object->hasNext()) {
  ------------------
  |  Branch (1105:7): [True: 13.4k, False: 6]
  ------------------
 1106|  13.4k|    if (p + 4 > pLast_) {
  ------------------
  |  Branch (1106:9): [True: 76, False: 13.3k]
  ------------------
 1107|     76|#ifndef SUPPRESS_WARNINGS
 1108|     76|      EXV_ERROR << "Directory " << groupName(object->group())
  ------------------
  |  |  142|     76|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 76]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|     76|  LogMsg(LogMsg::error).os()
  ------------------
 1109|      0|                << ": IFD exceeds data buffer, cannot read next pointer.\n";
 1110|     76|#endif
 1111|     76|      return;
 1112|     76|    }
 1113|  13.3k|    TiffComponent::UniquePtr tc;
 1114|  13.3k|    uint32_t next = getULong(p, byteOrder());
 1115|  13.3k|    if (next) {
  ------------------
  |  Branch (1115:9): [True: 12.7k, False: 614]
  ------------------
 1116|  12.7k|      tc = TiffCreator::create(Tag::next, object->group());
 1117|  12.7k|#ifndef SUPPRESS_WARNINGS
 1118|  12.7k|      if (!tc) {
  ------------------
  |  Branch (1118:11): [True: 7.35k, False: 5.43k]
  ------------------
 1119|  7.35k|        EXV_WARNING << "Directory " << groupName(object->group()) << " has an unexpected next pointer; ignored.\n";
  ------------------
  |  |  138|  7.35k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 7.35k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  7.35k|  LogMsg(LogMsg::warn).os()
  ------------------
 1120|  7.35k|      }
 1121|  12.7k|#endif
 1122|  12.7k|    }
 1123|  13.3k|    if (tc) {
  ------------------
  |  Branch (1123:9): [True: 5.43k, False: 7.96k]
  ------------------
 1124|  5.43k|      if (baseOffset() + next > size_) {
  ------------------
  |  Branch (1124:11): [True: 3.21k, False: 2.21k]
  ------------------
 1125|  3.21k|#ifndef SUPPRESS_WARNINGS
 1126|  3.21k|        EXV_ERROR << "Directory " << groupName(object->group()) << ": Next pointer is out of bounds; ignored.\n";
  ------------------
  |  |  142|  3.21k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 3.21k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  3.21k|  LogMsg(LogMsg::error).os()
  ------------------
 1127|  3.21k|#endif
 1128|  3.21k|        return;
 1129|  3.21k|      }
 1130|  2.21k|      tc->setStart(pData_ + baseOffset() + next);
 1131|  2.21k|      object->addNext(std::move(tc));
 1132|  2.21k|    }
 1133|  13.3k|  }  // object->hasNext()
 1134|       |
 1135|  13.4k|}  // TiffReader::visitDirectory
_ZN5Exiv28Internal10TiffReader11visitSubIfdEPNS0_10TiffSubIfdE:
 1137|  8.48k|void TiffReader::visitSubIfd(TiffSubIfd* object) {
 1138|  8.48k|  readTiffEntry(object);
 1139|  8.48k|  if ((object->tiffType() == ttUnsignedLong || object->tiffType() == ttSignedLong || object->tiffType() == ttTiffIfd) &&
  ------------------
  |  Branch (1139:8): [True: 6.41k, False: 2.06k]
  |  Branch (1139:48): [True: 584, False: 1.48k]
  |  Branch (1139:86): [True: 718, False: 763]
  ------------------
 1140|  7.71k|      object->count() >= 1) {
  ------------------
  |  Branch (1140:7): [True: 5.35k, False: 2.36k]
  ------------------
 1141|       |    // Todo: Fix hack
 1142|  5.35k|    uint32_t maxi = 9;
 1143|  5.35k|    if (object->group() == IfdId::ifd1Id)
  ------------------
  |  Branch (1143:9): [True: 192, False: 5.16k]
  ------------------
 1144|    192|      maxi = 1;
 1145|  25.7k|    for (uint32_t i = 0; i < object->count(); ++i) {
  ------------------
  |  Branch (1145:26): [True: 25.1k, False: 657]
  ------------------
 1146|  25.1k|      uint32_t offset = getULong(object->pData() + (4 * i), byteOrder());
 1147|  25.1k|      if (baseOffset() + offset > size_) {
  ------------------
  |  Branch (1147:11): [True: 4.41k, False: 20.7k]
  ------------------
 1148|  4.41k|#ifndef SUPPRESS_WARNINGS
 1149|  4.41k|        EXV_ERROR << "Directory " << groupName(object->group()) << ", entry 0x" << std::setw(4) << std::setfill('0')
  ------------------
  |  |  142|  4.41k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 4.41k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  4.41k|  LogMsg(LogMsg::error).os()
  ------------------
 1150|      0|                  << std::hex << object->tag() << " Sub-IFD pointer " << i << " is out of bounds; ignoring it.\n";
 1151|  4.41k|#endif
 1152|  4.41k|        return;
 1153|  4.41k|      }
 1154|  20.7k|      if (i >= maxi) {
  ------------------
  |  Branch (1154:11): [True: 284, False: 20.4k]
  ------------------
 1155|    284|#ifndef SUPPRESS_WARNINGS
 1156|    284|        EXV_WARNING << "Directory " << groupName(object->group()) << ", entry 0x" << std::setw(4) << std::setfill('0')
  ------------------
  |  |  138|    284|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 284]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    284|  LogMsg(LogMsg::warn).os()
  ------------------
 1157|      0|                    << std::hex << object->tag() << ": Skipping sub-IFDs beyond the first " << i << ".\n";
 1158|    284|#endif
 1159|    284|        break;
 1160|    284|      }
 1161|       |      // If there are multiple dirs, group is incremented for each
 1162|  20.4k|      auto td = std::make_unique<TiffDirectory>(object->tag(),
 1163|  20.4k|                                                static_cast<IfdId>(static_cast<uint32_t>(object->newGroup_) + i));
 1164|  20.4k|      td->setStart(pData_ + baseOffset() + offset);
 1165|  20.4k|      object->addChild(std::move(td));
 1166|  20.4k|    }
 1167|  5.35k|  }
 1168|  3.13k|#ifndef SUPPRESS_WARNINGS
 1169|  3.13k|  else {
 1170|  3.13k|    EXV_WARNING << "Directory " << groupName(object->group()) << ", entry 0x" << std::setw(4) << std::setfill('0')
  ------------------
  |  |  138|  3.13k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 3.13k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  3.13k|  LogMsg(LogMsg::warn).os()
  ------------------
 1171|      0|                << std::hex << object->tag() << " doesn't look like a sub-IFD.\n";
 1172|  3.13k|  }
 1173|  8.48k|#endif
 1174|       |
 1175|  8.48k|}  // TiffReader::visitSubIfd
_ZN5Exiv28Internal10TiffReader12visitMnEntryEPNS0_11TiffMnEntryE:
 1177|  11.8k|void TiffReader::visitMnEntry(TiffMnEntry* object) {
 1178|  11.8k|  readTiffEntry(object);
 1179|       |  // Find camera make
 1180|  11.8k|  TiffFinder finder(0x010f, IfdId::ifd0Id);
 1181|  11.8k|  pRoot_->accept(finder);
 1182|  11.8k|  auto te = dynamic_cast<const TiffEntryBase*>(finder.result());
 1183|  11.8k|  if (te && te->pValue()) {
  ------------------
  |  Branch (1183:7): [True: 11.6k, False: 254]
  |  Branch (1183:13): [True: 11.3k, False: 294]
  ------------------
 1184|  11.3k|    auto make = te->pValue()->toString();
 1185|       |    // create concrete makernote, based on make and makernote contents
 1186|  11.3k|    object->mn_ =
 1187|  11.3k|        TiffMnCreator::create(object->tag(), object->mnGroup_, make, object->pData_, object->size_, byteOrder());
 1188|  11.3k|  }
 1189|  11.8k|  if (object->mn_)
  ------------------
  |  Branch (1189:7): [True: 2.78k, False: 9.06k]
  ------------------
 1190|  2.78k|    object->mn_->setStart(object->pData());
 1191|       |
 1192|  11.8k|}  // TiffReader::visitMnEntry
_ZN5Exiv28Internal10TiffReader17visitIfdMakernoteEPNS0_16TiffIfdMakernoteE:
 1194|  2.78k|void TiffReader::visitIfdMakernote(TiffIfdMakernote* object) {
 1195|  2.78k|  object->setImageByteOrder(byteOrder());  // set the byte order for the image
 1196|       |
 1197|  2.78k|  if (!object->readHeader(object->start(), pLast_ - object->start(), byteOrder())) {
  ------------------
  |  Branch (1197:7): [True: 412, False: 2.37k]
  ------------------
 1198|    412|#ifndef SUPPRESS_WARNINGS
 1199|    412|    EXV_ERROR << "Failed to read " << groupName(object->ifd_.group()) << " IFD Makernote header.\n";
  ------------------
  |  |  142|    412|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 412]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|    412|  LogMsg(LogMsg::error).os()
  ------------------
 1200|       |#ifdef EXIV2_DEBUG_MESSAGES
 1201|       |    if (pLast_ - object->start() >= 16u) {
 1202|       |      hexdump(std::cerr, object->start(), 16u);
 1203|       |    }
 1204|       |#endif  // EXIV2_DEBUG_MESSAGES
 1205|    412|#endif  // SUPPRESS_WARNINGS
 1206|    412|    setGo(geKnownMakernote, false);
 1207|    412|    return;
 1208|    412|  }
 1209|       |
 1210|  2.37k|  object->ifd_.setStart(object->start() + object->ifdOffset());
 1211|       |
 1212|       |  // Modify reader for Makernote peculiarities, byte order and offset
 1213|  2.37k|  object->mnOffset_ = object->start() - pData_;
 1214|  2.37k|  auto state = TiffRwState{object->byteOrder(), object->baseOffset()};
 1215|  2.37k|  setMnState(&state);
 1216|       |
 1217|  2.37k|}  // TiffReader::visitIfdMakernote
_ZN5Exiv28Internal10TiffReader20visitIfdMakernoteEndEPNS0_16TiffIfdMakernoteE:
 1219|  2.33k|void TiffReader::visitIfdMakernoteEnd(TiffIfdMakernote* /*object*/) {
 1220|       |  // Reset state (byte order, create function, offset) back to that for the image
 1221|  2.33k|  setOrigState();
 1222|  2.33k|}  // TiffReader::visitIfdMakernoteEnd
_ZN5Exiv28Internal10TiffReader13readTiffEntryEPNS0_13TiffEntryBaseE:
 1224|   846k|void TiffReader::readTiffEntry(TiffEntryBase* object) {
 1225|   846k|  try {
 1226|   846k|    byte* p = object->start();
 1227|       |
 1228|   846k|    if (p + 12 > pLast_) {
  ------------------
  |  Branch (1228:9): [True: 0, False: 846k]
  ------------------
 1229|      0|#ifndef SUPPRESS_WARNINGS
 1230|      0|      EXV_ERROR << "Entry in directory " << groupName(object->group())
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
 1231|      0|                << "requests access to memory beyond the data buffer. " << "Skipping entry.\n";
 1232|      0|#endif
 1233|      0|      return;
 1234|      0|    }
 1235|       |    // Component already has tag
 1236|   846k|    p += 2;
 1237|   846k|    auto tiffType = static_cast<TiffType>(getUShort(p, byteOrder()));
 1238|   846k|    TypeId typeId = toTypeId(tiffType, object->tag(), object->group());
 1239|   846k|    size_t typeSize = TypeInfo::typeSize(typeId);
 1240|   846k|    if (0 == typeSize) {
  ------------------
  |  Branch (1240:9): [True: 752k, False: 94.1k]
  ------------------
 1241|   752k|#ifndef SUPPRESS_WARNINGS
 1242|   752k|      EXV_WARNING << stringFormat(
  ------------------
  |  |  138|   752k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 752k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|   752k|  LogMsg(LogMsg::warn).os()
  ------------------
                    EXV_WARNING << stringFormat(
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
 1243|      0|          "Directory {}, entry 0x{:04x} has unknown Exif (TIFF) type {}; setting type size 1.\n",
 1244|      0|          groupName(object->group()), object->tag(), static_cast<uint16_t>(tiffType));
 1245|   752k|#endif
 1246|   752k|      typeSize = 1;
 1247|   752k|    }
 1248|   846k|    p += 2;
 1249|   846k|    uint32_t count = getULong(p, byteOrder());
 1250|   846k|    if (count >= 0x10000000) {
  ------------------
  |  Branch (1250:9): [True: 359k, False: 487k]
  ------------------
 1251|   359k|#ifndef SUPPRESS_WARNINGS
 1252|   359k|      EXV_ERROR << stringFormat("Directory {}, entry 0x{:04x} has invalid size {}*{}; skipping entry.\n",
  ------------------
  |  |  142|   359k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 359k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|   359k|  LogMsg(LogMsg::error).os()
  ------------------
                    EXV_ERROR << stringFormat("Directory {}, entry 0x{:04x} has invalid size {}*{}; skipping entry.\n",
  ------------------
  |  |   18|      0|#define stringFormat std::format
  ------------------
 1253|      0|                                groupName(object->group()), object->tag(), count, typeSize);
 1254|   359k|#endif
 1255|   359k|      return;
 1256|   359k|    }
 1257|   487k|    p += 4;
 1258|       |
 1259|   487k|    if (count > std::numeric_limits<size_t>::max() / typeSize) {
  ------------------
  |  Branch (1259:9): [True: 0, False: 487k]
  ------------------
 1260|      0|      throw Error(ErrorCode::kerArithmeticOverflow);
 1261|      0|    }
 1262|   487k|    size_t size = typeSize * count;
 1263|   487k|    size_t offset = getULong(p, byteOrder());
 1264|   487k|    byte* pData = p;
 1265|   487k|    if (size > 4 && Safe::add<size_t>(baseOffset(), offset) >= size_) {
  ------------------
  |  Branch (1265:9): [True: 369k, False: 117k]
  |  Branch (1265:21): [True: 285k, False: 83.5k]
  ------------------
 1266|       |      // #1143
 1267|   285k|      if (object->tag() == 0x2001 && std::string(groupName(object->group())) == "Sony1") {
  ------------------
  |  Branch (1267:11): [True: 452, False: 285k]
  |  Branch (1267:11): [True: 101, False: 285k]
  |  Branch (1267:38): [True: 101, False: 351]
  ------------------
 1268|       |        // This tag is Exif.Sony1.PreviewImage, which refers to a preview image which is
 1269|       |        // not stored in the metadata. Instead it is stored at the end of the file, after
 1270|       |        // the main image. The value of `size` refers to the size of the preview image, not
 1271|       |        // the size of the tag's payload, so we set it to zero here so that we don't attempt
 1272|       |        // to read those bytes from the metadata. We currently leave this tag as "undefined",
 1273|       |        // although we may attempt to handle it better in the future. More discussion of
 1274|       |        // this issue can be found here:
 1275|       |        //
 1276|       |        //   https://github.com/Exiv2/exiv2/issues/2001
 1277|       |        //   https://github.com/Exiv2/exiv2/pull/2008
 1278|       |        //   https://github.com/Exiv2/exiv2/pull/2013
 1279|    101|        typeId = undefined;
 1280|    101|        size = 0;
 1281|   285k|      } else {
 1282|   285k|#ifndef SUPPRESS_WARNINGS
 1283|   285k|        EXV_ERROR << "Offset of directory " << groupName(object->group()) << ", entry 0x" << std::setw(4)
  ------------------
  |  |  142|   285k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 285k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|   285k|  LogMsg(LogMsg::error).os()
  ------------------
 1284|      0|                  << std::setfill('0') << std::hex << object->tag() << " is out of bounds: " << "Offset = 0x"
 1285|      0|                  << std::setw(8) << std::setfill('0') << std::hex << offset << "; truncating the entry\n";
 1286|   285k|#endif
 1287|   285k|      }
 1288|   285k|      size = 0;
 1289|   285k|    }
 1290|   487k|    if (size > 4) {
  ------------------
  |  Branch (1290:9): [True: 83.5k, False: 403k]
  ------------------
 1291|       |      // setting pData to pData_ + baseOffset() + offset can result in pData pointing to invalid memory,
 1292|       |      // as offset can be arbitrarily large
 1293|  83.5k|      if (Safe::add<size_t>(baseOffset(), offset) > static_cast<size_t>(pLast_ - pData_)) {
  ------------------
  |  Branch (1293:11): [True: 0, False: 83.5k]
  ------------------
 1294|      0|        throw Error(ErrorCode::kerCorruptedMetadata);
 1295|      0|      }
 1296|  83.5k|      pData = const_cast<byte*>(pData_) + baseOffset() + offset;
 1297|       |
 1298|       |      // check for size being invalid
 1299|  83.5k|      if (size > static_cast<size_t>(pLast_ - pData)) {
  ------------------
  |  Branch (1299:11): [True: 33.8k, False: 49.6k]
  ------------------
 1300|  33.8k|#ifndef SUPPRESS_WARNINGS
 1301|  33.8k|        EXV_ERROR << "Upper boundary of data for " << "directory " << groupName(object->group()) << ", entry 0x"
  ------------------
  |  |  142|  33.8k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 33.8k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  33.8k|  LogMsg(LogMsg::error).os()
  ------------------
 1302|      0|                  << std::setw(4) << std::setfill('0') << std::hex << object->tag()
 1303|      0|                  << " is out of bounds: " << "Offset = 0x" << std::setw(8) << std::setfill('0') << std::hex << offset
 1304|      0|                  << ", size = " << std::dec << size
 1305|      0|                  << ", exceeds buffer size by "
 1306|       |                  // cast to make MSVC happy
 1307|      0|                  << size - static_cast<size_t>(pLast_ - pData) << " Bytes; truncating the entry\n";
 1308|  33.8k|#endif
 1309|  33.8k|        size = 0;
 1310|  33.8k|      }
 1311|  83.5k|    }
 1312|   487k|    auto v = Value::create(typeId);
 1313|   487k|    enforce(v != nullptr, ErrorCode::kerCorruptedMetadata);
 1314|   487k|    v->read(pData, size, byteOrder());
 1315|       |
 1316|   487k|    object->setValue(std::move(v));
 1317|   487k|    auto d = std::make_shared<DataBuf>();
 1318|   487k|    object->setData(pData, size, std::move(d));
 1319|   487k|    object->setOffset(offset);
 1320|   487k|    object->setIdx(nextIdx(object->group()));
 1321|   487k|  } catch (std::overflow_error&) {
 1322|      0|    throw Error(ErrorCode::kerCorruptedMetadata);  // #562 don't throw std::overflow_error
 1323|      0|  }
 1324|   846k|}  // TiffReader::readTiffEntry
_ZN5Exiv28Internal10TiffReader16visitBinaryArrayEPNS0_15TiffBinaryArrayE:
 1326|  10.0k|void TiffReader::visitBinaryArray(TiffBinaryArray* object) {
 1327|  10.0k|  if (!postProc_) {
  ------------------
  |  Branch (1327:7): [True: 5.02k, False: 5.02k]
  ------------------
 1328|       |    // Defer reading children until after all other components are read, but
 1329|       |    // since state (offset) is not set during post-processing, read entry here
 1330|  5.02k|    readTiffEntry(object);
 1331|  5.02k|    object->iniOrigDataBuf();
 1332|  5.02k|    postList_.push_back(object);
 1333|  5.02k|    return;
 1334|  5.02k|  }
 1335|       |  // Check duplicates
 1336|  5.02k|  TiffFinder finder(object->tag(), object->group());
 1337|  5.02k|  pRoot_->accept(finder);
 1338|  5.02k|  if (auto te = dynamic_cast<const TiffEntryBase*>(finder.result())) {
  ------------------
  |  Branch (1338:12): [True: 5.02k, False: 0]
  ------------------
 1339|  5.02k|    if (te->idx() != object->idx()) {
  ------------------
  |  Branch (1339:9): [True: 2.31k, False: 2.71k]
  ------------------
 1340|  2.31k|#ifndef SUPPRESS_WARNINGS
 1341|  2.31k|      EXV_WARNING << "Not decoding duplicate binary array tag 0x" << std::setw(4) << std::setfill('0') << std::hex
  ------------------
  |  |  138|  2.31k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 2.31k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  2.31k|  LogMsg(LogMsg::warn).os()
  ------------------
 1342|      0|                  << object->tag() << std::dec << ", group " << groupName(object->group()) << ", idx " << object->idx()
 1343|      0|                  << "\n";
 1344|  2.31k|#endif
 1345|  2.31k|      object->setDecoded(false);
 1346|  2.31k|      return;
 1347|  2.31k|    }
 1348|  5.02k|  }
 1349|       |
 1350|  2.71k|  if (object->TiffEntryBase::doSize() == 0)
  ------------------
  |  Branch (1350:7): [True: 1.56k, False: 1.14k]
  ------------------
 1351|  1.56k|    return;
 1352|  1.14k|  if (!object->initialize(pRoot_))
  ------------------
  |  Branch (1352:7): [True: 319, False: 827]
  ------------------
 1353|    319|    return;
 1354|    827|  const ArrayCfg* cfg = object->cfg();
 1355|    827|  if (!cfg)
  ------------------
  |  Branch (1355:7): [True: 0, False: 827]
  ------------------
 1356|      0|    return;
 1357|       |
 1358|    827|  if (auto cryptFct = cfg->cryptFct_) {
  ------------------
  |  Branch (1358:12): [True: 209, False: 618]
  ------------------
 1359|    209|    const byte* pData = object->pData();
 1360|    209|    size_t size = object->TiffEntryBase::doSize();
 1361|    209|    auto buf = std::make_shared<DataBuf>(cryptFct(object->tag(), pData, size, pRoot_));
 1362|    209|    if (!buf->empty())
  ------------------
  |  Branch (1362:9): [True: 152, False: 57]
  ------------------
 1363|    152|      object->setData(std::move(buf));
 1364|    209|  }
 1365|       |
 1366|    827|  const ArrayDef* defs = object->def();
 1367|    827|  const ArrayDef* defsEnd = defs + object->defSize();
 1368|    827|  const ArrayDef* def = &cfg->elDefaultDef_;
 1369|    827|  ArrayDef gap = *def;
 1370|       |
 1371|   568k|  for (size_t idx = 0; idx < object->TiffEntryBase::doSize();) {
  ------------------
  |  Branch (1371:24): [True: 567k, False: 827]
  ------------------
 1372|   567k|    if (defs) {
  ------------------
  |  Branch (1372:9): [True: 269k, False: 297k]
  ------------------
 1373|   269k|      def = std::find(defs, defsEnd, idx);
 1374|   269k|      if (def == defsEnd) {
  ------------------
  |  Branch (1374:11): [True: 268k, False: 1.40k]
  ------------------
 1375|   268k|        if (cfg->concat_) {
  ------------------
  |  Branch (1375:13): [True: 220, False: 268k]
  ------------------
 1376|       |          // Determine gap-size
 1377|    220|          const ArrayDef* xdef = defs;
 1378|  1.11k|          for (; xdef != defsEnd && xdef->idx_ <= idx; ++xdef) {
  ------------------
  |  Branch (1378:18): [True: 1.06k, False: 45]
  |  Branch (1378:37): [True: 893, False: 175]
  ------------------
 1379|    893|          }
 1380|    220|          size_t gapSize = 0;
 1381|    220|          if (xdef != defsEnd && xdef->idx_ > idx) {
  ------------------
  |  Branch (1381:15): [True: 175, False: 45]
  |  Branch (1381:34): [True: 175, False: 0]
  ------------------
 1382|    175|            gapSize = xdef->idx_ - idx;
 1383|    175|          } else {
 1384|     45|            gapSize = object->TiffEntryBase::doSize() - idx;
 1385|     45|          }
 1386|    220|          gap.idx_ = idx;
 1387|    220|          gap.tiffType_ = cfg->elDefaultDef_.tiffType_;
 1388|    220|          gap.count_ = gapSize / cfg->tagStep();
 1389|    220|          if (gap.count_ * cfg->tagStep() != gapSize) {
  ------------------
  |  Branch (1389:15): [True: 1, False: 219]
  ------------------
 1390|      1|            gap.tiffType_ = ttUndefined;
 1391|      1|            gap.count_ = gapSize;
 1392|      1|          }
 1393|    220|          def = &gap;
 1394|   268k|        } else {
 1395|   268k|          def = &cfg->elDefaultDef_;
 1396|   268k|        }
 1397|   268k|      }
 1398|   269k|    }
 1399|   567k|    idx += object->addElement(idx, *def);  // idx may be different from def->idx_
 1400|   567k|  }
 1401|       |
 1402|    827|}  // TiffReader::visitBinaryArray
_ZN5Exiv28Internal10TiffReader18visitBinaryElementEPNS0_17TiffBinaryElementE:
 1404|   569k|void TiffReader::visitBinaryElement(TiffBinaryElement* object) {
 1405|   569k|  auto pData = object->start();
 1406|   569k|  size_t size = object->TiffEntryBase::doSize();
 1407|   569k|  ByteOrder bo = object->elByteOrder();
 1408|   569k|  if (bo == invalidByteOrder)
  ------------------
  |  Branch (1408:7): [True: 545k, False: 23.7k]
  ------------------
 1409|   545k|    bo = byteOrder();
 1410|   569k|  TypeId typeId = toTypeId(object->elDef()->tiffType_, object->tag(), object->group());
 1411|   569k|  auto v = Value::create(typeId);
 1412|   569k|  enforce(v != nullptr, ErrorCode::kerCorruptedMetadata);
 1413|   569k|  v->read(pData, size, bo);
 1414|       |
 1415|   569k|  object->setValue(std::move(v));
 1416|   569k|  object->setOffset(0);
 1417|   569k|  object->setIdx(nextIdx(object->group()));
 1418|   569k|}
tiffvisitor_int.cpp:_ZN5Exiv28InternalL7findTagEPKNS_7TagInfoEt:
  341|  8.41k|static const TagInfo* findTag(const TagInfo* pList, uint16_t tag) {
  342|   589k|  while (pList->tag_ != 0xffff && pList->tag_ != tag)
  ------------------
  |  Branch (342:10): [True: 589k, False: 0]
  |  Branch (342:35): [True: 580k, False: 8.41k]
  ------------------
  343|   580k|    pList++;
  344|  8.41k|  return pList->tag_ != 0xffff ? pList : nullptr;
  ------------------
  |  Branch (344:10): [True: 8.41k, False: 0]
  ------------------
  345|  8.41k|}

_ZN5Exiv28Internal11TiffVisitorD2Ev:
   65|  25.0k|  virtual ~TiffVisitor() = default;
_ZN5Exiv28Internal11TiffEncoderD2Ev:
  355|  4.40k|  ~TiffEncoder() override = default;
_ZN5Exiv28Internal11TiffRwStateC2ENS_9ByteOrderEm:
  538|  12.7k|  constexpr TiffRwState(ByteOrder byteOrder, size_t baseOffset) : byteOrder_(byteOrder), baseOffset_(baseOffset) {
  539|  12.7k|  }
_ZN5Exiv28Internal10TiffFinderC2EtNS_5IfdIdE:
  142|   127k|  constexpr TiffFinder(uint16_t tag, IfdId group) : tag_(tag), group_(group) {
  143|   127k|  }
_ZN5Exiv28Internal11TiffVisitorC2Ev:
   63|   152k|  TiffVisitor() = default;
_ZNK5Exiv28Internal10TiffFinder6resultEv:
  181|   127k|  [[nodiscard]] TiffComponent* result() const {
  182|   127k|    return tiffComponent_;
  183|   127k|  }
_ZNK5Exiv28Internal11TiffEncoder9byteOrderEv:
  458|   134k|  [[nodiscard]] ByteOrder byteOrder() const {
  459|   134k|    return byteOrder_;
  460|   134k|  }
_ZNK5Exiv28Internal11TiffEncoder11writeMethodEv:
  467|  17.8k|  [[nodiscard]] WriteMethod writeMethod() const {
  468|  17.8k|    return writeMethod_;
  469|  17.8k|  }
_ZNK5Exiv28Internal11TiffRwState9byteOrderEv:
  548|  4.14M|  [[nodiscard]] ByteOrder byteOrder() const {
  549|  4.14M|    return byteOrder_;
  550|  4.14M|  }
_ZNK5Exiv28Internal11TiffRwState10baseOffsetEv:
  562|   627k|  [[nodiscard]] size_t baseOffset() const {
  563|   627k|    return baseOffset_;
  564|   627k|  }

_ZN5Exiv28TypeInfo8typeSizeENS_6TypeIdE:
   86|  2.45M|size_t TypeInfo::typeSize(TypeId typeId) {
   87|  2.45M|  if (auto tit = Exiv2::find(typeInfoTable, typeId))
  ------------------
  |  Branch (87:12): [True: 1.69M, False: 752k]
  ------------------
   88|  1.69M|    return tit->size_;
   89|   752k|  return 0;
   90|  2.45M|}
_ZN5Exiv27DataBufC2Em:
   92|  1.14M|DataBuf::DataBuf(size_t size) : pData_(size) {
   93|  1.14M|}
_ZN5Exiv27DataBufC2EPKhm:
   95|  52.1k|DataBuf::DataBuf(const byte* pData, size_t size) : pData_(pData, pData + size) {
   96|  52.1k|}
_ZN5Exiv27DataBuf5allocEm:
   98|  10.1k|void DataBuf::alloc(size_t size) {
   99|  10.1k|  pData_.resize(size);
  100|  10.1k|}
_ZN5Exiv27DataBuf6resizeEm:
  102|   446k|void DataBuf::resize(size_t size) {
  103|   446k|  pData_.resize(size);
  104|   446k|}
_ZN5Exiv27DataBuf5resetEv:
  106|  27.4k|void DataBuf::reset() {
  107|  27.4k|  pData_.clear();
  108|  27.4k|}
_ZNK5Exiv27DataBuf10read_uint8Em:
  110|  1.68M|uint8_t Exiv2::DataBuf::read_uint8(size_t offset) const {
  111|  1.68M|  if (offset >= pData_.size()) {
  ------------------
  |  Branch (111:7): [True: 0, False: 1.68M]
  ------------------
  112|      0|    throw std::out_of_range("Overflow in Exiv2::DataBuf::read_uint8");
  113|      0|  }
  114|  1.68M|  return pData_[offset];
  115|  1.68M|}
_ZN5Exiv27DataBuf11write_uint8Emh:
  117|  76.9k|void Exiv2::DataBuf::write_uint8(size_t offset, uint8_t x) {
  118|  76.9k|  if (offset >= pData_.size()) {
  ------------------
  |  Branch (118:7): [True: 0, False: 76.9k]
  ------------------
  119|      0|    throw std::out_of_range("Overflow in Exiv2::DataBuf::write_uint8");
  120|      0|  }
  121|  76.9k|  pData_[offset] = x;
  122|  76.9k|}
_ZNK5Exiv27DataBuf11read_uint16EmNS_9ByteOrderE:
  124|   977k|uint16_t Exiv2::DataBuf::read_uint16(size_t offset, ByteOrder byteOrder) const {
  125|   977k|  if (pData_.size() < 2 || offset > (pData_.size() - 2)) {
  ------------------
  |  Branch (125:7): [True: 0, False: 977k]
  |  Branch (125:28): [True: 1, False: 977k]
  ------------------
  126|      1|    throw std::out_of_range("Overflow in Exiv2::DataBuf::read_uint16");
  127|      1|  }
  128|   977k|  return getUShort(&pData_[offset], byteOrder);
  129|   977k|}
_ZN5Exiv27DataBuf12write_uint16EmtNS_9ByteOrderE:
  131|  4.40k|void Exiv2::DataBuf::write_uint16(size_t offset, uint16_t x, ByteOrder byteOrder) {
  132|  4.40k|  if (pData_.size() < 2 || offset > (pData_.size() - 2)) {
  ------------------
  |  Branch (132:7): [True: 0, False: 4.40k]
  |  Branch (132:28): [True: 0, False: 4.40k]
  ------------------
  133|      0|    throw std::out_of_range("Overflow in Exiv2::DataBuf::write_uint16");
  134|      0|  }
  135|  4.40k|  us2Data(&pData_[offset], x, byteOrder);
  136|  4.40k|}
_ZNK5Exiv27DataBuf11read_uint32EmNS_9ByteOrderE:
  138|  1.95M|uint32_t Exiv2::DataBuf::read_uint32(size_t offset, ByteOrder byteOrder) const {
  139|  1.95M|  if (pData_.size() < 4 || offset > (pData_.size() - 4)) {
  ------------------
  |  Branch (139:7): [True: 1, False: 1.95M]
  |  Branch (139:28): [True: 3, False: 1.95M]
  ------------------
  140|      4|    throw std::out_of_range("Overflow in Exiv2::DataBuf::read_uint32");
  141|      4|  }
  142|  1.95M|  return getULong(&pData_[offset], byteOrder);
  143|  1.95M|}
_ZN5Exiv27DataBuf12write_uint32EmjNS_9ByteOrderE:
  145|  4.40k|void Exiv2::DataBuf::write_uint32(size_t offset, uint32_t x, ByteOrder byteOrder) {
  146|  4.40k|  if (pData_.size() < 4 || offset > (pData_.size() - 4)) {
  ------------------
  |  Branch (146:7): [True: 0, False: 4.40k]
  |  Branch (146:28): [True: 0, False: 4.40k]
  ------------------
  147|      0|    throw std::out_of_range("Overflow in Exiv2::DataBuf::write_uint32");
  148|      0|  }
  149|  4.40k|  ul2Data(&pData_[offset], x, byteOrder);
  150|  4.40k|}
_ZNK5Exiv27DataBuf11read_uint64EmNS_9ByteOrderE:
  152|  2.76k|uint64_t Exiv2::DataBuf::read_uint64(size_t offset, ByteOrder byteOrder) const {
  153|  2.76k|  if (pData_.size() < 8 || offset > (pData_.size() - 8)) {
  ------------------
  |  Branch (153:7): [True: 0, False: 2.76k]
  |  Branch (153:28): [True: 0, False: 2.76k]
  ------------------
  154|      0|    throw std::out_of_range("Overflow in Exiv2::DataBuf::read_uint64");
  155|      0|  }
  156|  2.76k|  return getULongLong(&pData_[offset], byteOrder);
  157|  2.76k|}
_ZNK5Exiv27DataBuf8cmpBytesEmPKvm:
  166|   258k|int Exiv2::DataBuf::cmpBytes(size_t offset, const void* buf, size_t bufsize) const {
  167|   258k|  if (pData_.size() < bufsize || offset > pData_.size() - bufsize) {
  ------------------
  |  Branch (167:7): [True: 0, False: 258k]
  |  Branch (167:34): [True: 0, False: 258k]
  ------------------
  168|      0|    throw std::out_of_range("Overflow in Exiv2::DataBuf::cmpBytes");
  169|      0|  }
  170|   258k|  return memcmp(&pData_[offset], buf, bufsize);
  171|   258k|}
_ZN5Exiv27DataBuf4dataEm:
  173|  17.9M|byte* Exiv2::DataBuf::data(size_t offset) {
  174|  17.9M|  return const_cast<byte*>(c_data(offset));
  175|  17.9M|}
_ZNK5Exiv27DataBuf6c_dataEm:
  177|  18.1M|const byte* Exiv2::DataBuf::c_data(size_t offset) const {
  178|  18.1M|  if (pData_.empty() || offset == pData_.size()) {
  ------------------
  |  Branch (178:7): [True: 20.2k, False: 18.1M]
  |  Branch (178:25): [True: 483, False: 18.1M]
  ------------------
  179|  20.7k|    return nullptr;
  180|  20.7k|  }
  181|  18.1M|  if (offset > pData_.size()) {
  ------------------
  |  Branch (181:7): [True: 0, False: 18.1M]
  ------------------
  182|      0|    throw std::out_of_range("Overflow in Exiv2::DataBuf::c_data");
  183|      0|  }
  184|  18.1M|  return &pData_[offset];
  185|  18.1M|}
_ZNK5Exiv27DataBuf5c_strEm:
  187|  67.1k|const char* Exiv2::DataBuf::c_str(size_t offset) const {
  188|  67.1k|  return reinterpret_cast<const char*>(c_data(offset));
  189|  67.1k|}
_ZN5Exiv2lsERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEERKNS0_4pairIiiEE:
  210|  9.44k|std::ostream& operator<<(std::ostream& os, const Rational& r) {
  211|  9.44k|  return os << r.first << "/" << r.second;
  212|  9.44k|}
_ZN5Exiv2lsERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEERKNS0_4pairIjjEE:
  239|  4.28k|std::ostream& operator<<(std::ostream& os, const URational& r) {
  240|  4.28k|  return os << r.first << "/" << r.second;
  241|  4.28k|}
_ZN5Exiv29getUShortEPKhNS_9ByteOrderE:
  247|  3.86M|uint16_t getUShort(const byte* buf, ByteOrder byteOrder) {
  248|  3.86M|  return getUShort(makeSliceUntil(buf, 2), byteOrder);
  249|  3.86M|}
_ZN5Exiv28getULongEPKhNS_9ByteOrderE:
  251|  7.40M|uint32_t getULong(const byte* buf, ByteOrder byteOrder) {
  252|  7.40M|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (252:7): [True: 2.24M, False: 5.15M]
  ------------------
  253|  2.24M|    return buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
  254|  2.24M|  }
  255|  5.15M|  return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
  256|  7.40M|}
_ZN5Exiv212getULongLongEPKhNS_9ByteOrderE:
  258|  33.1k|uint64_t getULongLong(const byte* buf, ByteOrder byteOrder) {
  259|  33.1k|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (259:7): [True: 2.46k, False: 30.7k]
  ------------------
  260|  2.46k|    return static_cast<uint64_t>(buf[7]) << 56 | static_cast<uint64_t>(buf[6]) << 48 |
  261|  2.46k|           static_cast<uint64_t>(buf[5]) << 40 | static_cast<uint64_t>(buf[4]) << 32 |
  262|  2.46k|           static_cast<uint64_t>(buf[3]) << 24 | static_cast<uint64_t>(buf[2]) << 16 |
  263|  2.46k|           static_cast<uint64_t>(buf[1]) << 8 | static_cast<uint64_t>(buf[0]);
  264|  2.46k|  }
  265|  30.7k|  return static_cast<uint64_t>(buf[0]) << 56 | static_cast<uint64_t>(buf[1]) << 48 |
  266|  30.7k|         static_cast<uint64_t>(buf[2]) << 40 | static_cast<uint64_t>(buf[3]) << 32 |
  267|  30.7k|         static_cast<uint64_t>(buf[4]) << 24 | static_cast<uint64_t>(buf[5]) << 16 |
  268|  30.7k|         static_cast<uint64_t>(buf[6]) << 8 | static_cast<uint64_t>(buf[7]);
  269|  33.1k|}
_ZN5Exiv212getURationalEPKhNS_9ByteOrderE:
  271|  1.39M|URational getURational(const byte* buf, ByteOrder byteOrder) {
  272|  1.39M|  uint32_t nominator = getULong(buf, byteOrder);
  273|  1.39M|  uint32_t denominator = getULong(buf + 4, byteOrder);
  274|  1.39M|  return {nominator, denominator};
  275|  1.39M|}
_ZN5Exiv28getShortEPKhNS_9ByteOrderE:
  277|   892k|int16_t getShort(const byte* buf, ByteOrder byteOrder) {
  278|   892k|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (278:7): [True: 700k, False: 192k]
  ------------------
  279|   700k|    return buf[1] << 8 | buf[0];
  280|   700k|  }
  281|   192k|  return buf[0] << 8 | buf[1];
  282|   892k|}
_ZN5Exiv27getLongEPKhNS_9ByteOrderE:
  284|   324k|int32_t getLong(const byte* buf, ByteOrder byteOrder) {
  285|   324k|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (285:7): [True: 170k, False: 153k]
  ------------------
  286|   170k|    return buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
  287|   170k|  }
  288|   153k|  return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
  289|   324k|}
_ZN5Exiv211getRationalEPKhNS_9ByteOrderE:
  291|  28.4k|Rational getRational(const byte* buf, ByteOrder byteOrder) {
  292|  28.4k|  int32_t nominator = getLong(buf, byteOrder);
  293|  28.4k|  int32_t denominator = getLong(buf + 4, byteOrder);
  294|  28.4k|  return {nominator, denominator};
  295|  28.4k|}
_ZN5Exiv28getFloatEPKhNS_9ByteOrderE:
  297|  47.5k|float getFloat(const byte* buf, ByteOrder byteOrder) {
  298|       |  // This algorithm assumes that the internal representation of the float
  299|       |  // type is the 4-byte IEEE 754 binary32 format, which is common but not
  300|       |  // required by the C++ standard.
  301|  47.5k|#ifdef __cpp_lib_bit_cast
  302|  47.5k|  return std::bit_cast<float>(getULong(buf, byteOrder));
  303|       |#else
  304|       |  union {
  305|       |    uint32_t ul_;
  306|       |    float f_;
  307|       |  } u;
  308|       |  u.ul_ = getULong(buf, byteOrder);
  309|       |  return u.f_;
  310|       |#endif
  311|  47.5k|}
_ZN5Exiv29getDoubleEPKhNS_9ByteOrderE:
  313|   342k|double getDouble(const byte* buf, ByteOrder byteOrder) {
  314|       |  // This algorithm assumes that the internal representation of the double
  315|       |  // type is the 8-byte IEEE 754 binary64 format, which is common but not
  316|       |  // required by the C++ standard.
  317|   342k|#ifdef __cpp_lib_bit_cast
  318|   342k|  if (byteOrder == littleEndian)
  ------------------
  |  Branch (318:7): [True: 24.8k, False: 317k]
  ------------------
  319|  24.8k|    return std::bit_cast<double>(static_cast<uint64_t>(buf[7]) << 56 | static_cast<uint64_t>(buf[6]) << 48 |
  320|  24.8k|                                 static_cast<uint64_t>(buf[5]) << 40 | static_cast<uint64_t>(buf[4]) << 32 |
  321|  24.8k|                                 static_cast<uint64_t>(buf[3]) << 24 | static_cast<uint64_t>(buf[2]) << 16 |
  322|  24.8k|                                 static_cast<uint64_t>(buf[1]) << 8 | static_cast<uint64_t>(buf[0]));
  323|   317k|  return std::bit_cast<double>(static_cast<uint64_t>(buf[0]) << 56 | static_cast<uint64_t>(buf[1]) << 48 |
  324|   317k|                               static_cast<uint64_t>(buf[2]) << 40 | static_cast<uint64_t>(buf[3]) << 32 |
  325|   317k|                               static_cast<uint64_t>(buf[4]) << 24 | static_cast<uint64_t>(buf[5]) << 16 |
  326|   317k|                               static_cast<uint64_t>(buf[6]) << 8 | static_cast<uint64_t>(buf[7]));
  327|       |#else
  328|       |  union {
  329|       |    uint64_t ull_;
  330|       |    double d_;
  331|       |  } u;
  332|       |  u.ull_ = 0;
  333|       |  if (byteOrder == littleEndian) {
  334|       |    u.ull_ = static_cast<uint64_t>(buf[7]) << 56 | static_cast<uint64_t>(buf[6]) << 48 |
  335|       |             static_cast<uint64_t>(buf[5]) << 40 | static_cast<uint64_t>(buf[4]) << 32 |
  336|       |             static_cast<uint64_t>(buf[3]) << 24 | static_cast<uint64_t>(buf[2]) << 16 |
  337|       |             static_cast<uint64_t>(buf[1]) << 8 | static_cast<uint64_t>(buf[0]);
  338|       |  } else {
  339|       |    u.ull_ = static_cast<uint64_t>(buf[0]) << 56 | static_cast<uint64_t>(buf[1]) << 48 |
  340|       |             static_cast<uint64_t>(buf[2]) << 40 | static_cast<uint64_t>(buf[3]) << 32 |
  341|       |             static_cast<uint64_t>(buf[4]) << 24 | static_cast<uint64_t>(buf[5]) << 16 |
  342|       |             static_cast<uint64_t>(buf[6]) << 8 | static_cast<uint64_t>(buf[7]);
  343|       |  }
  344|       |  return u.d_;
  345|       |#endif
  346|   342k|}
_ZN5Exiv27us2DataEPhtNS_9ByteOrderE:
  348|   358k|size_t us2Data(byte* buf, uint16_t s, ByteOrder byteOrder) {
  349|   358k|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (349:7): [True: 358k, False: 580]
  ------------------
  350|   358k|    buf[0] = static_cast<byte>(s & 0x00ffU);
  351|   358k|    buf[1] = static_cast<byte>((s & 0xff00U) >> 8);
  352|   358k|  } else {
  353|    580|    buf[0] = static_cast<byte>((s & 0xff00U) >> 8);
  354|    580|    buf[1] = static_cast<byte>(s & 0x00ffU);
  355|    580|  }
  356|   358k|  return 2;
  357|   358k|}
_ZN5Exiv27ul2DataEPhjNS_9ByteOrderE:
  359|  1.63M|size_t ul2Data(byte* buf, uint32_t l, ByteOrder byteOrder) {
  360|  1.63M|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (360:7): [True: 1.62M, False: 1.14k]
  ------------------
  361|  1.62M|    buf[0] = static_cast<byte>(l & 0x000000ffU);
  362|  1.62M|    buf[1] = static_cast<byte>((l & 0x0000ff00U) >> 8);
  363|  1.62M|    buf[2] = static_cast<byte>((l & 0x00ff0000U) >> 16);
  364|  1.62M|    buf[3] = static_cast<byte>((l & 0xff000000U) >> 24);
  365|  1.62M|  } else {
  366|  1.14k|    buf[0] = static_cast<byte>((l & 0xff000000U) >> 24);
  367|  1.14k|    buf[1] = static_cast<byte>((l & 0x00ff0000U) >> 16);
  368|  1.14k|    buf[2] = static_cast<byte>((l & 0x0000ff00U) >> 8);
  369|  1.14k|    buf[3] = static_cast<byte>(l & 0x000000ffU);
  370|  1.14k|  }
  371|  1.63M|  return 4;
  372|  1.63M|}
_ZN5Exiv27ur2DataEPhNSt3__14pairIjjEENS_9ByteOrderE:
  389|   420k|size_t ur2Data(byte* buf, URational l, ByteOrder byteOrder) {
  390|   420k|  size_t o = ul2Data(buf, l.first, byteOrder);
  391|   420k|  o += ul2Data(buf + o, l.second, byteOrder);
  392|   420k|  return o;
  393|   420k|}
_ZN5Exiv26s2DataEPhsNS_9ByteOrderE:
  395|  7.22k|size_t s2Data(byte* buf, int16_t s, ByteOrder byteOrder) {
  396|  7.22k|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (396:7): [True: 7.00k, False: 227]
  ------------------
  397|  7.00k|    buf[0] = static_cast<byte>(s & 0x00ffU);
  398|  7.00k|    buf[1] = static_cast<byte>((s & 0xff00U) >> 8);
  399|  7.00k|  } else {
  400|    227|    buf[0] = static_cast<byte>((s & 0xff00U) >> 8);
  401|    227|    buf[1] = static_cast<byte>(s & 0x00ffU);
  402|    227|  }
  403|  7.22k|  return 2;
  404|  7.22k|}
_ZN5Exiv26l2DataEPhiNS_9ByteOrderE:
  406|   313k|size_t l2Data(byte* buf, int32_t l, ByteOrder byteOrder) {
  407|   313k|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (407:7): [True: 312k, False: 797]
  ------------------
  408|   312k|    buf[0] = static_cast<byte>(l & 0x000000ffU);
  409|   312k|    buf[1] = static_cast<byte>((l & 0x0000ff00U) >> 8);
  410|   312k|    buf[2] = static_cast<byte>((l & 0x00ff0000U) >> 16);
  411|   312k|    buf[3] = static_cast<byte>((l & 0xff000000U) >> 24);
  412|   312k|  } else {
  413|    797|    buf[0] = static_cast<byte>((l & 0xff000000U) >> 24);
  414|    797|    buf[1] = static_cast<byte>((l & 0x00ff0000U) >> 16);
  415|    797|    buf[2] = static_cast<byte>((l & 0x0000ff00U) >> 8);
  416|    797|    buf[3] = static_cast<byte>(l & 0x000000ffU);
  417|    797|  }
  418|   313k|  return 4;
  419|   313k|}
_ZN5Exiv26r2DataEPhNSt3__14pairIiiEENS_9ByteOrderE:
  421|  22.0k|size_t r2Data(byte* buf, Rational l, ByteOrder byteOrder) {
  422|  22.0k|  size_t o = l2Data(buf, l.first, byteOrder);
  423|  22.0k|  o += l2Data(buf + o, l.second, byteOrder);
  424|  22.0k|  return o;
  425|  22.0k|}
_ZN5Exiv26f2DataEPhfNS_9ByteOrderE:
  427|  6.37k|size_t f2Data(byte* buf, float f, ByteOrder byteOrder) {
  428|       |  // This algorithm assumes that the internal representation of the float
  429|       |  // type is the 4-byte IEEE 754 binary32 format, which is common but not
  430|       |  // required by the C++ standard.
  431|  6.37k|#ifdef __cpp_lib_bit_cast
  432|  6.37k|  return ul2Data(buf, std::bit_cast<uint32_t>(f), byteOrder);
  433|       |#else
  434|       |  union {
  435|       |    uint32_t ul_;
  436|       |    float f_;
  437|       |  } u;
  438|       |  u.f_ = f;
  439|       |  return ul2Data(buf, u.ul_, byteOrder);
  440|       |#endif
  441|  6.37k|}
_ZN5Exiv26d2DataEPhdNS_9ByteOrderE:
  443|  48.2k|size_t d2Data(byte* buf, double d, ByteOrder byteOrder) {
  444|       |  // This algorithm assumes that the internal representation of the double
  445|       |  // type is the 8-byte IEEE 754 binary64 format, which is common but not
  446|       |  // required by the C++ standard.
  447|  48.2k|  union {
  448|  48.2k|    uint64_t ull_;
  449|  48.2k|    double d_;
  450|  48.2k|  } u;
  451|  48.2k|  u.d_ = d;
  452|  48.2k|  uint64_t m = 0xff;
  453|  48.2k|  if (byteOrder == littleEndian) {
  ------------------
  |  Branch (453:7): [True: 47.9k, False: 308]
  ------------------
  454|  47.9k|    buf[0] = static_cast<byte>(u.ull_ & m);
  455|  47.9k|    buf[1] = static_cast<byte>((u.ull_ & (m << 8)) >> 8);
  456|  47.9k|    buf[2] = static_cast<byte>((u.ull_ & (m << 16)) >> 16);
  457|  47.9k|    buf[3] = static_cast<byte>((u.ull_ & (m << 24)) >> 24);
  458|  47.9k|    buf[4] = static_cast<byte>((u.ull_ & (m << 32)) >> 32);
  459|  47.9k|    buf[5] = static_cast<byte>((u.ull_ & (m << 40)) >> 40);
  460|  47.9k|    buf[6] = static_cast<byte>((u.ull_ & (m << 48)) >> 48);
  461|  47.9k|    buf[7] = static_cast<byte>((u.ull_ & (m << 56)) >> 56);
  462|  47.9k|  } else {
  463|    308|    buf[0] = static_cast<byte>((u.ull_ & (m << 56)) >> 56);
  464|    308|    buf[1] = static_cast<byte>((u.ull_ & (m << 48)) >> 48);
  465|    308|    buf[2] = static_cast<byte>((u.ull_ & (m << 40)) >> 40);
  466|    308|    buf[3] = static_cast<byte>((u.ull_ & (m << 32)) >> 32);
  467|    308|    buf[4] = static_cast<byte>((u.ull_ & (m << 24)) >> 24);
  468|    308|    buf[5] = static_cast<byte>((u.ull_ & (m << 16)) >> 16);
  469|    308|    buf[6] = static_cast<byte>((u.ull_ & (m << 8)) >> 8);
  470|    308|    buf[7] = static_cast<byte>(u.ull_ & m);
  471|    308|  }
  472|  48.2k|  return 8;
  473|  48.2k|}
_ZN5Exiv219floatToRationalCastEf:
  651|     11|Rational floatToRationalCast(float f) {
  652|       |  // Convert f to double because it simplifies the range checks
  653|       |  // below. (All int values can be losslessly converted to double, but
  654|       |  // sometimes get rounded when converted to float.)
  655|     11|  const double d = f;
  656|       |  // Beware: primitive conversion algorithm
  657|     11|  int32_t den;
  658|     11|  if (std::fabs(d) <= std::numeric_limits<int32_t>::max() / 1000000) {
  ------------------
  |  Branch (658:7): [True: 11, False: 0]
  ------------------
  659|     11|    den = 1000000;
  660|     11|  } else if (std::fabs(d) <= std::numeric_limits<int32_t>::max() / 10000) {
  ------------------
  |  Branch (660:14): [True: 0, False: 0]
  ------------------
  661|      0|    den = 10000;
  662|      0|  } else if (std::fabs(d) <= std::numeric_limits<int32_t>::max() / 100) {
  ------------------
  |  Branch (662:14): [True: 0, False: 0]
  ------------------
  663|      0|    den = 100;
  664|      0|  } else if (std::fabs(d) <= std::numeric_limits<int32_t>::max()) {
  ------------------
  |  Branch (664:14): [True: 0, False: 0]
  ------------------
  665|      0|    den = 1;
  666|      0|  } else {
  667|      0|    return {d > 0 ? 1 : -1, 0};
  ------------------
  |  Branch (667:13): [True: 0, False: 0]
  ------------------
  668|      0|  }
  669|     11|  const auto nom = static_cast<int32_t>(std::lround(d * den));
  670|     11|  const int32_t g = std::gcd(nom, den);
  671|       |
  672|     11|  return {nom / g, den / g};
  673|     11|}
types.cpp:_ZNK12_GLOBAL__N_113TypeInfoTableeqEN5Exiv26TypeIdE:
   34|  24.5M|  bool operator==(Exiv2::TypeId typeId) const {
   35|  24.5M|    return typeId_ == typeId;
   36|  24.5M|  }

_ZN5Exiv28Internal5upperENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
    8|  28.8k|std::string upper(std::string_view str) {
    9|  28.8k|  std::string result;
   10|  28.8k|  result.reserve(str.size());
   11|  28.8k|  for (auto c : str)
  ------------------
  |  Branch (11:15): [True: 115k, False: 28.8k]
  ------------------
   12|   115k|    result.push_back(std::toupper(static_cast<unsigned char>(c)));
   13|  28.8k|  return result;
   14|  28.8k|}

_ZN5Exiv28Internal8containsIPKcEEbNSt3__117basic_string_viewIcNS4_11char_traitsIcEEEET_:
    9|  6.56k|constexpr bool contains(std::string_view s, auto c) {
   10|       |#ifdef __cpp_lib_string_contains
   11|       |  return s.contains(c);
   12|       |#else
   13|  6.56k|  return s.find(c) != std::string_view::npos;
   14|  6.56k|#endif
   15|  6.56k|}

_ZN5Exiv25ValueC2ENS_6TypeIdE:
   19|  2.11M|Value::Value(TypeId typeId) : type_(typeId) {
   20|  2.11M|}
_ZN5Exiv25Value6createENS_6TypeIdE:
   22|  1.16M|Value::UniquePtr Value::create(TypeId typeId) {
   23|  1.16M|  switch (typeId) {
   24|      0|    case invalidTypeId:
  ------------------
  |  Branch (24:5): [True: 0, False: 1.16M]
  ------------------
   25|  3.11k|    case signedByte:
  ------------------
  |  Branch (25:5): [True: 3.11k, False: 1.16M]
  ------------------
   26|   238k|    case unsignedByte:
  ------------------
  |  Branch (26:5): [True: 235k, False: 932k]
  ------------------
   27|   238k|      return std::make_unique<DataValue>(typeId);
   28|  13.6k|    case asciiString:
  ------------------
  |  Branch (28:5): [True: 13.6k, False: 1.15M]
  ------------------
   29|  13.6k|      return std::make_unique<AsciiValue>();
   30|   336k|    case unsignedShort:
  ------------------
  |  Branch (30:5): [True: 336k, False: 830k]
  ------------------
   31|   336k|      return std::make_unique<ValueType<uint16_t>>();
   32|  34.5k|    case unsignedLong:
  ------------------
  |  Branch (32:5): [True: 34.5k, False: 1.13M]
  ------------------
   33|  37.6k|    case tiffIfd:
  ------------------
  |  Branch (33:5): [True: 3.03k, False: 1.16M]
  ------------------
   34|  37.6k|      return std::make_unique<ValueType<uint32_t>>(typeId);
   35|  6.41k|    case unsignedRational:
  ------------------
  |  Branch (35:5): [True: 6.41k, False: 1.16M]
  ------------------
   36|  6.41k|      return std::make_unique<ValueType<URational>>();
   37|  4.01k|    case undefined:
  ------------------
  |  Branch (37:5): [True: 4.01k, False: 1.16M]
  ------------------
   38|  4.01k|      return std::make_unique<DataValue>();
   39|  9.10k|    case signedShort:
  ------------------
  |  Branch (39:5): [True: 9.10k, False: 1.15M]
  ------------------
   40|  9.10k|      return std::make_unique<ValueType<int16_t>>();
   41|  8.81k|    case signedLong:
  ------------------
  |  Branch (41:5): [True: 8.81k, False: 1.15M]
  ------------------
   42|  8.81k|      return std::make_unique<ValueType<int32_t>>();
   43|  1.93k|    case signedRational:
  ------------------
  |  Branch (43:5): [True: 1.93k, False: 1.16M]
  ------------------
   44|  1.93k|      return std::make_unique<ValueType<Rational>>();
   45|  2.04k|    case tiffFloat:
  ------------------
  |  Branch (45:5): [True: 2.04k, False: 1.16M]
  ------------------
   46|  2.04k|      return std::make_unique<ValueType<float>>();
   47|  5.26k|    case tiffDouble:
  ------------------
  |  Branch (47:5): [True: 5.26k, False: 1.16M]
  ------------------
   48|  5.26k|      return std::make_unique<ValueType<double>>();
   49|  27.8k|    case string:
  ------------------
  |  Branch (49:5): [True: 27.8k, False: 1.13M]
  ------------------
   50|  27.8k|      return std::make_unique<StringValue>();
   51|  6.80k|    case date:
  ------------------
  |  Branch (51:5): [True: 6.80k, False: 1.16M]
  ------------------
   52|  6.80k|      return std::make_unique<DateValue>();
   53|  9.17k|    case time:
  ------------------
  |  Branch (53:5): [True: 9.17k, False: 1.15M]
  ------------------
   54|  9.17k|      return std::make_unique<TimeValue>();
   55|    344|    case comment:
  ------------------
  |  Branch (55:5): [True: 344, False: 1.16M]
  ------------------
   56|    344|      return std::make_unique<CommentValue>();
   57|  44.4k|    case xmpText:
  ------------------
  |  Branch (57:5): [True: 44.4k, False: 1.12M]
  ------------------
   58|  44.4k|      return std::make_unique<XmpTextValue>();
   59|      0|    case xmpBag:
  ------------------
  |  Branch (59:5): [True: 0, False: 1.16M]
  ------------------
   60|  12.2k|    case xmpSeq:
  ------------------
  |  Branch (60:5): [True: 12.2k, False: 1.15M]
  ------------------
   61|  12.2k|    case xmpAlt:
  ------------------
  |  Branch (61:5): [True: 0, False: 1.16M]
  ------------------
   62|  12.2k|      return std::make_unique<XmpArrayValue>(typeId);
   63|      0|    case langAlt:
  ------------------
  |  Branch (63:5): [True: 0, False: 1.16M]
  ------------------
   64|      0|      return std::make_unique<LangAltValue>();
   65|   402k|    default:
  ------------------
  |  Branch (65:5): [True: 402k, False: 765k]
  ------------------
   66|   402k|      return std::make_unique<DataValue>(typeId);
   67|  1.16M|  }
   68|  1.16M|}  // Value::create
_ZN5Exiv25Value11setDataAreaEPKhm:
   70|  2.50k|int Value::setDataArea(const byte* /*buf*/, size_t /*len*/) {
   71|  2.50k|  return -1;
   72|  2.50k|}
_ZNK5Exiv25Value8toStringEv:
   74|  19.5k|std::string Value::toString() const {
   75|  19.5k|  std::ostringstream os;
   76|  19.5k|  write(os);
   77|  19.5k|  ok_ = !os.fail();
   78|  19.5k|  return os.str();
   79|  19.5k|}
_ZNK5Exiv25Value12sizeDataAreaEv:
   85|  22.5k|size_t Value::sizeDataArea() const {
   86|  22.5k|  return 0;
   87|  22.5k|}
_ZNK5Exiv25Value8dataAreaEv:
   89|     17|DataBuf Value::dataArea() const {
   90|     17|  return {nullptr, 0};
   91|     17|}
_ZN5Exiv29DataValueC2ENS_6TypeIdE:
   93|   645k|DataValue::DataValue(TypeId typeId) : Value(typeId) {
   94|   645k|}
_ZNK5Exiv29DataValue5countEv:
  100|   937k|size_t DataValue::count() const {
  101|   937k|  return size();
  102|   937k|}
_ZN5Exiv29DataValue4readEPKhmNS_9ByteOrderE:
  104|   645k|int DataValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) {
  105|       |  // byteOrder not needed
  106|   645k|  value_.assign(buf, buf + len);
  107|   645k|  return 0;
  108|   645k|}
_ZNK5Exiv29DataValue4copyEPhNS_9ByteOrderE:
  122|   123k|size_t DataValue::copy(byte* buf, ByteOrder /*byteOrder*/) const {
  123|       |  // byteOrder not needed
  124|   123k|  return std::copy(value_.begin(), value_.end(), buf) - buf;
  125|   123k|}
_ZNK5Exiv29DataValue4sizeEv:
  127|  1.28M|size_t DataValue::size() const {
  128|  1.28M|  return value_.size();
  129|  1.28M|}
_ZNK5Exiv29DataValue6clone_Ev:
  131|  1.76M|DataValue* DataValue::clone_() const {
  132|  1.76M|  return new DataValue(*this);
  133|  1.76M|}
_ZNK5Exiv29DataValue5writeERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE:
  135|  2.14k|std::ostream& DataValue::write(std::ostream& os) const {
  136|  2.14k|  if (!value_.empty()) {
  ------------------
  |  Branch (136:7): [True: 1.88k, False: 268]
  ------------------
  137|  1.88k|    std::copy(value_.begin(), value_.end() - 1, std::ostream_iterator<int>(os, " "));
  138|  1.88k|    os << static_cast<int>(value_.back());
  139|  1.88k|  }
  140|  2.14k|  return os;
  141|  2.14k|}
_ZNK5Exiv29DataValue7toInt64Em:
  148|  39.4k|int64_t DataValue::toInt64(size_t n) const {
  149|  39.4k|  ok_ = true;
  150|  39.4k|  return value_.at(n);
  151|  39.4k|}
_ZNK5Exiv29DataValue8toUint32Em:
  153|  98.5k|uint32_t DataValue::toUint32(size_t n) const {
  154|  98.5k|  ok_ = true;
  155|  98.5k|  return value_.at(n);
  156|  98.5k|}
_ZN5Exiv215StringValueBase4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  172|  3.25k|int StringValueBase::read(const std::string& buf) {
  173|  3.25k|  value_ = buf;
  174|  3.25k|  return 0;
  175|  3.25k|}
_ZN5Exiv215StringValueBase4readEPKhmNS_9ByteOrderE:
  177|  37.5k|int StringValueBase::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) {
  178|       |  // byteOrder not needed
  179|  37.5k|  if (buf)
  ------------------
  |  Branch (179:7): [True: 37.5k, False: 0]
  ------------------
  180|  37.5k|    value_ = std::string(reinterpret_cast<const char*>(buf), len);
  181|  37.5k|  return 0;
  182|  37.5k|}
_ZNK5Exiv215StringValueBase4copyEPhNS_9ByteOrderE:
  184|  2.41k|size_t StringValueBase::copy(byte* buf, ByteOrder /*byteOrder*/) const {
  185|  2.41k|  if (value_.empty())
  ------------------
  |  Branch (185:7): [True: 1.00k, False: 1.40k]
  ------------------
  186|  1.00k|    return 0;
  187|       |  // byteOrder not needed
  188|  1.40k|  return value_.copy(reinterpret_cast<char*>(buf), value_.size());
  189|  2.41k|}
_ZNK5Exiv215StringValueBase5countEv:
  191|  69.0k|size_t StringValueBase::count() const {
  192|  69.0k|  return size();
  193|  69.0k|}
_ZNK5Exiv215StringValueBase4sizeEv:
  195|  74.9k|size_t StringValueBase::size() const {
  196|  74.9k|  return value_.size();
  197|  74.9k|}
_ZNK5Exiv215StringValueBase7toInt64Em:
  203|  48.3k|int64_t StringValueBase::toInt64(size_t n) const {
  204|  48.3k|  ok_ = true;
  205|  48.3k|  return value_.at(n);
  206|  48.3k|}
_ZNK5Exiv215StringValueBase8toUint32Em:
  208|  5.78k|uint32_t StringValueBase::toUint32(size_t n) const {
  209|  5.78k|  ok_ = true;
  210|  5.78k|  return value_.at(n);
  211|  5.78k|}
_ZN5Exiv211StringValueC2Ev:
  223|  27.8k|StringValue::StringValue() : StringValueBase(string) {
  224|  27.8k|}
_ZNK5Exiv211StringValue6clone_Ev:
  229|  55.4k|StringValue* StringValue::clone_() const {
  230|  55.4k|  return new StringValue(*this);
  231|  55.4k|}
_ZN5Exiv210AsciiValueC2Ev:
  233|  13.7k|AsciiValue::AsciiValue() : StringValueBase(asciiString) {
  234|  13.7k|}
_ZN5Exiv210AsciiValue4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  239|  2.54k|int AsciiValue::read(const std::string& buf) {
  240|  2.54k|  value_ = buf;
  241|       |  // ensure count>0 and nul terminated # https://github.com/Exiv2/exiv2/issues/1484
  242|  2.54k|  if (value_.empty() || value_.back() != '\0') {
  ------------------
  |  Branch (242:7): [True: 6, False: 2.53k]
  |  Branch (242:25): [True: 2.53k, False: 0]
  ------------------
  243|  2.54k|    value_ += '\0';
  244|  2.54k|  }
  245|  2.54k|  return 0;
  246|  2.54k|}
_ZNK5Exiv210AsciiValue6clone_Ev:
  248|  32.7k|AsciiValue* AsciiValue::clone_() const {
  249|  32.7k|  return new AsciiValue(*this);
  250|  32.7k|}
_ZNK5Exiv210AsciiValue5writeERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE:
  252|  8.33k|std::ostream& AsciiValue::write(std::ostream& os) const {
  253|       |  // Write only up to the first '\0' (if any)
  254|  8.33k|  std::string::size_type pos = value_.find_first_of('\0');
  255|  8.33k|  if (pos == std::string::npos)
  ------------------
  |  Branch (255:7): [True: 1.02k, False: 7.31k]
  ------------------
  256|  1.02k|    pos = value_.size();
  257|  8.33k|  return os << value_.substr(0, pos);
  258|  8.33k|}
_ZN5Exiv212CommentValueC2Ev:
  292|    344|CommentValue::CommentValue() : StringValueBase(Exiv2::undefined) {
  293|    344|}
_ZN5Exiv212CommentValue4readEPKhmNS_9ByteOrderE:
  329|    344|int CommentValue::read(const byte* buf, size_t len, ByteOrder byteOrder) {
  330|    344|  byteOrder_ = byteOrder;
  331|    344|  return StringValueBase::read(buf, len, byteOrder);
  332|    344|}
_ZNK5Exiv212CommentValue6clone_Ev:
  410|    690|CommentValue* CommentValue::clone_() const {
  411|    690|  return new CommentValue(*this);
  412|    690|}
_ZN5Exiv28XmpValue15setXmpArrayTypeENS0_12XmpArrayTypeE:
  414|  18.9k|void XmpValue::setXmpArrayType(XmpArrayType xmpArrayType) {
  415|  18.9k|  xmpArrayType_ = xmpArrayType;
  416|  18.9k|}
_ZN5Exiv28XmpValue12setXmpStructENS0_9XmpStructE:
  418|  3.23k|void XmpValue::setXmpStruct(XmpStruct xmpStruct) {
  419|  3.23k|  xmpStruct_ = xmpStruct;
  420|  3.23k|}
_ZNK5Exiv28XmpValue12xmpArrayTypeEv:
  422|  1.16k|XmpValue::XmpArrayType XmpValue::xmpArrayType() const {
  423|  1.16k|  return xmpArrayType_;
  424|  1.16k|}
_ZN5Exiv28XmpValue12xmpArrayTypeENS_6TypeIdE:
  426|  18.2k|XmpValue::XmpArrayType XmpValue::xmpArrayType(TypeId typeId) {
  427|  18.2k|  XmpArrayType xa = xaNone;
  428|  18.2k|  switch (typeId) {
  429|     84|    case xmpAlt:
  ------------------
  |  Branch (429:5): [True: 84, False: 18.1k]
  ------------------
  430|     84|      xa = xaAlt;
  431|     84|      break;
  432|    487|    case xmpBag:
  ------------------
  |  Branch (432:5): [True: 487, False: 17.7k]
  ------------------
  433|    487|      xa = xaBag;
  434|    487|      break;
  435|  14.9k|    case xmpSeq:
  ------------------
  |  Branch (435:5): [True: 14.9k, False: 3.26k]
  ------------------
  436|  14.9k|      xa = xaSeq;
  437|  14.9k|      break;
  438|  2.69k|    default:
  ------------------
  |  Branch (438:5): [True: 2.69k, False: 15.5k]
  ------------------
  439|  2.69k|      break;
  440|  18.2k|  }
  441|  18.2k|  return xa;
  442|  18.2k|}
_ZNK5Exiv28XmpValue9xmpStructEv:
  444|  1.06k|XmpValue::XmpStruct XmpValue::xmpStruct() const {
  445|  1.06k|  return xmpStruct_;
  446|  1.06k|}
_ZN5Exiv212XmpTextValueC2Ev:
  468|  94.3k|XmpTextValue::XmpTextValue() : XmpValue(xmpText) {
  469|  94.3k|}
_ZN5Exiv212XmpTextValue4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  475|   705k|int XmpTextValue::read(const std::string& buf) {
  476|       |  // support a type=Alt,Bag,Seq,Struct indicator
  477|   705k|  std::string b = buf;
  478|   705k|  std::string type;
  479|   705k|  if (buf.starts_with("type=")) {
  ------------------
  |  Branch (479:7): [True: 2.20k, False: 703k]
  ------------------
  480|  2.20k|    std::string::size_type pos = buf.find_first_of(' ');
  481|  2.20k|    type = buf.substr(5, pos - 5);
  482|       |    // Strip quotes (so you can also specify the type without quotes)
  483|  2.20k|    if (!type.empty() && type.front() == '"')
  ------------------
  |  Branch (483:9): [True: 1.81k, False: 386]
  |  Branch (483:26): [True: 1.48k, False: 332]
  ------------------
  484|  1.48k|      type = type.substr(1);
  485|  2.20k|    if (!type.empty() && type.back() == '"')
  ------------------
  |  Branch (485:9): [True: 1.27k, False: 927]
  |  Branch (485:26): [True: 597, False: 681]
  ------------------
  486|    597|      type.pop_back();
  487|  2.20k|    b.clear();
  488|  2.20k|    if (pos != std::string::npos)
  ------------------
  |  Branch (488:9): [True: 1.12k, False: 1.07k]
  ------------------
  489|  1.12k|      b = buf.substr(pos + 1);
  490|  2.20k|  }
  491|   705k|  if (!type.empty()) {
  ------------------
  |  Branch (491:7): [True: 1.27k, False: 704k]
  ------------------
  492|  1.27k|    if (type == "Alt") {
  ------------------
  |  Branch (492:9): [True: 211, False: 1.06k]
  ------------------
  493|    211|      setXmpArrayType(XmpValue::xaAlt);
  494|  1.06k|    } else if (type == "Bag") {
  ------------------
  |  Branch (494:16): [True: 199, False: 868]
  ------------------
  495|    199|      setXmpArrayType(XmpValue::xaBag);
  496|    868|    } else if (type == "Seq") {
  ------------------
  |  Branch (496:16): [True: 288, False: 580]
  ------------------
  497|    288|      setXmpArrayType(XmpValue::xaSeq);
  498|    580|    } else if (type == "Struct") {
  ------------------
  |  Branch (498:16): [True: 204, False: 376]
  ------------------
  499|    204|      setXmpStruct();
  500|    376|    } else {
  501|    376|      throw Error(ErrorCode::kerInvalidXmpText, type);
  502|    376|    }
  503|  1.27k|  }
  504|   705k|  value_ = std::move(b);
  505|   705k|  return 0;
  506|   705k|}
_ZNK5Exiv212XmpTextValue5writeERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE:
  522|  1.11k|std::ostream& XmpTextValue::write(std::ostream& os) const {
  523|  1.11k|  bool del = false;
  524|  1.11k|  if (xmpArrayType() != XmpValue::xaNone) {
  ------------------
  |  Branch (524:7): [True: 51, False: 1.06k]
  ------------------
  525|     51|    switch (xmpArrayType()) {
  ------------------
  |  Branch (525:13): [True: 51, False: 0]
  ------------------
  526|     43|      case XmpValue::xaAlt:
  ------------------
  |  Branch (526:7): [True: 43, False: 8]
  ------------------
  527|     43|        os << "type=\"Alt\"";
  528|     43|        break;
  529|      0|      case XmpValue::xaBag:
  ------------------
  |  Branch (529:7): [True: 0, False: 51]
  ------------------
  530|      0|        os << "type=\"Bag\"";
  531|      0|        break;
  532|      8|      case XmpValue::xaSeq:
  ------------------
  |  Branch (532:7): [True: 8, False: 43]
  ------------------
  533|      8|        os << "type=\"Seq\"";
  534|      8|        break;
  535|      0|      case XmpValue::xaNone:
  ------------------
  |  Branch (535:7): [True: 0, False: 51]
  ------------------
  536|      0|        break;  // just to suppress the warning
  537|     51|    }
  538|     51|    del = true;
  539|  1.06k|  } else if (xmpStruct() != XmpValue::xsNone) {
  ------------------
  |  Branch (539:14): [True: 0, False: 1.06k]
  ------------------
  540|      0|    switch (xmpStruct()) {
  ------------------
  |  Branch (540:13): [True: 0, False: 0]
  ------------------
  541|      0|      case XmpValue::xsStruct:
  ------------------
  |  Branch (541:7): [True: 0, False: 0]
  ------------------
  542|      0|        os << "type=\"Struct\"";
  543|      0|        break;
  544|      0|      case XmpValue::xsNone:
  ------------------
  |  Branch (544:7): [True: 0, False: 0]
  ------------------
  545|      0|        break;  // just to suppress the warning
  546|      0|    }
  547|      0|    del = true;
  548|      0|  }
  549|  1.11k|  if (del && !value_.empty())
  ------------------
  |  Branch (549:7): [True: 51, False: 1.06k]
  |  Branch (549:14): [True: 0, False: 51]
  ------------------
  550|      0|    os << " ";
  551|  1.11k|  return os << value_;
  552|  1.11k|}
_ZNK5Exiv212XmpTextValue6clone_Ev:
  570|   171k|XmpTextValue* XmpTextValue::clone_() const {
  571|   171k|  return new XmpTextValue(*this);
  572|   171k|}
_ZN5Exiv213XmpArrayValueC2ENS_6TypeIdE:
  574|  15.1k|XmpArrayValue::XmpArrayValue(TypeId typeId) : XmpValue(typeId) {
  575|  15.1k|  setXmpArrayType(xmpArrayType(typeId));
  576|  15.1k|}
_ZN5Exiv213XmpArrayValue4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  578|  80.0k|int XmpArrayValue::read(const std::string& buf) {
  579|  80.0k|  if (!buf.empty())
  ------------------
  |  Branch (579:7): [True: 62.5k, False: 17.5k]
  ------------------
  580|  62.5k|    value_.push_back(buf);
  581|  80.0k|  return 0;
  582|  80.0k|}
_ZNK5Exiv213XmpArrayValue5countEv:
  588|    155|size_t XmpArrayValue::count() const {
  589|    155|  return value_.size();
  590|    155|}
_ZNK5Exiv213XmpArrayValue5writeERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE:
  592|    148|std::ostream& XmpArrayValue::write(std::ostream& os) const {
  593|    148|  if (!value_.empty()) {
  ------------------
  |  Branch (593:7): [True: 145, False: 3]
  ------------------
  594|    145|    std::copy(value_.begin(), value_.end() - 1, std::ostream_iterator<std::string>(os, ", "));
  595|    145|    os << value_.back();
  596|    145|  }
  597|    148|  return os;
  598|    148|}
_ZNK5Exiv213XmpArrayValue8toStringEm:
  600|  2.79k|std::string XmpArrayValue::toString(size_t n) const {
  601|  2.79k|  ok_ = true;
  602|  2.79k|  return value_.at(n);
  603|  2.79k|}
_ZNK5Exiv213XmpArrayValue6clone_Ev:
  621|  32.8k|XmpArrayValue* XmpArrayValue::clone_() const {
  622|  32.8k|  return new XmpArrayValue(*this);
  623|  32.8k|}
_ZN5Exiv212LangAltValueC2Ev:
  625|  1.15k|LangAltValue::LangAltValue() : XmpValue(langAlt) {
  626|  1.15k|}
_ZNK5Exiv212LangAltValue5countEv:
  679|     63|size_t LangAltValue::count() const {
  680|     63|  return value_.size();
  681|     63|}
_ZNK5Exiv212LangAltValue5writeERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEE:
  683|     42|std::ostream& LangAltValue::write(std::ostream& os) const {
  684|     42|  bool first = true;
  685|       |
  686|       |  // Write the default entry first
  687|     42|  if (auto i = value_.find("x-default"); i != value_.end()) {
  ------------------
  |  Branch (687:42): [True: 0, False: 42]
  ------------------
  688|      0|    os << "lang=\"" << i->first << "\" " << i->second;
  689|      0|    first = false;
  690|      0|  }
  691|       |
  692|       |  // Write the others
  693|     42|  for (const auto& [lang, s] : value_) {
  ------------------
  |  Branch (693:30): [True: 42, False: 42]
  ------------------
  694|     42|    if (lang != "x-default") {
  ------------------
  |  Branch (694:9): [True: 42, False: 0]
  ------------------
  695|     42|      if (!first)
  ------------------
  |  Branch (695:11): [True: 0, False: 42]
  ------------------
  696|      0|        os << ", ";
  697|     42|      os << "lang=\"" << lang << "\" " << s;
  698|     42|      first = false;
  699|     42|    }
  700|     42|  }
  701|     42|  return os;
  702|     42|}
_ZNK5Exiv212LangAltValue8toStringEm:
  704|     94|std::string LangAltValue::toString(size_t /*n*/) const {
  705|     94|  return toString("x-default");
  706|     94|}
_ZNK5Exiv212LangAltValue8toStringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  708|     94|std::string LangAltValue::toString(const std::string& qualifier) const {
  709|     94|  if (auto i = value_.find(qualifier); i != value_.end()) {
  ------------------
  |  Branch (709:40): [True: 31, False: 63]
  ------------------
  710|     31|    ok_ = true;
  711|     31|    return i->second;
  712|     31|  }
  713|     63|  ok_ = false;
  714|     63|  return "";
  715|     94|}
_ZNK5Exiv212LangAltValue6clone_Ev:
  737|  2.99k|LangAltValue* LangAltValue::clone_() const {
  738|  2.99k|  return new LangAltValue(*this);
  739|  2.99k|}
_ZN5Exiv29DateValueC2Ev:
  741|  6.80k|DateValue::DateValue() : Value(date) {
  742|  6.80k|  date_ = {};
  743|  6.80k|}
_ZN5Exiv29DateValue4readEPKhmNS_9ByteOrderE:
  749|  6.80k|int DateValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) {
  750|  6.80k|  const std::string str(reinterpret_cast<const char*>(buf), len);
  751|  6.80k|  return read(str);
  752|  6.80k|}
_ZN5Exiv29DateValue4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  754|  6.80k|int DateValue::read(const std::string& buf) {
  755|       |  // ISO 8601 date formats:
  756|       |  // https://web.archive.org/web/20171020084445/https://www.loc.gov/standards/datetime/ISO_DIS%208601-1.pdf
  757|  6.80k|  size_t monthPos = 0;
  758|  6.80k|  size_t dayPos = 0;
  759|       |
  760|  6.80k|  auto printWarning = [] {
  761|  6.80k|#ifndef SUPPRESS_WARNINGS
  762|  6.80k|    EXV_WARNING << Error(ErrorCode::kerUnsupportedDateFormat) << "\n";
  763|  6.80k|#endif
  764|  6.80k|  };
  765|       |
  766|  6.80k|  if (buf.size() < 8) {
  ------------------
  |  Branch (766:7): [True: 277, False: 6.53k]
  ------------------
  767|    277|    printWarning();
  768|    277|    return 1;
  769|    277|  }
  770|       |
  771|  6.53k|  if ((buf.size() >= 10 && buf[4] == '-' && buf[7] == '-') || (buf.size() == 8)) {
  ------------------
  |  Branch (771:8): [True: 3.12k, False: 3.40k]
  |  Branch (771:28): [True: 2.47k, False: 652]
  |  Branch (771:45): [True: 818, False: 1.65k]
  |  Branch (771:63): [True: 3.39k, False: 2.32k]
  ------------------
  772|  4.21k|    if (buf.size() >= 10) {
  ------------------
  |  Branch (772:9): [True: 818, False: 3.39k]
  ------------------
  773|    818|      monthPos = 5;
  774|    818|      dayPos = 8;
  775|  3.39k|    } else {
  776|  3.39k|      monthPos = 4;
  777|  3.39k|      dayPos = 6;
  778|  3.39k|    }
  779|       |
  780|  4.21k|    auto checkDigits = [&buf, &printWarning](size_t start, size_t count, int32_t& dest) {
  781|  4.21k|      for (size_t i = start; i < start + count; ++i) {
  782|  4.21k|        if (!std::isdigit(buf[i])) {
  783|  4.21k|          printWarning();
  784|  4.21k|          return 1;
  785|  4.21k|        }
  786|  4.21k|      }
  787|  4.21k|      dest = std::stoul(buf.substr(start, count));
  788|  4.21k|      return 0;
  789|  4.21k|    };
  790|       |
  791|  4.21k|    if (checkDigits(0, 4, date_.year) || checkDigits(monthPos, 2, date_.month) || checkDigits(dayPos, 2, date_.day)) {
  ------------------
  |  Branch (791:9): [True: 1.26k, False: 2.94k]
  |  Branch (791:42): [True: 837, False: 2.10k]
  |  Branch (791:83): [True: 649, False: 1.45k]
  ------------------
  792|  2.75k|      printWarning();
  793|  2.75k|      return 1;
  794|  2.75k|    }
  795|       |
  796|  1.45k|    if (date_.month > 12 || date_.day > 31) {
  ------------------
  |  Branch (796:9): [True: 526, False: 932]
  |  Branch (796:29): [True: 576, False: 356]
  ------------------
  797|  1.10k|      date_.month = 0;
  798|  1.10k|      date_.day = 0;
  799|  1.10k|      printWarning();
  800|  1.10k|      return 1;
  801|  1.10k|    }
  802|    356|    return 0;
  803|  1.45k|  }
  804|  2.32k|  printWarning();
  805|  2.32k|  return 1;
  806|  6.53k|}
_ZNK5Exiv29DateValue6clone_Ev:
  834|    428|DateValue* DateValue::clone_() const {
  835|    428|  return new DateValue(*this);
  836|    428|}
_ZN5Exiv29TimeValueC2Ev:
  877|  9.17k|TimeValue::TimeValue() : Value(time) {
  878|  9.17k|  time_ = {};
  879|  9.17k|}
_ZN5Exiv29TimeValue4readEPKhmNS_9ByteOrderE:
  885|  9.17k|int TimeValue::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/) {
  886|  9.17k|  const std::string str(reinterpret_cast<const char*>(buf), len);
  887|  9.17k|  return read(str);
  888|  9.17k|}
_ZN5Exiv29TimeValue4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  890|  9.17k|int TimeValue::read(const std::string& buf) {
  891|       |  // ISO 8601 time formats:
  892|       |  // https://web.archive.org/web/20171020084445/https://www.loc.gov/standards/datetime/ISO_DIS%208601-1.pdf
  893|       |  // Not supported formats:
  894|       |  // 4.2.2.4 Representations with decimal fraction: 232050,5
  895|  9.17k|  auto printWarning = [] {
  896|  9.17k|#ifndef SUPPRESS_WARNINGS
  897|  9.17k|    EXV_WARNING << Error(ErrorCode::kerUnsupportedTimeFormat) << "\n";
  898|  9.17k|#endif
  899|  9.17k|    return 1;
  900|  9.17k|  };
  901|       |
  902|  9.17k|  if (buf.size() < 2)
  ------------------
  |  Branch (902:7): [True: 346, False: 8.82k]
  ------------------
  903|    346|    return printWarning();
  904|       |
  905|  8.82k|  for (auto c : buf)
  ------------------
  |  Branch (905:15): [True: 130k, False: 5.12k]
  ------------------
  906|   130k|    if (c != ':' && c != '+' && c != '-' && c != 'Z' && !std::isdigit(c))
  ------------------
  |  Branch (906:9): [True: 128k, False: 2.51k]
  |  Branch (906:21): [True: 125k, False: 2.98k]
  |  Branch (906:33): [True: 120k, False: 4.70k]
  |  Branch (906:45): [True: 118k, False: 1.95k]
  |  Branch (906:57): [True: 3.70k, False: 115k]
  ------------------
  907|  3.70k|      return printWarning();
  908|       |
  909|  5.12k|  size_t mpos;
  910|  5.12k|  size_t spos;
  911|  5.12k|  if (buf.find(':') != std::string::npos) {
  ------------------
  |  Branch (911:7): [True: 1.67k, False: 3.44k]
  ------------------
  912|  1.67k|    mpos = 3;
  913|  1.67k|    spos = 6;
  914|  3.44k|  } else {
  915|  3.44k|    mpos = 2;
  916|  3.44k|    spos = 4;
  917|  3.44k|  }
  918|       |
  919|  5.12k|  auto hi = std::stoi(buf.substr(0, 2));
  920|  5.12k|  if (hi < 0 || hi > 23)
  ------------------
  |  Branch (920:7): [True: 396, False: 4.72k]
  |  Branch (920:17): [True: 98, False: 4.62k]
  ------------------
  921|    491|    return printWarning();
  922|  4.63k|  time_.hour = hi;
  923|  4.63k|  if (buf.size() > 3) {
  ------------------
  |  Branch (923:7): [True: 4.50k, False: 126]
  ------------------
  924|  4.50k|    auto mi = std::stoi(buf.substr(mpos, 2));
  925|  4.50k|    if (mi < 0 || mi > 59)
  ------------------
  |  Branch (925:9): [True: 90, False: 4.41k]
  |  Branch (925:19): [True: 242, False: 4.17k]
  ------------------
  926|    330|      return printWarning();
  927|  4.17k|    time_.minute = std::stoi(buf.substr(mpos, 2));
  928|  4.17k|  } else {
  929|    126|    time_.minute = 0;
  930|    126|  }
  931|  4.30k|  if (buf.size() > 5) {
  ------------------
  |  Branch (931:7): [True: 3.93k, False: 369]
  ------------------
  932|  3.93k|    auto si = std::stoi(buf.substr(spos, 2));
  933|  3.93k|    if (si < 0 || si > 60)
  ------------------
  |  Branch (933:9): [True: 337, False: 3.59k]
  |  Branch (933:19): [True: 557, False: 3.03k]
  ------------------
  934|    875|      return printWarning();
  935|  3.05k|    time_.second = std::stoi(buf.substr(spos, 2));
  936|  3.05k|  } else {
  937|    369|    time_.second = 0;
  938|    369|  }
  939|       |
  940|  3.42k|  auto fpos = buf.find('+');
  941|  3.42k|  if (fpos == std::string::npos)
  ------------------
  |  Branch (941:7): [True: 2.37k, False: 1.05k]
  ------------------
  942|  2.37k|    fpos = buf.find('-');
  943|       |
  944|  3.42k|  if (fpos != std::string::npos) {
  ------------------
  |  Branch (944:7): [True: 2.81k, False: 608]
  ------------------
  945|  2.81k|    auto format = buf.substr(fpos, buf.size());
  946|  2.81k|    auto posColon = format.find(':');
  947|  2.81k|    if (posColon == std::string::npos) {
  ------------------
  |  Branch (947:9): [True: 1.72k, False: 1.09k]
  ------------------
  948|       |      // Extended format
  949|  1.72k|      auto tzhi = std::stoi(format.substr(0, 3));
  950|  1.72k|      if (tzhi < -23 || tzhi > 23)
  ------------------
  |  Branch (950:11): [True: 104, False: 1.62k]
  |  Branch (950:25): [True: 87, False: 1.53k]
  ------------------
  951|    180|        return printWarning();
  952|  1.54k|      time_.tzHour = tzhi;
  953|  1.54k|      if (format.size() > 3) {
  ------------------
  |  Branch (953:11): [True: 1.43k, False: 109]
  ------------------
  954|  1.43k|        int minute = std::stoi(format.substr(3));
  955|  1.43k|        if (minute < 0 || minute > 59)
  ------------------
  |  Branch (955:13): [True: 156, False: 1.28k]
  |  Branch (955:27): [True: 432, False: 850]
  ------------------
  956|    583|          return printWarning();
  957|    855|        time_.tzMinute = time_.tzHour < 0 ? -minute : minute;
  ------------------
  |  Branch (957:26): [True: 258, False: 597]
  ------------------
  958|    855|      }
  959|  1.54k|    } else {
  960|       |      // Basic format
  961|  1.09k|      auto tzhi = std::stoi(format.substr(0, posColon));
  962|  1.09k|      if (tzhi < -23 || tzhi > 23)
  ------------------
  |  Branch (962:11): [True: 52, False: 1.03k]
  |  Branch (962:25): [True: 90, False: 948]
  ------------------
  963|    135|        return printWarning();
  964|    955|      time_.tzHour = tzhi;
  965|    955|      int minute = std::stoi(format.substr(posColon + 1));
  966|    955|      if (minute < 0 || minute > 59)
  ------------------
  |  Branch (966:11): [True: 165, False: 790]
  |  Branch (966:25): [True: 126, False: 664]
  ------------------
  967|    281|        return printWarning();
  968|    674|      time_.tzMinute = time_.tzHour < 0 ? -minute : minute;
  ------------------
  |  Branch (968:24): [True: 336, False: 338]
  ------------------
  969|    674|    }
  970|  2.81k|  }
  971|  2.24k|  return 0;
  972|  3.42k|}
_ZNK5Exiv29TimeValue6clone_Ev:
 1007|  2.81k|TimeValue* TimeValue::clone_() const {
 1008|  2.81k|  return new TimeValue(*this);
 1009|  2.81k|}
value.cpp:_ZZN5Exiv29DateValue4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEENK3$_0clEv:
  760|  9.20k|  auto printWarning = [] {
  761|  9.20k|#ifndef SUPPRESS_WARNINGS
  762|  9.20k|    EXV_WARNING << Error(ErrorCode::kerUnsupportedDateFormat) << "\n";
  ------------------
  |  |  138|  9.20k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 9.20k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  9.20k|  LogMsg(LogMsg::warn).os()
  ------------------
  763|  9.20k|#endif
  764|  9.20k|  };
value.cpp:_ZZN5Exiv29DateValue4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEENK3$_1clEmmRi:
  780|  9.26k|    auto checkDigits = [&buf, &printWarning](size_t start, size_t count, int32_t& dest) {
  781|  28.9k|      for (size_t i = start; i < start + count; ++i) {
  ------------------
  |  Branch (781:30): [True: 22.4k, False: 6.50k]
  ------------------
  782|  22.4k|        if (!std::isdigit(buf[i])) {
  ------------------
  |  Branch (782:13): [True: 2.75k, False: 19.6k]
  ------------------
  783|  2.75k|          printWarning();
  784|  2.75k|          return 1;
  785|  2.75k|        }
  786|  22.4k|      }
  787|  6.50k|      dest = std::stoul(buf.substr(start, count));
  788|  6.50k|      return 0;
  789|  9.26k|    };
value.cpp:_ZZN5Exiv29TimeValue4readERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEENK3$_0clEv:
  895|  6.92k|  auto printWarning = [] {
  896|  6.92k|#ifndef SUPPRESS_WARNINGS
  897|  6.92k|    EXV_WARNING << Error(ErrorCode::kerUnsupportedTimeFormat) << "\n";
  ------------------
  |  |  138|  6.92k|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 6.92k]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|  6.92k|  LogMsg(LogMsg::warn).os()
  ------------------
  898|  6.92k|#endif
  899|  6.92k|    return 1;
  900|  6.92k|  };

_ZN5Exiv29WebPImageC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEE:
   77|    379|WebPImage::WebPImage(BasicIo::UniquePtr io) : Image(ImageType::webp, mdNone, std::move(io)) {
   78|    379|}  // WebPImage::WebPImage
_ZNK5Exiv29WebPImage8mimeTypeEv:
   80|     33|std::string WebPImage::mimeType() const {
   81|     33|  return "image/webp";
   82|     33|}
_ZN5Exiv29WebPImage12readMetadataEv:
  475|    379|void WebPImage::readMetadata() {
  476|    379|  if (io_->open() != 0)
  ------------------
  |  Branch (476:7): [True: 0, False: 379]
  ------------------
  477|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
  478|    379|  IoCloser closer(*io_);
  479|       |  // Ensure that this is the correct image type
  480|    379|  if (!isWebPType(*io_, true)) {
  ------------------
  |  Branch (480:7): [True: 0, False: 379]
  ------------------
  481|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (481:9): [True: 0, False: 0]
  |  Branch (481:25): [True: 0, False: 0]
  ------------------
  482|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
  483|      0|    throw Error(ErrorCode::kerNotAJpeg);
  484|      0|  }
  485|    379|  clearMetadata();
  486|       |
  487|    379|  byte data[12];
  488|    379|  DataBuf chunkId(5);
  489|    379|  chunkId.write_uint8(4, '\0');
  490|       |
  491|    379|  io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::ErrorCode::kerCorruptedMetadata);
  492|       |
  493|    379|  const uint32_t filesize = Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U);
  494|    379|  Internal::enforce(filesize <= io_->size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  495|       |
  496|    379|  WebPImage::decodeChunks(filesize);
  497|       |
  498|    379|}  // WebPImage::readMetadata
_ZN5Exiv29WebPImage12decodeChunksEj:
  500|    360|void WebPImage::decodeChunks(uint32_t filesize) {
  501|    360|  DataBuf chunkId(5);
  502|    360|  std::array<byte, WEBP_TAG_SIZE> size_buff;
  503|    360|  bool has_canvas_data = false;
  504|       |
  505|       |#ifdef EXIV2_DEBUG_MESSAGES
  506|       |  std::cout << "Reading metadata" << '\n';
  507|       |#endif
  508|       |
  509|    360|  chunkId.write_uint8(4, '\0');
  510|  2.15k|  while (!io_->eof() && io_->tell() < filesize) {
  ------------------
  |  Branch (510:10): [True: 1.84k, False: 313]
  |  Branch (510:25): [True: 1.79k, False: 47]
  ------------------
  511|  1.79k|    io_->readOrThrow(chunkId.data(), WEBP_TAG_SIZE, Exiv2::ErrorCode::kerCorruptedMetadata);
  512|  1.79k|    io_->readOrThrow(size_buff.data(), WEBP_TAG_SIZE, Exiv2::ErrorCode::kerCorruptedMetadata);
  513|       |
  514|  1.79k|    const uint32_t size = Exiv2::getULong(size_buff.data(), littleEndian);
  515|       |
  516|       |    // Check that `size` is within bounds.
  517|  1.79k|    Internal::enforce(io_->tell() <= filesize, Exiv2::ErrorCode::kerCorruptedMetadata);
  518|  1.79k|    Internal::enforce(size <= (filesize - io_->tell()), Exiv2::ErrorCode::kerCorruptedMetadata);
  519|       |
  520|  1.79k|    if (DataBuf payload(size); payload.empty()) {
  ------------------
  |  Branch (520:32): [True: 996, False: 799]
  ------------------
  521|    996|      io_->seek(size, BasicIo::cur);
  522|    996|    } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X) && !has_canvas_data) {
  ------------------
  |  Branch (522:16): [True: 27, False: 772]
  |  Branch (522:66): [True: 24, False: 3]
  ------------------
  523|     24|      Internal::enforce(size >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
  524|       |
  525|     24|      has_canvas_data = true;
  526|     24|      std::array<byte, WEBP_TAG_SIZE> size_buf;
  527|       |
  528|     24|      io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  529|       |
  530|       |      // Fetch width
  531|     24|      std::copy_n(payload.begin() + 4, 3, size_buf.begin());
  532|     24|      size_buf.back() = 0;
  533|     24|      pixelWidth_ = Exiv2::getULong(size_buf.data(), littleEndian) + 1;
  534|       |
  535|       |      // Fetch height
  536|     24|      std::copy_n(payload.begin() + 7, 3, size_buf.begin());
  537|     24|      size_buf.back() = 0;
  538|     24|      pixelHeight_ = Exiv2::getULong(size_buf.data(), littleEndian) + 1;
  539|    775|    } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8) && !has_canvas_data) {
  ------------------
  |  Branch (539:16): [True: 30, False: 745]
  |  Branch (539:65): [True: 20, False: 10]
  ------------------
  540|     20|      Internal::enforce(size >= 10, Exiv2::ErrorCode::kerCorruptedMetadata);
  541|       |
  542|     20|      has_canvas_data = true;
  543|     20|      io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  544|     20|      std::array<byte, WEBP_TAG_SIZE> size_buf;
  545|       |
  546|       |      // Fetch width""
  547|     20|      std::copy_n(payload.begin() + 6, 2, size_buf.begin());
  548|     20|      size_buf[2] = 0;
  549|     20|      size_buf[3] = 0;
  550|     20|      pixelWidth_ = Exiv2::getULong(size_buf.data(), littleEndian) & 0x3fff;
  551|       |
  552|       |      // Fetch height
  553|     20|      std::copy_n(payload.begin() + 8, 2, size_buf.begin());
  554|     20|      size_buf[2] = 0;
  555|     20|      size_buf[3] = 0;
  556|     20|      pixelHeight_ = Exiv2::getULong(size_buf.data(), littleEndian) & 0x3fff;
  557|    755|    } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_canvas_data) {
  ------------------
  |  Branch (557:16): [True: 23, False: 732]
  |  Branch (557:66): [True: 22, False: 1]
  ------------------
  558|     22|      Internal::enforce(size >= 5, Exiv2::ErrorCode::kerCorruptedMetadata);
  559|       |
  560|     22|      has_canvas_data = true;
  561|     22|      std::array<byte, 2> size_buf_w;
  562|     22|      std::array<byte, 3> size_buf_h;
  563|       |
  564|     22|      io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  565|       |
  566|       |      // Fetch width
  567|     22|      std::copy_n(payload.begin() + 1, 2, size_buf_w.begin());
  568|     22|      size_buf_w.back() &= 0x3F;
  569|     22|      pixelWidth_ = Exiv2::getUShort(size_buf_w.data(), littleEndian) + 1;
  570|       |
  571|       |      // Fetch height
  572|     22|      std::copy_n(payload.begin() + 2, 3, size_buf_h.begin());
  573|     22|      size_buf_h[0] = ((size_buf_h[0] >> 6) & 0x3) | ((size_buf_h[1] & 0x3FU) << 0x2);
  574|     22|      size_buf_h[1] = ((size_buf_h[1] >> 6) & 0x3) | ((size_buf_h[2] & 0xFU) << 0x2);
  575|     22|      pixelHeight_ = Exiv2::getUShort(size_buf_h.data(), littleEndian) + 1;
  576|    733|    } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_canvas_data) {
  ------------------
  |  Branch (576:16): [True: 0, False: 733]
  |  Branch (576:66): [True: 0, False: 0]
  ------------------
  577|      0|      Internal::enforce(size >= 12, Exiv2::ErrorCode::kerCorruptedMetadata);
  578|       |
  579|      0|      has_canvas_data = true;
  580|      0|      std::array<byte, WEBP_TAG_SIZE> size_buf;
  581|       |
  582|      0|      io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  583|       |
  584|       |      // Fetch width
  585|      0|      std::copy_n(payload.begin() + 6, 3, size_buf.begin());
  586|      0|      size_buf.back() = 0;
  587|      0|      pixelWidth_ = Exiv2::getULong(size_buf.data(), littleEndian) + 1;
  588|       |
  589|       |      // Fetch height
  590|      0|      std::copy_n(payload.begin() + 9, 3, size_buf.begin());
  591|      0|      size_buf.back() = 0;
  592|      0|      pixelHeight_ = Exiv2::getULong(size_buf.data(), littleEndian) + 1;
  593|    733|    } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ICCP)) {
  ------------------
  |  Branch (593:16): [True: 25, False: 708]
  ------------------
  594|     25|      io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  595|     25|      this->setIccProfile(std::move(payload));
  596|    708|    } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_EXIF)) {
  ------------------
  |  Branch (596:16): [True: 327, False: 381]
  ------------------
  597|    327|      io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  598|       |
  599|    327|      std::array<byte, 2> size_buff2;
  600|       |      // 4 meaningful bytes + 2 padding bytes
  601|    327|      auto exifLongHeader = std::array<byte, 6>{0xFF, 0x01, 0xFF, 0xE1, 0x00, 0x00};
  602|    327|      auto exifShortHeader = std::array<byte, 6>{0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
  603|    327|      const byte exifTiffLEHeader[] = {0x49, 0x49, 0x2A};        // "MM*"
  604|    327|      const byte exifTiffBEHeader[] = {0x4D, 0x4D, 0x00, 0x2A};  // "II\0*"
  605|    327|      size_t offset = 0;
  606|    327|      bool s_header = false;
  607|    327|      bool le_header = false;
  608|    327|      bool be_header = false;
  609|    327|      size_t pos = getHeaderOffset(payload.c_data(), payload.size(), exifLongHeader.data(), 4);
  610|       |
  611|    327|      if (pos == std::string::npos) {
  ------------------
  |  Branch (611:11): [True: 309, False: 18]
  ------------------
  612|    309|        pos = getHeaderOffset(payload.c_data(), payload.size(), exifLongHeader.data(), 6);
  613|    309|        if (pos != std::string::npos) {
  ------------------
  |  Branch (613:13): [True: 0, False: 309]
  ------------------
  614|      0|          s_header = true;
  615|      0|        }
  616|    309|      }
  617|    327|      if (pos == std::string::npos) {
  ------------------
  |  Branch (617:11): [True: 309, False: 18]
  ------------------
  618|    309|        pos = getHeaderOffset(payload.c_data(), payload.size(), exifTiffLEHeader, 3);
  619|    309|        if (pos != std::string::npos) {
  ------------------
  |  Branch (619:13): [True: 81, False: 228]
  ------------------
  620|     81|          le_header = true;
  621|     81|        }
  622|    309|      }
  623|    327|      if (pos == std::string::npos) {
  ------------------
  |  Branch (623:11): [True: 228, False: 99]
  ------------------
  624|    228|        pos = getHeaderOffset(payload.c_data(), payload.size(), exifTiffBEHeader, 4);
  625|    228|        if (pos != std::string::npos) {
  ------------------
  |  Branch (625:13): [True: 52, False: 176]
  ------------------
  626|     52|          be_header = true;
  627|     52|        }
  628|    228|      }
  629|       |
  630|    327|      if (s_header) {
  ------------------
  |  Branch (630:11): [True: 0, False: 327]
  ------------------
  631|      0|        offset += 6;
  632|      0|      }
  633|    327|      if (be_header || le_header) {
  ------------------
  |  Branch (633:11): [True: 52, False: 275]
  |  Branch (633:24): [True: 81, False: 194]
  ------------------
  634|    133|        offset += 12;
  635|    133|      }
  636|       |
  637|    327|      const size_t sizePayload = Safe::add(payload.size(), offset);
  638|    327|      DataBuf rawExifData(sizePayload);
  639|       |
  640|    327|      if (s_header) {
  ------------------
  |  Branch (640:11): [True: 0, False: 327]
  ------------------
  641|      0|        us2Data(size_buff2.data(), static_cast<uint16_t>(sizePayload - 6), bigEndian);
  642|      0|        std::copy_n(exifLongHeader.begin(), 4, rawExifData.begin());
  643|      0|        std::copy(size_buff2.begin(), size_buff2.end(), rawExifData.begin() + 4);
  644|      0|      }
  645|       |
  646|    327|      if (be_header || le_header) {
  ------------------
  |  Branch (646:11): [True: 52, False: 275]
  |  Branch (646:24): [True: 81, False: 194]
  ------------------
  647|    133|        us2Data(size_buff2.data(), static_cast<uint16_t>(sizePayload - 6), bigEndian);
  648|    133|        std::copy_n(exifLongHeader.begin(), 4, rawExifData.begin());
  649|    133|        std::copy(size_buff2.begin(), size_buff2.end(), rawExifData.begin() + 4);
  650|    133|        std::copy(exifShortHeader.begin(), exifShortHeader.end(), rawExifData.begin() + 6);
  651|    133|      }
  652|       |
  653|    327|      std::copy(payload.begin(), payload.end(), rawExifData.begin() + offset);
  654|       |
  655|       |#ifdef EXIV2_DEBUG_MESSAGES
  656|       |      std::cout << "Display Hex Dump [size:" << sizePayload << "]" << '\n';
  657|       |      std::cout << binaryToHex(rawExifData.c_data(), sizePayload);
  658|       |#endif
  659|       |
  660|    327|      if (pos != std::string::npos) {
  ------------------
  |  Branch (660:11): [True: 151, False: 176]
  ------------------
  661|    151|        XmpData xmpData;
  662|    151|        ByteOrder bo = ExifParser::decode(exifData_, payload.c_data(pos), payload.size() - pos);
  663|    151|        setByteOrder(bo);
  664|    176|      } else {
  665|    176|#ifndef SUPPRESS_WARNINGS
  666|    176|        EXV_WARNING << "Failed to decode Exif metadata." << '\n';
  ------------------
  |  |  138|    176|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 176]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    176|  LogMsg(LogMsg::warn).os()
  ------------------
  667|    176|#endif
  668|    176|        exifData_.clear();
  669|    176|      }
  670|    381|    } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_XMP)) {
  ------------------
  |  Branch (670:16): [True: 32, False: 349]
  ------------------
  671|     32|      io_->readOrThrow(payload.data(), payload.size(), Exiv2::ErrorCode::kerCorruptedMetadata);
  672|     32|      xmpPacket_.assign(payload.c_str(), payload.size());
  673|     32|      if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) {
  ------------------
  |  Branch (673:11): [True: 32, False: 0]
  |  Branch (673:34): [True: 32, False: 0]
  ------------------
  674|     32|#ifndef SUPPRESS_WARNINGS
  675|     32|        EXV_WARNING << "Failed to decode XMP metadata." << '\n';
  ------------------
  |  |  138|     32|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 32]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|     32|  LogMsg(LogMsg::warn).os()
  ------------------
  676|     32|#endif
  677|     32|      } else {
  678|       |#ifdef EXIV2_DEBUG_MESSAGES
  679|       |        std::cout << "Display Hex Dump [size:" << payload.size() << "]" << '\n';
  680|       |        std::cout << binaryToHex(payload.c_data(), payload.size());
  681|       |#endif
  682|      0|      }
  683|    349|    } else {
  684|    349|      io_->seek(size, BasicIo::cur);
  685|    349|    }
  686|       |
  687|  1.79k|    if (io_->tell() % 2)
  ------------------
  |  Branch (687:9): [True: 235, False: 1.56k]
  ------------------
  688|    235|      io_->seek(+1, BasicIo::cur);
  689|  1.79k|  }
  690|    360|}
_ZN5Exiv215newWebPInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  694|    379|Image::UniquePtr newWebPInstance(BasicIo::UniquePtr io, bool /*create*/) {
  695|    379|  auto image = std::make_unique<WebPImage>(std::move(io));
  696|    379|  if (!image->good()) {
  ------------------
  |  Branch (696:7): [True: 0, False: 379]
  ------------------
  697|      0|    return nullptr;
  698|      0|  }
  699|    379|  return image;
  700|    379|}
_ZN5Exiv210isWebPTypeERNS_7BasicIoEb:
  702|  23.2k|bool isWebPType(BasicIo& iIo, bool /*advance*/) {
  703|  23.2k|  if (iIo.size() < 12) {
  ------------------
  |  Branch (703:7): [True: 141, False: 23.1k]
  ------------------
  704|    141|    return false;
  705|    141|  }
  706|  23.1k|  const int32_t len = 4;
  707|  23.1k|  constexpr std::array<byte, len> RiffImageId{'R', 'I', 'F', 'F'};
  708|  23.1k|  constexpr std::array<byte, len> WebPImageId{'W', 'E', 'B', 'P'};
  709|  23.1k|  std::array<byte, len> webp;
  710|  23.1k|  std::array<byte, len> data;
  711|  23.1k|  std::array<byte, len> riff;
  712|  23.1k|  iIo.readOrThrow(riff.data(), len, Exiv2::ErrorCode::kerCorruptedMetadata);
  713|  23.1k|  iIo.readOrThrow(data.data(), len, Exiv2::ErrorCode::kerCorruptedMetadata);
  714|  23.1k|  iIo.readOrThrow(webp.data(), len, Exiv2::ErrorCode::kerCorruptedMetadata);
  715|  23.1k|  bool matched_riff = riff == RiffImageId;
  716|  23.1k|  bool matched_webp = webp == WebPImageId;
  717|  23.1k|  iIo.seek(-12, BasicIo::cur);
  718|  23.1k|  return matched_riff && matched_webp;
  ------------------
  |  Branch (718:10): [True: 1.92k, False: 21.2k]
  |  Branch (718:26): [True: 1.13k, False: 791]
  ------------------
  719|  23.2k|}
_ZN5Exiv29WebPImage13equalsWebPTagERKNS_7DataBufEPKc:
  728|  3.44k|bool WebPImage::equalsWebPTag(const Exiv2::DataBuf& buf, const char* str) {
  729|  5.84k|  for (int i = 0; i < 4; i++)
  ------------------
  |  Branch (729:19): [True: 5.37k, False: 464]
  ------------------
  730|  5.37k|    if (toupper(buf.read_uint8(i)) != str[i])
  ------------------
  |  Branch (730:9): [True: 2.98k, False: 2.39k]
  ------------------
  731|  2.98k|      return false;
  732|    464|  return true;
  733|  3.44k|}
_ZN5Exiv29WebPImage15getHeaderOffsetEPKhmS2_m:
  796|  1.17k|size_t WebPImage::getHeaderOffset(const byte* data, size_t data_size, const byte* header, size_t header_size) {
  797|  1.17k|  size_t pos = std::string::npos;  // error value
  798|  1.17k|  if (data_size < header_size) {
  ------------------
  |  Branch (798:7): [True: 265, False: 908]
  ------------------
  799|    265|    return pos;
  800|    265|  }
  801|  1.08M|  for (size_t i = 0; i < data_size - header_size; i++) {
  ------------------
  |  Branch (801:22): [True: 1.08M, False: 757]
  ------------------
  802|  1.08M|    if (memcmp(header, &data[i], header_size) == 0) {
  ------------------
  |  Branch (802:9): [True: 151, False: 1.08M]
  ------------------
  803|    151|      pos = i;
  804|    151|      break;
  805|    151|    }
  806|  1.08M|  }
  807|    908|  return pos;
  808|  1.17k|}

_ZN5Exiv28Xmpdatum4ImplC2ERKNS_6XmpKeyEPKNS_5ValueE:
  251|   110k|Xmpdatum::Impl::Impl(const XmpKey& key, const Value* pValue) : key_(key.clone()) {
  252|   110k|  if (pValue)
  ------------------
  |  Branch (252:7): [True: 66.2k, False: 44.4k]
  ------------------
  253|  66.2k|    value_ = pValue->clone();
  254|   110k|}
_ZN5Exiv28Xmpdatum4ImplC2ERKS1_:
  256|   140k|Xmpdatum::Impl::Impl(const Impl& rhs) {
  257|   140k|  if (rhs.key_)
  ------------------
  |  Branch (257:7): [True: 140k, False: 0]
  ------------------
  258|   140k|    key_ = rhs.key_->clone();  // deep copy
  259|   140k|  if (rhs.value_)
  ------------------
  |  Branch (259:7): [True: 140k, False: 0]
  ------------------
  260|   140k|    value_ = rhs.value_->clone();  // deep copy
  261|   140k|}
_ZN5Exiv28XmpdatumC2ERKNS_6XmpKeyEPKNS_5ValueE:
  275|   110k|Xmpdatum::Xmpdatum(const XmpKey& key, const Value* pValue) : p_(std::make_unique<Impl>(key, pValue)) {
  276|   110k|}
_ZN5Exiv28XmpdatumC2ERKS0_:
  278|   140k|Xmpdatum::Xmpdatum(const Xmpdatum& rhs) : p_(std::make_unique<Impl>(*rhs.p_)) {
  279|   140k|}
_ZN5Exiv28XmpdatumD2Ev:
  288|   251k|Xmpdatum::~Xmpdatum() = default;
_ZNK5Exiv28Xmpdatum3keyEv:
  290|  6.53M|std::string Xmpdatum::key() const {
  291|  6.53M|  return p_->key_ ? p_->key_->key() : "";
  ------------------
  |  Branch (291:10): [True: 6.53M, False: 0]
  ------------------
  292|  6.53M|}
_ZNK5Exiv28Xmpdatum6typeIdEv:
  318|    948|TypeId Xmpdatum::typeId() const {
  319|    948|  return p_->value_ ? p_->value_->typeId() : invalidTypeId;
  ------------------
  |  Branch (319:10): [True: 948, False: 0]
  ------------------
  320|    948|}
_ZNK5Exiv28Xmpdatum5countEv:
  330|    218|size_t Xmpdatum::count() const {
  331|    218|  return p_->value_ ? p_->value_->count() : 0;
  ------------------
  |  Branch (331:10): [True: 218, False: 0]
  ------------------
  332|    218|}
_ZNK5Exiv28Xmpdatum8toStringEv:
  338|  1.18k|std::string Xmpdatum::toString() const {
  339|  1.18k|  return p_->value_ ? p_->value_->toString() : "";
  ------------------
  |  Branch (339:10): [True: 1.18k, False: 0]
  ------------------
  340|  1.18k|}
_ZNK5Exiv28Xmpdatum8toStringEm:
  342|  2.89k|std::string Xmpdatum::toString(size_t n) const {
  343|  2.89k|  return p_->value_ ? p_->value_->toString(n) : "";
  ------------------
  |  Branch (343:10): [True: 2.89k, False: 0]
  ------------------
  344|  2.89k|}
_ZNK5Exiv28Xmpdatum5valueEv:
  362|  3.42k|const Value& Xmpdatum::value() const {
  363|  3.42k|  if (!p_->value_)
  ------------------
  |  Branch (363:7): [True: 0, False: 3.42k]
  ------------------
  364|      0|    throw Error(ErrorCode::kerValueNotSet, key());
  365|  3.42k|  return *p_->value_;
  366|  3.42k|}
_ZN5Exiv28Xmpdatum8setValueERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  382|   658k|int Xmpdatum::setValue(const std::string& value) {
  383|   658k|  XmpProperties::XmpLock lock;
  384|   658k|  if (!p_->value_) {
  ------------------
  |  Branch (384:7): [True: 44.4k, False: 614k]
  ------------------
  385|  44.4k|    TypeId type = xmpText;
  386|  44.4k|    if (p_->key_) {
  ------------------
  |  Branch (386:9): [True: 44.4k, False: 0]
  ------------------
  387|  44.4k|      type = XmpProperties::propertyTypeUnlocked(*p_->key_.get(), lock);
  388|  44.4k|    }
  389|  44.4k|    p_->value_ = Value::create(type);
  390|  44.4k|  }
  391|   658k|  return p_->value_->read(value);
  392|   658k|}
_ZN5Exiv27XmpDataixERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  394|   660k|Xmpdatum& XmpData::operator[](const std::string& key) {
  395|   660k|  XmpProperties::XmpLock lock;
  396|   660k|  XmpKey xmpKey(key, lock);
  397|   660k|  auto pos = std::find_if(xmpMetadata_.begin(), xmpMetadata_.end(), FindXmpdatum(xmpKey));
  398|   660k|  if (pos == xmpMetadata_.end()) {
  ------------------
  |  Branch (398:7): [True: 44.4k, False: 615k]
  ------------------
  399|  44.4k|    return xmpMetadata_.emplace_back(xmpKey);
  400|  44.4k|  }
  401|   615k|  return *pos;
  402|   660k|}
_ZN5Exiv27XmpData3addERKNS_6XmpKeyEPKNS_5ValueE:
  404|  12.2k|int XmpData::add(const XmpKey& key, const Value* value) {
  405|  12.2k|  XmpProperties::XmpLock lock;
  406|  12.2k|  return addUnlocked(key, value, lock);
  407|  12.2k|}
_ZN5Exiv27XmpData11addUnlockedERKNS_6XmpKeyEPKNS_5ValueERKNS_13XmpProperties7XmpLockE:
  409|  66.2k|int XmpData::addUnlocked(const XmpKey& key, const Value* value, const XmpProperties::XmpLock&) {
  410|  66.2k|  xmpMetadata_.emplace_back(key, value);
  411|  66.2k|  return 0;
  412|  66.2k|}
_ZNK5Exiv27XmpData7findKeyERKNS_6XmpKeyE:
  424|  32.7k|XmpData::const_iterator XmpData::findKey(const XmpKey& key) const {
  425|  32.7k|  XmpProperties::XmpLock lock;
  426|  32.7k|  return std::find_if(xmpMetadata_.begin(), xmpMetadata_.end(), FindXmpdatum(key));
  427|  32.7k|}
_ZN5Exiv27XmpData7findKeyERKNS_6XmpKeyE:
  429|   151k|XmpData::iterator XmpData::findKey(const XmpKey& key) {
  430|   151k|  XmpProperties::XmpLock lock;
  431|   151k|  return std::find_if(xmpMetadata_.begin(), xmpMetadata_.end(), FindXmpdatum(key));
  432|   151k|}
_ZN5Exiv27XmpData5clearEv:
  434|  31.5k|void XmpData::clear() {
  435|  31.5k|  XmpProperties::XmpLock lock;
  436|  31.5k|  clearUnlocked(lock);
  437|  31.5k|}
_ZN5Exiv27XmpData13clearUnlockedERKNS_13XmpProperties7XmpLockE:
  439|  42.0k|void XmpData::clearUnlocked(const XmpProperties::XmpLock&) {
  440|  42.0k|  xmpMetadata_.clear();
  441|  42.0k|}
_ZNK5Exiv27XmpData3endEv:
  456|  32.7k|XmpData::const_iterator XmpData::end() const {
  457|  32.7k|  return xmpMetadata_.end();
  458|  32.7k|}
_ZNK5Exiv27XmpData5emptyEv:
  460|  5.83k|bool XmpData::empty() const {
  461|  5.83k|  XmpProperties::XmpLock lock;
  462|  5.83k|  return emptyUnlocked(lock);
  463|  5.83k|}
_ZNK5Exiv27XmpData13emptyUnlockedERKNS_13XmpProperties7XmpLockE:
  465|  10.2k|bool XmpData::emptyUnlocked(const XmpProperties::XmpLock&) const {
  466|  10.2k|  return xmpMetadata_.empty();
  467|  10.2k|}
_ZN5Exiv27XmpData5beginEv:
  478|  1.20k|XmpData::iterator XmpData::begin() {
  479|  1.20k|  return xmpMetadata_.begin();
  480|  1.20k|}
_ZN5Exiv27XmpData3endEv:
  482|   153k|XmpData::iterator XmpData::end() {
  483|   153k|  return xmpMetadata_.end();
  484|   153k|}
_ZN5Exiv227xmpToolkitEnsureInitializedEv:
  535|  14.9k|void xmpToolkitEnsureInitialized() {
  536|  14.9k|  static XmpToolkitLifetimeManager instance;
  537|  14.9k|  (void)instance;
  538|  14.9k|}
_ZN5Exiv29XmpParser6decodeERNS_7XmpDataERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  660|  11.4k|int XmpParser::decode(XmpData& xmpData, const std::string& xmpPacket) {
  661|  11.4k|  try {
  662|  11.4k|    xmpData.setPacket(xmpPacket);
  663|  11.4k|    if (xmpPacket.empty()) {
  ------------------
  |  Branch (663:9): [True: 945, False: 10.5k]
  ------------------
  664|    945|      xmpData.clear();
  665|    945|      return 0;
  666|    945|    }
  667|       |
  668|       |    // Acquire Giant Lock
  669|  10.5k|    XmpProperties::XmpLock lock;
  670|  10.5k|    try {
  671|  10.5k|      xmpToolkitEnsureInitialized();
  672|  10.5k|    } catch (const Error&) {
  673|      0|#ifndef SUPPRESS_WARNINGS
  674|      0|      EXV_ERROR << "XMP toolkit initialization failed.\n";
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
  675|      0|#endif
  676|      0|      return 2;
  677|      0|    }
  678|       |
  679|  10.5k|    xmpData.clearUnlocked(lock);
  680|       |
  681|       |    // Make sure the unterminated substring is used
  682|  10.5k|    size_t len = xmpPacket.size();
  683|   137k|    while (len > 0 && 0 == xmpPacket[len - 1])
  ------------------
  |  Branch (683:12): [True: 137k, False: 76]
  |  Branch (683:23): [True: 126k, False: 10.4k]
  ------------------
  684|   126k|      --len;
  685|       |
  686|  10.5k|    XMLValidator::check(xmpPacket.data(), len);
  687|  10.5k|    SXMPMeta meta(xmpPacket.data(), static_cast<XMP_StringLen>(len));
  688|  10.5k|    SXMPIterator iter(meta);
  689|  10.5k|    std::string schemaNs;
  690|  10.5k|    std::string propPath;
  691|  10.5k|    std::string propValue;
  692|  10.5k|    XMP_OptionBits opt = 0;
  693|  73.2k|    while (iter.Next(&schemaNs, &propPath, &propValue, &opt)) {
  ------------------
  |  Branch (693:12): [True: 62.7k, False: 10.5k]
  ------------------
  694|  62.7k|      printNode(schemaNs, propPath, propValue, opt);
  695|  62.7k|      if (XMP_PropIsAlias(opt)) {
  ------------------
  |  Branch (695:11): [True: 0, False: 62.7k]
  ------------------
  696|      0|        throw Error(ErrorCode::kerAliasesNotSupported, schemaNs, propPath, propValue);
  697|      0|      }
  698|  62.7k|      if (XMP_NodeIsSchema(opt)) {
  ------------------
  |  Branch (698:11): [True: 8.75k, False: 54.0k]
  ------------------
  699|       |        // Register unknown namespaces with Exiv2
  700|       |        // (Namespaces are automatically registered with the XMP Toolkit)
  701|  8.75k|        if (XmpProperties::prefixUnlocked(schemaNs, lock).empty()) {
  ------------------
  |  Branch (701:13): [True: 2.80k, False: 5.94k]
  ------------------
  702|  2.80k|          std::string prefix;
  703|  2.80k|          if (!SXMPMeta::GetNamespacePrefix(schemaNs.c_str(), &prefix))
  ------------------
  |  Branch (703:15): [True: 0, False: 2.80k]
  ------------------
  704|      0|            throw Error(ErrorCode::kerSchemaNamespaceNotRegistered, schemaNs);
  705|  2.80k|          prefix.pop_back();
  706|  2.80k|          XmpProperties::registerNsUnlocked(schemaNs, prefix, lock);
  707|  2.80k|        }
  708|  8.75k|        continue;
  709|  8.75k|      }
  710|  54.0k|      auto key = makeXmpKey(schemaNs, propPath, lock);
  711|  54.0k|      if (XMP_ArrayIsAltText(opt)) {
  ------------------
  |  Branch (711:11): [True: 1.15k, False: 52.8k]
  ------------------
  712|       |        // Read Lang Alt property
  713|  1.15k|        auto val = std::make_unique<LangAltValue>();
  714|  1.15k|        XMP_Index count = meta.CountArrayItems(schemaNs.c_str(), propPath.c_str());
  715|  2.65k|        while (count-- > 0) {
  ------------------
  |  Branch (715:16): [True: 1.50k, False: 1.15k]
  ------------------
  716|       |          // Get the text
  717|  1.50k|          bool haveNext = iter.Next(&schemaNs, &propPath, &propValue, &opt);
  718|  1.50k|          printNode(schemaNs, propPath, propValue, opt);
  719|  1.50k|          if (!haveNext || !XMP_PropIsSimple(opt) || !XMP_PropHasLang(opt)) {
  ------------------
  |  Branch (719:15): [True: 0, False: 1.50k]
  |  Branch (719:28): [True: 0, False: 1.50k]
  |  Branch (719:54): [True: 0, False: 1.50k]
  ------------------
  720|      0|            throw Error(ErrorCode::kerDecodeLangAltPropertyFailed, propPath, opt);
  721|      0|          }
  722|  1.50k|          std::string text = propValue;
  723|       |          // Get the language qualifier
  724|  1.50k|          haveNext = iter.Next(&schemaNs, &propPath, &propValue, &opt);
  725|  1.50k|          printNode(schemaNs, propPath, propValue, opt);
  726|  1.50k|          if (!haveNext || !XMP_PropIsSimple(opt) || !XMP_PropIsQualifier(opt) ||
  ------------------
  |  Branch (726:15): [True: 0, False: 1.50k]
  |  Branch (726:15): [True: 0, False: 1.50k]
  |  Branch (726:28): [True: 0, False: 1.50k]
  |  Branch (726:54): [True: 0, False: 1.50k]
  ------------------
  727|  1.50k|              propPath.substr(propPath.size() - 8, 8) != "xml:lang") {
  ------------------
  |  Branch (727:15): [True: 0, False: 1.50k]
  ------------------
  728|      0|            throw Error(ErrorCode::kerDecodeLangAltQualifierFailed, propPath, opt);
  729|      0|          }
  730|  1.50k|          val->value_[propValue] = std::move(text);
  731|  1.50k|        }
  732|  1.15k|        xmpData.addUnlocked(*key, val.get(), lock);
  733|  1.15k|        continue;
  734|  1.15k|      }
  735|  52.8k|      if (XMP_PropIsArray(opt) && !XMP_PropHasQualifiers(opt) && !XMP_ArrayIsAltText(opt)) {
  ------------------
  |  Branch (735:11): [True: 3.29k, False: 49.5k]
  |  Branch (735:35): [True: 3.29k, False: 0]
  |  Branch (735:66): [True: 3.29k, False: 0]
  ------------------
  736|       |        // Check if all elements are simple
  737|  3.29k|        bool simpleArray = true;
  738|  3.29k|        SXMPIterator aIter(meta, schemaNs.c_str(), propPath.c_str());
  739|  3.29k|        std::string aSchemaNs;
  740|  3.29k|        std::string aPropPath;
  741|  3.29k|        std::string aPropValue;
  742|  3.29k|        XMP_OptionBits aOpt = 0;
  743|  18.2k|        while (aIter.Next(&aSchemaNs, &aPropPath, &aPropValue, &aOpt)) {
  ------------------
  |  Branch (743:16): [True: 15.3k, False: 2.96k]
  ------------------
  744|  15.3k|          if (propPath == aPropPath)
  ------------------
  |  Branch (744:15): [True: 3.29k, False: 12.0k]
  ------------------
  745|  3.29k|            continue;
  746|  12.0k|          if (!XMP_PropIsSimple(aOpt) || XMP_PropHasQualifiers(aOpt) || XMP_PropIsQualifier(aOpt) ||
  ------------------
  |  Branch (746:15): [True: 270, False: 11.7k]
  |  Branch (746:42): [True: 66, False: 11.6k]
  |  Branch (746:73): [True: 0, False: 11.6k]
  ------------------
  747|  12.0k|              XMP_NodeIsSchema(aOpt) || XMP_PropIsAlias(aOpt)) {
  ------------------
  |  Branch (747:15): [True: 0, False: 11.6k]
  |  Branch (747:41): [True: 0, False: 11.6k]
  ------------------
  748|    336|            simpleArray = false;
  749|    336|            break;
  750|    336|          }
  751|  12.0k|        }
  752|  3.29k|        if (simpleArray) {
  ------------------
  |  Branch (752:13): [True: 2.96k, False: 336]
  ------------------
  753|       |          // Read the array into an XmpArrayValue
  754|  2.96k|          auto val = std::make_unique<XmpArrayValue>(arrayValueTypeId(opt));
  755|  2.96k|          XMP_Index count = meta.CountArrayItems(schemaNs.c_str(), propPath.c_str());
  756|  14.6k|          while (count-- > 0) {
  ------------------
  |  Branch (756:18): [True: 11.6k, False: 2.96k]
  ------------------
  757|  11.6k|            iter.Next(&schemaNs, &propPath, &propValue, &opt);
  758|  11.6k|            printNode(schemaNs, propPath, propValue, opt);
  759|  11.6k|            val->read(propValue);
  760|  11.6k|          }
  761|  2.96k|          xmpData.addUnlocked(*key, val.get(), lock);
  762|  2.96k|          continue;
  763|  2.96k|        }
  764|  3.29k|      }
  765|       |
  766|  49.8k|      auto val = std::make_unique<XmpTextValue>();
  767|  49.8k|      if (XMP_PropIsStruct(opt) || XMP_PropIsArray(opt)) {
  ------------------
  |  Branch (767:11): [True: 2.69k, False: 47.2k]
  |  Branch (767:36): [True: 336, False: 46.8k]
  ------------------
  768|       |        // Create a metadatum with only XMP options
  769|  3.02k|        val->setXmpArrayType(xmpArrayType(opt));
  770|  3.02k|        val->setXmpStruct(xmpStruct(opt));
  771|  3.02k|        xmpData.addUnlocked(*key, val.get(), lock);
  772|  3.02k|        continue;
  773|  3.02k|      }
  774|  46.8k|      if (XMP_PropIsSimple(opt) || XMP_PropIsQualifier(opt)) {
  ------------------
  |  Branch (774:11): [True: 46.8k, False: 0]
  |  Branch (774:36): [True: 0, False: 0]
  ------------------
  775|  46.8k|        val->read(propValue);
  776|  46.8k|        xmpData.addUnlocked(*key, val.get(), lock);
  777|  46.8k|        continue;
  778|  46.8k|      }
  779|       |      // Don't let any node go by unnoticed
  780|      0|      throw Error(ErrorCode::kerUnhandledXmpNode, key->key(), opt);
  781|  46.8k|    }  // iterate through all XMP nodes
  782|       |
  783|  10.5k|    return 0;
  784|  10.5k|  }
  785|  11.4k|#ifndef SUPPRESS_WARNINGS
  786|  11.4k|  catch (const Error& e) {
  787|      7|    if (e.code() == ErrorCode::kerXMPToolkitError) {
  ------------------
  |  Branch (787:9): [True: 0, False: 7]
  ------------------
  788|       |      // Initialization failures caught above, this handles other XMP errors if any wrapped in Error
  789|      0|    }
  790|      7|    throw;
  791|  3.42k|  } catch (const XMP_Error& e) {
  792|  3.42k|    EXV_ERROR << Error(ErrorCode::kerXMPToolkitError, e.GetID(), e.GetErrMsg()) << "\n";
  ------------------
  |  |  142|  3.42k|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 3.42k]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|  3.42k|  LogMsg(LogMsg::error).os()
  ------------------
  793|  3.42k|    xmpData.clear();
  794|  3.42k|    return 3;
  795|  3.42k|  }
  796|       |#else
  797|       |  catch (const XMP_Error&) {
  798|       |    xmpData.clear();
  799|       |    return 3;
  800|       |  }
  801|       |#endif  // SUPPRESS_WARNINGS
  802|  11.4k|}  // XmpParser::decode
_ZN5Exiv29XmpParser6encodeERNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS_7XmpDataEtj:
  816|  4.40k|int XmpParser::encode(std::string& xmpPacket, const XmpData& xmpData, uint16_t formatFlags, uint32_t padding) {
  817|  4.40k|  try {
  818|       |    // Acquire Giant Lock
  819|  4.40k|    XmpProperties::XmpLock lock;
  820|  4.40k|    try {
  821|  4.40k|      xmpToolkitEnsureInitialized();
  822|  4.40k|    } catch (const Error&) {
  823|      0|#ifndef SUPPRESS_WARNINGS
  824|      0|      EXV_ERROR << "XMP toolkit initialization failed.\n";
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
  825|      0|#endif
  826|      0|      return 2;
  827|      0|    }
  828|       |
  829|  4.40k|    if (xmpData.emptyUnlocked(lock)) {
  ------------------
  |  Branch (829:9): [True: 4.40k, False: 0]
  ------------------
  830|  4.40k|      xmpPacket.clear();
  831|  4.40k|      return 0;
  832|  4.40k|    }  // We are holding the Giant Lock, so we can iterate nsRegistry_ safely.
  833|       |    // XmpProperties interactions must go through Unlocked/impl methods to avoid deadlocks.
  834|      0|    for (const auto& [xmp, uri] : XmpProperties::nsRegistry_) {
  ------------------
  |  Branch (834:33): [True: 0, False: 0]
  ------------------
  835|       |#ifdef EXIV2_DEBUG_MESSAGES
  836|       |      std::cerr << "Registering " << uri.prefix_ << " : " << xmp << "\n";
  837|       |#endif
  838|       |      // registerNsImpl is safe since we hold the lock
  839|      0|      registerNsImpl(xmp, uri.prefix_);
  840|      0|    }
  841|       |
  842|      0|    SXMPMeta meta;
  843|      0|    for (const auto& xmp : xmpData) {
  ------------------
  |  Branch (843:26): [True: 0, False: 0]
  ------------------
  844|       |      // Must use Unlocked version of ns() because we hold the lock!
  845|      0|      const std::string ns = XmpProperties::nsUnlocked(xmp.groupName(), lock);
  846|      0|      XMP_OptionBits options = 0;
  847|       |
  848|      0|      if (xmp.typeId() == langAlt) {
  ------------------
  |  Branch (848:11): [True: 0, False: 0]
  ------------------
  849|       |        // Encode Lang Alt property
  850|      0|        const auto la = dynamic_cast<const LangAltValue*>(&xmp.value());
  851|      0|        if (!la)
  ------------------
  |  Branch (851:13): [True: 0, False: 0]
  ------------------
  852|      0|          throw Error(ErrorCode::kerEncodeLangAltPropertyFailed, xmp.key());
  853|       |
  854|      0|        int idx = 1;
  855|      0|        for (const auto& [lang, specs] : la->value_) {
  ------------------
  |  Branch (855:40): [True: 0, False: 0]
  ------------------
  856|      0|          if (!specs.empty()) {  // remove lang specs with no value
  ------------------
  |  Branch (856:15): [True: 0, False: 0]
  ------------------
  857|      0|            printNode(ns, xmp.tagName(), specs, 0);
  858|      0|            meta.AppendArrayItem(ns.c_str(), xmp.tagName().c_str(), kXMP_PropArrayIsAlternate, specs.c_str());
  859|      0|            const std::string item = xmp.tagName() + "[" + toString(idx++) + "]";
  860|      0|            meta.SetQualifier(ns.c_str(), item.c_str(), kXMP_NS_XML, "lang", lang.c_str());
  861|      0|          }
  862|      0|        }
  863|      0|        continue;
  864|      0|      }
  865|       |
  866|       |      // Todo: Xmpdatum should have an XmpValue, not a Value
  867|      0|      const auto val = dynamic_cast<const XmpValue*>(&xmp.value());
  868|      0|      if (!val)
  ------------------
  |  Branch (868:11): [True: 0, False: 0]
  ------------------
  869|      0|        throw Error(ErrorCode::kerInvalidKeyXmpValue, xmp.key(), xmp.typeName());
  870|      0|      options = xmpArrayOptionBits(val->xmpArrayType()) | xmpArrayOptionBits(val->xmpStruct());
  871|      0|      if (xmp.typeId() == xmpBag || xmp.typeId() == xmpSeq || xmp.typeId() == xmpAlt) {
  ------------------
  |  Branch (871:11): [True: 0, False: 0]
  |  Branch (871:37): [True: 0, False: 0]
  |  Branch (871:63): [True: 0, False: 0]
  ------------------
  872|      0|        printNode(ns, xmp.tagName(), "", options);
  873|      0|        meta.SetProperty(ns.c_str(), xmp.tagName().c_str(), nullptr, options);
  874|      0|        for (size_t idx = 0; idx < xmp.count(); ++idx) {
  ------------------
  |  Branch (874:30): [True: 0, False: 0]
  ------------------
  875|      0|          const std::string item = xmp.tagName() + "[" + toString(idx + 1) + "]";
  876|      0|          printNode(ns, item, xmp.toString(static_cast<long>(idx)), 0);
  877|      0|          meta.SetProperty(ns.c_str(), item.c_str(), xmp.toString(static_cast<long>(idx)).c_str());
  878|      0|        }
  879|      0|        continue;
  880|      0|      }
  881|      0|      if (xmp.typeId() == xmpText) {
  ------------------
  |  Branch (881:11): [True: 0, False: 0]
  ------------------
  882|      0|        const auto xt = dynamic_cast<const XmpTextValue*>(&xmp.value());
  883|      0|        if (xmp.count() == 0 || xt->xmpStruct() != XmpValue::xsNone || xt->xmpArrayType() != XmpValue::xaNone) {
  ------------------
  |  Branch (883:13): [True: 0, False: 0]
  |  Branch (883:33): [True: 0, False: 0]
  |  Branch (883:72): [True: 0, False: 0]
  ------------------
  884|      0|          printNode(ns, xmp.tagName(), "", options);
  885|      0|          meta.SetProperty(ns.c_str(), xmp.tagName().c_str(), nullptr, options);
  886|      0|        } else {
  887|      0|          printNode(ns, xmp.tagName(), xmp.toString(0), options);
  888|      0|          meta.SetProperty(ns.c_str(), xmp.tagName().c_str(), xmp.toString(0).c_str(), options);
  889|      0|        }
  890|      0|        continue;
  891|      0|      }
  892|       |      // Don't let any Xmpdatum go by unnoticed
  893|      0|      throw Error(ErrorCode::kerUnhandledXmpdatum, xmp.tagName(), xmp.typeName());
  894|      0|    }
  895|      0|    std::string tmpPacket;
  896|      0|    meta.SerializeToBuffer(&tmpPacket, xmpFormatOptionBits(static_cast<XmpFormatFlags>(formatFlags)),
  897|      0|                           padding);  // throws
  898|      0|    xmpPacket = std::move(tmpPacket);
  899|       |
  900|      0|    return 0;
  901|      0|  }
  902|  4.40k|#ifndef SUPPRESS_WARNINGS
  903|  4.40k|  catch (const Error& /* e */) {
  904|      0|    throw;
  905|      0|  } catch (const XMP_Error& e) {
  906|      0|    EXV_ERROR << Error(ErrorCode::kerXMPToolkitError, e.GetID(), e.GetErrMsg()) << "\n";
  ------------------
  |  |  142|      0|  if (LogMsg::error >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (142:7): [True: 0, False: 0]
  |  |  |  Branch (142:43): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  LogMsg(LogMsg::error).os()
  ------------------
  907|      0|    return 3;
  908|      0|  }
  909|       |#else
  910|       |  catch (const XMP_Error&) {
  911|       |    return 3;
  912|       |  }
  913|       |#endif  // SUPPRESS_WARNINGS
  914|  4.40k|}  // XmpParser::encode
_ZN5Exiv29XmpParser10makeXmpKeyERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_RKNS_13XmpProperties7XmpLockE:
 1076|  54.0k|                                                      const XmpProperties::XmpLock& lock) {
 1077|  54.0k|  std::string property;
 1078|  54.0k|  std::string::size_type idx = propPath.find(':');
 1079|  54.0k|  if (idx == std::string::npos) {
  ------------------
  |  Branch (1079:7): [True: 0, False: 54.0k]
  ------------------
 1080|      0|    throw Exiv2::Error(Exiv2::ErrorCode::kerPropertyNameIdentificationFailed, propPath, schemaNs);
 1081|      0|  }
 1082|       |  // Don't worry about out_of_range, XMP parser takes care of this
 1083|  54.0k|  property = propPath.substr(idx + 1);
 1084|  54.0k|  std::string prefix = Exiv2::XmpProperties::prefixUnlocked(schemaNs, lock);
 1085|  54.0k|  if (prefix.empty()) {
  ------------------
  |  Branch (1085:7): [True: 0, False: 54.0k]
  ------------------
 1086|      0|    throw Exiv2::Error(Exiv2::ErrorCode::kerNoPrefixForNamespace, propPath, schemaNs);
 1087|      0|  }
 1088|  54.0k|  return Exiv2::XmpKey::UniquePtr(new Exiv2::XmpKey(prefix, property, lock));
 1089|  54.0k|}  // makeXmpKey
xmp.cpp:_ZNK12_GLOBAL__N_112FindXmpdatumclERKN5Exiv28XmpdatumE:
  201|  6.53M|  bool operator()(const Exiv2::Xmpdatum& xmpdatum) const {
  202|  6.53M|    return key_ == xmpdatum.key();
  203|  6.53M|  }
xmp.cpp:_ZN12_GLOBAL__N_112FindXmpdatumC2ERKN5Exiv26XmpKeyE:
  195|   844k|  explicit FindXmpdatum(const Exiv2::XmpKey& key) : key_(key.key()) {
  196|   844k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator5checkEPKcm:
   66|  10.5k|  static void check(const char* buf, size_t buflen) {
   67|  10.5k|    XMLValidator validator;
   68|  10.5k|    validator.check_internal(buf, buflen);
   69|  10.5k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidatorC2Ev:
   77|  10.5k|  XMLValidator() : parser_(XML_ParserCreateNS(nullptr, '@')) {
   78|  10.5k|    if (!parser_) {
  ------------------
  |  Branch (78:9): [True: 0, False: 10.5k]
  ------------------
   79|      0|      throw Error(ErrorCode::kerXMPToolkitError, "Could not create expat parser");
   80|      0|    }
   81|  10.5k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator14check_internalEPKcm:
  102|  10.5k|  void check_internal(const char* buf, size_t buflen) {
  103|  10.5k|    if (buflen > static_cast<size_t>(std::numeric_limits<int>::max())) {
  ------------------
  |  Branch (103:9): [True: 0, False: 10.5k]
  ------------------
  104|      0|      throw Error(ErrorCode::kerXMPToolkitError, "Buffer length is greater than INT_MAX");
  105|      0|    }
  106|       |
  107|  10.5k|    XML_SetUserData(parser_, this);
  108|  10.5k|    XML_SetElementHandler(parser_, startElement_cb, endElement_cb);
  109|  10.5k|    XML_SetNamespaceDeclHandler(parser_, startNamespace_cb, endNamespace_cb);
  110|  10.5k|    XML_SetStartDoctypeDeclHandler(parser_, startDTD_cb);
  111|       |
  112|  10.5k|    if (XML_Parse(parser_, buf, static_cast<int>(buflen), true) == XML_STATUS_ERROR) {
  ------------------
  |  Branch (112:9): [True: 1.74k, False: 8.77k]
  ------------------
  113|  1.74k|      setError(XML_ErrorString(XML_GetErrorCode(parser_)));
  114|  1.74k|    }
  115|       |
  116|  10.5k|    if (haserror_) {
  ------------------
  |  Branch (116:9): [True: 1.74k, False: 8.77k]
  ------------------
  117|  1.74k|      throw XMP_Error(kXMPErr_BadXML, "Error in XMLValidator");
  118|  1.74k|    }
  119|  10.5k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator15startElement_cbEPvPKcPS3_:
  158|  65.3k|  static void XMLCALL startElement_cb(void* userData, const XML_Char* name, const XML_Char** attrs) noexcept {
  159|  65.3k|    static_cast<XMLValidator*>(userData)->startElement(name, attrs);
  160|  65.3k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator12startElementEPKcPS2_:
  121|  65.3k|  void startElement(const XML_Char*, const XML_Char**) noexcept {
  122|  65.3k|    if (element_depth_ > max_recursion_limit_) {
  ------------------
  |  Branch (122:9): [True: 230, False: 65.1k]
  ------------------
  123|    230|      setError("Too deeply nested");
  124|    230|    }
  125|  65.3k|    ++element_depth_;
  126|  65.3k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator13endElement_cbEPvPKc:
  164|  54.6k|  static void XMLCALL endElement_cb(void* userData, const XML_Char* name) noexcept {
  165|  54.6k|    static_cast<XMLValidator*>(userData)->endElement(name);
  166|  54.6k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator10endElementEPKc:
  128|  54.6k|  void endElement(const XML_Char*) noexcept {
  129|  54.6k|    if (element_depth_ > 0) {
  ------------------
  |  Branch (129:9): [True: 54.6k, False: 0]
  ------------------
  130|  54.6k|      --element_depth_;
  131|  54.6k|    } else {
  132|      0|      setError("Negative depth");
  133|      0|    }
  134|  54.6k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator17startNamespace_cbEPvPKcS3_:
  170|  45.3k|  static void XMLCALL startNamespace_cb(void* userData, const XML_Char* prefix, const XML_Char* uri) noexcept {
  171|  45.3k|    static_cast<XMLValidator*>(userData)->startNamespace(prefix, uri);
  172|  45.3k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator14startNamespaceEPKcS2_:
  136|  45.3k|  void startNamespace(const XML_Char*, const XML_Char*) noexcept {
  137|  45.3k|    if (namespace_depth_ > max_recursion_limit_) {
  ------------------
  |  Branch (137:9): [True: 430, False: 44.8k]
  ------------------
  138|    430|      setError("Too deeply nested");
  139|    430|    }
  140|  45.3k|    ++namespace_depth_;
  141|  45.3k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator15endNamespace_cbEPvPKc:
  176|  35.7k|  static void XMLCALL endNamespace_cb(void* userData, const XML_Char* prefix) noexcept {
  177|  35.7k|    static_cast<XMLValidator*>(userData)->endNamespace(prefix);
  178|  35.7k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator12endNamespaceEPKc:
  143|  35.7k|  void endNamespace(const XML_Char*) noexcept {
  144|  35.7k|    if (namespace_depth_ > 0) {
  ------------------
  |  Branch (144:9): [True: 35.7k, False: 0]
  ------------------
  145|  35.7k|      --namespace_depth_;
  146|  35.7k|    } else {
  147|      0|      setError("Negative depth");
  148|      0|    }
  149|  35.7k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidator8setErrorEPKc:
   87|  2.40k|  void setError(const char* msg) {
   88|  2.40k|    const XML_Size errlinenum = XML_GetCurrentLineNumber(parser_);
   89|  2.40k|    const XML_Size errcolnum = XML_GetCurrentColumnNumber(parser_);
   90|  2.40k|#ifndef SUPPRESS_WARNINGS
   91|  2.40k|    EXV_INFO << "Invalid XML at line " << errlinenum << ", column " << errcolnum << ": " << msg << "\n";
  ------------------
  |  |  134|  2.40k|  if (LogMsg::info >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (134:7): [True: 0, False: 2.40k]
  |  |  |  Branch (134:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  135|  2.40k|  LogMsg(LogMsg::info).os()
  ------------------
   92|  2.40k|#endif
   93|       |    // If this is the first error, then save it.
   94|  2.40k|    if (!haserror_) {
  ------------------
  |  Branch (94:9): [True: 1.74k, False: 660]
  ------------------
   95|  1.74k|      haserror_ = true;
   96|  1.74k|      errmsg_ = msg;
   97|  1.74k|      errlinenum_ = errlinenum;
   98|  1.74k|      errcolnum_ = errcolnum;
   99|  1.74k|    }
  100|  2.40k|  }
xmp.cpp:_ZN12_GLOBAL__N_112XMLValidatorD2Ev:
   83|  10.5k|  ~XMLValidator() {
   84|  10.5k|    XML_ParserFree(parser_);
   85|  10.5k|  }
xmp.cpp:_ZN12_GLOBAL__N_19xmpStructEj:
  933|  3.02k|Exiv2::XmpValue::XmpStruct xmpStruct(XMP_OptionBits opt) {
  934|  3.02k|  Exiv2::XmpValue::XmpStruct var(Exiv2::XmpValue::xsNone);
  935|  3.02k|  if (XMP_PropIsStruct(opt)) {
  ------------------
  |  Branch (935:7): [True: 2.69k, False: 336]
  ------------------
  936|  2.69k|    var = Exiv2::XmpValue::xsStruct;
  937|  2.69k|  }
  938|  3.02k|  return var;
  939|  3.02k|}
xmp.cpp:_ZN12_GLOBAL__N_116arrayValueTypeIdEj:
  953|  5.98k|Exiv2::TypeId arrayValueTypeId(XMP_OptionBits opt) {
  954|  5.98k|  Exiv2::TypeId typeId(Exiv2::invalidTypeId);
  955|  5.98k|  if (XMP_PropIsArray(opt)) {
  ------------------
  |  Branch (955:7): [True: 3.29k, False: 2.69k]
  ------------------
  956|  3.29k|    if (XMP_ArrayIsAlternate(opt))
  ------------------
  |  Branch (956:9): [True: 84, False: 3.21k]
  ------------------
  957|     84|      typeId = Exiv2::xmpAlt;
  958|  3.21k|    else if (XMP_ArrayIsOrdered(opt))
  ------------------
  |  Branch (958:14): [True: 2.72k, False: 487]
  ------------------
  959|  2.72k|      typeId = Exiv2::xmpSeq;
  960|    487|    else if (XMP_ArrayIsUnordered(opt))
  ------------------
  |  Branch (960:14): [True: 487, False: 0]
  ------------------
  961|    487|      typeId = Exiv2::xmpBag;
  962|  3.29k|  }
  963|  5.98k|  return typeId;
  964|  5.98k|}
xmp.cpp:_ZN12_GLOBAL__N_112xmpArrayTypeEj:
  966|  3.02k|Exiv2::XmpValue::XmpArrayType xmpArrayType(XMP_OptionBits opt) {
  967|  3.02k|  return Exiv2::XmpValue::xmpArrayType(arrayValueTypeId(opt));
  968|  3.02k|}
xmp.cpp:_ZN12_GLOBAL__N_19printNodeERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEES8_S8_j:
 1069|  77.4k|void printNode(const std::string&, const std::string&, const std::string&, XMP_OptionBits) {
 1070|  77.4k|}
_ZN5Exiv28Xmpdatum4ImplD2Ev:
  244|   251k|  ~Impl() = default;

_ZN5Exiv225XmpToolkitLifetimeManagerC2Ev:
   33|      1|  XmpToolkitLifetimeManager() {
   34|      1|    if (SXMPMeta::Initialize()) {
  ------------------
  |  Branch (34:9): [True: 1, False: 0]
  ------------------
   35|       |#ifdef EXV_ADOBE_XMPSDK
   36|       |      SXMPMeta::RegisterNamespace("http://ns.adobe.com/lightroom/1.0/", "lr", nullptr);
   37|       |      SXMPMeta::RegisterNamespace("http://rs.tdwg.org/dwc/index.htm", "dwc", nullptr);
   38|       |      SXMPMeta::RegisterNamespace("http://purl.org/dc/terms/", "dcterms", nullptr);
   39|       |      SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/1.0/", "digiKam", nullptr);
   40|       |      SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/kipi/1.0/", "kipi", nullptr);
   41|       |      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.0/", "MicrosoftPhoto", nullptr);
   42|       |      SXMPMeta::RegisterNamespace("http://ns.acdsee.com/iptc/1.0/", "acdsee", nullptr);
   43|       |      SXMPMeta::RegisterNamespace("http://iptc.org/std/Iptc4xmpExt/2008-02-29/", "iptcExt", nullptr);
   44|       |      SXMPMeta::RegisterNamespace("http://ns.useplus.org/ldf/xmp/1.0/", "plus", nullptr);
   45|       |      SXMPMeta::RegisterNamespace("http://ns.iview-multimedia.com/mediapro/1.0/", "mediapro", nullptr);
   46|       |      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/expressionmedia/1.0/", "expressionmedia", nullptr);
   47|       |      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/", "MP", nullptr);
   48|       |      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/RegionInfo#", "MPRI", nullptr);
   49|       |      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/Region#", "MPReg", nullptr);
   50|       |      SXMPMeta::RegisterNamespace("http://ns.google.com/photos/1.0/panorama/", "GPano", nullptr);
   51|       |      SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/regions/", "mwg-rs", nullptr);
   52|       |      SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/keywords/", "mwg-kw", nullptr);
   53|       |      SXMPMeta::RegisterNamespace("http://ns.adobe.com/xmp/sType/Area#", "stArea", nullptr);
   54|       |      SXMPMeta::RegisterNamespace("http://cipa.jp/exif/1.0/", "exifEX", nullptr);
   55|       |      SXMPMeta::RegisterNamespace("http://ns.adobe.com/camera-raw-saved-settings/1.0/", "crss", nullptr);
   56|       |      SXMPMeta::RegisterNamespace("http://www.audio/", "audio", nullptr);
   57|       |      SXMPMeta::RegisterNamespace("http://www.video/", "video", nullptr);
   58|       |#else
   59|      1|      SXMPMeta::RegisterNamespace("http://ns.adobe.com/lightroom/1.0/", "lr");
   60|      1|      SXMPMeta::RegisterNamespace("http://rs.tdwg.org/dwc/index.htm", "dwc");
   61|      1|      SXMPMeta::RegisterNamespace("http://purl.org/dc/terms/", "dcterms");
   62|      1|      SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/1.0/", "digiKam");
   63|      1|      SXMPMeta::RegisterNamespace("http://www.digikam.org/ns/kipi/1.0/", "kipi");
   64|      1|      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.0/", "MicrosoftPhoto");
   65|      1|      SXMPMeta::RegisterNamespace("http://ns.acdsee.com/iptc/1.0/", "acdsee");
   66|      1|      SXMPMeta::RegisterNamespace("http://iptc.org/std/Iptc4xmpExt/2008-02-29/", "iptcExt");
   67|      1|      SXMPMeta::RegisterNamespace("http://ns.useplus.org/ldf/xmp/1.0/", "plus");
   68|      1|      SXMPMeta::RegisterNamespace("http://ns.iview-multimedia.com/mediapro/1.0/", "mediapro");
   69|      1|      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/expressionmedia/1.0/", "expressionmedia");
   70|      1|      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/", "MP");
   71|      1|      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/RegionInfo#", "MPRI");
   72|      1|      SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/Region#", "MPReg");
   73|      1|      SXMPMeta::RegisterNamespace("http://ns.google.com/photos/1.0/panorama/", "GPano");
   74|      1|      SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/regions/", "mwg-rs");
   75|      1|      SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/keywords/", "mwg-kw");
   76|      1|      SXMPMeta::RegisterNamespace("http://ns.adobe.com/xmp/sType/Area#", "stArea");
   77|      1|      SXMPMeta::RegisterNamespace("http://cipa.jp/exif/1.0/", "exifEX");
   78|      1|      SXMPMeta::RegisterNamespace("http://ns.adobe.com/camera-raw-saved-settings/1.0/", "crss");
   79|      1|      SXMPMeta::RegisterNamespace("http://www.audio/", "audio");
   80|      1|      SXMPMeta::RegisterNamespace("http://www.video/", "video");
   81|      1|#endif
   82|      1|    } else {
   83|      0|      throw Error(ErrorCode::kerXMPToolkitError, 2, "Failed to initialize XMP Toolkit");
   84|      0|    }
   85|      1|  }
_ZN5Exiv225XmpToolkitLifetimeManagerD2Ev:
   87|      1|  ~XmpToolkitLifetimeManager() {
   88|       |    // Use Unsafe version to avoid acquiring mutex during static destruction.
   89|       |    // This is safe because static destruction is single-threaded per C++ standard.
   90|      1|    XmpProperties::unregisterAllNsNoLock(XmpProperties::LifetimeKey{});
   91|      1|    SXMPMeta::Terminate();
   92|      1|  }

_ZN5Exiv210XmpSidecarC2ENSt3__110unique_ptrINS_7BasicIoENS1_14default_deleteIS3_EEEEb:
   29|  1.21k|XmpSidecar::XmpSidecar(BasicIo::UniquePtr io, bool create) : Image(ImageType::xmp, mdXmp, std::move(io)) {
   30|  1.21k|  if (create && io_->open() == 0) {
  ------------------
  |  Branch (30:7): [True: 0, False: 1.21k]
  |  Branch (30:17): [True: 0, False: 0]
  ------------------
   31|      0|    IoCloser closer(*io_);
   32|      0|    io_->write(reinterpret_cast<const byte*>(xmlHeader), xmlHdrCnt);
   33|      0|  }
   34|  1.21k|}  // XmpSidecar::XmpSidecar
_ZNK5Exiv210XmpSidecar8mimeTypeEv:
   36|  3.46k|std::string XmpSidecar::mimeType() const {
   37|  3.46k|  return "application/rdf+xml";
   38|  3.46k|}
_ZN5Exiv210XmpSidecar12readMetadataEv:
   45|  1.21k|void XmpSidecar::readMetadata() {
   46|       |#ifdef EXIV2_DEBUG_MESSAGES
   47|       |  std::cerr << "Reading XMP file " << io_->path() << "\n";
   48|       |#endif
   49|  1.21k|  if (io_->open() != 0) {
  ------------------
  |  Branch (49:7): [True: 0, False: 1.21k]
  ------------------
   50|      0|    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
   51|      0|  }
   52|  1.21k|  IoCloser closer(*io_);
   53|       |  // Ensure that this is the correct image type
   54|  1.21k|  if (!isXmpType(*io_, false)) {
  ------------------
  |  Branch (54:7): [True: 0, False: 1.21k]
  ------------------
   55|      0|    if (io_->error() || io_->eof())
  ------------------
  |  Branch (55:9): [True: 0, False: 0]
  |  Branch (55:25): [True: 0, False: 0]
  ------------------
   56|      0|      throw Error(ErrorCode::kerFailedToReadImageData);
   57|      0|    throw Error(ErrorCode::kerNotAnImage, "XMP");
   58|      0|  }
   59|       |  // Read the XMP packet from the IO stream
   60|  1.21k|  std::string xmpPacket;
   61|  1.21k|  const long len = 64 * 1024;
   62|  1.21k|  auto buf = std::make_unique<byte[]>(len);
   63|  2.65k|  while (auto l = io_->read(buf.get(), len)) {
  ------------------
  |  Branch (63:15): [True: 1.44k, False: 1.21k]
  ------------------
   64|  1.44k|    xmpPacket.append(reinterpret_cast<char*>(buf.get()), l);
   65|  1.44k|  }
   66|  1.21k|  if (io_->error())
  ------------------
  |  Branch (66:7): [True: 0, False: 1.21k]
  ------------------
   67|      0|    throw Error(ErrorCode::kerFailedToReadImageData);
   68|  1.21k|  clearMetadata();
   69|  1.21k|  xmpPacket_ = std::move(xmpPacket);
   70|  1.21k|  if (!xmpPacket_.empty() && XmpParser::decode(xmpData_, xmpPacket_)) {
  ------------------
  |  Branch (70:7): [True: 1.20k, False: 1]
  |  Branch (70:30): [True: 249, False: 960]
  ------------------
   71|    249|#ifndef SUPPRESS_WARNINGS
   72|    249|    EXV_WARNING << "Failed to decode XMP metadata.\n";
  ------------------
  |  |  138|    249|  if (LogMsg::warn >= LogMsg::level() && LogMsg::handler()) \
  |  |  ------------------
  |  |  |  Branch (138:7): [True: 0, False: 249]
  |  |  |  Branch (138:42): [True: 0, False: 0]
  |  |  ------------------
  |  |  139|    249|  LogMsg(LogMsg::warn).os()
  ------------------
   73|    249|#endif
   74|    249|  }
   75|       |
   76|       |  // #1112 - store dates to deal with loss of TZ information during conversions
   77|  5.31k|  for (const auto& xmp : xmpData_) {
  ------------------
  |  Branch (77:24): [True: 5.31k, False: 1.21k]
  ------------------
   78|  5.31k|    std::string key(xmp.key());
   79|  5.31k|    if (Internal::contains(key, "Date")) {
  ------------------
  |  Branch (79:9): [True: 122, False: 5.18k]
  ------------------
   80|    122|      dates_[key] = xmp.value().toString();
   81|    122|    }
   82|  5.31k|  }
   83|       |
   84|  1.21k|  copyXmpToIptc(xmpData_, iptcData_);
   85|  1.21k|  copyXmpToExif(xmpData_, exifData_);
   86|  1.21k|}  // XmpSidecar::readMetadata
_ZN5Exiv214newXmpInstanceENSt3__110unique_ptrINS_7BasicIoENS0_14default_deleteIS2_EEEEb:
  152|  1.21k|Image::UniquePtr newXmpInstance(BasicIo::UniquePtr io, bool create) {
  153|  1.21k|  auto image = std::make_unique<XmpSidecar>(std::move(io), create);
  154|  1.21k|  if (!image->good()) {
  ------------------
  |  Branch (154:7): [True: 0, False: 1.21k]
  ------------------
  155|      0|    return nullptr;
  156|      0|  }
  157|  1.21k|  return image;
  158|  1.21k|}
_ZN5Exiv29isXmpTypeERNS_7BasicIoEb:
  160|  18.9k|bool isXmpType(BasicIo& iIo, bool advance) {
  161|       |  /*
  162|       |    Check if the file starts with an optional XML declaration followed by
  163|       |    either an XMP header (<?xpacket ... ?>) or an <x:xmpmeta> element.
  164|       |
  165|       |    In addition, in order for empty XmpSidecar objects as created by
  166|       |    Exiv2 to pass the test, just an XML header is also considered ok.
  167|       |   */
  168|  18.9k|  const int32_t len = 80;
  169|  18.9k|  byte buf[len];
  170|  18.9k|  iIo.read(buf, xmlHdrCnt + 1);
  171|  18.9k|  if (iIo.eof() && 0 == strncmp(reinterpret_cast<const char*>(buf), xmlHeader, xmlHdrCnt)) {
  ------------------
  |  Branch (171:7): [True: 314, False: 18.6k]
  |  Branch (171:20): [True: 3, False: 311]
  ------------------
  172|      3|    return true;
  173|      3|  }
  174|  18.9k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (174:7): [True: 0, False: 18.9k]
  |  Branch (174:22): [True: 311, False: 18.6k]
  ------------------
  175|    311|    return false;
  176|    311|  }
  177|  18.6k|  iIo.read(buf + xmlHdrCnt + 1, len - xmlHdrCnt - 1);
  178|  18.6k|  if (iIo.error() || iIo.eof()) {
  ------------------
  |  Branch (178:7): [True: 0, False: 18.6k]
  |  Branch (178:22): [True: 19, False: 18.6k]
  ------------------
  179|     19|    return false;
  180|     19|  }
  181|       |  // Skip leading BOM
  182|  18.6k|  int32_t start = 0;
  183|  18.6k|  if (0 == strncmp(reinterpret_cast<const char*>(buf), "\xef\xbb\xbf", 3)) {
  ------------------
  |  Branch (183:7): [True: 84, False: 18.5k]
  ------------------
  184|     84|    start = 3;
  185|     84|  }
  186|  18.6k|  bool rc = false;
  187|  18.6k|  std::string head(reinterpret_cast<const char*>(buf + start), len - start);
  188|  18.6k|  if (head.starts_with("<?xml")) {
  ------------------
  |  Branch (188:7): [True: 91, False: 18.5k]
  ------------------
  189|       |    // Forward to the next tag
  190|     91|    auto it = std::find(head.begin() + 5, head.end(), '<');
  191|     91|    if (it != head.end())
  ------------------
  |  Branch (191:9): [True: 81, False: 10]
  ------------------
  192|     81|      head = head.substr(std::distance(head.begin(), it));
  193|     91|  }
  194|  18.6k|  if (head.starts_with("<?xpacket") || head.starts_with("<x:xmpmeta")) {
  ------------------
  |  Branch (194:7): [True: 2.58k, False: 16.0k]
  |  Branch (194:40): [True: 1.04k, False: 14.9k]
  ------------------
  195|  3.62k|    rc = true;
  196|  3.62k|  }
  197|  18.6k|  if (!advance || !rc) {
  ------------------
  |  Branch (197:7): [True: 18.6k, False: 0]
  |  Branch (197:19): [True: 0, False: 0]
  ------------------
  198|  18.6k|    iIo.seek(-(len - start), BasicIo::cur);  // Swallow the BOM
  199|  18.6k|  }
  200|  18.6k|  return rc;
  201|  18.6k|}

XMP_NewExpatAdapter:
   68|  8.77k|{
   69|  8.77k|	return new ExpatAdapter;
   70|  8.77k|}	// XMP_NewExpatAdapter
_ZN12ExpatAdapterC2Ev:
   74|  8.77k|ExpatAdapter::ExpatAdapter() : parser(0)
   75|  8.77k|{
   76|       |
   77|       |	#if XMP_DebugBuild
   78|       |		this->elemNesting = 0;
   79|       |		#if DumpXMLParseEvents
   80|       |			if ( this->parseLog == 0 ) this->parseLog = stdout;
   81|       |		#endif
   82|       |	#endif
   83|       |
   84|  8.77k|	this->parser = XML_ParserCreateNS ( 0, FullNameSeparator );
  ------------------
  |  |   33|  8.77k|#define FullNameSeparator	'@'
  ------------------
   85|  8.77k|	if ( this->parser == 0 ) XMP_Throw ( "Failure creating Expat parser", kXMPErr_ExternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (85:7): [True: 0, False: 8.77k]
  ------------------
   86|       |	
   87|  8.77k|	XML_SetUserData ( this->parser, this );
   88|       |	
   89|  8.77k|	XML_SetNamespaceDeclHandler ( this->parser, StartNamespaceDeclHandler, EndNamespaceDeclHandler );
   90|  8.77k|	XML_SetElementHandler ( this->parser, StartElementHandler, EndElementHandler );
   91|       |
   92|  8.77k|	XML_SetCharacterDataHandler ( this->parser, CharacterDataHandler );
   93|  8.77k|	XML_SetCdataSectionHandler ( this->parser, StartCdataSectionHandler, EndCdataSectionHandler );
   94|       |
   95|  8.77k|	XML_SetProcessingInstructionHandler ( this->parser, ProcessingInstructionHandler );
   96|  8.77k|	XML_SetCommentHandler ( this->parser, CommentHandler );
   97|       |
   98|  8.77k|	#if BanAllEntityUsage
   99|  8.77k|		XML_SetStartDoctypeDeclHandler ( this->parser, StartDoctypeDeclHandler );
  100|  8.77k|		isAborted = false;
  101|  8.77k|	#endif
  102|       |
  103|  8.77k|	this->parseStack.push_back ( &this->tree );	// Push the XML root node.
  104|       |
  105|  8.77k|}	// ExpatAdapter::ExpatAdapter
_ZN12ExpatAdapterD2Ev:
  110|  8.77k|{
  111|       |
  112|  8.77k|	if ( this->parser != 0 ) XML_ParserFree ( this->parser );
  ------------------
  |  Branch (112:7): [True: 8.77k, False: 0]
  ------------------
  113|  8.77k|	this->parser = 0;
  114|       |
  115|  8.77k|}	// ExpatAdapter::~ExpatAdapter
_ZN12ExpatAdapter11ParseBufferEPKvmb:
  126|  8.85k|{
  127|  8.85k|	enum XML_Status status;
  128|       |	
  129|  8.85k|	if ( length == 0 ) {	// Expat does not like empty buffers.
  ------------------
  |  Branch (129:7): [True: 0, False: 8.85k]
  ------------------
  130|      0|		if ( ! last ) return;
  ------------------
  |  Branch (130:8): [True: 0, False: 0]
  ------------------
  131|      0|		buffer = kOneSpace;
  132|      0|		length = 1;
  133|      0|	}
  134|       |	
  135|  8.85k|	status = XML_Parse ( this->parser, (const char *)buffer, length, last );
  136|       |	
  137|  8.85k|	#if BanAllEntityUsage
  138|  8.85k|		if ( this->isAborted ) XMP_Throw ( "DOCTYPE is not allowed", kXMPErr_BadXML );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (138:8): [True: 0, False: 8.85k]
  ------------------
  139|  8.85k|	#endif
  140|       |
  141|  8.85k|	if ( status != XML_STATUS_OK ) {
  ------------------
  |  Branch (141:7): [True: 75, False: 8.77k]
  ------------------
  142|       |	
  143|     75|		XMP_StringPtr errMsg = "XML parsing failure";
  144|       |
  145|       |		#if 0	// XMP_DebugBuild	// Disable for now to make test output uniform. Restore later with thread safety.
  146|       |		
  147|       |			// *** This is a good candidate for a callback error notification mechanism.
  148|       |			// *** This code is not thread safe, the sExpatMessage isn't locked. But that's OK for debug usage.
  149|       |
  150|       |			enum XML_Error expatErr = XML_GetErrorCode ( this->parser );
  151|       |			const char *   expatMsg = XML_ErrorString ( expatErr );
  152|       |			int errLine = XML_GetCurrentLineNumber ( this->parser );
  153|       |		
  154|       |			char msgBuffer[1000];
  155|       |			// AUDIT: Use of sizeof(msgBuffer) for snprintf length is safe.
  156|       |			snprintf ( msgBuffer, sizeof(msgBuffer), "# Expat error %d at line %d, \"%s\"", expatErr, errLine, expatMsg );
  157|       |			sExpatMessage = msgBuffer;
  158|       |			errMsg = sExpatMessage.c_str();
  159|       |
  160|       |			#if  DumpXMLParseEvents
  161|       |				if ( this->parseLog != 0 ) fprintf ( this->parseLog, "%s\n", errMsg, expatErr, errLine, expatMsg );
  162|       |			#endif
  163|       |
  164|       |		#endif
  165|       |
  166|     75|		XMP_Throw ( errMsg, kXMPErr_BadXML );
  ------------------
  |  |  199|     75|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  167|       |
  168|      0|	}
  169|       |	
  170|  8.85k|}	// ExpatAdapter::ParseBuffer
ExpatAdapter.cpp:_ZL25StartNamespaceDeclHandlerPvPKcS1_:
  242|  35.4k|{
  243|  35.4k|	IgnoreParam(userData);
  ------------------
  |  |  117|  35.4k|#define IgnoreParam(p)	(void)p
  ------------------
  244|       |	
  245|       |	// As a bug fix hack, change a URI of "http://purl.org/dc/1.1/" to ""http://purl.org/dc/elements/1.1/.
  246|       |	// Early versions of Flash that put XMP in SWF used a bad URI for the dc: namespace.
  247|       |	
  248|       |	#if XMP_DebugBuild & DumpXMLParseEvents		// Avoid unused variable warning.
  249|       |		ExpatAdapter * thiz = (ExpatAdapter*)userData;
  250|       |	#endif
  251|       |
  252|  35.4k|	if ( prefix == 0 ) prefix = "_dflt_";	// Have default namespace.
  ------------------
  |  Branch (252:7): [True: 111, False: 35.3k]
  ------------------
  253|  35.4k|	if ( uri == 0 ) return;	// Ignore, have xmlns:pre="", no URI to register.
  ------------------
  |  Branch (253:7): [True: 43, False: 35.3k]
  ------------------
  254|       |	
  255|       |	#if XMP_DebugBuild & DumpXMLParseEvents
  256|       |		if ( thiz->parseLog != 0 ) {
  257|       |			PrintIndent ( thiz->parseLog, thiz->elemNesting );
  258|       |			fprintf ( thiz->parseLog, "StartNamespace: %s - \"%s\"\n", prefix, uri );
  259|       |		}
  260|       |	#endif
  261|       |	
  262|  35.3k|	if ( XMP_LitMatch ( uri, "http://purl.org/dc/1.1/" ) ) uri = "http://purl.org/dc/elements/1.1/";
  ------------------
  |  |   96|  35.3k|#define XMP_LitMatch(s,l)		(std::strcmp((s),(l)) == 0)
  |  |  ------------------
  |  |  |  Branch (96:28): [True: 364, False: 35.0k]
  |  |  ------------------
  ------------------
  263|  35.3k|	XMPMeta::RegisterNamespace ( uri, prefix );
  264|       |
  265|  35.3k|}	// StartNamespaceDeclHandler
ExpatAdapter.cpp:_ZL23EndNamespaceDeclHandlerPvPKc:
  270|  35.4k|{
  271|  35.4k|	IgnoreParam(userData);
  ------------------
  |  |  117|  35.4k|#define IgnoreParam(p)	(void)p
  ------------------
  272|       |
  273|       |	#if XMP_DebugBuild & DumpXMLParseEvents		// Avoid unused variable warning.
  274|       |		ExpatAdapter * thiz = (ExpatAdapter*)userData;
  275|       |	#endif
  276|       |
  277|  35.4k|	if ( prefix == 0 ) prefix = "_dflt_";	// Have default namespace.
  ------------------
  |  Branch (277:7): [True: 111, False: 35.3k]
  ------------------
  278|       |	
  279|       |	#if XMP_DebugBuild & DumpXMLParseEvents
  280|       |		if ( thiz->parseLog != 0 ) {
  281|       |			PrintIndent ( thiz->parseLog, thiz->elemNesting );
  282|       |			fprintf ( thiz->parseLog, "EndNamespace: %s\n", prefix );
  283|       |		}
  284|       |	#endif
  285|       |	
  286|       |	// ! Nothing to do, Expat has done all of the XML processing.
  287|       |
  288|  35.4k|}	// EndNamespaceDeclHandler
ExpatAdapter.cpp:_ZL19StartElementHandlerPvPKcPS1_:
  293|  54.3k|{
  294|  54.3k|	XMP_Assert ( attrs != 0 );
  ------------------
  |  |  142|  54.3k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  295|  54.3k|	ExpatAdapter * thiz = (ExpatAdapter*)userData;
  296|       |	
  297|  54.3k|	size_t attrCount = 0;
  298|   189k|	for ( XMP_StringPtr* a = attrs; *a != 0; ++a ) ++attrCount;
  ------------------
  |  Branch (298:34): [True: 134k, False: 54.3k]
  ------------------
  299|  54.3k|	if ( (attrCount & 1) != 0 )	XMP_Throw ( "Expat attribute info has odd length", kXMPErr_ExternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (299:7): [True: 0, False: 54.3k]
  ------------------
  300|  54.3k|	attrCount = attrCount/2;	// They are name/value pairs.
  301|       |	
  302|       |	#if XMP_DebugBuild & DumpXMLParseEvents
  303|       |		if ( thiz->parseLog != 0 ) {
  304|       |			PrintIndent ( thiz->parseLog, thiz->elemNesting );
  305|       |			fprintf ( thiz->parseLog, "StartElement: %s, %d attrs", name, attrCount );
  306|       |			for ( XMP_StringPtr* attr = attrs; *attr != 0; attr += 2 ) {
  307|       |				XMP_StringPtr attrName = *attr;
  308|       |				XMP_StringPtr attrValue = *(attr+1);
  309|       |				fprintf ( thiz->parseLog, ", %s = \"%s\"", attrName, attrValue );
  310|       |			}
  311|       |			fprintf ( thiz->parseLog, "\n" );
  312|       |		}
  313|       |	#endif
  314|       |
  315|  54.3k|	XML_Node * parentNode = thiz->parseStack.back();
  316|  54.3k|	XML_Node * elemNode   = new XML_Node ( parentNode, "", kElemNode );
  317|       |	
  318|  54.3k|	SetQualName ( name, elemNode );
  319|       |	
  320|   121k|	for ( XMP_StringPtr* attr = attrs; *attr != 0; attr += 2 ) {
  ------------------
  |  Branch (320:37): [True: 67.3k, False: 54.3k]
  ------------------
  321|       |
  322|  67.3k|		XMP_StringPtr attrName = *attr;
  323|  67.3k|		XMP_StringPtr attrValue = *(attr+1);
  324|  67.3k|		XML_Node * attrNode = new XML_Node ( elemNode, "", kAttrNode );
  325|       |
  326|  67.3k|		SetQualName ( attrName, attrNode );
  327|  67.3k|		attrNode->value = attrValue;
  328|  67.3k|		if ( attrNode->name == "xml:lang" ) NormalizeLangValue ( &attrNode->value );
  ------------------
  |  Branch (328:8): [True: 2.68k, False: 64.6k]
  ------------------
  329|  67.3k|		elemNode->attrs.push_back ( attrNode );
  330|       |
  331|  67.3k|	}
  332|       |	
  333|  54.3k|	parentNode->content.push_back ( elemNode );
  334|  54.3k|	thiz->parseStack.push_back ( elemNode );
  335|       |	
  336|  54.3k|	if ( elemNode->name == "rdf:RDF" ) {
  ------------------
  |  Branch (336:7): [True: 6.12k, False: 48.2k]
  ------------------
  337|  6.12k|		thiz->rootNode = elemNode;
  338|  6.12k|		++thiz->rootCount;
  339|  6.12k|	}
  340|       |	#if XMP_DebugBuild
  341|       |		++thiz->elemNesting;
  342|       |	#endif
  343|       |
  344|  54.3k|}	// StartElementHandler
ExpatAdapter.cpp:_ZL11SetQualNamePKcP8XML_Node:
  187|   121k|{
  188|       |	// Expat delivers the full name as a catenation of namespace URI, separator, and local name.
  189|       |
  190|       |	// As a compatibility hack, an "about" or "ID" attribute of an rdf:Description element is
  191|       |	// changed to "rdf:about" or rdf:ID. Easier done here than in the RDF recognizer.
  192|       |	
  193|       |	// As a bug fix hack, change a URI of "http://purl.org/dc/1.1/" to ""http://purl.org/dc/elements/1.1/.
  194|       |	// Early versions of Flash that put XMP in SWF used a bad URI for the dc: namespace.
  195|       |
  196|       |	// ! This code presumes the RDF namespace prefix is "rdf".
  197|       |
  198|   121k|	size_t sepPos = strlen(fullName);
  199|  12.5M|	for ( --sepPos; sepPos > 0; --sepPos ) {
  ------------------
  |  Branch (199:18): [True: 12.5M, False: 4.76k]
  ------------------
  200|  12.5M|		if ( fullName[sepPos] == FullNameSeparator ) break;
  ------------------
  |  |   33|  12.5M|#define FullNameSeparator	'@'
  ------------------
  |  Branch (200:8): [True: 116k, False: 12.4M]
  ------------------
  201|  12.5M|	}
  202|       |
  203|   121k|	if ( fullName[sepPos] == FullNameSeparator ) {
  ------------------
  |  |   33|   121k|#define FullNameSeparator	'@'
  ------------------
  |  Branch (203:7): [True: 116k, False: 4.76k]
  ------------------
  204|       |
  205|   116k|		XMP_StringPtr prefix;
  206|   116k|		XMP_StringLen prefixLen;
  207|   116k|		XMP_StringPtr localPart = fullName + sepPos + 1;
  208|       |
  209|   116k|		node->ns.assign ( fullName, sepPos );
  210|   116k|		if ( node->ns == "http://purl.org/dc/1.1/" ) node->ns = "http://purl.org/dc/elements/1.1/";
  ------------------
  |  Branch (210:8): [True: 385, False: 116k]
  ------------------
  211|       |
  212|   116k|		bool found = XMPMeta::GetNamespacePrefix ( node->ns.c_str(), &prefix, &prefixLen );
  213|   116k|		if ( ! found ) XMP_Throw ( "Unknown URI in Expat full name", kXMPErr_ExternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (213:8): [True: 0, False: 116k]
  ------------------
  214|   116k|		node->nsPrefixLen = prefixLen;	// ! Includes the ':'.
  215|       |		
  216|   116k|		node->name = prefix;
  217|   116k|		node->name += localPart;
  218|       |
  219|   116k|	} else {
  220|       |
  221|  4.76k|		node->name = fullName;	// The name is not in a namespace.
  222|       |	
  223|  4.76k|		if ( node->parent->name == "rdf:Description" ) {
  ------------------
  |  Branch (223:8): [True: 841, False: 3.92k]
  ------------------
  224|    841|			if ( node->name == "about" ) {
  ------------------
  |  Branch (224:9): [True: 326, False: 515]
  ------------------
  225|    326|				node->ns   = kXMP_NS_RDF;
  226|    326|				node->name = "rdf:about";
  227|    326|				node->nsPrefixLen = 4;	// ! Include the ':'.
  228|    515|			} else if ( node->name == "ID" ) {
  ------------------
  |  Branch (228:16): [True: 27, False: 488]
  ------------------
  229|     27|				node->ns   = kXMP_NS_RDF;
  230|     27|				node->name = "rdf:ID";
  231|     27|				node->nsPrefixLen = 4;	// ! Include the ':'.
  232|     27|			}
  233|    841|		}
  234|       |		
  235|  4.76k|	}
  236|       |
  237|   121k|}	// SetQualName
ExpatAdapter.cpp:_ZL17EndElementHandlerPvPKc:
  349|  54.3k|{
  350|  54.3k|	IgnoreParam(name);
  ------------------
  |  |  117|  54.3k|#define IgnoreParam(p)	(void)p
  ------------------
  351|       |	
  352|  54.3k|	ExpatAdapter * thiz = (ExpatAdapter*)userData;
  353|       |
  354|       |	#if XMP_DebugBuild
  355|       |		--thiz->elemNesting;
  356|       |	#endif
  357|  54.3k|	(void) thiz->parseStack.pop_back();
  358|       |	
  359|       |	#if XMP_DebugBuild & DumpXMLParseEvents
  360|       |		if ( thiz->parseLog != 0 ) {
  361|       |			PrintIndent ( thiz->parseLog, thiz->elemNesting );
  362|       |			fprintf ( thiz->parseLog, "EndElement: %s\n", name );
  363|       |		}
  364|       |	#endif
  365|       |
  366|  54.3k|}	// EndElementHandler
ExpatAdapter.cpp:_ZL20CharacterDataHandlerPvPKci:
  371|   171k|{
  372|   171k|	ExpatAdapter * thiz = (ExpatAdapter*)userData;
  373|       |	
  374|   171k|	if ( (cData == 0) || (len == 0) ) { cData = ""; len = 0; }
  ------------------
  |  Branch (374:7): [True: 0, False: 171k]
  |  Branch (374:23): [True: 0, False: 171k]
  ------------------
  375|       |	
  376|       |	#if XMP_DebugBuild & DumpXMLParseEvents
  377|       |		if ( thiz->parseLog != 0 ) {
  378|       |			PrintIndent ( thiz->parseLog, thiz->elemNesting );
  379|       |			fprintf ( thiz->parseLog, "CharContent: \"" );
  380|       |			for ( int i = 0; i < len; ++i ) fprintf ( thiz->parseLog, "%c", cData[i] );
  381|       |			fprintf ( thiz->parseLog, "\"\n" );
  382|       |		}
  383|       |	#endif
  384|       |	
  385|   171k|	XML_Node * parentNode = thiz->parseStack.back();
  386|   171k|	XML_Node * cDataNode  = new XML_Node ( parentNode, "", kCDataNode );
  387|       |	
  388|   171k|	cDataNode->value.assign ( cData, len );
  389|   171k|	parentNode->content.push_back ( cDataNode );
  390|       |	
  391|   171k|}	// CharacterDataHandler
ExpatAdapter.cpp:_ZL28ProcessingInstructionHandlerPvPKcS1_:
  436|  12.4k|{
  437|  12.4k|	XMP_Assert ( target != 0 );
  ------------------
  |  |  142|  12.4k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  438|  12.4k|	ExpatAdapter * thiz = (ExpatAdapter*)userData;
  439|       |
  440|  12.4k|	if ( ! XMP_LitMatch ( target, "xpacket" ) ) return;	// Ignore all PIs except the XMP packet wrapper.
  ------------------
  |  |   96|  12.4k|#define XMP_LitMatch(s,l)		(std::strcmp((s),(l)) == 0)
  ------------------
  |  Branch (440:7): [True: 606, False: 11.8k]
  ------------------
  441|  11.8k|	if ( data == 0 ) data = "";
  ------------------
  |  Branch (441:7): [True: 0, False: 11.8k]
  ------------------
  442|       |	
  443|       |	#if XMP_DebugBuild & DumpXMLParseEvents
  444|       |		if ( thiz->parseLog != 0 ) {
  445|       |			PrintIndent ( thiz->parseLog, thiz->elemNesting );
  446|       |			fprintf ( thiz->parseLog, "PI: %s - \"%s\"\n", target, data );
  447|       |		}
  448|       |	#endif
  449|       |	
  450|  11.8k|	XML_Node * parentNode = thiz->parseStack.back();
  451|  11.8k|	XML_Node * piNode  = new XML_Node ( parentNode, target, kPINode );
  452|       |	
  453|  11.8k|	piNode->value.assign ( data );
  454|  11.8k|	parentNode->content.push_back ( piNode );
  455|       |	
  456|  11.8k|}	// ProcessingInstructionHandler

_Z10ProcessRDFP8XMP_NodeRK8XML_Nodej:
  624|  5.81k|{
  625|  5.81k|	IgnoreParam(options);
  ------------------
  |  |  117|  5.81k|#define IgnoreParam(p)	(void)p
  ------------------
  626|       |	
  627|  5.81k|	RDF_RDF ( xmpTree, rdfNode );
  628|       |
  629|  5.81k|}	// ProcessRDF
ParseRDF.cpp:_ZL7RDF_RDFP8XMP_NodeRK8XML_Node:
  646|  5.81k|{
  647|       |
  648|  5.81k|	if ( ! xmlNode.attrs.empty() ) XMP_Throw ( "Invalid attributes of rdf:RDF element", kXMPErr_BadRDF );
  ------------------
  |  |  199|     91|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (648:7): [True: 91, False: 5.72k]
  ------------------
  649|  5.72k|	RDF_NodeElementList ( xmpTree, xmlNode, kIsTopLevel );
  650|       |
  651|  5.72k|}	// RDF_RDF
ParseRDF.cpp:_ZL19RDF_NodeElementListP8XMP_NodeRK8XML_Nodeb:
  663|  5.72k|{
  664|  5.72k|	XMP_Assert ( isTopLevel );
  ------------------
  |  |  142|  5.72k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  665|       |	
  666|  5.72k|	XML_cNodePos currChild = xmlParent.content.begin();	// *** Change these loops to the indexed pattern.
  667|  5.72k|	XML_cNodePos endChild  = xmlParent.content.end();
  668|       |
  669|  31.5k|	for ( ; currChild != endChild; ++currChild ) {
  ------------------
  |  Branch (669:10): [True: 25.8k, False: 5.72k]
  ------------------
  670|  25.8k|		if ( (*currChild)->IsWhitespaceNode() ) continue;
  ------------------
  |  Branch (670:8): [True: 20.0k, False: 5.75k]
  ------------------
  671|  5.75k|		RDF_NodeElement ( xmpParent, **currChild, isTopLevel );
  672|  5.75k|	}
  673|       |
  674|  5.72k|}	// RDF_NodeElementList
ParseRDF.cpp:_ZL15RDF_NodeElementP8XMP_NodeRK8XML_Nodeb:
  694|  10.5k|{
  695|  10.5k|	RDFTermKind nodeTerm = GetRDFTermKind ( xmlNode.name );
  696|  10.5k|	if ( (nodeTerm != kRDFTerm_Description) && (nodeTerm != kRDFTerm_Other) ) {
  ------------------
  |  Branch (696:7): [True: 5.01k, False: 5.56k]
  |  Branch (696:45): [True: 6, False: 5.00k]
  ------------------
  697|      6|		XMP_Throw ( "Node element must be rdf:Description or typedNode", kXMPErr_BadRDF );
  ------------------
  |  |  199|      6|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  698|      0|	}
  699|       |
  700|  10.5k|	if ( isTopLevel && (nodeTerm == kRDFTerm_Other) ) {
  ------------------
  |  Branch (700:7): [True: 5.75k, False: 4.81k]
  |  Branch (700:21): [True: 195, False: 5.56k]
  ------------------
  701|    195|		XMP_Throw ( "Top level typedNode not allowed", kXMPErr_BadXMP );
  ------------------
  |  |  199|    195|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  702|  10.3k|	} else {
  703|  10.3k|		RDF_NodeElementAttrs ( xmpParent, xmlNode, isTopLevel );
  704|  10.3k|		RDF_PropertyElementList ( xmpParent, xmlNode, isTopLevel );
  705|  10.3k|	}
  706|       |
  707|  10.5k|}	// RDF_NodeElement
ParseRDF.cpp:_ZL14GetRDFTermKindRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
  264|   135k|{
  265|   135k|	RDFTermKind term = kRDFTerm_Other;
  266|       |
  267|       |	// Arranged to hopefully minimize the parse time for large XMP.
  268|       |
  269|   135k|	if ( (name.size() > 4) && (strncmp ( name.c_str(), "rdf:", 4 ) == 0) ) {
  ------------------
  |  Branch (269:7): [True: 135k, False: 286]
  |  Branch (269:28): [True: 38.7k, False: 96.7k]
  ------------------
  270|       |
  271|  38.7k|		if ( name == "rdf:li" ) {
  ------------------
  |  Branch (271:8): [True: 19.6k, False: 19.0k]
  ------------------
  272|  19.6k|			term = kRDFTerm_li;
  273|  19.6k|		} else if ( name == "rdf:parseType" ) {
  ------------------
  |  Branch (273:15): [True: 69, False: 19.0k]
  ------------------
  274|     69|			term = kRDFTerm_parseType;
  275|  19.0k|		} else if ( name == "rdf:Description" ) {
  ------------------
  |  Branch (275:15): [True: 5.59k, False: 13.4k]
  ------------------
  276|  5.59k|			term = kRDFTerm_Description;
  277|  13.4k|		} else if ( name == "rdf:about" ) {
  ------------------
  |  Branch (277:15): [True: 1.02k, False: 12.3k]
  ------------------
  278|  1.02k|			term = kRDFTerm_about;
  279|  12.3k|		} else if ( name == "rdf:resource" ) {
  ------------------
  |  Branch (279:15): [True: 75, False: 12.3k]
  ------------------
  280|     75|			term = kRDFTerm_resource;
  281|  12.3k|		} else if ( name == "rdf:RDF" ) {
  ------------------
  |  Branch (281:15): [True: 38, False: 12.2k]
  ------------------
  282|     38|			term = kRDFTerm_RDF;
  283|  12.2k|		} else if ( name == "rdf:ID" ) {
  ------------------
  |  Branch (283:15): [True: 27, False: 12.2k]
  ------------------
  284|     27|			term = kRDFTerm_ID;
  285|  12.2k|		} else if ( name == "rdf:nodeID" ) {
  ------------------
  |  Branch (285:15): [True: 40, False: 12.2k]
  ------------------
  286|     40|			term = kRDFTerm_nodeID;
  287|  12.2k|		} else if ( name == "rdf:datatype" ) {
  ------------------
  |  Branch (287:15): [True: 81, False: 12.1k]
  ------------------
  288|     81|			term = kRDFTerm_datatype;
  289|  12.1k|		} else if ( name == "rdf:aboutEach" ) {
  ------------------
  |  Branch (289:15): [True: 34, False: 12.0k]
  ------------------
  290|     34|			term = kRDFTerm_aboutEach;
  291|  12.0k|		} else if ( name == "rdf:aboutEachPrefix" ) {
  ------------------
  |  Branch (291:15): [True: 10, False: 12.0k]
  ------------------
  292|     10|			term = kRDFTerm_aboutEachPrefix;
  293|  12.0k|		} else if ( name == "rdf:bagID" ) {
  ------------------
  |  Branch (293:15): [True: 90, False: 11.9k]
  ------------------
  294|     90|			term = kRDFTerm_bagID;
  295|     90|		}
  296|       |
  297|  38.7k|	}
  298|       |
  299|   135k|	return term;
  300|       |
  301|   135k|}	// GetRDFTermKind
ParseRDF.cpp:_ZL20RDF_NodeElementAttrsP8XMP_NodeRK8XML_Nodeb:
  731|  10.3k|{
  732|  10.3k|	XMP_OptionBits exclusiveAttrs = 0;	// Used to detect attributes that are mutually exclusive.
  733|       |
  734|  10.3k|	XML_cNodePos currAttr = xmlNode.attrs.begin();
  735|  10.3k|	XML_cNodePos endAttr  = xmlNode.attrs.end();
  736|       |
  737|  28.7k|	for ( ; currAttr != endAttr; ++currAttr ) {
  ------------------
  |  Branch (737:10): [True: 19.2k, False: 9.49k]
  ------------------
  738|       |
  739|  19.2k|		RDFTermKind attrTerm = GetRDFTermKind ( (*currAttr)->name );
  740|       |
  741|  19.2k|		switch ( attrTerm ) {
  742|       |
  743|     27|			case kRDFTerm_ID     :
  ------------------
  |  Branch (743:4): [True: 27, False: 19.1k]
  ------------------
  744|     61|			case kRDFTerm_nodeID :
  ------------------
  |  Branch (744:4): [True: 34, False: 19.1k]
  ------------------
  745|  1.08k|			case kRDFTerm_about  :
  ------------------
  |  Branch (745:4): [True: 1.02k, False: 18.1k]
  ------------------
  746|       |
  747|  1.08k|				if ( exclusiveAttrs & kExclusiveAttrMask ) XMP_Throw ( "Mutally exclusive about, ID, nodeID attributes", kXMPErr_BadRDF );
  ------------------
  |  |  199|     19|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (747:10): [True: 19, False: 1.07k]
  ------------------
  748|  1.07k|				exclusiveAttrs |= (1 << attrTerm);
  749|       |
  750|  1.07k|				if ( isTopLevel && (attrTerm == kRDFTerm_about) ) {
  ------------------
  |  Branch (750:10): [True: 1.07k, False: 0]
  |  Branch (750:24): [True: 1.00k, False: 61]
  ------------------
  751|       |					// This is the rdf:about attribute on a top level node. Set the XMP tree name if
  752|       |					// it doesn't have a name yet. Make sure this name matches the XMP tree name.
  753|  1.00k|					XMP_Assert ( xmpParent->parent == 0 );	// Must be the tree root node.
  ------------------
  |  |  142|  1.00k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  754|  1.00k|					if ( xmpParent->name.empty() ) {
  ------------------
  |  Branch (754:11): [True: 1.00k, False: 0]
  ------------------
  755|  1.00k|						xmpParent->name = (*currAttr)->value;
  756|  1.00k|					} else if ( ! (*currAttr)->value.empty() ) {
  ------------------
  |  Branch (756:18): [True: 0, False: 0]
  ------------------
  757|      0|						if ( xmpParent->name != (*currAttr)->value ) XMP_Throw ( "Mismatched top level rdf:about values", kXMPErr_BadXMP );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (757:12): [True: 0, False: 0]
  ------------------
  758|      0|					}
  759|  1.00k|				}
  760|       |
  761|  1.07k|				break;
  762|       |
  763|  17.7k|			case kRDFTerm_Other :
  ------------------
  |  Branch (763:4): [True: 17.7k, False: 1.47k]
  ------------------
  764|  17.7k|				AddChildNode ( xmpParent, **currAttr, (*currAttr)->value.c_str(), isTopLevel );
  765|  17.7k|				break;
  766|       |
  767|    381|			default :
  ------------------
  |  Branch (767:4): [True: 381, False: 18.8k]
  ------------------
  768|    381|				XMP_Throw ( "Invalid nodeElement attribute", kXMPErr_BadRDF );
  ------------------
  |  |  199|    381|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  769|       |
  770|  19.2k|		}
  771|       |
  772|  19.2k|	}
  773|       |
  774|  10.3k|}	// RDF_NodeElementAttrs
ParseRDF.cpp:_ZL12AddChildNodeP8XMP_NodeRK8XML_NodePKcb:
  362|  73.6k|{
  363|       |	#if 0
  364|       |		cout << "AddChildNode, parent = " << xmpParent->name << ", child = " << xmlNode.name;
  365|       |		cout << ", value = \"" << value << '"';
  366|       |		if ( isTopLevel ) cout << ", top level";
  367|       |		cout << endl;
  368|       |	#endif
  369|       |	
  370|  73.6k|	if ( xmlNode.ns.empty() ) {
  ------------------
  |  Branch (370:7): [True: 437, False: 73.2k]
  ------------------
  371|    437|		XMP_Throw ( "XML namespace required for all elements and attributes", kXMPErr_BadRDF );
  ------------------
  |  |  199|    437|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  372|      0|	}
  373|       |		
  374|  73.2k|	XMP_StringPtr  childName    = xmlNode.name.c_str();
  375|  73.2k|	const bool     isArrayItem  = (xmlNode.name == "rdf:li");
  376|  73.2k|	const bool     isValueNode  = (xmlNode.name == "rdf:value");
  377|  73.2k|	XMP_OptionBits childOptions = 0;
  378|       |	
  379|  73.2k|	if ( isTopLevel ) {
  ------------------
  |  Branch (379:7): [True: 22.7k, False: 50.4k]
  ------------------
  380|       |
  381|       |		// Lookup the schema node, adjust the XMP parent pointer.
  382|  22.7k|		XMP_Assert ( xmpParent->parent == 0 );	// Incoming parent must be the tree root.
  ------------------
  |  |  142|  22.7k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  383|  22.7k|		XMP_Node * schemaNode = FindSchemaNode ( xmpParent, xmlNode.ns.c_str(), kXMP_CreateNodes );
  ------------------
  |  |  295|  22.7k|#define kXMP_CreateNodes	true
  ------------------
  384|  22.7k|		if ( schemaNode->options & kXMP_NewImplicitNode ) schemaNode->options ^= kXMP_NewImplicitNode;	// Clear the implicit node bit.
  ------------------
  |  |  410|  22.7k|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
              		if ( schemaNode->options & kXMP_NewImplicitNode ) schemaNode->options ^= kXMP_NewImplicitNode;	// Clear the implicit node bit.
  ------------------
  |  |  410|  10.0k|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  |  Branch (384:8): [True: 10.0k, False: 12.6k]
  ------------------
  385|       |			// *** Should use "opt &= ~flag" (no conditional), need runtime check for proper 32 bit code.
  386|  22.7k|		xmpParent = schemaNode;
  387|       |		
  388|       |		// If this is an alias set the isAlias flag in the node and the hasAliases flag in the tree.
  389|  22.7k|		if ( sRegisteredAliasMap->find ( xmlNode.name ) != sRegisteredAliasMap->end() ) {
  ------------------
  |  Branch (389:8): [True: 0, False: 22.7k]
  ------------------
  390|      0|			childOptions |= kXMP_PropIsAlias;
  391|      0|			schemaNode->parent->options |= kXMP_PropHasAliases;
  392|      0|		}
  393|       |		
  394|  22.7k|	}
  395|       |
  396|       |	// Make sure that this is not a duplicate of a named node.
  397|  73.2k|	if ( ! (isArrayItem | isValueNode) ) {
  ------------------
  |  Branch (397:7): [True: 53.4k, False: 19.7k]
  ------------------
  398|  53.4k|		if ( FindChildNode ( xmpParent, childName, kXMP_ExistingOnly ) != 0 ) {
  ------------------
  |  |  296|  53.4k|#define kXMP_ExistingOnly	false
  ------------------
  |  Branch (398:8): [True: 2, False: 53.4k]
  ------------------
  399|      2|			XMP_Throw ( "Duplicate property or field node", kXMPErr_BadXMP );
  ------------------
  |  |  199|      2|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  400|      0|		}
  401|       |		
  402|  53.4k|	}
  403|       |	
  404|       |	// Add the new child to the XMP parent node.
  405|  73.2k|	XMP_Node * newChild = new XMP_Node ( xmpParent, childName, value, childOptions );
  406|  73.2k|	if ( (! isValueNode) || xmpParent->children.empty() ) {
  ------------------
  |  Branch (406:7): [True: 73.1k, False: 54]
  |  Branch (406:26): [True: 34, False: 20]
  ------------------
  407|  73.1k|		 xmpParent->children.push_back ( newChild );
  408|  73.1k|	} else {
  409|     21|		 xmpParent->children.insert ( xmpParent->children.begin(), newChild );
  410|     21|	}
  411|  73.2k|	if ( isValueNode ) {
  ------------------
  |  Branch (411:7): [True: 54, False: 73.1k]
  ------------------
  412|     54|		if ( isTopLevel || (! (xmpParent->options & kXMP_PropValueIsStruct)) ) XMP_Throw ( "Misplaced rdf:value element", kXMPErr_BadRDF );
  ------------------
  |  |  199|     53|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (412:8): [True: 52, False: 2]
  |  Branch (412:22): [True: 1, False: 1]
  ------------------
  413|      1|		xmpParent->options |= kRDF_HasValueElem;
  414|      1|	}
  415|       |	
  416|  73.1k|	if ( isArrayItem ) {
  ------------------
  |  Branch (416:7): [True: 19.6k, False: 53.4k]
  ------------------
  417|  19.6k|		if ( ! (xmpParent->options & kXMP_PropValueIsArray) ) XMP_Throw ( "Misplaced rdf:li element", kXMPErr_BadRDF );
  ------------------
  |  |  199|      2|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (417:8): [True: 2, False: 19.6k]
  ------------------
  418|  19.6k|		newChild->name = kXMP_ArrayItemName;
  ------------------
  |  |  293|  19.6k|#define kXMP_ArrayItemName	"[]"
  ------------------
  419|       |		#if 0	// *** XMP_DebugBuild
  420|       |			newChild->_namePtr = newChild->name.c_str();
  421|       |		#endif
  422|  19.6k|	}
  423|       |	
  424|  73.1k|	return newChild;
  425|       |
  426|  73.1k|}	// AddChildNode
ParseRDF.cpp:_ZL23RDF_PropertyElementListP8XMP_NodeRK8XML_Nodeb:
  786|  9.49k|{
  787|  9.49k|	XML_cNodePos currChild = xmlParent.content.begin();
  788|  9.49k|	XML_cNodePos endChild  = xmlParent.content.end();
  789|       |
  790|   103k|	for ( ; currChild != endChild; ++currChild ) {
  ------------------
  |  Branch (790:10): [True: 94.5k, False: 9.19k]
  ------------------
  791|  94.5k|		if ( (*currChild)->IsWhitespaceNode() ) continue;
  ------------------
  |  Branch (791:8): [True: 69.0k, False: 25.4k]
  ------------------
  792|  25.4k|		if ( (*currChild)->kind != kElemNode ) {
  ------------------
  |  Branch (792:8): [True: 304, False: 25.1k]
  ------------------
  793|    304|			XMP_Throw ( "Expected property element node not found", kXMPErr_BadRDF );
  ------------------
  |  |  199|    304|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  794|      0|		}
  795|  25.1k|		RDF_PropertyElement ( xmpParent, **currChild, isTopLevel );
  796|  25.1k|	}
  797|       |
  798|  9.49k|}	// RDF_PropertyElementList
ParseRDF.cpp:_ZL19RDF_PropertyElementP8XMP_NodeRK8XML_Nodeb:
  853|  25.1k|{
  854|  25.1k|	RDFTermKind nodeTerm = GetRDFTermKind ( xmlNode.name );
  855|  25.1k|	if ( ! IsPropertyElementName ( nodeTerm ) ) XMP_Throw ( "Invalid property element name", kXMPErr_BadRDF );
  ------------------
  |  |  199|     30|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (855:7): [True: 30, False: 25.1k]
  ------------------
  856|       |	
  857|  25.1k|	if ( xmlNode.attrs.size() > 3 ) {
  ------------------
  |  Branch (857:7): [True: 3.42k, False: 21.7k]
  ------------------
  858|       |
  859|       |		// Only an emptyPropertyElt can have more than 3 attributes.
  860|  3.42k|		RDF_EmptyPropertyElement ( xmpParent, xmlNode, isTopLevel );
  861|       |
  862|  21.7k|	} else {
  863|       |
  864|       |		// Look through the attributes for one that isn't rdf:ID or xml:lang, it will usually tell
  865|       |		// what we should be dealing with. The called routines must verify their specific syntax!
  866|       |
  867|  21.7k|		XML_cNodePos currAttr = xmlNode.attrs.begin();
  868|  21.7k|		XML_cNodePos endAttr  = xmlNode.attrs.end();
  869|  21.7k|		XMP_VarString * attrName = 0;
  870|       |
  871|  23.8k|		for ( ; currAttr != endAttr; ++currAttr ) {
  ------------------
  |  Branch (871:11): [True: 3.40k, False: 20.4k]
  ------------------
  872|  3.40k|			attrName = &((*currAttr)->name);
  873|  3.40k|			if ( (*attrName != "xml:lang") && (*attrName != "rdf:ID") ) break;
  ------------------
  |  Branch (873:9): [True: 1.29k, False: 2.11k]
  |  Branch (873:38): [True: 1.29k, False: 0]
  ------------------
  874|  3.40k|		}
  875|       |
  876|  21.7k|		if ( currAttr != endAttr ) {
  ------------------
  |  Branch (876:8): [True: 1.29k, False: 20.4k]
  ------------------
  877|       |
  878|  1.29k|			XMP_Assert ( attrName != 0 );
  ------------------
  |  |  142|  1.29k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  879|  1.29k|			XMP_VarString& attrValue = (*currAttr)->value;
  880|       |
  881|  1.29k|			if ( *attrName == "rdf:datatype" ) {
  ------------------
  |  Branch (881:9): [True: 4, False: 1.29k]
  ------------------
  882|      4|				RDF_LiteralPropertyElement ( xmpParent, xmlNode, isTopLevel );
  883|  1.29k|			} else if ( *attrName != "rdf:parseType" ) {
  ------------------
  |  Branch (883:16): [True: 1.28k, False: 5]
  ------------------
  884|  1.28k|				RDF_EmptyPropertyElement ( xmpParent, xmlNode, isTopLevel );
  885|  1.28k|			} else if ( attrValue == "Literal" ) {
  ------------------
  |  Branch (885:16): [True: 0, False: 5]
  ------------------
  886|      0|				RDF_ParseTypeLiteralPropertyElement ( xmpParent, xmlNode, isTopLevel );
  887|      5|			} else if ( attrValue == "Resource" ) {
  ------------------
  |  Branch (887:16): [True: 0, False: 5]
  ------------------
  888|      0|				RDF_ParseTypeResourcePropertyElement ( xmpParent, xmlNode, isTopLevel );
  889|      5|			} else if ( attrValue == "Collection" ) {
  ------------------
  |  Branch (889:16): [True: 0, False: 5]
  ------------------
  890|      0|				RDF_ParseTypeCollectionPropertyElement ( xmpParent, xmlNode, isTopLevel );
  891|      5|			} else {
  892|      5|				RDF_ParseTypeOtherPropertyElement ( xmpParent, xmlNode, isTopLevel );
  893|      5|			}
  894|       |
  895|  20.4k|		} else {
  896|       |
  897|       |			// Only rdf:ID and xml:lang, could be a resourcePropertyElt, a literalPropertyElt, or an.
  898|       |			// emptyPropertyElt. Look at the child XML nodes to decide which.
  899|       |
  900|  20.4k|			if ( xmlNode.content.empty() ) {
  ------------------
  |  Branch (900:9): [True: 867, False: 19.5k]
  ------------------
  901|       |
  902|    867|				RDF_EmptyPropertyElement ( xmpParent, xmlNode, isTopLevel );
  903|       |
  904|  19.5k|			} else {
  905|       |			
  906|  19.5k|				XML_cNodePos currChild = xmlNode.content.begin();
  907|  19.5k|				XML_cNodePos endChild  = xmlNode.content.end();
  908|       |
  909|  45.1k|				for ( ; currChild != endChild; ++currChild ) {
  ------------------
  |  Branch (909:13): [True: 30.4k, False: 14.7k]
  ------------------
  910|  30.4k|					if ( (*currChild)->kind != kCDataNode ) break;
  ------------------
  |  Branch (910:11): [True: 4.84k, False: 25.6k]
  ------------------
  911|  30.4k|				}
  912|       |				
  913|  19.5k|				if ( currChild == endChild ) {
  ------------------
  |  Branch (913:10): [True: 14.7k, False: 4.84k]
  ------------------
  914|  14.7k|					RDF_LiteralPropertyElement ( xmpParent, xmlNode, isTopLevel );
  915|  14.7k|				} else {
  916|  4.84k|					RDF_ResourcePropertyElement ( xmpParent, xmlNode, isTopLevel );
  917|  4.84k|				}
  918|       |			
  919|  19.5k|			}
  920|       |
  921|  20.4k|		}
  922|       |		
  923|  21.7k|	}
  924|       |
  925|  25.1k|}	// RDF_PropertyElement
ParseRDF.cpp:_ZL21IsPropertyElementNameh:
  349|  25.1k|{
  350|       |
  351|  25.1k|	if 	( (term == kRDFTerm_Description) || IsOldTerm ( term ) ) return false;
  ------------------
  |  Branch (351:8): [True: 28, False: 25.1k]
  |  Branch (351:42): [True: 1, False: 25.1k]
  ------------------
  352|  25.1k|	return (! IsCoreSyntaxTerm ( term ));
  353|       |
  354|  25.1k|}	// IsPropertyElementName
ParseRDF.cpp:_ZL9IsOldTermh:
  333|  25.1k|{
  334|       |
  335|  25.1k|	if 	( (kRDFTerm_FirstOld <= term) && (term <= kRDFTerm_LastOld) ) return true;
  ------------------
  |  Branch (335:8): [True: 1, False: 25.1k]
  |  Branch (335:39): [True: 1, False: 0]
  ------------------
  336|  25.1k|	return false;
  337|       |
  338|  25.1k|}	// IsOldTerm
ParseRDF.cpp:_ZL16IsCoreSyntaxTermh:
  316|  25.1k|{
  317|       |
  318|  25.1k|	if 	( (kRDFTerm_FirstCore <= term) && (term <= kRDFTerm_LastCore) ) return true;
  ------------------
  |  Branch (318:8): [True: 19.6k, False: 5.47k]
  |  Branch (318:40): [True: 1, False: 19.6k]
  ------------------
  319|  25.1k|	return false;
  320|       |
  321|  25.1k|}	// IsCoreSyntaxTerm
ParseRDF.cpp:_ZL24RDF_EmptyPropertyElementP8XMP_NodeRK8XML_Nodeb:
 1189|  5.57k|{
 1190|  5.57k|	bool hasPropertyAttrs = false;
 1191|  5.57k|	bool hasResourceAttr  = false;
 1192|  5.57k|	bool hasNodeIDAttr    = false;
 1193|  5.57k|	bool hasValueAttr     = false;
 1194|       |	
 1195|  5.57k|	const XML_Node * valueNode = 0;	// ! Can come from rdf:value or rdf:resource.
 1196|       |	
 1197|  5.57k|	if ( ! xmlNode.content.empty() ) XMP_Throw ( "Nested content not allowed with rdf:resource or property attributes", kXMPErr_BadRDF );
  ------------------
  |  |  199|      8|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1197:7): [True: 8, False: 5.56k]
  ------------------
 1198|       |	
 1199|       |	// First figure out what XMP this maps to and remember the XML node for a simple value.
 1200|       |	
 1201|  5.56k|	XML_cNodePos currAttr = xmlNode.attrs.begin();
 1202|  5.56k|	XML_cNodePos endAttr  = xmlNode.attrs.end();
 1203|       |
 1204|  46.6k|	for ( ; currAttr != endAttr; ++currAttr ) {
  ------------------
  |  Branch (1204:10): [True: 41.0k, False: 5.56k]
  ------------------
 1205|       |
 1206|  41.0k|		RDFTermKind attrTerm = GetRDFTermKind ( (*currAttr)->name );
 1207|       |
 1208|  41.0k|		switch ( attrTerm ) {
 1209|       |
 1210|      0|			case kRDFTerm_ID :
  ------------------
  |  Branch (1210:4): [True: 0, False: 41.0k]
  ------------------
 1211|       |				// Nothing to do.
 1212|      0|				break;
 1213|       |
 1214|     11|			case kRDFTerm_resource :
  ------------------
  |  Branch (1214:4): [True: 11, False: 41.0k]
  ------------------
 1215|     11|				if ( hasNodeIDAttr ) XMP_Throw ( "Empty property element can't have both rdf:resource and rdf:nodeID", kXMPErr_BadRDF );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1215:10): [True: 0, False: 11]
  ------------------
 1216|     11|				if ( hasValueAttr ) XMP_Throw ( "Empty property element can't have both rdf:value and rdf:resource", kXMPErr_BadXMP );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1216:10): [True: 0, False: 11]
  ------------------
 1217|     11|				hasResourceAttr = true;
 1218|     11|				if ( ! hasValueAttr ) valueNode = *currAttr;
  ------------------
  |  Branch (1218:10): [True: 11, False: 0]
  ------------------
 1219|     11|				break;
 1220|       |
 1221|      3|			case kRDFTerm_nodeID :
  ------------------
  |  Branch (1221:4): [True: 3, False: 41.0k]
  ------------------
 1222|      3|				if ( hasResourceAttr ) XMP_Throw ( "Empty property element can't have both rdf:resource and rdf:nodeID", kXMPErr_BadRDF );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1222:10): [True: 0, False: 3]
  ------------------
 1223|      3|				hasNodeIDAttr = true;
 1224|      3|				break;
 1225|       |
 1226|  41.0k|			case kRDFTerm_Other :
  ------------------
  |  Branch (1226:4): [True: 41.0k, False: 15]
  ------------------
 1227|  41.0k|				if ( (*currAttr)->name == "rdf:value" ) {
  ------------------
  |  Branch (1227:10): [True: 1.23k, False: 39.8k]
  ------------------
 1228|  1.23k|					if ( hasResourceAttr ) XMP_Throw ( "Empty property element can't have both rdf:value and rdf:resource", kXMPErr_BadXMP );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1228:11): [True: 0, False: 1.23k]
  ------------------
 1229|  1.23k|					hasValueAttr = true;
 1230|  1.23k|					valueNode = *currAttr;
 1231|  39.8k|				} else if ( (*currAttr)->name != "xml:lang" ) {
  ------------------
  |  Branch (1231:17): [True: 38.9k, False: 839]
  ------------------
 1232|  38.9k|					hasPropertyAttrs = true;
 1233|  38.9k|				}
 1234|  41.0k|				break;
 1235|       |
 1236|  41.0k|			default :
  ------------------
  |  Branch (1236:4): [True: 1, False: 41.0k]
  ------------------
 1237|      1|				XMP_Throw ( "Unrecognized attribute of empty property element", kXMPErr_BadRDF );
  ------------------
  |  |  199|      1|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
 1238|      0|				break;
 1239|       |
 1240|  41.0k|		}
 1241|       |
 1242|  41.0k|	}
 1243|       |	
 1244|       |	// Create the right kind of child node and visit the attributes again to add the fields or qualifiers.
 1245|       |	// ! Because of implementation vagaries, the xmpParent is the tree root for top level properties.
 1246|       |	// ! The schema is found, created if necessary, by AddChildNode.
 1247|       |	
 1248|  5.56k|	XMP_Node * childNode = AddChildNode ( xmpParent, xmlNode, "", isTopLevel );
 1249|  5.56k|	bool childIsStruct = false;
 1250|       |	
 1251|  5.56k|	if ( hasValueAttr | hasResourceAttr ) {
  ------------------
  |  Branch (1251:7): [True: 1.24k, False: 4.31k]
  ------------------
 1252|  1.24k|		childNode->value = valueNode->value;
 1253|  1.24k|		if ( ! hasValueAttr ) childNode->options |= kXMP_PropValueIsURI;	// ! Might have both rdf:value and rdf:resource.
  ------------------
  |  Branch (1253:8): [True: 10, False: 1.23k]
  ------------------
 1254|  4.31k|	} else if ( hasPropertyAttrs ) {
  ------------------
  |  Branch (1254:14): [True: 3.44k, False: 870]
  ------------------
 1255|  3.44k|		childNode->options |= kXMP_PropValueIsStruct;
 1256|  3.44k|		childIsStruct = true;
 1257|  3.44k|	}
 1258|       |		
 1259|  5.56k|	currAttr = xmlNode.attrs.begin();
 1260|  5.56k|	endAttr  = xmlNode.attrs.end();
 1261|       |
 1262|  46.4k|	for ( ; currAttr != endAttr; ++currAttr ) {
  ------------------
  |  Branch (1262:10): [True: 40.9k, False: 5.54k]
  ------------------
 1263|       |
 1264|  40.9k|		if ( *currAttr == valueNode ) continue;	// Skip the rdf:value or rdf:resource attribute holding the value.
  ------------------
  |  Branch (1264:8): [True: 1.24k, False: 39.7k]
  ------------------
 1265|  39.7k|		RDFTermKind attrTerm = GetRDFTermKind ( (*currAttr)->name );
 1266|       |
 1267|  39.7k|		switch ( attrTerm ) {
 1268|       |
 1269|      0|			case kRDFTerm_ID       :
  ------------------
  |  Branch (1269:4): [True: 0, False: 39.7k]
  ------------------
 1270|      3|			case kRDFTerm_nodeID   :
  ------------------
  |  Branch (1270:4): [True: 3, False: 39.7k]
  ------------------
 1271|      3|				break;	// Ignore all rdf:ID and rdf:nodeID attributes.w
 1272|       |				
 1273|      0|			case kRDFTerm_resource :
  ------------------
  |  Branch (1273:4): [True: 0, False: 39.7k]
  ------------------
 1274|      0|				AddQualifierNode ( childNode, **currAttr );
 1275|      0|				break;
 1276|       |
 1277|  39.7k|			case kRDFTerm_Other :
  ------------------
  |  Branch (1277:4): [True: 39.7k, False: 3]
  ------------------
 1278|  39.7k|				if ( (! childIsStruct) || (*currAttr)->name == "xml:lang" ) {
  ------------------
  |  Branch (1278:10): [True: 8.92k, False: 30.7k]
  |  Branch (1278:31): [True: 5, False: 30.7k]
  ------------------
 1279|  8.93k|					AddQualifierNode ( childNode, **currAttr );
 1280|  30.7k|				} else {
 1281|  30.7k|					AddChildNode ( childNode, **currAttr, (*currAttr)->value.c_str(), false );
 1282|  30.7k|				}
 1283|  39.7k|				break;
 1284|       |
 1285|      0|			default :
  ------------------
  |  Branch (1285:4): [True: 0, False: 39.7k]
  ------------------
 1286|      0|				XMP_Throw ( "Unrecognized attribute of empty property element", kXMPErr_BadRDF );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
 1287|      0|				break;
 1288|       |
 1289|  39.7k|		}
 1290|       |
 1291|  39.7k|	}
 1292|       |
 1293|  5.56k|}	// RDF_EmptyPropertyElement
ParseRDF.cpp:_ZL16AddQualifierNodeP8XMP_NodeRK8XML_Node:
  483|  10.2k|{
  484|  10.2k|	if ( attr.ns.empty() ) {
  ------------------
  |  Branch (484:7): [True: 6, False: 10.2k]
  ------------------
  485|      6|		XMP_Throw ( "XML namespace required for all elements and attributes", kXMPErr_BadRDF );
  ------------------
  |  |  199|      6|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  486|      0|	}
  487|       |	
  488|  10.2k|	return AddQualifierNode ( xmpParent, attr.name, attr.value );
  489|       |
  490|  10.2k|}	// AddQualifierNode
ParseRDF.cpp:_ZL16AddQualifierNodeP8XMP_NodeRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
  435|  10.2k|{
  436|       |
  437|       |	#if 0
  438|       |		cout << "AddQualifierNode, parent = " << xmpParent->name << ", name = " << name;
  439|       |		cout << ", value = \"" << value << '"' << endl;
  440|       |	#endif
  441|       |	
  442|  10.2k|	const bool isLang = (name == "xml:lang");
  443|  10.2k|	const bool isType = (name == "rdf:type");
  444|       |
  445|  10.2k|	XMP_Node * newQual = 0;
  446|       |
  447|  10.2k|		newQual = new XMP_Node ( xmpParent, name, value, kXMP_PropIsQualifier );
  448|       |
  449|  10.2k|		if ( ! (isLang | isType) ) {
  ------------------
  |  Branch (449:8): [True: 8.08k, False: 2.13k]
  ------------------
  450|  8.08k|			xmpParent->qualifiers.push_back ( newQual );
  451|  8.08k|		} else if ( isLang ) {
  ------------------
  |  Branch (451:15): [True: 2.11k, False: 19]
  ------------------
  452|  2.11k|			if ( xmpParent->qualifiers.empty() ) {
  ------------------
  |  Branch (452:9): [True: 2.11k, False: 1]
  ------------------
  453|  2.11k|				xmpParent->qualifiers.push_back ( newQual );
  454|  2.11k|			} else {
  455|      1|				xmpParent->qualifiers.insert ( xmpParent->qualifiers.begin(), newQual );
  456|      1|			}
  457|  2.11k|			xmpParent->options |= kXMP_PropHasLang;
  458|  2.11k|		} else {
  459|     19|			XMP_Assert ( isType );
  ------------------
  |  |  142|     19|	#define XMP_Assert(c)	((void) 0)
  ------------------
  460|     19|			if ( xmpParent->qualifiers.empty() ) {
  ------------------
  |  Branch (460:9): [True: 13, False: 6]
  ------------------
  461|     13|				xmpParent->qualifiers.push_back ( newQual );
  462|     13|			} else {
  463|      6|				size_t offset = 0;
  464|      6|				if ( XMP_PropHasLang ( xmpParent->options ) ) offset = 1;
  ------------------
  |  Branch (464:10): [True: 5, False: 1]
  ------------------
  465|      6|				xmpParent->qualifiers.insert ( xmpParent->qualifiers.begin()+offset, newQual );
  466|      6|			}
  467|     19|			xmpParent->options |= kXMP_PropHasType;
  468|     19|		}
  469|       |
  470|  10.2k|		xmpParent->options |= kXMP_PropHasQualifiers;
  471|       |
  472|  10.2k|	return newQual;
  473|       |
  474|  10.2k|}	// AddQualifierNode
ParseRDF.cpp:_ZL26RDF_LiteralPropertyElementP8XMP_NodeRK8XML_Nodeb:
 1014|  14.7k|{
 1015|  14.7k|	XMP_Node * newChild = AddChildNode ( xmpParent, xmlNode, "", isTopLevel );
 1016|       |	
 1017|  14.7k|	XML_cNodePos currAttr = xmlNode.attrs.begin();
 1018|  14.7k|	XML_cNodePos endAttr  = xmlNode.attrs.end();
 1019|       |
 1020|  16.0k|	for ( ; currAttr != endAttr; ++currAttr ) {
  ------------------
  |  Branch (1020:10): [True: 1.27k, False: 14.7k]
  ------------------
 1021|  1.27k|		XMP_VarString & attrName = (*currAttr)->name;
 1022|  1.27k|		if ( attrName == "xml:lang" ) {
  ------------------
  |  Branch (1022:8): [True: 1.26k, False: 7]
  ------------------
 1023|  1.26k|			AddQualifierNode ( newChild, **currAttr );
 1024|  1.26k|		} else if ( (attrName == "rdf:ID") || (attrName == "rdf:datatype") ) {
  ------------------
  |  Branch (1024:15): [True: 0, False: 7]
  |  Branch (1024:41): [True: 4, False: 3]
  ------------------
 1025|      4|			continue;	// Ignore all rdf:ID and rdf:datatype attributes.
 1026|      4|		} else {
 1027|      3|			XMP_Throw ( "Invalid attribute for literal property element", kXMPErr_BadRDF );
  ------------------
  |  |  199|      3|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
 1028|      0|		}
 1029|  1.27k|	}
 1030|       |	
 1031|  14.7k|	XML_cNodePos currChild = xmlNode.content.begin();
 1032|  14.7k|	XML_cNodePos endChild  = xmlNode.content.end();
 1033|  14.7k|	size_t      textSize  = 0;
 1034|       |
 1035|  30.3k|	for ( ; currChild != endChild; ++currChild ) {
  ------------------
  |  Branch (1035:10): [True: 15.5k, False: 14.7k]
  ------------------
 1036|  15.5k|		if ( (*currChild)->kind != kCDataNode ) XMP_Throw ( "Invalid child of literal property element", kXMPErr_BadRDF );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1036:8): [True: 0, False: 15.5k]
  ------------------
 1037|  15.5k|		textSize += (*currChild)->value.size();
 1038|  15.5k|	}
 1039|       |	
 1040|  14.7k|	newChild->value.reserve ( textSize );
 1041|       |
 1042|  30.3k|	for ( currChild = xmlNode.content.begin(); currChild != endChild; ++currChild ) {
  ------------------
  |  Branch (1042:45): [True: 15.5k, False: 14.7k]
  ------------------
 1043|  15.5k|		newChild->value += (*currChild)->value;
 1044|  15.5k|	}
 1045|       |
 1046|       |	#if 0	// *** XMP_DebugBuild
 1047|       |		newChild->_valuePtr = newChild->value.c_str();
 1048|       |	#endif
 1049|       |	
 1050|  14.7k|}	// RDF_LiteralPropertyElement
ParseRDF.cpp:_ZL18FixupQualifiedNodeP8XMP_Node:
  504|      1|{
  505|      1|	size_t qualNum, qualLim;
  506|      1|	size_t childNum, childLim;
  507|       |
  508|      1|	XMP_Enforce ( (xmpParent->options & kXMP_PropValueIsStruct) && (! xmpParent->children.empty()) );
  ------------------
  |  |  148|      2|		if ( ! (c) ) {																				\
  |  |  ------------------
  |  |  |  Branch (148:11): [True: 1, False: 0]
  |  |  |  Branch (148:11): [True: 1, False: 0]
  |  |  ------------------
  |  |  149|      0|			const char * assert_msg = _NotifyMsg ( XMP_Enforce, (c), __FILE__, __LINE__ );			\
  |  |  ------------------
  |  |  |  |  139|      0|#define _NotifyMsg(n,c,f,l)	#n " failed: " #c " in " f " at line " _MakeStr(l)
  |  |  |  |  ------------------
  |  |  |  |  |  |  138|      0|#define _MakeStr(p)			#p
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|      0|			XMP_Throw ( assert_msg , kXMPErr_EnforceFailure );										\
  |  |  ------------------
  |  |  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  |  |  ------------------
  |  |  151|      0|		}
  ------------------
  509|       |
  510|      1|	XMP_Node * valueNode = xmpParent->children[0];
  511|      1|	XMP_Enforce ( valueNode->name == "rdf:value" );
  ------------------
  |  |  148|      1|		if ( ! (c) ) {																				\
  |  |  ------------------
  |  |  |  Branch (148:8): [True: 0, False: 1]
  |  |  ------------------
  |  |  149|      0|			const char * assert_msg = _NotifyMsg ( XMP_Enforce, (c), __FILE__, __LINE__ );			\
  |  |  ------------------
  |  |  |  |  139|      0|#define _NotifyMsg(n,c,f,l)	#n " failed: " #c " in " f " at line " _MakeStr(l)
  |  |  |  |  ------------------
  |  |  |  |  |  |  138|      0|#define _MakeStr(p)			#p
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  150|      0|			XMP_Throw ( assert_msg , kXMPErr_EnforceFailure );										\
  |  |  ------------------
  |  |  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  |  |  ------------------
  |  |  151|      0|		}
  ------------------
  512|       |	
  513|      1|	xmpParent->qualifiers.reserve ( xmpParent->qualifiers.size() + xmpParent->children.size() + valueNode->qualifiers.size() );
  514|       |	
  515|       |	// Move the qualifiers on the value node to the parent. Make sure an xml:lang qualifier stays at
  516|       |	// the front. Check for duplicate names between the value node's qualifiers and the parent's
  517|       |	// children. The parent's children are about to become qualifiers. Check here, between the
  518|       |	// groups. Intra-group duplicates are caught by AddChildNode.
  519|       |	
  520|      1|	qualNum = 0;
  521|      1|	qualLim = valueNode->qualifiers.size();
  522|       |	
  523|      1|	if ( valueNode->options & kXMP_PropHasLang ) {
  ------------------
  |  Branch (523:7): [True: 0, False: 1]
  ------------------
  524|       |
  525|      0|		if ( xmpParent->options & kXMP_PropHasLang ) XMP_Throw ( "Redundant xml:lang for rdf:value element", kXMPErr_BadXMP );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (525:8): [True: 0, False: 0]
  ------------------
  526|       |
  527|      0|		XMP_Node * langQual = valueNode->qualifiers[0];
  528|       |		
  529|      0|		XMP_Assert ( langQual->name == "xml:lang" );
  ------------------
  |  |  142|      0|	#define XMP_Assert(c)	((void) 0)
  ------------------
  530|      0|		langQual->parent = xmpParent;
  531|      0|		xmpParent->options |= kXMP_PropHasLang;
  532|       |
  533|      0|		if ( xmpParent->qualifiers.empty() ) {
  ------------------
  |  Branch (533:8): [True: 0, False: 0]
  ------------------
  534|      0|			xmpParent->qualifiers.push_back ( langQual );	// *** Should use utilities to add qual & set parent.
  535|      0|		} else {
  536|      0|			xmpParent->qualifiers.insert ( xmpParent->qualifiers.begin(), langQual );
  537|      0|		}
  538|      0|		valueNode->qualifiers[0] = 0;	// We just moved it to the parent.
  539|       |
  540|      0|		qualNum = 1;	// Start the remaining copy after the xml:lang qualifier.
  541|       |
  542|      0|	}
  543|       |	
  544|      1|	for ( ; qualNum != qualLim; ++qualNum ) {
  ------------------
  |  Branch (544:10): [True: 0, False: 1]
  ------------------
  545|       |
  546|      0|		XMP_Node * currQual = valueNode->qualifiers[qualNum];
  547|      0|		if ( FindChildNode ( xmpParent, currQual->name.c_str(), kXMP_ExistingOnly ) != 0 ) {
  ------------------
  |  |  296|      0|#define kXMP_ExistingOnly	false
  ------------------
  |  Branch (547:8): [True: 0, False: 0]
  ------------------
  548|      0|			XMP_Throw ( "Duplicate qualifier node", kXMPErr_BadXMP );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  549|      0|		}
  550|       |
  551|      0|		currQual->parent = xmpParent;
  552|      0|		xmpParent->qualifiers.push_back ( currQual );
  553|      0|		valueNode->qualifiers[qualNum] = 0;	// We just moved it to the parent.
  554|       |
  555|      0|	}
  556|       |	
  557|      1|	valueNode->qualifiers.clear();	// ! There should be nothing but null pointers.
  558|       |	
  559|       |	// Change the parent's other children into qualifiers. This loop starts at 1, child 0 is the
  560|       |	// rdf:value node. Put xml:lang at the front, append all others.
  561|       |	
  562|      1|	for ( childNum = 1, childLim = xmpParent->children.size(); childNum != childLim; ++childNum ) {
  ------------------
  |  Branch (562:61): [True: 0, False: 1]
  ------------------
  563|       |
  564|      0|		XMP_Node * currQual = xmpParent->children[childNum];
  565|       |	
  566|      0|			bool isLang = (currQual->name == "xml:lang");
  567|       |			
  568|      0|			currQual->options |= kXMP_PropIsQualifier;
  569|      0|			currQual->parent = xmpParent;
  570|       |
  571|      0|			if ( isLang ) {
  ------------------
  |  Branch (571:9): [True: 0, False: 0]
  ------------------
  572|      0|				if ( xmpParent->options & kXMP_PropHasLang ) XMP_Throw ( "Duplicate xml:lang qualifier", kXMPErr_BadXMP );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (572:10): [True: 0, False: 0]
  ------------------
  573|      0|				xmpParent->options |= kXMP_PropHasLang;
  574|      0|			} else if ( currQual->name == "rdf:type" ) {
  ------------------
  |  Branch (574:16): [True: 0, False: 0]
  ------------------
  575|      0|				xmpParent->options |= kXMP_PropHasType;
  576|      0|			}
  577|       |
  578|      0|			if ( (! isLang) || xmpParent->qualifiers.empty() ) {
  ------------------
  |  Branch (578:9): [True: 0, False: 0]
  |  Branch (578:23): [True: 0, False: 0]
  ------------------
  579|      0|				xmpParent->qualifiers.push_back ( currQual );
  580|      0|			} else {
  581|      0|				xmpParent->qualifiers.insert ( xmpParent->qualifiers.begin(), currQual );
  582|      0|			}
  583|      0|			xmpParent->children[childNum] = 0;	// We just moved it to the qualifers.
  584|       |		
  585|      0|	}
  586|       |	
  587|      1|	if ( ! xmpParent->qualifiers.empty() ) xmpParent->options |= kXMP_PropHasQualifiers;
  ------------------
  |  Branch (587:7): [True: 0, False: 1]
  ------------------
  588|       |	
  589|       |	// Move the options and value last, other checks need the parent's original options. Move the
  590|       |	// value node's children to be the parent's children. Delete the now useless value node.
  591|       |	
  592|      1|	XMP_Assert ( xmpParent->options & (kXMP_PropValueIsStruct | kRDF_HasValueElem) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  593|      1|	xmpParent->options &= ~ (static_cast<unsigned long>(kXMP_PropValueIsStruct) | static_cast<unsigned long>(kRDF_HasValueElem));
  594|      1|	xmpParent->options |= valueNode->options;
  595|       |	
  596|      1|	xmpParent->value.swap ( valueNode->value );
  597|       |	#if 0	// *** XMP_DebugBuild
  598|       |		xmpParent->_valuePtr = xmpParent->value.c_str();
  599|       |	#endif
  600|       |
  601|      1|	xmpParent->children[0] = 0;	// ! Remove the value node itself before the swap.
  602|      1|	xmpParent->children.swap ( valueNode->children );
  603|       |	
  604|      1|	for ( size_t childNum = 0, childLim = xmpParent->children.size(); childNum != childLim; ++childNum ) {
  ------------------
  |  Branch (604:68): [True: 0, False: 1]
  ------------------
  605|      0|		XMP_Node * currChild = xmpParent->children[childNum];
  606|      0|		currChild->parent = xmpParent;
  607|      0|	}
  608|       |
  609|      1|	delete valueNode;
  610|       |	
  611|      1|}	// FixupQualifiedNode
ParseRDF.cpp:_ZL33RDF_ParseTypeOtherPropertyElementP8XMP_NodeRK8XML_Nodeb:
 1146|      5|{
 1147|      5|	IgnoreParam(xmpParent); IgnoreParam(xmlNode); IgnoreParam(isTopLevel); 
  ------------------
  |  |  117|      5|#define IgnoreParam(p)	(void)p
  ------------------
              	IgnoreParam(xmpParent); IgnoreParam(xmlNode); IgnoreParam(isTopLevel); 
  ------------------
  |  |  117|      5|#define IgnoreParam(p)	(void)p
  ------------------
              	IgnoreParam(xmpParent); IgnoreParam(xmlNode); IgnoreParam(isTopLevel); 
  ------------------
  |  |  117|      5|#define IgnoreParam(p)	(void)p
  ------------------
 1148|       |
 1149|      5|	XMP_Throw ( "ParseTypeOther property element not allowed", kXMPErr_BadXMP );
  ------------------
  |  |  199|      5|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
 1150|       |
 1151|      0|}	// RDF_ParseTypeOtherPropertyElement
ParseRDF.cpp:_ZL27RDF_ResourcePropertyElementP8XMP_NodeRK8XML_Nodeb:
  942|  4.84k|{
  943|  4.84k|	if ( isTopLevel && (xmlNode.name == "iX:changes") ) return;	// Strip old "punchcard" chaff.
  ------------------
  |  Branch (943:7): [True: 4.83k, False: 13]
  |  Branch (943:21): [True: 0, False: 4.83k]
  ------------------
  944|       |	
  945|  4.84k|	XMP_Node * newCompound = AddChildNode ( xmpParent, xmlNode, "", isTopLevel );
  946|       |	
  947|  4.84k|	XML_cNodePos currAttr = xmlNode.attrs.begin();
  948|  4.84k|	XML_cNodePos endAttr  = xmlNode.attrs.end();
  949|       |
  950|  4.85k|	for ( ; currAttr != endAttr; ++currAttr ) {
  ------------------
  |  Branch (950:10): [True: 6, False: 4.84k]
  ------------------
  951|      6|		XMP_VarString & attrName = (*currAttr)->name;
  952|      6|		if ( attrName == "xml:lang" ) {
  ------------------
  |  Branch (952:8): [True: 6, False: 0]
  ------------------
  953|      6|			AddQualifierNode ( newCompound, **currAttr );
  954|      6|		} else if ( attrName == "rdf:ID" ) {
  ------------------
  |  Branch (954:15): [True: 0, False: 0]
  ------------------
  955|      0|			continue;	// Ignore all rdf:ID attributes.
  956|      0|		} else {
  957|      0|			XMP_Throw ( "Invalid attribute for resource property element", kXMPErr_BadRDF );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  958|      0|		}
  959|      6|	}
  960|       |	
  961|  4.84k|	XML_cNodePos currChild = xmlNode.content.begin();
  962|  4.84k|	XML_cNodePos endChild  = xmlNode.content.end();
  963|       |
  964|  14.7k|	for ( ; currChild != endChild; ++currChild ) {
  ------------------
  |  Branch (964:10): [True: 14.7k, False: 1]
  ------------------
  965|  14.7k|		if ( ! (*currChild)->IsWhitespaceNode() ) break;
  ------------------
  |  Branch (965:8): [True: 4.84k, False: 9.89k]
  ------------------
  966|  14.7k|	}
  967|  4.84k|	if ( currChild == endChild ) XMP_Throw ( "Missing child of resource property element", kXMPErr_BadRDF );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (967:7): [True: 0, False: 4.84k]
  ------------------
  968|  4.84k|	if ( (*currChild)->kind != kElemNode ) XMP_Throw ( "Children of resource property element must be XML elements", kXMPErr_BadRDF );
  ------------------
  |  |  199|     24|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (968:7): [True: 24, False: 4.82k]
  ------------------
  969|       |
  970|  4.82k|	if ( (*currChild)->name == "rdf:Bag" ) {
  ------------------
  |  Branch (970:7): [True: 496, False: 4.32k]
  ------------------
  971|    496|		newCompound->options |= kXMP_PropValueIsArray;
  972|  4.32k|	} else if ( (*currChild)->name == "rdf:Seq" ) {
  ------------------
  |  Branch (972:14): [True: 2.95k, False: 1.36k]
  ------------------
  973|  2.95k|		newCompound->options |= kXMP_PropValueIsArray | kXMP_PropArrayIsOrdered;
  974|  2.95k|	} else if ( (*currChild)->name == "rdf:Alt" ) {
  ------------------
  |  Branch (974:14): [True: 1.34k, False: 22]
  ------------------
  975|  1.34k|		newCompound->options |= kXMP_PropValueIsArray | kXMP_PropArrayIsOrdered | kXMP_PropArrayIsAlternate;
  976|  1.34k|	} else {
  977|     22|		newCompound->options |= kXMP_PropValueIsStruct;
  978|     22|		if ( (*currChild)->name != "rdf:Description" ) {
  ------------------
  |  Branch (978:8): [True: 18, False: 4]
  ------------------
  979|     18|			XMP_VarString typeName ( (*currChild)->ns );
  980|     18|			size_t        colonPos = (*currChild)->name.find_first_of(':');
  981|     18|			if ( colonPos == XMP_VarString::npos ) XMP_Throw ( "All XML elements must be in a namespace", kXMPErr_BadXMP );
  ------------------
  |  |  199|      1|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (981:9): [True: 1, False: 17]
  ------------------
  982|     17|			typeName.append ( (*currChild)->name, colonPos, XMP_VarString::npos );
  983|     17|			AddQualifierNode ( newCompound, XMP_VarString("rdf:type"), typeName );
  984|     17|		}
  985|     22|	}
  986|       |
  987|  4.82k|	RDF_NodeElement ( newCompound, **currChild, kNotTopLevel );
  988|  4.82k|	if ( newCompound->options & kRDF_HasValueElem ) {
  ------------------
  |  Branch (988:7): [True: 1, False: 4.82k]
  ------------------
  989|      1|		FixupQualifiedNode ( newCompound );
  990|  4.82k|	} else if ( newCompound->options & kXMP_PropArrayIsAlternate ) {
  ------------------
  |  Branch (990:14): [True: 1.32k, False: 3.49k]
  ------------------
  991|  1.32k|		DetectAltText ( newCompound );
  992|  1.32k|	}
  993|       |
  994|  14.4k|	for ( ++currChild; currChild != endChild; ++currChild ) {
  ------------------
  |  Branch (994:21): [True: 9.67k, False: 4.80k]
  ------------------
  995|  9.67k|		if ( ! (*currChild)->IsWhitespaceNode() ) XMP_Throw ( "Invalid child of resource property element", kXMPErr_BadRDF );
  ------------------
  |  |  199|     17|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (995:8): [True: 17, False: 9.65k]
  ------------------
  996|  9.65k|	}
  997|       |
  998|  4.82k|}	// RDF_ResourcePropertyElement

_Z28InitializeUnicodeConversionsv:
  147|      1|{
  148|      1|	UC_Assert ( (sizeof(UTF8Unit) == 1) && (sizeof(UTF16Unit) == 2) && (sizeof(UTF32Unit) == 4) ); 
  149|       |
  150|      1|	UTF16Unit u16  = 0x00FF;
  151|      1|	bool bigEndian = (*((UTF8Unit*)&u16) == 0);
  152|       |
  153|      1|	UTF8_to_UTF16Native = UTF8_to_UTF16Nat;
  154|      1|	UTF8_to_UTF32Native = UTF8_to_UTF32Nat;
  155|      1|	UTF16Native_to_UTF8 = UTF16Nat_to_UTF8;
  156|      1|	UTF32Native_to_UTF8 = UTF32Nat_to_UTF8;
  157|       |	
  158|      1|	if ( bigEndian ) {
  ------------------
  |  Branch (158:7): [True: 0, False: 1]
  ------------------
  159|       |	
  160|      0|		swap32to16Offset = 0;
  161|       |
  162|      0|		CodePoint_to_UTF16BE = CodePoint_to_UTF16Nat;
  163|      0|		CodePoint_to_UTF16LE = CodePoint_to_UTF16Swp;
  164|       |
  165|      0|		CodePoint_from_UTF16BE = CodePoint_from_UTF16Nat;
  166|      0|		CodePoint_from_UTF16LE = CodePoint_from_UTF16Swp;
  167|       |
  168|      0|		UTF8_to_UTF16BE = UTF8_to_UTF16Nat;
  169|      0|		UTF8_to_UTF16LE = UTF8_to_UTF16Swp;
  170|      0|		UTF8_to_UTF32BE = UTF8_to_UTF32Nat;
  171|      0|		UTF8_to_UTF32LE = UTF8_to_UTF32Swp;
  172|       |
  173|      0|		UTF16BE_to_UTF8 = UTF16Nat_to_UTF8;
  174|      0|		UTF16LE_to_UTF8 = UTF16Swp_to_UTF8;
  175|      0|		UTF32BE_to_UTF8 = UTF32Nat_to_UTF8;
  176|      0|		UTF32LE_to_UTF8 = UTF32Swp_to_UTF8;
  177|       |
  178|      0|		UTF16BE_to_UTF32BE = UTF16Nat_to_UTF32Nat;
  179|      0|		UTF16BE_to_UTF32LE = UTF16Nat_to_UTF32Swp;
  180|      0|		UTF16LE_to_UTF32BE = UTF16Swp_to_UTF32Nat;
  181|      0|		UTF16LE_to_UTF32LE = UTF16Swp_to_UTF32Swp;
  182|       |
  183|      0|		UTF32BE_to_UTF16BE = UTF32Nat_to_UTF16Nat;
  184|      0|		UTF32BE_to_UTF16LE = UTF32Nat_to_UTF16Swp;
  185|      0|		UTF32LE_to_UTF16BE = UTF32Swp_to_UTF16Nat;
  186|      0|		UTF32LE_to_UTF16LE = UTF32Swp_to_UTF16Swp;
  187|       |
  188|      1|	} else {
  189|       |	
  190|      1|		swap32to16Offset = 1;	// ! Offset in UTF16 units!
  191|       |
  192|      1|		CodePoint_to_UTF16BE = CodePoint_to_UTF16Swp;
  193|      1|		CodePoint_to_UTF16LE = CodePoint_to_UTF16Nat;
  194|       |
  195|      1|		CodePoint_from_UTF16BE = CodePoint_from_UTF16Swp;
  196|      1|		CodePoint_from_UTF16LE = CodePoint_from_UTF16Nat;
  197|       |
  198|      1|		UTF8_to_UTF16BE = UTF8_to_UTF16Swp;
  199|      1|		UTF8_to_UTF16LE = UTF8_to_UTF16Nat;
  200|      1|		UTF8_to_UTF32BE = UTF8_to_UTF32Swp;
  201|      1|		UTF8_to_UTF32LE = UTF8_to_UTF32Nat;
  202|       |
  203|      1|		UTF16BE_to_UTF8 = UTF16Swp_to_UTF8;
  204|      1|		UTF16LE_to_UTF8 = UTF16Nat_to_UTF8;
  205|      1|		UTF32BE_to_UTF8 = UTF32Swp_to_UTF8;
  206|      1|		UTF32LE_to_UTF8 = UTF32Nat_to_UTF8;
  207|       |
  208|      1|		UTF16BE_to_UTF32BE = UTF16Swp_to_UTF32Swp;
  209|      1|		UTF16BE_to_UTF32LE = UTF16Swp_to_UTF32Nat;
  210|      1|		UTF16LE_to_UTF32BE = UTF16Nat_to_UTF32Swp;
  211|      1|		UTF16LE_to_UTF32LE = UTF16Nat_to_UTF32Nat;
  212|       |
  213|      1|		UTF32BE_to_UTF16BE = UTF32Swp_to_UTF16Swp;
  214|      1|		UTF32BE_to_UTF16LE = UTF32Swp_to_UTF16Nat;
  215|      1|		UTF32LE_to_UTF16BE = UTF32Nat_to_UTF16Swp;
  216|      1|		UTF32LE_to_UTF16LE = UTF32Nat_to_UTF16Nat;
  217|       |
  218|      1|	}
  219|       |
  220|      1|}	// InitializeUnicodeConversions
_Z19CodePoint_from_UTF8PKhmPjPm:
  567|  1.97k|{
  568|  1.97k|	UTF8Unit inUnit;	// ! Don't read until we know there is input.
  569|  1.97k|	size_t unitCount = 0;
  570|       |
  571|  1.97k|	UC_Assert ( (utf8In != 0) && (cpOut != 0) && (utf8Read != 0) );
  572|  1.97k|	if ( utf8Len == 0 ) goto Done;
  ------------------
  |  Branch (572:7): [True: 0, False: 1.97k]
  ------------------
  573|  1.97k|	inUnit = *utf8In;
  574|  1.97k|	if ( inUnit >= 0x80 ) goto MultiByte;	// ! Force linear execution path for ASCII.
  ------------------
  |  Branch (574:7): [True: 1.97k, False: 0]
  ------------------
  575|       |	
  576|      0|	unitCount = 1;
  577|      0|	*cpOut = inUnit;	// ! Don't put after Done, don't write if no input.
  578|       |	
  579|      0|Done:	
  580|      0|	*utf8Read = unitCount;
  581|      0|	return;
  582|       |
  583|  1.97k|MultiByte:
  584|  1.97k|	CodePoint_from_UTF8_Multi ( utf8In, utf8Len, cpOut, utf8Read );
  585|  1.97k|	return;
  586|       |	
  587|      0|}	// CodePoint_from_UTF8
UnicodeConversions.cpp:_ZL25CodePoint_from_UTF8_MultiPKhmPjPm:
  516|  1.97k|{
  517|  1.97k|	UTF8Unit  inUnit = *utf8In;
  518|  1.97k|	size_t    unitCount = 0;
  519|  1.97k|	UTF32Unit cp;	// ! Avoid gcc complaints about declarations after goto's.
  520|  1.97k|	const UTF8Unit * utf8Pos;
  521|       |
  522|       |	// -------------------------------------------------------------------------------------
  523|       |	// We've got a multibyte UTF-8 character. The first byte has the number of bytes and the
  524|       |	// highest order data bits. The other bytes each add 6 more data bits.
  525|       |	
  526|       |	#if 0	// This might be a more effcient way to count the bytes.
  527|       |		static XMP_Uns8 kByteCounts[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 4 };
  528|       |		size_t bytesNeeded = kByteCounts [ inUnit >> 4 ];
  529|       |		if ( (bytesNeeded < 2) || ((bytesNeeded == 4) && ((inUnit & 0x08) != 0)) ) {
  530|       |			UC_Throw ( "Invalid UTF-8 sequence length", kXMPErr_BadParam );
  531|       |		}
  532|       |	#endif
  533|       |
  534|  1.97k|	size_t bytesNeeded = 0;	// Count the leading 1 bits in the first byte.
  535|  6.20k|	for ( UTF8Unit temp = inUnit; temp > 0x7F; temp = temp << 1 ) ++bytesNeeded;
  ------------------
  |  Branch (535:32): [True: 4.23k, False: 1.97k]
  ------------------
  536|       |		// *** Consider CPU-specific assembly inline, e.g. cntlzw on PowerPC.
  537|       |	
  538|  1.97k|	if ( (bytesNeeded < 2) || (bytesNeeded > 4) ) UC_Throw ( "Invalid UTF-8 sequence length", kXMPErr_BadParam );
  ------------------
  |  |   18|      0|	#define UC_Throw(msg,id)  throw XMP_Error ( id, msg )
  ------------------
  |  Branch (538:7): [True: 0, False: 1.97k]
  |  Branch (538:28): [True: 0, False: 1.97k]
  ------------------
  539|  1.97k|	if ( bytesNeeded > utf8Len ) goto Done;	// Not enough input in this buffer.
  ------------------
  |  Branch (539:7): [True: 0, False: 1.97k]
  ------------------
  540|  1.97k|	unitCount = bytesNeeded;
  541|       |	
  542|  1.97k|	cp = inUnit & ((1 << (7-unitCount)) - 1);	// Isolate the initial data bits in the bottom of cp.
  543|       |	
  544|  1.97k|	utf8Pos = utf8In + 1;	// We've absorbed the first byte.
  545|  4.23k|	for ( --bytesNeeded; bytesNeeded > 0; --bytesNeeded, ++utf8Pos ) {
  ------------------
  |  Branch (545:23): [True: 2.26k, False: 1.97k]
  ------------------
  546|  2.26k|		inUnit = *utf8Pos;
  547|  2.26k|		if ( (inUnit & UTF8Unit(0xC0)) != UTF8Unit(0x80) ) UC_Throw ( "Invalid UTF-8 data byte", kXMPErr_BadParam );
  ------------------
  |  |   18|      0|	#define UC_Throw(msg,id)  throw XMP_Error ( id, msg )
  ------------------
  |  Branch (547:8): [True: 0, False: 2.26k]
  ------------------
  548|  2.26k|		cp = (cp << 6) | (inUnit & 0x3F);
  549|  2.26k|	}
  550|       |	
  551|  1.97k|	if ( cp >= 0xD800 ) {	// Skip the next comparisons most of the time.
  ------------------
  |  Branch (551:7): [True: 0, False: 1.97k]
  ------------------
  552|      0|		if ( (0xD800 <= cp) && (cp <= 0xDFFF) ) UC_Throw ( "Bad UTF-8 - surrogate code point", kXMPErr_BadParam );
  ------------------
  |  |   18|      0|	#define UC_Throw(msg,id)  throw XMP_Error ( id, msg )
  ------------------
  |  Branch (552:8): [True: 0, False: 0]
  |  Branch (552:26): [True: 0, False: 0]
  ------------------
  553|      0|		if ( cp > 0x10FFFF ) UC_Throw ( "Bad UTF-8 - out of range", kXMPErr_BadParam );
  ------------------
  |  |   18|      0|	#define UC_Throw(msg,id)  throw XMP_Error ( id, msg )
  ------------------
  |  Branch (553:8): [True: 0, False: 0]
  ------------------
  554|      0|	}
  555|       |	
  556|  1.97k|	*cpOut = cp;	// ! Don't put after Done, don't write if no input.
  557|       |	
  558|  1.97k|Done:	
  559|  1.97k|	*utf8Read = unitCount;
  560|  1.97k|	return;
  561|       |	
  562|  1.97k|}	// CodePoint_from_UTF8_Multi

XMPCore_Impl.cpp:_ZL19VerifySimpleXMLNamePKcS0_:
   87|   245k|{
   88|       |
   89|   245k|	const XMP_Uns8 * nameStart = (const XMP_Uns8 *) _nameStart;
   90|   245k|	const XMP_Uns8 * nameEnd   = (const XMP_Uns8 *) _nameEnd;
   91|   245k|	const XMP_Uns8 * namePos   = nameStart;
   92|   245k|	XMP_Uns32 cp;
   93|       |	
   94|       |	// The first character is more restricted.
   95|       |	
   96|   245k|	if ( nameStart >= nameEnd ) XMP_Throw ( "Empty XML name", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (96:7): [True: 0, False: 245k]
  ------------------
   97|       |
   98|   245k|	cp = *namePos;
   99|   245k|	if ( cp < 0x80 ) {
  ------------------
  |  Branch (99:7): [True: 245k, False: 230]
  ------------------
  100|   245k|		++namePos;
  101|   245k|		if ( ! IsStartChar_ASCII(cp) ) goto NameError;
  ------------------
  |  Branch (101:8): [True: 0, False: 245k]
  ------------------
  102|   245k|	} else {
  103|    230|		cp = GetCodePoint ( &namePos );
  104|    230|		if ( ! IsStartChar_NonASCII(cp) ) goto NameError;
  ------------------
  |  Branch (104:8): [True: 0, False: 230]
  ------------------
  105|    230|	}
  106|       |
  107|       |	// Check the rest of the name.
  108|       |	
  109|  13.1M|	while ( namePos < nameEnd ) {
  ------------------
  |  Branch (109:10): [True: 12.8M, False: 245k]
  ------------------
  110|  12.8M|		cp = *namePos;
  111|  12.8M|		if ( cp < 0x80 ) {
  ------------------
  |  Branch (111:8): [True: 12.8M, False: 811]
  ------------------
  112|  12.8M|			++namePos;
  113|  12.8M|			if ( (! IsStartChar_ASCII(cp)) && (! IsOtherChar_ASCII(cp)) ) goto NameError;
  ------------------
  |  Branch (113:9): [True: 211k, False: 12.6M]
  |  Branch (113:38): [True: 0, False: 211k]
  ------------------
  114|  12.8M|		} else {
  115|    811|			cp = GetCodePoint ( &namePos );
  116|    811|			if ( (! IsStartChar_NonASCII(cp)) && (! IsOtherChar_NonASCII(cp)) ) goto NameError;
  ------------------
  |  Branch (116:9): [True: 158, False: 653]
  |  Branch (116:41): [True: 0, False: 158]
  ------------------
  117|    811|		}
  118|  12.8M|	}
  119|       |
  120|   245k|	return;
  121|       |
  122|   245k|NameError:
  123|      0|	XMP_Throw ( "Bad XML name", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  124|       |	
  125|      0|}	// VerifySimpleXMLName
XMPCore_Impl.cpp:_ZL17IsStartChar_ASCIIj:
   31|  13.1M|{
   32|       |	// ASCII starting characters for an XML name.
   33|  13.1M|	if ( (('a' <= cp) && (cp <= 'z')) || (('A' <= cp) && (cp <= 'Z')) || (cp == '_') ) return true;
  ------------------
  |  Branch (33:8): [True: 12.6M, False: 507k]
  |  Branch (33:23): [True: 12.6M, False: 0]
  |  Branch (33:40): [True: 295k, False: 211k]
  |  Branch (33:55): [True: 295k, False: 844]
  |  Branch (33:71): [True: 844, False: 211k]
  ------------------
   34|   211k|	return false;
   35|  13.1M|}
XMPCore_Impl.cpp:_ZL12GetCodePointPPKh:
   19|  1.04k|{
   20|  1.04k|	const XMP_Uns8 * u8Ptr = *utf8Str_io;
   21|  1.04k|	XMP_Uns32 cp;
   22|  1.04k|	size_t u8Len;
   23|  1.04k|	CodePoint_from_UTF8 ( u8Ptr, 4, &cp, &u8Len );	// Throws an exception for errors.
   24|  1.04k|	*utf8Str_io = u8Ptr + u8Len;
   25|  1.04k|	return cp;
   26|  1.04k|}
XMPCore_Impl.cpp:_ZL20IsStartChar_NonASCIIj:
   40|  1.04k|{
   41|       |	// Non-ASCII starting characters for an XML name.
   42|       |	
   43|  1.04k|	if ( ((0xC0 <= cp) && (cp <= 0xD6))  || ((0xD8 <= cp) && (cp <= 0xF6)) ) return true;
  ------------------
  |  Branch (43:8): [True: 926, False: 115]
  |  Branch (43:24): [True: 136, False: 790]
  |  Branch (43:43): [True: 790, False: 115]
  |  Branch (43:59): [True: 153, False: 637]
  ------------------
   44|    752|	if ( ((0xF8 <= cp) && (cp <= 0x2FF)) || ((0x370 <= cp) && (cp <= 0x37D)) ) return true;
  ------------------
  |  Branch (44:8): [True: 637, False: 115]
  |  Branch (44:24): [True: 494, False: 143]
  |  Branch (44:43): [True: 100, False: 158]
  |  Branch (44:60): [True: 0, False: 100]
  ------------------
   45|       |
   46|    258|	if ( ((0x37F <= cp) && (cp <= 0x1FFF))  || ((0x200C <= cp) && (cp <= 0x200D)) ) return true;
  ------------------
  |  Branch (46:8): [True: 100, False: 158]
  |  Branch (46:25): [True: 81, False: 19]
  |  Branch (46:46): [True: 19, False: 158]
  |  Branch (46:64): [True: 0, False: 19]
  ------------------
   47|    177|	if ( ((0x2070 <= cp) && (cp <= 0x218F)) || ((0x2C00 <= cp) && (cp <= 0x2FEF)) ) return true;
  ------------------
  |  Branch (47:8): [True: 19, False: 158]
  |  Branch (47:26): [True: 0, False: 19]
  |  Branch (47:46): [True: 19, False: 158]
  |  Branch (47:64): [True: 0, False: 19]
  ------------------
   48|    177|	if ( ((0x3001 <= cp) && (cp <= 0xD7FF)) || ((0xF900 <= cp) && (cp <= 0xFDCF)) ) return true;
  ------------------
  |  Branch (48:8): [True: 19, False: 158]
  |  Branch (48:26): [True: 19, False: 0]
  |  Branch (48:46): [True: 0, False: 158]
  |  Branch (48:64): [True: 0, False: 0]
  ------------------
   49|    158|	if ( ((0xFDF0 <= cp) && (cp <= 0xFFFD)) || ((0x10000 <= cp) && (cp <= 0xEFFFF)) ) return true;
  ------------------
  |  Branch (49:8): [True: 0, False: 158]
  |  Branch (49:26): [True: 0, False: 0]
  |  Branch (49:46): [True: 0, False: 158]
  |  Branch (49:65): [True: 0, False: 0]
  ------------------
   50|       |
   51|    158|	return false;
   52|       |
   53|    158|}
XMPCore_Impl.cpp:_ZL17IsOtherChar_ASCIIj:
   58|   211k|{
   59|       |	// ASCII following characters for an XML name.
   60|   211k|	if ( (('0' <= cp) && (cp <= '9')) || (cp == '-') || (cp == '.') ) return true;
  ------------------
  |  Branch (60:8): [True: 183k, False: 28.5k]
  |  Branch (60:23): [True: 183k, False: 0]
  |  Branch (60:39): [True: 25.9k, False: 2.52k]
  |  Branch (60:54): [True: 2.52k, False: 0]
  ------------------
   61|      0|	return false;
   62|   211k|}
XMPCore_Impl.cpp:_ZL20IsOtherChar_NonASCIIj:
   67|    158|{
   68|       |	// Non-ASCII following characters for an XML name.
   69|    158|	if ( (cp == 0xB7) || ((0x300 <= cp) && (cp <= 0x36F))  || ((0x203F <= cp) && (cp <= 0x2040)) ) return true;
  ------------------
  |  Branch (69:7): [True: 115, False: 43]
  |  Branch (69:24): [True: 43, False: 0]
  |  Branch (69:41): [True: 43, False: 0]
  |  Branch (69:61): [True: 0, False: 0]
  |  Branch (69:79): [True: 0, False: 0]
  ------------------
   70|      0|	return false;
   71|    158|}
XMPMeta.cpp:_ZL19VerifySimpleXMLNamePKcS0_:
   87|  35.4k|{
   88|       |
   89|  35.4k|	const XMP_Uns8 * nameStart = (const XMP_Uns8 *) _nameStart;
   90|  35.4k|	const XMP_Uns8 * nameEnd   = (const XMP_Uns8 *) _nameEnd;
   91|  35.4k|	const XMP_Uns8 * namePos   = nameStart;
   92|  35.4k|	XMP_Uns32 cp;
   93|       |	
   94|       |	// The first character is more restricted.
   95|       |	
   96|  35.4k|	if ( nameStart >= nameEnd ) XMP_Throw ( "Empty XML name", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (96:7): [True: 0, False: 35.4k]
  ------------------
   97|       |
   98|  35.4k|	cp = *namePos;
   99|  35.4k|	if ( cp < 0x80 ) {
  ------------------
  |  Branch (99:7): [True: 35.3k, False: 149]
  ------------------
  100|  35.3k|		++namePos;
  101|  35.3k|		if ( ! IsStartChar_ASCII(cp) ) goto NameError;
  ------------------
  |  Branch (101:8): [True: 0, False: 35.3k]
  ------------------
  102|  35.3k|	} else {
  103|    149|		cp = GetCodePoint ( &namePos );
  104|    149|		if ( ! IsStartChar_NonASCII(cp) ) goto NameError;
  ------------------
  |  Branch (104:8): [True: 0, False: 149]
  ------------------
  105|    149|	}
  106|       |
  107|       |	// Check the rest of the name.
  108|       |	
  109|   148k|	while ( namePos < nameEnd ) {
  ------------------
  |  Branch (109:10): [True: 113k, False: 35.4k]
  ------------------
  110|   113k|		cp = *namePos;
  111|   113k|		if ( cp < 0x80 ) {
  ------------------
  |  Branch (111:8): [True: 112k, False: 780]
  ------------------
  112|   112k|			++namePos;
  113|   112k|			if ( (! IsStartChar_ASCII(cp)) && (! IsOtherChar_ASCII(cp)) ) goto NameError;
  ------------------
  |  Branch (113:9): [True: 8.01k, False: 104k]
  |  Branch (113:38): [True: 0, False: 8.01k]
  ------------------
  114|   112k|		} else {
  115|    780|			cp = GetCodePoint ( &namePos );
  116|    780|			if ( (! IsStartChar_NonASCII(cp)) && (! IsOtherChar_NonASCII(cp)) ) goto NameError;
  ------------------
  |  Branch (116:9): [True: 105, False: 675]
  |  Branch (116:41): [True: 0, False: 105]
  ------------------
  117|    780|		}
  118|   113k|	}
  119|       |
  120|  35.4k|	return;
  121|       |
  122|  35.4k|NameError:
  123|      0|	XMP_Throw ( "Bad XML name", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  124|       |	
  125|      0|}	// VerifySimpleXMLName
XMPMeta.cpp:_ZL17IsStartChar_ASCIIj:
   31|   147k|{
   32|       |	// ASCII starting characters for an XML name.
   33|   147k|	if ( (('a' <= cp) && (cp <= 'z')) || (('A' <= cp) && (cp <= 'Z')) || (cp == '_') ) return true;
  ------------------
  |  Branch (33:8): [True: 123k, False: 24.1k]
  |  Branch (33:23): [True: 123k, False: 0]
  |  Branch (33:40): [True: 16.0k, False: 8.01k]
  |  Branch (33:55): [True: 15.3k, False: 727]
  |  Branch (33:71): [True: 727, False: 8.01k]
  ------------------
   34|  8.01k|	return false;
   35|   147k|}
XMPMeta.cpp:_ZL12GetCodePointPPKh:
   19|    929|{
   20|    929|	const XMP_Uns8 * u8Ptr = *utf8Str_io;
   21|    929|	XMP_Uns32 cp;
   22|    929|	size_t u8Len;
   23|    929|	CodePoint_from_UTF8 ( u8Ptr, 4, &cp, &u8Len );	// Throws an exception for errors.
   24|    929|	*utf8Str_io = u8Ptr + u8Len;
   25|    929|	return cp;
   26|    929|}
XMPMeta.cpp:_ZL20IsStartChar_NonASCIIj:
   40|    929|{
   41|       |	// Non-ASCII starting characters for an XML name.
   42|       |	
   43|    929|	if ( ((0xC0 <= cp) && (cp <= 0xD6))  || ((0xD8 <= cp) && (cp <= 0xF6)) ) return true;
  ------------------
  |  Branch (43:8): [True: 919, False: 10]
  |  Branch (43:24): [True: 77, False: 842]
  |  Branch (43:43): [True: 842, False: 10]
  |  Branch (43:59): [True: 77, False: 765]
  ------------------
   44|    775|	if ( ((0xF8 <= cp) && (cp <= 0x2FF)) || ((0x370 <= cp) && (cp <= 0x37D)) ) return true;
  ------------------
  |  Branch (44:8): [True: 765, False: 10]
  |  Branch (44:24): [True: 244, False: 521]
  |  Branch (44:43): [True: 426, False: 105]
  |  Branch (44:60): [True: 0, False: 426]
  ------------------
   45|       |
   46|    531|	if ( ((0x37F <= cp) && (cp <= 0x1FFF))  || ((0x200C <= cp) && (cp <= 0x200D)) ) return true;
  ------------------
  |  Branch (46:8): [True: 426, False: 105]
  |  Branch (46:25): [True: 329, False: 97]
  |  Branch (46:46): [True: 97, False: 105]
  |  Branch (46:64): [True: 0, False: 97]
  ------------------
   47|    202|	if ( ((0x2070 <= cp) && (cp <= 0x218F)) || ((0x2C00 <= cp) && (cp <= 0x2FEF)) ) return true;
  ------------------
  |  Branch (47:8): [True: 97, False: 105]
  |  Branch (47:26): [True: 0, False: 97]
  |  Branch (47:46): [True: 97, False: 105]
  |  Branch (47:64): [True: 0, False: 97]
  ------------------
   48|    202|	if ( ((0x3001 <= cp) && (cp <= 0xD7FF)) || ((0xF900 <= cp) && (cp <= 0xFDCF)) ) return true;
  ------------------
  |  Branch (48:8): [True: 97, False: 105]
  |  Branch (48:26): [True: 97, False: 0]
  |  Branch (48:46): [True: 0, False: 105]
  |  Branch (48:64): [True: 0, False: 0]
  ------------------
   49|    105|	if ( ((0xFDF0 <= cp) && (cp <= 0xFFFD)) || ((0x10000 <= cp) && (cp <= 0xEFFFF)) ) return true;
  ------------------
  |  Branch (49:8): [True: 0, False: 105]
  |  Branch (49:26): [True: 0, False: 0]
  |  Branch (49:46): [True: 0, False: 105]
  |  Branch (49:65): [True: 0, False: 0]
  ------------------
   50|       |
   51|    105|	return false;
   52|       |
   53|    105|}
XMPMeta.cpp:_ZL17IsOtherChar_ASCIIj:
   58|  8.01k|{
   59|       |	// ASCII following characters for an XML name.
   60|  8.01k|	if ( (('0' <= cp) && (cp <= '9')) || (cp == '-') || (cp == '.') ) return true;
  ------------------
  |  Branch (60:8): [True: 5.75k, False: 2.26k]
  |  Branch (60:23): [True: 5.75k, False: 0]
  |  Branch (60:39): [True: 732, False: 1.53k]
  |  Branch (60:54): [True: 1.53k, False: 0]
  ------------------
   61|      0|	return false;
   62|  8.01k|}
XMPMeta.cpp:_ZL20IsOtherChar_NonASCIIj:
   67|    105|{
   68|       |	// Non-ASCII following characters for an XML name.
   69|    105|	if ( (cp == 0xB7) || ((0x300 <= cp) && (cp <= 0x36F))  || ((0x203F <= cp) && (cp <= 0x2040)) ) return true;
  ------------------
  |  Branch (69:7): [True: 10, False: 95]
  |  Branch (69:24): [True: 95, False: 0]
  |  Branch (69:41): [True: 95, False: 0]
  |  Branch (69:61): [True: 0, False: 0]
  |  Branch (69:79): [True: 0, False: 0]
  ------------------
   70|      0|	return false;
   71|    105|}

WXMPIterator_PropCTor_1:
   40|  10.4k|{
   41|  10.4k|    XMP_ENTER_WRAPPER ( "WXMPIterator_PropCTor_1" )
  ------------------
  |  |  241|  10.4k|	AnnounceEntry ( proc );									\
  |  |  242|  10.4k|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|  10.4k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|  10.4k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  10.4k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|  10.4k|	try {													\
  |  |  245|  10.4k|		XMP_AutoMutex mutex;								\
  |  |  246|  10.4k|		wResult->errMessage = 0;
  ------------------
   42|       |
   43|  10.4k|		if ( schemaNS == 0 ) schemaNS = "";
  ------------------
  |  Branch (43:8): [True: 0, False: 10.4k]
  ------------------
   44|  10.4k|		if ( propName == 0 ) propName = "";
  ------------------
  |  Branch (44:8): [True: 0, False: 10.4k]
  ------------------
   45|       |
   46|  10.4k|		const XMPMeta & xmpObj = WtoXMPMeta_Ref ( xmpRef );
  ------------------
  |  |  108|  10.4k|#define WtoXMPMeta_Ref(xmpRef)	*((const XMPMeta *)(xmpRef))
  ------------------
   47|  10.4k|		XMPIterator *   iter   = new XMPIterator ( xmpObj, schemaNS, propName, options );
   48|  10.4k|		++iter->clientRefs;
   49|  10.4k|		XMP_Assert ( iter->clientRefs == 1 );
  ------------------
  |  |  142|  10.4k|	#define XMP_Assert(c)	((void) 0)
  ------------------
   50|  10.4k|		wResult->ptrResult = XMPIteratorRef ( iter );
   51|       |
   52|  10.4k|    XMP_EXIT_WRAPPER
  ------------------
  |  |  249|  10.4k|	XMP_CATCH_EXCEPTIONS	\
  |  |  ------------------
  |  |  |  |  265|  10.4k|	} catch ( XMP_Error & xmpErr ) {								\
  |  |  |  |  266|      0|		wResult->int32Result = xmpErr.GetID(); 						\
  |  |  |  |  267|      0|		wResult->ptrResult   = (void*)"XMP";						\
  |  |  |  |  268|      0|		wResult->errMessage  = xmpErr.GetErrMsg();					\
  |  |  |  |  269|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (269:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  270|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  271|      0|	} catch ( std::exception & stdErr ) {							\
  |  |  |  |  272|      0|		wResult->int32Result = kXMPErr_StdException; 				\
  |  |  |  |  273|      0|		wResult->errMessage  = stdErr.what(); 						\
  |  |  |  |  274|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (274:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  275|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  276|      0|	} catch ( ... ) {												\
  |  |  |  |  277|      0|		wResult->int32Result = kXMPErr_UnknownException; 			\
  |  |  |  |  278|      0|		wResult->errMessage  = "Caught unknown exception";			\
  |  |  |  |  279|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  280|      0|	}
  |  |  ------------------
  |  |  250|  10.4k|	AnnounceExit();
  ------------------
   53|  10.4k|}
WXMPIterator_DecrementRefCount_1:
   96|  10.4k|{
   97|  10.4k|	WXMP_Result * wResult = &void_wResult;	// ! Needed to "fool" the EnterWrapper macro.
   98|  10.4k|	XMP_ENTER_WRAPPER ( "WXMPIterator_DecrementRefCount_1" )
  ------------------
  |  |  241|  10.4k|	AnnounceEntry ( proc );									\
  |  |  242|  10.4k|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|  10.4k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|  10.4k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  10.4k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|  10.4k|	try {													\
  |  |  245|  10.4k|		XMP_AutoMutex mutex;								\
  |  |  246|  10.4k|		wResult->errMessage = 0;
  ------------------
   99|       |
  100|  10.4k|		XMPIterator * thiz = (XMPIterator*)iterRef;
  101|       |		
  102|  10.4k|		XMP_Assert ( thiz->clientRefs > 0 );
  ------------------
  |  |  142|  10.4k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  103|  10.4k|		--thiz->clientRefs;
  104|  10.4k|		if ( thiz->clientRefs <= 0 ) delete ( thiz );
  ------------------
  |  Branch (104:8): [True: 10.4k, False: 0]
  ------------------
  105|       |
  106|  10.4k|	XMP_EXIT_WRAPPER_NO_THROW
  ------------------
  |  |  258|  10.4k|	} catch ( ... )	{							\
  |  |  259|      0|		AnnounceCatch ( "no-throw catch-all" );	\
  |  |  260|      0|		/* Do nothing. */						\
  |  |  261|      0|	}											\
  |  |  262|  10.4k|	AnnounceExit();
  ------------------
  107|  10.4k|}
WXMPIterator_Next_1:
  136|   102k|{
  137|   102k|    XMP_ENTER_WRAPPER ( "WXMPIterator_Next_1" )
  ------------------
  |  |  241|   102k|	AnnounceEntry ( proc );									\
  |  |  242|   102k|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|   102k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|   102k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|   102k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|   102k|	try {													\
  |  |  245|   102k|		XMP_AutoMutex mutex;								\
  |  |  246|   102k|		wResult->errMessage = 0;
  ------------------
  138|       |
  139|   102k|		if ( schemaNS == 0 ) schemaNS = &voidStringPtr;
  ------------------
  |  Branch (139:8): [True: 0, False: 102k]
  ------------------
  140|   102k|		if ( nsSize == 0 ) nsSize = &voidStringLen;
  ------------------
  |  Branch (140:8): [True: 0, False: 102k]
  ------------------
  141|   102k|		if ( propPath == 0 ) propPath = &voidStringPtr;
  ------------------
  |  Branch (141:8): [True: 0, False: 102k]
  ------------------
  142|   102k|		if ( pathSize == 0 ) pathSize = &voidStringLen;
  ------------------
  |  Branch (142:8): [True: 0, False: 102k]
  ------------------
  143|   102k|		if ( propValue == 0 ) propValue = &voidStringPtr;
  ------------------
  |  Branch (143:8): [True: 0, False: 102k]
  ------------------
  144|   102k|		if ( valueSize == 0 ) valueSize = &voidStringLen;
  ------------------
  |  Branch (144:8): [True: 0, False: 102k]
  ------------------
  145|   102k|		if ( propOptions == 0 ) propOptions = &voidOptionBits;
  ------------------
  |  Branch (145:8): [True: 0, False: 102k]
  ------------------
  146|       |
  147|   102k|		XMPIterator * iter = WtoXMPIterator_Ptr ( iterRef );
  ------------------
  |  |  112|   102k|#define WtoXMPIterator_Ptr(iterRef)	(((iterRef) == 0) ? 0 : (XMPIterator *)(iterRef))
  |  |  ------------------
  |  |  |  Branch (112:38): [True: 0, False: 102k]
  |  |  ------------------
  ------------------
  148|   102k|		XMP_Bool found = iter->Next ( schemaNS, nsSize, propPath, pathSize, propValue, valueSize, propOptions );
  149|   102k|		wResult->int32Result = found;
  150|       |
  151|   102k|    XMP_EXIT_WRAPPER_KEEP_LOCK ( found )
  ------------------
  |  |  253|   102k|		if ( keep ) mutex.KeepLock();		\
  |  |  ------------------
  |  |  |  Branch (253:8): [True: 92.7k, False: 10.0k]
  |  |  ------------------
  |  |  254|   102k|	XMP_CATCH_EXCEPTIONS					\
  |  |  ------------------
  |  |  |  |  265|   102k|	} catch ( XMP_Error & xmpErr ) {								\
  |  |  |  |  266|     18|		wResult->int32Result = xmpErr.GetID(); 						\
  |  |  |  |  267|     18|		wResult->ptrResult   = (void*)"XMP";						\
  |  |  |  |  268|     18|		wResult->errMessage  = xmpErr.GetErrMsg();					\
  |  |  |  |  269|     18|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (269:8): [True: 0, False: 18]
  |  |  |  |  ------------------
  |  |  |  |  270|     18|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  271|     18|	} catch ( std::exception & stdErr ) {							\
  |  |  |  |  272|      0|		wResult->int32Result = kXMPErr_StdException; 				\
  |  |  |  |  273|      0|		wResult->errMessage  = stdErr.what(); 						\
  |  |  |  |  274|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (274:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  275|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  276|      0|	} catch ( ... ) {												\
  |  |  |  |  277|      0|		wResult->int32Result = kXMPErr_UnknownException; 			\
  |  |  |  |  278|      0|		wResult->errMessage  = "Caught unknown exception";			\
  |  |  |  |  279|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  280|      0|	}
  |  |  ------------------
  |  |  255|   102k|	AnnounceExit();
  ------------------
  152|   102k|}
WXMPUtils_UnlockIter_1:
  174|  92.7k|{
  175|  92.7k|	WXMP_Result * wResult = &void_wResult;	// ! Needed to "fool" the EnterWrapper macro.
  176|  92.7k|    XMP_ENTER_WRAPPER_NO_LOCK ( "WXMPUtils_UnlockIter_1" )
  ------------------
  |  |  235|  92.7k|	AnnounceNoLock ( proc );								\
  |  |  236|  92.7k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  92.7k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  237|  92.7k|	try {													\
  |  |  238|  92.7k|		wResult->errMessage = 0;
  ------------------
  177|       |
  178|  92.7k|		XMPIterator * iter = WtoXMPIterator_Ptr ( iterRef );
  ------------------
  |  |  112|  92.7k|#define WtoXMPIterator_Ptr(iterRef)	(((iterRef) == 0) ? 0 : (XMPIterator *)(iterRef))
  |  |  ------------------
  |  |  |  Branch (112:38): [True: 0, False: 92.7k]
  |  |  ------------------
  ------------------
  179|  92.7k|		iter->UnlockIter ( options );
  180|       |
  181|  92.7k|    XMP_EXIT_WRAPPER_NO_THROW
  ------------------
  |  |  258|  92.7k|	} catch ( ... )	{							\
  |  |  259|      0|		AnnounceCatch ( "no-throw catch-all" );	\
  |  |  260|      0|		/* Do nothing. */						\
  |  |  261|      0|	}											\
  |  |  262|  92.7k|	AnnounceExit();
  ------------------
  182|  92.7k|}

WXMPMeta_Initialize_1:
   50|      1|{
   51|      1|	XMP_ENTER_WRAPPER_NO_LOCK ( "WXMPMeta_Initialize_1" )
  ------------------
  |  |  235|      1|	AnnounceNoLock ( proc );								\
  |  |  236|      1|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  237|      1|	try {													\
  |  |  238|      1|		wResult->errMessage = 0;
  ------------------
   52|       |
   53|      1|		bool ok = XMPMeta::Initialize();
   54|      1|		wResult->int32Result = ok;
   55|       |
   56|      1|	XMP_EXIT_WRAPPER
  ------------------
  |  |  249|      1|	XMP_CATCH_EXCEPTIONS	\
  |  |  ------------------
  |  |  |  |  265|      1|	} catch ( XMP_Error & xmpErr ) {								\
  |  |  |  |  266|      0|		wResult->int32Result = xmpErr.GetID(); 						\
  |  |  |  |  267|      0|		wResult->ptrResult   = (void*)"XMP";						\
  |  |  |  |  268|      0|		wResult->errMessage  = xmpErr.GetErrMsg();					\
  |  |  |  |  269|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (269:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  270|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  271|      0|	} catch ( std::exception & stdErr ) {							\
  |  |  |  |  272|      0|		wResult->int32Result = kXMPErr_StdException; 				\
  |  |  |  |  273|      0|		wResult->errMessage  = stdErr.what(); 						\
  |  |  |  |  274|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (274:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  275|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  276|      0|	} catch ( ... ) {												\
  |  |  |  |  277|      0|		wResult->int32Result = kXMPErr_UnknownException; 			\
  |  |  |  |  278|      0|		wResult->errMessage  = "Caught unknown exception";			\
  |  |  |  |  279|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  280|      0|	}
  |  |  ------------------
  |  |  250|      1|	AnnounceExit();
  ------------------
   57|      1|}
WXMPMeta_Terminate_1:
   62|      1|{
   63|      1|	WXMP_Result * wResult = &void_wResult;	// ! Needed to "fool" the EnterWrapper macro.
   64|      1|	XMP_ENTER_WRAPPER_NO_LOCK ( "WXMPMeta_Terminate_1" )
  ------------------
  |  |  235|      1|	AnnounceNoLock ( proc );								\
  |  |  236|      1|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  237|      1|	try {													\
  |  |  238|      1|		wResult->errMessage = 0;
  ------------------
   65|       |
   66|      1|		XMPMeta::Terminate();
   67|       |
   68|      1|	XMP_EXIT_WRAPPER_NO_THROW
  ------------------
  |  |  258|      1|	} catch ( ... )	{							\
  |  |  259|      0|		AnnounceCatch ( "no-throw catch-all" );	\
  |  |  260|      0|		/* Do nothing. */						\
  |  |  261|      0|	}											\
  |  |  262|      1|	AnnounceExit();
  ------------------
   69|      0|}
WXMPMeta_CTor_1:
   77|  8.77k|{
   78|  8.77k|	XMP_ENTER_WRAPPER ( "WXMPMeta_CTor_1" )
  ------------------
  |  |  241|  8.77k|	AnnounceEntry ( proc );									\
  |  |  242|  8.77k|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|  8.77k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|  8.77k|	try {													\
  |  |  245|  8.77k|		XMP_AutoMutex mutex;								\
  |  |  246|  8.77k|		wResult->errMessage = 0;
  ------------------
   79|       |
   80|  8.77k|		XMPMeta * xmpObj = new XMPMeta();
   81|  8.77k|		++xmpObj->clientRefs;
   82|  8.77k|		XMP_Assert ( xmpObj->clientRefs == 1 );
  ------------------
  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  ------------------
   83|  8.77k|		wResult->ptrResult = XMPMetaRef ( xmpObj );
   84|       |
   85|  8.77k|	XMP_EXIT_WRAPPER
  ------------------
  |  |  249|  8.77k|	XMP_CATCH_EXCEPTIONS	\
  |  |  ------------------
  |  |  |  |  265|  8.77k|	} catch ( XMP_Error & xmpErr ) {								\
  |  |  |  |  266|      0|		wResult->int32Result = xmpErr.GetID(); 						\
  |  |  |  |  267|      0|		wResult->ptrResult   = (void*)"XMP";						\
  |  |  |  |  268|      0|		wResult->errMessage  = xmpErr.GetErrMsg();					\
  |  |  |  |  269|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (269:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  270|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  271|      0|	} catch ( std::exception & stdErr ) {							\
  |  |  |  |  272|      0|		wResult->int32Result = kXMPErr_StdException; 				\
  |  |  |  |  273|      0|		wResult->errMessage  = stdErr.what(); 						\
  |  |  |  |  274|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (274:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  275|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  276|      0|	} catch ( ... ) {												\
  |  |  |  |  277|      0|		wResult->int32Result = kXMPErr_UnknownException; 			\
  |  |  |  |  278|      0|		wResult->errMessage  = "Caught unknown exception";			\
  |  |  |  |  279|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  280|      0|	}
  |  |  ------------------
  |  |  250|  8.77k|	AnnounceExit();
  ------------------
   86|  8.77k|}
WXMPMeta_DecrementRefCount_1:
  108|  8.77k|{
  109|  8.77k|	WXMP_Result * wResult = &void_wResult;	// ! Needed to "fool" the EnterWrapper macro.
  110|  8.77k|	XMP_ENTER_WRAPPER ( "WXMPMeta_DecrementRefCount_1" )
  ------------------
  |  |  241|  8.77k|	AnnounceEntry ( proc );									\
  |  |  242|  8.77k|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|  8.77k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|  8.77k|	try {													\
  |  |  245|  8.77k|		XMP_AutoMutex mutex;								\
  |  |  246|  8.77k|		wResult->errMessage = 0;
  ------------------
  111|       |
  112|  8.77k|		XMPMeta * thiz = (XMPMeta*)xmpRef;
  113|       |		
  114|  8.77k|		XMP_Assert ( thiz->clientRefs > 0 );
  ------------------
  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  115|  8.77k|		--thiz->clientRefs;
  116|  8.77k|		if ( thiz->clientRefs <= 0 ) delete ( thiz );
  ------------------
  |  Branch (116:8): [True: 8.77k, False: 0]
  ------------------
  117|       |
  118|  8.77k|	XMP_EXIT_WRAPPER_NO_THROW
  ------------------
  |  |  258|  8.77k|	} catch ( ... )	{							\
  |  |  259|      0|		AnnounceCatch ( "no-throw catch-all" );	\
  |  |  260|      0|		/* Do nothing. */						\
  |  |  261|      0|	}											\
  |  |  262|  8.77k|	AnnounceExit();
  ------------------
  119|  8.77k|}
WXMPMeta_Unlock_1:
  207|  2.80k|{
  208|  2.80k|	WXMP_Result * wResult = &void_wResult;	// ! Needed to "fool" the EnterWrapper macro.
  209|  2.80k|	XMP_ENTER_WRAPPER_NO_LOCK ( "WXMPMeta_Unlock_1" )
  ------------------
  |  |  235|  2.80k|	AnnounceNoLock ( proc );								\
  |  |  236|  2.80k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  2.80k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  237|  2.80k|	try {													\
  |  |  238|  2.80k|		wResult->errMessage = 0;
  ------------------
  210|       |
  211|  2.80k|		XMPMeta::Unlock ( options );
  212|       |
  213|  2.80k|	XMP_EXIT_WRAPPER_NO_THROW
  ------------------
  |  |  258|  2.80k|	} catch ( ... )	{							\
  |  |  259|      0|		AnnounceCatch ( "no-throw catch-all" );	\
  |  |  260|      0|		/* Do nothing. */						\
  |  |  261|      0|	}											\
  |  |  262|  2.80k|	AnnounceExit();
  ------------------
  214|  2.80k|}
WXMPMeta_RegisterNamespace_1:
  222|     22|{
  223|     22|	XMP_ENTER_WRAPPER ( "WXMPMeta_RegisterNamespace_1" )
  ------------------
  |  |  241|     22|	AnnounceEntry ( proc );									\
  |  |  242|     22|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|     22|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|     22|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|     22|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|     22|	try {													\
  |  |  245|     22|		XMP_AutoMutex mutex;								\
  |  |  246|     22|		wResult->errMessage = 0;
  ------------------
  224|       |
  225|     22|		if ( (namespaceURI == 0) || (*namespaceURI == 0) ) XMP_Throw ( "Empty namespace URI", kXMPErr_BadSchema );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (225:8): [True: 0, False: 22]
  |  Branch (225:31): [True: 0, False: 22]
  ------------------
  226|     22|		if ( (prefix == 0) || (*prefix == 0) ) XMP_Throw ( "Empty prefix", kXMPErr_BadSchema );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (226:8): [True: 0, False: 22]
  |  Branch (226:25): [True: 0, False: 22]
  ------------------
  227|       |
  228|     22|		XMPMeta::RegisterNamespace ( namespaceURI, prefix );
  229|       |
  230|     22|	XMP_EXIT_WRAPPER
  ------------------
  |  |  249|     22|	XMP_CATCH_EXCEPTIONS	\
  |  |  ------------------
  |  |  |  |  265|     22|	} catch ( XMP_Error & xmpErr ) {								\
  |  |  |  |  266|      0|		wResult->int32Result = xmpErr.GetID(); 						\
  |  |  |  |  267|      0|		wResult->ptrResult   = (void*)"XMP";						\
  |  |  |  |  268|      0|		wResult->errMessage  = xmpErr.GetErrMsg();					\
  |  |  |  |  269|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (269:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  270|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  271|      0|	} catch ( std::exception & stdErr ) {							\
  |  |  |  |  272|      0|		wResult->int32Result = kXMPErr_StdException; 				\
  |  |  |  |  273|      0|		wResult->errMessage  = stdErr.what(); 						\
  |  |  |  |  274|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (274:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  275|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  276|      0|	} catch ( ... ) {												\
  |  |  |  |  277|      0|		wResult->int32Result = kXMPErr_UnknownException; 			\
  |  |  |  |  278|      0|		wResult->errMessage  = "Caught unknown exception";			\
  |  |  |  |  279|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  280|      0|	}
  |  |  ------------------
  |  |  250|     22|	AnnounceExit();
  ------------------
  231|     22|}
WXMPMeta_GetNamespacePrefix_1:
  240|  2.80k|{
  241|  2.80k|	XMP_ENTER_WRAPPER ( "WXMPMeta_GetNamespacePrefix_1" )
  ------------------
  |  |  241|  2.80k|	AnnounceEntry ( proc );									\
  |  |  242|  2.80k|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|  2.80k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|  2.80k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  2.80k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|  2.80k|	try {													\
  |  |  245|  2.80k|		XMP_AutoMutex mutex;								\
  |  |  246|  2.80k|		wResult->errMessage = 0;
  ------------------
  242|       |
  243|  2.80k|		if ( (namespaceURI == 0) || (*namespaceURI == 0) ) XMP_Throw ( "Empty namespace URI", kXMPErr_BadSchema );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (243:8): [True: 0, False: 2.80k]
  |  Branch (243:31): [True: 0, False: 2.80k]
  ------------------
  244|       |
  245|  2.80k|		if ( namespacePrefix == 0 ) namespacePrefix = &voidStringPtr;
  ------------------
  |  Branch (245:8): [True: 0, False: 2.80k]
  ------------------
  246|  2.80k|		if ( prefixSize == 0 ) prefixSize = &voidStringLen;
  ------------------
  |  Branch (246:8): [True: 0, False: 2.80k]
  ------------------
  247|       |
  248|  2.80k|		bool found = XMPMeta::GetNamespacePrefix ( namespaceURI, namespacePrefix, prefixSize );
  249|  2.80k|		wResult->int32Result = found;
  250|       |		
  251|  2.80k|	XMP_EXIT_WRAPPER_KEEP_LOCK ( found )
  ------------------
  |  |  253|  2.80k|		if ( keep ) mutex.KeepLock();		\
  |  |  ------------------
  |  |  |  Branch (253:8): [True: 2.80k, False: 0]
  |  |  ------------------
  |  |  254|  2.80k|	XMP_CATCH_EXCEPTIONS					\
  |  |  ------------------
  |  |  |  |  265|  2.80k|	} catch ( XMP_Error & xmpErr ) {								\
  |  |  |  |  266|      0|		wResult->int32Result = xmpErr.GetID(); 						\
  |  |  |  |  267|      0|		wResult->ptrResult   = (void*)"XMP";						\
  |  |  |  |  268|      0|		wResult->errMessage  = xmpErr.GetErrMsg();					\
  |  |  |  |  269|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (269:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  270|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  271|      0|	} catch ( std::exception & stdErr ) {							\
  |  |  |  |  272|      0|		wResult->int32Result = kXMPErr_StdException; 				\
  |  |  |  |  273|      0|		wResult->errMessage  = stdErr.what(); 						\
  |  |  |  |  274|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (274:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  275|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  276|      0|	} catch ( ... ) {												\
  |  |  |  |  277|      0|		wResult->int32Result = kXMPErr_UnknownException; 			\
  |  |  |  |  278|      0|		wResult->errMessage  = "Caught unknown exception";			\
  |  |  |  |  279|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  280|      0|	}
  |  |  ------------------
  |  |  255|  2.80k|	AnnounceExit();
  ------------------
  252|  2.80k|}
WXMPMeta_CountArrayItems_1:
 1168|  4.11k|{
 1169|  4.11k|	XMP_ENTER_WRAPPER ( "WXMPMeta_CountArrayItems_1" )
  ------------------
  |  |  241|  4.11k|	AnnounceEntry ( proc );									\
  |  |  242|  4.11k|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|  4.11k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|  4.11k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  4.11k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|  4.11k|	try {													\
  |  |  245|  4.11k|		XMP_AutoMutex mutex;								\
  |  |  246|  4.11k|		wResult->errMessage = 0;
  ------------------
 1170|       |		
 1171|  4.11k|		if ( (schemaNS == 0) || (*schemaNS == 0) ) XMP_Throw ( "Empty schema namespace URI", kXMPErr_BadSchema );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1171:8): [True: 0, False: 4.11k]
  |  Branch (1171:27): [True: 0, False: 4.11k]
  ------------------
 1172|  4.11k|		if ( (arrayName == 0) || (*arrayName == 0) ) XMP_Throw ( "Empty array name", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1172:8): [True: 0, False: 4.11k]
  |  Branch (1172:28): [True: 0, False: 4.11k]
  ------------------
 1173|       |
 1174|  4.11k|		const XMPMeta & meta = WtoXMPMeta_Ref ( xmpRef );
  ------------------
  |  |  108|  4.11k|#define WtoXMPMeta_Ref(xmpRef)	*((const XMPMeta *)(xmpRef))
  ------------------
 1175|  4.11k|		XMP_Index count = meta.CountArrayItems ( schemaNS, arrayName );
 1176|  4.11k|		wResult->int32Result = count;
 1177|       |		
 1178|  4.11k|	XMP_EXIT_WRAPPER
  ------------------
  |  |  249|  4.11k|	XMP_CATCH_EXCEPTIONS	\
  |  |  ------------------
  |  |  |  |  265|  4.11k|	} catch ( XMP_Error & xmpErr ) {								\
  |  |  |  |  266|      0|		wResult->int32Result = xmpErr.GetID(); 						\
  |  |  |  |  267|      0|		wResult->ptrResult   = (void*)"XMP";						\
  |  |  |  |  268|      0|		wResult->errMessage  = xmpErr.GetErrMsg();					\
  |  |  |  |  269|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (269:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  270|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  271|      0|	} catch ( std::exception & stdErr ) {							\
  |  |  |  |  272|      0|		wResult->int32Result = kXMPErr_StdException; 				\
  |  |  |  |  273|      0|		wResult->errMessage  = stdErr.what(); 						\
  |  |  |  |  274|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (274:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  275|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  276|      0|	} catch ( ... ) {												\
  |  |  |  |  277|      0|		wResult->int32Result = kXMPErr_UnknownException; 			\
  |  |  |  |  278|      0|		wResult->errMessage  = "Caught unknown exception";			\
  |  |  |  |  279|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  280|      0|	}
  |  |  ------------------
  |  |  250|  4.11k|	AnnounceExit();
  ------------------
 1179|  4.11k|}
WXMPMeta_ParseFromBuffer_1:
 1270|  8.77k|{
 1271|  8.77k|	XMP_ENTER_WRAPPER ( "WXMPMeta_ParseFromBuffer_1" )
  ------------------
  |  |  241|  8.77k|	AnnounceEntry ( proc );									\
  |  |  242|  8.77k|	XMP_Assert ( sXMP_InitCount > 0 );	                    \
  |  |  ------------------
  |  |  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  243|  8.77k|	XMP_Assert ( (0 <= sLockCount) && (sLockCount <= 1) );	\
  |  |  ------------------
  |  |  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  |  |  ------------------
  |  |  244|  8.77k|	try {													\
  |  |  245|  8.77k|		XMP_AutoMutex mutex;								\
  |  |  246|  8.77k|		wResult->errMessage = 0;
  ------------------
 1272|       |
 1273|  8.77k|		XMPMeta * meta = WtoXMPMeta_Ptr ( xmpRef );
  ------------------
  |  |  109|  8.77k|#define WtoXMPMeta_Ptr(xmpRef)	(((xmpRef) == 0) ? 0 : (XMPMeta *)(xmpRef))
  |  |  ------------------
  |  |  |  Branch (109:33): [True: 0, False: 8.77k]
  |  |  ------------------
  ------------------
 1274|  8.77k|		meta->ParseFromBuffer ( buffer, bufferSize, options );
 1275|       |		
 1276|  8.77k|	XMP_EXIT_WRAPPER
  ------------------
  |  |  249|  8.77k|	XMP_CATCH_EXCEPTIONS	\
  |  |  ------------------
  |  |  |  |  265|  8.77k|	} catch ( XMP_Error & xmpErr ) {								\
  |  |  |  |  266|  1.66k|		wResult->int32Result = xmpErr.GetID(); 						\
  |  |  |  |  267|  1.66k|		wResult->ptrResult   = (void*)"XMP";						\
  |  |  |  |  268|  1.66k|		wResult->errMessage  = xmpErr.GetErrMsg();					\
  |  |  |  |  269|  1.66k|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (269:8): [True: 0, False: 1.66k]
  |  |  |  |  ------------------
  |  |  |  |  270|  1.66k|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  271|  1.66k|	} catch ( std::exception & stdErr ) {							\
  |  |  |  |  272|      0|		wResult->int32Result = kXMPErr_StdException; 				\
  |  |  |  |  273|      0|		wResult->errMessage  = stdErr.what(); 						\
  |  |  |  |  274|      0|		if ( wResult->errMessage == 0 ) wResult->errMessage = "";	\
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (274:8): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  275|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  276|      0|	} catch ( ... ) {												\
  |  |  |  |  277|      0|		wResult->int32Result = kXMPErr_UnknownException; 			\
  |  |  |  |  278|      0|		wResult->errMessage  = "Caught unknown exception";			\
  |  |  |  |  279|      0|		AnnounceCatch ( wResult->errMessage );						\
  |  |  |  |  280|      0|	}
  |  |  ------------------
  |  |  250|  8.77k|	AnnounceExit();
  ------------------
 1277|  8.77k|}

_ZN8XML_NodeC2EPS_PKch:
   90|   314k|            : kind(_kind), name(_name), nsPrefixLen(0), parent(_parent) {};
_ZN8XML_NodeD2Ev:
   95|   314k|	virtual ~XML_Node() { RemoveAttrs(); RemoveContent(); };
_ZN16XMLParserAdapterC2Ev:
  112|  8.77k|		: tree(0,"",kRootNode), rootNode(0), rootCount(0), charEncoding(XMP_OptionBits(-1)), pendingCount(0)
  113|  8.77k|	{
  114|       |		#if XMP_DebugBuild
  115|       |			parseLog = 0;
  116|       |		#endif
  117|  8.77k|	};
_ZN16XMLParserAdapterD2Ev:
  119|  8.77k|	virtual ~XMLParserAdapter() {};

_ZNK8XML_Node16IsWhitespaceNodeEv:
   39|   144k|{
   40|   144k|	if ( this->kind != kCDataNode ) return false;
  ------------------
  |  Branch (40:7): [True: 35.5k, False: 109k]
  ------------------
   41|       |
   42|   363k|	for ( size_t i = 0; i < this->value.size(); ++i ) {
  ------------------
  |  Branch (42:22): [True: 255k, False: 108k]
  ------------------
   43|   255k|		unsigned char ch = this->value[i];
   44|   255k|		if ( IsWhitespaceChar ( ch ) ) continue;
  ------------------
  |  |   45|   255k|#define IsWhitespaceChar(ch)	( ((ch) == ' ') || ((ch) == 0x09) || ((ch) == 0x0A) || ((ch) == 0x0D) )
  |  |  ------------------
  |  |  |  Branch (45:32): [True: 199k, False: 55.6k]
  |  |  |  Branch (45:49): [True: 250, False: 55.3k]
  |  |  |  Branch (45:67): [True: 54.8k, False: 538]
  |  |  |  Branch (45:85): [True: 0, False: 538]
  |  |  ------------------
  ------------------
   45|       |		// *** Add checks for other whitespace characters.
   46|    538|		return false;	// All the checks failed, this isn't whitespace.
   47|   255k|	}
   48|       |
   49|   108k|	return true;
   50|       |
   51|   109k|}	// XML_Node::IsWhitespaceNode
_ZN8XML_Node11RemoveAttrsEv:
  427|   314k|{
  428|       |
  429|   381k|	for ( size_t i = 0, vLim = this->attrs.size(); i < vLim; ++i ) delete this->attrs[i];
  ------------------
  |  Branch (429:49): [True: 67.3k, False: 314k]
  ------------------
  430|   314k|	this->attrs.clear();
  431|       |
  432|   314k|}	// XML_Node::RemoveAttrs
_ZN8XML_Node13RemoveContentEv:
  439|   314k|{
  440|       |
  441|   551k|	for ( size_t i = 0, vLim = this->content.size(); i < vLim; ++i ) delete this->content[i];
  ------------------
  |  Branch (441:51): [True: 237k, False: 314k]
  ------------------
  442|   314k|	this->content.clear();
  443|       |
  444|   314k|}	// XML_Node::RemoveContent

_Z13XMP_InitMutexP15pthread_mutex_t:
  114|      1|	bool XMP_InitMutex ( XMP_Mutex * mutex ) {
  115|      1|		int err = pthread_mutex_init ( mutex, 0 );
  116|      1|		return (err == 0 );
  117|      1|	}
_Z13XMP_TermMutexR15pthread_mutex_t:
  119|      1|	void XMP_TermMutex ( XMP_Mutex & mutex ) {
  120|      1|		(void) pthread_mutex_destroy ( &mutex );
  121|      1|	}
_Z23XMP_EnterCriticalRegionR15pthread_mutex_t:
  123|   156k|	void XMP_EnterCriticalRegion ( XMP_Mutex & mutex ) {
  124|   156k|		int err = pthread_mutex_lock ( &mutex );
  125|   156k|		if ( err != 0 ) XMP_Throw ( "XMP_EnterCriticalRegion - pthread_mutex_lock failure", kXMPErr_ExternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (125:8): [True: 0, False: 156k]
  ------------------
  126|   156k|	}
_Z22XMP_ExitCriticalRegionR15pthread_mutex_t:
  128|   156k|	void XMP_ExitCriticalRegion ( XMP_Mutex & mutex ) {
  129|   156k|		int err = pthread_mutex_unlock ( &mutex );
  130|   156k|		if ( err != 0 ) XMP_Throw ( "XMP_ExitCriticalRegion - pthread_mutex_unlock failure", kXMPErr_ExternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (130:8): [True: 0, False: 156k]
  ------------------
  131|   156k|	}
_Z16VerifySetOptionsjPKc:
  563|    201|{
  564|       |
  565|    201|	if ( options & kXMP_PropArrayIsAltText )   options |= kXMP_PropArrayIsAlternate;
  ------------------
  |  Branch (565:7): [True: 104, False: 97]
  ------------------
  566|    201|	if ( options & kXMP_PropArrayIsAlternate ) options |= kXMP_PropArrayIsOrdered;
  ------------------
  |  Branch (566:7): [True: 104, False: 97]
  ------------------
  567|    201|	if ( options & kXMP_PropArrayIsOrdered )   options |= kXMP_PropValueIsArray;
  ------------------
  |  Branch (567:7): [True: 134, False: 67]
  ------------------
  568|       |	
  569|    201|	if ( options & ~kXMP_AllSetOptionsMask ) {
  ------------------
  |  Branch (569:7): [True: 0, False: 201]
  ------------------
  570|      0|		XMP_Throw ( "Unrecognized option flags", kXMPErr_BadOptions );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  571|      0|	}
  572|       |	
  573|    201|	if ( (options & kXMP_PropValueIsStruct) && (options & kXMP_PropValueIsArray) ) {
  ------------------
  |  Branch (573:7): [True: 0, False: 201]
  |  Branch (573:45): [True: 0, False: 0]
  ------------------
  574|      0|		XMP_Throw ( "IsStruct and IsArray options are mutually exclusive", kXMPErr_BadOptions );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  575|      0|	}
  576|       |	
  577|    201|	if ( (options & kXMP_PropValueOptionsMask) && (options & kXMP_PropCompositeMask) ) {
  ------------------
  |  Branch (577:7): [True: 0, False: 201]
  |  Branch (577:48): [True: 0, False: 0]
  ------------------
  578|      0|		XMP_Throw ( "Structs and arrays can't have \"value\" options", kXMPErr_BadOptions );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  579|      0|	}
  580|       |	
  581|    201|	if ( (propValue != 0) && (options & kXMP_PropCompositeMask) ) {
  ------------------
  |  Branch (581:7): [True: 0, False: 201]
  |  Branch (581:27): [True: 0, False: 0]
  ------------------
  582|      0|		XMP_Throw ( "Structs and arrays can't have string values", kXMPErr_BadOptions );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  583|      0|	}
  584|       |
  585|    201|	return options;
  586|       |
  587|    201|}	// VerifySetOptions
_Z11ExpandXPathPKcS0_PNSt3__16vectorI13XPathStepInfoNS1_9allocatorIS3_EEEE:
  662|  91.6k|{
  663|  91.6k|	XMP_Assert ( (schemaNS != 0) && (propPath != 0) && (*propPath != 0) && (expandedXPath != 0) );
  ------------------
  |  |  142|  91.6k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  664|       |	
  665|  91.6k|	XMP_StringPtr	stepBegin, stepEnd;
  666|  91.6k|	XMP_StringPtr	qualName, nameEnd;
  667|  91.6k|	XMP_VarString	currStep;
  668|       |		
  669|  91.6k|	qualName = nameEnd = NULL;
  670|  91.6k|	size_t resCount = 2;	// Guess at the number of steps. At least 2, plus 1 for each '/' or '['.
  671|  13.5M|	for ( stepEnd = propPath; *stepEnd != 0; ++stepEnd ) {
  ------------------
  |  Branch (671:28): [True: 13.5M, False: 91.6k]
  ------------------
  672|  13.5M|		if ( (*stepEnd == '/') || (*stepEnd == '[') ) ++resCount;
  ------------------
  |  Branch (672:8): [True: 31.1k, False: 13.4M]
  |  Branch (672:29): [True: 59.8k, False: 13.4M]
  ------------------
  673|  13.5M|	}
  674|       |	
  675|  91.6k|	expandedXPath->clear();
  676|  91.6k|	expandedXPath->reserve ( resCount );
  677|       |	
  678|       |	// -------------------------------------------------------------------------------------------
  679|       |	// Pull out the first component and do some special processing on it: add the schema namespace
  680|       |	// prefix and see if it is an alias. The start must be a qualName.
  681|       |	
  682|  91.6k|	stepBegin = propPath;
  683|  91.6k|	stepEnd = stepBegin;
  684|  6.95M|	while ( (*stepEnd != 0) && (*stepEnd != '/') && (*stepEnd != '[') && (*stepEnd != '*') ) ++stepEnd;
  ------------------
  |  Branch (684:10): [True: 6.92M, False: 30.7k]
  |  Branch (684:29): [True: 6.92M, False: 1.09k]
  |  Branch (684:50): [True: 6.86M, False: 59.8k]
  |  Branch (684:71): [True: 6.86M, False: 0]
  ------------------
  685|  91.6k|	if ( stepEnd == stepBegin ) XMP_Throw ( "Empty initial XPath step", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (685:7): [True: 0, False: 91.6k]
  ------------------
  686|  91.6k|	currStep.assign ( stepBegin, (stepEnd - stepBegin) );
  687|       |	
  688|  91.6k|	VerifyXPathRoot ( schemaNS, currStep.c_str(), expandedXPath );
  689|       |
  690|  91.6k|	XMP_OptionBits stepFlags = kXMP_StructFieldStep;	
  691|  91.6k|	if ( sRegisteredAliasMap->find ( (*expandedXPath)[kRootPropStep].step ) != sRegisteredAliasMap->end() ) {
  ------------------
  |  Branch (691:7): [True: 0, False: 91.6k]
  ------------------
  692|      0|		stepFlags |= kXMP_StepIsAlias;
  693|      0|	}
  694|  91.6k|	(*expandedXPath)[kRootPropStep].options |= stepFlags;
  695|       |		
  696|       |	// -----------------------------------------------------
  697|       |	// Now continue to process the rest of the XPath string.
  698|       |
  699|   182k|	while ( *stepEnd != 0 ) {
  ------------------
  |  Branch (699:10): [True: 90.9k, False: 91.6k]
  ------------------
  700|       |
  701|  90.9k|		stepBegin = stepEnd;
  702|  90.9k|		if ( *stepBegin == '/' ) ++stepBegin;
  ------------------
  |  Branch (702:8): [True: 31.1k, False: 59.8k]
  ------------------
  703|  90.9k|		if ( *stepBegin == '*' ) {
  ------------------
  |  Branch (703:8): [True: 0, False: 90.9k]
  ------------------
  704|      0|			++stepBegin;
  705|      0|			if ( *stepBegin != '[' ) XMP_Throw ( "Missing '[' after '*'", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (705:9): [True: 0, False: 0]
  ------------------
  706|      0|		}
  707|  90.9k|		stepEnd = stepBegin;
  708|       |
  709|  90.9k|		if ( *stepBegin != '[' ) {
  ------------------
  |  Branch (709:8): [True: 31.1k, False: 59.8k]
  ------------------
  710|       |		
  711|       |			// A struct field or qualifier.
  712|  31.1k|			qualName = stepBegin;
  713|  6.42M|			while ( (*stepEnd != 0) && (*stepEnd != '/') && (*stepEnd != '[') && (*stepEnd != '*') ) ++stepEnd;
  ------------------
  |  Branch (713:12): [True: 6.39M, False: 31.1k]
  |  Branch (713:31): [True: 6.39M, False: 0]
  |  Branch (713:52): [True: 6.39M, False: 0]
  |  Branch (713:73): [True: 6.39M, False: 0]
  ------------------
  714|  31.1k|			nameEnd = stepEnd;
  715|  31.1k|			stepFlags = kXMP_StructFieldStep;	// ! Touch up later, also changing '@' to '?'.
  716|       |			
  717|  59.8k|		} else {
  718|       |		
  719|       |			// One of the array forms.
  720|       |		
  721|  59.8k|			++stepEnd;	// Look at the character after the leading '['.
  722|       |			
  723|  59.8k|			if ( ('0' <= *stepEnd) && (*stepEnd <= '9') ) {
  ------------------
  |  Branch (723:9): [True: 59.8k, False: 0]
  |  Branch (723:30): [True: 59.8k, False: 0]
  ------------------
  724|       |
  725|       |				// A numeric (decimal integer) array index.
  726|   155k|				while ( (*stepEnd != 0) && ('0' <= *stepEnd) && (*stepEnd <= '9') ) ++stepEnd;
  ------------------
  |  Branch (726:13): [True: 155k, False: 0]
  |  Branch (726:32): [True: 155k, False: 0]
  |  Branch (726:53): [True: 95.5k, False: 59.8k]
  ------------------
  727|  59.8k|				if ( *stepEnd != ']' ) XMP_Throw ( "Missing ']' for integer array index", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (727:10): [True: 0, False: 59.8k]
  ------------------
  728|  59.8k|				stepFlags = kXMP_ArrayIndexStep;
  729|       |
  730|  59.8k|			} else {
  731|       |
  732|       |				// Could be "[last()]" or one of the selector forms. Find the ']' or '='.
  733|       |				
  734|      0|				while ( (*stepEnd != 0) && (*stepEnd != ']') && (*stepEnd != '=') ) ++stepEnd;
  ------------------
  |  Branch (734:13): [True: 0, False: 0]
  |  Branch (734:32): [True: 0, False: 0]
  |  Branch (734:53): [True: 0, False: 0]
  ------------------
  735|      0|				if ( *stepEnd == 0 ) XMP_Throw ( "Missing ']' or '=' for array index", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (735:10): [True: 0, False: 0]
  ------------------
  736|       |
  737|      0|				if ( *stepEnd == ']' ) {
  ------------------
  |  Branch (737:10): [True: 0, False: 0]
  ------------------
  738|       |
  739|      0|					if ( strncmp ( "[last()", stepBegin, (stepEnd - stepBegin) ) != 0 ) {
  ------------------
  |  Branch (739:11): [True: 0, False: 0]
  ------------------
  740|      0|						XMP_Throw ( "Invalid non-numeric array index", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  741|      0|					}
  742|      0|					stepFlags = kXMP_ArrayLastStep;
  743|       |
  744|      0|				} else {
  745|       |
  746|      0|					qualName = stepBegin+1;
  747|      0|					nameEnd = stepEnd;
  748|      0|					++stepEnd;	// Absorb the '=', remember the quote.
  749|      0|					const char quote = *stepEnd;
  750|      0|					if ( (quote != '\'') && (quote != '"') ) {
  ------------------
  |  Branch (750:11): [True: 0, False: 0]
  |  Branch (750:30): [True: 0, False: 0]
  ------------------
  751|      0|						XMP_Throw ( "Invalid quote in array selector", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  752|      0|					}
  753|       |
  754|      0|					++stepEnd;	// Absorb the leading quote.
  755|      0|					while ( *stepEnd != 0 ) {
  ------------------
  |  Branch (755:14): [True: 0, False: 0]
  ------------------
  756|      0|						if ( *stepEnd == quote ) {
  ------------------
  |  Branch (756:12): [True: 0, False: 0]
  ------------------
  757|      0|							if ( *(stepEnd+1) != quote ) break;
  ------------------
  |  Branch (757:13): [True: 0, False: 0]
  ------------------
  758|      0|							++stepEnd;
  759|      0|						}
  760|      0|						++stepEnd;
  761|      0|					}
  762|      0|					if ( *stepEnd == 0 ) {
  ------------------
  |  Branch (762:11): [True: 0, False: 0]
  ------------------
  763|      0|						XMP_Throw ( "No terminating quote for array selector", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  764|      0|					}
  765|      0|					++stepEnd;	// Absorb the trailing quote.
  766|       |					
  767|      0|					stepFlags = kXMP_FieldSelectorStep;	// ! Touch up later, also changing '@' to '?'.
  768|       |
  769|      0|				}
  770|       |
  771|      0|			}
  772|       |
  773|  59.8k|			if ( *stepEnd != ']' ) XMP_Throw ( "Missing ']' for array index", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (773:9): [True: 0, False: 59.8k]
  ------------------
  774|  59.8k|			++stepEnd;
  775|       |			
  776|  59.8k|		}
  777|       |
  778|  90.9k|		if ( stepEnd == stepBegin ) XMP_Throw ( "Empty XPath step", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (778:8): [True: 0, False: 90.9k]
  ------------------
  779|  90.9k|		currStep.assign ( stepBegin, (stepEnd - stepBegin) );
  780|       |
  781|  90.9k|		if ( GetStepKind ( stepFlags ) == kXMP_StructFieldStep ) {
  ------------------
  |  |  408|  90.9k|#define GetStepKind(f)	((f) & kXMP_StepKindMask)
  ------------------
  |  Branch (781:8): [True: 31.1k, False: 59.8k]
  ------------------
  782|       |
  783|  31.1k|			if ( currStep[0] == '@' ) {
  ------------------
  |  Branch (783:9): [True: 0, False: 31.1k]
  ------------------
  784|      0|				currStep[0] = '?';
  785|      0|				if ( currStep != "?xml:lang" ) XMP_Throw ( "Only xml:lang allowed with '@'", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (785:10): [True: 0, False: 0]
  ------------------
  786|      0|			}
  787|  31.1k|			if ( currStep[0] == '?' ) {
  ------------------
  |  Branch (787:9): [True: 8.86k, False: 22.2k]
  ------------------
  788|  8.86k|				++qualName;
  789|  8.86k|				stepFlags = kXMP_QualifierStep;
  790|  8.86k|			}
  791|  31.1k|			VerifyQualName ( qualName, nameEnd );
  792|       |
  793|  59.8k|		} else if ( GetStepKind ( stepFlags ) == kXMP_FieldSelectorStep ) {
  ------------------
  |  |  408|  59.8k|#define GetStepKind(f)	((f) & kXMP_StepKindMask)
  ------------------
  |  Branch (793:15): [True: 0, False: 59.8k]
  ------------------
  794|       |
  795|      0|			if ( currStep[1] == '@' ) {
  ------------------
  |  Branch (795:9): [True: 0, False: 0]
  ------------------
  796|      0|				currStep[1] = '?';
  797|      0|				if ( strncmp ( currStep.c_str(), "[?xml:lang=", 11 ) != 0 ) {
  ------------------
  |  Branch (797:10): [True: 0, False: 0]
  ------------------
  798|      0|					XMP_Throw ( "Only xml:lang allowed with '@'", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  799|      0|				}
  800|      0|			}
  801|      0|			if ( currStep[1] == '?' ) {
  ------------------
  |  Branch (801:9): [True: 0, False: 0]
  ------------------
  802|      0|				++qualName;
  803|      0|				stepFlags = kXMP_QualSelectorStep;
  804|      0|			}
  805|      0|			VerifyQualName ( qualName, nameEnd );
  806|       |
  807|      0|		}
  808|       |
  809|  90.9k|		expandedXPath->push_back ( XPathStepInfo ( currStep, stepFlags ) );
  810|       |
  811|  90.9k|	}
  812|       |
  813|  91.6k|}	// ExpandXPath
_Z14FindSchemaNodeP8XMP_NodePKcbPNSt3__111__wrap_iterIPS0_EE:
  828|   161k|{
  829|   161k|	XMP_Node * schemaNode = 0;
  830|       |	
  831|   161k|	XMP_Assert ( xmpTree->parent == 0 );
  ------------------
  |  |  142|   161k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  832|       |	
  833|   466k|	for ( size_t schemaNum = 0, schemaLim = xmpTree->children.size(); schemaNum != schemaLim; ++schemaNum ) {
  ------------------
  |  Branch (833:68): [True: 421k, False: 45.2k]
  ------------------
  834|   421k|		XMP_Node * currSchema = xmpTree->children[schemaNum];
  835|   421k|		XMP_Assert ( currSchema->parent == xmpTree );
  ------------------
  |  |  142|   421k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  836|   421k|		if ( currSchema->name == nsURI ) {
  ------------------
  |  Branch (836:8): [True: 115k, False: 305k]
  ------------------
  837|   115k|			schemaNode = currSchema;
  838|   115k|			if ( ptrPos != 0 ) *ptrPos = xmpTree->children.begin() + schemaNum;
  ------------------
  |  Branch (838:9): [True: 91.3k, False: 24.5k]
  ------------------
  839|   115k|			break;
  840|   115k|		}
  841|   421k|	}
  842|       |	
  843|   161k|	if ( (schemaNode == 0) && createNodes ) {
  ------------------
  |  Branch (843:7): [True: 45.2k, False: 115k]
  |  Branch (843:28): [True: 10.3k, False: 34.9k]
  ------------------
  844|       |
  845|  10.3k|		schemaNode = new XMP_Node ( xmpTree, nsURI, (kXMP_SchemaNode | kXMP_NewImplicitNode) );
  ------------------
  |  |  410|  10.3k|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  846|  10.3k|		XMP_StringPtr prefixPtr;
  847|  10.3k|		XMP_StringLen prefixLen;
  848|  10.3k|        bool found = XMPMeta::GetNamespacePrefix ( nsURI, &prefixPtr, &prefixLen );	// *** Use map directly?
  849|  10.3k|		XMP_Assert ( found );
  ------------------
  |  |  142|  10.3k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  850|  10.3k|		UNUSED(found);
  851|       |
  852|  10.3k|		schemaNode->value.assign ( prefixPtr, prefixLen );
  853|  10.3k|		xmpTree->children.push_back ( schemaNode );
  854|  10.3k|		if ( ptrPos != 0 ) *ptrPos = xmpTree->children.end() - 1;
  ------------------
  |  Branch (854:8): [True: 240, False: 10.0k]
  ------------------
  855|       |
  856|       |		#if 0	// *** XMP_DebugBuild
  857|       |			schemaNode->_valuePtr = schemaNode->value.c_str();
  858|       |		#endif
  859|       |
  860|  10.3k|	}
  861|       |	
  862|   161k|	XMP_Assert ( (ptrPos == 0) || (schemaNode == 0) || (schemaNode == **ptrPos) );
  ------------------
  |  |  142|   161k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  863|   161k|	XMP_Assert ( (schemaNode != 0) || (! createNodes) );
  ------------------
  |  |  142|   161k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  864|   161k|	return schemaNode;
  865|       |	
  866|   161k|}	// FindSchemaNode
_Z13FindChildNodeP8XMP_NodePKcbPNSt3__111__wrap_iterIPS0_EE:
  881|   169k|{
  882|   169k|	XMP_Node * childNode = 0;
  883|       |
  884|   169k|	if ( ! (parent->options & (kXMP_SchemaNode | kXMP_PropValueIsStruct)) ) {
  ------------------
  |  Branch (884:7): [True: 1, False: 169k]
  ------------------
  885|      1|		if ( ! (parent->options & kXMP_NewImplicitNode) ) {
  ------------------
  |  |  410|      1|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  |  Branch (885:8): [True: 1, False: 0]
  ------------------
  886|      1|			XMP_Throw ( "Named children only allowed for schemas and structs", kXMPErr_BadXPath );
  ------------------
  |  |  199|      1|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  887|      0|		}
  888|      0|		if ( parent->options & kXMP_PropValueIsArray ) {
  ------------------
  |  Branch (888:8): [True: 0, False: 0]
  ------------------
  889|      0|			XMP_Throw ( "Named children not allowed for arrays", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  890|      0|		}
  891|      0|		if ( ! createNodes ) {	// *** Should be assert? If !createNodes, why is the parent a new implicit node?
  ------------------
  |  Branch (891:8): [True: 0, False: 0]
  ------------------
  892|      0|			XMP_Throw ( "Parent is new implicit node, but createNodes is false", kXMPErr_InternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  893|      0|		}
  894|      0|		parent->options |= kXMP_PropValueIsStruct;
  895|      0|	}
  896|       |	
  897|  1.38M|	for ( size_t childNum = 0, childLim = parent->children.size(); childNum != childLim; ++childNum ) {
  ------------------
  |  Branch (897:65): [True: 1.32M, False: 55.2k]
  ------------------
  898|  1.32M|		XMP_Node * currChild = parent->children[childNum];
  899|  1.32M|		XMP_Assert ( currChild->parent == parent );
  ------------------
  |  |  142|  1.32M|	#define XMP_Assert(c)	((void) 0)
  ------------------
  900|  1.32M|		if ( currChild->name == childName ) {
  ------------------
  |  Branch (900:8): [True: 114k, False: 1.21M]
  ------------------
  901|   114k|			childNode = currChild;
  902|   114k|			if ( ptrPos != 0 ) *ptrPos = parent->children.begin() + childNum;
  ------------------
  |  Branch (902:9): [True: 113k, False: 956]
  ------------------
  903|   114k|			break;
  904|   114k|		}
  905|  1.32M|	}
  906|       |	
  907|   169k|	if ( (childNode == 0) && createNodes ) {
  ------------------
  |  Branch (907:7): [True: 55.2k, False: 114k]
  |  Branch (907:27): [True: 241, False: 55.0k]
  ------------------
  908|    241|		childNode = new XMP_Node ( parent, childName, kXMP_NewImplicitNode );
  ------------------
  |  |  410|    241|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  909|    241|		parent->children.push_back ( childNode );
  910|    241|		if ( ptrPos != 0 ) *ptrPos = parent->children.end() - 1;
  ------------------
  |  Branch (910:8): [True: 241, False: 0]
  ------------------
  911|    241|	}
  912|       |	
  913|   169k|	XMP_Assert ( (ptrPos == 0) || (childNode == 0) || (childNode == **ptrPos) );
  ------------------
  |  |  142|   169k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  914|   169k|	XMP_Assert ( (childNode != 0) || (! createNodes) );
  ------------------
  |  |  142|   169k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  915|   169k|	return childNode;
  916|       |	
  917|   169k|}	// FindChildNode
_Z17FindQualifierNodeP8XMP_NodePKcbPNSt3__111__wrap_iterIPS0_EE:
  934|  8.86k|{
  935|  8.86k|	XMP_Node * qualNode = 0;
  936|       |	
  937|  8.86k|	XMP_Assert ( *qualName != '?' );
  ------------------
  |  |  142|  8.86k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  938|       |	
  939|  32.4k|	for ( size_t qualNum = 0, qualLim = parent->qualifiers.size(); qualNum != qualLim; ++qualNum ) {
  ------------------
  |  Branch (939:65): [True: 32.4k, False: 0]
  ------------------
  940|  32.4k|		XMP_Node * currQual = parent->qualifiers[qualNum];
  941|  32.4k|		XMP_Assert ( currQual->parent == parent );
  ------------------
  |  |  142|  32.4k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  942|  32.4k|		if ( currQual->name == qualName ) {
  ------------------
  |  Branch (942:8): [True: 8.86k, False: 23.6k]
  ------------------
  943|  8.86k|			qualNode = currQual;
  944|  8.86k|			if ( ptrPos != 0 ) *ptrPos = parent->qualifiers.begin() + qualNum;
  ------------------
  |  Branch (944:9): [True: 8.86k, False: 0]
  ------------------
  945|  8.86k|			break;
  946|  8.86k|		}
  947|  32.4k|	}
  948|       |	
  949|  8.86k|	if ( (qualNode == 0) && createNodes ) {
  ------------------
  |  Branch (949:7): [True: 0, False: 8.86k]
  |  Branch (949:26): [True: 0, False: 0]
  ------------------
  950|       |
  951|      0|		qualNode = new XMP_Node ( parent, qualName, (static_cast<unsigned long>(kXMP_PropIsQualifier) | static_cast<unsigned long>(kXMP_NewImplicitNode)) );
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  952|      0|		parent->options |= kXMP_PropHasQualifiers;
  953|       |
  954|      0|		const bool isLang 	 = XMP_LitMatch ( qualName, "xml:lang" );
  ------------------
  |  |   96|      0|#define XMP_LitMatch(s,l)		(std::strcmp((s),(l)) == 0)
  ------------------
  955|      0|		const bool isType 	 = XMP_LitMatch ( qualName, "rdf:type" );
  ------------------
  |  |   96|      0|#define XMP_LitMatch(s,l)		(std::strcmp((s),(l)) == 0)
  ------------------
  956|      0|		const bool isSpecial = isLang | isType;
  957|       |
  958|      0|		if ( isLang ) {
  ------------------
  |  Branch (958:8): [True: 0, False: 0]
  ------------------
  959|      0|			parent->options |= kXMP_PropHasLang;
  960|      0|		} else if ( isType ) {
  ------------------
  |  Branch (960:15): [True: 0, False: 0]
  ------------------
  961|      0|			parent->options |= kXMP_PropHasType;
  962|      0|		}
  963|       |		
  964|      0|		if ( parent->qualifiers.empty() || (! isSpecial) ) {
  ------------------
  |  Branch (964:8): [True: 0, False: 0]
  |  Branch (964:38): [True: 0, False: 0]
  ------------------
  965|      0|			parent->qualifiers.push_back ( qualNode );
  966|      0|			if ( ptrPos != 0 ) *ptrPos = parent->qualifiers.end() - 1;
  ------------------
  |  Branch (966:9): [True: 0, False: 0]
  ------------------
  967|      0|		} else {
  968|      0|			XMP_NodePtrPos insertPos = parent->qualifiers.begin();	// ! Lang goes first, type after.
  969|      0|			if ( isType && (parent->options & kXMP_PropHasLang) ) ++insertPos;	// *** Does insert at end() work?
  ------------------
  |  Branch (969:9): [True: 0, False: 0]
  |  Branch (969:19): [True: 0, False: 0]
  ------------------
  970|      0|			insertPos = parent->qualifiers.insert ( insertPos, qualNode );
  971|      0|			if ( ptrPos != 0 ) *ptrPos = insertPos;
  ------------------
  |  Branch (971:9): [True: 0, False: 0]
  ------------------
  972|      0|		}
  973|       |
  974|      0|	}
  975|       |	
  976|  8.86k|	XMP_Assert ( (ptrPos == 0) || (qualNode == 0) || (qualNode == **ptrPos) );
  ------------------
  |  |  142|  8.86k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  977|  8.86k|	XMP_Assert ( (qualNode != 0) || (! createNodes) );
  ------------------
  |  |  142|  8.86k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  978|  8.86k|	return qualNode;
  979|       |	
  980|  8.86k|}	// FindQualifierNode
_Z8FindNodeP8XMP_NodeRKNSt3__16vectorI13XPathStepInfoNS1_9allocatorIS3_EEEEbjPNS1_11__wrap_iterIPS0_EE:
 1062|  91.6k|{
 1063|  91.6k|	XMP_Node *     currNode = 0;
 1064|  91.6k|	XMP_NodePtrPos currPos;
 1065|  91.6k|	XMP_NodePtrPos newSubPos;	// Root of implicitly created subtree. Valid only if leaf is new.
 1066|  91.6k|	bool           leafIsNew = false;
 1067|       |	
 1068|  91.6k|	XMP_Assert ( (leafOptions == 0) || createNodes );
  ------------------
  |  |  142|  91.6k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1069|       |
 1070|  91.6k|	if ( expandedXPath.empty() ) XMP_Throw ( "Empty XPath", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1070:7): [True: 0, False: 91.6k]
  ------------------
 1071|       |	
 1072|  91.6k|	size_t stepNum = 1;	// By default start calling FollowXPathStep for the top level property step.
 1073|  91.6k|	size_t stepLim = expandedXPath.size();
 1074|       |	
 1075|       |	// The start of processing deals with the schema node and top level alias. If the top level step
 1076|       |	// is not an alias, lookup the expanded path's schema URI. Otherwise, lookup the expanded path
 1077|       |	// for the actual. While tempting, don't substitute the actual's path into the local one, don't
 1078|       |	// risk messing with the caller's use of that. Also don't call FindNode recursively, we need to
 1079|       |	// keep track of the root of the implicitly created subtree as we move down the path.
 1080|       |	
 1081|  91.6k|	if ( ! (expandedXPath[kRootPropStep].options & kXMP_StepIsAlias) ) {
  ------------------
  |  Branch (1081:7): [True: 91.6k, False: 0]
  ------------------
 1082|       |		
 1083|  91.6k|		currNode = FindSchemaNode ( xmpTree, expandedXPath[kSchemaStep].step.c_str(), createNodes, &currPos );
 1084|  91.6k|		if ( currNode == 0 ) return 0;
  ------------------
  |  Branch (1084:8): [True: 0, False: 91.6k]
  ------------------
 1085|       |
 1086|  91.6k|		if ( currNode->options & kXMP_NewImplicitNode ) {
  ------------------
  |  |  410|  91.6k|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  |  Branch (1086:8): [True: 240, False: 91.3k]
  ------------------
 1087|    240|			currNode->options ^= kXMP_NewImplicitNode;	// Clear the implicit node bit.
  ------------------
  |  |  410|    240|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
 1088|    240|			if ( ! leafIsNew ) newSubPos = currPos;	// Save the top most implicit node.
  ------------------
  |  Branch (1088:9): [True: 240, False: 0]
  ------------------
 1089|    240|			leafIsNew = true;	// If any parent is new, the leaf will be new also.
 1090|    240|		}
 1091|       |
 1092|  91.6k|	} else {
 1093|       |
 1094|      0|		stepNum = 2;	// ! Continue processing the original path at the second level step.
 1095|       |
 1096|      0|		XMP_AliasMapPos aliasPos = sRegisteredAliasMap->find ( expandedXPath[kRootPropStep].step );
 1097|      0|		XMP_Assert ( aliasPos != sRegisteredAliasMap->end() );
  ------------------
  |  |  142|      0|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1098|       |		
 1099|      0|		currNode = FindSchemaNode ( xmpTree, aliasPos->second[kSchemaStep].step.c_str(), createNodes, &currPos );
 1100|      0|		if ( currNode == 0 ) goto EXIT;
  ------------------
  |  Branch (1100:8): [True: 0, False: 0]
  ------------------
 1101|      0|		if ( currNode->options & kXMP_NewImplicitNode ) {
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  |  Branch (1101:8): [True: 0, False: 0]
  ------------------
 1102|      0|			currNode->options ^= kXMP_NewImplicitNode;	// Clear the implicit node bit.
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
 1103|      0|			if ( ! leafIsNew ) newSubPos = currPos;	// Save the top most implicit node.
  ------------------
  |  Branch (1103:9): [True: 0, False: 0]
  ------------------
 1104|      0|			leafIsNew = true;	// If any parent is new, the leaf will be new also.
 1105|      0|		}
 1106|       |
 1107|      0|		currNode = FollowXPathStep ( currNode, aliasPos->second, 1, createNodes, &currPos );
 1108|      0|		if ( currNode == 0 ) goto EXIT;
  ------------------
  |  Branch (1108:8): [True: 0, False: 0]
  ------------------
 1109|      0|		if ( currNode->options & kXMP_NewImplicitNode ) {
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  |  Branch (1109:8): [True: 0, False: 0]
  ------------------
 1110|      0|			currNode->options ^= kXMP_NewImplicitNode;	// Clear the implicit node bit.
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
 1111|      0|			CheckImplicitStruct ( currNode, expandedXPath, 2, stepLim );
 1112|      0|			if ( ! leafIsNew ) newSubPos = currPos;	// Save the top most implicit node.
  ------------------
  |  Branch (1112:9): [True: 0, False: 0]
  ------------------
 1113|      0|			leafIsNew = true;	// If any parent is new, the leaf will be new also.
 1114|      0|		}
 1115|       |		
 1116|      0|		XMP_OptionBits arrayForm = aliasPos->second[kRootPropStep].options & kXMP_PropArrayFormMask;
 1117|      0|		XMP_Assert ( (arrayForm == 0) || (arrayForm & kXMP_PropValueIsArray) );
  ------------------
  |  |  142|      0|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1118|      0|		XMP_Assert ( (arrayForm == 0) ? (aliasPos->second.size() == 2) : (aliasPos->second.size() == 3) );
  ------------------
  |  |  142|      0|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1119|       |		
 1120|      0|		if ( arrayForm != 0 ) { 
  ------------------
  |  Branch (1120:8): [True: 0, False: 0]
  ------------------
 1121|      0|			currNode = FollowXPathStep ( currNode, aliasPos->second, 2, createNodes, &currPos, true );
 1122|      0|			if ( currNode == 0 ) goto EXIT;
  ------------------
  |  Branch (1122:9): [True: 0, False: 0]
  ------------------
 1123|      0|			if ( currNode->options & kXMP_NewImplicitNode ) {
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  |  Branch (1123:9): [True: 0, False: 0]
  ------------------
 1124|      0|				currNode->options ^= kXMP_NewImplicitNode;	// Clear the implicit node bit.
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
 1125|      0|				CheckImplicitStruct ( currNode, expandedXPath, 2, stepLim );
 1126|      0|				if ( ! leafIsNew ) newSubPos = currPos;	// Save the top most implicit node.
  ------------------
  |  Branch (1126:10): [True: 0, False: 0]
  ------------------
 1127|      0|				leafIsNew = true;	// If any parent is new, the leaf will be new also.
 1128|      0|			}
 1129|      0|		}
 1130|       |		
 1131|      0|	}
 1132|       |	
 1133|       |	// Now follow the remaining steps of the original XPath.
 1134|       |	
 1135|       |	// *** ??? Change all the num/lim loops back to num<lim? Probably safer.
 1136|       |	
 1137|  91.6k|	try {
 1138|   274k|		for ( ; stepNum < stepLim; ++stepNum ) {
  ------------------
  |  Branch (1138:11): [True: 182k, False: 91.6k]
  ------------------
 1139|   182k|			currNode = FollowXPathStep ( currNode, expandedXPath, stepNum, createNodes, &currPos );
 1140|   182k|			if ( currNode == 0 ) goto EXIT;
  ------------------
  |  Branch (1140:9): [True: 0, False: 182k]
  ------------------
 1141|   182k|			if ( currNode->options & kXMP_NewImplicitNode ) {
  ------------------
  |  |  410|   182k|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  |  Branch (1141:9): [True: 241, False: 182k]
  ------------------
 1142|    241|				currNode->options ^= kXMP_NewImplicitNode;	// Clear the implicit node bit.
  ------------------
  |  |  410|    241|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
 1143|    241|				CheckImplicitStruct ( currNode, expandedXPath, stepNum+1, stepLim );
 1144|    241|				if ( ! leafIsNew ) newSubPos = currPos;	// Save the top most implicit node.
  ------------------
  |  Branch (1144:10): [True: 1, False: 240]
  ------------------
 1145|    241|				leafIsNew = true;	// If any parent is new, the leaf will be new also.
 1146|    241|			}
 1147|   182k|		}
 1148|  91.6k|	} catch ( ... ) {
 1149|      0|		if ( leafIsNew ) DeleteSubtree ( newSubPos );
  ------------------
  |  Branch (1149:8): [True: 0, False: 0]
  ------------------
 1150|      0|		throw;
 1151|      0|	}
 1152|       |	
 1153|       |	// Done. Delete the implicitly created subtree if the eventual node was not found.
 1154|       |
 1155|  91.6k|EXIT:
 1156|       |
 1157|  91.6k|	XMP_Assert ( (currNode == 0) || (currNode == *currPos) );
  ------------------
  |  |  142|  91.6k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1158|  91.6k|	XMP_Assert ( (currNode != 0) || (! createNodes) );
  ------------------
  |  |  142|  91.6k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1159|       |
 1160|  91.6k|	if ( leafIsNew ) {
  ------------------
  |  Branch (1160:7): [True: 241, False: 91.3k]
  ------------------
 1161|    241|		if ( currNode != 0 ) {
  ------------------
  |  Branch (1161:8): [True: 241, False: 0]
  ------------------
 1162|    241|			currNode->options |= leafOptions;
 1163|    241|		} else {
 1164|      0|			DeleteSubtree ( newSubPos );
 1165|      0|		}
 1166|    241|	}
 1167|       |
 1168|  91.6k|	if ( (currNode != 0) && (ptrPos != 0) ) *ptrPos = currPos;
  ------------------
  |  Branch (1168:7): [True: 91.6k, False: 0]
  |  Branch (1168:26): [True: 0, False: 91.6k]
  ------------------
 1169|  91.6k|	return currNode;
 1170|       |	
 1171|  91.6k|}	// FindNode
_Z18NormalizeLangValuePNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
 1343|  2.68k|{
 1344|  2.68k|	char * tagStart;
 1345|  2.68k|	char * tagEnd;
 1346|       |
 1347|       |	// Find and process the primary subtag.
 1348|       |	
 1349|  2.68k|	tagStart = (char*) value->c_str();
 1350|  11.5k|	for ( tagEnd = tagStart; (*tagEnd != 0) && (*tagEnd != '-'); ++tagEnd ) {
  ------------------
  |  Branch (1350:27): [True: 11.4k, False: 88]
  |  Branch (1350:45): [True: 8.84k, False: 2.59k]
  ------------------
 1351|  8.84k|		if ( ('A' <= *tagEnd) && (*tagEnd <= 'Z') ) *tagEnd += 0x20;
  ------------------
  |  Branch (1351:8): [True: 7.22k, False: 1.61k]
  |  Branch (1351:28): [True: 1.16k, False: 6.05k]
  ------------------
 1352|  8.84k|	}
 1353|       |	
 1354|       |	// Find and process the secondary subtag.
 1355|       |	
 1356|  2.68k|	tagStart = tagEnd;
 1357|  2.68k|	if ( *tagStart == '-' ) ++tagStart;
  ------------------
  |  Branch (1357:7): [True: 2.59k, False: 88]
  ------------------
 1358|  24.0k|	for ( tagEnd = tagStart; (*tagEnd != 0) && (*tagEnd != '-'); ++tagEnd ) {
  ------------------
  |  Branch (1358:27): [True: 21.5k, False: 2.47k]
  |  Branch (1358:45): [True: 21.3k, False: 206]
  ------------------
 1359|  21.3k|		if ( ('A' <= *tagEnd) && (*tagEnd <= 'Z') ) *tagEnd += 0x20;
  ------------------
  |  Branch (1359:8): [True: 19.3k, False: 2.00k]
  |  Branch (1359:28): [True: 1.13k, False: 18.2k]
  ------------------
 1360|  21.3k|	}
 1361|  2.68k|	if ( tagEnd == tagStart+2 ) {
  ------------------
  |  Branch (1361:7): [True: 130, False: 2.55k]
  ------------------
 1362|    130|		if ( ('a' <= *tagStart) && (*tagStart <= 'z') ) *tagStart -= 0x20;
  ------------------
  |  Branch (1362:8): [True: 50, False: 80]
  |  Branch (1362:30): [True: 32, False: 18]
  ------------------
 1363|    130|		++tagStart;
 1364|    130|		if ( ('a' <= *tagStart) && (*tagStart <= 'z') ) *tagStart -= 0x20;
  ------------------
  |  Branch (1364:8): [True: 53, False: 77]
  |  Branch (1364:30): [True: 21, False: 32]
  ------------------
 1365|    130|	}
 1366|       |	
 1367|       |	// Find and process the remaining subtags.
 1368|       |	
 1369|  4.29k|	while ( true ) {
  ------------------
  |  Branch (1369:10): [True: 4.29k, Folded]
  ------------------
 1370|  4.29k|		tagStart = tagEnd;
 1371|  4.29k|		if ( *tagStart == '-' ) ++tagStart;
  ------------------
  |  Branch (1371:8): [True: 1.60k, False: 2.68k]
  ------------------
 1372|  4.29k|		if ( *tagStart == 0 ) break;
  ------------------
  |  Branch (1372:8): [True: 2.68k, False: 1.60k]
  ------------------
 1373|  7.48k|		for ( tagEnd = tagStart; (*tagEnd != 0) && (*tagEnd != '-'); ++tagEnd ) {
  ------------------
  |  Branch (1373:28): [True: 7.27k, False: 206]
  |  Branch (1373:46): [True: 5.87k, False: 1.40k]
  ------------------
 1374|  5.87k|			if ( ('A' <= *tagEnd) && (*tagEnd <= 'Z') ) *tagEnd += 0x20;
  ------------------
  |  Branch (1374:9): [True: 4.05k, False: 1.82k]
  |  Branch (1374:29): [True: 1.19k, False: 2.86k]
  ------------------
 1375|  5.87k|		}
 1376|  1.60k|	}
 1377|       |	
 1378|  2.68k|}	// NormalizeLangValue
_Z18NormalizeLangArrayP8XMP_Node:
 1390|  1.16k|{
 1391|  1.16k|	XMP_Assert ( XMP_ArrayIsAltText(array->options) );
  ------------------
  |  |  142|  1.16k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1392|       |	
 1393|  1.16k|	size_t itemNum;
 1394|  1.16k|	size_t itemLim = array->children.size();
 1395|  1.16k|	bool   hasDefault = false;
 1396|       |	
 1397|  1.33k|	for ( itemNum = 0; itemNum < itemLim; ++itemNum ) {
  ------------------
  |  Branch (1397:21): [True: 1.18k, False: 147]
  ------------------
 1398|       |	
 1399|  1.18k|		if ( array->children[itemNum]->qualifiers.empty() ||
  ------------------
  |  Branch (1399:8): [True: 0, False: 1.18k]
  ------------------
 1400|  1.18k|			 (array->children[itemNum]->qualifiers[0]->name != "xml:lang") ) {
  ------------------
  |  Branch (1400:5): [True: 0, False: 1.18k]
  ------------------
 1401|      0|			XMP_Throw ( "AltText array items must have an xml:lang qualifier", kXMPErr_BadXMP );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
 1402|      0|		}
 1403|       |
 1404|  1.18k|		if ( array->children[itemNum]->qualifiers[0]->value == "x-default" ) {
  ------------------
  |  Branch (1404:8): [True: 1.02k, False: 165]
  ------------------
 1405|  1.02k|			hasDefault = true;
 1406|  1.02k|			break;
 1407|  1.02k|		}
 1408|       |
 1409|  1.18k|	}
 1410|       |
 1411|  1.16k|	if ( hasDefault ) {
  ------------------
  |  Branch (1411:7): [True: 1.02k, False: 147]
  ------------------
 1412|       |
 1413|  1.02k|		if ( itemNum != 0 ) {
  ------------------
  |  Branch (1413:8): [True: 1, False: 1.02k]
  ------------------
 1414|      1|			XMP_Node * temp = array->children[0];
 1415|      1|			array->children[0] = array->children[itemNum];
 1416|      1|			array->children[itemNum] = temp;
 1417|      1|		}
 1418|       |
 1419|       |// 09-Oct-07, ahu: disabled to avoid unexpected behaviour
 1420|       |//		if ( itemLim == 2 ) array->children[1]->value = array->children[0]->value;
 1421|       |
 1422|  1.02k|	}
 1423|       |	
 1424|  1.16k|}	// NormalizeLangArray
_Z13DetectAltTextP8XMP_Node:
 1434|  1.32k|{
 1435|  1.32k|	XMP_Assert ( XMP_ArrayIsAlternate(xmpParent->options) );
  ------------------
  |  |  142|  1.32k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1436|       |
 1437|  1.32k|	size_t itemNum, itemLim;
 1438|       |	
 1439|  2.93k|	for ( itemNum = 0, itemLim = xmpParent->children.size(); itemNum < itemLim; ++itemNum ) {
  ------------------
  |  Branch (1439:59): [True: 1.75k, False: 1.17k]
  ------------------
 1440|  1.75k|		XMP_OptionBits currOptions = xmpParent->children[itemNum]->options;
 1441|  1.75k|		if ( (currOptions & kXMP_PropCompositeMask) || (! (currOptions & kXMP_PropHasLang)) ) break;
  ------------------
  |  Branch (1441:8): [True: 23, False: 1.73k]
  |  Branch (1441:50): [True: 126, False: 1.60k]
  ------------------
 1442|  1.75k|	}
 1443|       |	
 1444|  1.32k|	if ( (itemLim != 0) && (itemNum == itemLim) ) {
  ------------------
  |  Branch (1444:7): [True: 1.31k, False: 9]
  |  Branch (1444:25): [True: 1.16k, False: 149]
  ------------------
 1445|  1.16k|		xmpParent->options |= kXMP_PropArrayIsAltText;
 1446|  1.16k|		NormalizeLangArray ( xmpParent );
 1447|  1.16k|	}
 1448|       |
 1449|  1.32k|}	// DetectAltText
XMPCore_Impl.cpp:_ZL15VerifyXPathRootPKcS0_PNSt3__16vectorI13XPathStepInfoNS1_9allocatorIS3_EEEE:
  154|  91.6k|{
  155|       |	// Do some basic checks on the URI and name. Try to lookup the URI. See if the name is qualified.
  156|       |	
  157|  91.6k|	XMP_Assert ( (schemaURI != 0) && (propName != 0) && (*propName != 0) );
  ------------------
  |  |  142|  91.6k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  158|  91.6k|	XMP_Assert ( (expandedXPath != 0) && (expandedXPath->empty()) );
  ------------------
  |  |  142|  91.6k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  159|       |
  160|  91.6k|	if ( *schemaURI == 0 ) XMP_Throw ( "Schema namespace URI is required", kXMPErr_BadSchema );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (160:7): [True: 0, False: 91.6k]
  ------------------
  161|       |
  162|  91.6k|	if ( (*propName == '?') || (*propName == '@') ) {
  ------------------
  |  Branch (162:7): [True: 0, False: 91.6k]
  |  Branch (162:29): [True: 0, False: 91.6k]
  ------------------
  163|      0|		XMP_Throw ( "Top level name must not be a qualifier", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  164|      0|	}
  165|  6.95M|	for ( XMP_StringPtr ch = propName; *ch != 0; ++ch ) {
  ------------------
  |  Branch (165:37): [True: 6.86M, False: 91.6k]
  ------------------
  166|  6.86M|		if ( (*ch == '/') || (*ch == '[') ) {
  ------------------
  |  Branch (166:8): [True: 0, False: 6.86M]
  |  Branch (166:24): [True: 0, False: 6.86M]
  ------------------
  167|      0|			XMP_Throw ( "Top level name must be simple", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  168|      0|		}
  169|  6.86M|	}
  170|       |
  171|  91.6k|	XMP_StringMapPos uriPos = sNamespaceURIToPrefixMap->find ( XMP_VarString ( schemaURI ) );
  172|  91.6k|	if ( uriPos == sNamespaceURIToPrefixMap->end() ) {
  ------------------
  |  Branch (172:7): [True: 0, False: 91.6k]
  ------------------
  173|      0|		XMP_Throw ( "Unregistered schema namespace URI", kXMPErr_BadSchema );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  174|      0|	}
  175|       |
  176|  91.6k|	XMP_StringPtr colonPos = propName;
  177|   434k|	while ( (*colonPos != 0) && (*colonPos != ':') ) ++colonPos;
  ------------------
  |  Branch (177:10): [True: 434k, False: 243]
  |  Branch (177:30): [True: 343k, False: 91.4k]
  ------------------
  178|  91.6k|	VerifySimpleXMLName ( propName, colonPos );	// Verify the part before any colon.
  179|       |
  180|       |	// Verify the various URI and prefix combinations. Initialize the expanded XPath.
  181|       |	
  182|  91.6k|	if ( *colonPos == 0 ) {
  ------------------
  |  Branch (182:7): [True: 243, False: 91.4k]
  ------------------
  183|       |	
  184|       |		// The propName is unqualified, use the schemaURI and associated prefix.
  185|       |		
  186|    243|		expandedXPath->push_back ( XPathStepInfo ( schemaURI, kXMP_SchemaNode ) );
  187|    243|		expandedXPath->push_back ( XPathStepInfo ( uriPos->second, 0 ) );
  188|    243|		(*expandedXPath)[kRootPropStep].step += propName;
  189|       |	
  190|  91.4k|	} else {
  191|       |
  192|       |		// The propName is qualified. Make sure the prefix is legit. Use the associated URI and qualified name.
  193|       |
  194|  91.4k|		size_t prefixLen = colonPos - propName + 1;	// ! Include the colon.
  195|  91.4k|		VerifySimpleXMLName ( colonPos+1, colonPos+strlen(colonPos) );
  196|       |
  197|  91.4k|		XMP_VarString prefix ( propName, prefixLen );
  198|  91.4k|		XMP_StringMapPos prefixPos = sNamespacePrefixToURIMap->find ( prefix );
  199|  91.4k|		if ( prefixPos == sNamespacePrefixToURIMap->end() ) {
  ------------------
  |  Branch (199:8): [True: 0, False: 91.4k]
  ------------------
  200|      0|			XMP_Throw ( "Unknown schema namespace prefix", kXMPErr_BadSchema );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  201|      0|		}
  202|  91.4k|		if ( prefix != uriPos->second ) {
  ------------------
  |  Branch (202:8): [True: 18, False: 91.3k]
  ------------------
  203|     18|			XMP_Throw ( "Schema namespace URI and prefix mismatch", kXMPErr_BadSchema );
  ------------------
  |  |  199|     18|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  204|      0|		}
  205|       |
  206|  91.3k|		expandedXPath->push_back ( XPathStepInfo ( schemaURI, kXMP_SchemaNode ) );
  207|  91.3k|		expandedXPath->push_back ( XPathStepInfo ( propName, 0 ) );
  208|       |	
  209|  91.3k|	}
  210|       |
  211|  91.6k|}	// VerifyXPathRoot
XMPCore_Impl.cpp:_ZL14VerifyQualNamePKcS0_:
  219|  31.1k|{
  220|  31.1k|	if ( qualName >= nameEnd ) XMP_Throw ( "Empty qualified name", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (220:7): [True: 0, False: 31.1k]
  ------------------
  221|       |
  222|  31.1k|	XMP_StringPtr colonPos = qualName;
  223|   169k|	while ( (colonPos < nameEnd) && (*colonPos != ':') ) ++colonPos;
  ------------------
  |  Branch (223:10): [True: 169k, False: 0]
  |  Branch (223:34): [True: 138k, False: 31.1k]
  ------------------
  224|  31.1k|	if ( (colonPos == qualName) || (colonPos >= nameEnd) ) XMP_Throw ( "Ill-formed qualified name", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (224:7): [True: 0, False: 31.1k]
  |  Branch (224:33): [True: 0, False: 31.1k]
  ------------------
  225|       |
  226|  31.1k|	VerifySimpleXMLName ( qualName, colonPos );
  227|  31.1k|	VerifySimpleXMLName ( colonPos+1, nameEnd );
  228|       |
  229|  31.1k|	size_t prefixLen = colonPos - qualName + 1;	// ! Include the colon.
  230|  31.1k|	XMP_VarString prefix ( qualName, prefixLen );
  231|  31.1k|	XMP_StringMapPos prefixPos = sNamespacePrefixToURIMap->find ( prefix );
  232|  31.1k|	if ( prefixPos == sNamespacePrefixToURIMap->end() ) {
  ------------------
  |  Branch (232:7): [True: 0, False: 31.1k]
  ------------------
  233|      0|		XMP_Throw ( "Unknown namespace prefix for qualified name", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  234|      0|	}
  235|       |
  236|  31.1k|}	// VerifyQualName
XMPCore_Impl.cpp:_ZL15FollowXPathStepP8XMP_NodeRKNSt3__16vectorI13XPathStepInfoNS1_9allocatorIS3_EEEEmbPNS1_11__wrap_iterIPS0_EEb:
  394|   182k|{
  395|   182k|	XMP_Node * nextNode = 0;
  396|   182k|	const XPathStepInfo & nextStep = fullPath[stepNum];
  397|   182k|	XMP_Index      index    = 0;
  398|   182k|	XMP_OptionBits stepKind = nextStep.options & kXMP_StepKindMask;
  399|       |	
  400|   182k|	XMP_Assert ( (kXMP_StructFieldStep <= stepKind) && (stepKind <= kXMP_FieldSelectorStep) );
  ------------------
  |  |  142|   182k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  401|       |
  402|   182k|	if ( stepKind == kXMP_StructFieldStep ) {
  ------------------
  |  Branch (402:7): [True: 113k, False: 68.7k]
  ------------------
  403|       |
  404|   113k|		nextNode = FindChildNode ( parentNode, nextStep.step.c_str(), createNodes, ptrPos );
  405|       |
  406|   113k|	} else if ( stepKind == kXMP_QualifierStep ) {
  ------------------
  |  Branch (406:14): [True: 8.86k, False: 59.8k]
  ------------------
  407|       |	
  408|  8.86k|		XMP_StringPtr qualStep = nextStep.step.c_str();
  409|  8.86k|		XMP_Assert ( *qualStep == '?' );
  ------------------
  |  |  142|  8.86k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  410|  8.86k|		++qualStep;
  411|  8.86k|		nextNode = FindQualifierNode ( parentNode, qualStep, createNodes, ptrPos );
  412|       |
  413|  59.8k|	} else {
  414|       |	
  415|       |		// This is an array indexing step. First get the index, then get the node.
  416|       |
  417|  59.8k|		if ( ! (parentNode->options & kXMP_PropValueIsArray) ) {
  ------------------
  |  Branch (417:8): [True: 0, False: 59.8k]
  ------------------
  418|      0|			XMP_Throw ( "Indexing applied to non-array", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  419|      0|		}
  420|       |		
  421|  59.8k|		if ( stepKind == kXMP_ArrayIndexStep ) {
  ------------------
  |  Branch (421:8): [True: 59.8k, False: 0]
  ------------------
  422|  59.8k|			index = FindIndexedItem ( parentNode, nextStep.step, createNodes );
  423|  59.8k|		} else if ( stepKind == kXMP_ArrayLastStep ) {
  ------------------
  |  Branch (423:15): [True: 0, False: 0]
  ------------------
  424|      0|			index = parentNode->children.size() - 1;
  425|      0|		} else if ( stepKind == kXMP_FieldSelectorStep ) {
  ------------------
  |  Branch (425:15): [True: 0, False: 0]
  ------------------
  426|      0|			XMP_VarString fieldName, fieldValue;
  427|      0|			SplitNameAndValue ( nextStep.step, &fieldName, &fieldValue );
  428|      0|			index = LookupFieldSelector ( parentNode, fieldName.c_str(), fieldValue.c_str() );
  429|      0|		} else if ( stepKind == kXMP_QualSelectorStep ) {
  ------------------
  |  Branch (429:15): [True: 0, False: 0]
  ------------------
  430|      0|			XMP_VarString qualName, qualValue;
  431|      0|			SplitNameAndValue ( nextStep.step, &qualName, &qualValue );
  432|      0|			index = LookupQualSelector ( parentNode, qualName, qualValue );
  433|      0|		} else {
  434|      0|			XMP_Throw ( "Unknown array indexing step in FollowXPathStep", kXMPErr_InternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  435|      0|		}
  436|       |		
  437|  59.8k|		if ( (0 <= index) && (index <= (XMP_Index)parentNode->children.size()) ) nextNode = parentNode->children[index];
  ------------------
  |  Branch (437:8): [True: 59.8k, False: 0]
  |  Branch (437:24): [True: 59.8k, False: 0]
  ------------------
  438|       |
  439|  59.8k|		if ( (index == -1) && createNodes && aliasedArrayItem && (stepKind == kXMP_QualSelectorStep) ) {
  ------------------
  |  Branch (439:8): [True: 0, False: 59.8k]
  |  Branch (439:25): [True: 0, False: 0]
  |  Branch (439:40): [True: 0, False: 0]
  |  Branch (439:60): [True: 0, False: 0]
  ------------------
  440|       |		
  441|       |			// An ugly special case without an obvious better place to be. We have an alias to the
  442|       |			// x-default item of an alt-text array. A simple reference via SetProperty must create
  443|       |			// the x-default item if it does not yet exist.
  444|       |			
  445|      0|			XMP_Assert ( parentNode->options & kXMP_PropArrayIsAltText );
  ------------------
  |  |  142|      0|	#define XMP_Assert(c)	((void) 0)
  ------------------
  446|      0|			XMP_Assert ( (stepNum == 2) && (nextStep.step == "[?xml:lang=\"x-default\"]") );
  ------------------
  |  |  142|      0|	#define XMP_Assert(c)	((void) 0)
  ------------------
  447|       |
  448|      0|			nextNode = new XMP_Node ( parentNode, kXMP_ArrayItemName,
  ------------------
  |  |  293|      0|#define kXMP_ArrayItemName	"[]"
  ------------------
  449|      0|									  (kXMP_PropHasQualifiers | kXMP_PropHasLang | kXMP_NewImplicitNode) );
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  450|       |
  451|      0|			XMP_Node * langQual = new XMP_Node ( nextNode, "xml:lang", "x-default", kXMP_PropIsQualifier );
  452|      0|			nextNode->qualifiers.push_back ( langQual );
  453|       |
  454|      0|			if ( parentNode->children.empty() ) {
  ------------------
  |  Branch (454:9): [True: 0, False: 0]
  ------------------
  455|      0|				parentNode->children.push_back ( nextNode );
  456|      0|			} else {
  457|      0|				parentNode->children.insert ( parentNode->children.begin(), nextNode );
  458|      0|			}
  459|       |
  460|      0|			index = 0;	// ! C-style index! The x-default item is always first.
  461|       |
  462|      0|		}
  463|       |		
  464|  59.8k|		if ( (nextNode != 0) && (ptrPos != 0) ) *ptrPos = parentNode->children.begin() + index;
  ------------------
  |  Branch (464:8): [True: 59.8k, False: 0]
  |  Branch (464:27): [True: 59.8k, False: 0]
  ------------------
  465|       |	
  466|  59.8k|	}
  467|       |
  468|   182k|	if ( (nextNode != 0) && (nextNode->options & kXMP_NewImplicitNode) ) {
  ------------------
  |  |  410|   182k|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  |  Branch (468:7): [True: 182k, False: 0]
  |  Branch (468:26): [True: 241, False: 182k]
  ------------------
  469|    241|		nextNode->options |= (nextStep.options & kXMP_PropArrayFormMask);
  470|    241|	}
  471|       |	
  472|   182k|	XMP_Assert ( (ptrPos == 0) || (nextNode == 0) || (nextNode == **ptrPos) );
  ------------------
  |  |  142|   182k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  473|   182k|	XMP_Assert ( (nextNode != 0) || (! createNodes) );
  ------------------
  |  |  142|   182k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  474|   182k|	return nextNode;
  475|       |	
  476|   182k|}	// FollowXPathStep
XMPCore_Impl.cpp:_ZL15FindIndexedItemP8XMP_NodeRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEb:
  248|  59.8k|{
  249|  59.8k|	XMP_Index index = 0;
  250|  59.8k|	size_t    chLim = indexStep.size() - 1;
  251|       |
  252|  59.8k|	XMP_Assert ( (chLim >= 2) && (indexStep[0] == '[') && (indexStep[chLim] == ']') );
  ------------------
  |  |  142|  59.8k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  253|       |	
  254|   155k|	for ( size_t chNum = 1; chNum != chLim; ++chNum ) {
  ------------------
  |  Branch (254:26): [True: 95.5k, False: 59.8k]
  ------------------
  255|  95.5k|		XMP_Assert ( ('0' <= indexStep[chNum]) && (indexStep[chNum] <= '9') );
  ------------------
  |  |  142|  95.5k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  256|  95.5k|		index = (index * 10) + (indexStep[chNum] - '0');
  257|  95.5k|		if ( index < 0 ) {
  ------------------
  |  Branch (257:8): [True: 0, False: 95.5k]
  ------------------
  258|      0|			XMP_Throw ( "Array index overflow", kXMPErr_BadXPath );	// ! Overflow, not truly negative.
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  259|      0|		}
  260|  95.5k|	}
  261|       |
  262|  59.8k|	--index;	// Change to a C-style, zero based index.
  263|  59.8k|	if ( index < 0 ) XMP_Throw ( "Array index must be larger than zero", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (263:7): [True: 0, False: 59.8k]
  ------------------
  264|       |
  265|  59.8k|	if ( (index == (XMP_Index)arrayNode->children.size()) && createNodes ) {	// Append a new last+1 node.
  ------------------
  |  Branch (265:7): [True: 0, False: 59.8k]
  |  Branch (265:59): [True: 0, False: 0]
  ------------------
  266|      0|		XMP_Node * newItem = new XMP_Node ( arrayNode, kXMP_ArrayItemName, kXMP_NewImplicitNode );
  ------------------
  |  |  293|      0|#define kXMP_ArrayItemName	"[]"
  ------------------
              		XMP_Node * newItem = new XMP_Node ( arrayNode, kXMP_ArrayItemName, kXMP_NewImplicitNode );
  ------------------
  |  |  410|      0|#define kXMP_NewImplicitNode	kXMP_InsertAfterItem
  ------------------
  267|      0|		arrayNode->children.push_back ( newItem );
  268|      0|	}
  269|       |
  270|       |	// ! Don't throw here for a too large index. SetProperty will throw, GetProperty will not.
  271|  59.8k|	if ( index >= (XMP_Index)arrayNode->children.size() ) index = -1;
  ------------------
  |  Branch (271:7): [True: 0, False: 59.8k]
  ------------------
  272|  59.8k|	return index;
  273|       |	
  274|  59.8k|}	// FindIndexedItem
XMPCore_Impl.cpp:_ZL19CheckImplicitStructP8XMP_NodeRKNSt3__16vectorI13XPathStepInfoNS1_9allocatorIS3_EEEEmm:
  487|    241|{
  488|       |
  489|    241|	if ( (stepNum < stepLim) &&
  ------------------
  |  Branch (489:7): [True: 0, False: 241]
  ------------------
  490|      0|		 ((node->options & kXMP_PropCompositeMask) == 0) &&
  ------------------
  |  Branch (490:4): [True: 0, False: 0]
  ------------------
  491|      0|		 (GetStepKind ( expandedXPath[stepNum].options ) == kXMP_StructFieldStep) ) {
  ------------------
  |  |  408|      0|#define GetStepKind(f)	((f) & kXMP_StepKindMask)
  ------------------
  |  Branch (491:4): [True: 0, False: 0]
  ------------------
  492|       |
  493|      0|		node->options |= kXMP_PropValueIsStruct;
  494|       |
  495|      0|	}
  496|       |
  497|    241|}	// CheckImplicitStruct

_ZN13XMP_AutoMutexC2Ev:
  222|   156k|	XMP_AutoMutex() : mutex(&sXMPCoreLock) { XMP_EnterCriticalRegion ( *mutex ); ReportLock(); };
  ------------------
  |  |  168|   156k|	#define ReportLock()			++sLockCount
  ------------------
_ZN13XMP_AutoMutexD2Ev:
  223|   156k|	~XMP_AutoMutex() { if ( mutex != 0 ) { ReportUnlock(); XMP_ExitCriticalRegion ( *mutex ); mutex = 0; } };
  ------------------
  |  |  169|  61.3k|	#define ReportUnlock()			--sLockCount
  ------------------
  |  Branch (223:26): [True: 61.3k, False: 95.5k]
  ------------------
_ZN13XMP_AutoMutex8KeepLockEv:
  224|  95.5k|	void KeepLock() { ReportKeepLock(); mutex = 0; };
_ZN13XPathStepInfoC2EPKcj:
  389|   183k|	XPathStepInfo ( XMP_StringPtr _step, XMP_OptionBits _options ) : step(_step), options(_options) {};
_ZN13XPathStepInfoC2ENSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEj:
  390|  91.2k|	XPathStepInfo ( XMP_VarString _step, XMP_OptionBits _options ) : step(_step), options(_options) {};
_ZN8XMP_NodeC2EPS_PKcj:
  434|  19.5k|		: options(_options), name(_name), parent(_parent)
  435|  19.5k|	{
  436|       |		#if XMP_DebugBuild
  437|       |			XMP_Assert ( (name.find ( ':' ) != XMP_VarString::npos) || (name == kXMP_ArrayItemName) ||
  438|       |			             (options & kXMP_SchemaNode) || (parent == 0) );
  439|       |			// *** _namePtr  = name.c_str();
  440|       |			// *** _valuePtr = value.c_str();
  441|       |		#endif
  442|  19.5k|	};
_ZN8XMP_NodeC2EPS_PKcS2_j:
  456|  73.6k|		: options(_options), name(_name), value(_value), parent(_parent)
  457|  73.6k|	{
  458|       |		#if XMP_DebugBuild
  459|       |			XMP_Assert ( (name.find ( ':' ) != XMP_VarString::npos) || (name == kXMP_ArrayItemName) ||
  460|       |			             (options & kXMP_SchemaNode) || (parent == 0) );
  461|       |			// *** _namePtr  = name.c_str();
  462|       |			// *** _valuePtr = value.c_str();
  463|       |		#endif
  464|  73.6k|	};
_ZN8XMP_NodeC2EPS_RKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_j:
  467|  10.2k|		: options(_options), name(_name), value(_value), parent(_parent)
  468|  10.2k|	{
  469|       |		#if XMP_DebugBuild
  470|       |			XMP_Assert ( (name.find ( ':' ) != XMP_VarString::npos) || (name == kXMP_ArrayItemName) ||
  471|       |			             (options & kXMP_SchemaNode) || (parent == 0) );
  472|       |			// *** _namePtr  = name.c_str();
  473|       |			// *** _valuePtr = value.c_str();
  474|       |		#endif
  475|  10.2k|	};
_ZN8XMP_Node14RemoveChildrenEv:
  478|   114k|	{
  479|   198k|		for ( size_t i = 0, vLim = children.size(); i < vLim; ++i ) {
  ------------------
  |  Branch (479:47): [True: 83.9k, False: 114k]
  ------------------
  480|  83.9k|			if ( children[i] != 0 ) delete children[i];
  ------------------
  |  Branch (480:9): [True: 83.9k, False: 1]
  ------------------
  481|  83.9k|		}
  482|   114k|		children.clear();
  483|   114k|	}
_ZN8XMP_Node16RemoveQualifiersEv:
  486|   114k|	{
  487|   124k|		for ( size_t i = 0, vLim = qualifiers.size(); i < vLim; ++i ) {
  ------------------
  |  Branch (487:49): [True: 10.6k, False: 114k]
  ------------------
  488|  10.6k|			if ( qualifiers[i] != 0 ) delete qualifiers[i];
  ------------------
  |  Branch (488:9): [True: 10.6k, False: 0]
  ------------------
  489|  10.6k|		}
  490|   114k|		qualifiers.clear();
  491|   114k|	}
_ZN8XMP_Node9ClearNodeEv:
  494|  10.4k|	{
  495|  10.4k|		options = 0;
  496|  10.4k|		name.erase();
  497|  10.4k|		value.erase();
  498|  10.4k|		this->RemoveChildren();
  499|  10.4k|		this->RemoveQualifiers();
  500|  10.4k|	}
_ZN8XMP_NodeD2Ev:
  502|   103k|	virtual ~XMP_Node() { RemoveChildren(); RemoveQualifiers(); };

_ZN11XMPIterator10InitializeEv:
  376|      1|{
  377|      1|	sDummySchema = new XMP_Node ( 0, "dummy:schema/", kXMP_SchemaNode);
  378|      1|	return true;
  379|       |	
  380|      1|}	// Initialize
_ZN11XMPIterator9TerminateEv:
  388|      1|{
  389|      1|	delete ( sDummySchema );
  390|      1|	sDummySchema = 0;
  391|      1|	return;
  392|       |	
  393|      1|}	// Terminate
_ZN11XMPIteratorC2ERK7XMPMetaPKcS4_j:
  427|  10.4k|						   XMP_OptionBits  options ) : clientRefs(0), info(IterInfo(options,&xmpObj))
  428|  10.4k|{
  429|  10.4k|	if ( (options & kXMP_IterClassMask) != kXMP_IterProperties ) {
  ------------------
  |  Branch (429:7): [True: 0, False: 10.4k]
  ------------------
  430|      0|		XMP_Throw ( "Unsupported iteration kind", kXMPErr_BadOptions );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  431|      0|	}
  432|       |	
  433|       |	// *** Lock the XMPMeta object if we ever stop using a full DLL lock.
  434|       |
  435|  10.4k|	if ( *propName != 0 ) {
  ------------------
  |  Branch (435:7): [True: 3.29k, False: 7.11k]
  ------------------
  436|       |
  437|       |		// An iterator rooted at a specific node.
  438|       |
  439|       |		#if TraceIterators
  440|       |			printf ( "\nNew XMP property iterator for \"%s\", options = %X\n    Schema = %s, root = %s\n",
  441|       |			         xmpObj.tree.name.c_str(), options, schemaNS, propName );
  442|       |		#endif
  443|       |		
  444|  3.29k|		XMP_ExpandedXPath propPath;
  445|  3.29k|		ExpandXPath ( schemaNS, propName, &propPath );
  446|  3.29k|		XMP_Node * propNode = FindConstNode ( &xmpObj.tree, propPath );	// If not found get empty iteration.
  ------------------
  |  |  301|  3.29k|#define FindConstNode(t,p)		FindNode ( const_cast<XMP_Node*>(t), p, kXMP_ExistingOnly, 0 )
  |  |  ------------------
  |  |  |  |  296|  3.29k|#define kXMP_ExistingOnly	false
  |  |  ------------------
  ------------------
  447|       |		
  448|  3.29k|		if ( propNode != 0 ) {
  ------------------
  |  Branch (448:8): [True: 3.29k, False: 0]
  ------------------
  449|       |
  450|  3.29k|			XMP_VarString rootName ( propPath[1].step );	// The schema is [0].
  451|  3.29k|			for ( size_t i = 2; i < propPath.size(); ++i ) {
  ------------------
  |  Branch (451:24): [True: 0, False: 3.29k]
  ------------------
  452|      0|				XMP_OptionBits stepKind = GetStepKind ( propPath[i].options );
  ------------------
  |  |  408|      0|#define GetStepKind(f)	((f) & kXMP_StepKindMask)
  ------------------
  453|      0|				if ( stepKind <= kXMP_QualifierStep ) rootName += '/';
  ------------------
  |  Branch (453:10): [True: 0, False: 0]
  ------------------
  454|      0|				rootName += propPath[i].step;
  455|      0|			}
  456|       |
  457|  3.29k|			propName = rootName.c_str();
  458|  3.29k|			size_t leafOffset = rootName.size();
  459|  60.1k|			while ( (leafOffset > 0) && (propName[leafOffset] != '/') && (propName[leafOffset] != '[') ) --leafOffset;
  ------------------
  |  Branch (459:12): [True: 56.8k, False: 3.29k]
  |  Branch (459:32): [True: 56.8k, False: 0]
  |  Branch (459:65): [True: 56.8k, False: 0]
  ------------------
  460|  3.29k|			if ( propName[leafOffset] == '/' ) ++leafOffset;
  ------------------
  |  Branch (460:9): [True: 0, False: 3.29k]
  ------------------
  461|       |
  462|  3.29k|			info.tree.children.push_back ( IterNode ( propNode->options, propName, leafOffset ) );
  463|  3.29k|			SetCurrSchema ( info, propPath[kSchemaStep].step.c_str() );
  464|  3.29k|			if ( info.options & kXMP_IterJustChildren ) {
  ------------------
  |  Branch (464:9): [True: 0, False: 3.29k]
  ------------------
  465|      0|				AddNodeOffspring ( info, info.tree.children.back(), propNode );
  466|      0|			}
  467|       |
  468|  3.29k|		}
  469|       |	
  470|  7.11k|	} else if ( *schemaNS != 0 ) {
  ------------------
  |  Branch (470:14): [True: 0, False: 7.11k]
  ------------------
  471|       |
  472|       |		// An iterator for all properties in one schema.
  473|       |		
  474|       |		#if TraceIterators
  475|       |			printf ( "\nNew XMP schema iterator for \"%s\", options = %X\n    Schema = %s\n",
  476|       |			         xmpObj.tree.name.c_str(), options, schemaNS );
  477|       |		#endif
  478|       |		
  479|      0|		info.tree.children.push_back ( IterNode ( kXMP_SchemaNode, schemaNS, 0 ) );
  480|      0|		IterNode & iterSchema = info.tree.children.back();
  481|       |		
  482|      0|		XMP_Node * xmpSchema = FindConstSchema ( &xmpObj.tree, schemaNS );
  ------------------
  |  |  298|      0|#define FindConstSchema(t,u)	FindSchemaNode ( const_cast<XMP_Node*>(t), u, kXMP_ExistingOnly, 0 )
  |  |  ------------------
  |  |  |  |  296|      0|#define kXMP_ExistingOnly	false
  |  |  ------------------
  ------------------
  483|      0|		if ( xmpSchema != 0 ) AddSchemaProps ( info, iterSchema, xmpSchema );
  ------------------
  |  Branch (483:8): [True: 0, False: 0]
  ------------------
  484|       |		
  485|      0|		if ( info.options & kXMP_IterIncludeAliases ) AddSchemaAliases ( info, iterSchema, schemaNS );
  ------------------
  |  Branch (485:8): [True: 0, False: 0]
  ------------------
  486|       |		
  487|      0|		if ( iterSchema.children.empty() ) {
  ------------------
  |  Branch (487:8): [True: 0, False: 0]
  ------------------
  488|      0|			info.tree.children.pop_back();	// No properties, remove the schema node.
  489|      0|		} else {
  490|      0|			SetCurrSchema ( info, schemaNS );
  491|      0|		}
  492|       |	
  493|  7.11k|	} else {
  494|       |
  495|       |		// An iterator for all properties in all schema. First add schema that exist (have children),
  496|       |		// adding aliases from them if appropriate. Then add schema that have no actual properties
  497|       |		// but do have aliases to existing properties, if we're including aliases in the iteration.
  498|       |		
  499|       |		#if TraceIterators
  500|       |			printf ( "\nNew XMP tree iterator for \"%s\", options = %X\n",
  501|       |			         xmpObj.tree.name.c_str(), options );
  502|       |		#endif
  503|       |		
  504|       |		// First pick up the schema that exist.
  505|       |		
  506|  15.9k|		for ( size_t schemaNum = 0, schemaLim = xmpObj.tree.children.size(); schemaNum != schemaLim; ++schemaNum ) {
  ------------------
  |  Branch (506:72): [True: 8.82k, False: 7.11k]
  ------------------
  507|       |
  508|  8.82k|			const XMP_Node * xmpSchema = xmpObj.tree.children[schemaNum];
  509|  8.82k|			info.tree.children.push_back ( IterNode ( kXMP_SchemaNode, xmpSchema->name, 0 ) );
  510|  8.82k|			IterNode & iterSchema = info.tree.children.back();
  511|       |
  512|  8.82k|			if ( ! (info.options & kXMP_IterJustChildren) ) {
  ------------------
  |  Branch (512:9): [True: 8.82k, False: 0]
  ------------------
  513|  8.82k|				AddSchemaProps ( info, iterSchema, xmpSchema );
  514|  8.82k|				if ( info.options & kXMP_IterIncludeAliases ) AddSchemaAliases ( info, iterSchema, xmpSchema->name.c_str() );
  ------------------
  |  Branch (514:10): [True: 0, False: 8.82k]
  ------------------
  515|  8.82k|				if ( iterSchema.children.empty() ) info.tree.children.pop_back();	// No properties, remove the schema node.
  ------------------
  |  Branch (515:10): [True: 0, False: 8.82k]
  ------------------
  516|  8.82k|			}
  517|       |
  518|  8.82k|		}
  519|       |		
  520|  7.11k|		if ( info.options & kXMP_IterIncludeAliases ) {
  ------------------
  |  Branch (520:8): [True: 0, False: 7.11k]
  ------------------
  521|       |
  522|       |			// Add the schema that only have aliases. The most convenient, and safest way, is to go
  523|       |			// through the registered namespaces, see if it exists, and let AddSchemaAliases do its
  524|       |			// thing if not. Don't combine with the above loop, it is nicer to have the "real" stuff
  525|       |			// be in storage order (not subject to the namespace map order).
  526|       |			
  527|       |			// ! We don't do the kXMP_IterJustChildren handing in the same way here as above. The
  528|       |			// ! existing schema (presumably) have actual children. We need to call AddSchemaAliases
  529|       |			// ! here to determine if the namespace has any aliases to existing properties. We then
  530|       |			// ! strip the children if necessary.
  531|       |
  532|      0|			XMP_cStringMapPos currNS = sNamespaceURIToPrefixMap->begin();
  533|      0|			XMP_cStringMapPos endNS  = sNamespaceURIToPrefixMap->end();
  534|      0|			for ( ; currNS != endNS; ++currNS ) {
  ------------------
  |  Branch (534:12): [True: 0, False: 0]
  ------------------
  535|      0|				XMP_StringPtr schemaName = currNS->first.c_str();
  536|      0|				if ( FindConstSchema ( &xmpObj.tree, schemaName ) != 0 ) continue;
  ------------------
  |  |  298|      0|#define FindConstSchema(t,u)	FindSchemaNode ( const_cast<XMP_Node*>(t), u, kXMP_ExistingOnly, 0 )
  |  |  ------------------
  |  |  |  |  296|      0|#define kXMP_ExistingOnly	false
  |  |  ------------------
  ------------------
  |  Branch (536:10): [True: 0, False: 0]
  ------------------
  537|      0|				info.tree.children.push_back ( IterNode ( kXMP_SchemaNode, schemaName, 0 ) );
  538|      0|				IterNode & iterSchema = info.tree.children.back();
  539|      0|				AddSchemaAliases ( info, iterSchema, schemaName );
  540|      0|				if ( iterSchema.children.empty() ) {
  ------------------
  |  Branch (540:10): [True: 0, False: 0]
  ------------------
  541|      0|					info.tree.children.pop_back();	// No aliases, remove the schema node.
  542|      0|				} else if ( info.options & kXMP_IterJustChildren ) {
  ------------------
  |  Branch (542:17): [True: 0, False: 0]
  ------------------
  543|      0|					iterSchema.children.clear();	// Get rid of the children.
  544|      0|				}
  545|      0|			}
  546|       |
  547|      0|		}
  548|       |
  549|  7.11k|	}
  550|       |	
  551|       |	// Set the current iteration position to the first node to be visited.
  552|       |	
  553|  10.4k|	info.currPos = info.tree.children.begin();
  554|  10.4k|	info.endPos  = info.tree.children.end();
  555|       |	
  556|  10.4k|	if ( (info.options & kXMP_IterJustChildren) && (info.currPos != info.endPos) && (*schemaNS != 0) ) {
  ------------------
  |  Branch (556:7): [True: 0, False: 10.4k]
  |  Branch (556:49): [True: 0, False: 0]
  |  Branch (556:82): [True: 0, False: 0]
  ------------------
  557|      0|		info.currPos->visitStage = kIter_VisitSelf;
  558|      0|	}
  559|       |
  560|       |	#if TraceIterators
  561|       |		if ( info.currPos == info.endPos ) {
  562|       |			printf ( "    ** Empty iteration **\n" );
  563|       |		} else {
  564|       |			printf ( "    Initial node %s, stage = %s, iterator @ %.8X\n",
  565|       |			         info.currPos->fullPath.c_str(), sStageNames[info.currPos->visitStage], this );
  566|       |		}
  567|       |	#endif
  568|       |	
  569|  10.4k|}	// XMPIterator for XMPMeta objects
_ZN11XMPIteratorD2Ev:
  591|  10.4k|{
  592|  10.4k|	XMP_Assert ( this->clientRefs <= 0 );
  ------------------
  |  |  142|  10.4k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  593|       |	// Let everything else default.
  594|       |	
  595|  10.4k|}	// ~XMPIterator
_ZN11XMPIterator4NextEPPKcPjS2_S3_S2_S3_S3_:
  617|   102k|{
  618|       |	// *** Lock the XMPMeta object if we ever stop using a full DLL lock.
  619|       |	
  620|       |	// ! NOTE: Supporting aliases throws in some nastiness with schemas. There might not be any XMP
  621|       |	// ! node for the schema, but we still have to visit it because of possible aliases.
  622|       |	
  623|   102k|	if ( info.currPos == info.endPos ) return false;	// Happens at the start of an empty iteration.
  ------------------
  |  Branch (623:7): [True: 3.07k, False: 99.7k]
  ------------------
  624|       |	
  625|       |	#if TraceIterators
  626|       |		printf ( "Next iteration from %s, stage = %s, iterator @ %.8X\n",
  627|       |			     info.currPos->fullPath.c_str(), sStageNames[info.currPos->visitStage], this );
  628|       |	#endif
  629|       |	
  630|  99.7k|	const XMP_Node * xmpNode = GetNextXMPNode ( info );
  631|  99.7k|	if ( xmpNode == 0 ) return false;
  ------------------
  |  Branch (631:7): [True: 6.97k, False: 92.7k]
  ------------------
  632|  92.7k|	bool isSchemaNode = XMP_NodeIsSchema ( info.currPos->options );
  633|       |	
  634|  92.7k|	if ( info.options & kXMP_IterJustLeafNodes ) {
  ------------------
  |  Branch (634:7): [True: 0, False: 92.7k]
  ------------------
  635|      0|		while ( isSchemaNode || (! xmpNode->children.empty()) ) {
  ------------------
  |  Branch (635:11): [True: 0, False: 0]
  |  Branch (635:27): [True: 0, False: 0]
  ------------------
  636|      0|			info.currPos->visitStage = kIter_VisitQualifiers;	// Skip to this node's children.
  637|      0|			xmpNode = GetNextXMPNode ( info );
  638|      0|			if ( xmpNode == 0 ) return false;
  ------------------
  |  Branch (638:9): [True: 0, False: 0]
  ------------------
  639|      0|			isSchemaNode = XMP_NodeIsSchema ( info.currPos->options );
  640|      0|		}
  641|      0|	}
  642|       |	
  643|  92.7k|	*schemaNS = info.currSchema.c_str();
  644|  92.7k|	*nsSize   = info.currSchema.size();
  645|       |
  646|  92.7k|	*propOptions = info.currPos->options;
  647|       |
  648|  92.7k|	*propPath  = "";
  649|  92.7k|	*pathSize  = 0;
  650|  92.7k|	*propValue = "";
  651|  92.7k|	*valueSize = 0;
  652|       |	
  653|  92.7k|	if ( ! (*propOptions & kXMP_SchemaNode) ) {
  ------------------
  |  Branch (653:7): [True: 83.9k, False: 8.77k]
  ------------------
  654|       |
  655|  83.9k|		*propPath = info.currPos->fullPath.c_str();
  656|  83.9k|		*pathSize = info.currPos->fullPath.size();
  657|  83.9k|		if ( info.options & kXMP_IterJustLeafName ) {
  ------------------
  |  Branch (657:8): [True: 0, False: 83.9k]
  ------------------
  658|      0|			*propPath += info.currPos->leafOffset;
  659|      0|			*pathSize -= info.currPos->leafOffset;
  660|      0|		}
  661|       |		
  662|  83.9k|		if ( ! (*propOptions & kXMP_PropCompositeMask) ) {
  ------------------
  |  Branch (662:8): [True: 73.2k, False: 10.7k]
  ------------------
  663|  73.2k|			*propValue = xmpNode->value.c_str();
  664|  73.2k|			*valueSize = xmpNode->value.size();
  665|  73.2k|		}
  666|       |
  667|  83.9k|	}
  668|       |	
  669|       |	#if TraceIterators
  670|       |		printf ( "    Next node %s, stage = %s\n",
  671|       |			     info.currPos->fullPath.c_str(), sStageNames[info.currPos->visitStage] );
  672|       |	#endif
  673|       |	
  674|  92.7k|	return true;
  675|       |
  676|  92.7k|}	// Next
_ZN11XMPIterator10UnlockIterEj:
  729|  92.7k|{
  730|  92.7k|	UNUSED(options);
  731|       |
  732|  92.7k|	XMPMeta::Unlock ( 0 );
  733|       |	
  734|  92.7k|}	// UnlockIter
XMPIterator.cpp:_ZL13SetCurrSchemaR8IterInfoPKc:
  181|  3.29k|{
  182|       |
  183|  3.29k|	info.currSchema = schemaName;
  184|       |	#if 0	// *** XMP_DebugBuild
  185|       |		info._schemaPtr = info.currSchema.c_str();
  186|       |	#endif
  187|       |
  188|  3.29k|}	// SetCurrSchema
XMPIterator.cpp:_ZL16AddNodeOffspringR8IterInfoR8IterNodePK8XMP_Node:
  114|  83.9k|{
  115|  83.9k|	XMP_VarString currPath ( iterParent.fullPath );
  116|  83.9k|	size_t        leafOffset = iterParent.fullPath.size();
  117|       |	
  118|  83.9k|	if ( (! xmpParent->qualifiers.empty()) && (! (info.options & kXMP_IterOmitQualifiers)) ) {
  ------------------
  |  Branch (118:7): [True: 3.38k, False: 80.5k]
  |  Branch (118:44): [True: 3.38k, False: 0]
  ------------------
  119|       |
  120|       |		#if TraceIterators
  121|       |			printf ( "    Adding qualifiers of %s\n", currPath.c_str() );
  122|       |		#endif
  123|       |
  124|  3.38k|		currPath += "/?";	// All qualifiers are named and use paths like "Prop/?Qual".
  125|  3.38k|		leafOffset += 2;
  126|       |		
  127|  12.3k|		for ( size_t qualNum = 0, qualLim = xmpParent->qualifiers.size(); qualNum != qualLim; ++qualNum ) {
  ------------------
  |  Branch (127:69): [True: 9.00k, False: 3.38k]
  ------------------
  128|  9.00k|			const XMP_Node * xmpQual = xmpParent->qualifiers[qualNum];
  129|  9.00k|			currPath += xmpQual->name;
  130|  9.00k|			iterParent.qualifiers.push_back ( IterNode ( xmpQual->options, currPath, leafOffset ) );
  131|  9.00k|			currPath.erase ( leafOffset );
  132|       |			#if TraceIterators
  133|       |				printf ( "        %s\n", xmpQual->name.c_str() );
  134|       |			#endif
  135|  9.00k|		}
  136|       |		
  137|  3.38k|		leafOffset -= 2;
  138|  3.38k|		currPath.erase ( leafOffset );
  139|       |
  140|  3.38k|	}
  141|       |
  142|  83.9k|	if ( ! xmpParent->children.empty() ) {
  ------------------
  |  Branch (142:7): [True: 10.6k, False: 73.2k]
  ------------------
  143|       |	
  144|       |		#if TraceIterators
  145|       |			printf ( "    Adding children of %s\n", currPath.c_str() );
  146|       |		#endif
  147|       |
  148|  10.6k|		XMP_Assert ( xmpParent->options & kXMP_PropCompositeMask );
  ------------------
  |  |  142|  10.6k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  149|       |		
  150|  10.6k|		if ( xmpParent->options & kXMP_PropValueIsStruct ) {
  ------------------
  |  Branch (150:8): [True: 2.96k, False: 7.72k]
  ------------------
  151|  2.96k|			currPath += '/';
  152|  2.96k|			leafOffset += 1;
  153|  2.96k|		}
  154|       |		
  155|  67.6k|		for ( size_t childNum = 0, childLim = xmpParent->children.size(); childNum != childLim; ++childNum ) {
  ------------------
  |  Branch (155:69): [True: 56.9k, False: 10.6k]
  ------------------
  156|  56.9k|			const XMP_Node * xmpChild = xmpParent->children[childNum];
  157|  56.9k|			if ( ! (xmpParent->options & kXMP_PropValueIsArray) ) {
  ------------------
  |  Branch (157:9): [True: 22.9k, False: 34.0k]
  ------------------
  158|  22.9k|				currPath += xmpChild->name;
  159|  34.0k|			} else {
  160|  34.0k|				char buffer [32];	// AUDIT: Using sizeof(buffer) below for snprintf length is safe.
  161|  34.0k|				snprintf ( buffer, sizeof(buffer), "[%lu]", static_cast<unsigned long>(childNum+1) );	// ! XPath indices are one-based.
  162|  34.0k|				currPath += buffer;
  163|  34.0k|			}
  164|  56.9k|			iterParent.children.push_back ( IterNode ( xmpChild->options, currPath, leafOffset ) );
  165|  56.9k|			currPath.erase ( leafOffset );
  166|       |			#if TraceIterators
  167|       |				printf ( "        %s\n", (iterParent.children.back().fullPath.c_str() + leafOffset) );
  168|       |			#endif
  169|  56.9k|		}
  170|       |	
  171|  10.6k|	}
  172|       |
  173|  83.9k|}	// AddNodeOffspring
XMPIterator.cpp:_ZL14AddSchemaPropsR8IterInfoR8IterNodePK8XMP_Node:
   48|  8.82k|{
   49|  8.82k|	UNUSED(info);
   50|       |	#if TraceIterators
   51|       |		printf ( "    Adding properties of %s\n", xmpSchema->name.c_str() );
   52|       |	#endif
   53|       |
   54|  28.9k|	for ( size_t propNum = 0, propLim = xmpSchema->children.size(); propNum != propLim; ++propNum ) {
  ------------------
  |  Branch (54:66): [True: 20.1k, False: 8.82k]
  ------------------
   55|  20.1k|		const XMP_Node * xmpProp = xmpSchema->children[propNum];
   56|       |		// *** set the has-aliases bit when appropriate
   57|  20.1k|		iterSchema.children.push_back ( IterNode ( xmpProp->options, xmpProp->name, 0 ) );
   58|       |		#if TraceIterators
   59|       |			printf ( "        %s\n", xmpProp->name.c_str() );
   60|       |		#endif
   61|  20.1k|	}
   62|       |
   63|  8.82k|}	// AddSchemaProps
XMPIterator.cpp:_ZL14GetNextXMPNodeR8IterInfo:
  308|  99.7k|{
  309|  99.7k|	const XMP_Node * xmpNode = 0;
  310|       |
  311|       |	// ----------------------------------------------------------------------------------------------
  312|       |	// On entry currPos points to an iteration node whose state is either before-visit or visit-self.
  313|       |	// If it is before-visit then we will return that node's value part now. If it is visit-self it
  314|       |	// means the previous iteration returned the value portion of that node, so we can advance to the
  315|       |	// next node in the iteration tree. Then we find the corresponding XMP node, allowing for the XMP
  316|       |	// tree to have been modified since that part of the iteration tree was constructed.
  317|       |	
  318|       |	// ! NOTE: Supporting aliases throws in some nastiness with schemas. There might not be any XMP
  319|       |	// ! node for the schema, but we still have to visit it because of possible aliases. The static
  320|       |	// ! sDummySchema is returned if there is no real schema node.
  321|       |
  322|  99.7k|	if ( info.currPos->visitStage != kIter_BeforeVisit ) AdvanceIterPos ( info );
  ------------------
  |  Branch (322:7): [True: 92.3k, False: 7.33k]
  ------------------
  323|       |	
  324|  99.7k|	bool isSchemaNode = false;
  325|  99.7k|	XMP_ExpandedXPath expPath;	// Keep outside the loop to avoid constant construct/destruct.
  326|       |	
  327|  99.7k|	while ( info.currPos != info.endPos ) {
  ------------------
  |  Branch (327:10): [True: 92.7k, False: 6.99k]
  ------------------
  328|       |
  329|  92.7k|		isSchemaNode = XMP_NodeIsSchema ( info.currPos->options );
  330|  92.7k|		if ( isSchemaNode ) {
  ------------------
  |  Branch (330:8): [True: 8.75k, False: 83.9k]
  ------------------
  331|  8.75k|			SetCurrSchema ( info, info.currPos->fullPath );
  332|  8.75k|			xmpNode = FindConstSchema ( &info.xmpObj->tree, info.currPos->fullPath.c_str() );
  ------------------
  |  |  298|  8.75k|#define FindConstSchema(t,u)	FindSchemaNode ( const_cast<XMP_Node*>(t), u, kXMP_ExistingOnly, 0 )
  |  |  ------------------
  |  |  |  |  296|  8.75k|#define kXMP_ExistingOnly	false
  |  |  ------------------
  ------------------
  333|  8.75k|			if ( xmpNode == 0 ) xmpNode = sDummySchema;
  ------------------
  |  Branch (333:9): [True: 0, False: 8.75k]
  ------------------
  334|  83.9k|		} else {
  335|  83.9k|			ExpandXPath ( info.currSchema.c_str(), info.currPos->fullPath.c_str(), &expPath );
  336|  83.9k|			xmpNode = FindConstNode ( &info.xmpObj->tree, expPath );
  ------------------
  |  |  301|  83.9k|#define FindConstNode(t,p)		FindNode ( const_cast<XMP_Node*>(t), p, kXMP_ExistingOnly, 0 )
  |  |  ------------------
  |  |  |  |  296|  83.9k|#define kXMP_ExistingOnly	false
  |  |  ------------------
  ------------------
  337|  83.9k|		}
  338|  92.7k|		if ( xmpNode != 0 ) break;	// Exit the loop, we found a live XMP node.
  ------------------
  |  Branch (338:8): [True: 92.7k, False: 18]
  ------------------
  339|       |
  340|     18|		info.currPos->visitStage = kIter_VisitChildren;	// Make AdvanceIterPos move to the next sibling.
  341|     18|		info.currPos->children.clear();
  342|     18|		info.currPos->qualifiers.clear();
  343|     18|		AdvanceIterPos ( info );
  344|       |
  345|     18|	}
  346|       |
  347|  99.7k|	if ( info.currPos == info.endPos ) return 0;
  ------------------
  |  Branch (347:7): [True: 6.97k, False: 92.7k]
  ------------------
  348|       |	
  349|       |	// -------------------------------------------------------------------------------------------
  350|       |	// Now we've got the iteration node and corresponding XMP node. Add the iteration children for
  351|       |	// structs and arrays. The children of schema were added when the iterator was constructed.
  352|       |
  353|  92.7k|	XMP_Assert ( info.currPos->visitStage == kIter_BeforeVisit );
  ------------------
  |  |  142|  92.7k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  354|       |
  355|  92.7k|	if ( info.currPos->visitStage == kIter_BeforeVisit ) {
  ------------------
  |  Branch (355:7): [True: 92.7k, False: 18]
  ------------------
  356|  92.7k|		if ( (! isSchemaNode) && (! (info.options & kXMP_IterJustChildren)) ) {
  ------------------
  |  Branch (356:8): [True: 83.9k, False: 8.75k]
  |  Branch (356:28): [True: 83.9k, False: 0]
  ------------------
  357|  83.9k|			AddNodeOffspring ( info, *info.currPos, xmpNode );
  358|  83.9k|		}
  359|  92.7k|		info.currPos->visitStage = kIter_VisitSelf;
  360|  92.7k|	}
  361|       |	
  362|  92.7k|	return xmpNode;
  363|       |
  364|  99.7k|}	// GetNextXMPNode
XMPIterator.cpp:_ZL13SetCurrSchemaR8IterInfoRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  192|  13.4k|{
  193|       |
  194|  13.4k|	info.currSchema = schemaName;
  195|       |	#if 0	// *** XMP_DebugBuild
  196|       |		info._schemaPtr = info.currSchema.c_str();
  197|       |	#endif
  198|       |
  199|  13.4k|}	// SetCurrSchema
XMPIterator.cpp:_ZL14AdvanceIterPosR8IterInfo:
  212|  92.3k|{
  213|       |	// -------------------------------------------------------------------------------------------
  214|       |	// Keep looking until we find a node to visit or the end of everything. The first time through
  215|       |	// the current node will exist, we just visited it. But we have to keep looking if the current
  216|       |	// node was the last of its siblings or is an empty schema.
  217|       |	
  218|       |	// ! It is possible that info.currPos == info.endPos on entry. Don't dereference info.currPos yet!
  219|       |
  220|   206k|	while ( true ) {
  ------------------
  |  Branch (220:10): [True: 206k, Folded]
  ------------------
  221|       |	
  222|   206k|		if ( info.currPos == info.endPos ) {
  ------------------
  |  Branch (222:8): [True: 29.1k, False: 177k]
  ------------------
  223|       |		
  224|       |			// ------------------------------------------------------------------------------------
  225|       |			// At the end of a set of siblings, move up to an ancestor. We've either just finished
  226|       |			// the qualifiers and will move to the children, or have just finished the children and
  227|       |			// will move on to the next sibling.
  228|       |			
  229|  29.1k|			if ( info.ancestors.empty() ) break;	// We're at the end of the schema list.
  ------------------
  |  Branch (229:9): [True: 6.97k, False: 22.1k]
  ------------------
  230|       |
  231|  22.1k|			IterPosPair & parent = info.ancestors.back();
  232|  22.1k|			info.currPos = parent.first;
  233|  22.1k|			info.endPos  = parent.second;
  234|  22.1k|			info.ancestors.pop_back();
  235|       |			
  236|       |			#if TraceIterators
  237|       |				printf ( "    Moved up to %s, stage = %s\n",
  238|       |				         info.currPos->fullPath.c_str(), sStageNames[info.currPos->visitStage] );
  239|       |			#endif
  240|       |		
  241|   177k|		} else {
  242|       |			
  243|       |			// -------------------------------------------------------------------------------------------
  244|       |			// Decide what to do with this iteration node based on its state. Don't use a switch statement,
  245|       |			// some of the cases want to break from the loop. A break in a switch just exits the case.
  246|       |			
  247|       |			#if TraceIterators
  248|       |				printf ( "    Moving from %s, stage = %s\n",
  249|       |				         info.currPos->fullPath.c_str(), sStageNames[info.currPos->visitStage] );
  250|       |			#endif
  251|       |			
  252|   177k|			if ( info.currPos->visitStage == kIter_BeforeVisit ) {		// Visit this node now.
  ------------------
  |  Branch (252:9): [True: 62.9k, False: 114k]
  ------------------
  253|  62.9k|				if ( info.currPos->options & kXMP_SchemaNode ) SetCurrSchema ( info, info.currPos->fullPath );
  ------------------
  |  Branch (253:10): [True: 4.71k, False: 58.2k]
  ------------------
  254|  62.9k|				break;
  255|  62.9k|			}
  256|       |
  257|   114k|			if ( info.currPos->visitStage == kIter_VisitSelf ) {		// Just finished visiting the value portion.
  ------------------
  |  Branch (257:9): [True: 92.3k, False: 22.1k]
  ------------------
  258|  92.3k|				info.currPos->visitStage = kIter_VisitQualifiers;		// Start visiting the qualifiers.
  259|  92.3k|				if ( ! info.currPos->qualifiers.empty() ) {
  ------------------
  |  Branch (259:10): [True: 3.32k, False: 89.0k]
  ------------------
  260|  3.32k|					info.ancestors.push_back ( IterPosPair ( info.currPos, info.endPos ) );
  261|  3.32k|					info.endPos  = info.currPos->qualifiers.end();		// ! Set the parent's endPos before changing currPos!
  262|  3.32k|					info.currPos = info.currPos->qualifiers.begin();
  263|  3.32k|					break;
  264|  3.32k|				}
  265|  92.3k|			}
  266|       |
  267|   111k|			if ( info.currPos->visitStage == kIter_VisitQualifiers ) {	// Just finished visiting the qualifiers.
  ------------------
  |  Branch (267:9): [True: 92.3k, False: 18.8k]
  ------------------
  268|  92.3k|				info.currPos->qualifiers.clear();
  269|  92.3k|				info.currPos->visitStage = kIter_VisitChildren;			// Start visiting the children.
  270|  92.3k|				if ( ! info.currPos->children.empty() ) {
  ------------------
  |  Branch (270:10): [True: 19.1k, False: 73.2k]
  ------------------
  271|  19.1k|					info.ancestors.push_back ( IterPosPair ( info.currPos, info.endPos ) );
  272|  19.1k|					info.endPos  = info.currPos->children.end();		// ! Set the parent's endPos before changing currPos!
  273|  19.1k|					info.currPos = info.currPos->children.begin();
  274|  19.1k|					break;
  275|  19.1k|				}
  276|  92.3k|			}
  277|       |
  278|  92.0k|			if ( info.currPos->visitStage == kIter_VisitChildren ) {	// Just finished visiting the children.
  ------------------
  |  Branch (278:9): [True: 92.0k, False: 0]
  ------------------
  279|  92.0k|				info.currPos->children.clear();
  280|  92.0k|				++info.currPos;											// Move to the next sibling.
  281|  92.0k|				continue;
  282|  92.0k|			}
  283|       |			
  284|       |			#if TraceIterators
  285|       |				if ( info.currPos != info.endPos ) {
  286|       |					printf ( "    Moved to %s, stage = %s\n",
  287|       |					         info.currPos->fullPath.c_str(), sStageNames[info.currPos->visitStage] );
  288|       |				}
  289|       |			#endif
  290|       |			
  291|  92.0k|		}
  292|       |
  293|   206k|	}	// Loop to find the next node.
  294|       |	
  295|  92.3k|	XMP_Assert ( (info.currPos == info.endPos) || (info.currPos->visitStage == kIter_BeforeVisit) );
  ------------------
  |  |  142|  92.3k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  296|       |
  297|  92.3k|}	// AdvanceIterPos

_ZN8IterNodeC2Ev:
   43|  10.4k|	IterNode() : options(0), leafOffset(0), visitStage(kIter_BeforeVisit)
   44|  10.4k|	{
   45|       |		#if 0	// *** XMP_DebugBuild
   46|       |			_pathPtr = _leafPtr = 0;
   47|       |		#endif
   48|  10.4k|	};
_ZN8IterNodeC2EjRKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEm:
   51|  98.2k|			 : options(_options), fullPath(_fullPath), leafOffset(_leafOffset), visitStage(kIter_BeforeVisit)
   52|  98.2k|	{
   53|       |		#if 0	// *** XMP_DebugBuild
   54|       |			_pathPtr = fullPath.c_str();
   55|       |			_leafPtr = _pathPtr + leafOffset;
   56|       |		#endif
   57|  98.2k|	};
_ZN8IterInfoC2EjPK7XMPMeta:
   80|  10.4k|	IterInfo ( XMP_OptionBits _options, const XMPMeta * _xmpObj ) : options(_options), xmpObj(_xmpObj)
   81|  10.4k|	{
   82|       |		#if 0	// *** XMP_DebugBuild
   83|       |			_schemaPtr = 0;
   84|       |		#endif
   85|  10.4k|	};

_ZN7XMPMeta15ParseFromBufferEPKcjj:
 1096|  8.77k|{
 1097|  8.77k|	if ( (buffer == 0) && (xmpSize != 0) ) XMP_Throw ( "Null parse buffer", kXMPErr_BadParam );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1097:7): [True: 0, False: 8.77k]
  |  Branch (1097:24): [True: 0, False: 0]
  ------------------
 1098|  8.77k|	if ( xmpSize == kXMP_UseNullTermination ) xmpSize = strlen ( buffer );
  ------------------
  |  Branch (1098:7): [True: 0, False: 8.77k]
  ------------------
 1099|       |	
 1100|  8.77k|	const bool lastClientCall = ((options & kXMP_ParseMoreBuffers) == 0);	// *** Could use FlagIsSet & FlagIsClear macros.
 1101|       |	
 1102|  8.77k|	this->tree.ClearNode();	// Make sure the target XMP object is totally empty.
 1103|       |
 1104|  8.77k|	if ( this->xmlParser == 0 ) {
  ------------------
  |  Branch (1104:7): [True: 8.77k, False: 0]
  ------------------
 1105|  8.77k|		if ( (xmpSize == 0) && lastClientCall ) return;	// Tolerate empty parse. Expat complains if there are no XML elements.
  ------------------
  |  Branch (1105:8): [True: 0, False: 8.77k]
  |  Branch (1105:26): [True: 0, False: 0]
  ------------------
 1106|  8.77k|		this->xmlParser = XMP_NewExpatAdapter();
 1107|  8.77k|	}
 1108|       |	
 1109|  8.77k|	XMLParserAdapter& parser = *this->xmlParser;
 1110|       |	
 1111|       |	#if 0	// XMP_DebugBuild
 1112|       |		if ( parser.parseLog != 0 ) {
 1113|       |			char message [200];	// AUDIT: Using sizeof(message) below for snprintf length is safe.
 1114|       |			snprintf ( message, sizeof(message), "<!-- ParseFromBuffer, length = %d, options = %X%s -->",	// AUDIT: See above.
 1115|       |					   xmpSize, options, (lastClientCall ? " (last)" : "") );
 1116|       |			fwrite ( message, 1, strlen(message), parser.parseLog );
 1117|       |			fflush ( parser.parseLog );
 1118|       |		}
 1119|       |	#endif
 1120|       |		
 1121|  8.77k|	try {	// Cleanup the tree and xmlParser if anything fails.
 1122|       |	
 1123|       |		// Determine the character encoding before doing any real parsing. This is needed to do the
 1124|       |		// 8-bit special processing.
 1125|       |		
 1126|  8.77k|		if ( parser.charEncoding == XMP_OptionBits(-1) ) {
  ------------------
  |  Branch (1126:8): [True: 8.77k, False: 0]
  ------------------
 1127|       |
 1128|  8.77k|			if ( (parser.pendingCount == 0) && (xmpSize >= kXMLPendingInputMax) ) {
  ------------------
  |  Branch (1128:9): [True: 8.77k, False: 0]
  |  Branch (1128:39): [True: 8.70k, False: 75]
  ------------------
 1129|       |
 1130|       |				// This ought to be the common case, the first buffer is big enough.
 1131|  8.70k|				parser.charEncoding = DetermineInputEncoding ( (XMP_Uns8*)buffer, xmpSize );
 1132|       |
 1133|  8.70k|			} else {
 1134|       |			
 1135|       |				// Try to fill the pendingInput buffer before calling DetermineInputEncoding.
 1136|       |
 1137|     75|				size_t pendingOverlap = kXMLPendingInputMax - parser.pendingCount;
 1138|     75|				if ( pendingOverlap > xmpSize ) pendingOverlap = xmpSize;
  ------------------
  |  Branch (1138:10): [True: 75, False: 0]
  ------------------
 1139|       |
 1140|     75|				memcpy ( &parser.pendingInput[parser.pendingCount], buffer, pendingOverlap );	// AUDIT: Count is safe.
 1141|     75|				buffer += pendingOverlap;
 1142|     75|				xmpSize -= pendingOverlap;
 1143|     75|				parser.pendingCount += pendingOverlap;
 1144|       |
 1145|     75|				if ( (! lastClientCall) && (parser.pendingCount < kXMLPendingInputMax) ) return;
  ------------------
  |  Branch (1145:10): [True: 0, False: 75]
  |  Branch (1145:32): [True: 0, False: 0]
  ------------------
 1146|     75|				parser.charEncoding = DetermineInputEncoding ( parser.pendingInput, parser.pendingCount );
 1147|       |				
 1148|       |				#if Trace_ParsingHackery
 1149|       |					fprintf ( stderr, "XMP Character encoding is %d\n", parser.charEncoding );
 1150|       |				#endif
 1151|       |			
 1152|     75|			}
 1153|       |
 1154|  8.77k|		}
 1155|       |		
 1156|       |		// We have the character encoding. Process UTF-16 and UTF-32 as is. UTF-8 needs special
 1157|       |		// handling to take care of things like ISO Latin-1 or unescaped ASCII controls.
 1158|       |
 1159|  8.77k|		XMP_Assert ( parser.charEncoding != XMP_OptionBits(-1) );
  ------------------
  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1160|       |
 1161|  8.77k|		if ( parser.charEncoding != kXMP_EncodeUTF8 ) {
  ------------------
  |  Branch (1161:8): [True: 0, False: 8.77k]
  ------------------
 1162|       |		
 1163|      0|			if ( parser.pendingCount > 0 ) {
  ------------------
  |  Branch (1163:9): [True: 0, False: 0]
  ------------------
 1164|       |				// Might have pendingInput from the above portion to determine the character encoding.
 1165|      0|				parser.ParseBuffer ( parser.pendingInput, parser.pendingCount, false );
 1166|      0|			}
 1167|      0|			parser.ParseBuffer ( buffer, xmpSize, lastClientCall );
 1168|       |			
 1169|  8.77k|		} else {
 1170|       |
 1171|       |			#if Trace_ParsingHackery
 1172|       |				fprintf ( stderr, "Parsing %d bytes @ %.8X, %s, %d pending, context: %.8s\n",
 1173|       |						  xmpSize, buffer, (lastClientCall ? "last" : "not last"), parser.pendingCount, buffer );
 1174|       |			#endif
 1175|       |
 1176|       |			// The UTF-8 processing is a bit complex due to the need to tolerate ISO Latin-1 input.
 1177|       |			// This is done by scanning the input for byte sequences that are not valid UTF-8,
 1178|       |			// assuming they are Latin-1 characters in the range 0x80..0xFF. This requires saving a
 1179|       |			// pending input buffer to handle partial UTF-8 sequences at the end of a buffer.
 1180|       |			
 1181|  8.85k|			while ( parser.pendingCount > 0 ) {
  ------------------
  |  Branch (1181:12): [True: 75, False: 8.77k]
  ------------------
 1182|       |			
 1183|       |				// We've got some leftover input, process it first then continue with the current
 1184|       |				// buffer. Try to fill the pendingInput buffer before parsing further. We use a loop
 1185|       |				// for weird edge cases like a 2 byte input buffer, using 1 byte for pendingInput,
 1186|       |				// then having a partial UTF-8 end and need to absorb more.
 1187|       |				
 1188|     75|				size_t pendingOverlap = kXMLPendingInputMax - parser.pendingCount;
 1189|     75|				if ( pendingOverlap > xmpSize ) pendingOverlap = xmpSize;
  ------------------
  |  Branch (1189:10): [True: 75, False: 0]
  ------------------
 1190|       |				
 1191|     75|				memcpy ( &parser.pendingInput[parser.pendingCount], buffer, pendingOverlap );	// AUDIT: Count is safe.
 1192|     75|				parser.pendingCount += pendingOverlap;
 1193|     75|				buffer += pendingOverlap;
 1194|     75|				xmpSize -= pendingOverlap;
 1195|       |
 1196|     75|				if ( (! lastClientCall) && (parser.pendingCount < kXMLPendingInputMax) ) return;
  ------------------
  |  Branch (1196:10): [True: 0, False: 75]
  |  Branch (1196:32): [True: 0, False: 0]
  ------------------
 1197|     75|				size_t bytesDone = ProcessUTF8Portion ( &parser, parser.pendingInput, parser.pendingCount, lastClientCall );
 1198|     75|				size_t bytesLeft = parser.pendingCount - bytesDone;
 1199|       |
 1200|       |				#if Trace_ParsingHackery
 1201|       |					fprintf ( stderr, "   ProcessUTF8Portion handled %d pending bytes\n", bytesDone );
 1202|       |				#endif
 1203|       |				
 1204|     75|				if ( bytesDone == parser.pendingCount ) {
  ------------------
  |  Branch (1204:10): [True: 75, False: 0]
  ------------------
 1205|       |
 1206|       |					// Done with all of the pending input, move on to the current buffer.
 1207|     75|					parser.pendingCount = 0;
 1208|       |
 1209|     75|				} else if ( bytesLeft <= pendingOverlap ) {
  ------------------
  |  Branch (1209:17): [True: 0, False: 0]
  ------------------
 1210|       |
 1211|       |					// The leftover pending input all came from the current buffer. Exit this loop.
 1212|      0|					buffer -= bytesLeft;
 1213|      0|					xmpSize += bytesLeft;
 1214|      0|					parser.pendingCount = 0;
 1215|       |
 1216|      0|				} else if ( xmpSize > 0 ) {
  ------------------
  |  Branch (1216:17): [True: 0, False: 0]
  ------------------
 1217|       |
 1218|       |					// Pull more of the current buffer into the pending input and try again.
 1219|       |					// Backup by this pass's overlap so the loop entry code runs OK.
 1220|      0|					parser.pendingCount -= pendingOverlap;
 1221|      0|					buffer -= pendingOverlap;
 1222|      0|					xmpSize += pendingOverlap;
 1223|       |
 1224|      0|				} else {
 1225|       |
 1226|       |					// There is no more of the current buffer. Wait for more. Partial sequences at
 1227|       |					// the end of the last buffer should be treated as Latin-1 by ProcessUTF8Portion.
 1228|      0|					XMP_Assert ( ! lastClientCall );
  ------------------
  |  |  142|      0|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1229|      0|					parser.pendingCount = bytesLeft;
 1230|      0|					memcpy ( &parser.pendingInput[0], &parser.pendingInput[bytesDone], bytesLeft );	// AUDIT: Count is safe.
 1231|      0|					return;
 1232|       |
 1233|      0|				}
 1234|       |			
 1235|     75|			}
 1236|       |			
 1237|       |			// Done with the pending input, process the current buffer.
 1238|       |
 1239|  8.77k|			size_t bytesDone = ProcessUTF8Portion ( &parser, (XMP_Uns8*)buffer, xmpSize, lastClientCall );
 1240|       |
 1241|       |			#if Trace_ParsingHackery
 1242|       |				fprintf ( stderr, "   ProcessUTF8Portion handled %d additional bytes\n", bytesDone );
 1243|       |			#endif
 1244|       |			
 1245|  8.77k|			if ( bytesDone < xmpSize ) {
  ------------------
  |  Branch (1245:9): [True: 0, False: 8.77k]
  ------------------
 1246|       |
 1247|      0|				XMP_Assert ( ! lastClientCall );
  ------------------
  |  |  142|      0|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1248|      0|				size_t bytesLeft = xmpSize - bytesDone;
 1249|      0|				if ( bytesLeft > kXMLPendingInputMax ) XMP_Throw ( "Parser bytesLeft too large", kXMPErr_InternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1249:10): [True: 0, False: 0]
  ------------------
 1250|       |
 1251|      0|				memcpy ( parser.pendingInput, &buffer[bytesDone], bytesLeft );	// AUDIT: Count is safe.
 1252|      0|				parser.pendingCount = bytesLeft;
 1253|      0|				return;	// Wait for the next buffer.
 1254|       |
 1255|      0|			}
 1256|       |
 1257|  8.77k|		}
 1258|       |		
 1259|  8.77k|		if ( lastClientCall ) {
  ------------------
  |  Branch (1259:8): [True: 8.70k, False: 75]
  ------------------
 1260|       |		
 1261|       |			#if XMP_DebugBuild && DumpXMLParseTree
 1262|       |				if ( parser.parseLog == 0 ) parser.parseLog = stdout;
 1263|       |				DumpXMLTree ( parser.parseLog, parser.tree, 0 );
 1264|       |			#endif
 1265|       |
 1266|  8.70k|			const XML_Node * xmlRoot = FindRootNode ( this, *this->xmlParser, options );
 1267|       |
 1268|  8.70k|			if ( xmlRoot != 0 ) {
  ------------------
  |  Branch (1268:9): [True: 5.81k, False: 2.88k]
  ------------------
 1269|       |
 1270|  5.81k|				ProcessRDF ( &this->tree, *xmlRoot, options );
 1271|  5.81k|				NormalizeDCArrays ( &this->tree );
 1272|  5.81k|				if ( this->tree.options & kXMP_PropHasAliases ) MoveExplicitAliases ( &this->tree, options );
  ------------------
  |  Branch (1272:10): [True: 0, False: 5.81k]
  ------------------
 1273|  5.81k|				TouchUpDataModel ( this );
 1274|       |				
 1275|       |				// Delete empty schema nodes. Do this last, other cleanup can make empty schema.
 1276|  5.81k|				size_t schemaNum = 0;
 1277|  14.6k|				while ( schemaNum < this->tree.children.size() ) {
  ------------------
  |  Branch (1277:13): [True: 8.82k, False: 5.81k]
  ------------------
 1278|  8.82k|					XMP_Node * currSchema = this->tree.children[schemaNum];
 1279|  8.82k|					if ( currSchema->children.size() > 0 ) {
  ------------------
  |  Branch (1279:11): [True: 8.82k, False: 0]
  ------------------
 1280|  8.82k|						++schemaNum;
 1281|  8.82k|					} else {
 1282|      0|						delete this->tree.children[schemaNum];	// ! Delete the schema node itself.
 1283|      0|						this->tree.children.erase ( this->tree.children.begin() + schemaNum );
 1284|      0|					}
 1285|  8.82k|				}
 1286|       |				
 1287|  5.81k|			}
 1288|       |
 1289|  8.70k|			delete this->xmlParser;
 1290|  8.70k|			this->xmlParser = 0;
 1291|       |
 1292|  8.70k|		}
 1293|       |		
 1294|  8.77k|	} catch ( ... ) {
 1295|       |
 1296|  1.66k|		delete this->xmlParser;
 1297|  1.66k|		this->xmlParser = 0;
 1298|  1.66k|		prevTkVer = 0;
 1299|  1.66k|		this->tree.ClearNode();
 1300|  1.66k|		throw;
 1301|       |
 1302|  1.66k|	}
 1303|       |	
 1304|  8.77k|}	// ParseFromBuffer
XMPMeta-Parse.cpp:_ZL22DetermineInputEncodingPKhm:
  810|  8.77k|{
  811|  8.77k|	if ( length < 2 ) return kXMP_EncodeUTF8;
  ------------------
  |  Branch (811:7): [True: 0, False: 8.77k]
  ------------------
  812|       |	
  813|  8.77k|	XMP_Uns8 * uniChar = (XMP_Uns8*)buffer;	// ! Make sure comparisons are unsigned.
  814|       |	
  815|  8.77k|	if ( uniChar[0] == 0 ) {
  ------------------
  |  Branch (815:7): [True: 0, False: 8.77k]
  ------------------
  816|       |	
  817|       |		// These cases are:
  818|       |		//   00 nn -- -- - Big endian UTF-16
  819|       |		//   00 00 00 nn - Big endian UTF-32
  820|       |		//   00 00 FE FF - Big endian UTF 32
  821|       |
  822|      0|		if ( (length < 4) || (uniChar[1] != 0) ) return kXMP_EncodeUTF16Big;
  ------------------
  |  Branch (822:8): [True: 0, False: 0]
  |  Branch (822:24): [True: 0, False: 0]
  ------------------
  823|      0|		return kXMP_EncodeUTF32Big;
  824|       |		
  825|  8.77k|	} else if ( uniChar[0] < 0x80 ) {
  ------------------
  |  Branch (825:14): [True: 8.77k, False: 0]
  ------------------
  826|       |	
  827|       |		// These cases are:
  828|       |		//   nn mm -- -- - UTF-8, includes EF BB BF case
  829|       |		//   nn 00 00 00 - Little endian UTF-32
  830|       |		//   nn 00 -- -- - Little endian UTF-16
  831|       |
  832|  8.77k|		if ( uniChar[1] != 0 )  return kXMP_EncodeUTF8;
  ------------------
  |  Branch (832:8): [True: 8.77k, False: 0]
  ------------------
  833|      0|		if ( (length < 4) || (uniChar[2] != 0) ) return kXMP_EncodeUTF16Little;
  ------------------
  |  Branch (833:8): [True: 0, False: 0]
  |  Branch (833:24): [True: 0, False: 0]
  ------------------
  834|      0|		return kXMP_EncodeUTF32Little;
  835|       |
  836|      0|	} else {
  837|       |	
  838|       |		// These cases are:
  839|       |		//   EF BB BF -- - UTF-8
  840|       |		//   FE FF -- -- - Big endian UTF-16
  841|       |		//   FF FE 00 00 - Little endian UTF-32
  842|       |		//   FF FE -- -- - Little endian UTF-16
  843|       |
  844|      0|		if ( uniChar[0] == 0xEF ) return kXMP_EncodeUTF8;
  ------------------
  |  Branch (844:8): [True: 0, False: 0]
  ------------------
  845|      0|		if ( uniChar[0] == 0xFE ) return kXMP_EncodeUTF16Big;
  ------------------
  |  Branch (845:8): [True: 0, False: 0]
  ------------------
  846|      0|		if ( (length < 4) || (uniChar[2] != 0) ) return kXMP_EncodeUTF16Little;
  ------------------
  |  Branch (846:8): [True: 0, False: 0]
  |  Branch (846:24): [True: 0, False: 0]
  ------------------
  847|      0|		return kXMP_EncodeUTF32Little;
  848|       |
  849|      0|	}
  850|       |		
  851|  8.77k|}	// DetermineInputEncoding
XMPMeta-Parse.cpp:_ZL18ProcessUTF8PortionP16XMLParserAdapterPKhmb:
  976|  8.85k|{
  977|  8.85k|	const XMP_Uns8 * bufEnd = buffer + length;
  978|       |	
  979|  8.85k|	const XMP_Uns8 * spanEnd;
  980|       |
  981|       |	// `buffer` is copied into this std::string. If `buffer` only
  982|       |	// contains valid UTF-8 and no escape characters, then the copy
  983|       |	// will be identical to the original, but invalid characters are
  984|       |	// replaced - usually with a space character.  This std::string was
  985|       |	// added as a performance fix for:
  986|       |	// https://github.com/Exiv2/exiv2/security/advisories/GHSA-w8mv-g8qq-36mj
  987|       |	// Previously, the code was repeatedly calling
  988|       |	// `xmlParser->ParseBuffer()`, which turned out to have quadratic
  989|       |	// complexity, because expat kept reparsing the entire string from
  990|       |	// the beginning.
  991|  8.85k|	std::string copy;
  992|       |		
  993|  37.1M|	for ( spanEnd = buffer; spanEnd < bufEnd; ++spanEnd ) {
  ------------------
  |  Branch (993:26): [True: 37.1M, False: 8.85k]
  ------------------
  994|       |
  995|  37.1M|		if ( (0x20 <= *spanEnd) && (*spanEnd <= 0x7E) && (*spanEnd != '&') ) {
  ------------------
  |  Branch (995:8): [True: 36.8M, False: 250k]
  |  Branch (995:30): [True: 36.7M, False: 139k]
  |  Branch (995:52): [True: 36.0M, False: 671k]
  ------------------
  996|  36.0M|			copy.push_back(*spanEnd);
  997|  36.0M|			continue;	// A regular ASCII character.
  998|  36.0M|		}
  999|       |
 1000|  1.06M|		if ( *spanEnd >= 0x80 ) {
  ------------------
  |  Branch (1000:8): [True: 6.16k, False: 1.05M]
  ------------------
 1001|       |		
 1002|       |			// See if this is a multi-byte UTF-8 sequence, or a Latin-1 character to replace.
 1003|       |
 1004|  6.16k|			int uniLen = CountUTF8 ( spanEnd, bufEnd );
 1005|       |
 1006|  6.16k|			if ( uniLen > 0 ) {
  ------------------
  |  Branch (1006:9): [True: 6.16k, False: 0]
  ------------------
 1007|       |
 1008|       |				// A valid UTF-8 character, keep it as-is.
 1009|  6.16k|				copy.append((const char*)spanEnd, uniLen);
 1010|  6.16k|				spanEnd += uniLen - 1;	// ! The loop increment will put back the +1.
 1011|       |
 1012|  6.16k|			} else if ( (uniLen < 0) && (! last) ) {
  ------------------
  |  Branch (1012:16): [True: 0, False: 0]
  |  Branch (1012:32): [True: 0, False: 0]
  ------------------
 1013|       |
 1014|       |				// Have a partial UTF-8 character at the end of the buffer and more input coming.
 1015|      0|				xmlParser->ParseBuffer ( copy.c_str(), copy.size(), false );
 1016|      0|				return (spanEnd - buffer);
 1017|       |
 1018|      0|			} else {
 1019|       |
 1020|       |				// Not a valid UTF-8 sequence. Replace the first byte with the Latin-1 equivalent.
 1021|      0|				const char * replacement = kReplaceLatin1 [ *spanEnd - 0x80 ];
 1022|      0|				copy.append ( replacement );
 1023|       |
 1024|      0|			}
 1025|       |		
 1026|  1.05M|		} else if ( (*spanEnd < 0x20) || (*spanEnd == 0x7F) ) {
  ------------------
  |  Branch (1026:15): [True: 250k, False: 804k]
  |  Branch (1026:36): [True: 133k, False: 671k]
  ------------------
 1027|       |
 1028|       |			// Replace ASCII controls other than tab, LF, and CR with a space.
 1029|       |
 1030|   383k|			if ( (*spanEnd == kTab) || (*spanEnd == kLF) || (*spanEnd == kCR) ) {
  ------------------
  |  |  100|   383k|#define kTab ((char)0x09)
  ------------------
              			if ( (*spanEnd == kTab) || (*spanEnd == kLF) || (*spanEnd == kCR) ) {
  ------------------
  |  |  101|   376k|#define kLF ((char)0x0A)
  ------------------
              			if ( (*spanEnd == kTab) || (*spanEnd == kLF) || (*spanEnd == kCR) ) {
  ------------------
  |  |  102|   176k|#define kCR ((char)0x0D)
  ------------------
  |  Branch (1030:9): [True: 7.13k, False: 376k]
  |  Branch (1030:31): [True: 200k, False: 176k]
  |  Branch (1030:52): [True: 42.9k, False: 133k]
  ------------------
 1031|   250k|				copy.push_back(*spanEnd);
 1032|   250k|				continue;
 1033|   250k|			}
 1034|       |
 1035|   133k|			copy.push_back(' ');
 1036|       |		
 1037|   671k|		} else {
 1038|       |		
 1039|       |			// See if this is a numeric escape sequence for a prohibited ASCII control.
 1040|       |			
 1041|   671k|			XMP_Assert ( *spanEnd == '&' );
  ------------------
  |  |  142|   671k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1042|   671k|			int escLen = CountControlEscape ( spanEnd, bufEnd );
 1043|       |			
 1044|   671k|			if ( escLen < 0 ) {
  ------------------
  |  Branch (1044:9): [True: 124, False: 671k]
  ------------------
 1045|       |
 1046|       |				// Have a partial numeric escape in this buffer, wait for more input.
 1047|    124|				if ( last ) {
  ------------------
  |  Branch (1047:10): [True: 124, False: 0]
  ------------------
 1048|    124|					copy.push_back('&');
 1049|    124|					continue;	// No more buffers, not an escape, absorb as normal input.
 1050|    124|				}
 1051|      0|				xmlParser->ParseBuffer ( copy.c_str(), copy.size(), false );
 1052|      0|				return (spanEnd - buffer);
 1053|       |
 1054|   671k|			} else if ( escLen > 0 ) {
  ------------------
  |  Branch (1054:16): [True: 23.7k, False: 647k]
  ------------------
 1055|       |
 1056|       |				// Have a complete numeric escape to replace.
 1057|  23.7k|				copy.push_back(' ');
 1058|  23.7k|				spanEnd = spanEnd + escLen - 1;	// ! The loop continuation will increment spanEnd!
 1059|       |
 1060|   647k|			} else {
 1061|   647k|				copy.push_back('&');
 1062|   647k|			}
 1063|       |
 1064|   671k|		}
 1065|       |		
 1066|  1.06M|	}
 1067|       |	
 1068|  8.85k|	XMP_Assert ( spanEnd == bufEnd );
  ------------------
  |  |  142|  8.85k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1069|  8.85k|	copy.push_back(' ');
 1070|  8.85k|	xmlParser->ParseBuffer ( copy.c_str(), copy.size(), true );
 1071|  8.85k|	return length;
 1072|       |
 1073|  8.85k|}	// ProcessUTF8Portion
XMPMeta-Parse.cpp:_ZL9CountUTF8PKhS0_:
  867|  6.16k|{
  868|  6.16k|	XMP_Assert ( charStart < bufEnd );		// Catch this in debug builds.
  ------------------
  |  |  142|  6.16k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  869|  6.16k|	if ( charStart >= bufEnd ) return 0;	// Don't run-on in release builds.
  ------------------
  |  Branch (869:7): [True: 0, False: 6.16k]
  ------------------
  870|  6.16k|	if ( (*charStart & 0xC0) != 0xC0 ) return 0;	// Must have at least 2 high bits set.
  ------------------
  |  Branch (870:7): [True: 0, False: 6.16k]
  ------------------
  871|       |	
  872|  6.16k|	int byteCount = 2;
  873|  6.16k|	XMP_Uns8 firstByte = *charStart;
  874|  8.87k|	for ( firstByte = firstByte << 2; (firstByte & 0x80) != 0; firstByte = firstByte << 1 ) ++byteCount;
  ------------------
  |  Branch (874:36): [True: 2.71k, False: 6.16k]
  ------------------
  875|       |	
  876|  6.16k|	if ( (charStart + byteCount) > bufEnd ) return -byteCount;
  ------------------
  |  Branch (876:7): [True: 0, False: 6.16k]
  ------------------
  877|       |
  878|  15.0k|	for ( int i = 1; i < byteCount; ++i ) {
  ------------------
  |  Branch (878:19): [True: 8.87k, False: 6.16k]
  ------------------
  879|  8.87k|		if ( (charStart[i] & 0xC0) != 0x80 ) return 0;
  ------------------
  |  Branch (879:8): [True: 0, False: 8.87k]
  ------------------
  880|  8.87k|	}
  881|       |	
  882|  6.16k|	return byteCount;
  883|       |	
  884|  6.16k|}	// CountUTF8
XMPMeta-Parse.cpp:_ZL18CountControlEscapePKhS0_:
  897|   671k|{
  898|   671k|	XMP_Assert ( escStart < bufEnd );	// Catch this in debug builds.
  ------------------
  |  |  142|   671k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  899|   671k|	if ( escStart >= bufEnd ) return 0;	// Don't run-on in release builds.
  ------------------
  |  Branch (899:7): [True: 0, False: 671k]
  ------------------
  900|   671k|	XMP_Assert ( *escStart == '&' );
  ------------------
  |  |  142|   671k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  901|       |	
  902|   671k|	size_t tailLen = bufEnd - escStart;
  903|   671k|	if ( tailLen < 5 ) return -1;	// Don't need a more thorough check, we'll catch it on the next pass.
  ------------------
  |  Branch (903:7): [True: 124, False: 671k]
  ------------------
  904|       |	
  905|   671k|	if ( strncmp ( (char*)escStart, "&#x", 3 ) != 0 ) return 0;
  ------------------
  |  Branch (905:7): [True: 504k, False: 167k]
  ------------------
  906|       |	
  907|   167k|	XMP_Uns8 escValue = 0;
  908|   167k|	const XMP_Uns8 * escPos = escStart + 3;
  909|       |	
  910|   167k|	if ( ('0' <= *escPos) && (*escPos <= '9') ) {
  ------------------
  |  Branch (910:7): [True: 156k, False: 10.3k]
  |  Branch (910:27): [True: 2.59k, False: 154k]
  ------------------
  911|  2.59k|		escValue = *escPos - '0';
  912|  2.59k|		++escPos;
  913|   164k|	} else if ( ('A' <= *escPos) && (*escPos <= 'F') ) {
  ------------------
  |  Branch (913:14): [True: 149k, False: 15.0k]
  |  Branch (913:34): [True: 1.33k, False: 148k]
  ------------------
  914|  1.33k|		escValue = *escPos - 'A' + 10;
  915|  1.33k|		++escPos;
  916|   163k|	} else if ( ('a' <= *escPos) && (*escPos <= 'f') ) {
  ------------------
  |  Branch (916:14): [True: 141k, False: 22.0k]
  |  Branch (916:34): [True: 99.8k, False: 41.4k]
  ------------------
  917|  99.8k|		escValue = *escPos - 'a' + 10;
  918|  99.8k|		++escPos;
  919|  99.8k|	}
  920|       |	
  921|   167k|	if ( ('0' <= *escPos) && (*escPos <= '9') ) {
  ------------------
  |  Branch (921:7): [True: 133k, False: 34.1k]
  |  Branch (921:27): [True: 465, False: 132k]
  ------------------
  922|    465|		escValue = (escValue << 4) + (*escPos - '0');
  923|    465|		++escPos;
  924|   166k|	} else if ( ('A' <= *escPos) && (*escPos <= 'F') ) {
  ------------------
  |  Branch (924:14): [True: 123k, False: 43.2k]
  |  Branch (924:34): [True: 1.93k, False: 121k]
  ------------------
  925|  1.93k|		escValue = (escValue << 4) + (*escPos - 'A' + 10);
  926|  1.93k|		++escPos;
  927|   164k|	} else if ( ('a' <= *escPos) && (*escPos <= 'f') ) {
  ------------------
  |  Branch (927:14): [True: 114k, False: 50.2k]
  |  Branch (927:34): [True: 61.1k, False: 53.3k]
  ------------------
  928|  61.1k|		escValue = (escValue << 4) + (*escPos - 'a' + 10);
  929|  61.1k|		++escPos;
  930|  61.1k|	}
  931|       |	
  932|   167k|	if ( escPos == bufEnd ) return -1;	// Partial escape.
  ------------------
  |  Branch (932:7): [True: 0, False: 167k]
  ------------------
  933|   167k|	if ( *escPos != ';' ) return 0;
  ------------------
  |  Branch (933:7): [True: 137k, False: 29.8k]
  ------------------
  934|       |	
  935|  29.8k|	size_t escLen = escPos - escStart + 1;
  936|  29.8k|	if ( escLen < 5 ) return 0;	// ! Catch "&#x;".
  ------------------
  |  Branch (936:7): [True: 4.01k, False: 25.8k]
  ------------------
  937|       |	
  938|  25.8k|	if ( (escValue == kTab) || (escValue == kLF) || (escValue == kCR) ) return 0;	// An allowed escape.
  ------------------
  |  |  100|  25.8k|#define kTab ((char)0x09)
  ------------------
              	if ( (escValue == kTab) || (escValue == kLF) || (escValue == kCR) ) return 0;	// An allowed escape.
  ------------------
  |  |  101|  25.1k|#define kLF ((char)0x0A)
  ------------------
              	if ( (escValue == kTab) || (escValue == kLF) || (escValue == kCR) ) return 0;	// An allowed escape.
  ------------------
  |  |  102|  24.4k|#define kCR ((char)0x0D)
  ------------------
  |  Branch (938:7): [True: 720, False: 25.1k]
  |  Branch (938:29): [True: 724, False: 24.4k]
  |  Branch (938:50): [True: 642, False: 23.7k]
  ------------------
  939|       |	
  940|  23.7k|	return escLen;	// Found a full "prohibited" numeric escape.
  941|       |	
  942|  25.8k|}	// CountControlEscape
XMPMeta-Parse.cpp:_ZL12FindRootNodeP7XMPMetaRK16XMLParserAdapterj:
  151|  8.70k|{
  152|  8.70k|	const XML_Node * rootNode = xmlParser.rootNode;
  153|       |	
  154|  8.70k|	if ( xmlParser.rootCount > 1 ) rootNode = PickBestRoot ( xmlParser.tree, options );
  ------------------
  |  Branch (154:7): [True: 64, False: 8.63k]
  ------------------
  155|  8.70k|	if ( rootNode == 0 ) return 0;
  ------------------
  |  Branch (155:7): [True: 2.88k, False: 5.81k]
  ------------------
  156|       |	
  157|       |	// We have a root node. Try to extract previous toolkit version number.
  158|       |	
  159|  5.81k|	XMP_StringPtr verStr = "";
  160|       |	
  161|  5.81k|		XMP_Assert ( rootNode->name == "rdf:RDF" );
  ------------------
  |  |  142|  5.81k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  162|       |	
  163|  5.81k|		if ( (options & kXMP_RequireXMPMeta) &&
  ------------------
  |  Branch (163:8): [True: 0, False: 5.81k]
  ------------------
  164|      0|		     ((rootNode->parent == 0) ||
  ------------------
  |  Branch (164:9): [True: 0, False: 0]
  ------------------
  165|      0|		      ((rootNode->parent->name != "x:xmpmeta") && (rootNode->parent->name != "x:xapmeta"))) ) return 0;
  ------------------
  |  Branch (165:10): [True: 0, False: 0]
  |  Branch (165:53): [True: 0, False: 0]
  ------------------
  166|       |
  167|  7.47k|		for ( size_t attrNum = 0, attrLim = rootNode->parent->attrs.size(); attrNum < attrLim; ++attrNum ) {
  ------------------
  |  Branch (167:71): [True: 2.93k, False: 4.54k]
  ------------------
  168|  2.93k|			const XML_Node * currAttr =rootNode->parent->attrs[attrNum];
  169|  2.93k|			if ( (currAttr->name == "x:xmptk") || (currAttr->name == "x:xaptk") ) {
  ------------------
  |  Branch (169:9): [True: 1.09k, False: 1.84k]
  |  Branch (169:42): [True: 177, False: 1.66k]
  ------------------
  170|  1.27k|				verStr = currAttr->value.c_str();
  171|  1.27k|				break;
  172|  1.27k|			}
  173|  2.93k|		}
  174|       |		
  175|       |	// Decode the version number into MMmmuubbb digits. If any part is too big, peg it at 99 or 999.
  176|       |	
  177|  5.81k|	unsigned long part;
  178|  26.0k|	while ( (*verStr != 0) && ((*verStr < '0') || (*verStr > '9')) ) ++verStr;
  ------------------
  |  Branch (178:10): [True: 21.3k, False: 4.69k]
  |  Branch (178:29): [True: 4.41k, False: 16.9k]
  |  Branch (178:48): [True: 15.7k, False: 1.11k]
  ------------------
  179|       |	
  180|  5.81k|	part = 0;
  181|  9.06k|	while ( (*verStr != 0) && ('0' <= *verStr) && (*verStr <= '9') ) {
  ------------------
  |  Branch (181:10): [True: 4.37k, False: 4.69k]
  |  Branch (181:28): [True: 3.46k, False: 907]
  |  Branch (181:48): [True: 3.25k, False: 210]
  ------------------
  182|  3.25k|		part = (part * 10) + (*verStr - '0');
  183|  3.25k|		++verStr;
  184|  3.25k|	}
  185|  5.81k|	if ( part > 99 ) part = 99;
  ------------------
  |  Branch (185:7): [True: 91, False: 5.72k]
  ------------------
  186|  5.81k|	thiz->prevTkVer = part * 100*100*1000;
  187|       |	
  188|  5.81k|	part = 0;
  189|  5.81k|	if ( *verStr == '.' ) ++verStr;
  ------------------
  |  Branch (189:7): [True: 637, False: 5.17k]
  ------------------
  190|  7.99k|	while ( (*verStr != 0) && ('0' <= *verStr) && (*verStr <= '9') ) {
  ------------------
  |  Branch (190:10): [True: 3.30k, False: 4.69k]
  |  Branch (190:28): [True: 2.45k, False: 851]
  |  Branch (190:48): [True: 2.18k, False: 266]
  ------------------
  191|  2.18k|		part = (part * 10) + (*verStr - '0');
  192|  2.18k|		++verStr;
  193|  2.18k|	}
  194|  5.81k|	if ( part > 99 ) part = 99;
  ------------------
  |  Branch (194:7): [True: 55, False: 5.75k]
  ------------------
  195|  5.81k|	thiz->prevTkVer += part * 100*1000;
  196|       |	
  197|  5.81k|	part = 0;
  198|  5.81k|	if ( *verStr == '.' ) ++verStr;
  ------------------
  |  Branch (198:7): [True: 238, False: 5.57k]
  ------------------
  199|  6.74k|	while ( (*verStr != 0) && ('0' <= *verStr) && (*verStr <= '9') ) {
  ------------------
  |  Branch (199:10): [True: 2.04k, False: 4.69k]
  |  Branch (199:28): [True: 1.33k, False: 711]
  |  Branch (199:48): [True: 928, False: 406]
  ------------------
  200|    928|		part = (part * 10) + (*verStr - '0');
  201|    928|		++verStr;
  202|    928|	}
  203|  5.81k|	if ( part > 99 ) part = 99;
  ------------------
  |  Branch (203:7): [True: 31, False: 5.78k]
  ------------------
  204|  5.81k|	thiz->prevTkVer += part * 1000;
  205|       |	
  206|  5.81k|	part = 0;
  207|  5.81k|	if ( *verStr == '-' ) ++verStr;
  ------------------
  |  Branch (207:7): [True: 416, False: 5.39k]
  ------------------
  208|  6.74k|	while ( (*verStr != 0) && ('0' <= *verStr) && (*verStr <= '9') ) {
  ------------------
  |  Branch (208:10): [True: 2.05k, False: 4.69k]
  |  Branch (208:28): [True: 1.70k, False: 343]
  |  Branch (208:48): [True: 933, False: 774]
  ------------------
  209|    933|		part = (part * 10) + (*verStr - '0');
  210|    933|		++verStr;
  211|    933|	}
  212|  5.81k|	if ( part > 999 ) part = 999;
  ------------------
  |  Branch (212:7): [True: 23, False: 5.78k]
  ------------------
  213|  5.81k|	thiz->prevTkVer += part;
  214|       |	
  215|  5.81k|	return rootNode;
  216|       |	
  217|  5.81k|}	// FindRootNode
XMPMeta-Parse.cpp:_ZL12PickBestRootRK8XML_Nodej:
  111|    902|{
  112|       |
  113|       |	// Look among this parent's content for x:xmpmeta. The recursion for x:xmpmeta is broader than
  114|       |	// the strictly defined choice, but gives us smaller code.
  115|  5.42k|	for ( size_t childNum = 0, childLim = xmlParent.content.size(); childNum < childLim; ++childNum ) {
  ------------------
  |  Branch (115:66): [True: 4.60k, False: 820]
  ------------------
  116|  4.60k|		const XML_Node * childNode = xmlParent.content[childNum];
  117|  4.60k|		if ( childNode->kind != kElemNode ) continue;
  ------------------
  |  Branch (117:8): [True: 4.17k, False: 437]
  ------------------
  118|    437|		if ( (childNode->name == "x:xmpmeta") || (childNode->name == "x:xapmeta") ) return PickBestRoot ( *childNode, 0 );
  ------------------
  |  Branch (118:8): [True: 82, False: 355]
  |  Branch (118:44): [True: 0, False: 355]
  ------------------
  119|    437|	}
  120|       |	// Look among this parent's content for a bare rdf:RDF if that is allowed.
  121|    820|	if ( ! (options & kXMP_RequireXMPMeta) ) {
  ------------------
  |  Branch (121:7): [True: 820, False: 0]
  ------------------
  122|  3.83k|		for ( size_t childNum = 0, childLim = xmlParent.content.size(); childNum < childLim; ++childNum ) {
  ------------------
  |  Branch (122:67): [True: 3.06k, False: 767]
  ------------------
  123|  3.06k|			const XML_Node * childNode = xmlParent.content[childNum];
  124|  3.06k|			if ( childNode->kind != kElemNode ) continue;
  ------------------
  |  Branch (124:9): [True: 2.97k, False: 93]
  ------------------
  125|     93|			if ( childNode->name == "rdf:RDF" ) return childNode;
  ------------------
  |  Branch (125:9): [True: 53, False: 40]
  ------------------
  126|     93|		}
  127|    820|	}
  128|       |	
  129|       |	// Recurse into the content.
  130|  1.52k|	for ( size_t childNum = 0, childLim = xmlParent.content.size(); childNum < childLim; ++childNum ) {
  ------------------
  |  Branch (130:66): [True: 756, False: 766]
  ------------------
  131|    756|		const XML_Node * foundRoot = PickBestRoot ( *xmlParent.content[childNum], options );
  132|    756|		if ( foundRoot != 0 ) return foundRoot;
  ------------------
  |  Branch (132:8): [True: 1, False: 755]
  ------------------
  133|    756|	}
  134|       |	
  135|    766|	return 0;
  136|       |
  137|    767|}	// PickBestRoot
XMPMeta-Parse.cpp:_ZL17NormalizeDCArraysP8XMP_Node:
  231|  4.22k|{
  232|  4.22k|	XMP_Node * dcSchema = FindSchemaNode ( xmpTree, kXMP_NS_DC, kXMP_ExistingOnly );
  ------------------
  |  |  296|  4.22k|#define kXMP_ExistingOnly	false
  ------------------
  233|  4.22k|	if ( dcSchema == 0 ) return;
  ------------------
  |  Branch (233:7): [True: 3.64k, False: 582]
  ------------------
  234|       |	
  235|  2.04k|	for ( size_t propNum = 0, propLimit = dcSchema->children.size(); propNum < propLimit; ++propNum ) {
  ------------------
  |  Branch (235:67): [True: 1.46k, False: 582]
  ------------------
  236|  1.46k|		XMP_Node *     currProp  = dcSchema->children[propNum];
  237|  1.46k|		XMP_OptionBits arrayForm = 0;
  238|       |		
  239|  1.46k|		if ( ! XMP_PropIsSimple ( currProp->options ) ) continue;	// Nothing to do if not simple.
  ------------------
  |  Branch (239:8): [True: 887, False: 575]
  ------------------
  240|       |		
  241|    575|		if ( (currProp->name == "dc:creator" )     ||	// See if it is supposed to be an array.
  ------------------
  |  Branch (241:8): [True: 10, False: 565]
  ------------------
  242|    565|		     (currProp->name == "dc:date" ) ) {			// *** Think about an array of char* and a loop.
  ------------------
  |  Branch (242:8): [True: 20, False: 545]
  ------------------
  243|     30|			arrayForm = kXMP_PropArrayIsOrdered;
  244|    545|		} else if (
  245|    545|		     (currProp->name == "dc:description" ) ||
  ------------------
  |  Branch (245:8): [True: 2, False: 543]
  ------------------
  246|    543|		     (currProp->name == "dc:rights" )      ||
  ------------------
  |  Branch (246:8): [True: 100, False: 443]
  ------------------
  247|    443|		     (currProp->name == "dc:title" ) ) {
  ------------------
  |  Branch (247:8): [True: 2, False: 441]
  ------------------
  248|    104|			arrayForm = kXMP_PropArrayIsAltText;
  249|    441|		} else if (
  250|    441|		     (currProp->name == "dc:contributor" ) ||
  ------------------
  |  Branch (250:8): [True: 1, False: 440]
  ------------------
  251|    440|		     (currProp->name == "dc:language" )    ||
  ------------------
  |  Branch (251:8): [True: 10, False: 430]
  ------------------
  252|    430|		     (currProp->name == "dc:publisher" )   ||
  ------------------
  |  Branch (252:8): [True: 1, False: 429]
  ------------------
  253|    429|		     (currProp->name == "dc:relation" )    ||
  ------------------
  |  Branch (253:8): [True: 0, False: 429]
  ------------------
  254|    429|		     (currProp->name == "dc:subject" )     ||
  ------------------
  |  Branch (254:8): [True: 27, False: 402]
  ------------------
  255|    402|		     (currProp->name == "dc:type" ) ) {
  ------------------
  |  Branch (255:8): [True: 28, False: 374]
  ------------------
  256|     67|			arrayForm = kXMP_PropValueIsArray;
  257|     67|		}
  258|    575|		if ( arrayForm == 0 ) continue;	// Nothing to do if it isn't supposed to be an array.
  ------------------
  |  Branch (258:8): [True: 374, False: 201]
  ------------------
  259|       |		
  260|    201|		arrayForm = VerifySetOptions ( arrayForm, 0 );	// Set the implicit array bits.
  261|    201|		XMP_Node * newArray = new XMP_Node ( dcSchema, currProp->name.c_str(), arrayForm );
  262|    201|		dcSchema->children[propNum] = newArray;
  263|    201|		newArray->children.push_back ( currProp );
  264|    201|		currProp->parent = newArray;
  265|    201|		currProp->name = kXMP_ArrayItemName;
  ------------------
  |  |  293|    201|#define kXMP_ArrayItemName	"[]"
  ------------------
  266|       |		
  267|    201|		if ( XMP_ArrayIsAltText ( arrayForm ) && (! (currProp->options & kXMP_PropHasLang)) ) {
  ------------------
  |  Branch (267:8): [True: 104, False: 97]
  |  Branch (267:44): [True: 104, False: 0]
  ------------------
  268|    104|			XMP_Node * newLang = new XMP_Node ( currProp, "xml:lang", "x-default", kXMP_PropIsQualifier );
  269|    104|			currProp->options |= (kXMP_PropHasQualifiers | kXMP_PropHasLang);
  270|    104|			if ( currProp->qualifiers.empty() ) {	// *** Need a util?
  ------------------
  |  Branch (270:9): [True: 104, False: 0]
  ------------------
  271|    104|				currProp->qualifiers.push_back ( newLang );
  272|    104|			} else {
  273|      0|				currProp->qualifiers.insert ( currProp->qualifiers.begin(), newLang );
  274|      0|			}
  275|    104|		}
  276|       |
  277|    201|	}
  278|       |	
  279|    582|}	// NormalizeDCArrays
XMPMeta-Parse.cpp:_ZL16TouchUpDataModelP7XMPMeta:
  665|  4.22k|{
  666|  4.22k|	XMP_Node & tree = xmp->tree;
  667|       |	
  668|       |	// Do special case touch ups for certain schema.
  669|       |
  670|  4.22k|	XMP_Node * currSchema = 0;
  671|       |
  672|  4.22k|	currSchema = FindSchemaNode ( &tree, kXMP_NS_EXIF, kXMP_ExistingOnly );
  ------------------
  |  |  296|  4.22k|#define kXMP_ExistingOnly	false
  ------------------
  673|  4.22k|	if ( currSchema != 0 ) {
  ------------------
  |  Branch (673:7): [True: 1, False: 4.22k]
  ------------------
  674|       |
  675|       |		// Do a special case fix for exif:GPSTimeStamp.
  676|      1|		XMP_Node * gpsDateTime = FindChildNode ( currSchema, "exif:GPSTimeStamp", kXMP_ExistingOnly );
  ------------------
  |  |  296|      1|#define kXMP_ExistingOnly	false
  ------------------
  677|      1|		if ( gpsDateTime != 0 ) FixGPSTimeStamp ( currSchema, gpsDateTime );
  ------------------
  |  Branch (677:8): [True: 0, False: 1]
  ------------------
  678|       |	
  679|       |		// *** Should probably have RepairAltText change simple values to LangAlt with 'x-default' item.
  680|       |		// *** For now just do this for exif:UserComment, the one case we know about, late in cycle fix.
  681|      1|		XMP_Node * userComment = FindChildNode ( currSchema, "exif:UserComment", kXMP_ExistingOnly );
  ------------------
  |  |  296|      1|#define kXMP_ExistingOnly	false
  ------------------
  682|      1|		if ( (userComment != 0) && XMP_PropIsSimple ( userComment->options ) ) {
  ------------------
  |  Branch (682:8): [True: 0, False: 1]
  |  Branch (682:30): [True: 0, False: 0]
  ------------------
  683|      0|			XMP_Node * newChild = new XMP_Node ( userComment, kXMP_ArrayItemName,
  ------------------
  |  |  293|      0|#define kXMP_ArrayItemName	"[]"
  ------------------
  684|      0|												 userComment->value.c_str(), userComment->options );
  685|      0|			newChild->qualifiers.swap ( userComment->qualifiers );
  686|      0|			if ( ! XMP_PropHasLang ( newChild->options ) ) {
  ------------------
  |  Branch (686:9): [True: 0, False: 0]
  ------------------
  687|      0|				XMP_Node * langQual = new XMP_Node ( newChild, "xml:lang", "x-default", kXMP_PropIsQualifier );
  688|      0|				newChild->qualifiers.insert ( newChild->qualifiers.begin(), langQual );
  689|      0|				newChild->options |= (kXMP_PropHasQualifiers | kXMP_PropHasLang);
  690|      0|			}
  691|      0|			userComment->value.erase();
  692|      0|			userComment->options = kXMP_PropArrayFormMask;	// ! Happens to have all the right bits.
  693|      0|			userComment->children.push_back ( newChild );
  694|      0|		}
  695|       |
  696|      1|	}
  697|       |
  698|  4.22k|	currSchema = FindSchemaNode ( &tree, kXMP_NS_DM, kXMP_ExistingOnly );
  ------------------
  |  |  296|  4.22k|#define kXMP_ExistingOnly	false
  ------------------
  699|  4.22k|	if ( currSchema != 0 ) {
  ------------------
  |  Branch (699:7): [True: 29, False: 4.19k]
  ------------------
  700|       |		// Do a special case migration of xmpDM:copyright to dc:rights['x-default']. Do this before
  701|       |		// the dc: touch up since it can affect the dc: schema.
  702|     29|		XMP_Node * dmCopyright = FindChildNode ( currSchema, "xmpDM:copyright", kXMP_ExistingOnly );
  ------------------
  |  |  296|     29|#define kXMP_ExistingOnly	false
  ------------------
  703|     29|		if ( dmCopyright != 0 ) MigrateAudioCopyright ( xmp, dmCopyright );
  ------------------
  |  Branch (703:8): [True: 0, False: 29]
  ------------------
  704|     29|	}
  705|       |
  706|  4.22k|	currSchema = FindSchemaNode ( &tree, kXMP_NS_DC, kXMP_ExistingOnly );
  ------------------
  |  |  296|  4.22k|#define kXMP_ExistingOnly	false
  ------------------
  707|  4.22k|	if ( currSchema != 0 ) {
  ------------------
  |  Branch (707:7): [True: 582, False: 3.64k]
  ------------------
  708|       |		// Do a special case fix for dc:subject, make sure it is an unordered array.
  709|    582|		XMP_Node * dcSubject = FindChildNode ( currSchema, "dc:subject", kXMP_ExistingOnly );
  ------------------
  |  |  296|    582|#define kXMP_ExistingOnly	false
  ------------------
  710|    582|		if ( dcSubject != 0 ) {
  ------------------
  |  Branch (710:8): [True: 188, False: 394]
  ------------------
  711|    188|                        XMP_OptionBits keepMask = static_cast<XMP_OptionBits>(~(kXMP_PropArrayIsOrdered | kXMP_PropArrayIsAlternate | kXMP_PropArrayIsAltText));
  712|    188|			dcSubject->options &= keepMask;	// Make sure any ordered array bits are clear.
  713|    188|		}
  714|    582|	}
  715|       |	
  716|       |	// Fix any broken AltText arrays that we know about.
  717|       |	
  718|  4.22k|	RepairAltText ( tree, kXMP_NS_DC, "dc:description" );	// ! Note inclusion of prefixes for direct node lookup!
  719|  4.22k|	RepairAltText ( tree, kXMP_NS_DC, "dc:rights" );
  720|  4.22k|	RepairAltText ( tree, kXMP_NS_DC, "dc:title" );
  721|  4.22k|	RepairAltText ( tree, kXMP_NS_XMP_Rights, "xmpRights:UsageTerms" );
  722|  4.22k|	RepairAltText ( tree, kXMP_NS_EXIF, "exif:UserComment" );
  723|       |	
  724|       |	// Tweak old XMP: Move an instance ID from rdf:about to the xmpMM:InstanceID property. An old
  725|       |	// instance ID usually looks like "uuid:bac965c4-9d87-11d9-9a30-000d936b79c4", plus InDesign
  726|       |	// 3.0 wrote them like "bac965c4-9d87-11d9-9a30-000d936b79c4". If the name looks like a UUID
  727|       |	// simply move it to xmpMM:InstanceID, don't worry about any existing xmpMM:InstanceID. Both
  728|       |	// will only be present when a newer file with the xmpMM:InstanceID property is updated by an
  729|       |	// old app that uses rdf:about.
  730|       |	
  731|  4.22k|	if ( ! tree.name.empty() ) {
  ------------------
  |  Branch (731:7): [True: 517, False: 3.70k]
  ------------------
  732|       |
  733|    517|		bool nameIsUUID = false;
  734|    517|		XMP_StringPtr nameStr = tree.name.c_str();
  735|       |
  736|    517|		if ( XMP_LitNMatch ( nameStr, "uuid:", 5 ) ) {
  ------------------
  |  |   97|    517|#define XMP_LitNMatch(s,l,n)	(std::strncmp((s),(l),(n)) == 0)
  |  |  ------------------
  |  |  |  Branch (97:30): [True: 225, False: 292]
  |  |  ------------------
  ------------------
  737|       |
  738|    225|			nameIsUUID = true;
  739|       |
  740|    292|		} else if ( tree.name.size() == 36 ) {
  ------------------
  |  Branch (740:15): [True: 166, False: 126]
  ------------------
  741|       |
  742|    166|			nameIsUUID = true;	// ! Assume true, we'll set it to false below if not.
  743|  2.69k|			for ( int i = 0;  i < 36; ++i ) {
  ------------------
  |  Branch (743:22): [True: 2.67k, False: 18]
  ------------------
  744|  2.67k|				char ch = nameStr[i];
  745|  2.67k|				if ( ch == '-' ) {
  ------------------
  |  Branch (745:10): [True: 86, False: 2.58k]
  ------------------
  746|     86|					if ( (i == 8) || (i == 13) || (i == 18) || (i == 23) ) continue;
  ------------------
  |  Branch (746:11): [True: 19, False: 67]
  |  Branch (746:23): [True: 19, False: 48]
  |  Branch (746:36): [True: 10, False: 38]
  |  Branch (746:49): [True: 20, False: 18]
  ------------------
  747|     18|					nameIsUUID = false;
  748|     18|					break;
  749|  2.58k|				} else {
  750|  2.58k|					if ( (('0' <= ch) && (ch <= '9')) || (('a' <= ch) && (ch <= 'z')) ) continue;
  ------------------
  |  Branch (750:12): [True: 2.51k, False: 72]
  |  Branch (750:27): [True: 943, False: 1.57k]
  |  Branch (750:44): [True: 1.52k, False: 120]
  |  Branch (750:59): [True: 1.51k, False: 10]
  ------------------
  751|    130|					nameIsUUID = false;
  752|    130|					break;
  753|  2.58k|				}
  754|  2.67k|			}
  755|       |
  756|    166|		}
  757|       |		
  758|    517|		if ( nameIsUUID ) {
  ------------------
  |  Branch (758:8): [True: 243, False: 274]
  ------------------
  759|       |
  760|    243|			XMP_ExpandedXPath expPath;
  761|    243|			ExpandXPath ( kXMP_NS_XMP_MM, "InstanceID", &expPath );
  762|    243|			XMP_Node * idNode = FindNode ( &tree, expPath, kXMP_CreateNodes, 0 );
  ------------------
  |  |  295|    243|#define kXMP_CreateNodes	true
  ------------------
  763|    243|			if ( idNode == 0 ) XMP_Throw ( "Failure creating xmpMM:InstanceID", kXMPErr_InternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (763:9): [True: 0, False: 243]
  ------------------
  764|       |
  765|    243|			idNode->options = 0;	// Clobber any existing xmpMM:InstanceID.
  766|    243|			idNode->value = tree.name;
  767|    243|			idNode->RemoveChildren();
  768|    243|			idNode->RemoveQualifiers();
  769|       |
  770|    243|			tree.name.erase();
  771|       |
  772|    243|		}
  773|       |
  774|    517|	}
  775|       |
  776|  4.22k|}	// TouchUpDataModel
XMPMeta-Parse.cpp:_ZL13RepairAltTextR8XMP_NodePKcS2_:
  609|  21.1k|{
  610|  21.1k|	XMP_Node * schemaNode = FindSchemaNode ( &tree, schemaNS, kXMP_ExistingOnly );
  ------------------
  |  |  296|  21.1k|#define kXMP_ExistingOnly	false
  ------------------
  611|  21.1k|	if ( schemaNode == 0 ) return;
  ------------------
  |  Branch (611:7): [True: 19.2k, False: 1.89k]
  ------------------
  612|       |	
  613|  1.89k|	XMP_Node * arrayNode = FindChildNode ( schemaNode, arrayName, kXMP_ExistingOnly );
  ------------------
  |  |  296|  1.89k|#define kXMP_ExistingOnly	false
  ------------------
  614|  1.89k|	if ( (arrayNode == 0) || XMP_ArrayIsAltText ( arrayNode->options ) ) return;	// Already OK.
  ------------------
  |  Branch (614:7): [True: 1.12k, False: 766]
  |  Branch (614:27): [True: 697, False: 69]
  ------------------
  615|       |	
  616|     69|	if ( ! XMP_PropIsArray ( arrayNode->options ) ) return;	// ! Not even an array, leave it alone.
  ------------------
  |  Branch (616:7): [True: 1, False: 68]
  ------------------
  617|       |	// *** Should probably change simple values to LangAlt with 'x-default' item.
  618|       |	
  619|     68|	arrayNode->options |= (kXMP_PropArrayIsOrdered | kXMP_PropArrayIsAlternate | kXMP_PropArrayIsAltText);
  620|       |	
  621|    480|	for ( int i = arrayNode->children.size()-1; i >= 0; --i ) {	// ! Need a signed index type.
  ------------------
  |  Branch (621:46): [True: 412, False: 68]
  ------------------
  622|       |
  623|    412|		XMP_Node * currChild = arrayNode->children[i];
  624|       |
  625|    412|		if ( ! XMP_PropIsSimple ( currChild->options ) ) {
  ------------------
  |  Branch (625:8): [True: 4, False: 408]
  ------------------
  626|       |
  627|       |			// Delete non-simple children.
  628|      4|			delete ( currChild );
  629|      4|			arrayNode->children.erase ( arrayNode->children.begin() + i );
  630|       |
  631|    408|		} else if ( ! XMP_PropHasLang ( currChild->options ) ) {
  ------------------
  |  Branch (631:15): [True: 358, False: 50]
  ------------------
  632|       |		
  633|    358|			if ( currChild->value.empty() ) {
  ------------------
  |  Branch (633:9): [True: 7, False: 351]
  ------------------
  634|       |
  635|       |				// Delete empty valued children that have no xml:lang.
  636|      7|				delete ( currChild );
  637|      7|				arrayNode->children.erase ( arrayNode->children.begin() + i );
  638|       |
  639|    351|			} else {
  640|       |
  641|       |				// Add an xml:lang qualifier with the value "x-repair".
  642|    351|				XMP_Node * repairLang = new XMP_Node ( currChild, "xml:lang", "x-repair", kXMP_PropIsQualifier );
  643|    351|				if ( currChild->qualifiers.empty() ) {
  ------------------
  |  Branch (643:10): [True: 351, False: 0]
  ------------------
  644|    351|					currChild->qualifiers.push_back ( repairLang );
  645|    351|				} else {
  646|      0|					currChild->qualifiers.insert ( currChild->qualifiers.begin(), repairLang );
  647|      0|				}
  648|    351|				currChild->options |= (kXMP_PropHasQualifiers | kXMP_PropHasLang);
  649|       |
  650|    351|			}
  651|       |
  652|    358|		}
  653|       |
  654|    412|	}
  655|       |
  656|     68|}	// RepairAltText

_ZN7XMPMetaC2Ev:
  588|  8.77k|XMPMeta::XMPMeta() : clientRefs(0), prevTkVer(0), tree(XMP_Node(0,"",0)), xmlParser(0)
  589|  8.77k|{
  590|       |	// Nothing more to do, clientRefs is incremented in wrapper.
  591|       |	#if XMP_TraceCTorDTor
  592|       |		printf ( "Default construct XMPMeta @ %.8X\n", this );
  593|       |	#endif
  594|  8.77k|}	// XMPMeta
_ZN7XMPMetaD2Ev:
  599|  8.77k|{
  600|       |	#if XMP_TraceCTorDTor
  601|       |		printf ( "Destruct XMPMeta @ %.8X\n", this );
  602|       |	#endif
  603|       |
  604|  8.77k|	XMP_Assert ( this->clientRefs <= 0 );
  ------------------
  |  |  142|  8.77k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  605|  8.77k|	if ( xmlParser != 0 ) delete ( xmlParser );
  ------------------
  |  Branch (605:7): [True: 0, False: 8.77k]
  ------------------
  606|  8.77k|	xmlParser = 0;
  607|       |
  608|  8.77k|}	// ~XMPMeta
_ZN7XMPMeta10InitializeEv:
  644|      1|{
  645|       |	// Allocate and initialize static objects.
  646|       |	
  647|      1|	++sXMP_InitCount;
  648|      1|	if ( sXMP_InitCount > 1 ) return true;
  ------------------
  |  Branch (648:7): [True: 0, False: 1]
  ------------------
  649|       |	
  650|       |	#if TraceXMPCalls
  651|       |		// xmpOut = fopen ( "xmp.out", "w" );	// Coordinate with client glue in WXMP_Common.hpp
  652|       |		fprintf ( xmpOut, "XMP initializing\n" ); fflush ( xmpOut );
  653|       |	#endif
  654|       |	
  655|      1|	sExceptionMessage = new XMP_VarString();
  656|      1|	XMP_InitMutex ( &sXMPCoreLock );
  657|      1|    sOutputNS  = new XMP_VarString;
  658|      1|    sOutputStr = new XMP_VarString;
  659|       |
  660|      1|	xdefaultName = new XMP_VarString ( "x-default" );
  661|       |	
  662|      1|	sNamespaceURIToPrefixMap	= new XMP_StringMap;
  663|      1|	sNamespacePrefixToURIMap	= new XMP_StringMap;
  664|      1|	sRegisteredAliasMap			= new XMP_AliasMap;
  665|       |	
  666|      1|	InitializeUnicodeConversions();
  667|       |	
  668|       |	// Register standard namespaces and aliases.
  669|      1|	RegisterNamespace ( kXMP_NS_XML, "xml" );
  670|      1|	RegisterNamespace ( kXMP_NS_RDF, "rdf" );
  671|      1|	RegisterNamespace ( kXMP_NS_DC, "dc" );
  672|       |
  673|      1|	RegisterNamespace ( kXMP_NS_XMP, "xmp" );
  674|      1|	RegisterNamespace ( kXMP_NS_PDF, "pdf" );
  675|      1|	RegisterNamespace ( kXMP_NS_Photoshop, "photoshop" );
  676|      1|	RegisterNamespace ( kXMP_NS_PSAlbum, "album" );
  677|      1|	RegisterNamespace ( kXMP_NS_EXIF, "exif" );
  678|      1|	RegisterNamespace ( kXMP_NS_EXIF_Aux, "aux" );
  679|      1|	RegisterNamespace ( kXMP_NS_TIFF, "tiff" );
  680|      1|	RegisterNamespace ( kXMP_NS_PNG, "png" );
  681|      1|	RegisterNamespace ( kXMP_NS_JPEG, "jpeg" );
  682|      1|	RegisterNamespace ( kXMP_NS_JP2K, "jp2k" );
  683|      1|	RegisterNamespace ( kXMP_NS_CameraRaw, "crs" );
  684|      1|	RegisterNamespace ( kXMP_NS_ASF, "asf" );
  685|      1|	RegisterNamespace ( kXMP_NS_WAV, "wav" );
  686|       |
  687|      1|	RegisterNamespace ( kXMP_NS_AdobeStockPhoto, "bmsp" );
  688|      1|	RegisterNamespace ( kXMP_NS_CreatorAtom, "creatorAtom" );
  689|       |
  690|      1|	RegisterNamespace ( kXMP_NS_XMP_Rights, "xmpRights" );
  691|      1|	RegisterNamespace ( kXMP_NS_XMP_MM, "xmpMM" );
  692|      1|	RegisterNamespace ( kXMP_NS_XMP_BJ, "xmpBJ" );
  693|      1|	RegisterNamespace ( kXMP_NS_XMP_Note, "xmpNote" );
  694|       |
  695|      1|	RegisterNamespace ( kXMP_NS_DM, "xmpDM" );
  696|      1|	RegisterNamespace ( kXMP_NS_XMP_Text, "xmpT" );
  697|      1|	RegisterNamespace ( kXMP_NS_XMP_PagedFile, "xmpTPg" );
  698|      1|	RegisterNamespace ( kXMP_NS_XMP_Graphics, "xmpG" );
  699|      1|	RegisterNamespace ( kXMP_NS_XMP_Image, "xmpGImg" );
  700|       |
  701|      1|	RegisterNamespace ( kXMP_NS_XMP_Font, "stFnt" );
  702|      1|	RegisterNamespace ( kXMP_NS_XMP_Dimensions, "stDim" );
  703|      1|	RegisterNamespace ( kXMP_NS_XMP_ResourceEvent, "stEvt" );
  704|      1|	RegisterNamespace ( kXMP_NS_XMP_ResourceRef, "stRef" );
  705|      1|	RegisterNamespace ( kXMP_NS_XMP_ST_Version, "stVer" );
  706|      1|	RegisterNamespace ( kXMP_NS_XMP_ST_Job, "stJob" );
  707|      1|	RegisterNamespace ( kXMP_NS_XMP_ManifestItem, "stMfs" );
  708|       |
  709|      1|	RegisterNamespace ( kXMP_NS_XMP_IdentifierQual, "xmpidq" );
  710|       |
  711|      1|	RegisterNamespace ( kXMP_NS_IPTCCore, "Iptc4xmpCore" );
  712|      1|	RegisterNamespace ( kXMP_NS_DICOM, "DICOM" );
  713|       |
  714|      1|	RegisterNamespace ( kXMP_NS_PDFA_Schema, "pdfaSchema" );
  715|      1|	RegisterNamespace ( kXMP_NS_PDFA_Property, "pdfaProperty" );
  716|      1|	RegisterNamespace ( kXMP_NS_PDFA_Type, "pdfaType" );
  717|      1|	RegisterNamespace ( kXMP_NS_PDFA_Field, "pdfaField" );
  718|      1|	RegisterNamespace ( kXMP_NS_PDFA_ID, "pdfaid" );
  719|      1|	RegisterNamespace ( kXMP_NS_PDFA_Extension, "pdfaExtension" );
  720|       |
  721|      1|	RegisterNamespace ( kXMP_NS_PDFX, "pdfx" );
  722|      1|	RegisterNamespace ( kXMP_NS_PDFX_ID, "pdfxid" );
  723|       |	
  724|      1|	RegisterNamespace ( "adobe:ns:meta/", "x" );
  725|      1|	RegisterNamespace ( "http://ns.adobe.com/iX/1.0/", "iX" );
  726|       |
  727|       |// 06-Oct-07, ahu: Do not use aliases. They result in unexpected behaviour.
  728|       |//	XMPMeta::RegisterStandardAliases ( "" );
  729|       |	
  730|       |	// Initialize the other core classes.
  731|       |	
  732|      1|	if ( ! XMPIterator::Initialize() ) XMP_Throw ( "Failure from XMPIterator::Initialize", kXMPErr_InternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (732:7): [True: 0, False: 1]
  ------------------
  733|      1|	if ( ! XMPUtils::Initialize() ) XMP_Throw ( "Failure from XMPUtils::Initialize", kXMPErr_InternalFailure );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (733:7): [True: 0, False: 1]
  ------------------
  734|       |	// Do miscelaneous semantic checks of types and arithmetic.
  735|       |
  736|      1|	XMP_Assert ( sizeof(XMP_Int8) == 1 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  737|      1|	XMP_Assert ( sizeof(XMP_Int16) == 2 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  738|      1|	XMP_Assert ( sizeof(XMP_Int32) == 4 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  739|      1|	XMP_Assert ( sizeof(XMP_Int64) == 8 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  740|      1|	XMP_Assert ( sizeof(XMP_Uns8) == 1 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  741|      1|	XMP_Assert ( sizeof(XMP_Uns16) == 2 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  742|      1|	XMP_Assert ( sizeof(XMP_Uns32) == 4 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  743|      1|	XMP_Assert ( sizeof(XMP_Uns64) == 8 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  744|       |	
  745|      1|	XMP_Assert ( sizeof(XMP_OptionBits) == 4 );	// Check that option masking work on all 32 bits.
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  746|      1|	XMP_OptionBits flag = ~0;
  747|       |
  748|      1|	XMP_Assert ( flag == (XMP_OptionBits)(-1L) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  749|      1|	XMP_Assert ( (flag ^ kXMP_PropHasLang) == 0xFFFFFFBFUL );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  750|      1|	XMP_Assert ( (flag & ~kXMP_PropHasLang) == 0xFFFFFFBFUL );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  751|       |	
  752|      1|	XMP_OptionBits opt1 = 0;	// Check the general option bit macros.
  753|      1|	XMP_OptionBits opt2 = flag;
  754|      1|	XMP_SetOption ( opt1, kXMP_PropValueIsArray );
  755|      1|	XMP_ClearOption ( opt2, kXMP_PropValueIsArray );
  756|      1|	XMP_Assert ( opt1 == ~opt2 );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  757|      1|	XMP_Assert ( XMP_TestOption ( opt1, kXMP_PropValueIsArray ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  758|      1|	XMP_Assert ( ! XMP_TestOption ( opt2, kXMP_PropValueIsArray ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  759|       |	
  760|      1|	XMP_Assert ( XMP_PropIsSimple ( ~kXMP_PropCompositeMask ) );	// Check the special option bit macros.
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  761|      1|	XMP_Assert ( ! XMP_PropIsSimple ( kXMP_PropValueIsStruct ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  762|      1|	XMP_Assert ( ! XMP_PropIsSimple ( kXMP_PropValueIsArray ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  763|       |
  764|      1|	XMP_Assert ( XMP_PropIsStruct ( kXMP_PropValueIsStruct ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  765|      1|	XMP_Assert ( XMP_PropIsArray  ( kXMP_PropValueIsArray ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  766|      1|	XMP_Assert ( ! XMP_PropIsStruct ( ~kXMP_PropValueIsStruct ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  767|      1|	XMP_Assert ( ! XMP_PropIsArray  ( ~kXMP_PropValueIsArray ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  768|       |	
  769|      1|	XMP_Assert ( XMP_ArrayIsUnordered ( ~kXMP_PropArrayIsOrdered ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  770|      1|	XMP_Assert ( XMP_ArrayIsOrdered   ( kXMP_PropArrayIsOrdered ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  771|      1|	XMP_Assert ( XMP_ArrayIsAlternate ( kXMP_PropArrayIsAlternate ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  772|      1|	XMP_Assert ( XMP_ArrayIsAltText   ( kXMP_PropArrayIsAltText ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  773|      1|	XMP_Assert ( ! XMP_ArrayIsUnordered ( kXMP_PropArrayIsOrdered ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  774|      1|	XMP_Assert ( ! XMP_ArrayIsOrdered   ( ~kXMP_PropArrayIsOrdered ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  775|      1|	XMP_Assert ( ! XMP_ArrayIsAlternate ( ~kXMP_PropArrayIsAlternate ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  776|      1|	XMP_Assert ( ! XMP_ArrayIsAltText   ( ~kXMP_PropArrayIsAltText ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  777|       |	
  778|      1|	XMP_Assert ( XMP_PropHasQualifiers ( kXMP_PropHasQualifiers ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  779|      1|	XMP_Assert ( XMP_PropIsQualifier   ( kXMP_PropIsQualifier ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  780|      1|	XMP_Assert ( XMP_PropHasLang       ( kXMP_PropHasLang ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  781|      1|	XMP_Assert ( ! XMP_PropHasQualifiers ( ~kXMP_PropHasQualifiers ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  782|      1|	XMP_Assert ( ! XMP_PropIsQualifier   ( ~kXMP_PropIsQualifier ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  783|      1|	XMP_Assert ( ! XMP_PropHasLang       ( ~kXMP_PropHasLang ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  784|       |	
  785|      1|	XMP_Assert ( XMP_NodeIsSchema ( kXMP_SchemaNode ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  786|      1|	XMP_Assert ( XMP_PropIsAlias  ( kXMP_PropIsAlias ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  787|      1|	XMP_Assert ( ! XMP_NodeIsSchema ( ~kXMP_SchemaNode ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  788|      1|	XMP_Assert ( ! XMP_PropIsAlias  ( ~kXMP_PropIsAlias ) );
  ------------------
  |  |  142|      1|	#define XMP_Assert(c)	((void) 0)
  ------------------
  789|       |	
  790|       |	#if 0	// Generally off, enable to hand check generated code.
  791|       |		extern XMP_OptionBits opt3, opt4;
  792|       |		if ( XMP_TestOption ( opt3, kXMP_PropValueIsArray ) ) opt4 = opt3;
  793|       |		if ( ! XMP_TestOption ( opt3, kXMP_PropValueIsStruct ) ) opt4 = opt3;
  794|       |		static bool ok1 = XMP_TestOption ( opt4, kXMP_PropValueIsArray );
  795|       |		static bool ok2 = ! XMP_TestOption ( opt4, kXMP_PropValueIsStruct );
  796|       |	#endif
  797|       |	
  798|       |	// Make sure the embedded info strings are referenced and kept.
  799|      1|	if ( (kXMPCore_EmbeddedVersion[0] == 0) || (kXMPCore_EmbeddedCopyright[0] == 0) ) return false;
  ------------------
  |  Branch (799:7): [True: 0, False: 1]
  |  Branch (799:45): [True: 0, False: 1]
  ------------------
  800|      1|	return true;
  801|       |
  802|      1|}	// Initialize
_ZN7XMPMeta9TerminateEv:
  813|      1|{
  814|      1|	--sXMP_InitCount;
  815|      1|	if ( sXMP_InitCount > 0 ) return;
  ------------------
  |  Branch (815:7): [True: 0, False: 1]
  ------------------
  816|       |
  817|       |	#if TraceXMPCalls
  818|       |		fprintf ( xmpOut, "XMP terminating\n" ); fflush ( xmpOut );
  819|       |		// fclose ( xmpOut );	// Coordinate with fopen in XMPMeta::Initialize.
  820|       |	#endif
  821|       |	
  822|      1|	XMPIterator::Terminate();
  823|      1|	XMPUtils::Terminate();
  824|      1|	EliminateGlobal ( sNamespaceURIToPrefixMap );
  ------------------
  |  |  809|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  825|      1|	EliminateGlobal ( sNamespacePrefixToURIMap );
  ------------------
  |  |  809|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  826|      1|	EliminateGlobal ( sRegisteredAliasMap );
  ------------------
  |  |  809|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  827|       |    
  828|      1|    EliminateGlobal ( xdefaultName );
  ------------------
  |  |  809|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  829|      1|    EliminateGlobal ( sOutputNS );
  ------------------
  |  |  809|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  830|      1|    EliminateGlobal ( sOutputStr );
  ------------------
  |  |  809|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  831|      1|	EliminateGlobal ( sExceptionMessage );
  ------------------
  |  |  809|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  832|       |
  833|      1|	XMP_TermMutex ( sXMPCoreLock );
  834|       |	
  835|      1|}	// Terminate
_ZN7XMPMeta6UnlockEj:
  844|  95.5k|{
  845|  95.5k|	UNUSED(options);
  846|       |
  847|       |    #if TraceXMPLocking
  848|       |    	fprintf ( xmpOut, "  Unlocking XMP toolkit, count = %d\n", sLockCount ); fflush ( xmpOut );
  849|       |	#endif
  850|  95.5k|    --sLockCount;
  851|  95.5k|    XMP_Assert ( sLockCount == 0 );
  ------------------
  |  |  142|  95.5k|	#define XMP_Assert(c)	((void) 0)
  ------------------
  852|  95.5k|	XMP_ExitCriticalRegion ( sXMPCoreLock );
  853|       |
  854|  95.5k|}	// Unlock
_ZN7XMPMeta17RegisterNamespaceEPKcS1_:
 1041|  35.4k|{
 1042|  35.4k|	if ( (*namespaceURI == 0) || (*prefix == 0) ) {
  ------------------
  |  Branch (1042:7): [True: 0, False: 35.4k]
  |  Branch (1042:31): [True: 0, False: 35.4k]
  ------------------
 1043|      0|		XMP_Throw ( "Empty namespace URI or prefix", kXMPErr_BadParam );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
 1044|      0|	}
 1045|       |	
 1046|  35.4k|	XMP_VarString	nsURI ( namespaceURI );
 1047|  35.4k|	XMP_VarString	prfix ( prefix );
 1048|  35.4k|	if ( prfix[prfix.size()-1] != ':' ) prfix += ':';
  ------------------
  |  Branch (1048:7): [True: 35.4k, False: 0]
  ------------------
 1049|  35.4k|	VerifySimpleXMLName ( prefix, prefix+prfix.size()-1 );	// Exclude the colon.
 1050|       |	
 1051|       |        // Set the new namespace in both maps.
 1052|  35.4k|        (*sNamespaceURIToPrefixMap)[nsURI] = prfix;
 1053|  35.4k|        (*sNamespacePrefixToURIMap)[prfix] = nsURI;
 1054|       |	
 1055|  35.4k|}	// RegisterNamespace
_ZN7XMPMeta18GetNamespacePrefixEPKcPS1_Pj:
 1066|   130k|{
 1067|   130k|	bool	found	= false;
 1068|       |	
 1069|   130k|	XMP_Assert ( *namespaceURI != 0 ); 	// ! Enforced by wrapper.
  ------------------
  |  |  142|   130k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1070|   130k|	XMP_Assert ( (namespacePrefix != 0) && (prefixSize != 0) );	// ! Enforced by wrapper.
  ------------------
  |  |  142|   130k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1071|       |
 1072|   130k|	XMP_VarString    nsURI ( namespaceURI );
 1073|   130k|	XMP_StringMapPos uriPos	= sNamespaceURIToPrefixMap->find ( nsURI );
 1074|       |	
 1075|   130k|	if ( uriPos != sNamespaceURIToPrefixMap->end() ) {
  ------------------
  |  Branch (1075:7): [True: 130k, False: 0]
  ------------------
 1076|   130k|		*namespacePrefix = uriPos->second.c_str();
 1077|   130k|		*prefixSize = uriPos->second.size();
 1078|   130k|		found = true;
 1079|   130k|	}
 1080|       |	
 1081|   130k|	return found;
 1082|       |	
 1083|   130k|}	// GetNamespacePrefix
_ZNK7XMPMeta15CountArrayItemsEPKcS1_:
 1510|  4.11k|{
 1511|  4.11k|	XMP_Assert ( (schemaNS != 0) && (arrayName != 0) );	// Enforced by wrapper.
  ------------------
  |  |  142|  4.11k|	#define XMP_Assert(c)	((void) 0)
  ------------------
 1512|       |
 1513|  4.11k|	XMP_ExpandedXPath	expPath;
 1514|  4.11k|	ExpandXPath ( schemaNS, arrayName, &expPath );
 1515|       |	
 1516|  4.11k|	const XMP_Node * arrayNode = FindConstNode ( &tree, expPath );
  ------------------
  |  |  301|  4.11k|#define FindConstNode(t,p)		FindNode ( const_cast<XMP_Node*>(t), p, kXMP_ExistingOnly, 0 )
  |  |  ------------------
  |  |  |  |  296|  4.11k|#define kXMP_ExistingOnly	false
  |  |  ------------------
  ------------------
 1517|       |
 1518|  4.11k|	if ( arrayNode == 0 ) return 0;
  ------------------
  |  Branch (1518:7): [True: 0, False: 4.11k]
  ------------------
 1519|  4.11k|	if ( ! (arrayNode->options & kXMP_PropValueIsArray) ) XMP_Throw ( "The named property is not an array", kXMPErr_BadXPath );
  ------------------
  |  |  199|      0|#define XMP_Throw(msg,id)	{ AnnounceThrow ( msg ); throw XMP_Error ( id, msg ); }
  ------------------
  |  Branch (1519:7): [True: 0, False: 4.11k]
  ------------------
 1520|  4.11k|	return arrayNode->children.size();
 1521|       |	
 1522|  4.11k|}	// CountArrayItems

_ZN8XMPUtils10InitializeEv:
  640|      1|{
  641|      1|	sComposedPath	= new XMP_VarString();
  642|      1|	sConvertedValue = new XMP_VarString();
  643|      1|	sBase64Str		= new XMP_VarString();
  644|      1|	sCatenatedItems = new XMP_VarString();
  645|      1|	sStandardXMP    = new XMP_VarString();
  646|      1|	sExtendedXMP    = new XMP_VarString();
  647|      1|	sExtendedDigest = new XMP_VarString();
  648|       |
  649|       |	#if XMP_MacBuild && __MWERKS__
  650|       |		LookupTimeProcs();
  651|       |	#endif
  652|       |
  653|      1|	return true;
  654|       |
  655|      1|}	// Initialize
_ZN8XMPUtils9TerminateEv:
  666|      1|{
  667|      1|	EliminateGlobal ( sComposedPath );
  ------------------
  |  |  662|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  668|      1|	EliminateGlobal ( sConvertedValue );
  ------------------
  |  |  662|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  669|      1|	EliminateGlobal ( sBase64Str );
  ------------------
  |  |  662|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  670|      1|	EliminateGlobal ( sCatenatedItems );
  ------------------
  |  |  662|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  671|      1|	EliminateGlobal ( sStandardXMP );
  ------------------
  |  |  662|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  672|      1|	EliminateGlobal ( sExtendedXMP );
  ------------------
  |  |  662|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  673|      1|	EliminateGlobal ( sExtendedDigest );
  ------------------
  |  |  662|      1|#define EliminateGlobal(g) delete ( g ); g = 0
  ------------------
  674|       |
  675|      1|	return;
  676|       |
  677|      1|}	// Terminate

