This commit is contained in:
elasota
2020-05-10 20:03:59 -04:00
parent 231c4b411f
commit e1f9e86c56

View File

@@ -1,379 +1,379 @@
#include "CSInputBuffer.h" #include "CSInputBuffer.h"
#include "IFileReader.h" #include "IFileReader.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
// Allocation and management // Allocation and management
CSInputBuffer *CSInputBufferAlloc(IFileReader *parent, int size) CSInputBuffer *CSInputBufferAlloc(IFileReader *parent, int size)
{ {
CSInputBuffer *self = static_cast<CSInputBuffer*>(malloc(sizeof(CSInputBuffer) + size)); CSInputBuffer *self = static_cast<CSInputBuffer*>(malloc(sizeof(CSInputBuffer) + size));
if (!self) return NULL; if (!self) return NULL;
self->parent = parent; self->parent = parent;
self->startoffs = parent->GetPosition(); self->startoffs = parent->GetPosition();
self->eof = false; self->eof = false;
self->buffer = (uint8_t *)&self[1]; self->buffer = (uint8_t *)&self[1];
self->bufsize = size; self->bufsize = size;
self->bufbytes = 0; self->bufbytes = 0;
self->currbyte = 0; self->currbyte = 0;
self->bits = 0; self->bits = 0;
self->numbits = 0; self->numbits = 0;
return self; return self;
} }
CSInputBuffer *CSInputBufferAllocWithBuffer(const uint8_t *buffer, int length, IFileReader::FilePos_t startoffs) CSInputBuffer *CSInputBufferAllocWithBuffer(const uint8_t *buffer, int length, IFileReader::FilePos_t startoffs)
{ {
CSInputBuffer *self = static_cast<CSInputBuffer*>(malloc(sizeof(CSInputBuffer))); CSInputBuffer *self = static_cast<CSInputBuffer*>(malloc(sizeof(CSInputBuffer)));
if (!self) return NULL; if (!self) return NULL;
self->parent = NULL; self->parent = NULL;
self->startoffs = -startoffs; self->startoffs = -startoffs;
self->eof = true; self->eof = true;
self->buffer = (uint8_t *)buffer; // Since eof is set, the buffer won't be written to. self->buffer = (uint8_t *)buffer; // Since eof is set, the buffer won't be written to.
self->bufsize = length; self->bufsize = length;
self->bufbytes = length; self->bufbytes = length;
self->currbyte = 0; self->currbyte = 0;
self->bits = 0; self->bits = 0;
self->numbits = 0; self->numbits = 0;
return self; return self;
} }
CSInputBuffer *CSInputBufferAllocEmpty() CSInputBuffer *CSInputBufferAllocEmpty()
{ {
CSInputBuffer *self = static_cast<CSInputBuffer*>(malloc(sizeof(CSInputBuffer))); CSInputBuffer *self = static_cast<CSInputBuffer*>(malloc(sizeof(CSInputBuffer)));
if (!self) return NULL; if (!self) return NULL;
self->parent = NULL; self->parent = NULL;
self->startoffs = 0; self->startoffs = 0;
self->eof = true; self->eof = true;
self->buffer = NULL; self->buffer = NULL;
self->bufsize = 0; self->bufsize = 0;
self->bufbytes = 0; self->bufbytes = 0;
self->currbyte = 0; self->currbyte = 0;
self->bits = 0; self->bits = 0;
self->numbits = 0; self->numbits = 0;
return self; return self;
} }
void CSInputBufferFree(CSInputBuffer *self) void CSInputBufferFree(CSInputBuffer *self)
{ {
free(self); free(self);
} }
void CSInputSetMemoryBuffer(CSInputBuffer *self, uint8_t *buffer, int length, IFileReader::FilePos_t startoffs) void CSInputSetMemoryBuffer(CSInputBuffer *self, uint8_t *buffer, int length, IFileReader::FilePos_t startoffs)
{ {
self->eof = true; self->eof = true;
self->startoffs = -startoffs; self->startoffs = -startoffs;
self->buffer = buffer; self->buffer = buffer;
self->bufsize = length; self->bufsize = length;
self->bufbytes = length; self->bufbytes = length;
self->currbyte = 0; self->currbyte = 0;
self->bits = 0; self->bits = 0;
self->numbits = 0; self->numbits = 0;
} }
// Buffer and file positioning // Buffer and file positioning
void CSInputRestart(CSInputBuffer *self) void CSInputRestart(CSInputBuffer *self)
{ {
CSInputSeekToFileOffset(self, self->startoffs); CSInputSeekToFileOffset(self, self->startoffs);
} }
void CSInputFlush(CSInputBuffer *self) void CSInputFlush(CSInputBuffer *self)
{ {
self->currbyte = self->bufbytes = 0; self->currbyte = self->bufbytes = 0;
self->bits = 0; self->bits = 0;
self->numbits = 0; self->numbits = 0;
} }
void CSInputSynchronizeFileOffset(CSInputBuffer *self) void CSInputSynchronizeFileOffset(CSInputBuffer *self)
{ {
CSInputSeekToFileOffset(self, CSInputFileOffset(self)); CSInputSeekToFileOffset(self, CSInputFileOffset(self));
} }
void CSInputSeekToFileOffset(CSInputBuffer *self, IFileReader::FilePos_t offset) void CSInputSeekToFileOffset(CSInputBuffer *self, IFileReader::FilePos_t offset)
{ {
self->parent->SeekStart(offset); self->parent->SeekStart(offset);
self->eof = false; self->eof = false;
CSInputFlush(self); CSInputFlush(self);
} }
void CSInputSeekToBufferOffset(CSInputBuffer *self, IFileReader::FilePos_t offset) void CSInputSeekToBufferOffset(CSInputBuffer *self, IFileReader::FilePos_t offset)
{ {
CSInputSeekToFileOffset(self, offset + self->startoffs); CSInputSeekToFileOffset(self, offset + self->startoffs);
} }
void CSInputSetStartOffset(CSInputBuffer *self, IFileReader::FilePos_t offset) void CSInputSetStartOffset(CSInputBuffer *self, IFileReader::FilePos_t offset)
{ {
self->startoffs = offset; self->startoffs = offset;
} }
IFileReader::FilePos_t CSInputBufferOffset(CSInputBuffer *self) IFileReader::FilePos_t CSInputBufferOffset(CSInputBuffer *self)
{ {
return CSInputFileOffset(self) - self->startoffs; return CSInputFileOffset(self) - self->startoffs;
} }
IFileReader::FilePos_t CSInputFileOffset(CSInputBuffer *self) IFileReader::FilePos_t CSInputFileOffset(CSInputBuffer *self)
{ {
if (self->parent) return self->parent->GetPosition() - self->bufbytes + self->currbyte; if (self->parent) return self->parent->GetPosition() - self->bufbytes + self->currbyte;
else return self->currbyte; else return self->currbyte;
} }
IFileReader::FilePos_t CSInputBufferBitOffset(CSInputBuffer *self) IFileReader::FilePos_t CSInputBufferBitOffset(CSInputBuffer *self)
{ {
return CSInputBufferOffset(self) * 8 - (self->numbits & 7); return CSInputBufferOffset(self) * 8 - (self->numbits & 7);
} }
// Byte reading // Byte reading
void _CSInputFillBuffer(CSInputBuffer *self) void _CSInputFillBuffer(CSInputBuffer *self)
{ {
int left = _CSInputBytesLeftInBuffer(self); int left = _CSInputBytesLeftInBuffer(self);
if (left >= 0) memmove(self->buffer, self->buffer + self->currbyte, left); if (left >= 0) memmove(self->buffer, self->buffer + self->currbyte, left);
else else
{ {
self->parent->SeekCurrent(-left); self->parent->SeekCurrent(-left);
left = 0; left = 0;
} }
int actual = self->parent->Read(self->buffer + left, self->bufsize - left); int actual = self->parent->Read(self->buffer + left, self->bufsize - left);
if (actual == 0) self->eof = true; if (actual == 0) self->eof = true;
self->bufbytes = left + actual; self->bufbytes = left + actual;
self->currbyte = 0; self->currbyte = 0;
} }
// Bitstream reading // Bitstream reading
// TODO: clean up and/or make faster // TODO: clean up and/or make faster
bool _CSInputFillBits(CSInputBuffer *self) bool _CSInputFillBits(CSInputBuffer *self)
{ {
_CSInputCheckAndFillBuffer(self); _CSInputCheckAndFillBuffer(self);
int numbytes = (32 - self->numbits) >> 3; int numbytes = (32 - self->numbits) >> 3;
int left = _CSInputBytesLeftInBuffer(self); int left = _CSInputBytesLeftInBuffer(self);
if (numbytes > left) numbytes = left; if (numbytes > left) numbytes = left;
int startoffset = self->numbits >> 3; int startoffset = self->numbits >> 3;
// int shift=24-self->numbits; // int shift=24-self->numbits;
// for(int i=0;i<numbytes;i++) // for(int i=0;i<numbytes;i++)
// { // {
// self->bits|=_CSInputPeekByteWithoutEOF(self,i+startoffset)<<shift; // self->bits|=_CSInputPeekByteWithoutEOF(self,i+startoffset)<<shift;
// shift-=8; // shift-=8;
// } // }
switch (numbytes) switch (numbytes)
{ {
case 4: case 4:
self->bits = self->bits =
(_CSInputPeekByteWithoutEOF(self, startoffset) << 24) | (_CSInputPeekByteWithoutEOF(self, startoffset) << 24) |
(_CSInputPeekByteWithoutEOF(self, startoffset + 1) << 16) | (_CSInputPeekByteWithoutEOF(self, startoffset + 1) << 16) |
(_CSInputPeekByteWithoutEOF(self, startoffset + 2) << 8) | (_CSInputPeekByteWithoutEOF(self, startoffset + 2) << 8) |
_CSInputPeekByteWithoutEOF(self, startoffset + 3); _CSInputPeekByteWithoutEOF(self, startoffset + 3);
break; break;
case 3: case 3:
self->bits |= ( self->bits |= (
(_CSInputPeekByteWithoutEOF(self, startoffset) << 16) | (_CSInputPeekByteWithoutEOF(self, startoffset) << 16) |
(_CSInputPeekByteWithoutEOF(self, startoffset + 1) << 8) | (_CSInputPeekByteWithoutEOF(self, startoffset + 1) << 8) |
(_CSInputPeekByteWithoutEOF(self, startoffset + 2) << 0) (_CSInputPeekByteWithoutEOF(self, startoffset + 2) << 0)
) << (8 - self->numbits); ) << (8 - self->numbits);
break; break;
case 2: case 2:
self->bits |= ( self->bits |= (
(_CSInputPeekByteWithoutEOF(self, startoffset) << 8) | (_CSInputPeekByteWithoutEOF(self, startoffset) << 8) |
(_CSInputPeekByteWithoutEOF(self, startoffset + 1) << 0) (_CSInputPeekByteWithoutEOF(self, startoffset + 1) << 0)
) << (16 - self->numbits); ) << (16 - self->numbits);
break; break;
case 1: case 1:
self->bits |= _CSInputPeekByteWithoutEOF(self, startoffset) << (24 - self->numbits); self->bits |= _CSInputPeekByteWithoutEOF(self, startoffset) << (24 - self->numbits);
break; break;
} }
self->numbits += numbytes * 8; self->numbits += numbytes * 8;
return true; return true;
} }
bool _CSInputFillBitsLE(CSInputBuffer *self) bool _CSInputFillBitsLE(CSInputBuffer *self)
{ {
_CSInputCheckAndFillBuffer(self); _CSInputCheckAndFillBuffer(self);
int numbytes = (32 - self->numbits) >> 3; int numbytes = (32 - self->numbits) >> 3;
int left = _CSInputBytesLeftInBuffer(self); int left = _CSInputBytesLeftInBuffer(self);
if (numbytes > left) numbytes = left; if (numbytes > left) numbytes = left;
int startoffset = self->numbits >> 3; int startoffset = self->numbits >> 3;
for (int i = 0; i < numbytes; i++) for (int i = 0; i < numbytes; i++)
{ {
self->bits |= _CSInputPeekByteWithoutEOF(self, i + startoffset) << self->numbits; self->bits |= _CSInputPeekByteWithoutEOF(self, i + startoffset) << self->numbits;
self->numbits += 8; self->numbits += 8;
} }
return true; return true;
} }
bool CSInputNextBit(CSInputBuffer *self, unsigned int &bit) bool CSInputNextBit(CSInputBuffer *self, unsigned int &bit)
{ {
if (!CSInputPeekBitString(self, 1, bit)) if (!CSInputPeekBitString(self, 1, bit))
return false; return false;
return CSInputSkipPeekedBits(self, 1); return CSInputSkipPeekedBits(self, 1);
} }
bool CSInputNextBitLE(CSInputBuffer *self, unsigned int &bit) bool CSInputNextBitLE(CSInputBuffer *self, unsigned int &bit)
{ {
if (!CSInputPeekBitStringLE(self, 1, bit)) if (!CSInputPeekBitStringLE(self, 1, bit))
return false; return false;
return CSInputSkipPeekedBitsLE(self, 1); return CSInputSkipPeekedBitsLE(self, 1);
} }
bool CSInputNextBitString(CSInputBuffer *self, int numbits, unsigned int &bits) bool CSInputNextBitString(CSInputBuffer *self, int numbits, unsigned int &bits)
{ {
if (numbits == 0) if (numbits == 0)
{ {
bits = 0; bits = 0;
return true;
}
if (!CSInputPeekBitString(self, numbits, bits))
return false;
return CSInputSkipPeekedBits(self, numbits);
}
bool CSInputNextBitStringLE(CSInputBuffer *self, int numbits, unsigned int &bits)
{
if (numbits == 0)
{
bits = 0;
return true;
}
if (!CSInputPeekBitStringLE(self, numbits, bits))
return false;
if (!CSInputSkipPeekedBitsLE(self, numbits))
return false;
return true;
}
bool CSInputNextLongBitString(CSInputBuffer *self, int numbits, unsigned int &bits)
{
if (numbits <= 25)
return CSInputNextBitString(self, numbits, bits);
else
{
int rest = numbits - 25;
unsigned int readBits;
if (!CSInputNextBitString(self, 25, readBits))
return false;
readBits <<= rest;
unsigned int moreBits;
if (!CSInputNextBitString(self, rest, moreBits))
return false;
bits = (readBits | moreBits);
return true;
}
}
bool CSInputNextLongBitStringLE(CSInputBuffer *self, int numbits, unsigned int &bits)
{
if (numbits <= 25)
return CSInputNextBitStringLE(self, numbits, bits);
else
{
int rest = numbits - 25;
unsigned int readBits;
if (!CSInputNextBitStringLE(self, 25, readBits))
return false;
unsigned int moreBits;
if (!CSInputNextBitStringLE(self, rest, moreBits))
return false;
bits = (readBits | (moreBits << 25));
return true; return true;
} }
} if (!CSInputPeekBitString(self, numbits, bits))
return false;
bool CSInputSkipBits(CSInputBuffer *self, int numbits) return CSInputSkipPeekedBits(self, numbits);
{ }
if (numbits <= self->numbits)
return CSInputSkipPeekedBits(self, numbits); bool CSInputNextBitStringLE(CSInputBuffer *self, int numbits, unsigned int &bits)
else {
{ if (numbits == 0)
int skipbits = numbits - (self->numbits & 7); {
CSInputSkipToByteBoundary(self); bits = 0;
CSInputSkipBytes(self, skipbits >> 3); return true;
if (skipbits & 7) }
{ if (!CSInputPeekBitStringLE(self, numbits, bits))
unsigned int scratch; return false;
if (!CSInputNextBitString(self, skipbits & 7, scratch)) if (!CSInputSkipPeekedBitsLE(self, numbits))
return false; return false;
} return true;
}
return true;
} bool CSInputNextLongBitString(CSInputBuffer *self, int numbits, unsigned int &bits)
} {
if (numbits <= 25)
bool CSInputSkipBitsLE(CSInputBuffer *self, int numbits) return CSInputNextBitString(self, numbits, bits);
{ else
if (numbits <= self->numbits) {
return CSInputSkipPeekedBitsLE(self, numbits); int rest = numbits - 25;
else unsigned int readBits;
{ if (!CSInputNextBitString(self, 25, readBits))
int skipbits = numbits - (self->numbits & 7); return false;
CSInputSkipToByteBoundary(self); readBits <<= rest;
CSInputSkipBytes(self, skipbits >> 3); unsigned int moreBits;
if (skipbits & 7) if (!CSInputNextBitString(self, rest, moreBits))
{ return false;
unsigned int scratch; bits = (readBits | moreBits);
if (!CSInputNextBitStringLE(self, skipbits & 7, scratch)) return true;
return false; }
} }
return true; bool CSInputNextLongBitStringLE(CSInputBuffer *self, int numbits, unsigned int &bits)
} {
} if (numbits <= 25)
return CSInputNextBitStringLE(self, numbits, bits);
else
{
bool CSInputOnByteBoundary(CSInputBuffer *self) int rest = numbits - 25;
{ unsigned int readBits;
return (self->numbits & 7) == 0; if (!CSInputNextBitStringLE(self, 25, readBits))
} return false;
unsigned int moreBits;
bool CSInputSkipToByteBoundary(CSInputBuffer *self) if (!CSInputNextBitStringLE(self, rest, moreBits))
{ return false;
self->bits = 0; bits = (readBits | (moreBits << 25));
self->numbits = 0; return true;
}
return true; }
}
bool CSInputSkipBits(CSInputBuffer *self, int numbits)
bool CSInputSkipTo16BitBoundary(CSInputBuffer *self) {
{ if (numbits <= self->numbits)
if (!CSInputSkipToByteBoundary(self)) return CSInputSkipPeekedBits(self, numbits);
return false; else
if (CSInputBufferOffset(self) & 1) {
{ int skipbits = numbits - (self->numbits & 7);
if (!CSInputSkipBytes(self, 1)) CSInputSkipToByteBoundary(self);
return false; CSInputSkipBytes(self, skipbits >> 3);
} if (skipbits & 7)
{
return true; unsigned int scratch;
if (!CSInputNextBitString(self, skipbits & 7, scratch))
return false;
}
return true;
}
}
bool CSInputSkipBitsLE(CSInputBuffer *self, int numbits)
{
if (numbits <= self->numbits)
return CSInputSkipPeekedBitsLE(self, numbits);
else
{
int skipbits = numbits - (self->numbits & 7);
CSInputSkipToByteBoundary(self);
CSInputSkipBytes(self, skipbits >> 3);
if (skipbits & 7)
{
unsigned int scratch;
if (!CSInputNextBitStringLE(self, skipbits & 7, scratch))
return false;
}
return true;
}
}
bool CSInputOnByteBoundary(CSInputBuffer *self)
{
return (self->numbits & 7) == 0;
}
bool CSInputSkipToByteBoundary(CSInputBuffer *self)
{
self->bits = 0;
self->numbits = 0;
return true;
}
bool CSInputSkipTo16BitBoundary(CSInputBuffer *self)
{
if (!CSInputSkipToByteBoundary(self))
return false;
if (CSInputBufferOffset(self) & 1)
{
if (!CSInputSkipBytes(self, 1))
return false;
}
return true;
} }