1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
#include "lzh/lzh.h"
struct __attribute__((packed)) pymHeader
{
char id[4]; /* YM2!, YM3!, YM3b, //YM4!, YM5!, YM6! */
char mark[8]; /* LeOnArD!, YM5!, YM6! */
uint32_t nb_frame; /* YM5!, YM6! */
uint32_t attributes; /* YM5!, YM6! */
uint16_t nb_drum; /* YM5!, YM6! */
uint32_t clock; /* YM5!, YM6! */
uint16_t rate; /* YM5!, YM6! */
uint32_t loopframe; /* YM5!, YM6! */
uint16_t skip; /* YM5!, YM6! */
/* skip bytes of data if YM5!, YM6!
nb_drums {
uint32_t size;
size bytes of data;
}
char *song_name;
char *song_author;
char *song_comment;
data
uint32_t loopframe at EOF-4 for YM3b */
};
struct __attribute__((packed)) pmixHeader
{
char id[4]; /* MIX1 */
char mark[8]; /* LeOnArD! */
uint32_t attribute;
uint32_t sample_size;
uint32_t nb_mix_block;
/*
nb_mix_block {
uint32_t samplestart;
uint32_t samplelength;
uint16_t nbRepeat;
uint16_t replayFreq;
}
char *song_name;
char *song_author;
char *song_comment;
sample_size data;
*/
};
struct __attribute__((packed)) pymtHeader
{
char id[4]; /* YMT1, YMT2 */
char mark[8]; /* LeOnArD! */
uint16_t nb_voices;
uint16_t player_rate;
uint32_t music_length;
uint32_t music_loop;
uint16_t nb_digidrum;
uint32_t flags;
/*
char *music_name;
char *music_author;
char *music_comment;
data */
};
struct __attribute__((packed)) lzhHeader
{
uint8_t size;
uint8_t sum;
char id[5]; /* -lh5- */
uint32_t packed;
uint32_t original;
char reserved[5];
uint8_t level;
uint8_t name_length;
};
static char ex_buf[1024*1024*16];
static int Try_LH5(const char *mem, size_t len)
{
struct lzhHeader *h= (struct lzhHeader *)mem;
if (len<sizeof(lzhHeader))
{
return 0;
}
if (strcmp (h->id, "-lh5-", 5))
{
return 0;
}
printf ("[%sLHA compression%s]\n", FONT_BRIGHT_CYAN, FONT_RESET);
DumpPrefix (mem, len, 0x00, 1);
if (h->size)
{
printf ("size: %s%d%s ??\n", FONT_BRIGHT_GREEN, h->size, FONT_RESET);
} else {
printf ("size: %s%d # must be ZERO%s\n", FONT_BRIGHT_RED, h->size, FONT_RESET);
}
DumpPrefix (mem, len, 0x01, 1);
printf ("checksum: 0x%02x", h->sum);
DumpPrefix (mem, len, 0x02, 5);
printf ("id: %s\"%c%c%c%c%c\"%s\n", FONT_BRIGHT_GREEN, h->id[0], h->id[1], h->id[2], h->id[3], h->id[4], FONT_RESET);
DumpPrefix (mem, len, 0x07, 4);
printf ("packed: %u (size after compression)\n", (unsigned int)uint32_little(h->packed));
DumpPrefix (mem, len, 0x0b, 4);
printf ("original: %u (size before compression)\n", (unsigned int)uint32_little(h->original));
DumpPrefix (mem, len, 0x0f, 5);
printf ("Reserved\n");
DumpPrefix (mem, len, 0x14, 1);
if (!h->level)
{
printf ("level: %s%d%s\n", FONT_BRIGHT_GREEN, h->level, FONT_RESET);
} else {
printf ("level: %s%d # must be zero %s\n", FONT_BRIGHT_RED, h->level, FONT_RESET);
}
DumpPrefix (mem, len, 0x15, 1);
printf ("namelength: %d\n", h->namelength);
if ((h->size==0)||(h->level!=0))
{
return -1;
}
{
uint32_t fileSize = uint32_little(h->original);
uint32_t packedSize = uint32_little(h->packed)-2;
if (len < (sizeof(*h) + h->name_length + packedSize + 2))
{
printf ("%sFile does not contain complete data as specified by packetSize%s\n", FONT_BRIGHT_RED, FONT_RESET);
return -1;
}
{
CLzhDepacker *pDepacker = new CLzhDepacker;
const bool bRet = pDepacker->LzUnpack(mem + sizeof(*h) + h->name_length + 2, packedSize, ex_buf, fileSize);
delete pDepacker;
if (!bRet)
{
printf ("%sDECOMPRESSION FAILED%s\n", FONT_BRIGHT_RED, FONT_RESET);
return -1;
}
}
ParseYMFile (ex_buf, fileSize);
}
return 1;
}
|