1 // ================================================================================================= 2 // ADOBE SYSTEMS INCORPORATED 3 // Copyright 2010 Adobe Systems Incorporated 4 // All Rights Reserved 5 // 6 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms 7 // of the Adobe license agreement accompanying it. 8 // ================================================================================================= 9 10 #ifndef _WAVEBEHAVIOR_h_ 11 #define _WAVEBEHAVIOR_h_ 12 13 #include "public/include/XMP_Environment.h" // ! XMP_Environment.h must be the first included header. 14 15 #include "public/include/XMP_Const.h" 16 #include "public/include/XMP_IO.hpp" 17 18 #include "XMPFiles/source/FormatSupport/IFF/IChunkBehavior.h" 19 #include "XMPFiles/source/FormatSupport/IFF/ChunkPath.h" 20 #include "source/Endian.h" 21 22 namespace IFF_RIFF 23 { 24 25 /** 26 WAVE behavior class. 27 28 Implements the IChunkBehavior interface 29 */ 30 31 32 class WAVEBehavior : public IChunkBehavior 33 { 34 // Internal structure to hold RF64 related data 35 public: 36 #if SUNOS_SPARC || SUNOS_X86 37 #pragma pack ( 1 ) 38 #else 39 #pragma pack ( push, 1 ) 40 #endif //#if SUNOS_SPARC || SUNOS_X86 41 struct ChunkSize64 42 { 43 XMP_Uns64 size; 44 XMP_Uns32 id; 45 // Ctor ChunkSize64ChunkSize6446 ChunkSize64(): size(0), id(0) {} 47 }; 48 49 struct DS64 50 { 51 XMP_Uns64 riffSize; 52 XMP_Uns64 dataSize; 53 XMP_Uns64 sampleCount; 54 XMP_Uns32 tableLength; 55 // fix part ends here 56 XMP_Uns32 trailingBytes; 57 std::vector<ChunkSize64> table; 58 59 // ctor DS64DS6460 DS64(): riffSize(0), dataSize(0), sampleCount(0), tableLength(0), trailingBytes(0) {} 61 }; 62 #if SUNOS_SPARC || SUNOS_X86 63 #pragma pack ( ) 64 #else 65 #pragma pack ( pop ) 66 #endif //#if SUNOS_SPARC || SUNOS_X86 67 68 69 /** 70 ctor/dtor 71 */ WAVEBehavior()72 WAVEBehavior() : mChunksAdded(0), mIsRF64(false), mDS64Data(NULL) {} 73 ~WAVEBehavior()74 virtual ~WAVEBehavior() 75 { 76 if( mDS64Data != NULL ) 77 { 78 delete mDS64Data; 79 } 80 } 81 82 /** 83 Validate the passed in size value, identify the valid size if the passed in isn't valid 84 and return the valid size. 85 throw an exception if the passed in size isn't valid and there's no way to identify a 86 valid size. 87 88 @param size Size value 89 @param id Identifier of chunk 90 @param tree Chunk tree 91 @param stream Stream handle 92 93 @return Valid size value. 94 */ 95 XMP_Uns64 getRealSize( const XMP_Uns64 size, const ChunkIdentifier& id, IChunkContainer& tree, XMP_IO* stream ); 96 97 /** 98 Return the maximum size of a single chunk, i.e. the maximum size of a top-level chunk. 99 100 @return Maximum size 101 */ 102 XMP_Uns64 getMaxChunkSize() const; 103 104 /** 105 Return true if the passed identifier is valid for top-level chunks of a certain format. 106 107 @param id Chunk identifier 108 @param chunkNo order number of top-level chunk 109 @return true, if passed id is a valid top-level chunk 110 */ 111 bool isValidTopLevelChunk( const ChunkIdentifier& id, XMP_Uns32 chunkNo ); 112 113 /** 114 Fix the hierarchy of chunks depending ones based on size changes of one or more chunks 115 and second based on format specific rules. 116 Throw an exception if the hierarchy can't be fixed. 117 118 @param tree Vector of root chunks. 119 */ 120 void fixHierarchy( IChunkContainer& tree ); 121 122 /** 123 Insert a new chunk into the hierarchy of chunks. The behavior needs to decide the position 124 of the new chunk and has to do the insertion. 125 126 @param tree Chunk tree 127 @param chunk New chunk 128 */ 129 void insertChunk( IChunkContainer& tree, Chunk& chunk ) ; 130 131 /** 132 Remove the chunk described by the passed ChunkPath. 133 134 @param tree Chunk tree 135 @param path Path to the chunk that needs to be removed 136 137 @return true if the chunk was removed and need to be deleted 138 */ 139 bool removeChunk( IChunkContainer& tree, Chunk& chunk ) ; 140 141 protected: 142 /** 143 Create a FREE chunk. 144 If the chunkSize is smaller than the header+type - size then create an annotation chunk. 145 If the passed size is odd, then add a pad byte. 146 147 @param chunkSize Total size including header 148 @return New FREE chunk 149 */ 150 Chunk* createFREE( XMP_Uns64 chunkSize ); 151 152 /** 153 Check if the passed chunk is a FREE chunk. 154 (Could be also a small annotation chunk with zero bytes in its data) 155 156 @param chunk A chunk 157 158 @return true if the passed chunk is a FREE chunk 159 */ 160 XMP_Bool isFREEChunk( const Chunk& chunk ) const; 161 162 /** 163 Return the minimum size of a FREE chunk 164 */ 165 XMP_Uns64 getMinFREESize( ) const; 166 167 /** 168 Is the current file a RF64 file? 169 170 @param tree The whole chunk tree beginning with the root node 171 172 @return true if the current file is in the RF64 format 173 */ 174 bool isRF64( const IChunkContainer& tree ); 175 176 /** 177 Return RF64 structure. 178 179 If the related chunk ('ds64') is not yet parsed then it should be parsed by this method. 180 181 @param tree The chunk tree (probably a subtree) 182 @param stream File stream 183 184 @return DS64 structure 185 */ 186 DS64* getDS64( IChunkContainer& tree, XMP_IO* stream ); 187 188 /** 189 update the RF64 chunk (if this is RF64) based on the current chunk sizes 190 */ 191 void updateRF64( IChunkContainer& tree ); 192 193 /** 194 * Parses the data block of the given RF64 chunk into the internal data structures 195 * @param rf64Chunk the RF64 Chunk 196 * @param rf64 OUT the RF64 data structure 197 * @return The parsing was successful (true) or not (false) 198 */ 199 bool parseDS64Chunk( const Chunk& ds64Chunk, DS64& rf64 ); 200 201 /** 202 * Serializes the internal RF64 data structures into the data part of the given chunk 203 * @param rf64 the RF64 data structure 204 * @param rf64Chunk OUT the RF64 Chunk 205 * @return The serialization was successful (true) or not (false) 206 */ 207 bool serializeDS64Chunk( const WAVEBehavior::DS64& rf64, Chunk& ds64Chunk ); 208 209 private: 210 void doUpdateRF64( Chunk& chunk ); 211 212 private: 213 XMP_Uns32 mChunksAdded; 214 bool mIsRF64; 215 DS64* mDS64Data; 216 217 static const LittleEndian& mEndian; // WAVE is always Little Endian 218 static const XMP_Uns32 kNormalRF64ChunkSize = 0xFFFFFFFF; 219 static const XMP_Uns32 kMinimumDS64ChunkSize = 28; 220 }; // IFF_RIFF 221 222 } 223 #endif 224