#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "ao.h"
#include "corlett.h"
#include <zlib.h>
#include <stdlib.h>
#define DECOMP_MAX_SIZE ((32 * 1024 * 1024) + 12)
int corlett_decode(uint8 *input, uint32 input_len, uint8 **output, uint64 *size, corlett_t **c)
{
uint32 *buf;
uint32 res_area, comp_crc, actual_crc;
uint8 *decomp_dat, *tag_dec;
uLongf decomp_length, comp_length;
buf = (uint32 *)input;
if ((input[0] != 'P') || (input[1] != 'S') || (input[2] != 'F'))
{
return AO_FAIL;
}
res_area = LE32(buf[1]);
comp_length = LE32(buf[2]);
comp_crc = LE32(buf[3]);
if (comp_length > 0)
{
if (input_len < comp_length + 16)
return AO_FAIL;
actual_crc = crc32(0, (unsigned char *)&buf[4+(res_area/4)], comp_length);
if (actual_crc != comp_crc)
return AO_FAIL;
decomp_dat = malloc(DECOMP_MAX_SIZE);
decomp_length = DECOMP_MAX_SIZE;
if (uncompress(decomp_dat, &decomp_length, (unsigned char *)&buf[4+(res_area/4)], comp_length) != Z_OK)
{
free(decomp_dat);
return AO_FAIL;
}
decomp_dat = realloc(decomp_dat, (size_t)decomp_length + 1);
}
else
{
decomp_dat = NULL;
decomp_length = 0;
}
*c = malloc(sizeof(corlett_t));
if (!(*c))
{
free(decomp_dat);
return AO_FAIL;
}
memset(*c, 0, sizeof(corlett_t));
strcpy((*c)->inf_title, "n/a");
strcpy((*c)->inf_copy, "n/a");
strcpy((*c)->inf_artist, "n/a");
strcpy((*c)->inf_game, "n/a");
strcpy((*c)->inf_year, "n/a");
strcpy((*c)->inf_length, "n/a");
strcpy((*c)->inf_fade, "n/a");
(*c)->res_section = &buf[4];
(*c)->res_size = res_area;
*output = decomp_dat;
*size = decomp_length;
input_len -= (comp_length + 16 + res_area);
if (input_len < 5)
return AO_SUCCESS;
tag_dec = input + (comp_length + res_area + 16);
if ((tag_dec[0] == '[') && (tag_dec[1] == 'T') && (tag_dec[2] == 'A') && (tag_dec[3] == 'G') && (tag_dec[4] == ']'))
{
int tag, l, num_tags, data;
tag_dec += 5;
input_len -= 5;
tag = 0;
data = false;
num_tags = 0;
l = 0;
while (input_len && (num_tags < MAX_UNKNOWN_TAGS))
{
if (data)
{
if ((*tag_dec == 0xA) || (*tag_dec == 0x00))
{
(*c)->tag_data[num_tags][l] = 0;
data = false;
num_tags++;
l = 0;
}
else
{
(*c)->tag_data[num_tags][l++] = *tag_dec;
}
}
else
{
if (*tag_dec == '=')
{
(*c)->tag_name[num_tags][l] = 0;
l = 0;
data = true;
}
else
{
(*c)->tag_name[num_tags][l++] = *tag_dec;
}
}
tag_dec++;
input_len--;
}
for (num_tags = 0; num_tags < MAX_UNKNOWN_TAGS; num_tags++)
{
if (!strcasecmp((*c)->tag_name[num_tags], "_lib"))
{
strcpy((*c)->lib, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_lib2", 5))
{
strcpy((*c)->libaux[0], (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_lib3", 5))
{
strcpy((*c)->libaux[1], (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_lib4", 5))
{
strcpy((*c)->libaux[2], (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_lib5", 5))
{
strcpy((*c)->libaux[3], (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_lib6", 5))
{
strcpy((*c)->libaux[4], (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_lib7", 5))
{
strcpy((*c)->libaux[5], (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_lib8", 5))
{
strcpy((*c)->libaux[6], (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_lib9", 5))
{
strcpy((*c)->libaux[7], (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "_refresh", 8))
{
strcpy((*c)->inf_refresh, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "title", 5))
{
strcpy((*c)->inf_title, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "copyright", 9))
{
strcpy((*c)->inf_copy, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "artist", 6))
{
strcpy((*c)->inf_artist, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "game", 4))
{
strcpy((*c)->inf_game, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "year", 4))
{
strcpy((*c)->inf_year, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "length", 6))
{
strcpy((*c)->inf_length, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
else if (!strncmp((*c)->tag_name[num_tags], "fade", 4))
{
strcpy((*c)->inf_fade, (*c)->tag_data[num_tags]);
(*c)->tag_data[num_tags][0] = 0;
(*c)->tag_name[num_tags][0] = 0;
}
}
}
return AO_SUCCESS;
}
uint32 psfTimeToMS(char *str)
{
int x, c=0;
uint32 acc=0;
char s[100];
strncpy(s,str,100);
s[99]=0;
for (x=strlen(s); x>=0; x--)
{
if (s[x]=='.' || s[x]==',')
{
acc=atoi(s+x+1);
s[x]=0;
}
else if (s[x]==':')
{
if(c==0)
{
acc+=atoi(s+x+1)*10;
}
else if(c==1)
{
acc+=atoi(s+x+(x?1:0))*10*60;
}
c++;
s[x]=0;
}
else if (x==0)
{
if(c==0)
{
acc+=atoi(s+x)*10;
}
else if(c==1)
{
acc+=atoi(s+x)*10*60;
}
else if(c==2)
{
acc+=atoi(s+x)*10*60*60;
}
}
}
acc*=100;
return(acc);
}