mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-13 18:20:50 +01:00
Fix ciph-1 HCA and add errors [DQ Monsters: Super Light (Mobile)]
This commit is contained in:
parent
7b0e18171d
commit
0c53449df1
@ -26,7 +26,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
|
||||||
#define HCA_MASK 0x7F7F7F7F /* chunk obfuscation when the HCA is encrypted (ciph type > 0) */
|
#define HCA_MASK 0x7F7F7F7F /* chunk obfuscation when the HCA is encrypted with key */
|
||||||
#define HCA_SUBFRAMES_PER_FRAME 8
|
#define HCA_SUBFRAMES_PER_FRAME 8
|
||||||
#define HCA_SAMPLES_PER_SUBFRAME 128
|
#define HCA_SAMPLES_PER_SUBFRAME 128
|
||||||
#define HCA_SAMPLES_PER_FRAME (HCA_SUBFRAMES_PER_FRAME*HCA_SAMPLES_PER_SUBFRAME)
|
#define HCA_SAMPLES_PER_FRAME (HCA_SUBFRAMES_PER_FRAME*HCA_SAMPLES_PER_SUBFRAME)
|
||||||
@ -34,6 +34,13 @@
|
|||||||
|
|
||||||
#define HCA_MAX_CHANNELS 16 /* internal max? in practice only 8 can be encoded */
|
#define HCA_MAX_CHANNELS 16 /* internal max? in practice only 8 can be encoded */
|
||||||
|
|
||||||
|
#define HCA_ERROR_PARAMS -1
|
||||||
|
#define HCA_ERROR_HEADER -2
|
||||||
|
#define HCA_ERROR_CHECKSUM -3
|
||||||
|
#define HCA_ERROR_SYNC -4
|
||||||
|
#define HCA_ERROR_UNPACK -5
|
||||||
|
#define HCA_ERROR_BITREADER -6
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// Decoder config/state
|
// Decoder config/state
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -239,7 +246,7 @@ int clHCA_isOurFile(const void *data, unsigned int size) {
|
|||||||
unsigned int header_size = 0;
|
unsigned int header_size = 0;
|
||||||
|
|
||||||
if (!data || size < 0x08)
|
if (!data || size < 0x08)
|
||||||
return -1;
|
return HCA_ERROR_PARAMS;
|
||||||
|
|
||||||
bitreader_init(&br, data, 8);
|
bitreader_init(&br, data, 8);
|
||||||
if ((bitreader_peek(&br, 32) & HCA_MASK) == 0x48434100) {/*'HCA\0'*/
|
if ((bitreader_peek(&br, 32) & HCA_MASK) == 0x48434100) {/*'HCA\0'*/
|
||||||
@ -248,13 +255,13 @@ int clHCA_isOurFile(const void *data, unsigned int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (header_size == 0)
|
if (header_size == 0)
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
return header_size;
|
return header_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int clHCA_getInfo(clHCA *hca, clHCA_stInfo *info) {
|
int clHCA_getInfo(clHCA *hca, clHCA_stInfo *info) {
|
||||||
if (!hca || !info || !hca->is_valid)
|
if (!hca || !info || !hca->is_valid)
|
||||||
return -1;
|
return HCA_ERROR_PARAMS;
|
||||||
|
|
||||||
info->version = hca->version;
|
info->version = hca->version;
|
||||||
info->headerSize = hca->header_size;
|
info->headerSize = hca->header_size;
|
||||||
@ -424,7 +431,7 @@ static int ath_init(unsigned char *ath_curve, int type, unsigned int sample_rate
|
|||||||
ath_init1(ath_curve, sample_rate);
|
ath_init1(ath_curve, sample_rate);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -455,7 +462,7 @@ static void cipher_init1(unsigned char *cipher_table) {
|
|||||||
const int add = 11;
|
const int add = 11;
|
||||||
unsigned int i, v = 0;
|
unsigned int i, v = 0;
|
||||||
|
|
||||||
/* keyless encryption (unused?) */
|
/* keyless encryption (rare) */
|
||||||
for (i = 1; i < 256 - 1; i++) {
|
for (i = 1; i < 256 - 1; i++) {
|
||||||
v = (v * mul + add) & 0xFF;
|
v = (v * mul + add) & 0xFF;
|
||||||
if (v == 0 || v == 0xFF)
|
if (v == 0 || v == 0xFF)
|
||||||
@ -542,7 +549,7 @@ static void cipher_init56(unsigned char *cipher_table, unsigned long long keycod
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cipher_init(unsigned char *cipher_table, int type, unsigned long long keycode) {
|
static int cipher_init(unsigned char *cipher_table, int type, unsigned long long keycode) {
|
||||||
if (!(keycode))
|
if (type == 56 && !(keycode))
|
||||||
type = 0;
|
type = 0;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -556,7 +563,7 @@ static int cipher_init(unsigned char *cipher_table, int type, unsigned long long
|
|||||||
cipher_init56(cipher_table, keycode);
|
cipher_init56(cipher_table, keycode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -570,14 +577,15 @@ static unsigned int header_ceil2(unsigned int a, unsigned int b) {
|
|||||||
|
|
||||||
int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
||||||
clData br;
|
clData br;
|
||||||
|
int res;
|
||||||
|
|
||||||
if (!hca || !data )
|
if (!hca || !data)
|
||||||
return -1;
|
return HCA_ERROR_PARAMS;
|
||||||
|
|
||||||
hca->is_valid = 0;
|
hca->is_valid = 0;
|
||||||
|
|
||||||
if (size < 0x08)
|
if (size < 0x08)
|
||||||
return -1;
|
return HCA_ERROR_PARAMS;
|
||||||
|
|
||||||
bitreader_init(&br, data, size);
|
bitreader_init(&br, data, size);
|
||||||
|
|
||||||
@ -594,18 +602,18 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
hca->version != 0x0102 &&
|
hca->version != 0x0102 &&
|
||||||
hca->version != 0x0103 &&
|
hca->version != 0x0103 &&
|
||||||
hca->version != 0x0200)
|
hca->version != 0x0200)
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
#endif
|
#endif
|
||||||
if (size < hca->header_size)
|
if (size < hca->header_size)
|
||||||
return -1;
|
return HCA_ERROR_PARAMS;
|
||||||
|
|
||||||
if (crc16_checksum(data,hca->header_size))
|
if (crc16_checksum(data,hca->header_size))
|
||||||
return -1;
|
return HCA_ERROR_CHECKSUM;
|
||||||
|
|
||||||
size -= 0x08;
|
size -= 0x08;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* format info */
|
/* format info */
|
||||||
@ -618,18 +626,18 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
hca->encoder_padding = bitreader_read(&br, 16);
|
hca->encoder_padding = bitreader_read(&br, 16);
|
||||||
|
|
||||||
if (!(hca->channels >= 1 && hca->channels <= HCA_MAX_CHANNELS))
|
if (!(hca->channels >= 1 && hca->channels <= HCA_MAX_CHANNELS))
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
if (hca->frame_count == 0)
|
if (hca->frame_count == 0)
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
if (!(hca->sample_rate >= 1 && hca->sample_rate <= 0x7FFFFF)) /* encoder max seems 48000 */
|
if (!(hca->sample_rate >= 1 && hca->sample_rate <= 0x7FFFFF)) /* encoder max seems 48000 */
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
size -= 0x10;
|
size -= 0x10;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compression (v2.0) or decode (v1.x) info */
|
/* compression (v2.0) or decode (v1.x) info */
|
||||||
@ -668,7 +676,7 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
size -= 0x0c;
|
size -= 0x0c;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VBR (variable bit rate) info */
|
/* VBR (variable bit rate) info */
|
||||||
@ -678,7 +686,7 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
hca->vbr_noise_Level = bitreader_read(&br, 16);
|
hca->vbr_noise_Level = bitreader_read(&br, 16);
|
||||||
|
|
||||||
if (!(hca->frame_size == 0 && hca->vbr_max_frame_size > 8 && hca->vbr_max_frame_size <= 0x1FF))
|
if (!(hca->frame_size == 0 && hca->vbr_max_frame_size > 8 && hca->vbr_max_frame_size <= 0x1FF))
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
size -= 0x08;
|
size -= 0x08;
|
||||||
}
|
}
|
||||||
@ -710,7 +718,7 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
|
|
||||||
if (!(hca->loop_start_frame >= 0 && hca->loop_start_frame <= hca->loop_end_frame
|
if (!(hca->loop_start_frame >= 0 && hca->loop_start_frame <= hca->loop_end_frame
|
||||||
&& hca->loop_end_frame < hca->frame_count))
|
&& hca->loop_end_frame < hca->frame_count))
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
size -= 0x10;
|
size -= 0x10;
|
||||||
}
|
}
|
||||||
@ -729,7 +737,7 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
hca->ciph_type = bitreader_read(&br, 16);
|
hca->ciph_type = bitreader_read(&br, 16);
|
||||||
|
|
||||||
if (!(hca->ciph_type == 0 || hca->ciph_type == 1 || hca->ciph_type == 56))
|
if (!(hca->ciph_type == 0 || hca->ciph_type == 1 || hca->ciph_type == 56))
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
size -= 0x06;
|
size -= 0x06;
|
||||||
}
|
}
|
||||||
@ -760,11 +768,11 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
hca->comment_len = bitreader_read(&br, 8);
|
hca->comment_len = bitreader_read(&br, 8);
|
||||||
|
|
||||||
if (hca->comment_len > size)
|
if (hca->comment_len > size)
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
temp = realloc(hca->comment, hca->comment_len + 1);
|
temp = realloc(hca->comment, hca->comment_len + 1);
|
||||||
if (!temp)
|
if (!temp)
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
hca->comment = temp;
|
hca->comment = temp;
|
||||||
for (i = 0; i < hca->comment_len; ++i)
|
for (i = 0; i < hca->comment_len; ++i)
|
||||||
hca->comment[i] = bitreader_read(&br, 8);
|
hca->comment[i] = bitreader_read(&br, 8);
|
||||||
@ -782,17 +790,17 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
size -= (size - 0x02); /* fills up to header_size, sans checksum */
|
size -= (size - 0x02); /* fills up to header_size, sans checksum */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* should be fully read, but allow data buffer may be bigger than header_size */
|
/* should be fully read, but allow as data buffer may be bigger than header_size */
|
||||||
//if (size != 0x02)
|
//if (size != 0x02)
|
||||||
// return -1;
|
// return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
|
|
||||||
/* extra validations */
|
/* extra validations */
|
||||||
if (!(hca->frame_size >= 0x08 && hca->frame_size <= 0xFFFF)) /* actual max seems 0x155*channels */
|
if (!(hca->frame_size >= 0x08 && hca->frame_size <= 0xFFFF)) /* actual max seems 0x155*channels */
|
||||||
return -1; /* theoretically can be 0 if VBR (not seen) */
|
return HCA_ERROR_HEADER; /* theoretically can be 0 if VBR (not seen) */
|
||||||
|
|
||||||
if (!(hca->min_resolution == 1 && hca->max_resolution == 15))
|
if (!(hca->min_resolution == 1 && hca->max_resolution == 15))
|
||||||
return -1;
|
return HCA_ERROR_HEADER;
|
||||||
|
|
||||||
|
|
||||||
/* inits state */
|
/* inits state */
|
||||||
@ -803,10 +811,12 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
|
|||||||
hca->total_band_count - hca->base_band_count - hca->stereo_band_count,
|
hca->total_band_count - hca->base_band_count - hca->stereo_band_count,
|
||||||
hca->bands_per_hfr_group);
|
hca->bands_per_hfr_group);
|
||||||
|
|
||||||
if (ath_init(hca->ath_curve, hca->ath_type, hca->sample_rate) < 0)
|
res = ath_init(hca->ath_curve, hca->ath_type, hca->sample_rate);
|
||||||
return -1;
|
if (res < 0)
|
||||||
if (cipher_init(hca->cipher_table, hca->ciph_type, hca->keycode) < 0)
|
return res;
|
||||||
return -1;
|
res = cipher_init(hca->cipher_table, hca->ciph_type, hca->keycode);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
|
||||||
/* init channels */
|
/* init channels */
|
||||||
@ -1002,19 +1012,19 @@ int clHCA_DecodeBlock(clHCA *hca, void *data, unsigned int size) {
|
|||||||
unsigned int subframe, ch;
|
unsigned int subframe, ch;
|
||||||
|
|
||||||
if (!data || !hca || !hca->is_valid)
|
if (!data || !hca || !hca->is_valid)
|
||||||
return -1;
|
return HCA_ERROR_PARAMS;
|
||||||
if (size < hca->frame_size)
|
if (size < hca->frame_size)
|
||||||
return -1;
|
return HCA_ERROR_PARAMS;
|
||||||
|
|
||||||
bitreader_init(&br, data, hca->frame_size);
|
bitreader_init(&br, data, hca->frame_size);
|
||||||
|
|
||||||
/* test sync (not encrypted) */
|
/* test sync (not encrypted) */
|
||||||
sync = bitreader_read(&br, 16);
|
sync = bitreader_read(&br, 16);
|
||||||
if (sync != 0xFFFF)
|
if (sync != 0xFFFF)
|
||||||
return -1;
|
return HCA_ERROR_SYNC;
|
||||||
|
|
||||||
if (crc16_checksum(data, hca->frame_size))
|
if (crc16_checksum(data, hca->frame_size))
|
||||||
return -1;
|
return HCA_ERROR_CHECKSUM;
|
||||||
|
|
||||||
cipher_decrypt(hca->cipher_table, data, hca->frame_size);
|
cipher_decrypt(hca->cipher_table, data, hca->frame_size);
|
||||||
|
|
||||||
@ -1029,7 +1039,7 @@ int clHCA_DecodeBlock(clHCA *hca, void *data, unsigned int size) {
|
|||||||
int unpack = decode1_unpack_channel(&hca->channel[ch], &br,
|
int unpack = decode1_unpack_channel(&hca->channel[ch], &br,
|
||||||
hca->hfr_group_count, packed_noise_level, hca->ath_curve);
|
hca->hfr_group_count, packed_noise_level, hca->ath_curve);
|
||||||
if (unpack < 0)
|
if (unpack < 0)
|
||||||
return -1;
|
return unpack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,9 +1070,8 @@ int clHCA_DecodeBlock(clHCA *hca, void *data, unsigned int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* should read all frame sans checksum at most */
|
/* should read all frame sans checksum at most */
|
||||||
if (br.bit > br.size - 16) {
|
if (br.bit > br.size - 16)
|
||||||
return -1;
|
return HCA_ERROR_BITREADER;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1132,7 +1141,7 @@ static int decode1_unpack_channel(stChannel *ch, clData *br,
|
|||||||
/* may happen with bad keycodes, scalefactors must be 6b indexes */
|
/* may happen with bad keycodes, scalefactors must be 6b indexes */
|
||||||
int scalefactor_test = (int)scalefactor_prev + ((int)delta - (int)extra_delta);
|
int scalefactor_test = (int)scalefactor_prev + ((int)delta - (int)extra_delta);
|
||||||
if (scalefactor_test < 0 || scalefactor_test > 64) {
|
if (scalefactor_test < 0 || scalefactor_test > 64) {
|
||||||
return -1;
|
return HCA_ERROR_UNPACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
scalefactor_prev += delta - extra_delta;
|
scalefactor_prev += delta - extra_delta;
|
||||||
@ -1160,7 +1169,7 @@ static int decode1_unpack_channel(stChannel *ch, clData *br,
|
|||||||
}
|
}
|
||||||
/* 15 may be an invalid value? */
|
/* 15 may be an invalid value? */
|
||||||
//else {
|
//else {
|
||||||
// return -1;
|
// return HCA_ERROR_INSENSITY;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
Reference in New Issue
Block a user