Created
June 29, 2019 15:04
-
-
Save andr1972/2466f8a470842116bb0655116bf44047 to your computer and use it in GitHub Desktop.
Streams for Arithmetic encoder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdexcept> | |
#include "BitOutput.h" | |
BitOutput::BitOutput() : | |
currentByte(0), | |
numBitsFilled(0) | |
{} | |
void BitOutput::write(int b) { | |
if (b != 0 && b != 1) | |
throw std::domain_error("Argument must be 0 or 1"); | |
bitTrigger(b); | |
currentByte = (currentByte << 1) | b; | |
numBitsFilled++; | |
if (numBitsFilled == 8) { | |
// Note: ostream.put() takes char, which may be signed/unsigned | |
if (std::numeric_limits<char>::is_signed) | |
currentByte -= (currentByte >> 7) << 8; | |
//output.put(static_cast<char>(currentByte)); | |
byteTrigger(currentByte); | |
currentByte = 0; | |
numBitsFilled = 0; | |
} | |
} | |
void BitOutput::finish() { | |
while (numBitsFilled != 0) | |
write(0); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
/* | |
* The bits are written in big endian. | |
*/ | |
class BitOutput | |
{ | |
/*---- Fields ----*/ | |
// The accumulated bits for the current byte, always in the range [0x00, 0xFF]. | |
private: int currentByte; | |
// Number of accumulated bits in the current byte, always between 0 and 7 (inclusive). | |
private: int numBitsFilled; | |
/*---- Constructor ----*/ | |
// Constructs a bit output stream based on the given byte output stream. | |
public: BitOutput(); | |
/*---- Methods ----*/ | |
// Writes a bit to the stream. The given bit must be 0 or 1. | |
public: void write(int b); | |
// Writes the minimum number of "0" bits (between 0 and 7 of them) as padding to | |
// reach the next byte boundary. Most applications will require the bits in the last | |
// partial byte to be written before the underlying stream is closed. Note that this | |
// method merely writes data to the underlying output stream but does not close it. | |
public: void finish(); | |
protected: virtual void bitTrigger(int bit) = 0; | |
protected: virtual void byteTrigger(int byte) = 0; | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "BitOutputStream.h" | |
BitOutputStream::BitOutputStream(std::ostream& out) : BitOutput(),output(out) | |
{ | |
} | |
void BitOutputStream::bitTrigger(int byte) | |
{ | |
//none | |
} | |
void BitOutputStream::byteTrigger(int byte) | |
{ | |
output.put(static_cast<char>(byte)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Reference arithmetic coding | |
* Copyright (c) Project Nayuki | |
* | |
* https://www.nayuki.io/page/reference-arithmetic-coding | |
* https://github.com/nayuki/Reference-arithmetic-coding | |
*/ | |
#pragma once | |
#include <istream> | |
#include <ostream> | |
#include "BitOutput.h" | |
/* | |
* A stream where bits can be written to. Because they are written to an underlying | |
* byte stream, the end of the stream is padded with 0's up to a multiple of 8 bits. | |
* The bits are written in big endian. | |
*/ | |
class BitOutputStream: public BitOutput | |
{ | |
/*---- Fields ----*/ | |
// The underlying byte stream to write to. | |
private: std::ostream& output; | |
/*---- Constructor ----*/ | |
// Constructs a bit output stream based on the given byte output stream. | |
public: explicit BitOutputStream(std::ostream& out); | |
protected: void bitTrigger(int byte) override; | |
protected: void byteTrigger(int byte) override; | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include "DebugBitOutput.h" | |
DebugBitOutput::DebugBitOutput(int mode) : mode(mode) | |
{ | |
} | |
void DebugBitOutput::bitTrigger(int bit) | |
{ | |
if ((mode & 1) != 0) | |
printf("%d", bit); | |
} | |
void DebugBitOutput::byteTrigger(int byte) | |
{ | |
if ((mode & 3) != 0) | |
printf("="); | |
if ((mode & 2) != 0) | |
printf("%02x ", static_cast<unsigned char>(byte)); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "BitOutput.h" | |
/* | |
* Debug output | |
*/ | |
class DebugBitOutput : public BitOutput | |
{ | |
//output bits or bytes | |
private: int mode; | |
/*---- Constructor ----*/ | |
// Constructs a bit output stream based on the given byte output stream. | |
public: DebugBitOutput(int mode); | |
protected: void bitTrigger(int byte) override; | |
protected: void byteTrigger(int byte) override; | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment