Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1748 Video Support in V1.0: part 2/3 : support Riffvideo #2415

Merged
merged 7 commits into from
Dec 31, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions exiv2.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ and see if `enable_bmff=1`.
- Naked codestream JXL files do not contain Exif, IPTC or XMP metadata.

- Support of video files is limited. Currently **exiv2** only has some
rudimentary support to read metadata from quicktime and matroskavideo based video files (e.g.
.MOV/.MP4, MKV)

mohamedchebbii marked this conversation as resolved.
Show resolved Hide resolved
rudimentary support to read metadata from quicktime, matroska and riff based video files (e.g.
.MOV/.MP4, .MKV, .AVI, .WAV).


[TOC](#TOC)
Expand Down
1 change: 1 addition & 0 deletions include/exiv2/image_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum class ImageType {
webp,
xmp, ///< XMP sidecar files
qtime,
riff,
mkv,
};
} // namespace Exiv2
Expand Down
205 changes: 205 additions & 0 deletions include/exiv2/riffvideo.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2021 Exiv2 authors
* This program is part of the Exiv2 distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* asize_t with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
*/
#ifndef RIFFVIDEO_HPP
#define RIFFVIDEO_HPP

// *****************************************************************************
#include "exiv2lib_export.h"

// included header files
#include "exif.hpp"
#include "image.hpp"

// *****************************************************************************
// namespace extensions
namespace Exiv2 {

// *****************************************************************************
// class definitions

/*!
@brief Class to access RIFF video files.
*/
class EXIV2API RiffVideo : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor for a Riff video. Since the constructor
can not return a result, callers should check the good() method
after object construction to determine success or failure.
@param io An auto-pointer that owns a BasicIo instance used for
reading and writing image metadata. \b Important: The constructor
takes ownership of the passed in BasicIo instance through the
auto-pointer. Callers should not continue to use the BasicIo
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
explicit RiffVideo(BasicIo::UniquePtr io);

//! Copy constructor
RiffVideo(const RiffVideo& rhs) = delete;
//! Assignment operator
RiffVideo& operator=(const RiffVideo& rhs) = delete;

//@}

//! @name Manipulators
//@{
void printStructure(std::ostream& out, PrintStructureOption option, size_t depth) override;
void readMetadata() override;
void writeMetadata() override;
//@}

//! @name Accessors
//@{
[[nodiscard]] std::string mimeType() const override;
[[nodiscard]] const char* printAudioEncoding(uint64_t i);
//@}

protected:
/*!
@brief Check for a valid tag and decode the block at the current IO
position. Calls tagDecoder() or skips to next tag, if required.
*/
void decodeBlock();
/*!
@brief Interpret tag information, and call the respective function
to save it in the respective XMP container. Decodes a Tag
Information and saves it in the respective XMP container, if
the block size is small.
@param buf Data buffer which cotains tag ID.
@param size Size of the data block used to store Tag Information.
*/
void tagDecoder(Exiv2::DataBuf& buf, size_t size);
/*!
@brief Interpret Junk tag information, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void junkHandler(size_t size);
/*!
@brief Interpret Stream tag information, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void streamHandler(size_t size);
/*!
@brief Interpret Stream Format tag information, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void streamFormatHandler(size_t size);
/*!
@brief Interpret Riff Header tag information, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void aviHeaderTagsHandler(size_t size);
/*!
@brief Interpret Riff List tag information, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void listHandler(size_t size);
/*!
@brief Interpret Riff Stream Data tag information, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void streamDataTagHandler(size_t size);
/*!
@brief Interpret INFO tag information, and save it
in the respective XMP container.
*/
void infoTagsHandler();
/*!
@brief Interpret Nikon Tags related to Video information, and
save it in the respective XMP container.
*/
void nikonTagsHandler();
/*!
@brief Interpret OpenDML tag information, and save it
in the respective XMP container.
*/
void odmlTagsHandler();
//! @brief Skips Particular Blocks of Metadata List.
void skipListData();
/*!
@brief Interprets DateTimeOriginal tag or stream name tag
information, and save it in the respective XMP container.
@param size Size of the data block used to store Tag Information.
@param i parameter used to overload function
*/
void dateTimeOriginal(size_t size, int i = 0);
/*!
@brief Calculates Sample Rate of a particular stream.
@param buf Data buffer with the dividend.
@param divisor The Divisor required to calculate sample rate.
@return Return the sample rate of the stream.
*/
[[nodiscard]] double returnSampleRate(Exiv2::DataBuf& buf, size_t divisor = 1);
/*!
@brief Calculates Aspect Ratio of a video, and stores it in the
respective XMP container.
@param width Width of the video.
@param height Height of the video.
*/
void fillAspectRatio(size_t width = 1, size_t height = 1);
/*!
@brief Calculates Duration of a video, and stores it in the
respective XMP container.
@param frame_rate Frame rate of the video.
@param frame_count Total number of frames present in the video.
*/
void fillDuration(double frame_rate, size_t frame_count);

[[nodiscard]] bool equalsRiffTag(Exiv2::DataBuf& buf, const char* str);

private:
static constexpr int RIFF_TAG_SIZE = 0x4;
static constexpr auto RIFF_CHUNK_HEADER_ICCP = "ICCP";
static constexpr auto RIFF_CHUNK_HEADER_EXIF = "EXIF";
static constexpr auto RIFF_CHUNK_HEADER_XMP = "XMP ";
//! Variable to check the end of metadata traversing.
bool continueTraversing_;
//! Variable which stores current stream being processsed.
int streamType_;

}; // Class RiffVideo

// *****************************************************************************
// template, inline and free functions

// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new RiffVideo instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
EXIV2API Image::UniquePtr newRiffInstance(BasicIo::UniquePtr io, bool create);

//! Check if the file iIo is a Riff Video.
EXIV2API bool isRiffType(BasicIo& iIo, bool advance);

} // namespace Exiv2

#endif // RIFFVIDEO_HPP
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ set(PUBLIC_HEADERS
../include/exiv2/properties.hpp
../include/exiv2/psdimage.hpp
../include/exiv2/rafimage.hpp
../include/exiv2/riffvideo.hpp
../include/exiv2/rw2image.hpp
../include/exiv2/slice.hpp
../include/exiv2/tags.hpp
Expand Down Expand Up @@ -116,6 +117,7 @@ add_library( exiv2lib
properties.cpp
psdimage.cpp
rafimage.cpp
riffvideo.cpp
rw2image.cpp
tags.cpp
tgaimage.cpp
Expand Down
2 changes: 2 additions & 0 deletions src/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "psdimage.hpp"
#include "quicktimevideo.hpp"
#include "rafimage.hpp"
#include "riffvideo.hpp"
#include "rw2image.hpp"
#include "tags_int.hpp"
#include "tgaimage.hpp"
Expand Down Expand Up @@ -101,6 +102,7 @@ constexpr auto registry = std::array{
// needs to be before bmff because some ftyp files are handled as qt and
// the rest should fall through to bmff
Registry{ImageType::qtime, newQTimeInstance, isQTimeType, amRead, amNone, amRead, amNone},
Registry{ImageType::riff, newRiffInstance, isRiffType, amRead, amNone, amRead, amNone},
Registry{ImageType::mkv, newMkvInstance, isMkvType, amRead, amNone, amRead, amNone},

#ifdef EXV_ENABLE_BMFF
Expand Down
Loading