GSoC2013 Video Write Code. Thank You, Mahesh for a lot of hard work. And Thanks to Abhinav for mentoring. Great Job, Guys.

This commit is contained in:
Robin Mills 2014-09-07 11:59:45 +00:00
parent 0d5a0ae068
commit 66e473db32
31 changed files with 5594 additions and 3888 deletions

View File

@ -187,7 +187,7 @@ ENDIF()
ADD_CUSTOM_TARGET(tests COMMAND make test "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" )
ADD_CUSTOM_TARGET(teste COMMAND make teste "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" )
ADD_CUSTOM_TARGET(testv COMMAND make testv "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" )
ADD_CUSTOM_TARGET(testvw COMMAND make testvw "EXIV2_BINDIR=${CMAKE_BINARY_DIR}/bin" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/test/" )
##
# http://dev.exiv2.org/boards/3/topics/1364
# effectively does a make doc on the root directory

View File

@ -79,6 +79,9 @@ teste:
testv:
cd test && $(MAKE) testv
testvw:
cd test && $(MAKE) testvw
MAJOR=$(shell grep "define.*EXIV2_.*_VERSION .*\\d*" src/version.hpp | grep MAJOR | sed -e 's/EXIV2//g' | tr -dC [:digit:])
MINOR=$(shell grep "define.*EXIV2_.*_VERSION .*\\d*" src/version.hpp | grep MINOR | sed -e 's/EXIV2//g' | tr -dC [:digit:])
VERSION=exiv2-$(MAJOR).$(MINOR)

View File

@ -79,6 +79,9 @@ teste:
testv:
cd test && $(MAKE) testv
testvw:
cd test && $(MAKE) testvw
MAJOR=$(shell grep "define.*EXIV2_.*_VERSION .*\\d*" src/version.hpp | grep MAJOR | sed -e 's/EXIV2//g' | tr -dC [:digit:])
MINOR=$(shell grep "define.*EXIV2_.*_VERSION .*\\d*" src/version.hpp | grep MINOR | sed -e 's/EXIV2//g' | tr -dC [:digit:])
VERSION=exiv2-$(MAJOR).$(MINOR)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -72,10 +72,12 @@ SET( LIBEXIV2_HDR asfvideo.hpp
tgaimage.hpp
tiffimage.hpp
types.hpp
utilsvideo.hpp
value.hpp
version.hpp
xmp.hpp
xmpsidecar.hpp
utilsvideo.hpp
)
# Add library C++ source files to this list
@ -127,10 +129,12 @@ SET( LIBEXIV2_SRC asfvideo.cpp
tiffimage.cpp
tiffvisitor.cpp
types.cpp
utilsvideo.cpp
value.cpp
version.cpp
xmp.cpp
xmpsidecar.cpp
utilsvideo.cpp
)
##

View File

@ -117,6 +117,7 @@ CCSRC += preview.cpp \
tiffimage.cpp \
tiffvisitor.cpp \
types.cpp \
utilsvideo.cpp \
value.cpp \
version.cpp \
xmp.cpp \

View File

@ -159,7 +159,11 @@ namespace Action {
public:
virtual ~Print();
virtual int run(const std::string& path);
typedef std::auto_ptr<Print> AutoPtr;
typedef std::auto_ptr<Print> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
//! Print the Jpeg comment
@ -212,10 +216,18 @@ namespace Action {
public:
virtual ~Rename();
virtual int run(const std::string& path);
typedef std::auto_ptr<Rename> AutoPtr;
typedef std::auto_ptr<Rename> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
private:
/*!
* \brief clone TODO
* \return
*/
virtual Rename* clone_() const;
}; // class Rename
@ -224,10 +236,18 @@ namespace Action {
public:
virtual ~Adjust();
virtual int run(const std::string& path);
typedef std::auto_ptr<Adjust> AutoPtr;
typedef std::auto_ptr<Adjust> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
private:
/*!
* \brief clone TODO
* \return
*/
virtual Adjust* clone_() const;
int adjustDateTime(Exiv2::ExifData& exifData,
const std::string& key,
@ -247,7 +267,11 @@ namespace Action {
public:
virtual ~Erase();
virtual int run(const std::string& path);
typedef std::auto_ptr<Erase> AutoPtr;
typedef std::auto_ptr<Erase> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
/*!
@ -272,8 +296,12 @@ namespace Action {
int eraseXmpData(Exiv2::Image* image) const;
private:
/*!
* \brief clone TODO
* \return
*/
virtual Erase* clone_() const;
std::string path_;
std::string path_; //!< TODO
}; // class Erase
@ -284,7 +312,11 @@ namespace Action {
public:
virtual ~Extract();
virtual int run(const std::string& path);
typedef std::auto_ptr<Extract> AutoPtr;
typedef std::auto_ptr<Extract> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
/*!
@ -307,8 +339,12 @@ namespace Action {
void writePreviewFile(const Exiv2::PreviewImage& pvImg, int num) const;
private:
/*!
* \brief clone TODO
* \return
*/
virtual Extract* clone_() const;
std::string path_;
std::string path_; //!< TODO
}; // class Extract
@ -319,7 +355,11 @@ namespace Action {
public:
virtual ~Insert();
virtual int run(const std::string& path);
typedef std::auto_ptr<Insert> AutoPtr;
typedef std::auto_ptr<Insert> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
/*!
@ -348,7 +388,11 @@ namespace Action {
public:
virtual ~Modify();
virtual int run(const std::string& path);
typedef std::auto_ptr<Modify> AutoPtr;
typedef std::auto_ptr<Modify> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
Modify() {}
//! Apply modification commands to the \em pImage, return 0 if successful.
@ -381,12 +425,20 @@ namespace Action {
public:
virtual ~FixIso();
virtual int run(const std::string& path);
typedef std::auto_ptr<FixIso> AutoPtr;
typedef std::auto_ptr<FixIso> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
private:
/*!
* \brief clone TODO
* \return
*/
virtual FixIso* clone_() const;
std::string path_;
std::string path_; //!< TODO
}; // class FixIso
@ -399,12 +451,20 @@ namespace Action {
public:
virtual ~FixCom();
virtual int run(const std::string& path);
typedef std::auto_ptr<FixCom> AutoPtr;
typedef std::auto_ptr<FixCom> AutoPtr; //!< TODO
/*!
* \brief clone TODO
* \return
*/
AutoPtr clone() const;
private:
/*!
* \brief clone TODO
* \return
*/
virtual FixCom* clone_() const;
std::string path_;
std::string path_; //!< TODO
}; // class FixCom

View File

@ -160,6 +160,7 @@ namespace Exiv2 {
{ 0x7A22, "GSM-AMR (VBR including SID)" }
};
//! File properties.
extern const TagDetails filePropertiesTags[] = {
{ 7, "Xmp.video.FileLength" },
{ 6, "Xmp.video.CreationDate" },
@ -170,6 +171,7 @@ namespace Exiv2 {
{ 1, "Xmp.video.MaxBitRate" }
};
//!Contents Description.
extern const TagDetails contentDescriptionTags[] = {
{ 0, "Xmp.video.Title" },
{ 1, "Xmp.video.Author" },
@ -293,11 +295,37 @@ namespace Exiv2 {
using namespace Exiv2::Internal;
class AsfVideo::Private
{
public:
Private()
{
continueTraversing_ = true;
localPosition_ = 1;
streamNumber_ = 0;
height_ = 1;
width_ = 1;
}
//! Variable to check the end of metadata traversing.
bool continueTraversing_;
//! Variable which stores current position of the read pointer.
uint64_t localPosition_;
//! Variable which stores current stream being processsed.
int streamNumber_;
//! Variable to store height and width of a video frame.
uint64_t height_, width_;
};
AsfVideo::AsfVideo(BasicIo::AutoPtr io)
: Image(ImageType::asf, mdNone, io)
: Image(ImageType::asf, mdNone, io),d(new Private)
{
} // AsfVideo::AsfVideo
AsfVideo::~AsfVideo()
{
delete d;
}
std::string AsfVideo::mimeType() const
{
return "video/asf";
@ -319,15 +347,15 @@ namespace Exiv2 {
IoCloser closer(*io_);
clearMetadata();
continueTraversing_ = true;
d->continueTraversing_ = true;
io_->seek(0, BasicIo::beg);
height_ = width_ = 1;
d->height_ = d->width_ = 1;
xmpData_["Xmp.video.FileSize"] = (double)io_->size()/(double)1048576;
xmpData_["Xmp.video.FileName"] = io_->path();
xmpData_["Xmp.video.MimeType"] = mimeType();
while (continueTraversing_) decodeBlock();
while (d->continueTraversing_) decodeBlock();
aspectRatio();
} // AsfVideo::readMetadata
@ -337,7 +365,6 @@ namespace Exiv2 {
const long bufMinSize = 9;
DataBuf buf(bufMinSize);
unsigned long size = 0;
buf.pData_[8] = '\0' ;
const TagVocabulary* tv;
uint64_t cur_pos = io_->tell();
@ -345,7 +372,7 @@ namespace Exiv2 {
io_->read(guidBuf, 16);
if(io_->eof()) {
continueTraversing_ = false;
d->continueTraversing_ = false;
return;
}
@ -354,7 +381,6 @@ namespace Exiv2 {
getGUID(guidBuf, GUID);
tv = find( GUIDReferenceTags, GUID);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 8);
size = static_cast<unsigned long>(getUint64_t(buf));
@ -364,7 +390,7 @@ namespace Exiv2 {
else
io_->seek(cur_pos + size, BasicIo::beg);
localPosition_ = io_->tell();
d->localPosition_ = io_->tell();
} // AsfVideo::decodeBlock
void AsfVideo::tagDecoder(const TagVocabulary *tv, uint64_t size)
@ -376,11 +402,11 @@ namespace Exiv2 {
Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpSeq);
if(compareTag( exvGettext(tv->label_), "Header")) {
localPosition_ = 0;
d->localPosition_ = 0;
io_->read(buf.pData_, 4);
io_->read(buf.pData_, 2);
while(localPosition_ < cur_pos + size) decodeBlock();
while(d->localPosition_ < cur_pos + size) decodeBlock();
}
else if(compareTag( exvGettext(tv->label_), "File_Properties"))
@ -408,7 +434,7 @@ namespace Exiv2 {
extendedStreamProperties(size);
else if(compareTag( exvGettext(tv->label_), "Header_Extension")) {
localPosition_ = 0;
d->localPosition_ = 0;
headerExtension(size);
}
@ -428,7 +454,7 @@ namespace Exiv2 {
}
io_->seek(cur_pos + size, BasicIo::beg);
localPosition_ = io_->tell();
d->localPosition_ = io_->tell();
} // AsfVideo::tagDecoder
void AsfVideo::extendedStreamProperties(uint64_t size)
@ -440,16 +466,16 @@ namespace Exiv2 {
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 2);
streamNumber_ = Exiv2::getUShort(buf.pData_, littleEndian);
d->streamNumber_ = Exiv2::getUShort(buf.pData_, littleEndian);
io_->read(buf.pData_, 2);
io_->read(buf.pData_, 8);
avgTimePerFrame = getUint64_t(buf);
if(previousStream < streamNumber_ && avgTimePerFrame != 0)
if(previousStream < d->streamNumber_ && avgTimePerFrame != 0)
xmpData_["Xmp.video.FrameRate"] = (double)10000000/(double)avgTimePerFrame;
previousStream = streamNumber_;
previousStream = d->streamNumber_;
io_->seek(cur_pos + size, BasicIo::beg);
} // AsfVideo::extendedStreamProperties
@ -466,7 +492,6 @@ namespace Exiv2 {
}
for (int i = 0 ; i < 5 ; ++i) {
DataBuf buf(length[i]);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, length[i]);
if (io_->error() || io_->eof()) throw Error(14);
const TagDetails* td = find(contentDescriptionTags, i);
@ -510,7 +535,7 @@ namespace Exiv2 {
io_->read(buf.pData_, 8);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 1);
streamNumber_ = (int)buf.pData_[0] & 127;
d->streamNumber_ = (int)buf.pData_[0] & 127;
io_->read(buf.pData_, 5);
std::memset(buf.pData_, 0x0, buf.size_);
@ -519,7 +544,7 @@ namespace Exiv2 {
if(stream == 2) {
xmpData_["Xmp.video.Width"] = temp;
width_ = temp;
d->width_ = temp;
}
else if(stream == 1) {
xmpData_["Xmp.audio.Codec"] = test->printAudioEncoding(temp);
@ -535,7 +560,7 @@ namespace Exiv2 {
if(stream == 2) {
xmpData_["Xmp.video.Height"] = temp;
height_ = temp;
d->height_ = temp;
}
else if(stream == 1) {
xmpData_["Xmp.audio.SampleRate"] = temp;
@ -615,7 +640,7 @@ namespace Exiv2 {
buf.pData_[4] = '\0' ;
io_->read(buf.pData_, 4);
while(localPosition_ < cur_pos + size) decodeBlock();
while(d->localPosition_ < cur_pos + size) decodeBlock();
io_->seek(cur_pos + size, BasicIo::beg);
} // AsfVideo::headerExtension
@ -768,7 +793,7 @@ namespace Exiv2 {
{
//TODO - Make a better unified method to handle all cases of Aspect Ratio
double aspectRatio = (double)width_ / (double)height_;
double aspectRatio = (double)d->width_ / (double)d->height_;
aspectRatio = floor(aspectRatio*10) / 10;
xmpData_["Xmp.video.AspectRatio"] = aspectRatio;

View File

@ -69,6 +69,7 @@ namespace Exiv2 {
method to get a temporary reference.
*/
AsfVideo(BasicIo::AutoPtr io);
~AsfVideo();
//@}
//! @name Manipulators
@ -154,14 +155,9 @@ namespace Exiv2 {
//@}
private:
//! Variable to check the end of metadata traversing.
bool continueTraversing_;
//! Variable which stores current position of the read pointer.
uint64_t localPosition_;
//! Variable which stores current stream being processsed.
int streamNumber_;
//! Variable to store height and width of a video frame.
uint64_t height_, width_;
class Private;
Private * const d;
}; //Class AsfVideo

View File

@ -274,6 +274,11 @@ namespace Exiv2 {
}
template<typename charT> template<typename A>
/*!
* \brief BasicError<charT>::BasicError TODO
* \param code
* \param arg1
*/
BasicError<charT>::BasicError(int code, const A& arg1)
: code_(code), count_(1), arg1_(toBasicString<charT>(arg1))
{
@ -281,6 +286,12 @@ namespace Exiv2 {
}
template<typename charT> template<typename A, typename B>
/*!
* \brief BasicError<charT>::BasicError TODO
* \param code
* \param arg1
* \param arg2
*/
BasicError<charT>::BasicError(int code, const A& arg1, const B& arg2)
: code_(code), count_(2),
arg1_(toBasicString<charT>(arg1)),
@ -290,6 +301,13 @@ namespace Exiv2 {
}
template<typename charT> template<typename A, typename B, typename C>
/*!
* \brief BasicError<charT>::BasicError TODO
* \param code
* \param arg1
* \param arg2
* \param arg3
*/
BasicError<charT>::BasicError(int code, const A& arg1, const B& arg2, const C& arg3)
: code_(code), count_(3),
arg1_(toBasicString<charT>(arg1)),

View File

@ -131,8 +131,8 @@ namespace {
{ ImageType::tga, newTgaInstance, isTgaType, amNone, amNone, amNone, amNone },
{ ImageType::bmp, newBmpInstance, isBmpType, amNone, amNone, amNone, amNone },
{ ImageType::jp2, newJp2Instance, isJp2Type, amReadWrite, amReadWrite, amReadWrite, amNone },
{ ImageType::qtime,newQTimeInstance,isQTimeType,amRead, amNone, amRead, amNone },
{ ImageType::riff, newRiffInstance, isRiffType, amRead, amNone, amRead, amNone },
{ ImageType::qtime,newQTimeInstance,isQTimeType,amRead, amNone, amReadWrite, amNone },
{ ImageType::riff, newRiffInstance, isRiffType, amRead, amNone, amReadWrite, amNone },
{ ImageType::asf, newAsfInstance, isAsfType, amNone, amNone, amRead, amNone },
{ ImageType::mkv, newMkvInstance, isMkvType, amNone, amNone, amRead, amNone },
// End of list marker

File diff suppressed because it is too large Load Diff

View File

@ -37,36 +37,51 @@
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
namespace Exiv2
{
// *****************************************************************************
// class definitions
// Add MKV to the supported image formats
namespace ImageType {
const int mkv = 21; //!< Treating mkv as an image type>
}
// Add MKV to the supported image formats
namespace ImageType
{
const int mkv = 21; //!< Treating mkv as an image type>
}
// Todo: Should be hidden
/*!
// Todo: Should be hidden
/*!
@brief Helper structure for the Matroska tags lookup table.
*/
struct MatroskaTags {
uint64_t val_; //!< Tag value
const char* label_; //!< Translation of the tag value
struct MatroskaTags
{
uint64_t val_; //!< Tag value
const char* label_; //!< Translation of the tag value
//! Comparison operator for use with the find template
bool operator==(uint64_t key) const { return val_ == key; }
}; // struct TagDetails
//! Comparison operator for use with the find template
bool operator==(uint64_t key) const { return val_ == key; }
}; // struct TagDetails
/*!
/*!
* \brief The RevMatroskaTags struct reverse the matroskatag structure.
*/
struct RevMatroskaTags
{
const char* label_; //!< Translation of the tag value
uint64_t val_; //!< Tag value
//! Comparison operator for use with the find template
bool operator==(const std::string& key) const{return label_ == key;}
};
/*!
@brief Class to access Matroska video files.
*/
class EXIV2API MatroskaVideo : public Image {
public:
//! @name Creators
//@{
/*!
class EXIV2API MatroskaVideo : public Image
{
public:
//! @name Creators
//@{
/*!
@brief Constructor for a Matroska video. Since the constructor
can not return a result, callers should check the good() method
after object construction to determine success or failure.
@ -77,22 +92,22 @@ namespace Exiv2 {
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
MatroskaVideo(BasicIo::AutoPtr io);
//@}
MatroskaVideo(BasicIo::AutoPtr io);
//@}
//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}
//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}
//! @name Accessors
//@{
std::string mimeType() const;
//@}
//! @name Accessors
//@{
std::string mimeType() const;
//@}
protected:
/*!
protected:
/*!
@brief Function used to calulate the size of a block.
This information is only stored in one byte.
The size of the block is calculated by counting
@ -101,56 +116,79 @@ namespace Exiv2 {
@param b The byte, which stores the information to calculate the size
@return Return the size of the block.
*/
uint32_t findBlockSize(byte b);
/*!
uint32_t findBlockSize(byte b);
/*!
@brief Check for a valid tag and decode the block at the current IO position.
Calls contentManagement() or skips to next tag, if required.
*/
void decodeBlock();
/*!
void decodeBlock();
/*!
@brief Interpret tag information, and save it in the respective XMP container.
@param mt Pointer to current tag,
@param buf Pointer to the memory area with the tag information.
@param size Size of \em buf.
*/
void contentManagement(const MatroskaTags* mt, const byte* buf, long size);
/*!
void contentManagement(const MatroskaTags* mt, const Exiv2::byte* buf, int32_t size);
/*!
@brief Calculates Aspect Ratio of a video, and stores it in the
respective XMP container.
*/
void aspectRatio();
void aspectRatio();
private:
//! @name NOT Implemented
//@{
//! Copy constructor
MatroskaVideo(const MatroskaVideo& rhs);
//! Assignment operator
MatroskaVideo& operator=(const MatroskaVideo& rhs);
//@}
private:
//! @name NOT Implemented
//@{
//! Copy constructor
MatroskaVideo(const MatroskaVideo& rhs);
//! Assignment operator
MatroskaVideo& operator=(const MatroskaVideo& rhs);
~MatroskaVideo();
//@}
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@param oIo BasicIo instance to write to (a temporary location).
private:
//! Variable to check the end of metadata traversing.
bool continueTraversing_;
//! Variable to store height and width of a video frame.
uint64_t height_, width_;
@return 4 if opening or writing to the associated BasicIo fails
*/
EXV_DLLLOCAL void doWriteMetadata();
}; // class MatroskaVideo
/*!
* \brief writeStringData
* \param xmpStringData
* \param size
* \param skipOffset
*/
void writeStringData(Exiv2::Xmpdatum xmpStringData, int32_t size, int32_t skipOffset=0);
/*!
* \brief writeMatroskaKey
* \param inputStruct
* \param size
*/
void writeMatroskaKey(const RevMatroskaTags *revInternalMt, int32_t size);
private:
class Private;
Private * const d;
}; // class MatroskaVideo
// *****************************************************************************
// template, inline and free functions
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
// These could be static private functions on Image subclasses but then
// ImageFactory needs to be made a friend.
/*!
@brief Create a new MatroskaVideo 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::AutoPtr newMkvInstance(BasicIo::AutoPtr io, bool create);
EXIV2API Image::AutoPtr newMkvInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a Matroska Video.
EXIV2API bool isMkvType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a Matroska Video.
EXIV2API bool isMkvType(BasicIo& iIo, bool advance);
} // namespace Exiv2

File diff suppressed because it is too large Load Diff

View File

@ -22,13 +22,16 @@
@file quicktimevideo.hpp
@brief An Image subclass to support Quick Time video files
@version $Rev$
@author Abhinav Badola for GSoC 2012
@authors Abhinav Badola for GSoC 2012
<a href="mailto:mail.abu.to@gmail.com">mail.abu.to@gmail.com</a>
Mahesh Hegde for GSoC 2013
<a href="maheshmhegade at gmail dot com">maheshmhegade@gmail.com</a>
@date 28-Jun-12, AB: created
*/
#ifndef QUICKTIMEVIDEO_HPP
#define QUICKTIMEVIDEO_HPP
#include <iostream>
using namespace std;
// *****************************************************************************
// included header files
#include "exif.hpp"
@ -42,20 +45,36 @@ namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add qtime to the supported image formats
namespace ImageType {
const int qtime = 22; //!< Treating qtime as an image type>
}
// Add qtime to the supported image formats
namespace ImageType {
const int qtime = 22; //!< Treating qtime as an image type>
}
/*!
/*!
@brief Class to access QuickTime video files.
*/
class EXIV2API QuickTimeVideo:public Image
class EXIV2API QuickTimeVideo:public Image
{
public:
/*!
* \brief The QuickAtom class:
*Object of this class is intended to contain data about the premitive atom inside
*any atom
*/
class QuickAtom
{
public:
//! @name Creators
//@{
/*!
QuickAtom(){}
~QuickAtom(){}
public:
byte m_AtomId[5]; //!< Id of the Atom.
unsigned long m_AtomLocation; //!< Location of atom inside a file
unsigned long m_AtomSize; //!< Size of atom
};
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.
@ -66,27 +85,28 @@ namespace Exiv2 {
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
QuickTimeVideo(BasicIo::AutoPtr io);
//@}
QuickTimeVideo(BasicIo::AutoPtr io);
//@}
//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}
~QuickTimeVideo();
//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}
//! @name Accessors
//@{
std::string mimeType() const;
//@}
//! @name Accessors
//@{
std::string mimeType() const;
//@}
protected:
/*!
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();
/*!
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
@ -94,159 +114,236 @@ namespace Exiv2 {
@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, unsigned long size);
void tagDecoder(Exiv2::DataBuf & buf, uint32_t size);
private:
/*!
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(unsigned long size);
/*!
void fileTypeDecoder(uint32_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(unsigned long size);
/*!
void mediaHeaderDecoder(uint32_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(unsigned long size);
/*!
void videoHeaderDecoder(uint32_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(unsigned long size);
/*!
void movieHeaderDecoder(uint32_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(unsigned long size);
/*!
void trackHeaderDecoder(uint32_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(unsigned long size);
/*!
void handlerDecoder(uint32_t size);
/*!
@brief Interpret Tag which contain other sub-tags,
and save it in the respective XMP container.
*/
void multipleEntriesDecoder();
/*!
void multipleEntriesDecoder(uint32_t iDummySize);
/*!
@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(unsigned long size);
/*!
void sampleDesc(uint32_t size);
/*!
@brief Interpret Image Description Tag, and save it
in the respective XMP container.
*/
void imageDescDecoder();
/*!
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(unsigned long size);
/*!
void userDataDecoder(uint32_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(unsigned long size);
/*!
void previewTagDecoder(uint32_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(unsigned long size);
/*!
void keysTagDecoder(uint32_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(unsigned long size);
/*!
void trackApertureTagDecoder(uint32_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(unsigned long size);
/*!
void NikonTagsDecoder(uint32_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(unsigned long size);
/*!
void CameraTagsDecoder(uint32_t size);
/*!
@brief Interpret Audio Description Tag, and save it
in the respective XMP container.
*/
void audioDescDecoder();
/*!
void audioDescDecoder();
/*!
@brief Helps to calculate Frame Rate from timeToSample chunk,
and save it in the respective XMP container.
*/
void timeToSampleDecoder();
/*!
void timeToSampleDecoder(uint32_t iDummySize);
/*!
@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(unsigned long size);
/*!
void setMediaStream(uint32_t iDummySize);
/*!
@brief Calculates Aspect Ratio of a video, and stores it in the
respective XMP container.
*/
void aspectRatio();
void aspectRatio();
/*!
* \brief reverseTagDetails
* \param inputTagVocabulary
* \param outputTagVocabulary
* \param size
*/
void reverseTagDetails(const Internal::TagDetails inputTagVocabulary[],
Internal::RevTagDetails outputTagVocabulary[] , int32_t size);
private:
//! @name NOT Implemented
//@{
//! Copy constructor
QuickTimeVideo(const QuickTimeVideo& rhs);
//! Assignment operator
QuickTimeVideo& operator=(const QuickTimeVideo& rhs);
//@}
private:
//! @name NOT Implemented
//@{
//! Copy constructor
QuickTimeVideo(const QuickTimeVideo& rhs);
//! Assignment operator
QuickTimeVideo& operator=(const QuickTimeVideo& rhs);
//@}
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@param oIo BasicIo instance to write to (a temporary location).
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_;
@return 4 if opening or writing to the associated BasicIo fails
*/
EXV_DLLLOCAL void doWriteMetadata();
/*!
* \brief findAtomPositions
* \param atomId
* \return all the locations where atoms with atomId exist.
*/
std::vector< pair<uint32_t,uint32_t> > findAtomPositions(const char *atomId);
}; //QuickTimeVideo End
/*!
* \brief writeStringData
* \param xmpStringData
* \param size
* \param skipOffset
*/
void writeStringData(Exiv2::Xmpdatum xmpStringData, int32_t size, int32_t skipOffset=0);
/*!
* \brief writeLongData
* \param xmpIntData
* \param size
* \param skipOffset
*/
void writeLongData(Exiv2::Xmpdatum xmpIntData, int32_t size=4, int32_t skipOffset=0);
/*!
* \brief writeShortData
* \param xmpIntData
* \param size
* \param skipOffset
*/
void writeShortData(Exiv2::Xmpdatum xmpIntData, int16_t size=2, int32_t skipOffset=0);
/*!
* \brief writeMultibyte
* \param bRawData
* \param size
*/
bool writeMultibyte(Exiv2::byte * bRawData = NULL , int64_t iSize = 0, int64_t iOffset = 0);
/*!
* \brief writeApertureData
* \param xmpIntData
* \param size
* \param skipOffset
*/
void writeApertureData(Exiv2::Xmpdatum xmpIntData, int16_t size, int32_t skipOffset=0);
/*!
* \brief writeAudVidData
* \param iTagType
* \return
*/
bool writeAudVidData(int64_t iTagType);
/*!
* \brief writeAudVidData
* \param sXmpTag
* \param iOffset
* \return
*/
bool writeAudVidData( std::string sXmpTag, double iMulFactor, int64_t iBytCnt, int64_t iOffset, int64_t iRetFuncCall);
/*!
* \brief readAudVidData
* \param sTag
* \param iNumRdBytes
* \param dMulFact
* \param iFunc2Call
*/
void readAudVidData(std::string sTag, int32_t iNumRdBytes, double dMulFact ,int32_t iFunc2Call);
void readAudVidStrData(std::string sTag, int32_t iNumRdBytes);
void readStrData(std::string sTag, int32_t iNumRdBytes);
private:
class Private;
Private * const d;
}; //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.
/*!
// 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.
*/
EXIV2API Image::AutoPtr newQTimeInstance(BasicIo::AutoPtr io, bool create);
EXIV2API Image::AutoPtr newQTimeInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a Quick Time Video.
EXIV2API bool isQTimeType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a Quick Time Video.
EXIV2API bool isQTimeType(BasicIo& iIo, bool advance);
} // namespace Exiv2

File diff suppressed because it is too large Load Diff

View File

@ -22,8 +22,11 @@
@file riffvideo.hpp
@brief An Image subclass to support RIFF video files
@version $Rev$
@author Abhinav Badola for GSoC 2012
@authors Abhinav Badola for GSoC 2012
<a href="mailto:mail.abu.to@gmail.com">mail.abu.to@gmail.com</a>
Mahesh Hegde for GSoC 2013
<b href="mailto:maheshmhegade@gmail.com">maheshmhegade@gmail.com</b>
@date 18-Jun-12, AB: created
*/
#ifndef RIFFVIDEO_HPP
@ -42,20 +45,78 @@ namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add RIFF to the supported image formats
namespace ImageType {
const int riff = 20; //!< Treating riff as an image type>
}
// Add RIFF to the supported image formats
namespace ImageType {
const int riff = 20; //!< Treating riff as an image type>
}
/*!
using namespace std;
/*!
@brief Class to access RIFF video files.
*/
class EXIV2API RiffVideo:public Image
class EXIV2API RiffVideo:public Image
{
public:
//List, Header,Primitive and Junk chunks inside m_riffFileSkeleton reveal entire RIFF structure
/*!
* \brief The PrimitiveChunk class Hold the information about a unit chunk.
*/
class PrimitiveChunk
{
public:
//! @name Creators
//@{
/*!
PrimitiveChunk(){}
~PrimitiveChunk(){}
public:
byte m_chunkId[5]; //!< Primitive chunk ID.
uint64_t m_chunkLocation; //!< Chunk location in afile.
uint64_t m_chunkSize; //!< Chunk size.
};
/*!
* \brief The HeaderChunk class Hold the information about Header chunk
* Containing multiple primitive chunks.
*/
class HeaderChunk
{
public:
HeaderChunk(){}
~HeaderChunk(){}
public:
byte m_headerId[5]; //!< Chunk Header Id
unsigned long m_headerLocation; //!< Header Chunk Location in a file.
unsigned long m_headerSize; //!< Header Chunk size
};
/*!
* \brief The RiffMetaSkeleton class Hold information about all the
* chunks present in a file.
*/
class RiffMetaSkeleton
{
public:
RiffMetaSkeleton(){}
~RiffMetaSkeleton(){}
public:
vector<HeaderChunk*> m_headerChunks; //!< vector containing all Header chunks.
vector<PrimitiveChunk*> m_primitiveChunks; //!< vector Containing all the primitve chunks
};
/*!
* \brief The IoPosition enum reveal the position,while traversing the file.
*/
enum IoPosition
{
LastChunk, //!< "MOVI" or "DATA"
TraversingChunk, //!< "AVI" "hdrl" etc which further have sub-chunks
PremitiveChunk //!< Remaining chunks which do not have subchunk
};
//! @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.
@ -66,149 +127,227 @@ namespace Exiv2 {
instance after it is passed to this method. Use the Image::io()
method to get a temporary reference.
*/
RiffVideo(BasicIo::AutoPtr io);
//@}
RiffVideo(BasicIo::AutoPtr io);
//@}
//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}
~RiffVideo();
//! @name Accessors
//@{
std::string mimeType() const;
const char* printAudioEncoding(uint64_t i);
//@}
//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}
protected:
/*!
//! @name Accessors
//@{
std::string mimeType() const;
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, unsigned long size);
/*!
void decodeBlock();
/*!
* \brief tagDecoder Main method to call corresponding handler methos for decoding tags.
*/
void tagDecoder();
/*!
@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(long size);
/*!
void junkHandler(int32_t size);
/*! find whether stream is audio or video
*/
void setStreamType();
/*!
@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(long size);
/*!
void streamHandler(int32_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(long size);
/*!
void streamFormatHandler(int32_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(long size);
/*!
void aviHeaderTagsHandler(int32_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(long size);
/*!
void listHandler(long 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(long size);
/*!
void streamDataTagHandler(int32_t size);
/*!
@brief Interpret INFO tag information, and save it
in the respective XMP container.
*/
void infoTagsHandler();
/*!
void infoTagsHandler();
/*!
@brief Interpret Nikon Tags related to Video information, and
save it in the respective XMP container.
*/
void nikonTagsHandler();
/*!
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();
/*!
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(long size, int i = 0);
/*!
void dateTimeOriginal(int32_t size, int32_t 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.
*/
double returnSampleRate(Exiv2::DataBuf& buf, long divisor = 1);
/*!
double returnSampleRate(Exiv2::DataBuf& buf, int32_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(long width = 1,long height = 1);
/*!
void fillAspectRatio(int32_t width = 1, int32_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, long frame_count);
void fillDuration(double frame_rate, int32_t frame_count);
private:
//! @name NOT Implemented
//@{
//! Copy constructor
RiffVideo(const RiffVideo& rhs);
//! Assignment operator
RiffVideo& operator=(const RiffVideo& rhs);
//@}
/*!
* \brief copyRestOfTheFile copy rest of the file content as it is
* \param oldSavedData saved data from file, where data is already written into the file.
* \return
*/
bool copyRestOfTheFile(DataBuf oldSavedData);
private:
//! Variable to check the end of metadata traversing.
bool continueTraversing_;
//! Variable which stores current stream being processsed.
int streamType_;
/*!
* \brief reverseTagDetails reverse the position of members of a structure
* \param inputTagVocabulary
* \param outputTagVocabulary
* \param size
*/
void reverseTagDetails(const Internal::TagDetails inputTagVocabulary[],
Internal::RevTagDetails outputTagVocabulary[] , int32_t size);
}; //Class RiffVideo
private:
//! @name NOT Implemented
//@{
//! Copy constructor
RiffVideo(const RiffVideo& rhs);
//! Assignment operator
RiffVideo& operator=(const RiffVideo& rhs);
//@}
/*!
@brief Provides the main implementation of writeMetadata() by
writing all buffered metadata to the provided BasicIo.
@param oIo BasicIo instance to write to (a temporary location).
@return 4 if opening or writing to the associated BasicIo fails
*/
EXV_DLLLOCAL void doWriteMetadata();
/*!
* \brief findChunkPositions Finds the primitive shunk position in a file.
* \param chunkId Id of chunk to be searched
* \return
*/
std::vector<int32_t> findChunkPositions(const char *chunkId);
/*!
* \brief findHeaderPositions Finds the location of Header chunk in a file.
* \param headerId Id of Header Chunk to be searched.
* \return
*/
std::vector<int32_t> findHeaderPositions(const char* headerId);
/*!
* \brief writeNewSubChunks Writes the new chunk,also hold the data from overwritten
* location in a file.
* \param chunkData vector containing chunk ID and chunk Data
* \return
*/
bool writeNewSubChunks(std::vector<std::pair<std::string,std::string> > chunkData);
/*!
* \brief writeStringData
* \param stringData
* \param skipOffset
*/
void writeStringData(Exiv2::Xmpdatum xmpStringData, int32_t size, int32_t skipOffset=0);
/*!
* \brief writeLongData
* \param xmpIntData
* \param size
* \param skipOffset
*/
void writeLongData(Exiv2::Xmpdatum xmpIntData, int32_t size=4, int32_t skipOffset=0);
/*!
* \brief writeFloatData
* \param xmpIntData
* \param size
* \param skipOffset
*/
void writeFloatData(Exiv2::Xmpdatum xmpIntData, int32_t size=4, int32_t skipOffset=0);
/*!
* \brief writeShortData
* \param xmpIntData
* \param size
* \param skipOffset
*/
void writeShortData(Exiv2::Xmpdatum xmpIntData, int16_t size=2, int32_t skipOffset=0);
private:
// Good idea to use private(Refer KDE documentaion https://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++ )
class Private;
Private* const d;
}; //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.
/*!
// 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::AutoPtr newRiffInstance(BasicIo::AutoPtr io, bool create);
EXIV2API Image::AutoPtr newRiffInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a Riff Video.
EXIV2API bool isRiffType(BasicIo& iIo, bool advance);
//! Check if the file iIo is a Riff Video.
EXIV2API bool isRiffType(BasicIo& iIo, bool advance);
} // namespace Exiv2

View File

@ -191,6 +191,18 @@ namespace Exiv2 {
bool operator==(long key) const { return val_ == key; }
}; // struct TagDetails
/*!
@brief Helper structure for lookup tables for translations of numeric
tag values to human readable labels.
*/
struct RevTagDetails {
const char* label_; //!< Translation of the tag value
long val_; //!< Tag value
//! Comparison operator for use with the find template
bool operator==(const std::string& key) const{return label_ == key;}
};
/*!
@brief Helper structure for lookup tables for translations of bitmask
values to human readable labels.

View File

@ -125,10 +125,12 @@ namespace Exiv2 {
return tit->size_;
}
DataBuf::DataBuf(DataBuf& rhs)
DataBuf::DataBuf(const DataBuf& rhs)
: pData_(rhs.pData_), size_(rhs.size_)
{
rhs.release();
pData_ = new byte[rhs.size_];
size_ = rhs.size_;
std::copy(rhs.pData_,rhs.pData_+rhs.size_,pData_);
}
DataBuf::DataBuf(const byte* pData, long size)
@ -156,6 +158,7 @@ namespace Exiv2 {
size_ = 0;
pData_ = new byte[size];
size_ = size;
std::memset(pData_, 0x0, size_);
}
}

View File

@ -54,6 +54,7 @@
#include <utility>
#include <algorithm>
#include <sstream>
#include <cstring>
#ifdef EXV_HAVE_STDINT_H
# include <stdint.h>
@ -209,7 +210,7 @@ namespace Exiv2 {
//! Default constructor
DataBuf() : pData_(0), size_(0) {}
//! Constructor with an initial buffer size
explicit DataBuf(long size) : pData_(new byte[size]), size_(size) {}
explicit DataBuf(long size) : pData_(new byte[size]), size_(size) { std::memset(pData_, 0x0, size_); }
//! Constructor, copies an existing buffer
DataBuf(const byte* pData, long size);
/*!
@ -217,7 +218,7 @@ namespace Exiv2 {
object similar to std::auto_ptr, i.e., the original object is
modified.
*/
DataBuf(DataBuf& rhs);
DataBuf(const DataBuf& rhs);
//! Destructor, deletes the allocated buffer
~DataBuf() { delete[] pData_; }
//@}

60
src/utilsvideo.cpp Normal file
View File

@ -0,0 +1,60 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2014 Andreas Huggel <ahuggel@gmx.net>
*
* 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.
*/
/*!
@file utilsvideo.hpp
@brief An Image subclass to support RIFF video files
@version $Rev$
Mahesh Hegde 2014
<b href="mailto:maheshmhegade@gmail.com">maheshmhegade@gmail.com</b>
@date 16-Aug-14, AB: created
*/
#include "utilsvideo.hpp"
#ifndef _MSC_VER
#define stricmp strcasecmp
#endif
namespace Exiv2
{
bool UtilsVideo::compareTagValue(Exiv2::DataBuf& buf ,const char* str){
bool result = true;
for(int32_t i=0; result && i<4; i++ )
if(tolower(buf.pData_[i]) != tolower(str[i]))
return false;
return true;
}
bool UtilsVideo::compareTagValue(Exiv2::DataBuf& buf,const char arr[][5],int32_t arraysize){
bool result = false;
for ( int32_t i=0; !result && i< arraysize; i++)
result = (bool)(stricmp((const char*)buf.pData_,arr[i])==0);
return result;
}
bool UtilsVideo::simpleBytesComparision(Exiv2::DataBuf& buf ,const char* str,int32_t size){
for(int32_t i=0; i<size; i++ )
if(toupper(buf.pData_[i]) != str[i])
return false;
return true;
}
} // namespace Exiv2

42
src/utilsvideo.hpp Normal file
View File

@ -0,0 +1,42 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2014 Andreas Huggel <ahuggel@gmx.net>
*
* 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.
*/
/*!
@file utilsvideo.hpp
@brief An Image subclass to support RIFF video files
@version $Rev$
Mahesh Hegde 2014
<b href="mailto:maheshmhegade@gmail.com">maheshmhegade@gmail.com</b>
@date 16-Aug-14, AB: created
*/
#include "tags_int.hpp"
namespace Exiv2
{
class UtilsVideo
{
public:
static bool compareTagValue(Exiv2::DataBuf &buf, const char *str);
static bool compareTagValue(Exiv2::DataBuf& buf,const char arr[][5],int32_t arraysize);
static bool simpleBytesComparision(Exiv2::DataBuf& buf ,const char* str,int32_t size);
}; // class UtilsVideo
} // namespace Exiv2

View File

@ -187,6 +187,7 @@ namespace Exiv2 {
// dumpLibraryInfo is general purpose and not in the Exiv2 namespace
// used by exiv2 test suite to inspect libraries loaded at run-time
//! TO be completed.
EXIV2API void dumpLibraryInfo(std::ostream& os);

View File

@ -416,6 +416,8 @@ namespace Exiv2 {
SXMPMeta::RegisterNamespace("http://ns.microsoft.com/photo/1.2/t/Region#", "MPReg");
SXMPMeta::RegisterNamespace("http://www.metadataworkinggroup.com/schemas/regions/", "mwg-rs");
SXMPMeta::RegisterNamespace("http://ns.adobe.com/xmp/sType/Area#", "stArea");
SXMPMeta::RegisterNamespace("http://www.video/", "video");
SXMPMeta::RegisterNamespace("http://www.audio/", "audio");
#else
initialized_ = true;
#endif

View File

@ -65,24 +65,25 @@ SVN = svn://dev.exiv2.org/svn/testdata/trunk
##
# Add test drivers to this list
TESTS = addmoddel.sh \
bugfixes-test.sh \
exifdata-test.sh \
exiv2-test.sh \
imagetest.sh \
iotest.sh \
iptctest.sh \
modify-test.sh \
path-test.sh \
preview-test.sh \
stringto-test.sh \
tiff-test.sh \
write-test.sh \
write2-test.sh \
xmpparser-test.sh \
conversions.sh
TESTV = video-test.sh
TESTE = eps-test.sh
TESTS = addmoddel.sh \
bugfixes-test.sh \
exifdata-test.sh \
exiv2-test.sh \
imagetest.sh \
iotest.sh \
iptctest.sh \
modify-test.sh \
path-test.sh \
preview-test.sh \
stringto-test.sh \
tiff-test.sh \
write-test.sh \
write2-test.sh \
xmpparser-test.sh \
conversions.sh
TESTV = video-test.sh
TESTE = eps-test.sh
TESTVW = write-video-test.sh
tests:
cd .. ; make tests
@ -99,15 +100,26 @@ test:
testv:
@for t in /video ; do \
if [ ! -e data/$$t ]; then \
echo svn export '$(SVN)'$$t data$$t -r 3100 ; \
svn export '$(SVN)'$$t data$$t -r 3100 ; \
echo svn export '$(SVN)'$$t data$$t ; \
svn export '$(SVN)'$$t data$$t ; \
fi ; done
@list='$(TESTV)'; for p in $$list; do \
echo Running $$p ...; \
./$$p; \
done
testvw:
@for t in /video ; do \
if [ ! -e data/$$t ]; then \
echo svn export '$(SVN)'$$t data$$t ; \
svn export '$(SVN)'$$t data$$t ; \
fi ; done
@list='$(TESTVW)'; for p in $$list; do \
echo Running $$p ...; \
./$$p; \
done
##
# TODO: download eps data on demand for 0.24 (similar to testv)
teste:
@list='$(TESTE)'; for p in $$list; do \

View File

@ -52,7 +52,8 @@ copyTestFile()
if [ $# == 2 ]; then
cp -f "$here/data/$1" "$here/tmp/$2"
elif [ $# == 1 ]; then
cp -f "$here/data/$1" "$here/tmp/$1"
stub=$(basename $1)
cp -f "$here/data/$1" "$here/tmp/$stub"
else
echo "*** error copyTestFile: illegal number of inputs = $# ***"
fi
@ -213,14 +214,14 @@ iptcTest()
# Make sure to pass the test file first and the known good file second
diffCheck()
{
test=$1
good=$2
test=$(real_path $1)
good=$(real_path $2)
if [ -z "$errors" ]; then let -a errors=0; fi
#run diff and check results
diff -q --binary $diffargs $test $good
diff -q --binary $diffargs "$test" "$good"
if [ $? -ne 0 ]; then
errors=`expr $errors + 1`
errors=$(expr $errors + 1)
else
rm $test
fi
@ -341,39 +342,49 @@ extendedTest()
rm $tmp
}
##
# http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac
# real_path - report the absolute path to a file
real_path ()
{
OIFS=$IFS
IFS='/'
for I in $1; do
# Resolve relative path punctuation.
if [ "$I" = "." ] || [ -z "$I" ]; then
continue
elif [ "$I" = ".." ]; then
FOO="${FOO%%/${FOO##*/}}"
continue
else
FOO="${FOO}/${I}"
fi
which realpath 2>/dev/null >/dev/null
if [ $? == 0 ]; then
realpath "$1"
else
readlink -f "$1"
fi
}
## Resolve symbolic links
if [ -h "$FOO" ]; then
IFS=$OIFS
set `ls -l "$FOO"`
while shift ; do
if [ "$1" = "->" ]; then
FOO=$2
shift $#
break
fi
done
IFS='/'
fi
done
IFS=$OIFS
echo "$FOO"
copyVideoFiles ()
{
pushd "$testdir" 2>/dev/null >/dev/null
##
# find video files data/video and copy them for testing
declare -a videos
for video in $datadir/video/* ; do
# http://stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash
ext="${video##*.}"
if [ $ext != out ]; then
copyTestFile "$video"
videos+=($(basename "$video"))
fi
done
##
# TODO: remove debugging code
if [ "$FACTORY" == "rmills-mbp.localXX" ]; then
for v in write-video-test.out video-test.out; do
cp ~/gnu/exiv2/testdata/trunk/video/$v ~/gnu/exiv2/video13/test/data/video/
done
fi
# http://stackoverflow.com/questions/7442417/how-to-sort-an-array-in-bash
readarray -t sorted < <(printf '%s\0' "${videos[@]}" | sort -z | xargs -0n1)
echo ${videos[*]}
unset videos
popd 2>/dev/null >/dev/null
}
##

View File

@ -8,42 +8,35 @@
source ./functions.source
##
# set up output and reference file
out=$(real_path "$testdir/$this.out")
copyTestFile "video/$this.out"
( cd "$testdir"
for file in ../data/video/video-*; do
video="`basename "$file"`"
if [ $video != "video-test.out" ] ; then
printf "." >&3
echo
echo "-----> $video <-----"
copyTestFile "video/$video" "$video"
echo
echo "Command: exiv2 -u -pa $video"
runTest exiv2 -u -pa "$video"
exitcode="$?"
echo "Exit code: $exitcode"
if [ "$exitcode" -ne 0 -a "$exitcode" -ne 253 ] ; then
continue
fi
fi
videos=($(copyVideoFiles))
for video in ${videos[*]}; do
printf "." >&3
echo
echo "-----> $video <-----"
echo
echo "Command: exiv2 -u -pa $video"
# run command | ignore binary and no Date nor NumOfColours tags
runTest exiv2 -u -pa "$video" | sed -E -e 's/\d128-\d255/_/g' | grep -a -v -e Date -v -e NumOfC
done
) 3>&1 > "$testdir/video-test.out" 2>&1
echo "."
) 3>&1 2>&1 > "$out"
# ----------------------------------------------------------------------
# Result
if ! diff -q $diffargs "$testdir/$datadir/video/video-test.out" "$testdir/video-test.out" ; then
diff -u -a $diffargs "$testdir/$datadir/video/video-test.out" "$testdir/video-test.out"
exit 1
diffCheck "$out" "$testdir/$datadir/video/$this.out"
if [ $errors ]; then
echo -e $errors 'test case(s) failed!'
else
echo -e "all testcases passed."
fi
echo "All testcases passed."
# That's all Folks!
##
##

68
test/write-video-test.sh Executable file
View File

@ -0,0 +1,68 @@
#!/bin/bash
# Test driver for write video
source ./functions.source
##
# set up output and reference file
out=$(real_path "$testdir/$this.out")
copyTestFile "video/$this.out"
( cd "$testdir"
videos=($(copyVideoFiles))
# write metadata to videos
runTest exiv2 -M "set Xmp.video.MicroSecPerFrame 64" ${videos[*]}
runTest exiv2 -M "set Xmp.video.MaxDataRate 4096" ${videos[*]}
runTest exiv2 -M "set Xmp.video.FrameCount 2048" ${videos[*]}
runTest exiv2 -M "set Xmp.video.InitialFrames 4" ${videos[*]}
runTest exiv2 -M "set Xmp.video.StreamCount 2" ${videos[*]}
runTest exiv2 -M "set Xmp.video.SuggestedBufferSize 1024" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Width 240" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Height 320" ${videos[*]}
runTest exiv2 -M "set Xmp.video.FileDataRate 128" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Duration 2048" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Codec mjpg" ${videos[*]}
runTest exiv2 -M "set Xmp.video.FrameRate 1024" ${videos[*]}
runTest exiv2 -M "set Xmp.video.VideoQuality 128" ${videos[*]}
runTest exiv2 -M "set Xmp.video.VideoSampleSize 256" ${videos[*]}
runTest exiv2 -M "set Xmp.audio.Codec mpv4" ${videos[*]}
runTest exiv2 -M "set Xmp.audio.SampleRate 32" ${videos[*]}
runTest exiv2 -M "set Xmp.audio.SampleCount 32" ${videos[*]}
runTest exiv2 -M "set Xmp.video.DateUT $date" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Comment Metadata was Edited Using Exiv2" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Language Kannada" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Country India" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Copyright Photographer" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Genre Sample Test Video" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Software Exiv2 0.25" ${videos[*]}
runTest exiv2 -M "set Xmp.video.Junk Its a junk Data" ${videos[*]}
runTest exiv2 -M "set Xmp.video.MediaLanguage English" ${videos[*]}
for video in ${videos[*]}; do
printf "." >&3
echo
echo "-----> $video <-----"
echo
echo "Command: exiv2 -u -pa $video"
# run command | ignore binary and no Date nor NumOfColours tags
runTest exiv2 -u -pa "$video" | sed -E -e 's/\d128-\d255/_/g' | grep -a -v -e Date
done
) 3>&1 2>&1 > "$out"
echo "."
# ----------------------------------------------------------------------
# Result
diffCheck "$out" "$testdir/$datadir/video/$this.out"
if [ $errors ]; then
echo -e $errors 'test case(s) failed!'
else
echo -e "all testcases passed."
fi
# That's all Folks!
##