winamp/Src/external_dependencies/libmp4v2/mp4property.h
2024-09-24 14:54:57 +02:00

530 lines
12 KiB
C++

/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
*
* Contributor(s):
* Dave Mackie dmackie@cisco.com
*/
#ifndef __MP4_PROPERTY_INCLUDED__
#define __MP4_PROPERTY_INCLUDED__
// forward declarations
class MP4Atom;
class MP4File;
class MP4Descriptor;
MP4ARRAY_DECL(MP4Descriptor, MP4Descriptor*);
enum MP4PropertyType {
Integer8Property,
Integer16Property,
Integer24Property,
Integer32Property,
Integer64Property,
Float32Property,
StringProperty,
BytesProperty,
TableProperty,
DescriptorProperty,
};
class MP4Property {
public:
MP4Property(const char *name = NULL);
virtual ~MP4Property() { }
MP4Atom* GetParentAtom() {
return m_pParentAtom;
}
virtual void SetParentAtom(MP4Atom* pParentAtom) {
m_pParentAtom = pParentAtom;
}
const char *GetName() {
return m_name;
}
virtual MP4PropertyType GetType() = 0;
bool IsReadOnly() {
return m_readOnly;
}
void SetReadOnly(bool value = true) {
m_readOnly = value;
}
bool IsImplicit() {
return m_implicit;
}
void SetImplicit(bool value = true) {
m_implicit = value;
}
virtual u_int32_t GetCount() = 0;
virtual void SetCount(u_int32_t count) = 0;
virtual void Generate() { /* default is a no-op */ };
virtual void Read(MP4File* pFile, u_int32_t index = 0) = 0;
virtual void Write(MP4File* pFile, u_int32_t index = 0) = 0;
virtual bool FindProperty(const char* name,
MP4Property** ppProperty, u_int32_t* pIndex = NULL);
protected:
MP4Atom* m_pParentAtom;
const char* m_name;
bool m_readOnly;
bool m_implicit;
};
MP4ARRAY_DECL(MP4Property, MP4Property*);
class MP4IntegerProperty : public MP4Property {
protected:
MP4IntegerProperty(char* name)
: MP4Property(name) { };
public:
u_int64_t GetValue(u_int32_t index = 0);
void SetValue(u_int64_t value, u_int32_t index = 0);
void InsertValue(u_int64_t value, u_int32_t index = 0);
void DeleteValue(u_int32_t index = 0);
void IncrementValue(int32_t increment = 1, u_int32_t index = 0);
};
template <class val_t, u_int8_t size, MP4PropertyType prop_type>
class MP4IntegerPropertyT : public MP4IntegerProperty {
public:
MP4IntegerPropertyT(char* name)
: MP4IntegerProperty(name) {
SetCount(1);
m_values[0] = 0;
}
MP4PropertyType GetType() {
//return Integer##xsize##Property;
return prop_type;
}
u_int32_t GetCount() {
return m_values.Size();
}
void SetCount(u_int32_t count) {
m_values.Resize(count);
}
val_t GetValue(u_int32_t index = 0) {
return m_values[index];
}
void SetValue(val_t value, u_int32_t index = 0)
{
if (m_readOnly) {
throw new MP4Error(EACCES, "property is read-only", m_name); \
}
m_values[index] = value;
}
void AddValue(val_t value) {
m_values.Add(value);
}
void InsertValue(val_t value, u_int32_t index) {
m_values.Insert(value, index);
}
void DeleteValue(u_int32_t index) {
m_values.Delete(index);
}
void IncrementValue(int32_t increment = 1, u_int32_t index = 0) {
m_values[index] += increment;
}
void Read(MP4File* pFile, u_int32_t index = 0) {
if (m_implicit) {
return;
}
m_values[index] = (val_t)pFile->ReadUInt(size/8);
}
void Write(MP4File* pFile, u_int32_t index = 0) {
if (m_implicit) {
return;
}
pFile->WriteUInt((u_int64_t)m_values[index], size/8);
}
protected:
MP4TArray<val_t> m_values;
};
#define MP4INTEGER_PROPERTY_DECL(val_t, xsize) typedef MP4IntegerPropertyT<val_t, xsize, Integer##xsize##Property> MP4Integer##xsize##Property;
MP4INTEGER_PROPERTY_DECL(u_int8_t, 8);
MP4INTEGER_PROPERTY_DECL(u_int16_t, 16);
MP4INTEGER_PROPERTY_DECL(u_int32_t, 24);
MP4INTEGER_PROPERTY_DECL(u_int32_t, 32);
MP4INTEGER_PROPERTY_DECL(u_int64_t, 64);
class MP4BitfieldProperty : public MP4Integer64Property {
public:
MP4BitfieldProperty(char* name, u_int8_t numBits)
: MP4Integer64Property(name) {
ASSERT(numBits != 0);
ASSERT(numBits <= 64);
m_numBits = numBits;
}
u_int8_t GetNumBits() {
return m_numBits;
}
void SetNumBits(u_int8_t numBits) {
m_numBits = numBits;
}
void Read(MP4File* pFile, u_int32_t index = 0);
void Write(MP4File* pFile, u_int32_t index = 0);
protected:
u_int8_t m_numBits;
};
class MP4Float32Property : public MP4Property {
public:
MP4Float32Property(char* name)
: MP4Property(name) {
m_useFixed16Format = false;
m_useFixed32Format = false;
SetCount(1);
m_values[0] = 0.0;
}
MP4PropertyType GetType() {
return Float32Property;
}
u_int32_t GetCount() {
return m_values.Size();
}
void SetCount(u_int32_t count) {
m_values.Resize(count);
}
float GetValue(u_int32_t index = 0) {
return m_values[index];
}
void SetValue(float value, u_int32_t index = 0) {
if (m_readOnly) {
throw new MP4Error(EACCES, "property is read-only", m_name);
}
m_values[index] = value;
}
void AddValue(float value) {
m_values.Add(value);
}
void InsertValue(float value, u_int32_t index) {
m_values.Insert(value, index);
}
bool IsFixed16Format() {
return m_useFixed16Format;
}
void SetFixed16Format(bool useFixed16Format = true) {
m_useFixed16Format = useFixed16Format;
}
bool IsFixed32Format() {
return m_useFixed32Format;
}
void SetFixed32Format(bool useFixed32Format = true) {
m_useFixed32Format = useFixed32Format;
}
void Read(MP4File* pFile, u_int32_t index = 0);
void Write(MP4File* pFile, u_int32_t index = 0);
protected:
bool m_useFixed16Format;
bool m_useFixed32Format;
MP4Float32Array m_values;
};
class MP4StringProperty : public MP4Property {
public:
MP4StringProperty(char* name,
bool useCountedFormat = false, bool useUnicode = false);
~MP4StringProperty();
MP4PropertyType GetType() {
return StringProperty;
}
u_int32_t GetCount() {
return m_values.Size();
}
void SetCount(u_int32_t count);
const char* GetValue(u_int32_t index = 0) {
return m_values[index];
}
void SetValue(const char* value, u_int32_t index = 0);
void AddValue(const char* value) {
u_int32_t count = GetCount();
SetCount(count + 1);
SetValue(value, count);
}
bool IsCountedFormat() {
return m_useCountedFormat;
}
void SetCountedFormat(bool useCountedFormat) {
m_useCountedFormat = useCountedFormat;
}
bool IsExpandedCountedFormat() {
return m_useExpandedCount;
}
void SetExpandedCountedFormat(bool useExpandedCount) {
m_useExpandedCount = useExpandedCount;
}
bool IsUnicode() {
return m_useUnicode;
}
void SetUnicode(bool useUnicode) {
m_useUnicode = useUnicode;
}
u_int32_t GetFixedLength() {
return m_fixedLength;
}
void SetFixedLength(u_int32_t fixedLength) {
m_fixedLength = fixedLength;
}
void Read(MP4File* pFile, u_int32_t index = 0);
void Write(MP4File* pFile, u_int32_t index = 0);
protected:
bool m_useCountedFormat;
bool m_useExpandedCount;
bool m_useUnicode;
u_int32_t m_fixedLength;
MP4StringArray m_values;
};
class MP4BytesProperty : public MP4Property {
public:
MP4BytesProperty(char* name, u_int32_t valueSize = 0,
u_int32_t defaultValueSize = 0);
~MP4BytesProperty();
MP4PropertyType GetType() {
return BytesProperty;
}
u_int32_t GetCount() {
return m_values.Size();
}
void SetCount(u_int32_t count);
void GetValue(u_int8_t** ppValue, u_int32_t* pValueSize,
u_int32_t index = 0) {
// N.B. caller must free memory
*ppValue = (u_int8_t*)MP4Malloc(m_valueSizes[index]);
memcpy(*ppValue, m_values[index], m_valueSizes[index]);
*pValueSize = m_valueSizes[index];
}
void CopyValue(u_int8_t* pValue, u_int32_t index = 0) {
// N.B. caller takes responsbility for valid pointer
// and sufficient memory at the destination
memcpy(pValue, m_values[index], m_valueSizes[index]);
}
void SetValue(const u_int8_t* pValue, u_int32_t valueSize,
u_int32_t index = 0);
void AddValue(const u_int8_t* pValue, u_int32_t valueSize) {
u_int32_t count = GetCount();
SetCount(count + 1);
SetValue(pValue, valueSize, count);
}
u_int32_t GetValueSize(u_int32_t valueSize, u_int32_t index = 0) {
return m_valueSizes[index];
}
void SetValueSize(u_int32_t valueSize, u_int32_t index = 0);
u_int32_t GetFixedSize() {
return m_fixedValueSize;
}
void SetFixedSize(u_int32_t fixedSize);
void Read(MP4File* pFile, u_int32_t index = 0);
void Write(MP4File* pFile, u_int32_t index = 0);
protected:
u_int32_t m_fixedValueSize;
u_int32_t m_defaultValueSize;
MP4Integer32Array m_valueSizes;
MP4BytesArray m_values;
};
class MP4TableProperty : public MP4Property {
public:
MP4TableProperty(char* name, MP4IntegerProperty* pCountProperty);
~MP4TableProperty();
MP4PropertyType GetType() {
return TableProperty;
}
void SetParentAtom(MP4Atom* pParentAtom) {
m_pParentAtom = pParentAtom;
for (u_int32_t i = 0; i < m_pProperties.Size(); i++) {
m_pProperties[i]->SetParentAtom(pParentAtom);
}
}
void AddProperty(MP4Property* pProperty);
MP4Property* GetProperty(u_int32_t index) {
return m_pProperties[index];
}
virtual u_int32_t GetCount() {
return m_pCountProperty->GetValue();
}
virtual void SetCount(u_int32_t count) {
m_pCountProperty->SetValue(count);
}
void Read(MP4File* pFile, u_int32_t index = 0);
void Write(MP4File* pFile, u_int32_t index = 0);
bool FindProperty(const char* name,
MP4Property** ppProperty, u_int32_t* pIndex = NULL);
protected:
virtual void ReadEntry(MP4File* pFile, u_int32_t index);
virtual void WriteEntry(MP4File* pFile, u_int32_t index);
bool FindContainedProperty(const char* name,
MP4Property** ppProperty, u_int32_t* pIndex);
protected:
MP4IntegerProperty* m_pCountProperty;
MP4PropertyArray m_pProperties;
};
class MP4DescriptorProperty : public MP4Property {
public:
MP4DescriptorProperty(char* name = NULL,
u_int8_t tagsStart = 0, u_int8_t tagsEnd = 0,
bool mandatory = false, bool onlyOne = false);
~MP4DescriptorProperty();
MP4PropertyType GetType() {
return DescriptorProperty;
}
void SetParentAtom(MP4Atom* pParentAtom);
void SetSizeLimit(u_int64_t sizeLimit) {
m_sizeLimit = sizeLimit;
}
u_int32_t GetCount() {
return m_pDescriptors.Size();
}
void SetCount(u_int32_t count) {
m_pDescriptors.Resize(count);
}
void SetTags(u_int8_t tagsStart, u_int8_t tagsEnd = 0) {
m_tagsStart = tagsStart;
m_tagsEnd = tagsEnd ? tagsEnd : tagsStart;
}
MP4Descriptor* AddDescriptor(u_int8_t tag);
void AppendDescriptor(MP4Descriptor* pDescriptor) {
m_pDescriptors.Add(pDescriptor);
}
void DeleteDescriptor(u_int32_t index);
void Generate();
void Read(MP4File* pFile, u_int32_t index = 0);
void Write(MP4File* pFile, u_int32_t index = 0);
bool FindProperty(const char* name,
MP4Property** ppProperty, u_int32_t* pIndex = NULL);
protected:
virtual MP4Descriptor* CreateDescriptor(u_int8_t tag);
bool FindContainedProperty(const char* name,
MP4Property** ppProperty, u_int32_t* pIndex);
protected:
u_int8_t m_tagsStart;
u_int8_t m_tagsEnd;
u_int64_t m_sizeLimit;
bool m_mandatory;
bool m_onlyOne;
MP4DescriptorArray m_pDescriptors;
};
class MP4QosQualifierProperty : public MP4DescriptorProperty {
public:
MP4QosQualifierProperty(char* name = NULL,
u_int8_t tagsStart = 0, u_int8_t tagsEnd = 0,
bool mandatory = false, bool onlyOne = false) :
MP4DescriptorProperty(name, tagsStart, tagsEnd, mandatory, onlyOne) { }
protected:
MP4Descriptor* CreateDescriptor(u_int8_t tag);
};
#endif /* __MP4_PROPERTY_INCLUDED__ */