mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
can be of use later
This commit is contained in:
199
ttalib-1.1/BitReader.h
Normal file
199
ttalib-1.1/BitReader.h
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* BitReader.h
|
||||
*
|
||||
* Description: Bit reader internal interface
|
||||
*
|
||||
* Copyright (c) 2004 Alexander Djourik. All rights reserved.
|
||||
* Copyright (c) 2004 Pavel Zhilin. 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
|
||||
* aint with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Please see the file COPYING in this directory for full copyright
|
||||
* information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include "TTACommon.h"
|
||||
#include "TTAError.h"
|
||||
#include "crc32.h"
|
||||
|
||||
namespace TTALib
|
||||
{
|
||||
class BitReader
|
||||
{
|
||||
protected:
|
||||
HANDLE hInFile;
|
||||
|
||||
unsigned char bit_buffer[BIT_BUFFER_SIZE + 8];
|
||||
unsigned char *bit_buffer_end;
|
||||
|
||||
unsigned long frame_crc32;
|
||||
unsigned long bit_count;
|
||||
unsigned long bit_cache;
|
||||
unsigned char *bitpos;
|
||||
|
||||
unsigned long *st;
|
||||
unsigned long next_frame_pos;
|
||||
|
||||
public:
|
||||
BitReader(HANDLE fd) :
|
||||
frame_crc32(0xFFFFFFFFUL), hInFile (fd),
|
||||
bit_count(0), bit_cache(0), bit_buffer_end(bit_buffer + BIT_BUFFER_SIZE),
|
||||
bitpos(bit_buffer_end), input_byte_count (0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~BitReader(void) {}
|
||||
|
||||
virtual void GetHeader (TTAHeader *ttahdr)
|
||||
{
|
||||
unsigned long result, checksum;
|
||||
|
||||
if (!ReadFile(hInFile, ttahdr, sizeof(TTAHeader), &result, NULL) ||
|
||||
result != sizeof (TTAHeader))
|
||||
{
|
||||
throw TTAException (READ_ERROR);
|
||||
} else input_byte_count += sizeof(*ttahdr);
|
||||
|
||||
// check for supported formats
|
||||
if (ENDSWAP_INT32(ttahdr->TTAid) != TTA1_SIGN)
|
||||
throw TTAException (FORMAT_ERROR);
|
||||
|
||||
checksum = crc32((unsigned char *) ttahdr, sizeof(TTAHeader) - sizeof(long));
|
||||
if (checksum != ttahdr->CRC32)
|
||||
throw TTAException (FILE_ERROR);
|
||||
|
||||
ttahdr->AudioFormat = ENDSWAP_INT16(ttahdr->AudioFormat);
|
||||
ttahdr->NumChannels = ENDSWAP_INT16(ttahdr->NumChannels);
|
||||
ttahdr->BitsPerSample = ENDSWAP_INT16(ttahdr->BitsPerSample);
|
||||
ttahdr->SampleRate = ENDSWAP_INT32(ttahdr->SampleRate);
|
||||
ttahdr->DataLength = ENDSWAP_INT32(ttahdr->DataLength);
|
||||
}
|
||||
|
||||
virtual bool GetSeekTable (unsigned long *seek_table, long st_size)
|
||||
{
|
||||
unsigned long result, checksum;
|
||||
bool st_state = false;
|
||||
|
||||
if (!ReadFile(hInFile, seek_table, st_size * sizeof(long), &result, NULL) ||
|
||||
result != st_size * sizeof(long))
|
||||
throw TTAException (READ_ERROR);
|
||||
else input_byte_count += st_size * sizeof(long);
|
||||
|
||||
checksum = crc32((unsigned char *) seek_table, (st_size - 1) * sizeof(long));
|
||||
if (checksum == ENDSWAP_INT32(seek_table[st_size - 1]))
|
||||
st_state = true;
|
||||
|
||||
for (st = seek_table; st < (seek_table + st_size); st++)
|
||||
*st = ENDSWAP_INT32(*st);
|
||||
|
||||
next_frame_pos = SetFilePointer (hInFile, 0, NULL, FILE_CURRENT);
|
||||
st = seek_table;
|
||||
|
||||
return st_state;
|
||||
}
|
||||
|
||||
virtual void GetBinary(unsigned long *value, unsigned long bits) {
|
||||
while (bit_count < bits) {
|
||||
if (bitpos == bit_buffer_end) {
|
||||
unsigned long result;
|
||||
if (!ReadFile (hInFile, bit_buffer, BIT_BUFFER_SIZE, &result, NULL))
|
||||
throw TTAException (READ_ERROR);
|
||||
input_byte_count += result;
|
||||
bitpos = bit_buffer;
|
||||
}
|
||||
|
||||
UPDATE_CRC32(*bitpos, frame_crc32);
|
||||
bit_cache |= *bitpos << bit_count;
|
||||
bit_count += 8;
|
||||
bitpos++;
|
||||
}
|
||||
|
||||
*value = bit_cache & bit_mask[bits];
|
||||
bit_cache >>= bits;
|
||||
bit_count -= bits;
|
||||
bit_cache &= bit_mask[bit_count];
|
||||
}
|
||||
|
||||
virtual void GetUnary(unsigned long *value)
|
||||
{
|
||||
*value = 0;
|
||||
|
||||
while (!(bit_cache ^ bit_mask[bit_count])) {
|
||||
if (bitpos == bit_buffer_end) {
|
||||
unsigned long result;
|
||||
if (!ReadFile (hInFile, bit_buffer, BIT_BUFFER_SIZE, &result, NULL))
|
||||
throw TTAException (READ_ERROR);
|
||||
input_byte_count += result;
|
||||
bitpos = bit_buffer;
|
||||
}
|
||||
|
||||
*value += bit_count;
|
||||
bit_cache = *bitpos++;
|
||||
UPDATE_CRC32(bit_cache, frame_crc32);
|
||||
bit_count = 8;
|
||||
}
|
||||
|
||||
while (bit_cache & 1) {
|
||||
(*value)++;
|
||||
bit_cache >>= 1;
|
||||
bit_count--;
|
||||
}
|
||||
|
||||
bit_cache >>= 1;
|
||||
bit_count--;
|
||||
}
|
||||
|
||||
virtual int Done ()
|
||||
{
|
||||
unsigned long crc32, rbytes, result;
|
||||
frame_crc32 ^= 0xFFFFFFFFUL;
|
||||
|
||||
next_frame_pos += *st++;
|
||||
|
||||
rbytes = bit_buffer_end - bitpos;
|
||||
if (rbytes < sizeof(long)) {
|
||||
CopyMemory(bit_buffer, bitpos, 4);
|
||||
if (!ReadFile(hInFile, bit_buffer + rbytes,
|
||||
BIT_BUFFER_SIZE - rbytes, &result, NULL))
|
||||
throw TTAException (READ_ERROR);
|
||||
input_byte_count += result;
|
||||
bitpos = bit_buffer;
|
||||
}
|
||||
|
||||
CopyMemory(&crc32, bitpos, 4);
|
||||
crc32 = ENDSWAP_INT32(crc32);
|
||||
bitpos += sizeof(long);
|
||||
result = (crc32 != frame_crc32);
|
||||
|
||||
bit_cache = bit_count = 0;
|
||||
frame_crc32 = 0xFFFFFFFFUL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void SkipFrame ()
|
||||
{
|
||||
SetFilePointer(hInFile, next_frame_pos, NULL, FILE_BEGIN);
|
||||
bitpos = bit_buffer_end;
|
||||
}
|
||||
|
||||
unsigned long input_byte_count;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user