📄 huff.c
字号:
/****************************************************************************//* * huff.c -- Huffman Code handling * * Author : St閜hane TAVENARD * * (C) Copyright 1997-1997 St閜hane TAVENARD * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//****************************************************************************/#include "defs.h"#include "mpegaud.h"#include "mpegtab.h"/****************************************************************************//* * Open an huffman stream. */HUFFMAN *HUFF_open(void){ HUFFMAN *h; h = (HUFFMAN *) malloc(sizeof(*h)); if (!h) return(NULL); memset(h, 0, sizeof(*h));// h->buffer = fmalloc(HUFF_BUFFER_SIZE); lishuifen h->buffer = malloc(HUFF_BUFFER_SIZE); if (!h) { HUFF_close(h); return NULL; } memset(h->buffer, 0, HUFF_BUFFER_SIZE); h->buffer_size = HUFF_BUFFER_SIZE; return(h);}/****************************************************************************//* * Close the huffman stream. */void HUFF_close(HUFFMAN *h){ if (h) { if (h->buffer) // ffree(h->buffer); free(h->buffer); free(h); }}/****************************************************************************//* * Reset an huffman stream. */int HUFF_reset(HUFFMAN *h){ if (!h) return(-1); h->write_index = h->read_index = 0; h->bit_cache = h->cache_size = 0; h->nul_begin = 576; // begin of last null zone return(0);}/****************************************************************************//* * Write bytes to huffman buffer. */void HUFF_fill_bytes(HUFFMAN *h, unsigned int count, char *buffer){ unsigned int to_fill; while (count > 0) { to_fill = HUFF_BUFFER_SIZE - h->write_index; if (to_fill > count) to_fill = count; memcpy(&h->buffer[h->write_index], buffer, to_fill); count -= to_fill; buffer += to_fill; h->write_index += to_fill; if (h->write_index >= HUFF_BUFFER_SIZE) h->write_index = 0; }}/****************************************************************************//* * Set the start pos of the huffman buffer * relative to the end of buffer (byte size). * start_pos is used as a negative offset. */int HUFF_set_start(HUFFMAN *h, int start_pos){ int size; size = h->write_index - h->read_index + (h->cache_size>>3); if (size < 0) size += HUFF_BUFFER_SIZE; if (size < start_pos) return(-1); h->read_index = (h->write_index - start_pos) & (HUFF_BUFFER_SIZE-1); h->cache_size = 0; // Flush cache return(0);}/****************************************************************************/#define FILL_CACHE(h) { \ h->bit_cache = \ ((UINT32)h->buffer[h->read_index & (HUFF_BUFFER_SIZE-1) ])<<24 |\ ((UINT32)h->buffer[(h->read_index + 1) & (HUFF_BUFFER_SIZE-1)])<<16 |\ ((UINT32)h->buffer[(h->read_index + 2) & (HUFF_BUFFER_SIZE-1)])<<8 |\ ((UINT32)h->buffer[(h->read_index + 3) & (HUFF_BUFFER_SIZE-1)]);\ h->read_index = (h->read_index + 4) & (HUFF_BUFFER_SIZE-1);\}/****************************************************************************//* * Seek to a bit pos in the huffman buffer * (absolute pos) */int HUFF_seek(HUFFMAN *h, int seek_pos){ int advance; h->read_index = (seek_pos >> 3) & (HUFF_BUFFER_SIZE-1); advance = seek_pos & 7; FILL_CACHE(h); h->cache_size = 32; // Discard some bits if not aligned if (advance) HUFF_read_bits(h, advance); return(0);}/****************************************************************************//* * Update the bit cache and return next bit. */unsigned long HUFF_read_bit_cache(HUFFMAN *h){ unsigned long bits; FILL_CACHE(h); h->cache_size = 31; bits = (h->bit_cache & 0x80000000) ? 1 : 0; h->bit_cache <<= 1; return(bits);}/****************************************************************************//* * Update the bit cache and return next bits. */unsigned long HUFF_read_bits_cache(HUFFMAN *h, unsigned int count){ unsigned long bits; if (h->cache_size > 0) { bits = h->bit_cache >> (32 - count); count -= h->cache_size; } else { bits = 0; } FILL_CACHE(h); h->cache_size = 32 - count; bits |= h->bit_cache >> (32 - count); h->bit_cache <<= count; return(bits);}/****************************************************************************//* * Huffman tables. */static const UINT32 h1[4] = { 0x00000311, 0x20000301, 0x40000210, 0x80000100};static const UINT32 h2[9] = { 0x00000622, 0x04000602, 0x08000512, 0x10000521, 0x18000520, 0x20000311, 0x40000301, 0x60000310, 0x80000100};static const UINT32 h3[9] = { 0x00000622, 0x04000602, 0x08000512, 0x10000521, 0x18000520, 0x20000310, 0x40000211, 0x80000201, 0xc0000200};static const UINT32 h5[16] = { 0x00000833, 0x01000823, 0x02000732, 0x04000631, 0x08000713, 0x0a000703, 0x0c000730, 0x0e000722, 0x10000612, 0x14000621, 0x18000602, 0x1c000620, 0x20000311, 0x40000301, 0x60000310, 0x80000100};static const UINT32 h6[16] = { 0x00000733, 0x02000703, 0x04000623, 0x08000632, 0x0c000630, 0x10000513, 0x18000531, 0x20000522, 0x28000502, 0x30000412, 0x40000421, 0x50000420, 0x60000301, 0x80000211, 0xc0000310, 0xe0000300};static const UINT32 h7[36] = { 0x00000a55, 0x00400a45, 0x00800a54, 0x00c00a53, 0x01000935, 0x01800944, 0x02000925, 0x02800952, 0x03000815, 0x04000851, 0x05000905, 0x05800934, 0x06000850, 0x07000943, 0x07800933, 0x08000824, 0x09000842, 0x0a000714, 0x0c000741, 0x0e000740, 0x10000804, 0x11000823, 0x12000832, 0x13000803, 0x14000713, 0x16000731, 0x18000730, 0x1a000722, 0x1c000612, 0x20000521, 0x28000602, 0x2c000620, 0x30000411, 0x40000301, 0x60000310, 0x80000100};static const UINT32 h8[36] = { 0x00000b55, 0x00200b54, 0x00400a45, 0x00800953, 0x01000a35, 0x01400a44, 0x01800925, 0x02000952, 0x02800905, 0x03000815, 0x04000851, 0x05000934, 0x05800943, 0x06000950, 0x06800933, 0x07000824, 0x08000842, 0x09000814, 0x0a000741, 0x0c000804, 0x0d000840, 0x0e000823, 0x0f000832, 0x10000813, 0x11000831, 0x12000803, 0x13000830, 0x14000622, 0x18000602, 0x1c000620, 0x20000412, 0x30000421, 0x40000211, 0x80000301, 0xa0000310, 0xc0000200};static const UINT32 h9[36] = { 0x00000955, 0x00800945, 0x01000835, 0x02000853, 0x03000954, 0x03800905, 0x04000844, 0x05000825, 0x06000852, 0x07000815, 0x08000751, 0x0a000734, 0x0c000743, 0x0e000850, 0x0f000804, 0x10000724, 0x12000742, 0x14000733, 0x16000740, 0x18000614, 0x1c000641, 0x20000623, 0x24000632, 0x28000513, 0x30000531, 0x38000603, 0x3c000630, 0x40000522, 0x48000502, 0x50000412, 0x60000421, 0x70000420, 0x80000311, 0xa0000301, 0xc0000310, 0xe0000300};static const UINT32 h10[64] = { 0x00000b77, 0x00200b67, 0x00400b76, 0x00600b57, 0x00800b75, 0x00a00b66, 0x00c00a47, 0x01000a74, 0x01400a56, 0x01800a65, 0x01c00a37, 0x02000a73, 0x02400a46, 0x02800b55, 0x02a00b54, 0x02c00a63, 0x03000927, 0x03800972, 0x04000a64, 0x04400a07, 0x04800970, 0x05000962, 0x05800a45, 0x05c00a35, 0x06000906, 0x06800a53, 0x06c00a44, 0x07000817, 0x08000871, 0x09000936, 0x09800926, 0x0a000a25, 0x0a400a52, 0x0a800915, 0x0b000951, 0x0b800a34, 0x0bc00a43, 0x0c000816, 0x0d000861, 0x0e000860, 0x0f000905, 0x0f800950, 0x10000924, 0x10800942, 0x11000933, 0x11800904, 0x12000814, 0x13000841, 0x14000840, 0x15000823, 0x16000832, 0x17000803, 0x18000713, 0x1a000731, 0x1c000730, 0x1e000722, 0x20000612, 0x24000621, 0x28000602, 0x2c000620, 0x30000411, 0x40000301, 0x60000310, 0x80000100};static const UINT32 h11[64] = { 0x00000a77, 0x00400a67, 0x00800a76, 0x00c00a75, 0x01000a66, 0x01400a47, 0x01800a74, 0x01c00b57, 0x01e00b55, 0x02000a56, 0x02400a65, 0x02800937, 0x03000973, 0x03800946, 0x04000a45, 0x04400a54, 0x04800a35, 0x04c00a53, 0x05000827, 0x06000872, 0x07000964, 0x07800907, 0x08000771, 0x0a000817, 0x0b000870, 0x0c000836, 0x0d000863, 0x0e000860, 0x0f000944, 0x0f800925, 0x10000952, 0x10800905, 0x11000815, 0x12000762, 0x14000826, 0x15000806, 0x16000716, 0x18000761, 0x1a000851, 0x1b000834, 0x1c000850, 0x1d000943, 0x1d800933, 0x1e000824, 0x1f000842, 0x20000814, 0x21000841, 0x22000804, 0x23000840, 0x24000723, 0x26000732, 0x28000613, 0x2c000631, 0x30000703, 0x32000730, 0x34000622, 0x38000521, 0x40000412, 0x50000502, 0x58000520, 0x60000311, 0x80000301, 0xa0000310, 0xc0000200};static const UINT32 h12[64] = { 0x00000a77, 0x00400a67, 0x00800976, 0x01000957, 0x01800975, 0x02000966, 0x02800947, 0x03000974, 0x03800965, 0x04000856, 0x05000837, 0x06000973, 0x06800955, 0x07000827, 0x08000872, 0x09000846, 0x0a000864, 0x0b000817, 0x0c000871, 0x0d000907, 0x0d800970, 0x0e000836, 0x0f000863, 0x10000845, 0x11000854, 0x12000844, 0x13000906, 0x13800905, 0x14000726, 0x16000762, 0x18000761, 0x1a000816, 0x1b000860, 0x1c000835, 0x1d000853, 0x1e000825, 0x1f000852, 0x20000715, 0x22000751, 0x24000734, 0x26000743, 0x28000850, 0x29000804, 0x2a000724, 0x2c000742, 0x2e000714, 0x30000633, 0x34000641,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -