/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 |