1 /*
2
3 Audio Overload SDK
4
5 Copyright (c) 2007-2008, R. Belmont and Richard Bannister.
6
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
10
11 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
13 * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 // corlett.c
29
30 // Decodes file format designed by Neill Corlett (PSF, QSF, ...)
31
32 /*
33 - First 3 bytes: ASCII signature: "PSF" (case sensitive)
34
35 - Next 1 byte: Version byte
36 The version byte is used to determine the type of PSF file. It does NOT
37 affect the basic structure of the file in any way.
38
39 Currently accepted version bytes are:
40 0x01: Playstation (PSF1)
41 0x02: Playstation 2 (PSF2)
42 0x11: Saturn (SSF) [TENTATIVE]
43 0x12: Dreamcast (DSF) [TENTATIVE]
44 0x21: Nintendo 64 (USF) [RESERVED]
45 0x41: Capcom QSound (QSF)
46
47 - Next 4 bytes: Size of reserved area (R), little-endian unsigned long
48
49 - Next 4 bytes: Compressed program length (N), little-endian unsigned long
50 This is the length of the program data _after_ compression.
51
52 - Next 4 bytes: Compressed program CRC-32, little-endian unsigned long
53 This is the CRC-32 of the program data _after_ compression. Filling in
54 this value is mandatory, as a PSF file may be regarded as corrupt if it
55 does not match.
56
57 - Next R bytes: Reserved area.
58 May be empty if R is 0 bytes.
59
60 - Next N bytes: Compressed program, in zlib compress() format.
61 May be empty if N is 0 bytes.
62
63 The following data is optional and may be omitted:
64
65 - Next 5 bytes: ASCII signature: "[TAG]" (case sensitive)
66 If these 5 bytes do not match, then the remainder of the file may be
67 regarded as invalid and discarded.
68
69 - Remainder of file: Uncompressed ASCII tag data.
70 */
71
72 #include <assert.h>
73 #include <string.h>
74 #include <stdlib.h>
75
76 #include "ao.h"
77 #include "corlett.h"
78
79 #include <zlib.h>
80 #include <stdlib.h>
81
82 #define DECOMP_MAX_SIZE ((32 * 1024 * 1024) + 12)
83
corlett_decode(uint8 * input,uint32 input_len,uint8 ** output,uint64 * size,corlett_t ** c)84 int corlett_decode(uint8 *input, uint32 input_len, uint8 **output, uint64 *size, corlett_t **c)
85 {
86 uint32 *buf;
87 uint32 res_area, comp_crc, actual_crc;
88 uint8 *decomp_dat, *tag_dec;
89 uLongf decomp_length, comp_length;
90
91 // 32-bit pointer to data
92 buf = (uint32 *)input;
93
94 // Check we have a PSF format file.
95 if ((input[0] != 'P') || (input[1] != 'S') || (input[2] != 'F'))
96 {
97 return AO_FAIL;
98 }
99
100 // Get our values
101 res_area = LE32(buf[1]);
102 comp_length = LE32(buf[2]);
103 comp_crc = LE32(buf[3]);
104
105 if (comp_length > 0)
106 {
107 // Check length
108 if (input_len < comp_length + 16)
109 return AO_FAIL;
110
111 // Check CRC is correct
112 actual_crc = crc32(0, (unsigned char *)&buf[4+(res_area/4)], comp_length);
113 if (actual_crc != comp_crc)
114 return AO_FAIL;
115
116 // Decompress data if any
117 decomp_dat = malloc(DECOMP_MAX_SIZE);
118 decomp_length = DECOMP_MAX_SIZE;
119 if (uncompress(decomp_dat, &decomp_length, (unsigned char *)&buf[4+(res_area/4)], comp_length) != Z_OK)
120 {
121 free(decomp_dat);
122 return AO_FAIL;
123 }
124
125 // Resize memory buffer to what we actually need
126 decomp_dat = realloc(decomp_dat, (size_t)decomp_length + 1);
127 }
128 else
129 {
130 decomp_dat = NULL;
131 decomp_length = 0;
132 }
133
134 // Make structure
135 *c = malloc(sizeof(corlett_t));
136 if (!(*c))
137 {
138 free(decomp_dat);
139 return AO_FAIL;
140 }
141 memset(*c, 0, sizeof(corlett_t));
142 strcpy((*c)->inf_title, "n/a");
143 strcpy((*c)->inf_copy, "n/a");
144 strcpy((*c)->inf_artist, "n/a");
145 strcpy((*c)->inf_game, "n/a");
146 strcpy((*c)->inf_year, "n/a");
147 strcpy((*c)->inf_length, "n/a");
148 strcpy((*c)->inf_fade, "n/a");
149
150 // set reserved section pointer
151 (*c)->res_section = &buf[4];
152 (*c)->res_size = res_area;
153
154 // Return it
155 *output = decomp_dat;
156 *size = decomp_length;
157
158 // Next check for tags
159 input_len -= (comp_length + 16 + res_area);
160 if (input_len < 5)
161 return AO_SUCCESS;
162
163 // printf("\n\nNew corlett: input len %d\n", input_len);
164
165 tag_dec = input + (comp_length + res_area + 16);
166 if ((tag_dec[0] == '[') && (tag_dec[1] == 'T') && (tag_dec[2] == 'A') && (tag_dec[3] == 'G') && (tag_dec[4] == ']'))
167 {
168 int tag, l, num_tags, data;
169
170 // Tags found!
171 tag_dec += 5;
172 input_len -= 5;
173
174 tag = 0;
175 data = false;
176 num_tags = 0;
177 l = 0;
178 while (input_len && (num_tags < MAX_UNKNOWN_TAGS))
179 {
180 if (data)
181 {
182 if ((*tag_dec == 0xA) || (*tag_dec == 0x00))
183 {
184 (*c)->tag_data[num_tags][l] = 0;
185 data = false;
186 num_tags++;
187 l = 0;
188 }
189 else
190 {
191 (*c)->tag_data[num_tags][l++] = *tag_dec;
192 }
193 }
194 else
195 {
196 if (*tag_dec == '=')
197 {
198 (*c)->tag_name[num_tags][l] = 0;
199 l = 0;
200 data = true;
201 }
202 else
203 {
204 (*c)->tag_name[num_tags][l++] = *tag_dec;
205 }
206 }
207
208 tag_dec++;
209 input_len--;
210 }
211
212
213 // Now, process that tag array into what we expect
214 for (num_tags = 0; num_tags < MAX_UNKNOWN_TAGS; num_tags++)
215 {
216 // See if tag belongs in one of the special fields we have
217 if (!strcasecmp((*c)->tag_name[num_tags], "_lib"))
218 {
219 strcpy((*c)->lib, (*c)->tag_data[num_tags]);
220 (*c)->tag_data[num_tags][0] = 0;
221 (*c)->tag_name[num_tags][0] = 0;
222 }
223 else if (!strncmp((*c)->tag_name[num_tags], "_lib2", 5))
224 {
225 strcpy((*c)->libaux[0], (*c)->tag_data[num_tags]);
226 (*c)->tag_data[num_tags][0] = 0;
227 (*c)->tag_name[num_tags][0] = 0;
228 }
229 else if (!strncmp((*c)->tag_name[num_tags], "_lib3", 5))
230 {
231 strcpy((*c)->libaux[1], (*c)->tag_data[num_tags]);
232 (*c)->tag_data[num_tags][0] = 0;
233 (*c)->tag_name[num_tags][0] = 0;
234 }
235 else if (!strncmp((*c)->tag_name[num_tags], "_lib4", 5))
236 {
237 strcpy((*c)->libaux[2], (*c)->tag_data[num_tags]);
238 (*c)->tag_data[num_tags][0] = 0;
239 (*c)->tag_name[num_tags][0] = 0;
240 }
241 else if (!strncmp((*c)->tag_name[num_tags], "_lib5", 5))
242 {
243 strcpy((*c)->libaux[3], (*c)->tag_data[num_tags]);
244 (*c)->tag_data[num_tags][0] = 0;
245 (*c)->tag_name[num_tags][0] = 0;
246 }
247 else if (!strncmp((*c)->tag_name[num_tags], "_lib6", 5))
248 {
249 strcpy((*c)->libaux[4], (*c)->tag_data[num_tags]);
250 (*c)->tag_data[num_tags][0] = 0;
251 (*c)->tag_name[num_tags][0] = 0;
252 }
253 else if (!strncmp((*c)->tag_name[num_tags], "_lib7", 5))
254 {
255 strcpy((*c)->libaux[5], (*c)->tag_data[num_tags]);
256 (*c)->tag_data[num_tags][0] = 0;
257 (*c)->tag_name[num_tags][0] = 0;
258 }
259 else if (!strncmp((*c)->tag_name[num_tags], "_lib8", 5))
260 {
261 strcpy((*c)->libaux[6], (*c)->tag_data[num_tags]);
262 (*c)->tag_data[num_tags][0] = 0;
263 (*c)->tag_name[num_tags][0] = 0;
264 }
265 else if (!strncmp((*c)->tag_name[num_tags], "_lib9", 5))
266 {
267 strcpy((*c)->libaux[7], (*c)->tag_data[num_tags]);
268 (*c)->tag_data[num_tags][0] = 0;
269 (*c)->tag_name[num_tags][0] = 0;
270 }
271 else if (!strncmp((*c)->tag_name[num_tags], "_refresh", 8))
272 {
273 strcpy((*c)->inf_refresh, (*c)->tag_data[num_tags]);
274 (*c)->tag_data[num_tags][0] = 0;
275 (*c)->tag_name[num_tags][0] = 0;
276 }
277 else if (!strncmp((*c)->tag_name[num_tags], "title", 5))
278 {
279 strcpy((*c)->inf_title, (*c)->tag_data[num_tags]);
280 (*c)->tag_data[num_tags][0] = 0;
281 (*c)->tag_name[num_tags][0] = 0;
282 }
283 else if (!strncmp((*c)->tag_name[num_tags], "copyright", 9))
284 {
285 strcpy((*c)->inf_copy, (*c)->tag_data[num_tags]);
286 (*c)->tag_data[num_tags][0] = 0;
287 (*c)->tag_name[num_tags][0] = 0;
288 }
289 else if (!strncmp((*c)->tag_name[num_tags], "artist", 6))
290 {
291 strcpy((*c)->inf_artist, (*c)->tag_data[num_tags]);
292 (*c)->tag_data[num_tags][0] = 0;
293 (*c)->tag_name[num_tags][0] = 0;
294 }
295 else if (!strncmp((*c)->tag_name[num_tags], "game", 4))
296 {
297 strcpy((*c)->inf_game, (*c)->tag_data[num_tags]);
298 (*c)->tag_data[num_tags][0] = 0;
299 (*c)->tag_name[num_tags][0] = 0;
300 }
301 else if (!strncmp((*c)->tag_name[num_tags], "year", 4))
302 {
303 strcpy((*c)->inf_year, (*c)->tag_data[num_tags]);
304 (*c)->tag_data[num_tags][0] = 0;
305 (*c)->tag_name[num_tags][0] = 0;
306 }
307 else if (!strncmp((*c)->tag_name[num_tags], "length", 6))
308 {
309 strcpy((*c)->inf_length, (*c)->tag_data[num_tags]);
310 (*c)->tag_data[num_tags][0] = 0;
311 (*c)->tag_name[num_tags][0] = 0;
312 }
313 else if (!strncmp((*c)->tag_name[num_tags], "fade", 4))
314 {
315 strcpy((*c)->inf_fade, (*c)->tag_data[num_tags]);
316 (*c)->tag_data[num_tags][0] = 0;
317 (*c)->tag_name[num_tags][0] = 0;
318 }
319 }
320 }
321
322 // Bingo
323 return AO_SUCCESS;
324 }
325
psfTimeToMS(char * str)326 uint32 psfTimeToMS(char *str)
327 {
328 int x, c=0;
329 uint32 acc=0;
330 char s[100];
331
332 strncpy(s,str,100);
333 s[99]=0;
334
335 for (x=strlen(s); x>=0; x--)
336 {
337 if (s[x]=='.' || s[x]==',')
338 {
339 acc=atoi(s+x+1);
340 s[x]=0;
341 }
342 else if (s[x]==':')
343 {
344 if(c==0)
345 {
346 acc+=atoi(s+x+1)*10;
347 }
348 else if(c==1)
349 {
350 acc+=atoi(s+x+(x?1:0))*10*60;
351 }
352
353 c++;
354 s[x]=0;
355 }
356 else if (x==0)
357 {
358 if(c==0)
359 {
360 acc+=atoi(s+x)*10;
361 }
362 else if(c==1)
363 {
364 acc+=atoi(s+x)*10*60;
365 }
366 else if(c==2)
367 {
368 acc+=atoi(s+x)*10*60*60;
369 }
370 }
371 }
372
373 acc*=100;
374 return(acc);
375 }
376
377