Merge branch 'gsoc2012'

v0.27.3
Andreas Huggel 13 years ago
parent 233f0dd986
commit 9b131f3c61

@ -32,7 +32,8 @@ SET( LIBEXIV2_PRIVATE_HDR canonmn_int.hpp
)
# Add standalone C++ header files to this list
SET( LIBEXIV2_HDR basicio.hpp
SET( LIBEXIV2_HDR asfvideo.hpp
basicio.hpp
bmpimage.hpp
convert.hpp
cr2image.hpp
@ -49,6 +50,7 @@ SET( LIBEXIV2_HDR basicio.hpp
iptc.hpp
jp2image.hpp
jpgimage.hpp
matroskavideo.hpp
metadatum.hpp
mrwimage.hpp
orfimage.hpp
@ -56,7 +58,9 @@ SET( LIBEXIV2_HDR basicio.hpp
preview.hpp
properties.hpp
psdimage.hpp
quicktimevideo.hpp
rafimage.hpp
riffvideo.hpp
rw2image.hpp
tags.hpp
tgaimage.hpp
@ -69,7 +73,8 @@ SET( LIBEXIV2_HDR basicio.hpp
)
# Add library C++ source files to this list
SET( LIBEXIV2_SRC basicio.cpp
SET( LIBEXIV2_SRC asfvideo.cpp
basicio.cpp
bmpimage.cpp
canonmn.cpp
convert.cpp
@ -89,6 +94,7 @@ SET( LIBEXIV2_SRC basicio.cpp
jp2image.cpp
jpgimage.cpp
makernote.cpp
matroskavideo.cpp
metadatum.cpp
minoltamn.cpp
mrwimage.cpp
@ -101,7 +107,9 @@ SET( LIBEXIV2_SRC basicio.cpp
preview.cpp
properties.cpp
psdimage.cpp
quicktimevideo.cpp
rafimage.cpp
riffvideo.cpp
rw2image.cpp
samsungmn.cpp
sigmamn.cpp
@ -182,13 +190,16 @@ msvc_runtime_configure(${EXIV2_ENABLE_SHARED})
# ******************************************************************************
# exiv2lib library
ADD_LIBRARY( exiv2lib ${STATIC_FLAG} ${LIBEXIV2_SRC} ${LIBEXIV2_HDR} )
SET_TARGET_PROPERTIES( exiv2lib PROPERTIES
VERSION ${GENERIC_LIB_VERSION}
SOVERSION ${GENERIC_LIB_SOVERSION}
DEFINE_SYMBOL EXV_BUILDING_LIB
OUTPUT_NAME exiv2
)
if ( MSVC )
source_group("Header Files" FILES ${LIBEXIV2_HDR} )
endif()

@ -65,7 +65,8 @@ CCHDR = exiv2.hpp \
version.hpp
# Add library C++ source files to this list
CCSRC = basicio.cpp \
CCSRC = asfvideo.cpp \
basicio.cpp \
bmpimage.cpp \
canonmn.cpp \
convert.cpp \
@ -84,6 +85,7 @@ CCSRC = basicio.cpp \
jp2image.cpp \
jpgimage.cpp \
makernote.cpp \
matroskavideo.cpp \
metadatum.cpp \
minoltamn.cpp \
mrwimage.cpp \
@ -99,7 +101,9 @@ endif
CCSRC += preview.cpp \
properties.cpp \
psdimage.cpp \
quicktimevideo.cpp \
rafimage.cpp \
riffvideo.cpp \
rw2image.cpp \
samsungmn.cpp \
sigmamn.cpp \

@ -0,0 +1,746 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2012 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: asfvideo.cpp
Version: $Rev$
Author(s): Abhinav Badola for GSoC 2012 (AB) <mail.abu.to@gmail.com>
History: 08-Aug-12, AB: created
Credits: See header file
*/
// *****************************************************************************
#include "rcsid_int.hpp"
EXIV2_RCSID("@(#) $Id$")
// *****************************************************************************
// included header files
#include "asfvideo.hpp"
#include "futils.hpp"
#include "basicio.hpp"
#include "tags.hpp"
#include "tags_int.hpp"
#include "types.hpp"
#include "riffvideo.hpp"
#include "convert.hpp"
// + standard includes
#include <cmath>
#include <cstring>
#include <ctype.h>
// *****************************************************************************
// class member definitions
namespace Exiv2 {
namespace Internal {
/*!
Tag Look-up list for ASF Type Video Files
Associates the GUID of a Tag with its Tag Name(i.e. Human Readable Form)
Tags have been diferentiated into Various Categories.
The categories have been listed above the Tag Groups
*/
extern const TagVocabulary GUIDReferenceTags[] = {
/// Top-level ASF object GUIDS
{ "75B22630-668E-11CF-A6D9-00AA0062CE6C", "Header" },
{ "75B22636-668E-11CF-A6D9-00AA0062CE6C", "Data" },
{ "33000890-E5B1-11CF-89F4-00A0C90349CB", "Simple_Index" },
{ "D6E229D3-35DA-11D1-9034-00A0C90349BE", "Index" },
{ "FEB103F8-12AD-4C64-840F-2A1D2F7AD48C", "Media_Index" },
{ "3CB73FD0-0C4A-4803-953D-EDF7B6228F0C", "Timecode_Index" },
/// Header Object GUIDs
{ "8CABDCA1-A947-11CF-8EE4-00C00C205365", "File_Properties" },
{ "B7DC0791-A9B7-11CF-8EE6-00C00C205365", "Stream_Properties" },
{ "5FBF03B5-A92E-11CF-8EE3-00C00C205365", "Header_Extension" },
{ "86D15240-311D-11D0-A3A4-00A0C90348F6", "Codec_List" },
{ "1EFB1A30-0B62-11D0-A39B-00A0C90348F6", "Script_Command" },
{ "F487CD01-A951-11CF-8EE6-00C00C205365", "Marker" },
{ "D6E229DC-35DA-11D1-9034-00A0C90349BE", "Bitrate_Mutual_Exclusion" },
{ "75B22635-668E-11CF-A6D9-00AA0062CE6C", "Error_Correction" },
{ "75B22633-668E-11CF-A6D9-00AA0062CE6C", "Content_Description" },
{ "D2D0A440-E307-11D2-97F0-00A0C95EA850", "Extended_Content_Description" },
{ "2211B3FA-BD23-11D2-B4B7-00A0C955FC6E", "Content_Branding" },
{ "7BF875CE-468D-11D1-8D82-006097C9A2B2", "Stream_Bitrate_Properties" },
{ "2211B3FB-BD23-11D2-B4B7-00A0C955FC6E", "Content_Encryption" },
{ "298AE614-2622-4C17-B935-DAE07EE9289C", "Extended_Content_Encryption" },
{ "2211B3FC-BD23-11D2-B4B7-00A0C955FC6E", "Digital_Signature" },
{ "1806D474-CADF-4509-A4BA-9AABCB96AAE8", "Padding" },
/// Header Extension Object GUIDs
{ "14E6A5CB-C672-4332-8399-A96952065B5A", "Extended_Stream_Properties" },
{ "A08649CF-4775-4670-8A16-6E35357566CD", "Advanced_Mutual_Exclusion" },
{ "D1465A40-5A79-4338-B71B-E36B8FD6C249", "Group_Mutual_Exclusion" },
{ "D4FED15B-88D3-454F-81F0-ED5C45999E24", "Stream_Prioritization" },
{ "A69609E6-517B-11D2-B6AF-00C04FD908E9", "Bandwidth_Sharing" },
{ "7C4346A9-EFE0-4BFC-B229-393EDE415C85", "Language_List" },
{ "C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA", "Metadata" },
{ "44231C94-9498-49D1-A141-1D134E457054", "Metadata_Library" },
{ "D6E229DF-35DA-11D1-9034-00A0C90349BE", "Index_Parameters" },
{ "6B203BAD-3F11-48E4-ACA8-D7613DE2CFA7", "Media_Index_Parameters" },
{ "F55E496D-9797-4B5D-8C8B-604DFE9BFB24", "Timecode_Index_Parameters" },
{ "26F18B5D-4584-47EC-9F5F-0E651F0452C9", "Compatibility" },
{ "43058533-6981-49E6-9B74-AD12CB86D58C", "Advanced_Content_Encryption" },
/// Stream Properties Object Stream Type GUIDs
{ "F8699E40-5B4D-11CF-A8FD-00805F5C442B", "Audio_Media" },
{ "BC19EFC0-5B4D-11CF-A8FD-00805F5C442B", "Video_Media" },
{ "59DACFC0-59E6-11D0-A3AC-00A0C90348F6", "Command_Media" },
{ "B61BE100-5B4E-11CF-A8FD-00805F5C442B", "JFIF_Media" },
{ "35907DE0-E415-11CF-A917-00805F5C442B", "Degradable_JPEG_Media" },
{ "91BD222C-F21C-497A-8B6D-5AA86BFC0185", "File_Transfer_Media" },
{ "3AFB65E2-47EF-40F2-AC2C-70A90D71D343", "Binary_Media" },
/// Web stream Type-Specific Data GUIDs
{ "776257D4-C627-41CB-8F81-7AC7FF1C40CC", "Web_Stream_Media_Subtype" },
{ "DA1E6B13-8359-4050-B398-388E965BF00C", "Web_Stream_Format" },
/// Stream Properties Object Error Correction Type GUIDs
{ "20FB5700-5B55-11CF-A8FD-00805F5C442B", "No_Error_Correction" },
{ "BFC3CD50-618F-11CF-8BB2-00AA00B4E220", "Audio_Spread" },
/// Header Extension Object GUIDs
{ "ABD3D211-A9BA-11cf-8EE6-00C00C205365", "Reserved_1" },
/// Advanced Content Encryption Object System ID GUIDs
{ "7A079BB6-DAA4-4e12-A5CA-91D38DC11A8D", "Content_Encryption_System_Windows_Media_DRM_Network_Devices" },
/// Codec List Object GUIDs
{ "86D15241-311D-11D0-A3A4-00A0C90348F6", "Reserved_2" },
/// Script Command Object GUIDs
{ "4B1ACBE3-100B-11D0-A39B-00A0C90348F6", "Reserved_3" },
/// Marker Object GUIDs
{ "4CFEDB20-75F6-11CF-9C0F-00A0C90349CB", "Reserved_4" },
/// Mutual Exclusion Object Exclusion Type GUIDs
{ "D6E22A00-35DA-11D1-9034-00A0C90349BE", "Mutex_Language" },
{ "D6E22A01-35DA-11D1-9034-00A0C90349BE", "Mutex_Bitrate" },
{ "D6E22A02-35DA-11D1-9034-00A0C90349BE", "Mutex_Unknown" },
/// Bandwidth Sharing Object GUIDs
{ "AF6060AA-5197-11D2-B6AF-00C04FD908E9", "Bandwidth_Sharing_Exclusive" },
{ "AF6060AB-5197-11D2-B6AF-00C04FD908E9", "Bandwidth_Sharing_Partial" },
/// Standard Payload Extension System GUIDs
{ "399595EC-8667-4E2D-8FDB-98814CE76C1E", "Payload_Extension_System_Timecode" },
{ "E165EC0E-19ED-45D7-B4A7-25CBD1E28E9B", "Payload_Extension_System_File_Name" },
{ "D590DC20-07BC-436C-9CF7-F3BBFBF1A4DC", "Payload_Extension_System_Content_Type" },
{ "1B1EE554-F9EA-4BC8-821A-376B74E4C4B8", "Payload_Extension_System_Pixel_Aspect_Ratio" },
{ "C6BD9450-867F-4907-83A3-C77921B733AD", "Payload_Extension_System_Sample_Duration" },
{ "6698B84E-0AFA-4330-AEB2-1C0A98D7A44D", "Payload_Extension_System_Encryption_Sample_ID" },
{ "00E1AF06-7BEC-11D1-A582-00C04FC29CFB", "Payload_Extension_System_Degradable_JPEG" }
};
//! Audio codec type-specific data in ASF
extern const TagDetails audioCodec[] = {
{ 0x161, "Windows Media Audio (7, 8, and 9 Series)" },
{ 0x162, "Windows Media Audio 9 Professional" },
{ 0x163, "Windows Media Audio 9 Lossless" },
{ 0x7A21, "GSM-AMR (CBR, no SID)" },
{ 0x7A22, "GSM-AMR (VBR including SID)" }
};
extern const TagDetails filePropertiesTags[] = {
{ 7, "Xmp.video.FileLength" },
{ 6, "Xmp.video.CreationDate" },
{ 5, "Xmp.video.DataPackets" },
{ 4, "Xmp.video.Duration" },
{ 3, "Xmp.video.SendDuration" },
{ 2, "Xmp.video.Preroll" },
{ 1, "Xmp.video.MaxBitRate" }
};
extern const TagDetails contentDescriptionTags[] = {
{ 1, "Xmp.video.Title" },
{ 2, "Xmp.video.Author" },
{ 3, "Xmp.video.Copyright" },
{ 4, "Xmp.video.Description" },
{ 5, "Xmp.video.Rating" }
};
/*!
@brief Function used to read data from data buffer, reads 16-bit character
array and stores it in std::string object.
@param buf Exiv2 data buffer, which stores the information
@return Returns std::string object .
*/
std::string toString16(Exiv2::DataBuf& buf)
{
std::ostringstream os; char t;
for(int i = 0; i <= buf.size_; i += 2 ) {
t = buf.pData_[i] + 16 * buf.pData_[i + 1];
if(t == 0) {
if(i)
os << '\0';
break;
}
os<< t;
}
return os.str();
}
/*!
@brief Function used to check equality of two Tags (ignores case).
@param str1 char* Pointer to First Tag
@param str2 char* Pointer to Second Tag
@return Returns true if both are equal.
*/
bool compareTag(const char* str1, const char* str2) {
if ( strlen(str1) != strlen(str2))
return false;
for ( uint64_t i = 0 ; i < strlen(str1); ++i )
if (tolower(str1[i]) != tolower(str2[i]))
return false;
return true;
}
/*!
@brief Function used to convert a decimal number to its Hexadecimal
equivalent, then parsed into a character
@param n Integer which is to be parsed as Hexadecimal character
@return Return a Hexadecimal number, in character
*/
char returnHEX(int n) {
if(n >= 0 && n <= 9)
return (char)(n + 48);
else
return (char)(n + 55);
}
/*!
@brief Function used to calulate GUID, Tags comprises of 16 bytes.
The Buffer contains the Tag in Binary Form. The information is then
parsed into a character array GUID.
*/
void getGUID (byte buf[], char GUID[]) {
int i;
for (i = 0; i < 4; ++i) {
GUID[(3 - i) * 2] = returnHEX(buf[i] / 0x10);
GUID[(3 - i) * 2 + 1] = returnHEX(buf[i] % 0x10);
}
for (i = 4; i < 6; ++i) {
GUID[(9 - i) * 2 + 1] = returnHEX(buf[i] / 0x10);
GUID[(9 - i) * 2 + 2] = returnHEX(buf[i] % 0x10);
}
for (i = 6; i < 8; ++i) {
GUID[(14 - i) * 2] = returnHEX(buf[i] / 0x10);
GUID[(14 - i) * 2 + 1] = returnHEX(buf[i] % 0x10);
}
for (i = 8; i < 10; ++i) {
GUID[ i * 2 + 3] = returnHEX(buf[i] / 0x10);
GUID[ i * 2 + 4] = returnHEX(buf[i] % 0x10);
}
for (i = 10; i < 16; ++i) {
GUID[ i * 2 + 4] = returnHEX(buf[i] / 0x10);
GUID[ i * 2 + 5] = returnHEX(buf[i] % 0x10);
}
GUID[36] = '\0'; GUID[8] = GUID[13] = GUID[18] = GUID[23] = '-';
}
/*!
@brief Function used to check if data stored in buf is equivalent to
ASF Header Tag's GUID.
@param buf Exiv2 byte buffer
@return Returns true if the buffer data is equivalent to Header GUID.
*/
bool isASFType (byte buf[]) {
if(buf[0] == 0x30 && buf[1] == 0x26 && buf[2] == 0xb2 && buf[3] == 0x75 &&
buf[4] == 0x8e && buf[5] == 0x66 && buf[6] == 0xcf && buf[7] == 0x11 &&
buf[8] == 0xa6 && buf[9] == 0xd9 && buf[10] == 0x00 && buf[11] == 0xaa &&
buf[12] == 0x00 && buf[13] == 0x62 && buf[14] == 0xce && buf[15] == 0x6c )
return true;
return false;
}
//! Function used to convert buffer data into 64-bit Integer, information stored in littleEndian format
uint64_t getUint64_t(Exiv2::DataBuf& buf) {
uint64_t temp = 0;
for(int i = 0; i < 8; ++i)
temp = temp + buf.pData_[i]*(pow(256,i));
return temp;
}
}} // namespace Internal, Exiv2
namespace Exiv2 {
using namespace Exiv2::Internal;
AsfVideo::AsfVideo(BasicIo::AutoPtr io)
: Image(ImageType::asf, mdNone, io)
{
} // AsfVideo::AsfVideo
std::string AsfVideo::mimeType() const
{
return "video/asf";
}
void AsfVideo::writeMetadata()
{
}
void AsfVideo::readMetadata()
{
if (io_->open() != 0) throw Error(9, io_->path(), strError());
// Ensure that this is the correct image type
if (!isAsfType(*io_, false)) {
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "ASF");
}
IoCloser closer(*io_);
clearMetadata();
continueTraversing_ = true;
io_->seek(0, BasicIo::beg);
height_ = 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();
aspectRatio();
} // AsfVideo::readMetadata
void AsfVideo::decodeBlock()
{
const long bufMinSize = 8;
DataBuf buf(bufMinSize);
unsigned long size = 0;
buf.pData_[8] = '\0' ;
const TagVocabulary* tv;
uint64_t cur_pos = io_->tell();
byte guidBuf[16];
io_->read(guidBuf, 16);
if(io_->eof()) {
continueTraversing_ = false;
return;
}
char GUID[33] = "";
getGUID(guidBuf, GUID);
tv = find( GUIDReferenceTags, GUID);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 8);
size = getUint64_t(buf);
if(tv)
tagDecoder(tv,size-24);
else
io_->seek(cur_pos + size, BasicIo::beg);
localPosition_ = io_->tell();
} // AsfVideo::decodeBlock
void AsfVideo::tagDecoder(const TagVocabulary *tv, uint64_t size)
{
uint64_t cur_pos = io_->tell();
DataBuf buf(1000);
unsigned long count = 0, tempLength = 0;
buf.pData_[4] = '\0' ;
Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpSeq);
if(compareTag( exvGettext(tv->label_), "Header")) {
localPosition_ = 0;
io_->read(buf.pData_, 4);
io_->read(buf.pData_, 2);
while(localPosition_ < cur_pos + size) decodeBlock();
}
else if(compareTag( exvGettext(tv->label_), "File_Properties"))
fileProperties();
else if(compareTag( exvGettext(tv->label_), "Stream_Properties"))
streamProperties();
else if(compareTag( exvGettext(tv->label_), "Metadata"))
metadataHandler(1);
else if(compareTag( exvGettext(tv->label_), "Extended_Content_Description"))
metadataHandler(2);
else if(compareTag( exvGettext(tv->label_), "Metadata_Library"))
metadataHandler(3);
else if(compareTag( exvGettext(tv->label_), "Codec_List"))
codecList();
else if(compareTag( exvGettext(tv->label_), "Content_Description"))
contentDescription(size);
else if(compareTag( exvGettext(tv->label_), "Extended_Stream_Properties"))
extendedStreamProperties(size);
else if(compareTag( exvGettext(tv->label_), "Header_Extension")) {
localPosition_ = 0;
headerExtension(size);
}
else if(compareTag( exvGettext(tv->label_), "Language_List")) {
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 2);
count = Exiv2::getUShort(buf.pData_, littleEndian);
while(count--) {
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 1); tempLength = (int)buf.pData_[0];
io_->read(buf.pData_, tempLength);
v->read(toString16(buf));
}
xmpData_.add(Exiv2::XmpKey("Xmp.video.TrackLang"), v.get());
}
io_->seek(cur_pos + size, BasicIo::beg);
localPosition_ = io_->tell();
} // AsfVideo::tagDecoder
void AsfVideo::extendedStreamProperties(uint64_t size)
{
uint64_t cur_pos = io_->tell(), avgTimePerFrame = 0;
DataBuf buf(8);
static int previousStream;
io_->seek(cur_pos + 48, BasicIo::beg);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 2);
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)
xmpData_["Xmp.video.FrameRate"] = (double)10000000/(double)avgTimePerFrame;
previousStream = streamNumber_;
io_->seek(cur_pos + size, BasicIo::beg);
} // AsfVideo::extendedStreamProperties
void AsfVideo::contentDescription(uint64_t size)
{
long pos = io_->tell();
long length[5];
const TagDetails* td;
for (int i = 0 ; i < 5 ; ++i) {
byte buf[2];
io_->read(buf, 2);
length[i] = (long)buf[0] + 16 * (long)buf[1];
}
for (int i = 0 ; i < 5 ; ++i) {
DataBuf buf(length[i]);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, length[i]);
td = find(contentDescriptionTags, i + 1);
std::string str((const char*)buf.pData_, length[i]);
if (convertStringCharset(str, "UCS-2LE", "UTF-8")) {
xmpData_[td->label_] = str;
}
else {
xmpData_[td->label_] = toString16(buf);
}
}
io_->seek(pos + size, BasicIo::beg);
} // AsfVideo::contentDescription
void AsfVideo::streamProperties()
{
DataBuf buf(20);
buf.pData_[8] = '\0' ;
byte guidBuf[16]; int stream = 0;
io_->read(guidBuf, 16);
char streamType[33] = "";
Exiv2::RiffVideo *test = NULL;
getGUID(guidBuf, streamType);
const TagVocabulary* tv;
tv = find( GUIDReferenceTags, streamType);
io_->read(guidBuf, 16);
if(compareTag( exvGettext(tv->label_), "Audio_Media"))
stream = 1;
else if(compareTag( exvGettext(tv->label_), "Video_Media"))
stream = 2;
io_->read(buf.pData_, 8);
if(stream == 2)
xmpData_["Xmp.video.TimeOffset"] = getUint64_t(buf);
else if(stream == 1)
xmpData_["Xmp.audio.TimeOffset"] = getUint64_t(buf);
io_->read(buf.pData_, 8);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 1);
streamNumber_ = (int)buf.pData_[0] & 127;
io_->read(buf.pData_, 5);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 2);
long temp = Exiv2::getUShort(buf.pData_, littleEndian);
if(stream == 2) {
xmpData_["Xmp.video.Width"] = temp;
width_ = temp;
}
else if(stream == 1) {
xmpData_["Xmp.audio.Codec"] = test->printAudioEncoding(temp);
}
io_->read(buf.pData_, 2);
temp = Exiv2::getUShort(buf.pData_, littleEndian);
if(stream == 1)
xmpData_["Xmp.audio.ChannelType"] = temp;
io_->read(buf.pData_, 4);
temp = Exiv2::getULong(buf.pData_, littleEndian);
if(stream == 2) {
xmpData_["Xmp.video.Height"] = temp;
height_ = temp;
}
else if(stream == 1) {
xmpData_["Xmp.audio.SampleRate"] = temp;
}
} // AsfVideo::streamProperties
void AsfVideo::codecList()
{
DataBuf buf(200);
io_->read(buf.pData_, 16);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 4);
int codecCount = Exiv2::getULong(buf.pData_, littleEndian), descLength = 0, codecType = 0;
while(codecCount--) {
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 2);
codecType = Exiv2::getUShort(buf.pData_, littleEndian);
io_->read(buf.pData_, 2);
descLength = Exiv2::getUShort(buf.pData_, littleEndian) * 2;
io_->read(buf.pData_, descLength);
if(codecType == 1)
xmpData_["Xmp.video.Codec"] = toString16(buf);
else if(codecType == 2)
xmpData_["Xmp.audio.Compressor"] = toString16(buf);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 2);
descLength = Exiv2::getUShort(buf.pData_, littleEndian) * 2;
io_->read(buf.pData_, descLength);
if(codecType == 1)
xmpData_["Xmp.video.CodecDescription"] = toString16(buf);
else if(codecType == 2)
xmpData_["Xmp.audio.CodecDescription"] = toString16(buf);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 2);
descLength = Exiv2::getUShort(buf.pData_, littleEndian);
io_->read(buf.pData_, descLength);
}
} // AsfVideo::codecList
void AsfVideo::headerExtension(uint64_t size)
{
uint64_t cur_pos = io_->tell();
DataBuf buf(20);
io_->read(buf.pData_, 18);
buf.pData_[4] = '\0' ;
io_->read(buf.pData_, 4);
while(localPosition_ < cur_pos + size) decodeBlock();
io_->seek(cur_pos + size, BasicIo::beg);
} // AsfVideo::headerExtension
void AsfVideo::metadataHandler(int meta)
{
DataBuf buf(500);
io_->read(buf.pData_, 2);
int recordCount = Exiv2::getUShort(buf.pData_, littleEndian), nameLength = 0, dataLength = 0, dataType = 0;
Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpSeq);
byte guidBuf[16]; char fileID[33] = "";
while(recordCount--) {
std::memset(buf.pData_, 0x0, buf.size_);
if(meta == 1 || meta == 3) {
io_->read(buf.pData_, 4);
io_->read(buf.pData_, 2);
nameLength = Exiv2::getUShort(buf.pData_, littleEndian);
io_->read(buf.pData_, 2);
dataType = Exiv2::getUShort(buf.pData_, littleEndian);
io_->read(buf.pData_, 4);
dataLength = Exiv2::getULong(buf.pData_, littleEndian);
io_->read(buf.pData_, nameLength);
v->read(toString16(buf));
if(dataType == 6) {
io_->read(guidBuf, 16);
getGUID(guidBuf, fileID);
}
else
io_->read(buf.pData_, dataLength);
}
else if(meta == 2) {
io_->read(buf.pData_, 2);
nameLength = Exiv2::getUShort(buf.pData_, littleEndian);
io_->read(buf.pData_, nameLength);
v->read(toString16(buf));
io_->read(buf.pData_, 2);
dataType = Exiv2::getUShort(buf.pData_, littleEndian);
io_->read(buf.pData_, 2);
dataLength = Exiv2::getUShort(buf.pData_, littleEndian);
io_->read(buf.pData_, dataLength);
}
if(dataType == 0) { // Unicode String
v->read(toString16(buf));
}
else if(dataType == 2 || dataType == 5) { // 16-bit Unsigned Integer
v->read( Exiv2::toString( Exiv2::getUShort(buf.pData_, littleEndian)));
}
else if(dataType == 3) { // 32-bit Unsigned Integer
v->read( Exiv2::toString( Exiv2::getULong( buf.pData_, littleEndian)));
}
else if(dataType == 4) { // 64-bit Unsigned Integer
v->read(Exiv2::toString(getUint64_t(buf)));
}
else if(dataType == 6) { // 128-bit GUID
v->read(Exiv2::toString(fileID));
}
else { // Byte array
v->read( Exiv2::toString(buf.pData_));
}
}
if(meta == 1) {
xmpData_.add(Exiv2::XmpKey("Xmp.video.Metadata"), v.get());
}
else if(meta == 2) {
xmpData_.add(Exiv2::XmpKey("Xmp.video.ExtendedContentDescription"), v.get());
}
else {
xmpData_.add(Exiv2::XmpKey("Xmp.video.MetadataLibrary"), v.get());
}
} // AsfVideo::metadataHandler
void AsfVideo::fileProperties()
{
DataBuf buf(8);
buf.pData_[8] = '\0' ;
byte guidBuf[16];
io_->read(guidBuf, 16);
char fileID[33] = ""; int count = 7;
getGUID(guidBuf, fileID);
xmpData_["Xmp.video.FileID"] = fileID;
const TagDetails* td;
while(count--) {
td = find(filePropertiesTags , (count + 1));
io_->read(buf.pData_, 8);
if(count == 0) {
buf.pData_[4] = '\0' ;
io_->read(buf.pData_, 4); io_->read(buf.pData_, 4);
}
if(count == 3 || count == 2) {
xmpData_[exvGettext(td->label_)] = getUint64_t(buf) / 10000;
}
else {
xmpData_[exvGettext(td->label_)] = getUint64_t(buf);
}
}
} // AsfVideo::fileProperties
void AsfVideo::aspectRatio()
{
//TODO - Make a better unified method to handle all cases of Aspect Ratio
double aspectRatio = (double)width_ / (double)height_;
aspectRatio = floor(aspectRatio*10) / 10;
xmpData_["Xmp.video.AspectRatio"] = aspectRatio;
if(aspectRatio == 1.3) xmpData_["Xmp.video.AspectRatio"] = "4:3";
else if(aspectRatio == 1.7) xmpData_["Xmp.video.AspectRatio"] = "16:9";
else if(aspectRatio == 1.0) xmpData_["Xmp.video.AspectRatio"] = "1:1";
else if(aspectRatio == 1.6) xmpData_["Xmp.video.AspectRatio"] = "16:10";
else if(aspectRatio == 2.2) xmpData_["Xmp.video.AspectRatio"] = "2.21:1";
else if(aspectRatio == 2.3) xmpData_["Xmp.video.AspectRatio"] = "2.35:1";
else if(aspectRatio == 1.2) xmpData_["Xmp.video.AspectRatio"] = "5:4";
else xmpData_["Xmp.video.AspectRatio"] = aspectRatio;
} // AsfVideo::aspectRatio
Image::AutoPtr newAsfInstance(BasicIo::AutoPtr io, bool /*create*/)
{
Image::AutoPtr image(new AsfVideo(io));
if (!image->good()) {
image.reset();
}
return image;
}
bool isAsfType(BasicIo& iIo, bool advance)
{
const int32_t len = 16;
byte buf[len];
iIo.read(buf, len);
if (iIo.error() || iIo.eof()) {
return false;
}
bool matched = isASFType(buf);
if (!advance || !matched) {
iIo.seek(0, BasicIo::beg);
}
return matched;
}
} // namespace Exiv2

@ -0,0 +1,185 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2012 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 asfvideo.hpp
@brief An Image subclass to support ASF video files
@version $Rev$
@author Abhinav Badola for GSoC 2012
<a href="mailto:mail.abu.to@gmail.com">mail.abu.to@gmail.com</a>
@date 08-Aug-12, AB: created
*/
#ifndef ASFVIDEO_HPP
#define ASFVIDEO_HPP
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "image.hpp"
#include "tags_int.hpp"
// *****************************************************************************
// namespace extensions
using namespace Exiv2::Internal;
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add ASF to the supported image formats
namespace ImageType {
const int asf = 24; //!< Treating asf as an image type>
}
/*!
@brief Class to access ASF video files.
*/
class EXIV2API AsfVideo:public Image
{
public:
//! @name Creators
//@{
/*!
@brief Constructor for a ASF 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.
*/
AsfVideo(BasicIo::AutoPtr 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();
/*!
@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 tv Pointer to current tag,
@param size Size of the data block used to store Tag Information.
*/
void tagDecoder(const TagVocabulary* tv, uint64_t size);
/*!
@brief Interpret File_Properties tag information, and save it in
the respective XMP container.
*/
void fileProperties();
/*!
@brief Interpret Stream_Properties tag information, and save it
in the respective XMP container.
*/
void streamProperties();
/*!
@brief Interpret Codec_List tag information, and save it in
the respective XMP container.
*/
void codecList();
/*!
@brief Interpret Content_Description tag information, and save it
in the respective XMP container.
@param size Size of the data block used to store Tag Data.
*/
void contentDescription(uint64_t size);
/*!
@brief Interpret Extended_Stream_Properties tag information, and
save it in the respective XMP container.
@param size Size of the data block used to store Tag Data.
*/
void extendedStreamProperties(uint64_t size);
/*!
@brief Interpret Header_Extension tag information, and save it in
the respective XMP container.
@param size Size of the data block used to store Tag Data.
*/
void headerExtension(uint64_t size);
/*!
@brief Interpret Metadata, Extended_Content_Description,
Metadata_Library tag information, and save it in the respective
XMP container.
@param meta A default integer which helps to overload the function
for various Tags that have a similar method of decoding.
*/
void metadataHandler(int meta = 1);
/*!
@brief Calculates Aspect Ratio of a video, and stores it in the
respective XMP container.
*/
void aspectRatio();
private:
//! @name NOT Implemented
//@{
//! Copy constructor
AsfVideo(const AsfVideo& rhs);
//! Assignment operator
AsfVideo& operator=(const AsfVideo& rhs);
//@}
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 AsfVideo
// *****************************************************************************
// 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 AsfVideo 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 newAsfInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a Windows Asf Video.
EXIV2API bool isAsfType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef ASFVIDEO_HPP_

@ -173,6 +173,13 @@ namespace Exiv2 {
{ 0x80000261, N_("EOS 50D") },
{ 0x80000270, N_("EOS Rebel T2i / 550D / Kiss X4") },
{ 0x80000281, N_("EOS-1D Mark IV") },
{ 0x80000285, N_("EOS 5D Mark III") },
{ 0x80000286, N_("EOS Rebel T3i / 600D / Kiss X5") },
{ 0x80000287, N_("EOS 60D") },
{ 0x80000288, N_("EOS Rebel T3 / 1100D / Kiss X50") },
{ 0x80000297, N_("WFT-E2 II") },
{ 0x80000298, N_("WFT-E4 II") },
{ 0x80000301, N_("EOS Rebel T4i / 650D / Kiss X6i") },
};
//! SerialNumberFormat, tag 0x0015
@ -653,11 +660,16 @@ namespace Exiv2 {
{ 249, "Canon EF 800mm f/5.6L IS" },
{ 250, "Canon EF 24 f/1.4L II" },
{ 251, "Canon EF 70-200mm f/2.8L IS II USM" },
{ 252, "Canon EF 70-200mm f/2.8L IS II USM + 1.4x" },
{ 253, "Canon EF 70-200mm f/2.8L IS II USM + 2x" },
{ 254, "Canon EF 100mm f/2.8L Macro IS USM" },
{ 488, "Canon EF-S 15-85mm f/3.5-5.6 IS USM" },
{ 489, "Canon EF 70-300mm f/4-5.6L IS USM" },
{ 490, "Canon EF 8-15mm f/4L USM" },
{ 491, "Canon EF 300mm f/2.8L IS II USM" }
{ 491, "Canon EF 300mm f/2.8L IS II USM" },
{ 494, "Canon EF 600mm f/4.0L IS II USM" },
{ 495, "Canon EF 24-70mm f/2.8L II USM" },
{ 4144,"Canon EF 40mm f/2.8 STM" }
};
//! A lens id and a pretty-print function for special treatment of the id.

@ -60,6 +60,10 @@ EXIV2_RCSID("@(#) $Id$")
#include "tgaimage.hpp"
#include "bmpimage.hpp"
#include "jp2image.hpp"
#include "matroskavideo.hpp"
#include "quicktimevideo.hpp"
#include "riffvideo.hpp"
#include "asfvideo.hpp"
#include "rw2image.hpp"
#include "pgfimage.hpp"
#include "xmpsidecar.hpp"
@ -127,6 +131,10 @@ 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,amReadWrite, amNone, amNone, amNone },
{ ImageType::riff, newRiffInstance, isRiffType, amReadWrite, amNone, amNone, amNone },
{ ImageType::asf, newAsfInstance, isAsfType, amReadWrite, amNone, amNone, amNone },
{ ImageType::mkv, newMkvInstance, isMkvType, amReadWrite, amNone, amNone, amNone },
// End of list marker
{ ImageType::none, 0, 0, amNone, amNone, amNone, amNone }
};

@ -0,0 +1,731 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2012 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: matroskavideo.cpp
Version: $Rev$
Author(s): Abhinav Badola for GSoC 2012 (AB) <mail.abu.to@gmail.com>
History: 18-Jun-12, AB: created
Credits: See header file
*/
// *****************************************************************************
#include "rcsid_int.hpp"
EXIV2_RCSID("@(#) $Id$")
// *****************************************************************************
// included header files
#include "matroskavideo.hpp"
#include "futils.hpp"
#include "basicio.hpp"
#include "tags.hpp"
#include "tags_int.hpp"
// + standard includes
#include <cmath>
// *****************************************************************************
// class member definitions
namespace Exiv2 {
namespace Internal {
//! List of composite tags. They are skipped and the child tags are read immediately
uint32_t compositeTagsList[] = {
0x0000, 0x000e, 0x000f, 0x0020, 0x0026, 0x002e, 0x0036,
0x0037, 0x003b, 0x005b, 0x0060, 0x0061, 0x0068, 0x05b9,
0x0dbb, 0x1034, 0x1035, 0x1854, 0x21a7, 0x2240, 0x23c0,
0x2624, 0x27c8, 0x2911, 0x2924, 0x2944, 0x2d80, 0x3373,
0x35a1, 0x3e5b, 0x3e7b,
0x14d9b74, 0x254c367, 0x549a966, 0x654ae6b, 0x8538067,
0x941a469, 0xa45dfa3, 0xb538667, 0xc53bb6b, 0xf43b675
};
//! List of tags which are ignored, i.e., tag and value won't be read
uint32_t ignoredTagsList[] = {
0x0021, 0x0023, 0x0033, 0x0071, 0x0077, 0x006c, 0x0067, 0x007b, 0x02f2, 0x02f3,
0x1031, 0x1032, 0x13ab, 0x13ac, 0x15ee, 0x23a2, 0x23c6, 0x2e67, 0x33a4, 0x33c5,
0x3446, 0x2de7, 0x2df8, 0x26bf, 0x28ca, 0x3384, 0x13b8, 0x037e, 0x0485, 0x18d7,
0x0005, 0x0009, 0x0011, 0x0012, 0x0016, 0x0017, 0x0018, 0x0022, 0x0024, 0x0025,
0x0027, 0x002b, 0x002f, 0x003f, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x006a,
0x006b, 0x006e, 0x007a, 0x007d, 0x0255, 0x3eb5, 0x3ea5, 0x3d7b, 0x33c4, 0x2fab,
0x2ebc, 0x29fc, 0x29a5, 0x2955, 0x2933, 0x135f, 0x2922, 0x26a5, 0x26fc, 0x2532,
0x23c9, 0x23c4, 0x23c5, 0x137f, 0x1378, 0x07e2, 0x07e3, 0x07e4, 0x0675, 0x05bc,
0x05bd, 0x05db, 0x05dd, 0x0598, 0x050d, 0x0444, 0x037c,
0x3314f, 0x43a770, 0x1eb923, 0x1cb923, 0xeb524, 0x1c83ab, 0x1e83bb
};
/*!
Tag Look-up list for Matroska Type Video Files
The Tags have been categorized in 4 categories. Which are
mentioned as a comment in front of them.
s -- Tag to be Skipped
sd -- Tag to be Skipped along with its data
u -- Tag used directly for storing metadata
ui -- Tag used only internally
*/
extern const TagDetails matroskaTags[] = {
{ 0x0000, "ChapterDisplay" }, //s
{ 0x0003, "TrackType" }, //ui
{ 0x0005, "ChapterString" }, //sd
{ 0x0006, "VideoCodecID/AudioCodecID/CodecID" }, //ui
{ 0x0008, "TrackDefault" }, //ui
{ 0x0009, "ChapterTrackNumber" }, //sd
{ 0x000e, "Slices" }, //s
{ 0x000f, "ChapterTrack" }, //s
{ 0x0011, "ChapterTimeStart" }, //sd
{ 0x0012, "ChapterTimeEnd" }, //sd
{ 0x0016, "CueRefTime" }, //sd
{ 0x0017, "CueRefCluster" }, //sd
{ 0x0018, "ChapterFlagHidden" }, //sd
{ 0x001a, "Xmp.video.VideoScanTpye" }, //u
{ 0x001b, "BlockDuration" }, //s
{ 0x001c, "TrackLacing" }, //ui
{ 0x001f, "Xmp.audio.ChannelType" }, //u
{ 0x0020, "BlockGroup" }, //s
{ 0x0021, "Block" }, //sd
{ 0x0022, "BlockVirtual" }, //sd
{ 0x0023, "SimpleBlock" }, //sd
{ 0x0024, "CodecState" }, //sd
{ 0x0025, "BlockAdditional" }, //sd
{ 0x0026, "BlockMore" }, //s
{ 0x0027, "Position" }, //sd
{ 0x002a, "CodecDecodeAll" }, //ui
{ 0x002b, "PrevSize" }, //sd
{ 0x002e, "TrackEntry" }, //s
{ 0x002f, "EncryptedBlock" }, //sd
{ 0x0030, "Xmp.video.Width" }, //u
{ 0x0033, "CueTime" }, //sd
{ 0x0035, "Xmp.audio.SampleRate" }, //u
{ 0x0036, "ChapterAtom" }, //s
{ 0x0037, "CueTrackPositions" }, //s
{ 0x0039, "TrackUsed" }, //ui
{ 0x003a, "Xmp.video.Height" }, //u
{ 0x003b, "CuePoint" }, //s
{ 0x003f, "CRC-32" }, //sd
{ 0x004b, "BlockAdditionalID" }, //sd
{ 0x004c, "LaceNumber" }, //sd
{ 0x004d, "FrameNumber" }, //sd
{ 0x004e, "Delay" }, //sd
{ 0x004f, "ClusterDuration" }, //sd
{ 0x0057, "TrackNumber" }, //ui
{ 0x005b, "CueReference" }, //s
{ 0x0060, "Video" }, //s
{ 0x0061, "Audio" }, //s
{ 0x0067, "Timecode" }, //sd
{ 0x0068, "TimeSlice" }, //s
{ 0x006a, "CueCodecState" }, //sd
{ 0x006b, "CueRefCodecState" }, //sd
{ 0x006c, "Void" }, //sd
{ 0x006e, "BlockAddID" }, //sd
{ 0x0071, "CueClusterPosition" }, //sd
{ 0x0077, "CueTrack" }, //sd
{ 0x007a, "ReferencePriority" }, //sd
{ 0x007b, "ReferenceBlock" }, //sd
{ 0x007d, "ReferenceVirtual" }, //sd
{ 0x0254, "Xmp.video.ContentCompressAlgo" }, //u
{ 0x0255, "ContentCompressionSettings" }, //sd
{ 0x0282, "Xmp.video.DocType" }, //u
{ 0x0285, "Xmp.video.DocTypeReadVersion" }, //u
{ 0x0286, "Xmp.video.EBMLVersion" }, //u
{ 0x0287, "Xmp.video.DocTypeVersion" }, //u
{ 0x02f2, "EBMLMaxIDLength" }, //sd
{ 0x02f3, "EBMLMaxSizeLength" }, //sd
{ 0x02f7, "Xmp.video.EBMLReadVersion" }, //u
{ 0x037c, "ChapterLanguage" }, //sd
{ 0x037e, "ChapterCountry" }, //sd
{ 0x0444, "SegmentFamily" }, //sd
{ 0x0461, "Xmp.video.DateUTC" }, //Date Time Original - measured in seconds relatively to Jan 01, 2001, 0:00:00 GMT+0h
{ 0x047a, "Xmp.video.TagLanguage" }, //u
{ 0x0484, "Xmp.video.TagDefault" }, //u
{ 0x0485, "TagBinary" }, //sd
{ 0x0487, "Xmp.video.TagString" }, //u
{ 0x0489, "Xmp.video.Duration" }, //u
{ 0x050d, "ChapterProcessPrivate" }, //sd
{ 0x0598, "ChapterFlagEnabled" }, //sd
{ 0x05a3, "Xmp.video.TagName" }, //u
{ 0x05b9, "EditionEntry" }, //s
{ 0x05bc, "EditionUID" }, //sd
{ 0x05bd, "EditionFlagHidden" }, //sd
{ 0x05db, "EditionFlagDefault" }, //sd
{ 0x05dd, "EditionFlagOrdered" }, //sd
{ 0x065c, "Xmp.video.AttachFileData" }, //u
{ 0x0660, "Xmp.video.AttachFileMIME" }, //u
{ 0x066e, "Xmp.video.AttachFileName" }, //u
{ 0x0675, "AttachedFileReferral" }, //sd
{ 0x067e, "Xmp.video.AttachFileDesc" }, //u
{ 0x06ae, "Xmp.video.AttachFileUID" }, //u
{ 0x07e1, "Xmp.video.ContentEncryptAlgo" }, //u
{ 0x07e2, "ContentEncryptionKeyID" }, //sd
{ 0x07e3, "ContentSignature" }, //sd
{ 0x07e4, "ContentSignatureKeyID" }, //sd
{ 0x07e5, "Xmp.video.ContentSignAlgo" }, //u
{ 0x07e6, "Xmp.video.ContentSignHashAlgo" }, //u
{ 0x0d80, "Xmp.video.MuxingApp" }, //u
{ 0x0dbb, "Seek" }, //s
{ 0x1031, "ContentEncodingOrder" }, //sd
{ 0x1032, "ContentEncodingScope" }, //sd
{ 0x1033, "Xmp.video.ContentEncodingType" }, //u
{ 0x1034, "ContentCompression" }, //s
{ 0x1035, "ContentEncryption" }, //s
{ 0x135f, "CueRefNumber" }, //sd
{ 0x136e, "Xmp.video.TrackName" }, //u
{ 0x1378, "CueBlockNumber" }, //sd
{ 0x137f, "TrackOffset" }, //sd
{ 0x13ab, "SeekID" }, //sd
{ 0x13ac, "SeekPosition" }, //sd
{ 0x13b8, "Stereo3DMode" }, //sd
{ 0x14aa, "Xmp.video.CropBottom" }, //ui
{ 0x14b0, "Xmp.video.Width" }, //u
{ 0x14b2, "Xmp.video.DisplayUnit" }, //u
{ 0x14b3, "Xmp.video.AspectRatioType" }, //u
{ 0x14ba, "Xmp.video.Height" }, //u
{ 0x14bb, "Xmp.video.CropTop" }, //ui
{ 0x14cc, "Xmp.video.CropLeft" }, //ui
{ 0x14dd, "Xmp.video.CropRight" }, //ui
{ 0x15aa, "TrackForced" }, //ui
{ 0x15ee, "MaxBlockAdditionID" }, //sd
{ 0x1741, "Xmp.video.WritingApp" }, //u
{ 0x1854, "SilentTracks" }, //s
{ 0x18d7, "SilentTrackNumber" }, //sd
{ 0x21a7, "AttachedFile" }, //s
{ 0x2240, "ContentEncoding" }, //s
{ 0x2264, "Xmp.audio.BitsPerSample" }, //u
{ 0x23a2, "CodecPrivate" }, //sd
{ 0x23c0, "Targets" }, //s
{ 0x23c3, "Xmp.video.PhysicalEquivalent" }, //u
{ 0x23c4, "TagChapterUID" }, //sd
{ 0x23c5, "TagTrackUID" }, //sd
{ 0x23c6, "TagAttachmentUID" }, //sd
{ 0x23c9, "TagEditionUID" }, //sd
{ 0x23ca, "Xmp.video.TargetType" }, //u
{ 0x2532, "SignedElement" }, //sd
{ 0x2624, "TrackTranslate" }, //s
{ 0x26a5, "TrackTranslateTrackID" }, //sd
{ 0x26bf, "TrackTranslateCodec" }, //sd
{ 0x26fc, "TrackTranslateEditionUID" }, //sd
{ 0x27c8, "SimpleTag" }, //s
{ 0x28ca, "TargetTypeValue" }, //sd
{ 0x2911, "ChapterProcessCommand" }, //s
{ 0x2922, "ChapterProcessTime" }, //sd
{ 0x2924, "ChapterTranslate" }, //s
{ 0x2933, "ChapterProcessData" }, //sd
{ 0x2944, "ChapterProcess" }, //s
{ 0x2955, "ChapterProcessCodecID" }, //sd
{ 0x29a5, "ChapterTranslateID" }, //sd
{ 0x29bf, "Xmp.video.TranslateCodec" }, //u
{ 0x29fc, "ChapterTranslateEditionUID" }, //sd
{ 0x2d80, "ContentEncodings" }, //s
{ 0x2de7, "MinCache" }, //sd
{ 0x2df8, "MaxCache" }, //sd
{ 0x2e67, "ChapterSegmentUID" }, //sd
{ 0x2ebc, "ChapterSegmentEditionUID" }, //sd
{ 0x2fab, "TrackOverlay" }, //sd
{ 0x3373, "Tag" }, //s
{ 0x3384, "SegmentFileName" }, //sd
{ 0x33a4, "SegmentUID" }, //sd
{ 0x33c4, "ChapterUID" }, //sd
{ 0x33c5, "TrackUID" }, //sd
{ 0x3446, "TrackAttachmentUID" }, //sd
{ 0x35a1, "BlockAdditions" }, //s
{ 0x38b5, "Xmp.audio.OutputSampleRate" }, //u
{ 0x3ba9, "Xmp.video.Title" }, //u
{ 0x3d7b, "ChannelPositions" }, //sd
{ 0x3e5b, "SignatureElements" }, //s
{ 0x3e7b, "SignatureElementList" }, //s
{ 0x3e8a, "Xmp.video.ContentSignAlgo" }, //u
{ 0x3e9a, "Xmp.video.ContentSignHashAlgo" }, //u
{ 0x3ea5, "SignaturePublicKey" }, //sd
{ 0x3eb5, "Signature" }, //sd
{ 0x2b59c, "TrackLanguage" }, //ui
{ 0x3314f, "TrackTimecodeScale" }, //sd
{ 0x383e3, "Xmp.video.FrameRate" }, //u
{ 0x3e383, "VideoFrameRate/DefaultDuration" }, //ui
{ 0x58688, "VideoCodecName/AudioCodecName/CodecName" }, //ui
{ 0x6b240, "CodecDownloadURL" }, //ui
{ 0xad7b1, "TimecodeScale" }, //ui
{ 0xeb524, "ColorSpace" }, //sd
{ 0xfb523, "Xmp.video.OpColor" }, //u
{ 0x1a9697, "CodecSettings" }, //ui
{ 0x1b4040, "CodecInfoURL" }, //ui
{ 0x1c83ab, "PrevFileName" }, //sd
{ 0x1cb923, "PrevUID" }, //sd
{ 0x1e83bb, "NextFileName" }, //sd
{ 0x1eb923, "NextUID" }, //sd
{ 0x43a770, "Chapters" }, //sd
{ 0x14d9b74, "SeekHead" }, //s
{ 0x254c367, "Tags" }, //s
{ 0x549a966, "Info" }, //s
{ 0x654ae6b, "Tracks" }, //s
{ 0x8538067, "SegmentHeader" }, //s
{ 0x941a469, "Attachments" }, //s
{ 0xa45dfa3, "EBMLHeader" }, //s
{ 0xb538667, "SignatureSlot" }, //s
{ 0xc53bb6b, "Cues" }, //s
{ 0xf43b675, "Cluster" }, //s
};
extern const TagDetails matroskaTrackType[] = {
{ 0x1, "Video" },
{ 0x2, "Audio" },
{ 0x3, "Complex" },
{ 0x10, "Logo" },
{ 0x11, "Subtitle" },
{ 0x12, "Buttons" },
{ 0x20, "Control" }
};
extern const TagDetails compressionAlgorithm[] = {
{ 0, "zlib " },
{ 1, "bzlib" },
{ 2, "lzo1x" },
{ 3, "Header Stripping" }
};
extern const TagDetails audioChannels[] = {
{ 1, "Mono" },
{ 2, "Stereo" },
{ 5, "5.1 Surround Sound" },
{ 7, "7.1 Surround Sound" }
};
extern const TagDetails displayUnit[] = {
{ 0x0, "Pixels" },
{ 0x1, "cm" },
{ 0x2, "inches" }
};
extern const TagDetails encryptionAlgorithm[] = {
{ 0, "Not Encrypted" },
{ 1, "DES" },
{ 2, "3DES" },
{ 3, "Twofish" },
{ 4, "Blowfish" },
{ 5, "AES" }
};
extern const TagDetails chapterPhysicalEquivalent[] = {
{ 10, "Index" },
{ 20, "Track" },
{ 30, "Session" },
{ 40, "Layer" },
{ 50, "Side" },
{ 60, "CD / DVD" },
{ 70, "Set / Package" },
};
extern const TagDetails encodingType[] = {
{ 0, "Compression" },
{ 1, "Encryption" }
};
extern const TagDetails videoScanType[] = {
{ 0, "Progressive" },
{ 1, "Interlaced" }
};
extern const TagDetails chapterTranslateCodec[] = {
{ 0, "Matroska Script" },
{ 1, "DVD Menu" }
};
extern const TagDetails aspectRatioType[] = {
{ 0, "Free Resizing" },
{ 1, "Keep Aspect Ratio" },
{ 2, "Fixed" }
};
extern const TagDetails contentSignatureAlgorithm[] = {
{ 0, "Not Signed" },
{ 1, "RSA" }
};
extern const TagDetails contentSignatureHashAlgorithm[] = {
{ 0, "Not Signed" },
{ 1, "SHA1-160" },
{ 2, "MD5" }
};
extern const TagDetails trackEnable[] = {
{ 0x1, "Xmp.video.Enabled" },
{ 0x2, "Xmp.audio.Enabled" },
{ 0x11, "Xmp.video.SubTEnabled" }
};
extern const TagDetails defaultOn[] = {
{ 0x1, "Xmp.video.DefaultOn" },
{ 0x2, "Xmp.audio.DefaultOn" },
{ 0x11, "Xmp.video.SubTDefaultOn" }
};
extern const TagDetails trackForced[] = {
{ 0x1, "Xmp.video.TrackForced" },
{ 0x2, "Xmp.audio.TrackForced" },
{ 0x11, "Xmp.video.SubTTrackForced" }
};
extern const TagDetails trackLacing[] = {
{ 0x1, "Xmp.video.TrackLacing" },
{ 0x2, "Xmp.audio.TrackLacing" },
{ 0x11, "Xmp.video.SubTTrackLacing" }
};
extern const TagDetails codecDecodeAll[] = {
{ 0x1, "Xmp.video.CodecDecodeAll" },
{ 0x2, "Xmp.audio.CodecDecodeAll" },
{ 0x11, "Xmp.video.SubTCodecDecodeAll" }
};
extern const TagDetails codecDownloadUrl[] = {
{ 0x1, "Xmp.video.CodecDownloadUrl" },
{ 0x2, "Xmp.audio.CodecDownloadUrl" },
{ 0x11, "Xmp.video.SubTCodecDownloadUrl" }
};
extern const TagDetails codecSettings[] = {
{ 0x1, "Xmp.video.CodecSettings" },
{ 0x2, "Xmp.audio.CodecSettings" },
{ 0x11, "Xmp.video.SubTCodecSettings" }
};
extern const TagDetails trackCodec[] = {
{ 0x1, "Xmp.video.Codec" },
{ 0x2, "Xmp.audio.Compressor" },
{ 0x11, "Xmp.video.SubTCodec" }
};
extern const TagDetails trackLanguage[] = {
{ 0x1, "Xmp.video.TrackLang" },
{ 0x2, "Xmp.audio.TrackLang" },
{ 0x11, "Xmp.video.SubTLang" }
};
extern const TagDetails codecInfo[] = {
{ 0x1, "Xmp.video.CodecInfo" },
{ 0x2, "Xmp.audio.CodecInfo" },
{ 0x11, "Xmp.video.SubTCodecInfo" }
};
extern const TagDetails streamRate[] = {
{ 0x1, "Xmp.video.FrameRate" },
{ 0x2, "Xmp.audio.DefaultDuration" }
};
/*!
@brief Function used to calulate Tags, Tags may comprise of more than
one byte, that is why two buffers are to be provided.
The first buffer calculates size of the Tag and the second buffer
is used to calculate the rest of the Tag.
Returns Tag Value in unsinged long.
*/
unsigned long returnTagValue(byte b, Exiv2::DataBuf& buf2, int n ) {
long temp = 0;
long reg1 = 0;
reg1 = (b & (int)(pow(2,8-n)-1));
for(int i = n-2; i >= 0; i--) {
temp = temp + buf2.pData_[i]*(pow(256,n-i-2));
}
temp += reg1 * pow(256,n-1);
return temp;
}
//! Function used to convert buffer data into numerical information, information stored in BigEndian format
int64_t returnValue(Exiv2::DataBuf& buf, int n ) {
int64_t temp = 0;
for(int i = n-1; i >= 0; i--) {
temp = temp + buf.pData_[i]*(pow(256,n-i-1));
}
return temp;
}
}} // namespace Internal, Exiv2
namespace Exiv2 {
using namespace Exiv2::Internal;
MatroskaVideo::MatroskaVideo(BasicIo::AutoPtr io)
: Image(ImageType::mkv, mdNone, io)
{
} // MatroskaVideo::MatroskaVideo
std::string MatroskaVideo::mimeType() const
{
return "video/matroska";
}
void MatroskaVideo::writeMetadata()
{
}
void MatroskaVideo::readMetadata()
{
if (io_->open() != 0) throw Error(9, io_->path(), strError());
// Ensure that this is the correct image type
if (!isMkvType(*io_, false)) {
if (io_->error() || io_->eof()) throw Error(14);
throw Error(3, "Matroska");
}
IoCloser closer(*io_);
clearMetadata();
height_ = width_ = 1;
xmpData_["Xmp.video.FileName"] = io_->path();
xmpData_["Xmp.video.FileSize"] = (double)io_->size()/(double)1048576;
xmpData_["Xmp.video.MimeType"] = mimeType();
while (continueTraversing_) decodeBlock();
aspectRatio();
} // MatroskaVideo::readMetadata
void MatroskaVideo::decodeBlock()
{
const long bufMinSize = 200;
DataBuf buf2(bufMinSize);
byte b;
io_->read(&b, 1);
if(io_->eof()) {
continueTraversing_ = false;
return;
}
long sz = findBlockSize(b);
if (sz > 0) io_->read(buf2.pData_, sz - 1);
const TagDetails* td;
td = find(matroskaTags, returnTagValue(b, buf2, sz));
if(td->val_ == 0xc53bb6b || td->val_ == 0xf43b675) {
continueTraversing_ = false;
return;
}
bool skip = find(compositeTagsList, (uint32_t)td->val_);
bool ignore = find(ignoredTagsList, (uint32_t)td->val_);
io_->read(&b, 1);
sz = findBlockSize(b);
if (sz > 0) io_->read(buf2.pData_, sz - 1);
long size = returnTagValue(b, buf2, sz);
if (skip && !ignore) return;
if (ignore || size > bufMinSize) {
io_->seek(size, BasicIo::cur);
return;
}
DataBuf buf(bufMinSize);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, size);
contentManagement(td, buf, size);
} // MatroskaVideo::decodeBlock
void MatroskaVideo::contentManagement(const TagDetails* td, Exiv2::DataBuf& buf, long size)
{
int64_t duration_in_ms = 0;
static double time_code_scale = 1.0, temp = 0;
static long stream = 0, track_count = 0;
char str[4] = "No";
const TagDetails* internal_td = NULL;
switch (td->val_) {
case 0x0282: case 0x0d80: case 0x1741: case 0x3ba9: case 0x066e: case 0x0660:
case 0x065c: case 0x067e: case 0x047a: case 0x0487: case 0x05a3: case 0x136e:
case 0x23ca: case 0xeb524:
xmpData_[exvGettext(td->label_)] = buf.pData_;
break;
case 0x0030: case 0x003a: case 0x0287: case 0x14b0: case 0x14ba: case 0x285:
case 0x06ae: case 0x0286: case 0x02f7: case 0x2264: case 0x14aa: case 0x14bb:
case 0x14cc: case 0x14dd:
xmpData_[exvGettext(td->label_)] = returnValue(buf, size);
if(td->val_ == 0x0030 || td->val_ == 0x14b0)
width_ = returnValue(buf, size);
else if(td->val_ == 0x003a || td->val_ == 0x14ba)
height_ = returnValue(buf, size);
break;
case 0x001a: case 0x001f: case 0x0254: case 0x07e1: case 0x07e5: case 0x07e6:
case 0x1033: case 0x14b2: case 0x14b3: case 0x23c3: case 0x29bf: case 0x3e8a:
case 0x3e9a:
switch (td->val_) {
case 0x001a: internal_td = find(videoScanType, returnValue(buf, size)); break;
case 0x001f: internal_td = find(audioChannels, returnValue(buf, size)); break;
case 0x0254: internal_td = find(compressionAlgorithm, returnValue(buf, size)); break;
case 0x07e1: internal_td = find(encryptionAlgorithm, returnValue(buf, size)); break;
case 0x1033: internal_td = find(encodingType, returnValue(buf, size)); break;
case 0x3e8a:
case 0x07e5: internal_td = find(contentSignatureAlgorithm, returnValue(buf, size)); break;
case 0x3e9a:
case 0x07e6: internal_td = find(contentSignatureHashAlgorithm, returnValue(buf, size)); break;
case 0x14b2: internal_td = find(displayUnit, returnValue(buf, size)); break;
case 0x14b3: internal_td = find(aspectRatioType, returnValue(buf, size)); break;
case 0x23c3: internal_td = find(chapterPhysicalEquivalent, returnValue(buf, size)); break;
case 0x29bf: internal_td = find(chapterTranslateCodec, returnValue(buf, size)); break;
}
if(internal_td)
xmpData_[exvGettext(td->label_)] = exvGettext(internal_td->label_);
break;
case 0x0035: case 0x38b5:
xmpData_[exvGettext(td->label_)] = Exiv2::getFloat(buf.pData_, bigEndian);
break;
case 0x0039: case 0x0008: case 0x15aa: case 0x001c: case 0x002a: case 0x1a9697:
case 0x0484:
if (returnValue(buf, size)) strcpy(str, "Yes");
switch (td->val_) {
case 0x0039: internal_td = find(trackEnable, stream); break;
case 0x0008: internal_td = find(defaultOn, stream); break;
case 0x15aa: internal_td = find(trackForced, stream); break;
case 0x001c: internal_td = find(trackLacing, stream); break;
case 0x002a: internal_td = find(codecDecodeAll, stream); break;
case 0x1a9697: internal_td = find(codecSettings, stream); break;
case 0x0484: internal_td = td; break;
}
if (internal_td) xmpData_[exvGettext(internal_td->label_)] = str;
break;
case 0x0006: case 0x2b59c: case 0x58688: case 0x6b240: case 0x1b4040:
switch (td->val_) {
case 0x0006: internal_td = find(trackCodec, stream); break;
case 0x2b59c: internal_td = find(trackLanguage, stream); break;
case 0x58688: internal_td = find(codecInfo, stream); break;
case 0x6b240:
case 0x1b4040: internal_td = find(codecDownloadUrl, stream); break;
}
if (internal_td) xmpData_[exvGettext(internal_td->label_)] = buf.pData_;
break;
case 0x0489: case 0x0461:
switch (td->val_) {
case 0x0489:
if(size <= 4) {
duration_in_ms = Exiv2::getFloat(buf.pData_, bigEndian) * time_code_scale * 1000;
}
else {
duration_in_ms = Exiv2::getDouble(buf.pData_, bigEndian) * time_code_scale * 1000;
}
break;
case 0x0461: duration_in_ms = returnValue(buf, size)/1000000000; break;
}
xmpData_[exvGettext(td->label_)] = duration_in_ms;
break;
case 0x0057:
track_count++;
xmpData_["Xmp.video.TotalStream"] = track_count;
break;
case 0xad7b1:
time_code_scale = (double)returnValue(buf, size)/(double)1000000000;
xmpData_["Xmp.video.TimecodeScale"] = time_code_scale;
break;
case 0x0003:
internal_td = find(matroskaTrackType, returnValue(buf, size));
stream = internal_td->val_;
break;
case 0x3e383: case 0x383e3:
internal_td = find(streamRate, stream);
if (returnValue(buf, size)) {
switch (stream) {
case 1: temp = (double)1000000000/(double)returnValue(buf, size); break;
case 2: temp = returnValue(buf, size)/1000; break;
}
if (internal_td) xmpData_[exvGettext(internal_td->label_)] = temp;
}
else
if (internal_td) xmpData_[exvGettext(internal_td->label_)] = "Variable Bit Rate";
break;
default:
break;
}
} // MatroskaVideo::contentManagement
void MatroskaVideo::aspectRatio()
{
//TODO - Make a better unified method to handle all cases of Aspect Ratio
double aspectRatio = (double)width_ / (double)height_;
aspectRatio = floor(aspectRatio*10) / 10;
xmpData_["Xmp.video.AspectRatio"] = aspectRatio;
if(aspectRatio == 1.3) xmpData_["Xmp.video.AspectRatio"] = "4:3";
else if(aspectRatio == 1.7) xmpData_["Xmp.video.AspectRatio"] = "16:9";
else if(aspectRatio == 1.0) xmpData_["Xmp.video.AspectRatio"] = "1:1";
else if(aspectRatio == 1.6) xmpData_["Xmp.video.AspectRatio"] = "16:10";
else if(aspectRatio == 2.2) xmpData_["Xmp.video.AspectRatio"] = "2.21:1";
else if(aspectRatio == 2.3) xmpData_["Xmp.video.AspectRatio"] = "2.35:1";
else if(aspectRatio == 1.2) xmpData_["Xmp.video.AspectRatio"] = "5:4";
else xmpData_["Xmp.video.AspectRatio"] = aspectRatio;
} // MatroskaVideo::aspectRatio
long MatroskaVideo::findBlockSize(byte b)
{
if (b & 128) return 1;
else if (b & 64) return 2;
else if (b & 32) return 3;
else if (b & 16) return 4;
else if (b & 8) return 5;
else if (b & 4) return 6;
else if (b & 2) return 7;
else if (b & 1) return 8;
else return 0;
} // MatroskaVideo::findBlockSize
Image::AutoPtr newMkvInstance(BasicIo::AutoPtr io, bool /*create*/)
{
Image::AutoPtr image(new MatroskaVideo(io));
if (!image->good()) {
image.reset();
}
return image;
}
bool isMkvType(BasicIo& iIo, bool advance)
{
bool result = true;
byte tmpBuf[4];
iIo.read(tmpBuf, 4);
if (iIo.error() || iIo.eof()) return false;
if (0x1a != tmpBuf[0] || 0x45 != tmpBuf[1] || 0xdf != tmpBuf[2] || 0xa3 != tmpBuf[3]) {
result = false;
}
if (!advance || !result ) iIo.seek(0, BasicIo::beg);
return result;
}
} // namespace Exiv2

@ -0,0 +1,145 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2012 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 matroskavideo.hpp
@brief An Image subclass to support Matroska video files
@version $Rev$
@author Abhinav Badola for GSoC 2012
<a href="mailto:mail.abu.to@gmail.com">mail.abu.to@gmail.com</a>
@date 18-Jun-12, AB: created
*/
#ifndef MATROSKAVIDEO_HPP_
#define MATROSKAVIDEO_HPP_
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "image.hpp"
#include "tags_int.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add MKV to the supported image formats
namespace ImageType {
const int mkv = 21; //!< Treating mkv as an image type>
}
/*!
@brief Class to access Matroska video files.
*/
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.
@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.
*/
MatroskaVideo(BasicIo::AutoPtr io);
//@}
//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}
//! @name Accessors
//@{
std::string mimeType() const;
//@}
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
the number of leading zeros in the binary code of the byte.
Size = (No. of leading zeros + 1) bytes
@param b The byte, which stores the information to calculate the size
@return Return the size of the block.
*/
long 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();
/*!
@brief Interpret tag information, and save it in the respective XMP container.
@param td Pointer to current tag,
@param buf Data buffer with the tag information.
@param size Size of buf.
*/
void contentManagement(const Exiv2::Internal::TagDetails* td, Exiv2::DataBuf& buf, long size);
/*!
@brief Calculates Aspect Ratio of a video, and stores it in the
respective XMP container.
*/
void aspectRatio();
private:
//! @name NOT Implemented
//@{
//! Copy constructor
MatroskaVideo(const MatroskaVideo& rhs);
//! Assignment operator
MatroskaVideo& operator=(const MatroskaVideo& rhs);
//@}
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_;
}; // 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.
/*!
@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);
//! Check if the file iIo is a Matroska Video.
EXIV2API bool isMkvType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // #ifndef MATROSKAVIDEO_HPP_

@ -96,6 +96,8 @@ namespace Exiv2 {
extern const XmpPropertyInfo xmpMicrosoftPhotoRegionInfoInfo[];
extern const XmpPropertyInfo xmpMicrosoftPhotoRegionInfo[];
extern const XmpPropertyInfo xmpMWGRegionsInfo[];
extern const XmpPropertyInfo xmpVideoInfo[];
extern const XmpPropertyInfo xmpAudioInfo[];
extern const XmpNsInfo xmpNsInfo[] = {
// Schemas - NOTE: Schemas which the XMP-SDK doesn't know must be registered in XmpParser::initialize - Todo: Automate this
@ -126,12 +128,15 @@ namespace Exiv2 {
{ "http://ns.microsoft.com/photo/1.2/t/RegionInfo#", "MPRI", xmpMicrosoftPhotoRegionInfoInfo, N_("Microsoft Photo RegionInfo schema")},
{ "http://ns.microsoft.com/photo/1.2/t/Region#", "MPReg", xmpMicrosoftPhotoRegionInfo, N_("Microsoft Photo Region schema") },
{ "http://www.metadataworkinggroup.com/schemas/regions/", "mwg-rs", xmpMWGRegionsInfo,N_("Metadata Working Group Regions schema") },
{ "http://www.video", "video", xmpVideoInfo, N_("XMP Extended Video schema") },
{ "http://www.audio", "audio", xmpAudioInfo, N_("XMP Extended Audio schema") },
// Structures
{ "http://ns.adobe.com/xap/1.0/g/", "xapG", 0, N_("Colorant structure") },
{ "http://ns.adobe.com/xap/1.0/sType/Dimensions#", "stDim", 0, N_("Dimensions structure") },
{ "http://ns.adobe.com/xap/1.0/sType/Font#", "stFnt", 0, N_("Font structure") },
{ "http://ns.adobe.com/xap/1.0/g/img/", "xapGImg", 0, N_("Thumbnail structure") },
{ "http://ns.adobe.com/xap/1.0/g/img/", "xmpGImg", 0, N_("Thumbnail structure") },
{ "http://ns.adobe.com/xap/1.0/sType/ResourceEvent#", "stEvt", 0, N_("Resource Event structure") },
{ "http://ns.adobe.com/xap/1.0/sType/ResourceRef#", "stRef", 0, N_("ResourceRef structure") },
{ "http://ns.adobe.com/xap/1.0/sType/Version#", "stVer", 0, N_("Version structure") },
@ -986,6 +991,390 @@ namespace Exiv2 {
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpVideoInfo[] = {
{ "Album", N_("Album"), "Text", xmpText, xmpExternal, N_("The name of the album.") },
{ "ArchivalLocation", N_("Archival Location"), "Text", xmpText, xmpExternal, N_("Information about the Archival Location.") },
{ "Arranger", N_("Arranger"), "Text", xmpText, xmpExternal, N_("Information about the Arranger.") },
{ "ArrangerKeywords", N_("Arranger Keywords"), "Text", xmpText, xmpExternal, N_("Information about the Arranger Keywords.") },
{ "Artist", N_("Artist"), "Text", xmpText, xmpExternal, N_("The name of the artist or artists.") },
{ "AspectRatio", N_("Video Aspect Ratio"), "Ratio", xmpText, xmpExternal, N_("Ratio of Width:Height, helps to determine how a video would be displayed on a screen") },
{ "AspectRatioType", N_("Video Aspect Ratio Type"), "Text", xmpText, xmpExternal, N_("Aspect Ratio Type. Eg - Free-Resizing or Fixed") },
{ "AttachFileData", N_("Attached File Data"), "Text", xmpText, xmpExternal, N_("Attached File Data") },
{ "AttachFileDesc", N_("Attached File Description"), "Text", xmpText, xmpExternal, N_("Attached File Description") },
{ "AttachFileMIME", N_("Attached File MIME Type"), "Text", xmpText, xmpExternal, N_("Attached File MIME Type") },
{ "AttachFileName", N_("Attached File Name"), "Text", xmpText, xmpExternal, N_("Attached File Name") },
{ "AttachFileUID", N_("Attached File UID"), "Integer", xmpText, xmpExternal, N_("Attached File Universal ID") },
{ "BaseURL", N_("Base URL"), "Text", xmpText, xmpExternal, N_("A C string that specifies a Base URL.") },
{ "BitDepth", N_("Bit Depth"), "Integer", xmpText, xmpExternal, N_("A 16-bit integer that indicates the pixel depth of the compressed image. Values of 1, 2, 4, 8 , 16, 24, and 32 indicate the depth of color images") },
{ "Brightness", N_("Brightness"), "Integer", xmpText, xmpExternal, N_("Brightness setting.") },
{ "CameraByteOrder", N_("Camera Byte Order"), "Text", xmpText, xmpExternal, N_("Byte Order used by the Video Capturing device.") },
{ "Cinematographer", N_("Video Cinematographer"), "Text", xmpText, xmpExternal, N_("The video Cinematographer information.") },
{ "Codec", N_("Video Codec"), "Text", xmpText, xmpExternal, N_("The video codec information. Informs about the encoding algorithm of video. Codec Info is required for video playback.") },
{ "CodecDecodeAll", N_("Video Codec Decode Info"), "Text", xmpText, xmpExternal, N_("Contains information the video Codec Decode All, i.e. Enabled/Disabled") },
{ "CodecDescription", N_("Video Codec Description"), "Text", xmpText, xmpExternal, N_("Contains description the codec.") },
{ "CodecInfo", N_("Video Codec Information"), "Text", xmpText, xmpExternal, N_("Contains information the codec needs before decoding can be started.") },
{ "CodecDownloadUrl", N_("Video Codec Download URL"), "Text", xmpText, xmpExternal, N_("Video Codec Download URL.") },
{ "CodecSettings", N_("Video Codec Settings"), "Text", xmpText, xmpExternal, N_("Contains settings the codec needs before decoding can be started.") },
{ "ColorMode", N_("Color Mode"), "Text", xmpText, xmpExternal, N_("Color Mode") },
{ "ColorNoiseReduction", N_("Color Noise Reduction"), "Integer", xmpText, xmpExternal, N_("\"Color Noise Reducton\" setting. Range 0 to +100.") },
{ "ColorSpace", N_("Video Color Space"), "closed Choice of Text", xmpText, xmpInternal, N_("The color space. One of: sRGB (used by Photoshop), CCIR-601 (used for NTSC), "
"CCIR-709 (used for HD).") },
{ "Comment", N_("Comment"), "Text", xmpText, xmpExternal, N_("Information about the Comment.") },
{ "Commissioned", N_("Commissioned"), "Text", xmpText, xmpExternal, N_("Commissioned.") },
{ "CompatibleBrands", N_("QTime Compatible FileType Brand"), "Text", xmpText, xmpExternal, N_("Other QuickTime Compatible FileType Brand") },
{ "Composer", N_("Composer"), "Text", xmpText, xmpExternal, N_("Information about the Composer.") },
{ "ComposerKeywords", N_("Composer Keywords"), "Text", xmpText, xmpExternal, N_("Information about the Composer Keywords.") },
{ "Compressor", N_("Compressor"), "Text", xmpText, xmpExternal, N_("Video Compression Library Used") },
{ "CompressorID", N_("Video Compressor ID"), "Text", xmpText, xmpExternal, N_("Video Compression ID of Technology/Codec Used") },
{ "CompressorVersion", N_("Compressor Version"), "Text", xmpText, xmpExternal, N_("Information about the Compressor Version.") },
{ "Container", N_("Container Type"), "Text", xmpText, xmpExternal, N_("Primary Metadata Container") },
{ "ContentCompressAlgo", N_("Content Compression Algorithm"), "Text", xmpText, xmpExternal, N_("Content Compression Algorithm. Eg: zlib") },
{ "ContentEncodingType", N_("Content Encoding Type"), "Text", xmpText, xmpExternal, N_("Content Encoding Type. Eg: Encryption or Compression") },
{ "ContentEncryptAlgo", N_("Content Encryption Algorithm"), "Text", xmpText, xmpExternal, N_("Content Encryption Algorithm. Eg: Blowfish") },
{ "ContentSignAlgo", N_("Content Signature Algorithm"), "Text", xmpText, xmpExternal, N_("Content Signature Algorithm. Eg: RSA") },
{ "ContentSignHashAlgo", N_("Content Sign Hash Algorithm"), "Text", xmpText, xmpExternal, N_("Content Signature Hash Algorithm. Eg: SHA1-160 or MD5") },
{ "Contrast", N_("Contrast"), "Closed Choice of Integer", xmpText, xmpInternal, N_("Indicates the direction of contrast processing applied by the camera.") },
{ "Copyright", N_("Copyright"), "Text", xmpText, xmpExternal, N_("Copyright, can be name of an organization or an individual.") },
{ "CostumeDesigner", N_("Costume Designer"), "Text", xmpText, xmpExternal, N_("Costume Designer associated with the video.") },
{ "Country", N_("Country"), "Text", xmpText, xmpExternal, N_("Name of the country where the video was created.") },
{ "CreationDate", N_("Creation Date"), "Integer", xmpText, xmpExternal, N_("Specifies the date and time of the initial creation of the file. The value is given as the "
"number of 100-nanosecond intervals since January 1, 1601, according to Coordinated Universal Time (Greenwich Mean Time).") },
{ "CropBottom", N_("Pixel Crop Bottom"), "Integer", xmpText, xmpExternal, N_("Number of Pixels to be cropped from the bottom.") },
{ "CropLeft", N_("Pixel Crop Left"), "Integer", xmpText, xmpExternal, N_("Number of Pixels to be cropped from the left.") },
{ "CropRight", N_("Pixel Crop Right"), "Integer", xmpText, xmpExternal, N_("Number of Pixels to be cropped from the right.") },
{ "Cropped", N_("Cropped"), "Integer", xmpText, xmpExternal, N_("Field that indicates if a video is cropped.") },
{ "CropTop", N_("Pixel Crop Top"), "Integer", xmpText, xmpExternal, N_("Number of Pixels to be cropped from the top.") },
{ "CurrentTime", N_("Current Time"), "Integer", xmpText, xmpExternal, N_("The time value for current time position within the movie.") },
{ "DataPackets", N_("Data Packets"), "Integer", xmpText, xmpExternal, N_("Specifies the number of Data Packet entries that exist within the Data Object.") },
{ "DateTimeOriginal", N_("Date and Time Original"), "Date", xmpText, xmpInternal, N_("Date and time when original video was generated, in ISO 8601 format. ") },
{ "DateTimeDigitized", N_("Date and Time Digitized"), "Date", xmpText, xmpInternal, N_("Date and time when video was stored as digital data, can be the same "
"as DateTimeOriginal if originally stored in digital form. Stored in ISO 8601 format.") },
{ "DateUTC", N_("Date-Time Original"), "Text", xmpText, xmpExternal, N_("Contains the production date") },
{ "DefaultOn", N_("Video Track Default On"), "Text", xmpText, xmpExternal, N_("Video Track Default On , i.e. Enabled/Disabled") },
{ "DigitalZoomRatio", N_("Digital Zoom Ratio"), "Rational", xmpText, xmpInternal, N_("Indicates the digital zoom ratio when the video was shot.") },
{ "Dimensions", N_("Dimensions"), "Text", xmpText, xmpExternal, N_("Information about the Dimensions of the video frame.") },
{ "Director", N_("Director"), "Text", xmpText, xmpExternal, N_("Information about the Director.") },
{ "DisplayUnit", N_("Video Display Unit"), "Text", xmpText, xmpExternal, N_("Video display unit. Eg - cm, pixels, inch") },
{ "DistributedBy", N_("Distributed By"), "Text", xmpText, xmpExternal, N_("Distributed By, i.e. name of person or organization.") },
{ "DocType", N_("Doc Type"), "Text", xmpText, xmpExternal, N_("Describes the contents of the file. In the case of a MATROSKA file, its value is 'matroska'") },
{ "DocTypeReadVersion", N_("Doc Type Read Version"), "Integer", xmpText, xmpExternal, N_("A Matroska video specific property, helps in determining the compatibility of file with a particular version of a video player") },
{ "DocTypeVersion", N_("Doc Type Version"), "Integer", xmpText, xmpExternal, N_("A Matroska video specific property, indicated the version of filetype, helps in determining the compatibility") },
{ "DotsPerInch", N_("Dots Per Inch"), "Integer", xmpText, xmpExternal, N_("Dots Per Inch") },
{ "duration", N_("Duration"), "Integer", xmpText, xmpExternal, N_("The duration of the media file. Measured in milli-seconds.") },
{ "EBMLReadVersion", N_("EBML Read Version"), "Integer", xmpText, xmpExternal, N_("Extensible Binary Meta Language Read Version") },
{ "EBMLVersion", N_("EBML Version"), "Integer", xmpText, xmpExternal, N_("Extensible Binary Meta Language Version") },
{ "Edit1", N_("Edit Block 1 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "Edit2", N_("Edit Block 2 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "Edit3", N_("Edit Block 3 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "Edit4", N_("Edit Block 4 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "Edit5", N_("Edit Block 5 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "Edit6", N_("Edit Block 6 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "Edit7", N_("Edit Block 7 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "Edit8", N_("Edit Block 8 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "Edit9", N_("Edit Block 9 / Language"), "Text", xmpText, xmpExternal, N_("Information about the Edit / Language.") },
{ "EditedBy", N_("Edited By"), "Text", xmpText, xmpExternal, N_("Edited By, i.e. name of person or organization.") },
{ "Enabled", N_("Video Track Enabled"), "Text", xmpText, xmpExternal, N_("Status of Video Track, i.e. Enabled/Disabled") },
{ "EncodedBy", N_("Encoded By"), "Text", xmpText, xmpExternal, N_("Encoded By, i.e. name of person or organization.") },
{ "Encoder", N_("Encoder"), "Text", xmpText, xmpExternal, N_("Information about the Encoder.") },
{ "EndTimecode", N_("End Timecode"), "Integer", xmpText, xmpExternal, N_("End Timecode") },
{ "Engineer", N_("Engineer"), "Text", xmpText, xmpExternal, N_("Engineer, in most cases name of person.") },
{ "Equipment", N_("Equipment"), "Text", xmpText, xmpExternal, N_("Information about the Equipment used for recording Video.") },
{ "ExposureCompensation", N_("Exposure Compensation"), "Text", xmpText, xmpExternal, N_("Exposure Compensation Information.") },
{ "ExposureProgram", N_("Exposure Program"), "Text", xmpText, xmpExternal, N_("Exposure Program Information.") },
{ "ExposureTime", N_("Exposure Time"), "Rational", xmpText, xmpInternal, N_("Exposure time in seconds.") },
{ "ExtendedContentDescription",N_("Extended Content Description"), "Text", xmpSeq, xmpExternal, N_("Extended Content Description,ususally found in ASF type files.") },
{ "FileDataRate", N_("File Data Rate"), "Rational", xmpText, xmpExternal, N_("The file data rate in megabytes per second. For example: \"36/10\" = 3.6 MB/sec") },
{ "FileID", N_("File ID"), "Text", xmpText, xmpExternal, N_("File ID.") },
{ "FileLength", N_("File Length"), "Integer", xmpText, xmpInternal, N_("File length.") },
{ "FileName", N_("File Name"), "Text", xmpText, xmpExternal, N_("File Name or Absolute File Path") },
{ "FileSize", N_("File Size"), "Integer", xmpText, xmpExternal, N_("File Size, in MB") },
{ "FileType", N_("File Type"), "Text", xmpText, xmpExternal, N_("Extension of File or Type of File") },
{ "FilterEffect", N_("Filter Effect"), "Text", xmpText, xmpExternal, N_("Filter Effect Settings Applied.") },
{ "FirmwareVersion", N_("Firmware Version"), "Text", xmpText, xmpExternal, N_("Firmware Version of the Camera/Video device.") },
{ "FNumber", N_("F Number"), "Rational", xmpText, xmpInternal, N_("F number. Camera Lens specific data.") },
{ "FocalLength", N_("Focal Length"), "Rational", xmpText, xmpInternal, N_("Focal length of the lens, in millimeters.") },
{ "FocusMode", N_("Focus Mode"), "Text", xmpText, xmpExternal, N_("Focus Mode of the Lens. Eg - AF for Auto Focus") },
{ "Format", N_("Format"), "Text", xmpText, xmpExternal, N_("Indication of movie format (computer-generated, digitized, and so on).") },
{ "FrameCount", N_("Frame Count"), "Integer", xmpText, xmpExternal, N_("Total number of frames in a video") },
{ "FrameHeight", N_("Frame Height"), "Integer", xmpText, xmpExternal, N_("Height of frames in a video") },
{ "FrameRate", N_("Video Frame Rate"), "Frames per Second", xmpText, xmpExternal, N_("Rate at which frames are presented in a video (Expressed in fps(Frames per Second))") },
{ "FrameSize", N_("Video Frame Size"), "Dimensions", xmpText, xmpExternal, N_("The frame size. For example: w:720, h: 480, unit:pixels") },
{ "FrameWidth", N_("Frame Width"), "Integer", xmpText, xmpExternal, N_("Width of frames in a video") },
{ "Genre", N_("Genre"), "Text", xmpText, xmpExternal, N_("The name of the genre.") },
{ "GPSAltitude", N_("GPS Altitude"), "Rational", xmpText, xmpInternal, N_("GPS tag 6, 0x06. Indicates altitude in meters.") },
{ "GPSAltitudeRef", N_("GPS Altitude Reference"), "Closed Choice of Integer", xmpText, xmpInternal, N_("GPS tag 5, 0x05. Indicates whether the altitude is above or below sea level.") },
{ "GPSCoordinates", N_("GPS Coordinates"), "Text", xmpText, xmpExternal, N_("Information about the GPS Coordinates.") },
{ "GPSDateStamp", N_("GPS Time Stamp"), "Date", xmpText, xmpInternal, N_("Date stamp of GPS data, ") },
{ "GPSImgDirection", N_("GPS Image Direction"), "Rational", xmpText, xmpInternal, N_("Direction of image when captured, values range from 0 to 359.99.") },
{ "GPSImgDirectionRef", N_("GPS Image Direction Reference"), "Closed Choice of Text", xmpText, xmpInternal, N_("Reference for image direction.") },
{ "GPSLatitude", N_("GPS Latitude"), "GPSCoordinate", xmpText, xmpInternal, N_("(North/South). Indicates latitude.") },
{ "GPSLongitude", N_("GPS Longitude"), "GPSCoordinate", xmpText, xmpInternal, N_("(East/West). Indicates longitude.") },
{ "GPSMapDatum", N_("GPS Map Datum"), "Text", xmpText, xmpInternal, N_("Geodetic survey data.") },
{ "GPSSatellites", N_("GPS Satellites"), "Text", xmpText, xmpInternal, N_("Satellite information, format is unspecified.") },
{ "GPSTimeStamp", N_("GPS Time Stamp"), "Date", xmpText, xmpInternal, N_("Time stamp of GPS data, ") },
{ "GPSVersionID", N_("GPS Version ID"), "Text", xmpText, xmpInternal, N_("A decimal encoding with period separators. ") },
{ "GraphicsMode", N_("Graphcs Mode"), "Text", xmpText, xmpExternal, N_("A 16-bit integer that specifies the transfer mode. The transfer mode specifies which Boolean"
"operation QuickDraw should performwhen drawing ortransferring an image fromone location to another.") },
{ "Grouping", N_("Grouping"), "Text", xmpText, xmpExternal, N_("Information about the Grouping.") },
{ "HandlerClass", N_("Handler Class"), "Text", xmpText, xmpExternal, N_("A four-character code that identifies the type of the handler. Only two values are valid for this field: 'mhlr' for media handlers and 'dhlr' for data handlers.") },
{ "HandlerDescription", N_("Handler Description"), "Text", xmpText, xmpExternal, N_("A (counted) string that specifies the name of the component—that is, the media handler used when this media was created..") },
{ "HandlerType", N_("Handler Type"), "Text", xmpText, xmpExternal, N_("A four-character code that identifies the type of the media handler or data handler.") },
{ "HandlerVendorID", N_("Handler Vendor ID"), "Text", xmpText, xmpExternal, N_("Component manufacturer.") },
{ "Height", N_("Video Height"), "Integer", xmpText, xmpExternal, N_("Video height in pixels") },
{ "HueAdjustment", N_("Hue Adjustment"), "Integer", xmpText, xmpExternal, N_("Hue Adjustment Settings Information.") },
{ "ImageLength", N_("Image Length"), "Integer", xmpText, xmpExternal, N_("Image Length, a property inherited from BitMap format") },
{ "InfoBannerImage", N_("Info Banner Image"), "Text", xmpText, xmpExternal, N_("Information Banner Image.") },
{ "InfoBannerURL", N_("Info Banner URL"), "Text", xmpText, xmpExternal, N_("Information Banner URL.") },
{ "Information", N_("Information"), "Text", xmpText, xmpExternal, N_("Additional Movie Information.") },
{ "InfoText", N_("Info Text"), "Text", xmpText, xmpExternal, N_("Information Text.") },
{ "InfoURL", N_("Info URL"), "Text", xmpText, xmpExternal, N_("Information URL.") },
{ "ISRCCode", N_("ISRC Code"), "Text", xmpText, xmpExternal, N_("Information about the ISRC Code.") },
{ "Junk", N_("Junk Data"), "Text", xmpText, xmpExternal, N_("Video Junk data") },
{ "Language", N_("Language"), "Text", xmpText, xmpExternal, N_("Language.") },
{ "Length", N_("Length"), "Integer", xmpText, xmpExternal, N_("The length of the media file.") },
{ "LensModel", N_("Lens Model"), "Text", xmpText, xmpExternal, N_("Lens Model.") },
{ "LensType", N_("Lens Type"), "Text", xmpText, xmpExternal, N_("Lens Type.") },
{ "Lightness", N_("Lightness"), "Text", xmpText, xmpExternal, N_("Lightness.") },
{ "LocationInfo", N_("Location Information"), "Text", xmpText, xmpExternal, N_("Location Information.") },
{ "LogoIconURL", N_("Logo Icon URL"), "Text", xmpText, xmpExternal, N_("A C string that specifies Logo Icon URL.") },
{ "LogoURL", N_("Logo URL"), "Text", xmpText, xmpExternal, N_("A C string that specifies a Logo URL.") },
{ "Lyrics", N_("Lyrics"), "Text", xmpText, xmpExternal, N_("Lyrics of a Song/Video.") },
{ "MajorBrand", N_("QTime Major FileType Brand"), "Text", xmpText, xmpExternal, N_("QuickTime Major File Type Brand") },
{ "Make", N_("Equipment Make"), "Text", xmpText, xmpExternal, N_("Manufacturer of recording equipment") },
{ "MakerNoteType", N_("Camera Maker Note Type"), "Text", xmpText, xmpExternal, N_("Maker Note Type of the camera.") },
{ "MakerNoteVersion", N_("Camera Maker Note Version"), "Text", xmpText, xmpExternal, N_("Maker Note Version of the camera.") },
{ "MakerURL", N_("Maker URL"), "Text", xmpText, xmpExternal, N_("Camera Manufacturer's URL.") },
{ "MaxApertureValue", N_("Maximum Aperture Value"), "Rational", xmpText, xmpInternal, N_("Smallest F number of lens, in APEX.") },
{ "MaxBitRate", N_("Maximum Bit Rate"), "Integer", xmpText, xmpExternal, N_("Specifies the maximum instantaneous bit rate in bits per second for the entire file. This shall equal the sum of the bit rates of the individual digital media streams.") },
{ "MaxDataRate", N_("Maximum Data Rate"), "kiloBytes per Second", xmpText, xmpExternal, N_("Peak rate at which data is presented in a video (Expressed in kB/s(kiloBytes per Second))") },
{ "MediaCreateDate", N_("Media Track Create Date"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates (in seconds since midnight, January 1, 1904) when the media header was created.") },
{ "MediaDuration", N_("Media Track Duration"), "Integer", xmpText, xmpExternal, N_("A time value that indicates the duration of this media (in the movies time coordinate system).") },
{ "MediaHeaderVersion", N_("Media Header Version"), "Text", xmpText, xmpExternal, N_("A 1-byte specification of the version of this media header") },
{ "MediaLangCode", N_("Media Language Code"), "Integer", xmpText, xmpExternal, N_("A 16-bit integer that specifies the language code for this media.") },
{ "MediaModifyDate", N_("Media Track Modify Date"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates (in seconds since midnight, January 1, 1904) when the media header was last modified.") },
{ "MediaTimeScale", N_("Media Time Scale"), "Integer", xmpText, xmpExternal, N_("A time value that indicates the time scale for this media—that is, the number of time units that pass per second in its time coordinate system." ) },
{ "Medium", N_("Medium"), "Text", xmpSeq, xmpExternal, N_("Medium.") },
{ "Metadata", N_("Metadata"), "Text", xmpSeq, xmpExternal, N_("An array of Unknown / Unregistered Metadata Tags and their values.") },
{ "MetadataLibrary", N_("Metadata Library"), "Text", xmpSeq, xmpExternal, N_("An array of Unregistered Metadata Library Tags and their values.") },
{ "MeteringMode", N_("Metering Mode"), "Closed Choice of Integer", xmpText, xmpInternal, N_("Metering mode.") },
{ "MicroSecPerFrame", N_("Micro Seconds Per Frame"), "Integer", xmpText, xmpExternal, N_("Number of micro seconds per frame, or frame rate") },
{ "MimeType", N_("Mime Type"), "Text", xmpText, xmpExternal, N_("Tells about the video format") },
{ "MinorVersion", N_("QTime Minor FileType Version"), "Text", xmpText, xmpExternal, N_("QuickTime Minor File Type Version") },
{ "Model", N_("Equipment Model"), "Text", xmpText, xmpExternal, N_("Model name or number of equipment.") },
{ "ModificationDate", N_("Modification Date-Time"), "Text", xmpText, xmpExternal, N_("Contains the modification date of the video") },
{ "MovieHeaderVersion", N_("Movie Header Version"), "Integer", xmpText, xmpExternal, N_("Movie Header Version") },
{ "MusicBy", N_("Music By"), "Text", xmpText, xmpExternal, N_("Music By, i.e. name of person or organization.") },
{ "MuxingApp", N_("Muxing App"), "Text", xmpText, xmpExternal, N_("Contains the name of the library that has been used to create the file (like ”libmatroska 0.7.0“)") },
{ "Name", N_("Name"), "Text", xmpText, xmpExternal, N_("Name of song or the event.") },
{ "NextTrackID", N_("Next Track ID"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates a value to use for the track ID number of the next track added to this movie. Note that 0 is not a valid track ID value.") },
{ "NumOfColours", N_("Number Of Colours"), "Integer/Text", xmpText, xmpExternal, N_("Total number of colours used") },
{ "NumOfImpColours", N_("Number Of Important Colours"), "Integer/Text", xmpText, xmpExternal, N_("Number Of Important Colours, a property inherited from BitMap format") },
{ "NumOfParts", N_("Number Of Parts"), "Integer", xmpText, xmpExternal, N_("Total number of parts in the video.") },
{ "OpColor", N_("Operation Colours"), "Integer/Text", xmpText, xmpExternal, N_("Three 16-bit values that specify the red, green, and blue colors for the transfer mode operation indicated in the graphics mode field.") },
{ "Organization", N_("Organization"), "Text", xmpText, xmpExternal, N_("Name of organization associated with the video.") },
{ "Orientation", N_("Orientation"), "Closed Choice of Integer", xmpText, xmpInternal, N_("Video Orientation:"
"1 = Horizontal (normal) "
"2 = Mirror horizontal "
"3 = Rotate 180 "
"4 = Mirror vertical "
"5 = Mirror horizontal and rotate 270 CW "
"6 = Rotate 90 CW "
"7 = Mirror horizontal and rotate 90 CW "
"8 = Rotate 270 CW") },
{ "Part", N_("Part"), "Text", xmpText, xmpExternal, N_("Part.") },
{ "Performers", N_("Performers"), "Text", xmpText, xmpExternal, N_("Performers involved in the video.") },
{ "PerformerKeywords", N_("Performer Keywords"), "Text", xmpText, xmpExternal, N_("Performer Keywords.") },
{ "PerformerURL", N_("Performer URL"), "Text", xmpText, xmpExternal, N_("Performer's dedicated URL.") },
{ "PictureControlData", N_("Picture Control Data"), "Text", xmpText, xmpExternal, N_("Picture Control Data.") },
{ "PictureControlVersion", N_("Picture Control Version"), "Text", xmpText, xmpExternal, N_("Picture Control Data Version.") },
{ "PictureControlName", N_("Picture Control Name"), "Text", xmpText, xmpExternal, N_("Picture Control Name.") },
{ "PictureControlBase", N_("Picture Control Base"), "Text", xmpText, xmpExternal, N_("Picture Control Data Base.") },
{ "PictureControlAdjust", N_("Picture Control Adjust"), "Text", xmpText, xmpExternal, N_("Picture Control Adjust Information.") },
{ "PictureControlQuickAdjust",N_("Picture Control Quick Adjust"), "Text", xmpText, xmpExternal, N_("Picture Control Quick Adjustment Settings.") },
{ "PlaySelection", N_("Play Selection"), "Text", xmpText, xmpExternal, N_("Play Selection.") },
{ "PlayMode", N_("PlayMode"), "Text", xmpText, xmpExternal, N_("Information about the Play Mode.") },
{ "Producer", N_("Producer"), "Text", xmpText, xmpExternal, N_("Producer involved with the video.") },
{ "ProducerKeywords", N_("Producer Keywords"), "Text", xmpText, xmpExternal, N_("Information about the Producer Keywords.") },
{ "ProductionDesigner", N_("Production Designer"), "Text", xmpText, xmpExternal, N_("Information about the Production Designer.") },
{ "ProductionStudio", N_("Production Studio"), "Text", xmpText, xmpExternal, N_("Information about the Production Studio.") },
{ "Product", N_("Product"), "Text", xmpText, xmpExternal, N_("Product.") },
{ "PhysicalEquivalent", N_("Chapter Physical Equivalent"), "Text", xmpText, xmpExternal, N_("Contains the information of External media.") },
{ "PixelDepth", N_("Video Pixel Depth"), "closed Choice of Text", xmpText, xmpExternal, N_("The size in bits of each color component of a pixel. Standard Windows 32-bit "
"pixels have 8 bits per component. One of: 8Int, 16Int, 32Int, 32Float.") },
{ "PixelPerMeterX", N_("Pixels Per Meter X"), "Integer", xmpText, xmpExternal, N_("Pixels Per Meter X, a property inherited from BitMap format") },
{ "PixelPerMeterY", N_("Pixels Per Meter Y"), "Integer", xmpText, xmpExternal, N_("Pixels Per Meter Y, a property inherited from BitMap format") },
{ "Planes", N_("Planes"), "Integer", xmpText, xmpExternal, N_("The number of Image Planes in the video") },
{ "PosterTime", N_("Poster Time"), "Integer", xmpText, xmpExternal, N_("The time value of the time of the movie poster.") },
{ "PreferredRate", N_("Preferred Rate"), "Rational", xmpText, xmpExternal, N_("A 32-bit fixed-point number that specifies the rate at which to play this movie. A value of 1.0 indicates normal rate.") },
{ "PreferredVolume", N_("Preferred Volume"), "Rational", xmpText, xmpExternal, N_("A 16-bit fixed-point number that specifies how loud to play this movies sound. A value of 1.0 indicates full volume.") },
{ "Preroll", N_("Preroll"), "Integer", xmpText, xmpExternal, N_("Specifies the amount of time to buffer data before starting to play the file, in millisecond units. If this value is nonzero,"
"the Play Duration field and all of the payload Presentation Time fields have been offset by this amount. Therefore, player software "
"must subtract the value in the preroll field from the play duration and presentation times to calculate their actual values.") },
{ "PreviewDuration", N_("Preview Duration"), "Integer", xmpText, xmpExternal, N_("The duration of the movie preview in movie time scale units") },
{ "PreviewTime", N_("Preview Time"), "Integer", xmpText, xmpExternal, N_("The time value in the movie at which the preview begins.") },
{ "ProducedBy", N_("Produced By"), "Text", xmpText, xmpExternal, N_("Produced By, i.e. name of person or organization.") },
{ "ProjectRef", N_("Project Reference"), "ProjectLink", xmpText, xmpExternal, N_("A reference to the project that created this file.") },
{ "Rate", N_("Rate"), "Integer", xmpText, xmpExternal, N_("Rate.") },
{ "Rated", N_("Rated"), "Text", xmpText, xmpExternal, N_("The age circle required for viewing the video.") },
{ "Rating", N_("Rating"), "Text", xmpText, xmpExternal, N_("Rating, eg. 7 or 8 (generally out of 10).") },
{ "RecordLabelName", N_("Record Label Name"), "Text", xmpText, xmpExternal, N_("Record Label Name, or the name of the organization recording the video.") },
{ "RecordLabelURL", N_("Record Label URL"), "Text", xmpText, xmpExternal, N_("Record Label URL.") },
{ "RecordingCopyright", N_("Recording Copyright"), "Text", xmpText, xmpExternal, N_("Recording Copyright.") },
{ "Requirements", N_("Requirements"), "Text", xmpText, xmpExternal, N_("Information about the Requirements.") },
{ "ResolutionUnit", N_("Resolution Unit"), "Closed Choice of Integer", xmpText, xmpInternal, N_("Unit used for XResolution and YResolution. Value is one of: 2 = inches; 3 = centimeters.") },
{ "RippedBy", N_("Ripped By"), "Text", xmpText, xmpExternal, N_("Ripped By, i.e. name of person or organization.") },
{ "Saturation", N_("Saturation"), "Closed Choice of Integer", xmpText, xmpInternal, N_("Indicates the direction of saturation processing applied by the camera.") },
{ "SecondaryGenre", N_("Secondary Genre"), "Text", xmpText, xmpExternal, N_("The name of the secondary genre..") },
{ "SelectionTime", N_("Selection Time"), "Integer", xmpText, xmpExternal, N_("The time value for the start time of the current selection.") },
{ "SelectionDuration", N_("Selection Duration"), "Integer", xmpText, xmpExternal, N_("The duration of the current selection in movie time scale units.") },
{ "SendDuration", N_("Send Duration"), "Integer", xmpText, xmpExternal, N_("Specifies the time needed to send the file in 100-nanosecond units. This value should "
"include the duration of the last packet in the content.") },
{ "Sharpness", N_("Sharpness"), "Integer", xmpText, xmpExternal, N_("\"Sharpness\" setting. Range 0 to +100.") },
{ "Software", N_("Software"), "Text", xmpText, xmpExternal, N_("Software used to generate / create Video data.") },
{ "SoftwareVersion", N_("Software Version"), "Text", xmpText, xmpExternal, N_("The Version of the software used.") },
{ "SongWriter", N_("Song Writer"), "Text", xmpText, xmpExternal, N_("The name of the song writer.") },
{ "SongWriterKeywords", N_("Song Writer Keywords"), "Text", xmpText, xmpExternal, N_("Song Writer Keywords.") },
{ "Source", N_("Source"), "Text", xmpText, xmpExternal, N_("Source.") },
{ "SourceCredits", N_("Source Credits"), "Text", xmpText, xmpExternal, N_("Source Credits.") },
{ "SourceForm", N_("Source Form"), "Text", xmpText, xmpExternal, N_("Source Form.") },
{ "SourceImageHeight", N_("Source Image Height"), "Integer", xmpText, xmpExternal, N_("Video height in pixels") },
{ "SourceImageWidth", N_("Source Image Width"), "Integer", xmpText, xmpExternal, N_("Video width in pixels") },
{ "Starring", N_("Starring"), "Text", xmpText, xmpExternal, N_("Starring, name of famous people appearing in the video.") },
{ "StartTimecode", N_("Start Timecode"), "Integer", xmpText, xmpExternal, N_("Start Timecode") },
{ "Statistics", N_("Statistics"), "Text", xmpText, xmpExternal, N_("Statistics.") },
{ "StreamCount", N_("Stream Count"), "Integer", xmpText, xmpExternal, N_("Total Number Of Streams") },
{ "StreamName", N_("Stream Name"), "Text", xmpText, xmpExternal, N_("Describes the Stream Name. Eg - FUJIFILM AVI STREAM 0100") },
{ "StreamQuality", N_("Stream Quality"), "Integer", xmpText, xmpExternal, N_("Generral Stream Quality") },
{ "StreamSampleRate", N_("Stream Sample Rate"), "Rational", xmpText, xmpExternal, N_("Stream Sample Rate") },
{ "StreamSampleCount", N_("Stream Sample Count"), "Integer", xmpText, xmpExternal, N_("Stream Sample Count") },
{ "StreamSampleSize", N_("Stream Sample Size"), "Integer", xmpText, xmpExternal, N_("General Stream Sample Size") },
{ "StreamType", N_("Stream Type"), "Text", xmpText, xmpExternal, N_("Describes the Stream Type. Eg - Video, Audio or Subtitles") },
{ "SubTCodec", N_("Subtitles Codec"), "Text", xmpText, xmpExternal, N_("Subtitles stream codec, for general purpose") },
{ "SubTCodecDecodeAll", N_("Subtitle Codec Decode Info"), "Text", xmpText, xmpExternal, N_("Contains information the Subtitles codec decode all, i.e. Enabled/Disabled") },
{ "SubTCodecInfo", N_("Subtitles Codec Information"), "Text", xmpText, xmpExternal, N_("Contains additional information about subtitles.") },
{ "SubTCodecDownloadUrl", N_("Subtitle Codec Download URL"), "Text", xmpText, xmpExternal, N_("Video Subtitle Codec Download URL.") },
{ "SubTCodecSettings", N_("Subtitle Codec Settings"), "Text", xmpText, xmpExternal, N_("Contains settings the codec needs before decoding can be started.") },
{ "SubTDefaultOn", N_("Subtitle Track Default On"), "Text", xmpText, xmpExternal, N_("Subtitles Track Default On , i.e. Enabled/Disabled") },
{ "SubTEnabled", N_("Subtitle Track Enabled"), "Text", xmpText, xmpExternal, N_("Status of Subtitles Track, i.e. Enabled/Disabled") },
{ "Subtitle", N_("Subtitle"), "Text", xmpText, xmpExternal, N_("Subtitle of the video.") },
{ "SubtitleKeywords", N_("Subtitle Keywords"), "Text", xmpText, xmpExternal, N_("Subtitle Keywords.") },
{ "SubTLang", N_("Subtitles Language"), "Text", xmpText, xmpExternal, N_("The Language in which the subtitles is recorded in.") },
{ "SubTTrackForced", N_("Subtitle Track Forced"), "Text", xmpText, xmpExternal, N_("Subtitles Track Forced , i.e. Enabled/Disabled") },
{ "SubTTrackLacing", N_("Subtitle Track Lacing"), "Text", xmpText, xmpExternal, N_("Subtitles Track Lacing , i.e. Enabled/Disabled") },
{ "Subject", N_("Subject"), "Text", xmpText, xmpExternal, N_("Subject. ") },
{ "TapeName", N_("Tape Name"), "Text", xmpText, xmpExternal, N_("TapeName.") },
{ "TagDefault", N_("Tag Default Setting"), "Text", xmpText, xmpExternal, N_("If Tag is Default enabled, this value is Yes, else No ") },
{ "TagLanguage", N_("Tag Language"), "Text", xmpText, xmpExternal, N_("Language that has been used to define tags") },
{ "TagName", N_("Tag Name"), "Text", xmpText, xmpExternal, N_("Tags could be used to define several titles for a segment.") },
{ "TagString", N_("Tag String"), "Text", xmpText, xmpExternal, N_("Information contained in a Tags") },
{ "TargetType", N_("Target Type"), "Text", xmpText, xmpExternal, N_("A string describing the logical level of the object the Tag is refering to.") },
{ "Technician", N_("Technician"), "Text", xmpText, xmpExternal, N_("Technician, in most cases name of person.") },
{ "ThumbnailHeight", N_("Thumbnail Height"), "Integer", xmpText, xmpExternal, N_("Preview Image Thumbnail Height.") },
{ "ThumbnailLength", N_("Thumbnail Length"), "Integer", xmpText, xmpExternal, N_("Preview Image Thumbnail Length.") },
{ "ThumbnailWidth", N_("Thumbnail Width"), "Integer", xmpText, xmpExternal, N_("Preview Image Thumbnail Width.") },
{ "TimecodeScale", N_("Timecode Scale"), "Rational", xmpText, xmpExternal, N_("Multiplying factor which is helpful in calculation of a particular timecode") },
{ "TimeOffset", N_("Time Offset"), "Integer", xmpText, xmpExternal, N_("Specifies the presentation time offset of the stream in 100-nanosecond units. This value shall be equal to the send time of the first interleaved packet in the data section.") },
{ "TimeScale", N_("Time Scale"), "Integer", xmpText, xmpExternal, N_("A time value that indicates the time scale for this movie—that is, the number of time units that"
"pass per second in its time coordinate system. A time coordinate system that measures time"
"in sixtieths of a second, for example, has a time scale of 60.") },
{ "Title", N_("Title"), "Text", xmpText, xmpExternal, N_("Contains a general name of the SEGMENT, like 'Lord of the Rings - The Two Towers', however, Tags could be used to define several titles for a segment.") },
{ "ToningEffect", N_("Toning Effect"), "Text", xmpText, xmpExternal, N_("Toning Effect Settings Applied.") },
{ "TotalFrameCount", N_("Total Frame Count"), "Integer", xmpText, xmpExternal, N_("Total number of frames in a video") },
{ "TotalStream", N_("Number Of Streams"), "Integer", xmpText, xmpExternal, N_("Total number of streams present in a video. Eg - Video, Audio or Subtitles") },
{ "Track", N_("Track"), "Text", xmpText, xmpExternal, N_("Information about the Track.") },
{ "TrackCreateDate", N_("Video Track Create Date"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates (in seconds since midnight, January 1, 1904) when the track header was created.") },
{ "TrackDuration", N_("Video Track Duration"), "Integer", xmpText, xmpExternal, N_("A time value that indicates the duration of this track (in the movies time coordinate system).") },
{ "TrackForced", N_("Video Track Forced"), "Text", xmpText, xmpExternal, N_("Video Track Forced , i.e. Enabled/Disabled") },
{ "TrackID", N_("Track ID"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that uniquely identifies the track. The value 0 cannot be used.") },
{ "TrackHeaderVersion", N_("Track Header Version"), "Text", xmpText, xmpExternal, N_("A 1-byte specification of the version of this track header") },
{ "TrackLacing", N_("Video Track Lacing"), "Text", xmpText, xmpExternal, N_("Video Track Lacing , i.e. Enabled/Disabled") },
{ "TrackLang", N_("Track Language"), "Text", xmpText, xmpExternal, N_("The Language in which a particular stream is recorded in.") },
{ "TrackLayer", N_("Video Track Layer"), "Integer", xmpText, xmpExternal, N_("A 16-bit integer that indicates this tracks spatial priority in its movie. The QuickTime Movie"
"Toolbox uses this value to determine how tracks overlay one another. Tracks with lower layer"
"values are displayed in front of tracks with higher layer values.") },
{ "TrackModifyDate", N_("Video Track Modify Date"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates (in seconds since midnight, January 1, 1904) when the track header was last modified.") },
{ "TrackName", N_("Track Name"), "Text", xmpText, xmpExternal, N_("Track Name could be used to define titles for a segment.") },
{ "TrackNumber", N_("Track Number"), "Integer", xmpText, xmpExternal, N_("Track Number.") },
{ "TrackVolume", N_("Track Volume"), "Rational", xmpText, xmpExternal, N_("A 16-bit fixed-point number that specifies how loud to play this tracks sound. A value of 1.0 indicates full volume.") },
{ "TranslateCodec", N_("Chapter Translate Codec"), "Text", xmpText, xmpExternal, N_("Chapter Translate Codec information. Usually used in Matroska filr type.") },
{ "UnknownInfo", N_("Unknown Information"), "Text", xmpText, xmpExternal, N_("Unknown / Unregistered Metadata Tags and their values.") },
{ "UnknownInfo2", N_("Unknown Information"), "Text", xmpText, xmpExternal, N_("Unknown / Unregistered Metadata Tags and their values.") },
{ "URL", N_("Video URL"), "Text", xmpText, xmpExternal, N_("A C string that specifies a URL. There may be additional data after the C string.") },
{ "URN", N_("Video URN"), "Text", xmpText, xmpExternal, N_("A C string that specifies a URN. There may be additional data after the C string.") },
{ "VariProgram", N_("Vari Program"), "Text", xmpText, xmpExternal, N_("Software settings used to generate / create Video data.") },
{ "VegasVersionMajor", N_("Vegas Version Major"), "Text", xmpText, xmpExternal, N_("Vegas Version Major.") },
{ "VegasVersionMinor", N_("Vegas Version Minor"), "Text", xmpText, xmpExternal, N_("Vegas Version Minor.") },
{ "Vendor", N_("Vendor"), "Text", xmpText, xmpExternal, N_("The developer of the compressor that generated the compressed data.") },
{ "VendorID", N_("Vendor ID"), "Text", xmpText, xmpExternal, N_("A 32-bit integer that specifies the developer of the compressor that generated the compressed data. Often this field contains 'appl' to indicate Apple Computer, Inc.") },
{ "VideoQuality", N_("Video Quality"), "Integer", xmpText, xmpExternal, N_("Video Stream Quality") },
{ "VideoSampleSize", N_("Video Sample Size"), "Integer", xmpText, xmpExternal, N_("Video Stream Sample Size") },
{ "VideoScanType", N_("Video Scan Type"), "Text", xmpText, xmpExternal, N_("Video Scan Type, it can be Progressive or Interlaced") },
{ "WatermarkURL", N_("Watermark URL"), "Text", xmpText, xmpExternal, N_("A C string that specifies a Watermark URL.") },
{ "WhiteBalance", N_("White Balance"), "Closed Choice Text", xmpText, xmpExternal, N_("\"White Balance\" setting. One of: As Shot, Auto, Daylight, Cloudy, Shade, Tungsten, "
"Fluorescent, Flash, Custom") },
{ "WhiteBalanceFineTune", N_("White Balance Fine Tune"), "Integer", xmpText, xmpExternal, N_("White Balance Fine Tune.") },
{ "Width", N_("Video Width"), "Integer", xmpText, xmpExternal, N_("Video width in pixels") },
{ "WindowLocation", N_("Window Location"), "Text", xmpText, xmpExternal, N_("Information about the Window Location.") },
{ "WorldTime", N_("WorldTime"), "Integer", xmpText, xmpExternal, N_("World Time") },
{ "WrittenBy", N_("Written By"), "Text", xmpText, xmpExternal, N_("Written By, i.e. name of person or organization.") },
{ "WritingApp", N_("Writing App"), "Text", xmpText, xmpExternal, N_("Contains the name of the application used to create the file (like ”mkvmerge 0.8.1“)") },
{ "XResolution", N_("X Resolution"), "Rational", xmpText, xmpInternal, N_("Horizontal resolution in pixels per unit.") },
{ "Year", N_("Year"), "Integer", xmpText, xmpExternal, N_("Year in which the video was made.") },
{ "YResolution", N_("Y Resolution"), "Rational", xmpText, xmpInternal, N_("Vertical resolution in pixels per unit.") },
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPropertyInfo xmpAudioInfo[] = {
{ "AvgBytePerSec", N_("Average Bytes Per Second"), "Integer", xmpText, xmpExternal, N_("Average Bytes Per Second found in audio stream") },
{ "Balance", N_("Balance"), "Integer", xmpText, xmpExternal, N_("Indicates the left-right balance of the audio") },
{ "BitsPerSample", N_("Bits Per Sample/ Bit Rate"), "Integer", xmpText, xmpExternal, N_("Bits per test sample") },
{ "ChannelType", N_("Audio Channel Type"), "Integers", xmpText, xmpExternal, N_("The audio channel type. One of: Mono, Stereo, 5.1, 7.1.") },
{ "Codec", N_("Audio Codec"), "Text", xmpText, xmpExternal, N_("Codec used for Audio Encoding/Decoding") },
{ "CodecDecodeAll", N_("Audio Codec Decode Info"), "Text", xmpText, xmpExternal, N_("Contains information the audio codec decode all, i.e. Enabled/Disabled") },
{ "CodecDescription", N_("Audio Codec Description"), "Text", xmpText, xmpExternal, N_("Contains description the codec.") },
{ "CodecDownloadUrl", N_("Audio Codec Download URL"), "Text", xmpText, xmpExternal, N_("Audio Codec Download URL.") },
{ "CodecInfo", N_("Audio Codec Information"), "Text", xmpText, xmpExternal, N_("Contains information the codec needs before decoding can be started. An example is the Vorbis initialization packets for Vorbis audio.") },
{ "CodecSettings", N_("Audio Codec Settings"), "Text", xmpText, xmpExternal, N_("Contains settings the codec needs before decoding can be started.") },
{ "Compressor", N_("Audio Compressor"), "Text", xmpText, xmpExternal, N_("The audio compression used. For example, MP3.") },
{ "DefaultDuration", N_("MicroSec audio chunk lasts"), "Text", xmpText, xmpExternal, N_("The number of micro seconds an audio chunk plays.") },
{ "DefaultStream", N_("Default Stream"), "Text", xmpText, xmpExternal, N_("Audio Stream that would be played by default.") },
{ "DefaultOn", N_("Audio Track Default On"), "Text", xmpText, xmpExternal, N_("Audio Track Default On , i.e. Enabled/Disabled") },
{ "Enabled", N_("Audio Track Enabled"), "Text", xmpText, xmpExternal, N_("Status of Audio Track, i.e. Enabled/Disabled") },
{ "Format", N_("Audio Format"), "Text", xmpText, xmpExternal, N_("A four-character code that identifies the format of the audio.") },
{ "HandlerClass", N_("Handler Class"), "Text", xmpText, xmpExternal, N_("A four-character code that identifies the type of the handler. Only two values are valid for this field: 'mhlr' for media handlers and 'dhlr' for data handlers.") },
{ "HandlerDescription", N_("Handler Description"), "Text", xmpText, xmpExternal, N_("A (counted) string that specifies the name of the component—that is, the media handler used when this media was created..") },
{ "HandlerType", N_("Handler Type"), "Text", xmpText, xmpExternal, N_("A four-character code that identifies the type of the media handler or data handler.") },
{ "HandlerVendorID", N_("Handler Vendor ID"), "Text", xmpText, xmpExternal, N_("Component manufacturer.") },
{ "MediaCreateDate", N_("Media Track Create Date"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates (in seconds since midnight, January 1, 1904) when the media header was created.") },
{ "MediaDuration", N_("Media Track Duration"), "Integer", xmpText, xmpExternal, N_("A time value that indicates the duration of this media (in the movies time coordinate system).") },
{ "MediaHeaderVersion", N_("Media Header Version"), "Text", xmpText, xmpExternal, N_("A 1-byte specification of the version of this media header") },
{ "MediaLangCode", N_("Media Language Code"), "Integer", xmpText, xmpExternal, N_("A 16-bit integer that specifies the language code for this media.") },
{ "MediaModifyDate", N_("Media Track Modify Date"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates (in seconds since midnight, January 1, 1904) when the media header was last modified.") },
{ "MediaTimeScale", N_("Media Time Scale"), "Integer", xmpText, xmpExternal, N_("A time value that indicates the time scale for this media—that is, the number of time units that pass per second in its time coordinate system." ) },
{ "OutputSampleRate", N_("Output Audio Sample Rate"), "Integer", xmpText, xmpExternal, N_("The ouput audio sample rate. Can be any value, but commonly 32000, 41100, or 48000.") },
{ "SampleCount", N_("Audio Sample Count"), "Integer", xmpText, xmpExternal, N_("Sample taken for Analyzing Audio Stream") },
{ "SampleRate", N_("Audio Sample Rate"), "Integer", xmpText, xmpExternal, N_("The audio sample rate. Can be any value, but commonly 32000, 41100, or 48000.") },
{ "SampleType", N_("Audio Sample Type"), "closed Choice of Text", xmpText, xmpExternal, N_("The audio sample type. One of: 8Int, 16Int, 32Int, 32Float.") },
{ "SchemeTitle", N_("Sound Scheme Title"), "Text", xmpText, xmpExternal, N_("Sound Scheme Title.") },
{ "TimeOffset", N_("Time Offset"), "Integer", xmpText, xmpExternal, N_("Specifies the presentation time offset of the stream in 100-nanosecond units. This value shall be equal to the send time of the first interleaved packet in the data section.") },
{ "TrackCreateDate", N_("Audio Track Create Date"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates (in seconds since midnight, January 1, 1904) when the track header was created.") },
{ "TrackDuration", N_("Audio Track Duration"), "Integer", xmpText, xmpExternal, N_("A time value that indicates the duration of this track (in the movies time coordinate system).") },
{ "TrackForced", N_("Audio Track Forced"), "Text", xmpText, xmpExternal, N_("Audio Track Forced , i.e. Enabled/Disabled") },
{ "TrackID", N_("Track ID"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that uniquely identifies the track. The value 0 cannot be used.") },
{ "TrackHeaderVersion", N_("Track Header Version"), "Text", xmpText, xmpExternal, N_("A 1-byte specification of the version of this track header") },
{ "TrackLacing", N_("Audio Track Lacing"), "Text", xmpText, xmpExternal, N_("Audio Track Lacing , i.e. Enabled/Disabled") },
{ "TrackLang", N_("Track Language"), "Text", xmpText, xmpExternal, N_("The Language in which a particular stream is recorded in.") },
{ "TrackLayer", N_("Audio Track Layer"), "Integer", xmpText, xmpExternal, N_("A 16-bit integer that indicates this tracks spatial priority in its movie. The QuickTime Movie"
"Toolbox uses this value to determine how tracks overlay one another. Tracks with lower layer"
"values are displayed in front of tracks with higher layer values.") },
{ "TrackModifyDate", N_("Audio Track Modify Date"), "Integer", xmpText, xmpExternal, N_("A 32-bit integer that indicates (in seconds since midnight, January 1, 1904) when the track header was last modified.") },
{ "TrackVolume", N_("Track Volume"), "Rational", xmpText, xmpExternal, N_("A 16-bit fixed-point number that specifies how loud to play this tracks sound. A value of 1.0 indicates full volume.") },
{ "URL", N_("Audio URL"), "Text", xmpText, xmpExternal, N_("A C string that specifies a URL. There may be additional data after the C string.") },
{ "URN", N_("Audio URN"), "Text", xmpText, xmpExternal, N_("A C string that specifies a URN. There may be additional data after the C string.") },
{ "VendorID", N_("Vendor ID"), "Text", xmpText, xmpExternal, N_("A 32-bit integer that specifies the developer of the compressor that generated the compressed data. Often this field contains 'appl' to indicate Apple Computer, Inc.") },
{ 0, 0, 0, invalidTypeId, xmpInternal, 0 }
};
extern const XmpPrintInfo xmpPrintInfo[] = {
{"Xmp.crs.CropUnits", EXV_PRINT_TAG(crsCropUnits) },
{"Xmp.exif.ApertureValue", print0x9202 },

File diff suppressed because it is too large Load Diff

@ -0,0 +1,229 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2012 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 quicktimevideo.hpp
@brief An Image subclass to support Quick Time video files
@version $Rev$
@author Abhinav Badola for GSoC 2012
<a href="mailto:mail.abu.to@gmail.com">mail.abu.to@gmail.com</a>
@date 28-Jun-12, AB: created
*/
#ifndef QUICKTIMEVIDEO_HPP
#define QUICKTIMEVIDEO_HPP
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "image.hpp"
#include "tags_int.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// 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
{
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::AutoPtr 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();
/*!
@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);
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);
/*!
@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);
/*!
@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);
/*!
@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);
/*!
@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);
/*!
@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);
/*!
@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(unsigned long 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(unsigned long 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);
/*!
@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(unsigned long 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.
*/
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);
} // namespace Exiv2
#endif // QUICKTIMEVIDEO_HPP

File diff suppressed because it is too large Load Diff

@ -0,0 +1,215 @@
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2012 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 riffvideo.hpp
@brief An Image subclass to support RIFF video files
@version $Rev$
@author Abhinav Badola for GSoC 2012
<a href="mailto:mail.abu.to@gmail.com">mail.abu.to@gmail.com</a>
@date 18-Jun-12, AB: created
*/
#ifndef RIFFVIDEO_HPP
#define RIFFVIDEO_HPP
// *****************************************************************************
// included header files
#include "exif.hpp"
#include "image.hpp"
#include "tags_int.hpp"
// *****************************************************************************
// namespace extensions
namespace Exiv2 {
// *****************************************************************************
// class definitions
// Add RIFF to the supported image formats
namespace ImageType {
const int riff = 20; //!< Treating riff as an image type>
}
/*!
@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.
*/
RiffVideo(BasicIo::AutoPtr io);
//@}
//! @name Manipulators
//@{
void readMetadata();
void writeMetadata();
//@}
//! @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);
/*!
@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);
/*!
@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);
/*!
@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);
/*!
@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);
/*!
@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);
/*!
@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);
/*!
@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(long 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.
*/
double returnSampleRate(Exiv2::DataBuf& buf, long 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);
/*!
@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);
private:
//! @name NOT Implemented
//@{
//! Copy constructor
RiffVideo(const RiffVideo& rhs);
//! Assignment operator
RiffVideo& operator=(const RiffVideo& rhs);
//@}
private:
//! 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::AutoPtr newRiffInstance(BasicIo::AutoPtr io, bool create);
//! Check if the file iIo is a Riff Video.
EXIV2API bool isRiffType(BasicIo& iIo, bool advance);
} // namespace Exiv2
#endif // RIFFVIDEO_HPP

@ -186,7 +186,7 @@ namespace Exiv2 {
const char* label_; //!< Translation of the tag value
//! Comparison operator for use with the find template
bool operator==(long key) const { return val_ == key; }
bool operator==(long key) const { return val_ == key; }
}; // struct TagDetails
/*!

@ -73,7 +73,8 @@ TESTS = addmoddel.sh \
write-test.sh \
write2-test.sh \
xmpparser-test.sh \
conversions.sh
conversions.sh \
video-test.sh
test:
./mingfixup.sh

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,62 @@
#! /bin/sh
# Test driver for video files
#
# video-asf.wmv http://www.educationalquestions.com/video/DLP_PART_2_768k.wmv
# video-avi.avi http://redmine.yorba.org/attachments/631/Nikon_Coolpix_S3000.AVI
# video-matroska.mkv http://www.bunkus.org/videotools/mkvtoolnix/samples/vsshort-vorbis-subs.mkv
# video-quicktime.mp4 http://dev.exiv2.org/attachments/362/20100709_002.mp4
# ----------------------------------------------------------------------
# Setup
export LC_ALL=C
cd tmp/
if [ -z "$EXIV2_BINDIR" ] ; then
bin="$VALGRIND ../../src"
samples="$VALGRIND ../../samples"
else
bin="$VALGRIND $EXIV2_BINDIR"
samples="$VALGRIND $EXIV2_BINDIR"
fi
diffargs="--strip-trailing-cr"
if ! diff -q $diffargs /dev/null /dev/null 2>/dev/null ; then
diffargs=""
fi
# ----------------------------------------------------------------------
# Tests
(
for file in ../data/video/video-*; do
video="`basename "$file"`"
if [ $video = "video-test.out" ] ; then
continue
fi
printf "." >&3
echo
echo "-----> $video <-----"
cp "../data/video/$video" ./
echo
echo "Command: exiv2 -u -pa $video"
$bin/exiv2 -u -pa "$video"
exitcode="$?"
echo "Exit code: $exitcode"
if [ "$exitcode" -ne 0 -a "$exitcode" -ne 253 ] ; then
continue
fi
done
) 3>&1 > "video-test.out" 2>&1
echo "."
# ----------------------------------------------------------------------
# Result
if ! diff -q $diffargs "../data/video/video-test.out" "video-test.out" ; then
diff -u -a $diffargs "../data/video/video-test.out" "video-test.out"
exit 1
fi
echo "All testcases passed."

@ -9,6 +9,12 @@
include(../CMake_msvc.txt)
msvc_runtime_configure(${EXIV2_ENABLE_SHARED})
FOREACH(_currentfile ${XMPSRC})
IF(NOT MSVC)
SET_SOURCE_FILES_PROPERTIES(${_currentfile} PROPERTIES COMPILE_FLAGS "-fPIC")
ENDIF(NOT MSVC)
ENDFOREACH(_currentfile ${XMPSRC})
IF( EXIV2_ENABLE_XMP AND EXIV2_ENABLE_LIBXMP )
ADD_LIBRARY( xmp STATIC ${XMPSRC} )
GET_TARGET_PROPERTY( XMPLIB xmp LOCATION )

Loading…
Cancel
Save