Workaround for 64-bit MP4 atoms.

This commit is contained in:
Tsuda Kageyu 2014-08-04 23:45:59 +09:00
parent 80f5436370
commit 0fc8a0e69f
3 changed files with 42 additions and 26 deletions

View File

@ -20,6 +20,11 @@ if(NOT ${SIZEOF_INT} EQUAL 4)
MESSAGE(FATAL_ERROR "TagLib requires that int is 32-bit wide.")
endif()
check_type_size("long" SIZEOF_LONG)
if(${SIZEOF_LONG} EQUAL 8)
set(LONG_IS_INT64 1)
endif()
check_type_size("long long" SIZEOF_LONGLONG)
if(NOT ${SIZEOF_LONGLONG} EQUAL 8)
MESSAGE(FATAL_ERROR "TagLib requires that long long is 64-bit wide.")
@ -66,65 +71,65 @@ endif()
check_cxx_source_compiles("
#include <atomic>
int main() {
int main() {
std::atomic<unsigned int> x;
x.fetch_add(1);
x.fetch_sub(1);
return 0;
return 0;
}
" HAVE_STD_ATOMIC)
if(NOT HAVE_STD_ATOMIC)
check_cxx_source_compiles("
#include <boost/atomic.hpp>
int main() {
int main() {
boost::atomic<unsigned int> x(1);
x.fetch_add(1);
x.fetch_sub(1);
return 0;
return 0;
}
" HAVE_BOOST_ATOMIC)
if(NOT HAVE_BOOST_ATOMIC)
check_cxx_source_compiles("
int main() {
int main() {
volatile int x;
__sync_add_and_fetch(&x, 1);
int y = __sync_sub_and_fetch(&x, 1);
return 0;
return 0;
}
" HAVE_GCC_ATOMIC)
if(NOT HAVE_GCC_ATOMIC)
check_cxx_source_compiles("
#include <libkern/OSAtomic.h>
int main() {
int main() {
volatile int32_t x;
OSAtomicIncrement32Barrier(&x);
int32_t y = OSAtomicDecrement32Barrier(&x);
return 0;
return 0;
}
" HAVE_MAC_ATOMIC)
if(NOT HAVE_MAC_ATOMIC)
check_cxx_source_compiles("
#include <windows.h>
int main() {
int main() {
volatile LONG x;
InterlockedIncrement(&x);
LONG y = InterlockedDecrement(&x);
return 0;
return 0;
}
" HAVE_WIN_ATOMIC)
if(NOT HAVE_WIN_ATOMIC)
check_cxx_source_compiles("
#include <ia64intrin.h>
int main() {
int main() {
volatile int x;
__sync_add_and_fetch(&x, 1);
int y = __sync_sub_and_fetch(&x, 1);
return 0;
return 0;
}
" HAVE_IA64_ATOMIC)
endif()
@ -135,26 +140,26 @@ endif()
# Determine which kind of byte swap functions your compiler supports.
# GCC's __builtin_bswap* should be checked individually
# GCC's __builtin_bswap* should be checked individually
# because some of them can be missing depends on the GCC version.
check_cxx_source_compiles("
int main() {
__builtin_bswap16(0);
return 0;
return 0;
}
" HAVE_GCC_BYTESWAP_16)
check_cxx_source_compiles("
int main() {
__builtin_bswap32(0);
return 0;
return 0;
}
" HAVE_GCC_BYTESWAP_32)
check_cxx_source_compiles("
int main() {
__builtin_bswap64(0);
return 0;
return 0;
}
" HAVE_GCC_BYTESWAP_64)
@ -165,7 +170,7 @@ if(NOT HAVE_GCC_BYTESWAP_16 OR NOT HAVE_GCC_BYTESWAP_32 OR NOT HAVE_GCC_BYTESWAP
__bswap_16(0);
__bswap_32(0);
__bswap_64(0);
return 0;
return 0;
}
" HAVE_GLIBC_BYTESWAP)
@ -176,7 +181,7 @@ if(NOT HAVE_GCC_BYTESWAP_16 OR NOT HAVE_GCC_BYTESWAP_32 OR NOT HAVE_GCC_BYTESWAP
_byteswap_ushort(0);
_byteswap_ulong(0);
_byteswap_uint64(0);
return 0;
return 0;
}
" HAVE_MSC_BYTESWAP)
@ -187,7 +192,7 @@ if(NOT HAVE_GCC_BYTESWAP_16 OR NOT HAVE_GCC_BYTESWAP_32 OR NOT HAVE_GCC_BYTESWAP
OSSwapInt16(0);
OSSwapInt32(0);
OSSwapInt64(0);
return 0;
return 0;
}
" HAVE_MAC_BYTESWAP)
@ -198,7 +203,7 @@ if(NOT HAVE_GCC_BYTESWAP_16 OR NOT HAVE_GCC_BYTESWAP_32 OR NOT HAVE_GCC_BYTESWAP
swap16(0);
swap32(0);
swap64(0);
return 0;
return 0;
}
" HAVE_OPENBSD_BYTESWAP)
endif()
@ -224,9 +229,9 @@ endif()
check_cxx_source_compiles("
#include <codecvt>
int main() {
std::codecvt_utf8_utf16<wchar_t> x;
return 0;
int main() {
std::codecvt_utf8_utf16<wchar_t> x;
return 0;
}
" HAVE_STD_CODECVT)

View File

@ -8,6 +8,9 @@
/* 1 if little-endian, 2 if big-endian. */
#cmakedefine FLOAT_BYTEORDER ${FLOAT_BYTEORDER}
/* Defined if long is 64-bit wide */
#cmakedefine LONG_IS_INT64 ${LONG_IS_INT64}
/* Defined if your compiler supports some byte swap functions */
#cmakedefine HAVE_GCC_BYTESWAP_16 1
#cmakedefine HAVE_GCC_BYTESWAP_32 1

View File

@ -23,6 +23,10 @@
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tdebug.h>
#include <tstring.h>
#include "mp4atom.h"
@ -50,9 +54,12 @@ MP4::Atom::Atom(File *file)
length = header.toUInt();
if (length == 1) {
if(length == 1) {
const long long longLength = file->readBlock(8).toLongLong();
if (longLength >= 8 && longLength <= 0xFFFFFFFF) {
#ifdef LONG_IS_INT64
length = longLength;
#else
if(longLength <= 0xFFFFFFFF) {
// The atom has a 64-bit length, but it's actually a 32-bit value
length = (long)longLength;
}
@ -62,8 +69,9 @@ MP4::Atom::Atom(File *file)
file->seek(0, File::End);
return;
}
#endif
}
if (length < 8) {
if(length < 8) {
debug("MP4: Invalid atom size");
length = 0;
file->seek(0, File::End);