Coverage Report

Created: 2025-11-09 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/exiv2/include/exiv2/matroskavideo.hpp
Line
Count
Source
1
// ***************************************************************** -*- C++ -*-
2
/*
3
 * Copyright (C) 2004-2021 Exiv2 authors
4
 * This program is part of the Exiv2 distribution.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
19
 */
20
#ifndef EXIV2_MATROSKAVIDEO_HPP
21
#define EXIV2_MATROSKAVIDEO_HPP
22
23
// *****************************************************************************
24
#include "exiv2lib_export.h"
25
26
// included header files
27
#include "image.hpp"
28
29
// *****************************************************************************
30
// namespace extensions
31
namespace Exiv2 {
32
33
/*!
34
  @brief Helper structure for the Matroska tags lookup table.
35
 */
36
37
// *****************************************************************************
38
// class definitions
39
namespace Internal {
40
41
enum matroskaTypeEnum : char {
42
  String = 's',
43
  Integer = 'i',
44
  UInteger = 'u',
45
  Date = 'd',
46
  InternalField = 'n',
47
  Boolean = 'o',
48
  Binary = 'b',
49
  Master = 'm',
50
  Float = 'f',
51
  Utf8 = '8',
52
  UndefinedType = 'z',
53
};
54
55
enum matroskaProcessEnum : char {
56
  Process = 'p',
57
  Skip = 's',
58
  Composite = 'c',
59
  Undefined = 'u',
60
};
61
62
struct MatroskaTag {
63
  uint64_t _id;
64
  std::string _label;
65
  matroskaTypeEnum _type;
66
  matroskaProcessEnum _process;
67
68
  MatroskaTag(uint64_t id, std::string label, matroskaTypeEnum type, matroskaProcessEnum process) :
69
396
      _id(id), _label(std::move(label)), _type(type), _process(process) {
70
396
  }
71
72
  MatroskaTag(uint64_t id, std::string label) :
73
152
      _id(id),
74
152
      _label(std::move(label)),
75
152
      _type(matroskaTypeEnum::UndefinedType),
76
152
      _process(matroskaProcessEnum::Undefined) {
77
152
  }
78
79
2.49M
  bool operator==(uint64_t id) const {
80
2.49M
    return id == _id;
81
2.49M
  }
82
83
78.0k
  [[nodiscard]] bool isSkipped() const {
84
78.0k
    return _process == Skip;
85
78.0k
  }
86
60.3k
  [[nodiscard]] bool isComposite() const {
87
60.3k
    return _process == Composite;
88
60.3k
  }
89
0
  void dump(std::ostream& os) const {
90
0
    os << " MatroskaTag "
91
0
       << " id: [0x" << std::hex << _id << "] label:[" << _label << "] type:[" << _type << "] process :[" << _process
92
0
       << "]\n";
93
0
  }
94
};
95
}  // namespace Internal
96
97
/*!
98
  @brief Class to access Matroska video files.
99
 */
100
class EXIV2API MatroskaVideo : public Image {
101
 public:
102
  //! @name Creators
103
  //@{
104
  /*!
105
    @brief Constructor for a Matroska video. Since the constructor
106
        can not return a result, callers should check the good() method
107
        after object construction to determine success or failure.
108
    @param io An auto-pointer that owns a BasicIo instance used for
109
        reading and writing image metadata. \b Important: The constructor
110
        takes ownership of the passed in BasicIo instance through the
111
        auto-pointer. Callers should not continue to use the BasicIo
112
        instance after it is passed to this method. Use the Image::io()
113
        method to get a temporary reference.
114
   */
115
  explicit MatroskaVideo(BasicIo::UniquePtr io);
116
  //@}
117
118
  //! @name Manipulators
119
  //@{
120
  void readMetadata() override;
121
  void writeMetadata() override;
122
  //@}
123
124
  //! @name Accessors
125
  //@{
126
  [[nodiscard]] std::string mimeType() const override;
127
  //@}
128
129
 protected:
130
  /*!
131
    @brief Function used to calculate the size of a block.
132
        This information is only stored in one byte.
133
        The size of the block is calculated by counting
134
        the number of leading zeros in the binary code of the byte.
135
        Size = (No. of leading zeros + 1) bytes
136
    @param b The byte, which stores the information to calculate the size
137
    @return Return the size of the block.
138
   */
139
  [[nodiscard]] static uint32_t findBlockSize(byte b);
140
  /*!
141
    @brief Check for a valid tag and decode the block at the current IO position.
142
        Calls contentManagement() or skips to next tag, if required.
143
   */
144
  void decodeBlock();
145
  /*!
146
    @brief Interpret tag information, and save it in the respective XMP container.
147
    @param tag Pointer to current tag,
148
    @param buf Pointer to the memory area with the tag information.
149
    @param size Size of \em buf.
150
   */
151
152
  void decodeInternalTags(const Internal::MatroskaTag* tag, const byte* buf);
153
  void decodeStringTags(const Internal::MatroskaTag* tag, const byte* buf);
154
  void decodeIntegerTags(const Internal::MatroskaTag* tag, const byte* buf);
155
  void decodeBooleanTags(const Internal::MatroskaTag* tag, const byte* buf);
156
  void decodeDateTags(const Internal::MatroskaTag* tag, const byte* buf, size_t size);
157
  void decodeFloatTags(const Internal::MatroskaTag* tag, const byte* buf);
158
159
 private:
160
  //! Variable to check the end of metadata traversing.
161
  bool continueTraversing_{};
162
  //! Variable to store height and width of a video frame.
163
  uint64_t height_{};
164
  uint64_t width_{};
165
  uint32_t track_count_{};
166
  double time_code_scale_ = 1.0;
167
  uint64_t stream_{};
168
169
  static constexpr double bytesMB = 1048576;
170
171
};  // class MatroskaVideo
172
173
// *****************************************************************************
174
// template, inline and free functions
175
176
// These could be static private functions on Image subclasses but then
177
// ImageFactory needs to be made a friend.
178
/*!
179
  @brief Create a new MatroskaVideo instance and return an auto-pointer to it.
180
      Caller owns the returned object and the auto-pointer ensures that
181
      it will be deleted.
182
 */
183
EXIV2API Image::UniquePtr newMkvInstance(BasicIo::UniquePtr io, bool create);
184
185
//! Check if the file iIo is a Matroska Video.
186
EXIV2API bool isMkvType(BasicIo& iIo, bool advance);
187
188
}  // namespace Exiv2
189
190
#endif  // EXIV2_MATROSKAVIDEO_HPP