Work on Issue 846 (porting video code to MSVC). See http://dev.exiv2.org/issues/846 (item #8) for more discussion.

This commit is contained in:
Robin Mills 2012-09-18 07:17:59 +00:00
parent a75de0f76a
commit 6ca49acd13
7 changed files with 132 additions and 52 deletions

View File

@ -281,9 +281,9 @@ namespace Exiv2 {
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));
for(int i = 0; i < 8; ++i){
temp = temp + static_cast<uint64_t>(buf.pData_[i]*(pow(static_cast<float>(256), i)));
}
return temp;
}
@ -334,7 +334,7 @@ namespace Exiv2 {
void AsfVideo::decodeBlock()
{
const long bufMinSize = 8;
const long bufMinSize = 9;
DataBuf buf(bufMinSize);
unsigned long size = 0;
buf.pData_[8] = '\0' ;
@ -349,14 +349,14 @@ namespace Exiv2 {
return;
}
char GUID[33] = "";
char GUID[37] = ""; //the getGUID function write the GUID[36],
getGUID(guidBuf, GUID);
tv = find( GUIDReferenceTags, GUID);
std::memset(buf.pData_, 0x0, buf.size_);
io_->read(buf.pData_, 8);
size = getUint64_t(buf);
size = static_cast<long>(getUint64_t(buf));
if(tv)
tagDecoder(tv,size-24);
@ -487,7 +487,7 @@ namespace Exiv2 {
buf.pData_[8] = '\0' ;
byte guidBuf[16]; int stream = 0;
io_->read(guidBuf, 16);
char streamType[33] = "";
char streamType[37] = "";
Exiv2::RiffVideo *test = NULL;
getGUID(guidBuf, streamType);
@ -599,7 +599,7 @@ namespace Exiv2 {
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] = "";
byte guidBuf[16]; char fileID[37] = "";
while(recordCount--) {
std::memset(buf.pData_, 0x0, buf.size_);
@ -670,12 +670,12 @@ namespace Exiv2 {
void AsfVideo::fileProperties()
{
DataBuf buf(8);
DataBuf buf(9);
buf.pData_[8] = '\0' ;
byte guidBuf[16];
io_->read(guidBuf, 16);
char fileID[33] = ""; int count = 7;
char fileID[37] = ""; int count = 7;
getGUID(guidBuf, fileID);
xmpData_["Xmp.video.FileID"] = fileID;

View File

@ -833,6 +833,25 @@ namespace Exiv2 {
return std::fseek(p_->fp_, offset, fileSeek);
}
int FileIo::seek( uint64_t offset, Position pos )
{
assert(p_->fp_ != 0);
int fileSeek = 0;
switch (pos) {
case BasicIo::cur: fileSeek = SEEK_CUR; break;
case BasicIo::beg: fileSeek = SEEK_SET; break;
case BasicIo::end: fileSeek = SEEK_END; break;
}
if (p_->switchMode(Impl::opSeek) != 0) return 1;
#ifdef _MSC_VER
return _fseeki64(p_->fp_, offset, fileSeek);
#else
return std::fseeko(p_->fp_, offset, fileSeek);
#endif
}
long FileIo::tell() const
{
assert(p_->fp_ != 0);
@ -1122,6 +1141,22 @@ namespace Exiv2 {
return 0;
}
int MemIo::seek( uint64_t offset, Position pos )
{
uint64_t newIdx = 0;
switch (pos) {
case BasicIo::cur: newIdx = p_->idx_ + offset; break;
case BasicIo::beg: newIdx = offset; break;
case BasicIo::end: newIdx = p_->size_ + offset; break;
}
if (newIdx < 0 || newIdx > p_->size_) return 1;
p_->idx_ = static_cast<long>(newIdx); //not very sure about this. need more test!! - note by Shawn fly2xj@gmail.com //TODO
p_->eof_ = false;
return 0;
}
byte* MemIo::mmap(bool /*isWriteable*/)
{
return p_->data_;

View File

@ -170,6 +170,23 @@ namespace Exiv2 {
Nonzero if failure;
*/
virtual int seek(long offset, Position pos) = 0;
/*!
@brief Move the current IO position.
@param offset Number of bytes to move the position relative
to the starting position specified by \em pos
@param pos Position from which the seek should start
@return 0 if successful;<BR>
Nonzero if failure;
*/
virtual int seek(uint64_t offset, Position pos) = 0;
#if defined(_MSC_VER)// && defined(_WIN64)
int seek( int offset, Position pos)
{return seek(static_cast<long>(offset),pos);}
int seek(uint32_t offset, Position pos)
{return seek(static_cast<long>(offset),pos);}
#endif
/*!
@brief Direct access to the IO data. For files, this is done by
mapping the file into the process's address space; for memory
@ -425,6 +442,15 @@ namespace Exiv2 {
Nonzero if failure;
*/
virtual int seek(long offset, Position pos);
/*!
@brief Move the current file position.
@param offset Number of bytes to move the file position
relative to the starting position specified by \em pos
@param pos Position from which the seek should start
@return 0 if successful;<BR>
Nonzero if failure;
*/
virtual int seek(uint64_t offset, Position pos);
/*!
@brief Map the file into the process's address space. The file must be
open before mmap() is called. If the mapped area is writeable,
@ -633,6 +659,15 @@ namespace Exiv2 {
Nonzero if failure;
*/
virtual int seek(long offset, Position pos);
/*!
@brief Move the current IO position.
@param offset Number of bytes to move the IO position
relative to the starting position specified by \em pos
@param pos Position from which the seek should start
@return 0 if successful;<BR>
Nonzero if failure;
*/
virtual int seek(uint64_t offset, Position pos);
/*!
@brief Allow direct access to the underlying data buffer. The buffer
is not protected against write access in any way, the argument

View File

@ -352,7 +352,7 @@ namespace Exiv2
// Move to the next box.
io_->seek(position - sizeof(box) + box.boxLength, BasicIo::beg);
io_->seek(static_cast<long>(position - sizeof(box) + box.boxLength), BasicIo::beg);
if (io_->error() || io_->eof()) throw Error(14);
}

View File

@ -457,7 +457,7 @@ namespace Exiv2 {
int64_t temp = 0;
for(int i = size-1; i >= 0; i--) {
temp = temp + buf[i]*(pow(256,size-i-1));
temp = temp + static_cast<int64_t>(buf[i]*(pow(256.0, size-i-1)));
}
std::cerr << "size = " << size << ", val = " << temp << std::hex << " (0x" << temp << std::dec << ")";
@ -534,8 +534,8 @@ namespace Exiv2 {
return;
}
bool skip = find(compositeTagsList, mt->val_);
bool ignore = find(ignoredTagsList, mt->val_);
bool skip = find(compositeTagsList, mt->val_) != 0;
bool ignore = find(ignoredTagsList, mt->val_) != 0;
io_->read(buf, 1);
sz = findBlockSize(buf[0]); // 0-8
@ -560,8 +560,9 @@ namespace Exiv2 {
DataBuf buf2(bufMinSize);
std::memset(buf2.pData_, 0x0, buf2.size_);
io_->read(buf2.pData_, size);
contentManagement(mt, buf2.pData_, size);
long s = static_cast<long>(size) ;
io_->read(buf2.pData_,s);
contentManagement(mt, buf2.pData_,s);
} // MatroskaVideo::decodeBlock
void MatroskaVideo::contentManagement(const MatroskaTags* mt, const byte* buf, long size)
@ -648,10 +649,10 @@ namespace Exiv2 {
switch (mt->val_) {
case 0x0489:
if(size <= 4) {
duration_in_ms = getFloat(buf, bigEndian) * time_code_scale * 1000;
duration_in_ms = static_cast<int64_t>(getFloat(buf, bigEndian) * time_code_scale * 1000);
}
else {
duration_in_ms = getDouble(buf, bigEndian) * time_code_scale * 1000;
duration_in_ms = static_cast<int64_t>(getDouble(buf, bigEndian) * time_code_scale * 1000);
}
break;
case 0x0461: {
@ -673,7 +674,7 @@ namespace Exiv2 {
case 0x0003:
internalMt = find(matroskaTrackType, returnValue(buf, size));
stream = internalMt->val_;
stream = static_cast<long>(internalMt->val_);
break;
case 0x3e383: case 0x383e3:
@ -681,7 +682,7 @@ namespace Exiv2 {
if (returnValue(buf, size)) {
switch (stream) {
case 1: temp = (double)1000000000/(double)returnValue(buf, size); break;
case 2: temp = returnValue(buf, size)/1000; break;
case 2: temp = static_cast<double>(returnValue(buf, size) / 1000); break;
}
if (internalMt) xmpData_[internalMt->label_] = temp;
}

View File

@ -1,4 +1,4 @@
// ***************************************************************** -*- C++ -*-
// ***************************************************************** -*- C++ -*-
/*
* Copyright (C) 2004-2012 Andreas Huggel <ahuggel@gmx.net>
*
@ -555,7 +555,11 @@ namespace Exiv2 {
int64_t returnBufValue(Exiv2::DataBuf& buf, int n = 4) {
int64_t temp = 0;
for(int i = n - 1; i >= 0; i--)
temp = temp + buf.pData_[i]*(pow(256,n-i-1));
#ifdef _MSC_VER
temp = temp + static_cast<int64_t>(buf.pData_[i]*(pow(static_cast<float>(256), n-i-1)));
#else
temp = temp + buf.pData_[i]*(pow(256,n-i-1));
#endif
return temp;
}
@ -569,7 +573,11 @@ namespace Exiv2 {
uint64_t returnUnsignedBufValue(Exiv2::DataBuf& buf, int n = 4) {
uint64_t temp = 0;
for(int i = n-1; i >= 0; i--)
temp = temp + buf.pData_[i]*(pow(256,n-i-1));
#if _MSC_VER
temp = temp + static_cast<uint64_t>(buf.pData_[i]*(pow(static_cast<float>(256), n-i-1)));
#else
temp = temp + buf.pData_[i]*(pow(256,n-i-1));
#endif
return temp;
}
@ -640,7 +648,7 @@ namespace Exiv2 {
void QuickTimeVideo::decodeBlock()
{
const long bufMinSize = 4;
const long bufMinSize = 5;
DataBuf buf(bufMinSize);
unsigned long size = 0;
buf.pData_[4] = '\0' ;
@ -773,10 +781,10 @@ namespace Exiv2 {
byte n = 3;
while(n--) {
io_->seek(4, BasicIo::cur); io_->read(buf.pData_, 4);
io_->seek(static_cast<long>(4), BasicIo::cur); io_->read(buf.pData_, 4);
if(equalsQTimeTag(buf, "clef")) {
io_->seek(4, BasicIo::cur);
io_->seek(static_cast<long>(4), BasicIo::cur);
io_->read(buf.pData_, 2); io_->read(buf2.pData_, 2);
xmpData_["Xmp.video.CleanApertureWidth"] = Exiv2::toString(getUShort(buf.pData_, bigEndian))
+ "." + Exiv2::toString(getUShort(buf2.pData_, bigEndian));
@ -786,7 +794,7 @@ namespace Exiv2 {
}
else if(equalsQTimeTag(buf, "prof")) {
io_->seek(4, BasicIo::cur);
io_->seek(static_cast<long>(4), BasicIo::cur);
io_->read(buf.pData_, 2); io_->read(buf2.pData_, 2);
xmpData_["Xmp.video.ProductionApertureWidth"] = Exiv2::toString(getUShort(buf.pData_, bigEndian))
+ "." + Exiv2::toString(getUShort(buf2.pData_, bigEndian));
@ -796,7 +804,7 @@ namespace Exiv2 {
}
else if(equalsQTimeTag(buf, "enof")) {
io_->seek(4, BasicIo::cur);
io_->seek(static_cast<long>(4), BasicIo::cur);
io_->read(buf.pData_, 2); io_->read(buf2.pData_, 2);
xmpData_["Xmp.video.EncodedPixelsWidth"] = Exiv2::toString(getUShort(buf.pData_, bigEndian))
+ "." + Exiv2::toString(getUShort(buf2.pData_, bigEndian));
@ -805,7 +813,7 @@ namespace Exiv2 {
+ "." + Exiv2::toString(getUShort(buf2.pData_, bigEndian));
}
}
io_->seek(cur_pos + size, BasicIo::beg);
io_->seek(static_cast<long>(cur_pos + size), BasicIo::beg);
} // QuickTimeVideo::trackApertureTagDecoder
void QuickTimeVideo::CameraTagsDecoder(unsigned long size_external)
@ -834,7 +842,7 @@ namespace Exiv2 {
xmpData_["Xmp.video.WhiteBalance"] = exvGettext(td->label_);
io_->read(buf.pData_, 4); io_->read(buf2.pData_, 4);
xmpData_["Xmp.video.FocalLength"] = getULong(buf.pData_, littleEndian) / (double)getULong(buf2.pData_, littleEndian) ;
io_->seek(95, BasicIo::cur);
io_->seek(static_cast<long>(95), BasicIo::cur);
io_->read(buf.pData_, 48);
xmpData_["Xmp.video.Software"] = Exiv2::toString(buf.pData_);
io_->read(buf.pData_, 4);
@ -1104,7 +1112,7 @@ namespace Exiv2 {
io_->read(buf.pData_, 4);
uint64_t noOfEntries, totalframes = 0, timeOfFrames = 0;
noOfEntries = returnUnsignedBufValue(buf);
int temp;
uint64_t temp;
for(unsigned long i = 1; i <= noOfEntries; i++) {
io_->read(buf.pData_, 4);
@ -1171,7 +1179,7 @@ namespace Exiv2 {
break;
}
}
io_->read(buf.pData_, size % 4);
io_->read(buf.pData_, static_cast<long>(size % 4)); //cause size is so small, this cast should be right.
} // QuickTimeVideo::audioDescDecoder
void QuickTimeVideo::imageDescDecoder()
@ -1219,7 +1227,7 @@ namespace Exiv2 {
break;
}
}
io_->read(buf.pData_, size % 4);
io_->read(buf.pData_, static_cast<long>(size % 4));
xmpData_["Xmp.video.BitDepth"] = returnBufValue(buf, 1);
} // QuickTimeVideo::imageDescDecoder
@ -1237,7 +1245,7 @@ namespace Exiv2 {
} // QuickTimeVideo::multipleEntriesDecoder
void QuickTimeVideo::videoHeaderDecoder(unsigned long size) {
DataBuf buf(2);
DataBuf buf(3);
std::memset(buf.pData_, 0x0, buf.size_);
buf.pData_[2] = '\0';
currentStream_ = Video;
@ -1309,7 +1317,7 @@ namespace Exiv2 {
} // QuickTimeVideo::handlerDecoder
void QuickTimeVideo::fileTypeDecoder(unsigned long size) {
DataBuf buf(4);
DataBuf buf(5);
std::memset(buf.pData_, 0x0, buf.size_);
buf.pData_[4] = '\0';
Exiv2::Value::AutoPtr v = Exiv2::Value::create(Exiv2::xmpSeq);
@ -1340,10 +1348,10 @@ namespace Exiv2 {
} // QuickTimeVideo::fileTypeDecoder
void QuickTimeVideo::mediaHeaderDecoder(unsigned long size) {
DataBuf buf(4);
DataBuf buf(5);
std::memset(buf.pData_, 0x0, buf.size_);
buf.pData_[4] = '\0';
int time_scale = 1;
int64_t time_scale = 1;
for (int i = 0; size/4 != 0 ; size -=4, i++) {
io_->read(buf.pData_, 4);
@ -1397,10 +1405,10 @@ namespace Exiv2 {
} // QuickTimeVideo::mediaHeaderDecoder
void QuickTimeVideo::trackHeaderDecoder(unsigned long size) {
DataBuf buf(4);
DataBuf buf(5);
std::memset(buf.pData_, 0x0, buf.size_);
buf.pData_[4] = '\0';
uint64_t temp = 0;
int64_t temp = 0;
for (int i = 0; size/4 != 0 ; size -=4, i++) {
io_->read(buf.pData_, 4);
@ -1452,14 +1460,14 @@ namespace Exiv2 {
break;
case ImageWidth:
if(currentStream_ == Video) {
temp = returnBufValue(buf, 2) + ((buf.pData_[2] * 256 + buf.pData_[3]) * 0.01);
temp = returnBufValue(buf, 2) + static_cast<int64_t>((buf.pData_[2] * 256 + buf.pData_[3]) * 0.01);
xmpData_["Xmp.video.Width"] = temp;
width_ = temp;
}
break;
case ImageHeight:
if(currentStream_ == Video) {
temp = returnBufValue(buf, 2) + ((buf.pData_[2] * 256 + buf.pData_[3]) * 0.01);
temp = returnBufValue(buf, 2) + static_cast<int64_t>((buf.pData_[2] * 256 + buf.pData_[3]) * 0.01);
xmpData_["Xmp.video.Height"] = temp;
height_ = temp;
}
@ -1472,7 +1480,7 @@ namespace Exiv2 {
} // QuickTimeVideo::trackHeaderDecoder
void QuickTimeVideo::movieHeaderDecoder(unsigned long size) {
DataBuf buf(4);
DataBuf buf(5);
std::memset(buf.pData_, 0x0, buf.size_);
buf.pData_[4] = '\0';
@ -1557,10 +1565,11 @@ namespace Exiv2 {
bool matched = isQuickTimeType(buf[0], buf[1], buf[2], buf[3]);
if (!advance || !matched) {
iIo.seek(0, BasicIo::beg);
iIo.seek(static_cast<long>(0), BasicIo::beg);
}
return matched;
}
} // namespace Exiv2

View File

@ -537,7 +537,7 @@ namespace Exiv2 {
const long bufMinSize = 4;
DataBuf buf(bufMinSize);
buf.pData_[4] = '\0';
buf.pData_[3] = '\0';
io_->read(buf.pData_, bufMinSize);
xmpData_["Xmp.video.Container"] = buf.pData_;
@ -551,7 +551,7 @@ namespace Exiv2 {
void RiffVideo::decodeBlock()
{
const long bufMinSize = 4;
const long bufMinSize = 5;
DataBuf buf(bufMinSize);
DataBuf buf2(bufMinSize);
unsigned long size = 0;
@ -718,7 +718,7 @@ namespace Exiv2 {
void RiffVideo::skipListData()
{
const long bufMinSize = 4;
const long bufMinSize = 5;
DataBuf buf(bufMinSize);
buf.pData_[4] = '\0';
io_->seek(-12, BasicIo::cur);
@ -854,9 +854,9 @@ namespace Exiv2 {
void RiffVideo::junkHandler(long size)
{
const long bufMinSize = size;
DataBuf buf(bufMinSize), buf2(4);
DataBuf buf(bufMinSize), buf2(5);
std::memset(buf.pData_, 0x0, buf.size_);
buf.pData_[4] = '\0';
buf2.pData_[4] = '\0';
uint64_t cur_pos = io_->tell();
io_->read(buf.pData_, 4);
@ -922,7 +922,7 @@ namespace Exiv2 {
void RiffVideo::aviHeaderTagsHandler(long size)
{
const long bufMinSize = 4;
const long bufMinSize = 5;
DataBuf buf(bufMinSize);
buf.pData_[4] = '\0';
long width = 0, height = 0, frame_count = 0;
@ -968,7 +968,7 @@ namespace Exiv2 {
void RiffVideo::streamHandler(long size)
{
const long bufMinSize = 4;
const long bufMinSize = 5;
DataBuf buf(bufMinSize);
buf.pData_[4]='\0';
long divisor = 1;
@ -1032,7 +1032,7 @@ namespace Exiv2 {
void RiffVideo::streamFormatHandler(long size)
{
const long bufMinSize = 4;
const long bufMinSize = 5;
DataBuf buf(bufMinSize);
buf.pData_[4] = '\0';
uint64_t cur_pos = io_->tell();
@ -1163,7 +1163,7 @@ namespace Exiv2 {
if(frame_rate == 0)
return;
uint64_t duration = (double)frame_count * (double)1000 / (double)frame_rate;
uint64_t duration = static_cast<uint64_t>((double)frame_count * (double)1000 / (double)frame_rate);
xmpData_["Xmp.video.FileDataRate"] = (double)io_->size()/(double)(1048576*duration);
xmpData_["Xmp.video.Duration"] = duration; //Duration in number of seconds
} // RiffVideo::fillDuration