
#include <math.h>

#include "Layer3Decoder.h"

static unsigned long g_huffman_table_1[7] = {
	0x00020001, 0x00000000, 0x00020001, 0x00000010, 0x00020001, 
	0x00000001, 0x00000011, 
};

static unsigned long g_huffman_table_2[17] = {
	0x00020001, 0x00000000, 0x00040001, 0x00020001, 0x00000010, 
	0x00000001, 0x00020001, 0x00000011, 0x00040001, 0x00020001, 
	0x00000020, 0x00000021, 0x00020001, 0x00000012, 0x00020001, 
	0x00000002, 0x00000022, 
};

static unsigned long g_huffman_table_3[17] = {
	0x00040001, 0x00020001, 0x00000000, 0x00000001, 0x00020001, 
	0x00000011, 0x00020001, 0x00000010, 0x00040001, 0x00020001, 
	0x00000020, 0x00000021, 0x00020001, 0x00000012, 0x00020001, 
	0x00000002, 0x00000022, 
};

static unsigned long g_huffman_table_5[31] = {
	0x00020001, 0x00000000, 0x00040001, 0x00020001, 0x00000010, 
	0x00000001, 0x00020001, 0x00000011, 0x00080001, 0x00040001, 
	0x00020001, 0x00000020, 0x00000002, 0x00020001, 0x00000021, 
	0x00000012, 0x00080001, 0x00040001, 0x00020001, 0x00000022, 
	0x00000030, 0x00020001, 0x00000003, 0x00000013, 0x00020001, 
	0x00000031, 0x00020001, 0x00000032, 0x00020001, 0x00000023, 
	0x00000033, 
};

static unsigned long g_huffman_table_6[31] = {
	0x00060001, 0x00040001, 0x00020001, 0x00000000, 0x00000010, 
	0x00000011, 0x00060001, 0x00020001, 0x00000001, 0x00020001, 
	0x00000020, 0x00000021, 0x00060001, 0x00020001, 0x00000012, 
	0x00020001, 0x00000002, 0x00000022, 0x00040001, 0x00020001, 
	0x00000031, 0x00000013, 0x00040001, 0x00020001, 0x00000030, 
	0x00000032, 0x00020001, 0x00000023, 0x00020001, 0x00000003, 
	0x00000033, 
};

static unsigned long g_huffman_table_7[71] = {
	0x00020001, 0x00000000, 0x00040001, 0x00020001, 0x00000010, 
	0x00000001, 0x00080001, 0x00020001, 0x00000011, 0x00040001, 
	0x00020001, 0x00000020, 0x00000002, 0x00000021, 0x00120001, 
	0x00060001, 0x00020001, 0x00000012, 0x00020001, 0x00000022, 
	0x00000030, 0x00040001, 0x00020001, 0x00000031, 0x00000013, 
	0x00040001, 0x00020001, 0x00000003, 0x00000032, 0x00020001, 
	0x00000023, 0x00000004, 0x000a0001, 0x00040001, 0x00020001, 
	0x00000040, 0x00000041, 0x00020001, 0x00000014, 0x00020001, 
	0x00000042, 0x00000024, 0x000c0001, 0x00060001, 0x00040001, 
	0x00020001, 0x00000033, 0x00000043, 0x00000050, 0x00040001, 
	0x00020001, 0x00000034, 0x00000005, 0x00000051, 0x00060001, 
	0x00020001, 0x00000015, 0x00020001, 0x00000052, 0x00000025, 
	0x00040001, 0x00020001, 0x00000044, 0x00000035, 0x00040001, 
	0x00020001, 0x00000053, 0x00000054, 0x00020001, 0x00000045, 
	0x00000055, 
};

static unsigned long g_huffman_table_8[71] = {
	0x00060001, 0x00020001, 0x00000000, 0x00020001, 0x00000010, 
	0x00000001, 0x00020001, 0x00000011, 0x00040001, 0x00020001, 
	0x00000021, 0x00000012, 0x000e0001, 0x00040001, 0x00020001, 
	0x00000020, 0x00000002, 0x00020001, 0x00000022, 0x00040001, 
	0x00020001, 0x00000030, 0x00000003, 0x00020001, 0x00000031, 
	0x00000013, 0x000e0001, 0x00080001, 0x00040001, 0x00020001, 
	0x00000032, 0x00000023, 0x00020001, 0x00000040, 0x00000004, 
	0x00020001, 0x00000041, 0x00020001, 0x00000014, 0x00000042, 
	0x000c0001, 0x00060001, 0x00020001, 0x00000024, 0x00020001, 
	0x00000033, 0x00000050, 0x00040001, 0x00020001, 0x00000043, 
	0x00000034, 0x00000051, 0x00060001, 0x00020001, 0x00000015, 
	0x00020001, 0x00000005, 0x00000052, 0x00060001, 0x00020001, 
	0x00000025, 0x00020001, 0x00000044, 0x00000035, 0x00020001, 
	0x00000053, 0x00020001, 0x00000045, 0x00020001, 0x00000054, 
	0x00000055, 
};

static unsigned long g_huffman_table_9[71] = {
	0x00080001, 0x00040001, 0x00020001, 0x00000000, 0x00000010, 
	0x00020001, 0x00000001, 0x00000011, 0x000a0001, 0x00040001, 
	0x00020001, 0x00000020, 0x00000021, 0x00020001, 0x00000012, 
	0x00020001, 0x00000002, 0x00000022, 0x000c0001, 0x00060001, 
	0x00040001, 0x00020001, 0x00000030, 0x00000003, 0x00000031, 
	0x00020001, 0x00000013, 0x00020001, 0x00000032, 0x00000023, 
	0x000c0001, 0x00040001, 0x00020001, 0x00000041, 0x00000014, 
	0x00040001, 0x00020001, 0x00000040, 0x00000033, 0x00020001, 
	0x00000042, 0x00000024, 0x000a0001, 0x00060001, 0x00040001, 
	0x00020001, 0x00000004, 0x00000050, 0x00000043, 0x00020001, 
	0x00000034, 0x00000051, 0x00080001, 0x00040001, 0x00020001, 
	0x00000015, 0x00000052, 0x00020001, 0x00000025, 0x00000044, 
	0x00060001, 0x00040001, 0x00020001, 0x00000005, 0x00000054, 
	0x00000053, 0x00020001, 0x00000035, 0x00020001, 0x00000045, 
	0x00000055, 
};

static unsigned long g_huffman_table_10[127] = {
	0x00020001, 0x00000000, 0x00040001, 0x00020001, 0x00000010, 
	0x00000001, 0x000a0001, 0x00020001, 0x00000011, 0x00040001, 
	0x00020001, 0x00000020, 0x00000002, 0x00020001, 0x00000021, 
	0x00000012, 0x001c0001, 0x00080001, 0x00040001, 0x00020001, 
	0x00000022, 0x00000030, 0x00020001, 0x00000031, 0x00000013, 
	0x00080001, 0x00040001, 0x00020001, 0x00000003, 0x00000032, 
	0x00020001, 0x00000023, 0x00000040, 0x00040001, 0x00020001, 
	0x00000041, 0x00000014, 0x00040001, 0x00020001, 0x00000004, 
	0x00000033, 0x00020001, 0x00000042, 0x00000024, 0x001c0001, 
	0x000a0001, 0x00060001, 0x00040001, 0x00020001, 0x00000050, 
	0x00000005, 0x00000060, 0x00020001, 0x00000061, 0x00000016, 
	0x000c0001, 0x00060001, 0x00040001, 0x00020001, 0x00000043, 
	0x00000034, 0x00000051, 0x00020001, 0x00000015, 0x00020001, 
	0x00000052, 0x00000025, 0x00040001, 0x00020001, 0x00000026, 
	0x00000036, 0x00000071, 0x00140001, 0x00080001, 0x00020001, 
	0x00000017, 0x00040001, 0x00020001, 0x00000044, 0x00000053, 
	0x00000006, 0x00060001, 0x00040001, 0x00020001, 0x00000035, 
	0x00000045, 0x00000062, 0x00020001, 0x00000070, 0x00020001, 
	0x00000007, 0x00000064, 0x000e0001, 0x00040001, 0x00020001, 
	0x00000072, 0x00000027, 0x00060001, 0x00020001, 0x00000063, 
	0x00020001, 0x00000054, 0x00000055, 0x00020001, 0x00000046, 
	0x00000073, 0x00080001, 0x00040001, 0x00020001, 0x00000037, 
	0x00000065, 0x00020001, 0x00000056, 0x00000074, 0x00060001, 
	0x00020001, 0x00000047, 0x00020001, 0x00000066, 0x00000075, 
	0x00040001, 0x00020001, 0x00000057, 0x00000076, 0x00020001, 
	0x00000067, 0x00000077, 
};

static unsigned long g_huffman_table_11[127] = {
	0x00060001, 0x00020001, 0x00000000, 0x00020001, 0x00000010, 
	0x00000001, 0x00080001, 0x00020001, 0x00000011, 0x00040001, 
	0x00020001, 0x00000020, 0x00000002, 0x00000012, 0x00180001, 
	0x00080001, 0x00020001, 0x00000021, 0x00020001, 0x00000022, 
	0x00020001, 0x00000030, 0x00000003, 0x00040001, 0x00020001, 
	0x00000031, 0x00000013, 0x00040001, 0x00020001, 0x00000032, 
	0x00000023, 0x00040001, 0x00020001, 0x00000040, 0x00000004, 
	0x00020001, 0x00000041, 0x00000014, 0x001e0001, 0x00100001, 
	0x000a0001, 0x00040001, 0x00020001, 0x00000042, 0x00000024, 
	0x00040001, 0x00020001, 0x00000033, 0x00000043, 0x00000050, 
	0x00040001, 0x00020001, 0x00000034, 0x00000051, 0x00000061, 
	0x00060001, 0x00020001, 0x00000016, 0x00020001, 0x00000006, 
	0x00000026, 0x00020001, 0x00000062, 0x00020001, 0x00000015, 
	0x00020001, 0x00000005, 0x00000052, 0x00100001, 0x000a0001, 
	0x00060001, 0x00040001, 0x00020001, 0x00000025, 0x00000044, 
	0x00000060, 0x00020001, 0x00000063, 0x00000036, 0x00040001, 
	0x00020001, 0x00000070, 0x00000017, 0x00000071, 0x00100001, 
	0x00060001, 0x00040001, 0x00020001, 0x00000007, 0x00000064, 
	0x00000072, 0x00020001, 0x00000027, 0x00040001, 0x00020001, 
	0x00000053, 0x00000035, 0x00020001, 0x00000054, 0x00000045, 
	0x000a0001, 0x00040001, 0x00020001, 0x00000046, 0x00000073, 
	0x00020001, 0x00000037, 0x00020001, 0x00000065, 0x00000056, 
	0x000a0001, 0x00060001, 0x00040001, 0x00020001, 0x00000055, 
	0x00000057, 0x00000074, 0x00020001, 0x00000047, 0x00000066, 
	0x00040001, 0x00020001, 0x00000075, 0x00000076, 0x00020001, 
	0x00000067, 0x00000077, 
};

static unsigned long g_huffman_table_12[127] = {
	0x000c0001, 0x00040001, 0x00020001, 0x00000010, 0x00000001, 
	0x00020001, 0x00000011, 0x00020001, 0x00000000, 0x00020001, 
	0x00000020, 0x00000002, 0x00100001, 0x00040001, 0x00020001, 
	0x00000021, 0x00000012, 0x00040001, 0x00020001, 0x00000022, 
	0x00000031, 0x00020001, 0x00000013, 0x00020001, 0x00000030, 
	0x00020001, 0x00000003, 0x00000040, 0x001a0001, 0x00080001, 
	0x00040001, 0x00020001, 0x00000032, 0x00000023, 0x00020001, 
	0x00000041, 0x00000033, 0x000a0001, 0x00040001, 0x00020001, 
	0x00000014, 0x00000042, 0x00020001, 0x00000024, 0x00020001, 
	0x00000004, 0x00000050, 0x00040001, 0x00020001, 0x00000043, 
	0x00000034, 0x00020001, 0x00000051, 0x00000015, 0x001c0001, 
	0x000e0001, 0x00080001, 0x00040001, 0x00020001, 0x00000052, 
	0x00000025, 0x00020001, 0x00000053, 0x00000035, 0x00040001, 
	0x00020001, 0x00000060, 0x00000016, 0x00000061, 0x00040001, 
	0x00020001, 0x00000062, 0x00000026, 0x00060001, 0x00040001, 
	0x00020001, 0x00000005, 0x00000006, 0x00000044, 0x00020001, 
	0x00000054, 0x00000045, 0x00120001, 0x000a0001, 0x00040001, 
	0x00020001, 0x00000063, 0x00000036, 0x00040001, 0x00020001, 
	0x00000070, 0x00000007, 0x00000071, 0x00040001, 0x00020001, 
	0x00000017, 0x00000064, 0x00020001, 0x00000046, 0x00000072, 
	0x000a0001, 0x00060001, 0x00020001, 0x00000027, 0x00020001, 
	0x00000055, 0x00000073, 0x00020001, 0x00000037, 0x00000056, 
	0x00080001, 0x00040001, 0x00020001, 0x00000065, 0x00000074, 
	0x00020001, 0x00000047, 0x00000066, 0x00040001, 0x00020001, 
	0x00000075, 0x00000057, 0x00020001, 0x00000076, 0x00020001, 
	0x00000067, 0x00000077, 
};

static unsigned long g_huffman_table_13[511] = {
	0x00020001, 0x00000000, 0x00060001, 0x00020001, 0x00000010, 
	0x00020001, 0x00000001, 0x00000011, 0x001c0001, 0x00080001, 
	0x00040001, 0x00020001, 0x00000020, 0x00000002, 0x00020001, 
	0x00000021, 0x00000012, 0x00080001, 0x00040001, 0x00020001, 
	0x00000022, 0x00000030, 0x00020001, 0x00000003, 0x00000031, 
	0x00060001, 0x00020001, 0x00000013, 0x00020001, 0x00000032, 
	0x00000023, 0x00040001, 0x00020001, 0x00000040, 0x00000004, 
	0x00000041, 0x00460001, 0x001c0001, 0x000e0001, 0x00060001, 
	0x00020001, 0x00000014, 0x00020001, 0x00000033, 0x00000042, 
	0x00040001, 0x00020001, 0x00000024, 0x00000050, 0x00020001, 
	0x00000043, 0x00000034, 0x00040001, 0x00020001, 0x00000051, 
	0x00000015, 0x00040001, 0x00020001, 0x00000005, 0x00000052, 
	0x00020001, 0x00000025, 0x00020001, 0x00000044, 0x00000053, 
	0x000e0001, 0x00080001, 0x00040001, 0x00020001, 0x00000060, 
	0x00000006, 0x00020001, 0x00000061, 0x00000016, 0x00040001, 
	0x00020001, 0x00000080, 0x00000008, 0x00000081, 0x00100001, 
	0x00080001, 0x00040001, 0x00020001, 0x00000035, 0x00000062, 
	0x00020001, 0x00000026, 0x00000054, 0x00040001, 0x00020001, 
	0x00000045, 0x00000063, 0x00020001, 0x00000036, 0x00000070, 
	0x00060001, 0x00040001, 0x00020001, 0x00000007, 0x00000055, 
	0x00000071, 0x00020001, 0x00000017, 0x00020001, 0x00000027, 
	0x00000037, 0x00480001, 0x00180001, 0x000c0001, 0x00040001, 
	0x00020001, 0x00000018, 0x00000082, 0x00020001, 0x00000028, 
	0x00040001, 0x00020001, 0x00000064, 0x00000046, 0x00000072, 
	0x00080001, 0x00040001, 0x00020001, 0x00000084, 0x00000048, 
	0x00020001, 0x00000090, 0x00000009, 0x00020001, 0x00000091, 
	0x00000019, 0x00180001, 0x000e0001, 0x00080001, 0x00040001, 
	0x00020001, 0x00000073, 0x00000065, 0x00020001, 0x00000056, 
	0x00000074, 0x00040001, 0x00020001, 0x00000047, 0x00000066, 
	0x00000083, 0x00060001, 0x00020001, 0x00000038, 0x00020001, 
	0x00000075, 0x00000057, 0x00020001, 0x00000092, 0x00000029, 
	0x000e0001, 0x00080001, 0x00040001, 0x00020001, 0x00000067, 
	0x00000085, 0x00020001, 0x00000058, 0x00000039, 0x00020001, 
	0x00000093, 0x00020001, 0x00000049, 0x00000086, 0x00060001, 
	0x00020001, 0x000000a0, 0x00020001, 0x00000068, 0x0000000a, 
	0x00020001, 0x000000a1, 0x0000001a, 0x00440001, 0x00180001, 
	0x000c0001, 0x00040001, 0x00020001, 0x000000a2, 0x0000002a, 
	0x00040001, 0x00020001, 0x00000095, 0x00000059, 0x00020001, 
	0x000000a3, 0x0000003a, 0x00080001, 0x00040001, 0x00020001, 
	0x0000004a, 0x00000096, 0x00020001, 0x000000b0, 0x0000000b, 
	0x00020001, 0x000000b1, 0x0000001b, 0x00140001, 0x00080001, 
	0x00020001, 0x000000b2, 0x00040001, 0x00020001, 0x00000076, 
	0x00000077, 0x00000094, 0x00060001, 0x00040001, 0x00020001, 
	0x00000087, 0x00000078, 0x000000a4, 0x00040001, 0x00020001, 
	0x00000069, 0x000000a5, 0x0000002b, 0x000c0001, 0x00060001, 
	0x00040001, 0x00020001, 0x0000005a, 0x00000088, 0x000000b3, 
	0x00020001, 0x0000003b, 0x00020001, 0x00000079, 0x000000a6, 
	0x00060001, 0x00040001, 0x00020001, 0x0000006a, 0x000000b4, 
	0x000000c0, 0x00040001, 0x00020001, 0x0000000c, 0x00000098, 
	0x000000c1, 0x003c0001, 0x00160001, 0x000a0001, 0x00060001, 
	0x00020001, 0x0000001c, 0x00020001, 0x00000089, 0x000000b5, 
	0x00020001, 0x0000005b, 0x000000c2, 0x00040001, 0x00020001, 
	0x0000002c, 0x0000003c, 0x00040001, 0x00020001, 0x000000b6, 
	0x0000006b, 0x00020001, 0x000000c4, 0x0000004c, 0x00100001, 
	0x00080001, 0x00040001, 0x00020001, 0x000000a8, 0x0000008a, 
	0x00020001, 0x000000d0, 0x0000000d, 0x00020001, 0x000000d1, 
	0x00020001, 0x0000004b, 0x00020001, 0x00000097, 0x000000a7, 
	0x000c0001, 0x00060001, 0x00020001, 0x000000c3, 0x00020001, 
	0x0000007a, 0x00000099, 0x00040001, 0x00020001, 0x000000c5, 
	0x0000005c, 0x000000b7, 0x00040001, 0x00020001, 0x0000001d, 
	0x000000d2, 0x00020001, 0x0000002d, 0x00020001, 0x0000007b, 
	0x000000d3, 0x00340001, 0x001c0001, 0x000c0001, 0x00040001, 
	0x00020001, 0x0000003d, 0x000000c6, 0x00040001, 0x00020001, 
	0x0000006c, 0x000000a9, 0x00020001, 0x0000009a, 0x000000d4, 
	0x00080001, 0x00040001, 0x00020001, 0x000000b8, 0x0000008b, 
	0x00020001, 0x0000004d, 0x000000c7, 0x00040001, 0x00020001, 
	0x0000007c, 0x000000d5, 0x00020001, 0x0000005d, 0x000000e0, 
	0x000a0001, 0x00040001, 0x00020001, 0x000000e1, 0x0000001e, 
	0x00040001, 0x00020001, 0x0000000e, 0x0000002e, 0x000000e2, 
	0x00080001, 0x00040001, 0x00020001, 0x000000e3, 0x0000006d, 
	0x00020001, 0x0000008c, 0x000000e4, 0x00040001, 0x00020001, 
	0x000000e5, 0x000000ba, 0x000000f0, 0x00260001, 0x00100001, 
	0x00040001, 0x00020001, 0x000000f1, 0x0000001f, 0x00060001, 
	0x00040001, 0x00020001, 0x000000aa, 0x0000009b, 0x000000b9, 
	0x00020001, 0x0000003e, 0x00020001, 0x000000d6, 0x000000c8, 
	0x000c0001, 0x00060001, 0x00020001, 0x0000004e, 0x00020001, 
	0x000000d7, 0x0000007d, 0x00020001, 0x000000ab, 0x00020001, 
	0x0000005e, 0x000000c9, 0x00060001, 0x00020001, 0x0000000f, 
	0x00020001, 0x0000009c, 0x0000006e, 0x00020001, 0x000000f2, 
	0x0000002f, 0x00200001, 0x00100001, 0x00060001, 0x00040001, 
	0x00020001, 0x000000d8, 0x0000008d, 0x0000003f, 0x00060001, 
	0x00020001, 0x000000f3, 0x00020001, 0x000000e6, 0x000000ca, 
	0x00020001, 0x000000f4, 0x0000004f, 0x00080001, 0x00040001, 
	0x00020001, 0x000000bb, 0x000000ac, 0x00020001, 0x000000e7, 
	0x000000f5, 0x00040001, 0x00020001, 0x000000d9, 0x0000009d, 
	0x00020001, 0x0000005f, 0x000000e8, 0x001e0001, 0x000c0001, 
	0x00060001, 0x00020001, 0x0000006f, 0x00020001, 0x000000f6, 
	0x000000cb, 0x00040001, 0x00020001, 0x000000bc, 0x000000ad, 
	0x000000da, 0x00080001, 0x00020001, 0x000000f7, 0x00040001, 
	0x00020001, 0x0000007e, 0x0000007f, 0x0000008e, 0x00060001, 
	0x00040001, 0x00020001, 0x0000009e, 0x000000ae, 0x000000cc, 
	0x00020001, 0x000000f8, 0x0000008f, 0x00120001, 0x00080001, 
	0x00040001, 0x00020001, 0x000000db, 0x000000bd, 0x00020001, 
	0x000000ea, 0x000000f9, 0x00040001, 0x00020001, 0x0000009f, 
	0x000000eb, 0x00020001, 0x000000be, 0x00020001, 0x000000cd, 
	0x000000fa, 0x000e0001, 0x00040001, 0x00020001, 0x000000dd, 
	0x000000ec, 0x00060001, 0x00040001, 0x00020001, 0x000000e9, 
	0x000000af, 0x000000dc, 0x00020001, 0x000000ce, 0x000000fb, 
	0x00080001, 0x00040001, 0x00020001, 0x000000bf, 0x000000de, 
	0x00020001, 0x000000cf, 0x000000ee, 0x00040001, 0x00020001, 
	0x000000df, 0x000000ef, 0x00020001, 0x000000ff, 0x00020001, 
	0x000000ed, 0x00020001, 0x000000fd, 0x00020001, 0x000000fc, 
	0x000000fe, 
};

static unsigned long g_huffman_table_15[511] = {
	0x00100001, 0x00060001, 0x00020001, 0x00000000, 0x00020001, 
	0x00000010, 0x00000001, 0x00020001, 0x00000011, 0x00040001, 
	0x00020001, 0x00000020, 0x00000002, 0x00020001, 0x00000021, 
	0x00000012, 0x00320001, 0x00100001, 0x00060001, 0x00020001, 
	0x00000022, 0x00020001, 0x00000030, 0x00000031, 0x00060001, 
	0x00020001, 0x00000013, 0x00020001, 0x00000003, 0x00000040, 
	0x00020001, 0x00000032, 0x00000023, 0x000e0001, 0x00060001, 
	0x00040001, 0x00020001, 0x00000004, 0x00000014, 0x00000041, 
	0x00040001, 0x00020001, 0x00000033, 0x00000042, 0x00020001, 
	0x00000024, 0x00000043, 0x000a0001, 0x00060001, 0x00020001, 
	0x00000034, 0x00020001, 0x00000050, 0x00000005, 0x00020001, 
	0x00000051, 0x00000015, 0x00040001, 0x00020001, 0x00000052, 
	0x00000025, 0x00040001, 0x00020001, 0x00000044, 0x00000053, 
	0x00000061, 0x005a0001, 0x00240001, 0x00120001, 0x000a0001, 
	0x00060001, 0x00020001, 0x00000035, 0x00020001, 0x00000060, 
	0x00000006, 0x00020001, 0x00000016, 0x00000062, 0x00040001, 
	0x00020001, 0x00000026, 0x00000054, 0x00020001, 0x00000045, 
	0x00000063, 0x000a0001, 0x00060001, 0x00020001, 0x00000036, 
	0x00020001, 0x00000070, 0x00000007, 0x00020001, 0x00000071, 
	0x00000055, 0x00040001, 0x00020001, 0x00000017, 0x00000064, 
	0x00020001, 0x00000072, 0x00000027, 0x00180001, 0x00100001, 
	0x00080001, 0x00040001, 0x00020001, 0x00000046, 0x00000073, 
	0x00020001, 0x00000037, 0x00000065, 0x00040001, 0x00020001, 
	0x00000056, 0x00000080, 0x00020001, 0x00000008, 0x00000074, 
	0x00040001, 0x00020001, 0x00000081, 0x00000018, 0x00020001, 
	0x00000082, 0x00000028, 0x00100001, 0x00080001, 0x00040001, 
	0x00020001, 0x00000047, 0x00000066, 0x00020001, 0x00000083, 
	0x00000038, 0x00040001, 0x00020001, 0x00000075, 0x00000057, 
	0x00020001, 0x00000084, 0x00000048, 0x00060001, 0x00040001, 
	0x00020001, 0x00000090, 0x00000019, 0x00000091, 0x00040001, 
	0x00020001, 0x00000092, 0x00000076, 0x00020001, 0x00000067, 
	0x00000029, 0x005c0001, 0x00240001, 0x00120001, 0x000a0001, 
	0x00040001, 0x00020001, 0x00000085, 0x00000058, 0x00040001, 
	0x00020001, 0x00000009, 0x00000077, 0x00000093, 0x00040001, 
	0x00020001, 0x00000039, 0x00000094, 0x00020001, 0x00000049, 
	0x00000086, 0x000a0001, 0x00060001, 0x00020001, 0x00000068, 
	0x00020001, 0x000000a0, 0x0000000a, 0x00020001, 0x000000a1, 
	0x0000001a, 0x00040001, 0x00020001, 0x000000a2, 0x0000002a, 
	0x00020001, 0x00000095, 0x00000059, 0x001a0001, 0x000e0001, 
	0x00060001, 0x00020001, 0x000000a3, 0x00020001, 0x0000003a, 
	0x00000087, 0x00040001, 0x00020001, 0x00000078, 0x000000a4, 
	0x00020001, 0x0000004a, 0x00000096, 0x00060001, 0x00040001, 
	0x00020001, 0x00000069, 0x000000b0, 0x000000b1, 0x00040001, 
	0x00020001, 0x0000001b, 0x000000a5, 0x000000b2, 0x000e0001, 
	0x00080001, 0x00040001, 0x00020001, 0x0000005a, 0x0000002b, 
	0x00020001, 0x00000088, 0x00000097, 0x00020001, 0x000000b3, 
	0x00020001, 0x00000079, 0x0000003b, 0x00080001, 0x00040001, 
	0x00020001, 0x0000006a, 0x000000b4, 0x00020001, 0x0000004b, 
	0x000000c1, 0x00040001, 0x00020001, 0x00000098, 0x00000089, 
	0x00020001, 0x0000001c, 0x000000b5, 0x00500001, 0x00220001, 
	0x00100001, 0x00060001, 0x00040001, 0x00020001, 0x0000005b, 
	0x0000002c, 0x000000c2, 0x00060001, 0x00040001, 0x00020001, 
	0x0000000b, 0x000000c0, 0x000000a6, 0x00020001, 0x000000a7, 
	0x0000007a, 0x000a0001, 0x00040001, 0x00020001, 0x000000c3, 
	0x0000003c, 0x00040001, 0x00020001, 0x0000000c, 0x00000099, 
	0x000000b6, 0x00040001, 0x00020001, 0x0000006b, 0x000000c4, 
	0x00020001, 0x0000004c, 0x000000a8, 0x00140001, 0x000a0001, 
	0x00040001, 0x00020001, 0x0000008a, 0x000000c5, 0x00040001, 
	0x00020001, 0x000000d0, 0x0000005c, 0x000000d1, 0x00040001, 
	0x00020001, 0x000000b7, 0x0000007b, 0x00020001, 0x0000001d, 
	0x00020001, 0x0000000d, 0x0000002d, 0x000c0001, 0x00040001, 
	0x00020001, 0x000000d2, 0x000000d3, 0x00040001, 0x00020001, 
	0x0000003d, 0x000000c6, 0x00020001, 0x0000006c, 0x000000a9, 
	0x00060001, 0x00040001, 0x00020001, 0x0000009a, 0x000000b8, 
	0x000000d4, 0x00040001, 0x00020001, 0x0000008b, 0x0000004d, 
	0x00020001, 0x000000c7, 0x0000007c, 0x00440001, 0x00220001, 
	0x00120001, 0x000a0001, 0x00040001, 0x00020001, 0x000000d5, 
	0x0000005d, 0x00040001, 0x00020001, 0x000000e0, 0x0000000e, 
	0x000000e1, 0x00040001, 0x00020001, 0x0000001e, 0x000000e2, 
	0x00020001, 0x000000aa, 0x0000002e, 0x00080001, 0x00040001, 
	0x00020001, 0x000000b9, 0x0000009b, 0x00020001, 0x000000e3, 
	0x000000d6, 0x00040001, 0x00020001, 0x0000006d, 0x0000003e, 
	0x00020001, 0x000000c8, 0x0000008c, 0x00100001, 0x00080001, 
	0x00040001, 0x00020001, 0x000000e4, 0x0000004e, 0x00020001, 
	0x000000d7, 0x0000007d, 0x00040001, 0x00020001, 0x000000e5, 
	0x000000ba, 0x00020001, 0x000000ab, 0x0000005e, 0x00080001, 
	0x00040001, 0x00020001, 0x000000c9, 0x0000009c, 0x00020001, 
	0x000000f1, 0x0000001f, 0x00060001, 0x00040001, 0x00020001, 
	0x000000f0, 0x0000006e, 0x000000f2, 0x00020001, 0x0000002f, 
	0x000000e6, 0x00260001, 0x00120001, 0x00080001, 0x00040001, 
	0x00020001, 0x000000d8, 0x000000f3, 0x00020001, 0x0000003f, 
	0x000000f4, 0x00060001, 0x00020001, 0x0000004f, 0x00020001, 
	0x0000008d, 0x000000d9, 0x00020001, 0x000000bb, 0x000000ca, 
	0x00080001, 0x00040001, 0x00020001, 0x000000ac, 0x000000e7, 
	0x00020001, 0x0000007e, 0x000000f5, 0x00080001, 0x00040001, 
	0x00020001, 0x0000009d, 0x0000005f, 0x00020001, 0x000000e8, 
	0x0000008e, 0x00020001, 0x000000f6, 0x000000cb, 0x00220001, 
	0x00120001, 0x000a0001, 0x00060001, 0x00040001, 0x00020001, 
	0x0000000f, 0x000000ae, 0x0000006f, 0x00020001, 0x000000bc, 
	0x000000da, 0x00040001, 0x00020001, 0x000000ad, 0x000000f7, 
	0x00020001, 0x0000007f, 0x000000e9, 0x00080001, 0x00040001, 
	0x00020001, 0x0000009e, 0x000000cc, 0x00020001, 0x000000f8, 
	0x0000008f, 0x00040001, 0x00020001, 0x000000db, 0x000000bd, 
	0x00020001, 0x000000ea, 0x000000f9, 0x00100001, 0x00080001, 
	0x00040001, 0x00020001, 0x0000009f, 0x000000dc, 0x00020001, 
	0x000000cd, 0x000000eb, 0x00040001, 0x00020001, 0x000000be, 
	0x000000fa, 0x00020001, 0x000000af, 0x000000dd, 0x000e0001, 
	0x00060001, 0x00040001, 0x00020001, 0x000000ec, 0x000000ce, 
	0x000000fb, 0x00040001, 0x00020001, 0x000000bf, 0x000000ed, 
	0x00020001, 0x000000de, 0x000000fc, 0x00060001, 0x00040001, 
	0x00020001, 0x000000cf, 0x000000fd, 0x000000ee, 0x00040001, 
	0x00020001, 0x000000df, 0x000000fe, 0x00020001, 0x000000ef, 
	0x000000ff, 
};

static unsigned long g_huffman_table_16[511] = {
	0x00020001, 0x00000000, 0x00060001, 0x00020001, 0x00000010, 
	0x00020001, 0x00000001, 0x00000011, 0x002a0001, 0x00080001, 
	0x00040001, 0x00020001, 0x00000020, 0x00000002, 0x00020001, 
	0x00000021, 0x00000012, 0x000a0001, 0x00060001, 0x00020001, 
	0x00000022, 0x00020001, 0x00000030, 0x00000003, 0x00020001, 
	0x00000031, 0x00000013, 0x000a0001, 0x00040001, 0x00020001, 
	0x00000032, 0x00000023, 0x00040001, 0x00020001, 0x00000040, 
	0x00000004, 0x00000041, 0x00060001, 0x00020001, 0x00000014, 
	0x00020001, 0x00000033, 0x00000042, 0x00040001, 0x00020001, 
	0x00000024, 0x00000050, 0x00020001, 0x00000043, 0x00000034, 
	0x008a0001, 0x00280001, 0x00100001, 0x00060001, 0x00040001, 
	0x00020001, 0x00000005, 0x00000015, 0x00000051, 0x00040001, 
	0x00020001, 0x00000052, 0x00000025, 0x00040001, 0x00020001, 
	0x00000044, 0x00000035, 0x00000053, 0x000a0001, 0x00060001, 
	0x00040001, 0x00020001, 0x00000060, 0x00000006, 0x00000061, 
	0x00020001, 0x00000016, 0x00000062, 0x00080001, 0x00040001, 
	0x00020001, 0x00000026, 0x00000054, 0x00020001, 0x00000045, 
	0x00000063, 0x00040001, 0x00020001, 0x00000036, 0x00000070, 
	0x00000071, 0x00280001, 0x00120001, 0x00080001, 0x00020001, 
	0x00000017, 0x00020001, 0x00000007, 0x00020001, 0x00000055, 
	0x00000064, 0x00040001, 0x00020001, 0x00000072, 0x00000027, 
	0x00040001, 0x00020001, 0x00000046, 0x00000065, 0x00000073, 
	0x000a0001, 0x00060001, 0x00020001, 0x00000037, 0x00020001, 
	0x00000056, 0x00000008, 0x00020001, 0x00000080, 0x00000081, 
	0x00060001, 0x00020001, 0x00000018, 0x00020001, 0x00000074, 
	0x00000047, 0x00020001, 0x00000082, 0x00020001, 0x00000028, 
	0x00000066, 0x00180001, 0x000e0001, 0x00080001, 0x00040001, 
	0x00020001, 0x00000083, 0x00000038, 0x00020001, 0x00000075, 
	0x00000084, 0x00040001, 0x00020001, 0x00000048, 0x00000090, 
	0x00000091, 0x00060001, 0x00020001, 0x00000019, 0x00020001, 
	0x00000009, 0x00000076, 0x00020001, 0x00000092, 0x00000029, 
	0x000e0001, 0x00080001, 0x00040001, 0x00020001, 0x00000085, 
	0x00000058, 0x00020001, 0x00000093, 0x00000039, 0x00040001, 
	0x00020001, 0x000000a0, 0x0000000a, 0x0000001a, 0x00080001, 
	0x00020001, 0x000000a2, 0x00020001, 0x00000067, 0x00020001, 
	0x00000057, 0x00000049, 0x00060001, 0x00020001, 0x00000094, 
	0x00020001, 0x00000077, 0x00000086, 0x00020001, 0x000000a1, 
	0x00020001, 0x00000068, 0x00000095, 0x00dc0001, 0x007e0001, 
	0x00320001, 0x001a0001, 0x000c0001, 0x00060001, 0x00020001, 
	0x0000002a, 0x00020001, 0x00000059, 0x0000003a, 0x00020001, 
	0x000000a3, 0x00020001, 0x00000087, 0x00000078, 0x00080001, 
	0x00040001, 0x00020001, 0x000000a4, 0x0000004a, 0x00020001, 
	0x00000096, 0x00000069, 0x00040001, 0x00020001, 0x000000b0, 
	0x0000000b, 0x000000b1, 0x000a0001, 0x00040001, 0x00020001, 
	0x0000001b, 0x000000b2, 0x00020001, 0x0000002b, 0x00020001, 
	0x000000a5, 0x0000005a, 0x00060001, 0x00020001, 0x000000b3, 
	0x00020001, 0x000000a6, 0x0000006a, 0x00040001, 0x00020001, 
	0x000000b4, 0x0000004b, 0x00020001, 0x0000000c, 0x000000c1, 
	0x001e0001, 0x000e0001, 0x00060001, 0x00040001, 0x00020001, 
	0x000000b5, 0x000000c2, 0x0000002c, 0x00040001, 0x00020001, 
	0x000000a7, 0x000000c3, 0x00020001, 0x0000006b, 0x000000c4, 
	0x00080001, 0x00020001, 0x0000001d, 0x00040001, 0x00020001, 
	0x00000088, 0x00000097, 0x0000003b, 0x00040001, 0x00020001, 
	0x000000d1, 0x000000d2, 0x00020001, 0x0000002d, 0x000000d3, 
	0x00120001, 0x00060001, 0x00040001, 0x00020001, 0x0000001e, 
	0x0000002e, 0x000000e2, 0x00060001, 0x00040001, 0x00020001, 
	0x00000079, 0x00000098, 0x000000c0, 0x00020001, 0x0000001c, 
	0x00020001, 0x00000089, 0x0000005b, 0x000e0001, 0x00060001, 
	0x00020001, 0x0000003c, 0x00020001, 0x0000007a, 0x000000b6, 
	0x00040001, 0x00020001, 0x0000004c, 0x00000099, 0x00020001, 
	0x000000a8, 0x0000008a, 0x00060001, 0x00020001, 0x0000000d, 
	0x00020001, 0x000000c5, 0x0000005c, 0x00040001, 0x00020001, 
	0x0000003d, 0x000000c6, 0x00020001, 0x0000006c, 0x0000009a, 
	0x00580001, 0x00560001, 0x00240001, 0x00100001, 0x00080001, 
	0x00040001, 0x00020001, 0x0000008b, 0x0000004d, 0x00020001, 
	0x000000c7, 0x0000007c, 0x00040001, 0x00020001, 0x000000d5, 
	0x0000005d, 0x00020001, 0x000000e0, 0x0000000e, 0x00080001, 
	0x00020001, 0x000000e3, 0x00040001, 0x00020001, 0x000000d0, 
	0x000000b7, 0x0000007b, 0x00060001, 0x00040001, 0x00020001, 
	0x000000a9, 0x000000b8, 0x000000d4, 0x00020001, 0x000000e1, 
	0x00020001, 0x000000aa, 0x000000b9, 0x00180001, 0x000a0001, 
	0x00060001, 0x00040001, 0x00020001, 0x0000009b, 0x000000d6, 
	0x0000006d, 0x00020001, 0x0000003e, 0x000000c8, 0x00060001, 
	0x00040001, 0x00020001, 0x0000008c, 0x000000e4, 0x0000004e, 
	0x00040001, 0x00020001, 0x000000d7, 0x000000e5, 0x00020001, 
	0x000000ba, 0x000000ab, 0x000c0001, 0x00040001, 0x00020001, 
	0x0000009c, 0x000000e6, 0x00040001, 0x00020001, 0x0000006e, 
	0x000000d8, 0x00020001, 0x0000008d, 0x000000bb, 0x00080001, 
	0x00040001, 0x00020001, 0x000000e7, 0x0000009d, 0x00020001, 
	0x000000e8, 0x0000008e, 0x00040001, 0x00020001, 0x000000cb, 
	0x000000bc, 0x0000009e, 0x000000f1, 0x00020001, 0x0000001f, 
	0x00020001, 0x0000000f, 0x0000002f, 0x00420001, 0x00380001, 
	0x00020001, 0x000000f2, 0x00340001, 0x00320001, 0x00140001, 
	0x00080001, 0x00020001, 0x000000bd, 0x00020001, 0x0000005e, 
	0x00020001, 0x0000007d, 0x000000c9, 0x00060001, 0x00020001, 
	0x000000ca, 0x00020001, 0x000000ac, 0x0000007e, 0x00040001, 
	0x00020001, 0x000000da, 0x000000ad, 0x000000cc, 0x000a0001, 
	0x00060001, 0x00020001, 0x000000ae, 0x00020001, 0x000000db, 
	0x000000dc, 0x00020001, 0x000000cd, 0x000000be, 0x00060001, 
	0x00040001, 0x00020001, 0x000000eb, 0x000000ed, 0x000000ee, 
	0x00060001, 0x00040001, 0x00020001, 0x000000d9, 0x000000ea, 
	0x000000e9, 0x00020001, 0x000000de, 0x00040001, 0x00020001, 
	0x000000dd, 0x000000ec, 0x000000ce, 0x0000003f, 0x000000f0, 
	0x00040001, 0x00020001, 0x000000f3, 0x000000f4, 0x00020001, 
	0x0000004f, 0x00020001, 0x000000f5, 0x0000005f, 0x000a0001, 
	0x00020001, 0x000000ff, 0x00040001, 0x00020001, 0x000000f6, 
	0x0000006f, 0x00020001, 0x000000f7, 0x0000007f, 0x000c0001, 
	0x00060001, 0x00020001, 0x0000008f, 0x00020001, 0x000000f8, 
	0x000000f9, 0x00040001, 0x00020001, 0x0000009f, 0x000000fa, 
	0x000000af, 0x00080001, 0x00040001, 0x00020001, 0x000000fb, 
	0x000000bf, 0x00020001, 0x000000fc, 0x000000cf, 0x00040001, 
	0x00020001, 0x000000fd, 0x000000df, 0x00020001, 0x000000fe, 
	0x000000ef, 
};

static unsigned long g_huffman_table_24[512] = {
	0x003c0001, 0x00080001, 0x00040001, 0x00020001, 0x00000000, 
	0x00000010, 0x00020001, 0x00000001, 0x00000011, 0x000e0001, 
	0x00060001, 0x00040001, 0x00020001, 0x00000020, 0x00000002, 
	0x00000021, 0x00020001, 0x00000012, 0x00020001, 0x00000022, 
	0x00020001, 0x00000030, 0x00000003, 0x000e0001, 0x00040001, 
	0x00020001, 0x00000031, 0x00000013, 0x00040001, 0x00020001, 
	0x00000032, 0x00000023, 0x00040001, 0x00020001, 0x00000040, 
	0x00000004, 0x00000041, 0x00080001, 0x00040001, 0x00020001, 
	0x00000014, 0x00000033, 0x00020001, 0x00000042, 0x00000024, 
	0x00060001, 0x00040001, 0x00020001, 0x00000043, 0x00000034, 
	0x00000051, 0x00060001, 0x00040001, 0x00020001, 0x00000050, 
	0x00000005, 0x00000015, 0x00020001, 0x00000052, 0x00000025, 
	0x00fa0001, 0x00620001, 0x00220001, 0x00120001, 0x000a0001, 
	0x00040001, 0x00020001, 0x00000044, 0x00000053, 0x00020001, 
	0x00000035, 0x00020001, 0x00000060, 0x00000006, 0x00040001, 
	0x00020001, 0x00000061, 0x00000016, 0x00020001, 0x00000062, 
	0x00000026, 0x00080001, 0x00040001, 0x00020001, 0x00000054, 
	0x00000045, 0x00020001, 0x00000063, 0x00000036, 0x00040001, 
	0x00020001, 0x00000071, 0x00000055, 0x00020001, 0x00000064, 
	0x00000046, 0x00200001, 0x000e0001, 0x00060001, 0x00020001, 
	0x00000072, 0x00020001, 0x00000027, 0x00000037, 0x00020001, 
	0x00000073, 0x00040001, 0x00020001, 0x00000070, 0x00000007, 
	0x00000017, 0x000a0001, 0x00040001, 0x00020001, 0x00000065, 
	0x00000056, 0x00040001, 0x00020001, 0x00000080, 0x00000008, 
	0x00000081, 0x00040001, 0x00020001, 0x00000074, 0x00000047, 
	0x00020001, 0x00000018, 0x00000082, 0x00100001, 0x00080001, 
	0x00040001, 0x00020001, 0x00000028, 0x00000066, 0x00020001, 
	0x00000083, 0x00000038, 0x00040001, 0x00020001, 0x00000075, 
	0x00000057, 0x00020001, 0x00000084, 0x00000048, 0x00080001, 
	0x00040001, 0x00020001, 0x00000091, 0x00000019, 0x00020001, 
	0x00000092, 0x00000076, 0x00040001, 0x00020001, 0x00000067, 
	0x00000029, 0x00020001, 0x00000085, 0x00000058, 0x005c0001, 
	0x00220001, 0x00100001, 0x00080001, 0x00040001, 0x00020001, 
	0x00000093, 0x00000039, 0x00020001, 0x00000094, 0x00000049, 
	0x00040001, 0x00020001, 0x00000077, 0x00000086, 0x00020001, 
	0x00000068, 0x000000a1, 0x00080001, 0x00040001, 0x00020001, 
	0x000000a2, 0x0000002a, 0x00020001, 0x00000095, 0x00000059, 
	0x00040001, 0x00020001, 0x000000a3, 0x0000003a, 0x00020001, 
	0x00000087, 0x00020001, 0x00000078, 0x0000004a, 0x00160001, 
	0x000c0001, 0x00040001, 0x00020001, 0x000000a4, 0x00000096, 
	0x00040001, 0x00020001, 0x00000069, 0x000000b1, 0x00020001, 
	0x0000001b, 0x000000a5, 0x00060001, 0x00020001, 0x000000b2, 
	0x00020001, 0x0000005a, 0x0000002b, 0x00020001, 0x00000088, 
	0x000000b3, 0x00100001, 0x000a0001, 0x00060001, 0x00020001, 
	0x00000090, 0x00020001, 0x00000009, 0x000000a0, 0x00020001, 
	0x00000097, 0x00000079, 0x00040001, 0x00020001, 0x000000a6, 
	0x0000006a, 0x000000b4, 0x000c0001, 0x00060001, 0x00020001, 
	0x0000001a, 0x00020001, 0x0000000a, 0x000000b0, 0x00020001, 
	0x0000003b, 0x00020001, 0x0000000b, 0x000000c0, 0x00040001, 
	0x00020001, 0x0000004b, 0x000000c1, 0x00020001, 0x00000098, 
	0x00000089, 0x00430001, 0x00220001, 0x00100001, 0x00080001, 
	0x00040001, 0x00020001, 0x0000001c, 0x000000b5, 0x00020001, 
	0x0000005b, 0x000000c2, 0x00040001, 0x00020001, 0x0000002c, 
	0x000000a7, 0x00020001, 0x0000007a, 0x000000c3, 0x000a0001, 
	0x00060001, 0x00020001, 0x0000003c, 0x00020001, 0x0000000c, 
	0x000000d0, 0x00020001, 0x000000b6, 0x0000006b, 0x00040001, 
	0x00020001, 0x000000c4, 0x0000004c, 0x00020001, 0x00000099, 
	0x000000a8, 0x00100001, 0x00080001, 0x00040001, 0x00020001, 
	0x0000008a, 0x000000c5, 0x00020001, 0x0000005c, 0x000000d1, 
	0x00040001, 0x00020001, 0x000000b7, 0x0000007b, 0x00020001, 
	0x0000001d, 0x000000d2, 0x00090001, 0x00040001, 0x00020001, 
	0x0000002d, 0x000000d3, 0x00020001, 0x0000003d, 0x000000c6, 
	0x005500fa, 0x00040001, 0x00020001, 0x0000006c, 0x000000a9, 
	0x00020001, 0x0000009a, 0x000000d4, 0x00200001, 0x00100001, 
	0x00080001, 0x00040001, 0x00020001, 0x000000b8, 0x0000008b, 
	0x00020001, 0x0000004d, 0x000000c7, 0x00040001, 0x00020001, 
	0x0000007c, 0x000000d5, 0x00020001, 0x0000005d, 0x000000e1, 
	0x00080001, 0x00040001, 0x00020001, 0x0000001e, 0x000000e2, 
	0x00020001, 0x000000aa, 0x000000b9, 0x00040001, 0x00020001, 
	0x0000009b, 0x000000e3, 0x00020001, 0x000000d6, 0x0000006d, 
	0x00140001, 0x000a0001, 0x00060001, 0x00020001, 0x0000003e, 
	0x00020001, 0x0000002e, 0x0000004e, 0x00020001, 0x000000c8, 
	0x0000008c, 0x00040001, 0x00020001, 0x000000e4, 0x000000d7, 
	0x00040001, 0x00020001, 0x0000007d, 0x000000ab, 0x000000e5, 
	0x000a0001, 0x00040001, 0x00020001, 0x000000ba, 0x0000005e, 
	0x00020001, 0x000000c9, 0x00020001, 0x0000009c, 0x0000006e, 
	0x00080001, 0x00020001, 0x000000e6, 0x00020001, 0x0000000d, 
	0x00020001, 0x000000e0, 0x0000000e, 0x00040001, 0x00020001, 
	0x000000d8, 0x0000008d, 0x00020001, 0x000000bb, 0x000000ca, 
	0x004a0001, 0x00020001, 0x000000ff, 0x00400001, 0x003a0001, 
	0x00200001, 0x00100001, 0x00080001, 0x00040001, 0x00020001, 
	0x000000ac, 0x000000e7, 0x00020001, 0x0000007e, 0x000000d9, 
	0x00040001, 0x00020001, 0x0000009d, 0x000000e8, 0x00020001, 
	0x0000008e, 0x000000cb, 0x00080001, 0x00040001, 0x00020001, 
	0x000000bc, 0x000000da, 0x00020001, 0x000000ad, 0x000000e9, 
	0x00040001, 0x00020001, 0x0000009e, 0x000000cc, 0x00020001, 
	0x000000db, 0x000000bd, 0x00100001, 0x00080001, 0x00040001, 
	0x00020001, 0x000000ea, 0x000000ae, 0x00020001, 0x000000dc, 
	0x000000cd, 0x00040001, 0x00020001, 0x000000eb, 0x000000be, 
	0x00020001, 0x000000dd, 0x000000ec, 0x00080001, 0x00040001, 
	0x00020001, 0x000000ce, 0x000000ed, 0x00020001, 0x000000de, 
	0x000000ee, 0x0000000f, 0x00040001, 0x00020001, 0x000000f0, 
	0x0000001f, 0x000000f1, 0x00040001, 0x00020001, 0x000000f2, 
	0x0000002f, 0x00020001, 0x000000f3, 0x0000003f, 0x00120001, 
	0x00080001, 0x00040001, 0x00020001, 0x000000f4, 0x0000004f, 
	0x00020001, 0x000000f5, 0x0000005f, 0x00040001, 0x00020001, 
	0x000000f6, 0x0000006f, 0x00020001, 0x000000f7, 0x00020001, 
	0x0000007f, 0x0000008f, 0x000a0001, 0x00040001, 0x00020001, 
	0x000000f8, 0x000000f9, 0x00040001, 0x00020001, 0x0000009f, 
	0x000000af, 0x000000fa, 0x00080001, 0x00040001, 0x00020001, 
	0x000000fb, 0x000000bf, 0x00020001, 0x000000fc, 0x000000cf, 
	0x00040001, 0x00020001, 0x000000fd, 0x000000df, 0x00020001, 
	0x000000fe, 0x000000ef, 
};

static unsigned long g_huffman_table_32[31] = {
	0x00020001, 0x00000000, 0x00080001, 0x00040001, 0x00020001, 
	0x00000008, 0x00000004, 0x00020001, 0x00000001, 0x00000002, 
	0x00080001, 0x00040001, 0x00020001, 0x0000000c, 0x0000000a, 
	0x00020001, 0x00000003, 0x00000006, 0x00060001, 0x00020001, 
	0x00000009, 0x00020001, 0x00000005, 0x00000007, 0x00040001, 
	0x00020001, 0x0000000e, 0x0000000d, 0x00020001, 0x0000000f, 
	0x0000000b, 
};

static unsigned long g_huffman_table_33[31] = {
	0x00100001, 0x00080001, 0x00040001, 0x00020001, 0x00000000, 
	0x00000001, 0x00020001, 0x00000002, 0x00000003, 0x00040001, 
	0x00020001, 0x00000004, 0x00000005, 0x00020001, 0x00000006, 
	0x00000007, 0x00080001, 0x00040001, 0x00020001, 0x00000008, 
	0x00000009, 0x00020001, 0x0000000a, 0x0000000b, 0x00040001, 
	0x00020001, 0x0000000c, 0x0000000d, 0x00020001, 0x0000000e, 
	0x0000000f, 
};

typedef struct _HUFFMAN_
{
	unsigned long * TableData;
	unsigned long TreeLen;
	unsigned long linbits;
} HuffmanData;

static HuffmanData g_huffman_main [34] = 
{
	{  0                 ,   0,  0 },	/* Table  0 */
	{  g_huffman_table_1 ,   7,  0 },	/* Table  1 */
	{  g_huffman_table_2 ,  17,  0 },	/* Table  2 */
	{  g_huffman_table_3 ,  17,  0 },	/* Table  3 */
	{  0                 ,   0,  0 },	/* Table  4 */
	{  g_huffman_table_5 ,  31,  0 },	/* Table  5 */
	{  g_huffman_table_6 ,  31,  0 },	/* Table  6 */
	{  g_huffman_table_7 ,  71,  0 },	/* Table  7 */
	{  g_huffman_table_8 ,  71,  0 },	/* Table  8 */
	{  g_huffman_table_9 ,  71,  0 },	/* Table  9 */
	{  g_huffman_table_10, 127,  0 },	/* Table 10 */
	{  g_huffman_table_11, 127,  0 },	/* Table 11 */
	{  g_huffman_table_12, 127,  0 },	/* Table 12 */
	{  g_huffman_table_13, 511,  0 },	/* Table 13 */
	{  0                 ,   0,  0 },	/* Table 14 */
	{  g_huffman_table_15, 511,  0 },	/* Table 15 */
	{  g_huffman_table_16, 511,  1 },	/* Table 16 */
	{  g_huffman_table_16, 511,  2 },	/* Table 17 */
	{  g_huffman_table_16, 511,  3 },	/* Table 18 */
	{  g_huffman_table_16, 511,  4 },	/* Table 19 */
	{  g_huffman_table_16, 511,  6 },	/* Table 20 */
	{  g_huffman_table_16, 511,  8 },	/* Table 21 */
	{  g_huffman_table_16, 511, 10 },	/* Table 22 */
	{  g_huffman_table_16, 511, 13 },	/* Table 23 */
	{  g_huffman_table_24, 512,  4 },	/* Table 24 */
	{  g_huffman_table_24, 512,  5 },	/* Table 25 */
	{  g_huffman_table_24, 512,  6 },	/* Table 26 */
	{  g_huffman_table_24, 512,  7 },	/* Table 27 */
	{  g_huffman_table_24, 512,  8 },	/* Table 28 */
	{  g_huffman_table_24, 512,  9 },	/* Table 29 */
	{  g_huffman_table_24, 512, 11 },	/* Table 30 */
	{  g_huffman_table_24, 512, 13 },	/* Table 31 */
	{  g_huffman_table_32,  31,  0 },	/* Table 32 */
	{ g_huffman_table_33,  31,  0 },	/* Table 33 */
};

const CLayer3Decoder::SBI CLayer3Decoder::sfBandIndex[3][3] = 
{
	{ // MPEG1
		{	// 44.4 Khz
			{0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52,  62,  74,  90, 110, 134, 162, 196, 238, 288, 342, 418, 576},
			{0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192 }
		},
		{	// 48 Khz
			{0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50,  60,  72,  88, 106, 128, 156, 190, 230, 276, 330, 384, 576 },
			{0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192 }
		},
		{	// 32Khz
			{0, 4, 8, 12, 16, 20, 24, 30, 36, 44,  54,  66,  82, 102, 126, 156, 194, 240, 296, 364, 448, 550, 576 },
			{0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192}
		}
	},
	{ // MPEG2
		{	// 22.5khz
			{0, 6, 12, 18, 24, 30, 36, 44, 54, 66,  80,  96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576},
			{0, 4, 8,  12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192}
		},
		{	// 24Khz
			{0, 6, 12, 18, 24, 30, 36, 44, 54, 66,  80,  96, 114, 136, 162, 194, 232, 278, 332, 394, 464, 540, 576},
			{0, 4, 8,  12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192}
		},
		{	// 16khz
			{0, 6, 12, 18, 24, 30, 36, 44, 54, 66,  80,  96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576},
			{0, 4, 8,  12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192}
		},
	},
	{ // MPEG2.5
		{	// 11.25Khz
			{0, 6, 12, 18, 24, 30, 36, 44, 54, 66,  80,  96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576},
			{0, 4, 8,  12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192},
		},
		{	// 12Khz
			{0, 6, 12, 18, 24, 30, 36, 44, 54, 66,  80,  96, 116, 140, 168, 200, 238, 284, 336, 396, 464, 522, 576},
			{0, 4, 8,  12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192},
		},
		{	// 8Khz
			{0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570, 572, 574, 576},
			{0, 8,  16, 24, 36, 52, 72, 96, 124, 160, 162, 164, 166, 192},
		},
	}
};

const float CLayer3Decoder::ShortTwiddles[] = 
{
    0.866025403f, 0.500000000f, 1.931851653f, 
	0.707106781f, 0.517638090f, 0.504314480f, 
	0.541196100f, 0.630236207f, 0.821339815f, 
	1.306562965f, 3.830648788f, 0.793353340f, 
	0.608761429f, 0.923879532f, 0.382683432f, 
	0.991444861f, 0.130526192f, 0.382683432f, 
	0.608761429f, 0.793353340f, 0.923879532f, 
	0.991444861f, 0.130526192f
};

const float CLayer3Decoder::NormalTwiddles[] = 
{
    5.736856623f,   1.931851653f,  1.183100792f,
    0.871723397f,   0.707106781f,  0.610387294f, 
    0.551688959f,   0.517638090f,  0.501909918f,
    -0.500476342f, -0.504314480f, -0.512139757f,
    -0.524264562f, -0.541196100f, -0.563690973f, 
    -0.592844523f, -0.630236207f, -0.678170852f, 
    -0.740093616f, -0.821339815f, -0.930579498f,
    -1.082840285f, -1.306562965f, -1.662754762f, 
    -2.310113158f, -3.830648788f, -11.46279281f
};

CLayer3Decoder::CLayer3Decoder()
{
	int		i;
	float	ci[8] = { -0.6f,   -0.535f, -0.33f,   -0.185f,  -0.095f, -0.041f, -0.0142f, -0.0037f };

	for (i = 0; i < 8; i++) 
	{
		Cs[i] = 1.0f / (float)sqrt(1.0 + ci[i]*ci[i]);
		Ca[i] = ci[i] / (float)sqrt(1.0 + ci[i]*ci[i]);
	}

    for(i = 0; i < 64; i++) 
	{
		PowerTableMinus2[i]  = (float)pow(2.0, -2.0 * i);
		PowerTableMinus05[i] = (float)pow(2.0, -0.5 * i);
    }

    for(i = 0; i < 256; i++)
		GainTable[i] = (float)pow(2.0 , (0.25 * (i - 210.0)));
  
	// table for the MPEG1 intensity stereo position
	// 7 == INVALID_POS so....
	for(i=0; i<16; i++)
	{
		TanPi12Table[i] = (float)tan(i * PI/12);
	}

	// magic for the IMDCT stuff
	int odd_i, two_odd_i, four_odd_i, eight_odd_i;
	int j = 0;
	for(i = 0; i < 9; i++) 
	{
		odd_i = (i << 1) + 1;
		two_odd_i = odd_i << 1;
		four_odd_i = odd_i << 2;
		IMDCT9x8Table[j++] = (float)cos(PI18 * odd_i);
		IMDCT9x8Table[j++] = (float)cos(PI18 * two_odd_i);

		eight_odd_i = two_odd_i << 2;
		IMDCT9x8Table[j++] = (float)cos(PI18 * (four_odd_i - odd_i));
		IMDCT9x8Table[j++] = (float)cos(PI18 * four_odd_i);
		IMDCT9x8Table[j++] = (float)cos(PI18 * (four_odd_i + odd_i));
		IMDCT9x8Table[j++] = (float)cos(PI18 * (four_odd_i + two_odd_i));
		IMDCT9x8Table[j++] = (float)cos(PI18 * (eight_odd_i - odd_i));
		IMDCT9x8Table[j++] = (float)cos(PI18 * eight_odd_i);
    }

	for(int ch=0;ch<2;ch++)
		for(int j=0; j<576; j++)
   			prevblck[ch][j] = 0.0f;

	/* block_type 0 (normal window) */
	for(i = 0; i < 36; i++)
		IMDCTwin[0][i] = (float)sin(PI36 * (i + 0.5));

	/* block_type 1 (start block) */
	for(i = 0; i < 18; i++)
		IMDCTwin[1][i] = (float)sin(PI36 * (i + 0.5));
	for(i = 18; i < 24; i++)
		IMDCTwin[1][i] = 1.0f;
	for(i = 24; i < 30; i++)
		IMDCTwin[1][i] = (float)sin(PI12 * (i - 18 + 0.5));
	for(i = 30; i < 36; i++)
		IMDCTwin[1][i] = 0.0f;

	/* block_type 2 (short block) */
	for(i = 0; i < 12; i++)
		IMDCTwin[2][i] = (float)sin(PI12 * (i + 0.5));
	for(i = 12; i < 36; i++)
		IMDCTwin[2][i] = 0.0f;

	/* block_type 3 (stop block) */
	for(i = 0; i < 6; i++)
		IMDCTwin[3][i] = 0.0f;
	for(i = 6; i < 12; i++)
		IMDCTwin[3][i] = (float)sin(PI12 * (i - 6 + 0.5));
	for(i = 12; i < 18; i++)
		IMDCTwin[3][i] = 1.0f;
	for(i = 18; i < 36; i++)
		IMDCTwin[3][i] = (float)sin(PI36 * (i + 0.5));
}

CLayer3Decoder::~CLayer3Decoder()
{

}

void CLayer3Decoder::DecodeScalefactors(unsigned long ch, unsigned long gr)
{
	const unsigned int slentab1[16] = {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4};
	const unsigned int slentab2[16] = {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3};

	int sfb, window;

	for(sfb=0; sfb<21; sfb++)
	{
		m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] = 0;
	}

	for(sfb=0; sfb<13; sfb++)
	{
		m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][0] = 0;
		m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][1] = 0;
		m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][2] = 0;
	}

	if(m_MpegVer == MPEG1)
	{
		unsigned int slen1 = slentab1[m_fr->m_SI.grinf[gr][ch].ScalefacCompress];
		unsigned int slen2 = slentab2[m_fr->m_SI.grinf[gr][ch].ScalefacCompress];

		if( (m_fr->m_SI.grinf[gr][ch].WindowSwitchingFlag == 1) && (m_fr->m_SI.grinf[gr][ch].BlockType == 2))
		{
			if(m_fr->m_SI.grinf[gr][ch].MixedBlockFlag)
			{
				// this is the long block
				for (sfb = 0; sfb < 8; sfb++)
					m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] = br.GetBits(slen1);

				for (sfb = 3; sfb < 6; sfb++)
					for (window=0; window<3; window++)
						m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][window] = br.GetBits(slen1);

				for (sfb = 6; sfb < 12; sfb++)
					for (window=0; window<3; window++)
						m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][window] = br.GetBits(slen2);

				for (sfb=12,window=0; window<3; window++)
					m_fr->m_SI.grinf[gr][ch].Scalefac_Short[12][window] = 0;
			} 
			else 
			{  // SHORT
				// this is a short block...
				for(sfb=0; sfb<6; sfb++)
				{
					for(window=0; window<3; window++)
					{
						m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][window] = br.GetBits(slen1);
					}
				}

				for(sfb=6; sfb<12; sfb++)
				{
					for(window=0; window<3; window++)
					{
						m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][window] = br.GetBits(slen2);
					}
				}

				for(window=0; window<3; window++)
					m_fr->m_SI.grinf[gr][ch].Scalefac_Short[12][window] = 0;
			}
		}
		else
		{
			for(sfb=0; sfb<6; sfb++)
			{
				if((m_fr->m_SI.ScfSi[ch][0] == 0) || (gr == 0))
				{
					m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] = br.GetBits(slen1);
				}
				else
					m_fr->m_SI.grinf[1][ch].Scalefac_Long[sfb] = m_fr->m_SI.grinf[0][ch].Scalefac_Long[sfb];
			}

			for(sfb=6; sfb<11; sfb++)
			{
				if((m_fr->m_SI.ScfSi[ch][1] == 0) || (gr == 0))
				{
					m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] = br.GetBits(slen1);
				}
				else
					m_fr->m_SI.grinf[1][ch].Scalefac_Long[sfb] = m_fr->m_SI.grinf[0][ch].Scalefac_Long[sfb];
			}

			for(sfb=11; sfb<16; sfb++)
			{
				if((m_fr->m_SI.ScfSi[ch][2] == 0) || (gr == 0))
				{
					m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] = br.GetBits(slen2);
				}
				else
					m_fr->m_SI.grinf[1][ch].Scalefac_Long[sfb] = m_fr->m_SI.grinf[0][ch].Scalefac_Long[sfb];
			}

			for(sfb=16; sfb<21; sfb++)
			{
				if((m_fr->m_SI.ScfSi[ch][3] == 0) || (gr == 0))
				{
					m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] = br.GetBits(slen2);
				}
				else
					m_fr->m_SI.grinf[1][ch].Scalefac_Long[sfb] = m_fr->m_SI.grinf[0][ch].Scalefac_Long[sfb];
			}

			m_fr->m_SI.grinf[gr][ch].Scalefac_Long[21] = 0;
		}
	}
	else	// MPEG 2
	{
		int nfsbtable [2][3][3][4] =
		{
			{
				{
					{6, 5, 5, 5},
					{9, 9, 9, 9},
					{6, 9, 9, 9}
				},
				{
					{6, 5, 7,  3},
					{9, 9, 12, 6},
					{6, 9, 12, 6}
				},
				{
					{11, 10, 0, 0},
					{18, 18, 0, 0},
					{15, 18, 0, 0}
				},
			},
			{
				{
					{ 7,  7,  7, 0},
					{12, 12, 12, 0},
					{ 6, 15, 12, 0}
				},
				{
					{ 6,  6, 6, 3},
					{12,  9, 9, 6},
					{ 6, 12, 9, 6}
				},
				{
					{ 8, 8,  5, 0},
					{15, 12, 9, 0},
					{ 6, 18, 9, 0}
				},
			},
		};

		unsigned int scalefac_comp;

		unsigned int slen[4] = {0,0,0,0};
		unsigned long index1, index2, index3;

		if( (m_fr->m_SI.grinf[gr][ch].WindowSwitchingFlag == 1) && (m_fr->m_SI.grinf[gr][ch].BlockType == 2))
		{
			if(m_fr->m_SI.grinf[gr][ch].MixedBlockFlag)
			{
				index3 = 2;
			}
			else
			{
				index3 = 1;
			}
		}
		else
		{
			index3 = 0;
		}

		scalefac_comp =  m_fr->m_SI.grinf[gr][ch].ScalefacCompress;

		if(!( ((m_ModeExt == 1) || (m_ModeExt==3)) && (ch == 1)))
		{
			index1 = 0;
			m_fr->m_SI.grinf[gr][ch].PreFlag = 0;


			if (scalefac_comp>=500)
			{
				slen[0] = ((scalefac_comp-500)/ 3)%4;
				slen[1] = ((scalefac_comp-500)/ 1)%3;
				slen[2] = ((scalefac_comp-500)/ 1)%1;
				slen[3] = ((scalefac_comp-500)/ 1)%1;
				index2 = 2;
				m_fr->m_SI.grinf[gr][ch].PreFlag = 1;
			}
			else if (scalefac_comp>=400)
			{
				slen[0] = ((scalefac_comp-400)/20)%5;
				slen[1] = ((scalefac_comp-400)/ 4)%5;
				slen[2] = ((scalefac_comp-400)/ 1)%4;
				slen[3] = ((scalefac_comp-400)/ 1)%1;
				index2 = 1;
			}
			else
			{
				slen[0] = ((scalefac_comp-  0)/80)%5;
				slen[1] = ((scalefac_comp-  0)/16)%5;
				slen[2] = ((scalefac_comp-  0)/ 4)%4;
				slen[3] = ((scalefac_comp-  0)/ 1)%4;
				index2 = 0;
			}
		}
		else
		{
			index1 = 1;

			m_fr->m_SI.grinf[gr][ch].PreFlag = 0;
			scalefac_comp>>=1;

			if (scalefac_comp>=244)
			{
				slen[0] = ((scalefac_comp-244)/ 3)%4;
				slen[1] = ((scalefac_comp-244)/ 1)%3;
				slen[2] = ((scalefac_comp-244)/ 1)%1;
				slen[3] = ((scalefac_comp-244)/ 1)%1;
				index2 = 2;
			}
			else if (scalefac_comp>=180)
			{
				slen[0] = ((scalefac_comp-180)/16)%4;
				slen[1] = ((scalefac_comp-180)/ 4)%4;
				slen[2] = ((scalefac_comp-180)/ 1)%4;
				slen[3] = ((scalefac_comp-180)/ 1)%1;
				index2 = 1;
			}
			else
			{
				slen[0] = ((scalefac_comp-  0)/36)%5;
				slen[1] = ((scalefac_comp-  0)/ 6)%6;
				slen[2] = ((scalefac_comp-  0)/ 1)%6;
				slen[3] = ((scalefac_comp-  0)/ 1)%1;
				index2 = 0;
			}
		}

		if( (m_fr->m_SI.grinf[gr][ch].WindowSwitchingFlag == 1) && (m_fr->m_SI.grinf[gr][ch].BlockType == 2))
		{
			if(m_fr->m_SI.grinf[gr][ch].MixedBlockFlag)
			{
			}
			else
			{
				int sfb = 0;
				int window = 0;

				for(int j=0; j<4; j++)
				{
					for(int i=0; i<nfsbtable[index1][index2][index3][j]; i++)
					{
						if(slen[j] > 0)
							m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][window] = br.GetBits(slen[j]);
						else
							m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][window] = 0;

						window++;
						if(window > 2)
						{
							if( (m_MpegVer != MPEG1) && ((m_ModeExt == 1) || (m_ModeExt==3)) )
								m_fr->m_SI.grinf[gr][ch].is_max[sfb] = (1<<slen[j])-1;

							window = 0;
							sfb++;
						}

					}
				}

				for(window=0; window<3; window++)
					m_fr->m_SI.grinf[gr][ch].Scalefac_Short[12][window] = 0;
			}
		}
		else
		{
			int sfb = 0;

			for(int j=0; j<4; j++)
			{
				for(int i=0; i<nfsbtable[index1][index2][index3][j]; i++)
				{
					if(slen[j] > 0)
						m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] = br.GetBits(slen[j]);
					else
						m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] = 0;
					
					if( (m_MpegVer != MPEG1) && ((m_ModeExt == 1) || (m_ModeExt==3)) )
						m_fr->m_SI.grinf[gr][ch].is_max[sfb] = (1<<slen[j])-1;

					sfb++;
				}
			}
			m_fr->m_SI.grinf[gr][ch].Scalefac_Long[21] = 0;
			m_fr->m_SI.grinf[gr][ch].Scalefac_Long[22] = 0;
		}
	}
}

bool __forceinline CLayer3Decoder::HuffmanDecode(unsigned long TableNum, int * x, int * y, int * v, int * w)
{
	unsigned long point, error, bitsleft, treelen, linbits;
	unsigned long *htptr;

	point = 0;
	bitsleft = 32;

	/* Check for empty tables */
	if(g_huffman_main[TableNum].TreeLen == 0) 
	{
		*x = *y = *v = *w = 0;
		return true;
	}

	treelen = g_huffman_main[TableNum].TreeLen;
	linbits = g_huffman_main[TableNum].linbits;
	htptr = g_huffman_main[TableNum].TableData;

	/* Start reading the Huffman code word, bit by bit */
	error = 1;
	do 
	{

		/* Check if we've matched a code word */
		if((htptr[point] & 0xffff0000) == 0x00000000) 
		{
			error = 0;
			*x = (htptr[point] >> 4) & 0xf;
			*y = htptr[point] & 0xf;
			break;
		}

		if(br.GetBits(1)) 
		{ 
			/* Go right in tree */
			while((htptr[point] & 0xff) >= 250) 
			{
				point += htptr[point] & 0xff; 
			}
			point += htptr[point] & 0xff;
		}
		else 
		{ 
			/* Go left in tree */
			while((htptr[point] >> 16) >= 250) 
			{
				point += htptr[point] >> 16; 
			}
			point += htptr[point] >> 16;
		}
	} while((--bitsleft > 0) && (point < treelen));

	/* Check for error. */
	if(error) 
	{
		*x = *y = *v = *w = 0;
		return false;
	}

	/* Process sign encodings for quadruples tables. */
	if(TableNum > 31) 
	{
		*v = (*y >> 3) & 1;
		*w = (*y >> 2) & 1;
		*x = (*y >> 1) & 1;
		*y = *y & 1;

		if(*v > 0)
			if(br.GetBits(1)) 
				*v = -*v;
		if(*w > 0)
			if(br.GetBits(1)) 
				*w = -*w;
		if(*x > 0)
			if(br.GetBits(1)) 
				*x = -*x;
		if(*y > 0)
			if(br.GetBits(1)) 
				*y = -*y;
	} 
	else 
	{
		/* Get linbits */
		if((linbits > 0) && (*x == 15)) 
		{
			*x += br.GetBits(linbits);
		}

		/* Get sign bit */
		if(*x > 0) 
		{
			if(br.GetBits(1)) 
				*x = -*x;
		}

		/* Get linbits */
		if((linbits > 0) && (*y == 15)) 
		{
			*y += br.GetBits(linbits);
		}

		/* Get sign bit */
		if(*y > 0) 
		{
			if(br.GetBits(1)) 
				*y = -*y;
		}
	}

	return true;
}

bool CLayer3Decoder::ReadHuffman(unsigned long ch, unsigned long gr)
{
	unsigned long index = 0;
	unsigned long Part23End;
	unsigned long Region1;
	unsigned long Region2;
	unsigned long TableNumber;

	int x, y, v, w;

  
	Part23End = m_Part2Start[ch] + m_fr->m_SI.grinf[gr][ch].Part23Length;

	if(m_MpegVer == MPEG1)
	{
		m_MixedBandLimit[ch] = sfBandIndex[m_MpegVer][m_SampleFrequency].Long[8];
	}
	else
	{
		m_MixedBandLimit[ch] = sfBandIndex[m_MpegVer][m_SampleFrequency].Long[6];
	}

	if(	(m_fr->m_SI.grinf[gr][ch].WindowSwitchingFlag) && (m_fr->m_SI.grinf[gr][ch].BlockType == BLOCKTYPE_3WIN) )
	{
		Region1 = m_MixedBandLimit[ch];
		Region2 = 576;
	} 
	else 
	{
		Region1 = sfBandIndex[m_MpegVer][m_SampleFrequency].Long[m_fr->m_SI.grinf[gr][ch].Region0Count + 1];
		Region2 = sfBandIndex[m_MpegVer][m_SampleFrequency].Long[m_fr->m_SI.grinf[gr][ch].Region0Count + m_fr->m_SI.grinf[gr][ch].Region1Count + 2];
	}

	if(m_fr->m_SI.grinf[gr][ch].Part23Length == 0) 
	{
		for(index = 0; index < 576; index++) 
		{
			is[ch][index] = 0;
		}

		m_NonZero[ch] = 0;

		return true;
	}

	while(index < (m_fr->m_SI.grinf[gr][ch].BigValues << 1)) 
	{
		if(index < Region1) 
		{
			TableNumber = m_fr->m_SI.grinf[gr][ch].TableSelect[0];
		} 
		else if(index < Region2) 
		{
			TableNumber = m_fr->m_SI.grinf[gr][ch].TableSelect[1];
		} 
		else 
		{
			TableNumber = m_fr->m_SI.grinf[gr][ch].TableSelect[2];
		}
   
		if(!HuffmanDecode(TableNumber, &x, &y, &v, &w))
			return false;

		is[ch][index++]	= x;
		is[ch][index++]	= y;
	}

	unsigned long pos = br.GetPos();

	TableNumber = m_fr->m_SI.grinf[gr][ch].Count1Table_Select + 32;
	while((index < 576) && (pos < Part23End)) 
	{
		if(!HuffmanDecode(TableNumber, &x, &y, &v, &w))
			return false;
    
		is[ch][index++] = v;
		is[ch][index++] = w;
		is[ch][index++] = x;   
		is[ch][index++] = y;

		pos = br.GetPos();
	}


	pos = br.GetPos();
	if(pos > Part23End) 
	{
		index -= 4;
		if(index < 0)
			index = 0;
	}

	m_NonZero[ch] = index;

	br.SetPos(Part23End);

	for(; index < 576; index++) 
	{
		is[ch][index] = 0;
	}

	return true;
}

void CLayer3Decoder::DequantizeSample(int ch, int gr)
{
 	static const int pretab[22] = { 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0 };

	unsigned long index		= 0;
	int window		= 0;
	int windowsize	= 0;
	int sfb			= 0;
	int startband	= 0;
	float txr		= 0.0f;
    float globscale = GainTable[ m_fr->m_SI.grinf[gr][ch].GlobalGain ];


    if(m_fr->m_SI.grinf[gr][ch].WindowSwitchingFlag && m_fr->m_SI.grinf[gr][ch].BlockType == BLOCKTYPE_3WIN) 
	{
		if(m_fr->m_SI.grinf[gr][ch].MixedBlockFlag) 
		{
			int endblock = 0;
			// Mixed Block

			if(m_MpegVer == MPEG1)
			{
				endblock = 8;
			}
			else
			{
				endblock = 6;
			}


			for(sfb=0; sfb<endblock; sfb++)
			{
				windowsize = sfBandIndex[m_MpegVer][m_SampleFrequency].Long[sfb+1] - sfBandIndex[m_MpegVer][m_SampleFrequency].Long[sfb];

				for(int i=0; i<windowsize; i++)
				{
					txr = globscale * PowerTableMinus05[(1 + m_fr->m_SI.grinf[gr][ch].ScalefacScale) * (m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] + (m_fr->m_SI.grinf[gr][ch].PreFlag * pretab[sfb]) )];
					xr[ch][index] = txr * ( pow( (float)abs(is[ch][index]), (float)1.333333333333333) * ( is[ch][index] > 0 ? 1 : -1 ) );

					index ++;	// should be 36 at the end of all this!
				}
			}

			startband = 3;
		}

		// Short Block
		// xr[i] = sign(is[i]) * |is[i]|^(4/3) * 2 ^ 0.25 * (global_gain - 210 - 8 * subblock_gain[window]) * 2 ^ -(scalefac_multiplier * scalefac_s[band][window])

		// short blocks are arranged as 3 windowsize windows per scalefactorband
		// like this: 111 111 111  22 22 22  3 3 3
		//				SFB1		SFB2		SFB3 ... etc

		for(sfb=startband; sfb < 13; sfb++)
		{
			windowsize = sfBandIndex[m_MpegVer][m_SampleFrequency].Short[sfb+1] - sfBandIndex[m_MpegVer][m_SampleFrequency].Short[sfb];

			for(window = 0; window<3; window++)
			{
				for(int i=0; i<windowsize; i++)
				{
					txr = globscale * PowerTableMinus2[m_fr->m_SI.grinf[gr][ch].SubblockGain[window]] * PowerTableMinus05[(1 + m_fr->m_SI.grinf[gr][ch].ScalefacScale) * m_fr->m_SI.grinf[gr][ch].Scalefac_Short[sfb][window]];
					/* apply the sign(is[i]) * |is[i]| ^ (4/3) formula */
					xr[ch][index] = txr * ( pow( (float)abs(is[ch][index]), (float)1.333333333333333) * ( is[ch][index] > 0 ? 1 : -1 ) );
					index ++;
					if(index >= m_NonZero[ch])
						break;
				}
			}
		}
	}
	else
	{
		// Long Block
		// xr[i] = sign(is[i]) * | is[i] |^(4/3) * 2 ^ 0.25 * (global_gain - 210) * 2 ^ -(scalefac_multiplier * (scalefac_l[band] + preflag * pretab[band]))


		for(sfb=0; sfb<22; sfb++)
		{
			windowsize = sfBandIndex[m_MpegVer][m_SampleFrequency].Long[sfb+1] - sfBandIndex[m_MpegVer][m_SampleFrequency].Long[sfb];

			for(int i=0; i<windowsize; i++)
			{
				txr = globscale * PowerTableMinus05[(1 + m_fr->m_SI.grinf[gr][ch].ScalefacScale) * (m_fr->m_SI.grinf[gr][ch].Scalefac_Long[sfb] + (m_fr->m_SI.grinf[gr][ch].PreFlag * pretab[sfb]) )];
				xr[ch][index] = txr * ( pow( (float)abs(is[ch][index]), (float)1.333333333333333) * ( is[ch][index] > 0 ? 1 : -1 ) );
				index ++;
				if(index >= m_NonZero[ch])
					break;
			}
		}
	}

	for(; index<576; index++)
	{
		xr[ch][index] = 0.0;
	}
}

void CLayer3Decoder::Reorder(unsigned int ch, unsigned int gr)
{
    if(m_fr->m_SI.grinf[gr][ch].WindowSwitchingFlag && m_fr->m_SI.grinf[gr][ch].BlockType == BLOCKTYPE_3WIN) 
	{
		int ScaleFactorBand = 0;
		int BandStart;
		int BandSize;
		int Window, src, dst;
		int i;

		if(m_fr->m_SI.grinf[gr][ch].MixedBlockFlag) 
		{
			for(unsigned long index=0; index < m_MixedBandLimit[ch]; index++)
			{
		  		xrr[ch][index] = xr[ch][index];
			}


			ScaleFactorBand = 4;
		}

			/* short block, reorder everything  */
			// this is a 3window block, we need to reorder it.... in something like this
			// 111 222 333 444 555 666 777 888 999 101010 111111 121212
			// to
			// 123123123 456456456 789789789 101112101112101112
		do
		{
			BandStart = sfBandIndex[m_MpegVer][m_SampleFrequency].Short[ScaleFactorBand];
			BandSize  = sfBandIndex[m_MpegVer][m_SampleFrequency].Short[ScaleFactorBand+1] - BandStart;

			src = BandStart * 3;

			for(Window = 0; Window < 3; Window++)
			{
				dst = (BandStart * 3) + Window;

				for(i = 0; i < BandSize; i++) 
				{
					xrr[ch][dst] = xr[ch][src];
					src++;
					dst += 3;
				}
			}

			ScaleFactorBand++;

		} while(ScaleFactorBand < 13);
	}
	else
	{   
		// long blocks
		for(int index=0; index < 576; index++)
		{
			xrr[ch][index] = xr[ch][index];
		}
	}
}

void CLayer3Decoder::CalculateK(int index, int is_pos, int intensity_scale)
{
	// MPEG2/2.5

	if(is_pos == 0)
	{
		kl[index] = 1.0;
		kr[index] = 1.0;
	}
	else
	{

		if(intensity_scale == 1)
		{
			if(is_pos%2==1)
			{
				kl[index] = (float)pow(2.0f, -( (is_pos+1) / (4)) );
				kr[index] = 1.0;
			}
			else
			{
				kl[index] = 1.0;
				kr[index] = (float)pow(2.0f, -(is_pos/(4)) );
			}
		}
		else
		{
			if(is_pos%2==1)
			{
				kl[index] = (float)pow(2.0f, -( (is_pos+1) / (8)) );
				kr[index] = 1.0;
			}
			else
			{
				kl[index] = 1.0;
				kr[index] = (float)pow(2.0f, -(is_pos/(8)) );
			}
		}
	}
}

void CLayer3Decoder::Stereo(unsigned int gr)
{
	int index;

	if(m_Channels == 2)		// dont bother with stereo processing unless its STEREO duuh
	{
		int MS_Stereo	= (m_Mode == MODE_JOINT_STEREO) && (m_ModeExt & MODE_EXT_MS);
		int I_Stereo	= (m_Mode == MODE_JOINT_STEREO) && (m_ModeExt & MODE_EXT_IS);

		int	is_pos;	// intensity stereo positions
		int is_valid[576];
		float	is_ratio[576];	// intensity stereo left / right ratio

		int		intensity_scale = (m_fr->m_SI.grinf[gr][0].ScalefacCompress % 2);

		if(I_Stereo)
		{
			for(index=0; index<576; index++)
				is_valid[index] = 0;


			if(m_fr->m_SI.grinf[gr][0].WindowSwitchingFlag && (m_fr->m_SI.grinf[gr][0].BlockType == BLOCKTYPE_3WIN)) 
			{
				if(m_fr->m_SI.grinf[gr][0].MixedBlockFlag) 
				{
//					printf("Mixed Block - Arrgh");
				}
				else
				{
					unsigned long startband = 0;
					while((unsigned long)(sfBandIndex[m_MpegVer][m_SampleFrequency].Short[startband]*3) < m_NonZero[1])
						startband ++;

					for(int sfb=startband; sfb<13; sfb++)
					{
						int windowsize = sfBandIndex[m_MpegVer][m_SampleFrequency].Short[sfb+1] - sfBandIndex[m_MpegVer][m_SampleFrequency].Short[sfb];

						for(int window=0; window<3; window++)
						{
							int sfb_start = sfBandIndex[m_MpegVer][m_SampleFrequency].Short[sfb]*3 + windowsize*window;
							int sfb_stop = sfb_start + windowsize;

							for(int i = sfb_start; i < sfb_stop; i++) 
							{
								is_pos = m_fr->m_SI.grinf[gr][1].Scalefac_Short[ sfb ][window];

								if(m_MpegVer == MPEG1)
								{
									if (is_pos != 7)
									{
										is_ratio[ i ] = TanPi12Table[ is_pos ];
										is_valid[ i ] = 1;
									}
								}
								else
								{
									if(is_pos != m_fr->m_SI.grinf[gr][1].is_max[ sfb ] )
									{
										CalculateK(i, is_pos, intensity_scale);
										is_valid[ i ] = 1;
									}
								}
							}
						}
					}
				}
			}
			else
			{
				int i;

				int startband = 0;

				while(sfBandIndex[m_MpegVer][m_SampleFrequency].Long[startband] < m_NonZero[1])
					startband ++;

				for(int sfb = startband; sfb<22; sfb++)
				{
					i = sfBandIndex[m_MpegVer][m_SampleFrequency].Long[sfb];

					int windowsize = sfBandIndex[m_MpegVer][m_SampleFrequency].Long[sfb+1] - sfBandIndex[m_MpegVer][m_SampleFrequency].Long[sfb];

					for(int w=0; w<windowsize; w++)
					{
						is_pos = m_fr->m_SI.grinf[gr][1].Scalefac_Long[ sfb ];

						if(m_MpegVer == MPEG1)
						{
							if (is_pos != 7)
							{
								is_ratio[ i ] = TanPi12Table[ is_pos ];
								is_valid[ i ] = 1;
							}
						}
						else
						{
							if(is_pos != m_fr->m_SI.grinf[gr][1].is_max[ sfb ] )
							{
								CalculateK(i, is_pos, intensity_scale);
								is_valid[ i ] = 1;
							}
						}

						i++;
					}
				}
			}

			// process the intensity stere stuff
			for(index=0; index<576; index++)
			{
				float temp = xrr[0][index];

				if( is_valid[index] == 0 )
				{	
					// NOT intensity Stereo Mode
					if(MS_Stereo) 
					{
						// MSStereo mode. we have to undo it...
						xrr[0][index] = (temp + xrr[1][index]) / SQRT2;
						xrr[1][index] = (temp - xrr[1][index]) / SQRT2;
					} 
				}
				else
				{
					// this IS an intensity stereo value
					if(m_MpegVer == MPEG1)
					{
						xrr[0][index] = temp * (is_ratio[index] / (1.0f + is_ratio[index]));
						xrr[1][index] = temp * (1.0f / (1.0f + is_ratio[index])); 
					}
					else
					{
						xrr[0][index] = temp * kl[index];
						xrr[1][index] = temp * kr[index];
					}
				}
			}
		}
		else if(MS_Stereo) 
		{
			// MSStereo mode. we have to undo it...
			for(index=0; index<576; index++)
			{
				float temp = xrr[0][index];
				xrr[0][index] = (temp + xrr[1][index]) / SQRT2;
				xrr[1][index] = (temp - xrr[1][index]) / SQRT2;
			}
		} 
	}
}

void CLayer3Decoder::AntiAlias(unsigned int ch, unsigned int gr)
{
	int sb_amount;

	int index =0;

	if(m_fr->m_SI.grinf[gr][ch].BlockType != BLOCKTYPE_3WIN)
	{
		sb_amount = 558;	// antialias the full stectrum
	}
	else
	{
		if(m_fr->m_SI.grinf[gr][ch].MixedBlockFlag)
		{	// this is a long block, then a short block
			sb_amount = m_MixedBandLimit[ch];
		}
		else	// No antialiasing for short blocks
		{
			return;
		}
	}

    int src_idx1;
	int src_idx2;

	register float temp;

	for(int sb = 18; sb < sb_amount; sb+=18)
	{
		for(int i=0; i<8; i++)
		{
			src_idx1 = sb - 1 - i;
			src_idx2 = sb + i;

			temp = xrr[ch][src_idx1];

			xrr[ch][src_idx1] = (temp * Cs[i])				- (xrr[ch][src_idx2] * Ca[i]);
			xrr[ch][src_idx2] = (xrr[ch][src_idx2] * Cs[i]) + (temp * Ca[i]);
		}
	}

}

void CLayer3Decoder::FreqencyInverse(int gr, int ch)
{
    int sb, ss;

	int offset;

	for(sb = 1; sb < 32; sb+=2)
	{
		offset = 32;
		for(ss=1; ss<18; ss+=2)
		{
			xir[ch][offset+sb] = -xir[ch][offset+sb];
			offset += 64;
		}
	}
}

void CLayer3Decoder::IMDCT(float *in, float *out, int block_type)
{
	if(block_type == 2)
	{
		float	tmp[18];
		register float	sum;
		register float save;
		register float	pp1;

		int		six_i = 6;
		int		window;

		for(int i=0; i<36; i++)
		{
			out[i] = 0.0;
		}

		for(window=0; window<3; window++)
   		{
			in[15+window] += in[12+window];
			in[12+window] += in[9+window];
			in[9+window]  += in[6+window];
			in[6+window]  += in[3+window];
			in[3+window]  += in[window];

			in[15+window] += in[9+window];
			in[9+window]  += in[3+window];

			pp1 = in[6+window] * ShortTwiddles[0];
			sum = in[window]   + in[12+window] * ShortTwiddles[1];

			tmp[1] = in[window] - in[12+window];
			tmp[0] = sum + pp1;
			tmp[2] = sum - pp1;

			pp1 = in[9+window] * ShortTwiddles[0];
			sum = in[3+window] + in[15+window] * ShortTwiddles[1];

			tmp[4] = in[3+window] - in[15+window];
			tmp[5] = sum + pp1;
			tmp[3] = sum - pp1;

			tmp[3] *= ShortTwiddles[2];
			tmp[4] *= ShortTwiddles[3];
			tmp[5] *= ShortTwiddles[4];

			save = tmp[0];
			tmp[0] += tmp[5];
			tmp[5]  = save - tmp[5];

			save = tmp[1];
			tmp[1] += tmp[4];
			tmp[4]  = save - tmp[4];

			save = tmp[2];
			tmp[2] += tmp[3];
			tmp[3]  = save - tmp[3];

			tmp[0] *= ShortTwiddles[5];
			tmp[1] *= ShortTwiddles[6];
			tmp[2] *= ShortTwiddles[7];
			tmp[3] *= ShortTwiddles[8];
			tmp[4] *= ShortTwiddles[9];
			tmp[5] *= ShortTwiddles[10];

			tmp[6]  = -tmp[2] * ShortTwiddles[15];
			tmp[7]  = -tmp[1] * ShortTwiddles[13];
			tmp[8]  = -tmp[0] * ShortTwiddles[11];
			tmp[9]  = -tmp[0] * ShortTwiddles[12];
			tmp[10] = -tmp[1] * ShortTwiddles[14];
			tmp[11] = -tmp[2] * ShortTwiddles[16];

			tmp[0]  =  tmp[3];
			tmp[1]  =  tmp[4] * ShortTwiddles[17];
			tmp[2]  =  tmp[5] * ShortTwiddles[18];

			tmp[3]  = -tmp[5] * ShortTwiddles[19];
			tmp[4]  = -tmp[4] * ShortTwiddles[20];
			tmp[5]  = -tmp[0] * ShortTwiddles[21];

			tmp[0] *= ShortTwiddles[22];

   			out[six_i]		+= tmp[0];
			out[six_i + 1]  += tmp[1];
	   		out[six_i + 2]  += tmp[2];
			out[six_i + 3]  += tmp[3];
   			out[six_i + 4]  += tmp[4];
			out[six_i + 5]  += tmp[5];
	   		out[six_i + 6]  += tmp[6];
			out[six_i + 7]  += tmp[7];
	   		out[six_i + 8]  += tmp[8];
			out[six_i + 9]  += tmp[9];
	   		out[six_i + 10] += tmp[10];
			out[six_i + 11] += tmp[11];

   			six_i += 6;
   		}
	} 
	else 
	{
		float	tmp[18];

		int i, j;
		register float sum;
		register float sum2;
		register float save;

	    in[17] += in[16];
	    in[16] += in[15];
	    in[15] += in[14];
	    in[14] += in[13];
	    in[13] += in[12];
	    in[12] += in[11];
	    in[11] += in[10];
	    in[10] += in[9];
	    in[9]  += in[8];
	    in[8]  += in[7];
	    in[7]  += in[6];
	    in[6]  += in[5];
	    in[5]  += in[4];
	    in[4]  += in[3];
	    in[3]  += in[2];
	    in[2]  += in[1];
	    in[1]  += in[0];

		in[17] += in[15];
	    in[15] += in[13];
	    in[13] += in[11];
	    in[11] += in[9];
	    in[9]  += in[7];
	    in[7]  += in[5];
	    in[5]  += in[3];
	    in[3]  += in[1];

		j = 0;
		i = 0;

		int b = 9;
		do
		{
			sum = in[0];
			sum2 = in[1];

			sum  += in[2]  * IMDCT9x8Table[j];
			sum2 += in[3]  * IMDCT9x8Table[j];
			sum  += in[4]  * IMDCT9x8Table[j+1];
			sum2 += in[5]  * IMDCT9x8Table[j+1];
			sum  += in[6]  * IMDCT9x8Table[j+2];
			sum2 += in[7]  * IMDCT9x8Table[j+2];
			sum  += in[8]  * IMDCT9x8Table[j+3];
			sum2 += in[9]  * IMDCT9x8Table[j+3];
			sum  += in[10] * IMDCT9x8Table[j+4];
			sum2 += in[11] * IMDCT9x8Table[j+4];
			sum  += in[12] * IMDCT9x8Table[j+5];
			sum2 += in[13] * IMDCT9x8Table[j+5];
			sum  += in[14] * IMDCT9x8Table[j+6];
			sum2 += in[15] * IMDCT9x8Table[j+6];
			sum  += in[16] * IMDCT9x8Table[j+7];
			sum2 += in[17] * IMDCT9x8Table[j+7];

			tmp[i]		= sum;
			tmp[17-i]	= sum2;

			j += 8;
			i++;

		} while(--b);

		tmp[9]  *= NormalTwiddles[0];
		tmp[10] *= NormalTwiddles[1];
		tmp[11] *= NormalTwiddles[2];
		tmp[12] *= NormalTwiddles[3];
		tmp[13] *= NormalTwiddles[4];
		tmp[14] *= NormalTwiddles[5];
		tmp[15] *= NormalTwiddles[6];
		tmp[16] *= NormalTwiddles[7];
		tmp[17] *= NormalTwiddles[8];

	    for(i = 0; i < 9; i++) 
		{
			save		 = tmp[i];
			tmp[i]		+= tmp[17-i];
			tmp[17-i]	 = save - tmp[17-i];
	    }

		tmp[0]  *= NormalTwiddles[9];
		tmp[1]  *= NormalTwiddles[10];
		tmp[2]  *= NormalTwiddles[11];
		tmp[3]  *= NormalTwiddles[12];
		tmp[4]  *= NormalTwiddles[13];
		tmp[5]  *= NormalTwiddles[14];
		tmp[6]  *= NormalTwiddles[15];
		tmp[7]  *= NormalTwiddles[16];
		tmp[8]  *= NormalTwiddles[17];
		tmp[9]  *= NormalTwiddles[18];
		tmp[10] *= NormalTwiddles[19];
		tmp[11] *= NormalTwiddles[20];
		tmp[12] *= NormalTwiddles[21];
		tmp[13] *= NormalTwiddles[22];
		tmp[14] *= NormalTwiddles[23];
		tmp[15] *= NormalTwiddles[24];
		tmp[16] *= NormalTwiddles[25];
		tmp[17] *= NormalTwiddles[26];

	    for(i = 0; i < 9; i++) 
		{
			out[i]		= -tmp[i+9]	* IMDCTwin[block_type][i];
			out[i+9]	= tmp[17-i]	* IMDCTwin[block_type][i+9];
			out[i+18]	= tmp[8-i]	* IMDCTwin[block_type][i+18];
			out[i+27]	= tmp[i]	* IMDCTwin[block_type][i+27];
	    }
	}
}

void CLayer3Decoder::Hybrid(int ch, float *xfrom, float *xto, int blocktype, int windowswitching, int mixedblock)
{
	float rawout[36];
	unsigned int bt;
	int sb18 = 0;
	int sb = 0;

	int x = 32;

	do
	{
		bt = (windowswitching && mixedblock && (sb18 < 36)) ? 0 : blocktype;

		IMDCT(&xfrom[sb18], rawout, bt);

		xto[sb]		= rawout[ 0] + prevblck[ch][sb18+0];
		xto[sb+32]	= rawout[ 1] + prevblck[ch][sb18+1];
		xto[sb+64]	= rawout[ 2] + prevblck[ch][sb18+2];
		xto[sb+96]	= rawout[ 3] + prevblck[ch][sb18+3];
		xto[sb+128]	= rawout[ 4] + prevblck[ch][sb18+4];
		xto[sb+160]	= rawout[ 5] + prevblck[ch][sb18+5];
		xto[sb+192]	= rawout[ 6] + prevblck[ch][sb18+6];
		xto[sb+224]	= rawout[ 7] + prevblck[ch][sb18+7];
		xto[sb+256]	= rawout[ 8] + prevblck[ch][sb18+8];
		xto[sb+288]	= rawout[ 9] + prevblck[ch][sb18+9];
		xto[sb+320]	= rawout[10] + prevblck[ch][sb18+10];
		xto[sb+352]	= rawout[11] + prevblck[ch][sb18+11];
		xto[sb+384]	= rawout[12] + prevblck[ch][sb18+12];
		xto[sb+416]	= rawout[13] + prevblck[ch][sb18+13];
		xto[sb+448]	= rawout[14] + prevblck[ch][sb18+14];
		xto[sb+480]	= rawout[15] + prevblck[ch][sb18+15];
		xto[sb+512]	= rawout[16] + prevblck[ch][sb18+16];
		xto[sb+544]	= rawout[17] + prevblck[ch][sb18+17];

		prevblck[ch][sb18+0]	= rawout[18];
		prevblck[ch][sb18+1]	= rawout[19];
		prevblck[ch][sb18+2]	= rawout[20];
		prevblck[ch][sb18+3]	= rawout[21];
		prevblck[ch][sb18+4]	= rawout[22];
		prevblck[ch][sb18+5]	= rawout[23];
		prevblck[ch][sb18+6]	= rawout[24];
		prevblck[ch][sb18+7]	= rawout[25];
		prevblck[ch][sb18+8]	= rawout[26];
		prevblck[ch][sb18+9]	= rawout[27];
		prevblck[ch][sb18+10]	= rawout[28];
		prevblck[ch][sb18+11]	= rawout[29];
		prevblck[ch][sb18+12]	= rawout[30];
		prevblck[ch][sb18+13]	= rawout[31];
		prevblck[ch][sb18+14]	= rawout[32];
		prevblck[ch][sb18+15]	= rawout[33];
		prevblck[ch][sb18+16]	= rawout[34];
		prevblck[ch][sb18+17]	= rawout[35];

		sb++;
		sb18+=18;

	} while(--x);
}

bool CLayer3Decoder::ProcessFrame(Frame * fr, float * PCMSamples, unsigned long * NumSamples)
{
	unsigned long ch, gr;

	m_fr = fr;

	if(NumSamples)
		*NumSamples = 0;

	m_MpegVer			= fr->m_Header.GetMpegVersion();
	m_Mode				= fr->m_Header.GetMode();
	m_ModeExt			= fr->m_Header.GetModeExtension();
	m_Channels			= fr->m_Header.GetChannels();
	m_SampleFrequency	= fr->m_Header.GetSampleFrequencyIndex();
	m_Granules			= (m_MpegVer) == MPEG1 ? 2 : 1;

	br.FillBitReserve(m_fr->m_Data, m_fr->m_Header.GetDataSize());

	if(!br.BackStep(m_fr->m_SI.MainDataBegin))
	{
		return(false);
	}

	if(!PCMSamples)
	{
		return(true);
	}

	for(gr=0; gr<m_Granules; gr++)
	{
		for(ch = 0; ch<m_Channels; ch++)
		{
			m_Part2Start[ch] = br.GetPos();

			DecodeScalefactors(ch, gr);
			ReadHuffman(ch, gr);
			DequantizeSample(ch, gr);
         	Reorder(ch, gr);
		}

		Stereo(gr);

		for(ch = 0; ch<m_Channels; ch++)
		{
			AntiAlias(ch, gr);
			Hybrid(ch, xrr[ch], xir[ch], m_fr->m_SI.grinf[gr][ch].BlockType, m_fr->m_SI.grinf[gr][ch].WindowSwitchingFlag, m_fr->m_SI.grinf[gr][ch].MixedBlockFlag);
			FreqencyInverse(gr, ch);
		}

		if(m_Channels == 1)
		{
			for(int ss=0; ss<576; ss+=32)
			{
				PerformSynthesis(&xir[0][ss], ((float*)PCMSamples)+*NumSamples, 0, 1);

				*NumSamples += 32;
			}
		}
		else
		{
			for(int ss=0; ss<576; ss+=32)
			{
				PerformSynthesis(&xir[0][ss], ((float*)PCMSamples)+*NumSamples, 0, 2);
				PerformSynthesis(&xir[1][ss], ((float*)PCMSamples)+*NumSamples, 1, 2);

				*NumSamples += 64;
			}
		}
	}

	return(true);
}
