![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
00001 /* 00002 ------------------------------------------------------------------------------- 00003 This file is part of the Plink, Plonk, Plank libraries 00004 by Martin Robinson 00005 00006 http://code.google.com/p/pl-nk/ 00007 00008 Copyright University of the West of England, Bristol 2011-14 00009 All rights reserved. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions are met: 00013 00014 * Redistributions of source code must retain the above copyright 00015 notice, this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright 00017 notice, this list of conditions and the following disclaimer in the 00018 documentation and/or other materials provided with the distribution. 00019 * Neither the name of University of the West of England, Bristol nor 00020 the names of its contributors may be used to endorse or promote products 00021 derived from this software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 This software makes use of third party libraries. For more information see: 00035 doc/license.txt included in the distribution. 00036 ------------------------------------------------------------------------------- 00037 */ 00038 00039 #ifndef PLANK_IFFFILECOMMON_H 00040 #define PLANK_IFFFILECOMMON_H 00041 00042 #include "plank_File.h" 00043 00044 #define PLANKIFFFILE_CURRENTCHUNKPOSITION -1 00045 //#define PLANKIFFFILE_ANYCHUNKID -1 00046 #define PLANKIFFFILE_ID_FCC 1 00047 #define PLANKIFFFILE_ID_GUID 2 00048 00049 #define PLANKIFFFILE_W64_RIFF_ID "riff-912E-11CF-A5D6-28DB04C10000" 00050 #define PLANKIFFFILE_W64_LIST_ID "list-912F-11CF-A5D6-28DB04C10000" 00051 #define PLANKIFFFILE_W64_JUNK_ID "junk-ACF3-11D3-8CD1-00C04F8EDB8A" 00052 #define PLANKIFFFILE_ANYCHUNKID "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF" 00053 00054 typedef union PlankIffID 00055 { 00056 PlankFourCharCode fcc; 00057 PlankGUID guid; 00058 } PlankIffID; 00059 00060 typedef struct PlankIffFileHeaderInfo 00061 { 00062 PlankIffID mainID; 00063 PlankIffID formatID; 00064 PlankIffID junkID; 00065 00066 PlankLL mainLength; 00067 00068 PlankUC lengthSize; 00069 PlankUC idType; 00070 PlankUC headerLength; 00071 PlankUC reserved3; 00072 PlankUC mainHeaderEnd; 00073 PlankUC initMainLength; 00074 PlankUC alignment; 00075 PlankUC reserved7; 00076 00077 } PlankIffFileHeaderInfo; 00078 00079 typedef struct PlankIffFile* PlankIffFileRef; 00080 typedef struct PlankIffFile 00081 { 00082 PlankFile file; 00083 PlankIffFileHeaderInfo headerInfo; 00084 } PlankIffFile; 00085 00086 static inline PlankResult pl_IffFile_WriteChunkLength (PlankIffFileRef p, const PlankLL length) 00087 { 00088 if (p->headerInfo.lengthSize == 4) 00089 { 00090 return pl_File_WriteUI (&p->file, length < 0xffffffff ? (PlankUI)length : 0xffffffff); 00091 } 00092 else if (p->headerInfo.lengthSize == 8) 00093 { 00094 switch (p->headerInfo.idType) 00095 { 00096 case PLANKIFFFILE_ID_FCC: return pl_File_WriteLL (&p->file, length); 00097 case PLANKIFFFILE_ID_GUID: return pl_File_WriteLL (&p->file, length + p->headerInfo.lengthSize + sizeof (PlankGUID)); // includes the chunk header 00098 default: return PlankResult_UnknownError; 00099 } 00100 } 00101 else 00102 { 00103 return PlankResult_UnknownError; 00104 } 00105 } 00106 00107 static inline PlankResult pl_IffFile_ReadChunkLength (PlankIffFileRef p, PlankLL *length) 00108 { 00109 PlankResult result; 00110 PlankUI length32; 00111 00112 result = PlankResult_OK; 00113 00114 if (p->headerInfo.lengthSize == 4) 00115 { 00116 if ((result = pl_File_ReadUI (&p->file, &length32)) != PlankResult_OK) goto exit; 00117 *length = length32; 00118 } 00119 else if (p->headerInfo.lengthSize == 8) 00120 { 00121 switch (p->headerInfo.idType) 00122 { 00123 case PLANKIFFFILE_ID_FCC: 00124 result = pl_File_ReadLL (&p->file, length); 00125 break; 00126 case PLANKIFFFILE_ID_GUID: 00127 if ((result = pl_File_ReadLL (&p->file, length)) != PlankResult_OK) goto exit; 00128 *length -= p->headerInfo.lengthSize + sizeof (PlankGUID); // includes the chunk header 00129 break; 00130 default: 00131 result = PlankResult_UnknownError; 00132 } 00133 } 00134 else 00135 { 00136 result = PlankResult_UnknownError; 00137 } 00138 00139 exit: 00140 return result; 00141 } 00142 00143 static inline PlankResult pl_IffFile_InitID (PlankIffFileRef p, const char* string, PlankIffID* chunkID) 00144 { 00145 int length; 00146 00147 (void)p; 00148 00149 if (!string) 00150 { 00151 pl_MemoryZero (chunkID, sizeof (PlankIffID)); 00152 return PlankResult_OK; 00153 } 00154 else 00155 { 00156 length = (int)strlen (string); 00157 00158 switch (length) 00159 { 00160 case 4: chunkID->fcc = pl_FourCharCode (string); return PlankResult_OK; 00161 case 36: pl_GUID_InitString (&chunkID->guid, string); return PlankResult_OK; 00162 default: return PlankResult_UnknownError; 00163 } 00164 } 00165 } 00166 00167 static inline PlankResult pl_IffFile_WriteChunkID (PlankIffFileRef p, const PlankIffID* chunkID) 00168 { 00169 switch (p->headerInfo.idType) 00170 { 00171 case PLANKIFFFILE_ID_FCC: return pl_File_WriteFourCharCode (&p->file, chunkID->fcc); 00172 case PLANKIFFFILE_ID_GUID: return pl_File_WriteGUID (&p->file, &chunkID->guid); 00173 default: return PLANK_FALSE; 00174 } 00175 } 00176 00177 static inline PlankResult pl_IffFile_ReadChunkID (PlankIffFileRef p, PlankIffID* chunkID) 00178 { 00179 switch (p->headerInfo.idType) 00180 { 00181 case PLANKIFFFILE_ID_FCC: return pl_File_ReadFourCharCode (&p->file, &chunkID->fcc); 00182 case PLANKIFFFILE_ID_GUID: return pl_File_ReadGUID (&p->file, &chunkID->guid); 00183 default: return PLANK_FALSE; 00184 } 00185 } 00186 00187 static inline PlankB pl_IffFile_EqualIDs (PlankIffFileRef p, const PlankIffID* id1, const PlankIffID* id2) 00188 { 00189 switch (p->headerInfo.idType) 00190 { 00191 case PLANKIFFFILE_ID_FCC: return id1->fcc == id2->fcc; 00192 case PLANKIFFFILE_ID_GUID: return pl_GUID_Equal (&id1->guid, &id2->guid); 00193 default: return PLANK_FALSE; 00194 } 00195 } 00196 00197 static inline PlankB pl_IffFile_IsNullID (PlankIffFileRef p, const PlankIffID* chunkID) 00198 { 00199 switch (p->headerInfo.idType) 00200 { 00201 case PLANKIFFFILE_ID_FCC: return chunkID->fcc == 0; 00202 case PLANKIFFFILE_ID_GUID: return pl_GUID_IsNull (&chunkID->guid); 00203 default: return PLANK_FALSE; 00204 } 00205 } 00206 00207 static inline void pl_IffFile_ChunkIDString (PlankIffFileRef p, const PlankIffID* chunkID, char* string) 00208 { 00209 PlankFourCharCodeString fccs; 00210 00211 switch (p->headerInfo.idType) 00212 { 00213 case PLANKIFFFILE_ID_FCC: { 00214 fccs = pl_FourCharCode2String (chunkID->fcc); 00215 strcpy (string, fccs.string); return; 00216 } 00217 case PLANKIFFFILE_ID_GUID: pl_GUID_HexString (&chunkID->guid, PLANK_FALSE, string); return; 00218 default: string[0] = '\0'; return; 00219 } 00220 } 00221 00222 static inline int pl_IffFile_ChunkIDLength (PlankIffFileRef p) 00223 { 00224 switch (p->headerInfo.idType) 00225 { 00226 case PLANKIFFFILE_ID_FCC: return 4; 00227 case PLANKIFFFILE_ID_GUID: return 16; 00228 default: return 0; 00229 } 00230 } 00231 00232 static inline const PlankIffID* pl_IffFileAnyID() 00233 { 00234 static PlankIffID any; 00235 static PlankB firstTime = PLANK_TRUE; 00236 00237 if (firstTime) 00238 { 00239 any.guid.data1 = 0xffffffff; 00240 any.guid.data2 = 0xffff; 00241 any.guid.data3 = 0xffff; 00242 any.guid.data4[0] = 0xff; 00243 any.guid.data4[1] = 0xff; 00244 any.guid.data4[2] = 0xff; 00245 any.guid.data4[3] = 0xff; 00246 any.guid.data4[4] = 0xff; 00247 any.guid.data4[5] = 0xff; 00248 any.guid.data4[6] = 0xff; 00249 any.guid.data4[7] = 0xff; 00250 } 00251 00252 return &any; 00253 } 00254 00255 00256 00257 00258 #endif // PLANK_IFFFILECOMMON_H