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

Restore some video capabilities by restoring quicktimevideo.cpp #2337

Merged
merged 8 commits into from
Aug 24, 2022
2 changes: 1 addition & 1 deletion include/exiv2/basicio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class EXIV2API BasicIo {
read if \em rcount bytes are not available.
@param err Error code to use if an exception is thrown.
*/
void readOrThrow(byte* buf, size_t rcount, ErrorCode err);
void readOrThrow(byte* buf, size_t rcount, ErrorCode err = ErrorCode::kerCorruptedMetadata);
/*!
@brief Read one byte from the IO source. Current IO position is
advanced by one byte.
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 @@ -34,6 +34,7 @@ enum class ImageType {
tiff,
webp,
xmp, ///< XMP sidecar files
qtime,
};
} // namespace Exiv2

Expand Down
239 changes: 239 additions & 0 deletions include/exiv2/quicktimevideo.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
// ***************************************************************** -*- 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
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
*/
#ifndef QUICKTIMEVIDEO_HPP
#define QUICKTIMEVIDEO_HPP

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

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

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

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

/*!
@brief Class to access QuickTime video files.
*/
class QuickTimeVideo : public Image {
public:
//! @name Creators
//@{
/*!
@brief Constructor for a QuickTime 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.
*/
QuickTimeVideo(BasicIo::UniquePtr io);
//@}

//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}

//! @name Accessors
//@{
std::string mimeType() const;
//@}

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(std::string const& parent_box = "");
/*!
@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);

private:
/*!
@brief Interpret file type of the video, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void fileTypeDecoder(size_t size);
/*!
@brief Interpret Media Header Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void mediaHeaderDecoder(size_t size);
/*!
@brief Interpret Video Header Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void videoHeaderDecoder(size_t size);
/*!
@brief Interpret Movie Header Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void movieHeaderDecoder(size_t size);
/*!
@brief Interpret Track Header Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void trackHeaderDecoder(size_t size);
/*!
@brief Interpret Handler Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void handlerDecoder(size_t size);
/*!
@brief Interpret Tag which contain other sub-tags,
and save it in the respective XMP container.
*/
void multipleEntriesDecoder();
/*!
@brief Interpret Sample Description Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void sampleDesc(size_t size);
/*!
@brief Interpret Image Description Tag, and save it
in the respective XMP container.
*/
void imageDescDecoder();
/*!
@brief Interpret User Data Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void userDataDecoder(size_t size);
/*!
@brief Interpret Preview Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void previewTagDecoder(size_t size);
/*!
@brief Interpret Meta Keys Tags, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void keysTagDecoder(size_t size);
/*!
@brief Interpret Track Aperture Tags, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void trackApertureTagDecoder(size_t size);
/*!
@brief Interpret Nikon Tag, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void NikonTagsDecoder(size_t size);
/*!
@brief Interpret Tags from Different Camera make, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Information.
*/
void CameraTagsDecoder(size_t size);
/*!
@brief Interpret Audio Description Tag, and save it
in the respective XMP container.
*/
void audioDescDecoder();
/*!
@brief Helps to calculate Frame Rate from timeToSample chunk,
and save it in the respective XMP container.
*/
void timeToSampleDecoder();
/*!
@brief Recognizes which stream is currently under processing,
and save its information in currentStream_ .
*/
void setMediaStream();
/*!
@brief Used to discard a tag along with its data. The Tag will
be skipped and not decoded.
@param size Size of the data block that is to skipped.
*/
void discard(size_t size);
/*!
@brief Calculates Aspect Ratio of a video, and stores it in the
respective XMP container.
*/
void aspectRatio();

private:
//! @name NOT Implemented
//@{
//! Copy constructor
QuickTimeVideo(const QuickTimeVideo& rhs);
//! Assignment operator
QuickTimeVideo& operator=(const QuickTimeVideo& rhs);
//@}

private:
//! Variable which stores Time Scale unit, used to calculate time.
uint64_t timeScale_;
//! Variable which stores current stream being processsed.
int currentStream_;
//! Variable to check the end of metadata traversing.
bool continueTraversing_;
//! Variable to store height and width of a video frame.
uint64_t height_, width_;

}; // QuickTimeVideo End

// *****************************************************************************
// 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 QuicktimeVideo instance and return an auto-pointer to it.
Caller owns the returned object and the auto-pointer ensures that
it will be deleted.
*/
Image::UniquePtr newQTimeInstance(BasicIo::UniquePtr io, bool create);

//! Check if the file iIo is a Quick Time Video.
bool isQTimeType(BasicIo& iIo, bool advance);

} // namespace Exiv2

#endif // QUICKTIMEVIDEO_HPP
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ set(PUBLIC_HEADERS
../include/exiv2/webpimage.hpp
../include/exiv2/xmp_exiv2.hpp
../include/exiv2/xmpsidecar.hpp
../include/exiv2/quicktimevideo.hpp
)

add_library( exiv2lib
Expand Down Expand Up @@ -123,6 +124,7 @@ add_library( exiv2lib
webpimage.cpp
xmp.cpp
xmpsidecar.cpp
quicktimevideo.cpp
${PUBLIC_HEADERS}
$<TARGET_OBJECTS:exiv2lib_int>
)
Expand Down
6 changes: 1 addition & 5 deletions src/bmffimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,11 +677,7 @@ bool isBmffType(BasicIo& iIo, bool advance) {
// jxl files have a special start indicator of "JXL "
bool const is_jxl = (buf[4] == 'J' && buf[5] == 'X' && buf[6] == 'L' && buf[7] == ' ');

// MOV(quicktime) files seem to also start with ftyp, but we don't want to process them
// so check that we don't encounter "qt "
// FIXME what others types can we abort early here?
bool const is_video = (buf[8] == 'q' && buf[9] == 't' && buf[10] == ' ' && buf[11] == ' ');
bool matched = is_jxl || (is_ftyp && !is_video);
bool matched = is_jxl || is_ftyp;
if (!advance || !matched) {
iIo.seek(0, BasicIo::beg);
}
Expand Down
4 changes: 4 additions & 0 deletions src/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "orfimage.hpp"
#include "pgfimage.hpp"
#include "psdimage.hpp"
#include "quicktimevideo.hpp"
#include "rafimage.hpp"
#include "rw2image.hpp"
#include "tags_int.hpp"
Expand Down Expand Up @@ -96,6 +97,9 @@ constexpr auto registry = std::array{
Registry{ImageType::tga, newTgaInstance, isTgaType, amNone, amNone, amNone, amNone},
Registry{ImageType::bmp, newBmpInstance, isBmpType, amNone, amNone, amNone, amNone},
Registry{ImageType::jp2, newJp2Instance, isJp2Type, amReadWrite, amReadWrite, amReadWrite, amNone},
// 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},
#ifdef EXV_ENABLE_BMFF
Registry{ImageType::bmff, newBmffInstance, isBmffType, amRead, amRead, amRead, amNone},
#endif // EXV_ENABLE_BMFF
Expand Down
3 changes: 1 addition & 2 deletions src/properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4902,8 +4902,7 @@ const XmpPrintInfo xmpPrintInfo[] = {
{"Xmp.plus.MinorModelAgeDisclosure", EXV_PRINT_VOCABULARY(plusMinorModelAgeDisclosure)},
{"Xmp.plus.ModelReleaseStatus", EXV_PRINT_VOCABULARY(plusModelReleaseStatus)},
{"Xmp.plus.PropertyReleaseStatus", EXV_PRINT_VOCABULARY(plusPropertyReleaseStatus)},
{"Xmp.plus.Reuse", EXV_PRINT_VOCABULARY(plusReuse)},
};
{"Xmp.plus.Reuse", EXV_PRINT_VOCABULARY(plusReuse)}};

XmpNsInfo::Ns::Ns(std::string ns) : ns_(std::move(ns)) {
}
Expand Down
Loading