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