2008-04-29 12:55:25 +00:00
|
|
|
#include <qpdf/BitStream.hh>
|
|
|
|
#include <qpdf/BitWriter.hh>
|
|
|
|
#include <qpdf/Pl_Buffer.hh>
|
2019-06-21 03:35:23 +00:00
|
|
|
#include <qpdf/QIntC.hh>
|
|
|
|
#include <qpdf/QUtil.hh>
|
2023-05-20 11:22:32 +00:00
|
|
|
#include <cstdlib>
|
2008-04-29 12:55:25 +00:00
|
|
|
#include <iostream>
|
|
|
|
|
2022-03-07 22:55:11 +00:00
|
|
|
// See comments in bits_functions.hh
|
2008-04-29 12:55:25 +00:00
|
|
|
#define BITS_TESTING 1
|
|
|
|
#define BITS_READ 1
|
|
|
|
#define BITS_WRITE 1
|
2022-03-07 22:55:11 +00:00
|
|
|
#include <qpdf/bits_functions.hh>
|
2008-04-29 12:55:25 +00:00
|
|
|
|
|
|
|
static void
|
2019-06-21 03:35:23 +00:00
|
|
|
print_values(long long byte_offset, size_t bit_offset, size_t bits_available)
|
2008-04-29 12:55:25 +00:00
|
|
|
{
|
|
|
|
std::cout << "byte offset = " << byte_offset << ", "
|
2022-02-08 14:18:08 +00:00
|
|
|
<< "bit offset = " << bit_offset << ", "
|
|
|
|
<< "bits available = " << bits_available << std::endl;
|
2008-04-29 12:55:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_read_bits(
|
|
|
|
unsigned char const* buf,
|
2022-02-08 14:18:08 +00:00
|
|
|
unsigned char const*& p,
|
|
|
|
size_t& bit_offset,
|
|
|
|
size_t& bits_available,
|
|
|
|
size_t bits_wanted)
|
2008-04-29 12:55:25 +00:00
|
|
|
{
|
2022-02-08 14:18:08 +00:00
|
|
|
unsigned long result = QIntC::to_ulong(read_bits(p, bit_offset, bits_available, bits_wanted));
|
2008-04-29 12:55:25 +00:00
|
|
|
|
|
|
|
std::cout << "bits read: " << bits_wanted << ", result = " << result << std::endl;
|
|
|
|
print_values(p - buf, bit_offset, bits_available);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-06-21 03:35:23 +00:00
|
|
|
test_write_bits(
|
|
|
|
unsigned char& ch, size_t& bit_offset, unsigned long val, size_t bits, Pl_Buffer* bp)
|
2008-04-29 12:55:25 +00:00
|
|
|
{
|
|
|
|
write_bits(ch, bit_offset, val, bits, bp);
|
2019-06-21 03:35:23 +00:00
|
|
|
std::cout << "ch = " << QUtil::uint_to_string_base(ch, 16, 2) << ", bit_offset = " << bit_offset
|
|
|
|
<< std::endl;
|
2008-04-29 12:55:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_buffer(Pl_Buffer* bp)
|
|
|
|
{
|
|
|
|
bp->finish();
|
|
|
|
Buffer* b = bp->getBuffer();
|
|
|
|
unsigned char const* p = b->getBuffer();
|
2012-06-20 15:20:57 +00:00
|
|
|
size_t l = b->getSize();
|
2008-04-29 12:55:25 +00:00
|
|
|
for (unsigned long i = 0; i < l; ++i) {
|
2019-06-21 03:35:23 +00:00
|
|
|
std::cout << QUtil::uint_to_string_base(p[i], 16, 2) << ((i == l - 1) ? "\n" : " ");
|
2008-04-29 12:55:25 +00:00
|
|
|
}
|
2019-06-21 03:35:23 +00:00
|
|
|
std::cout << std::endl;
|
2008-04-29 12:55:25 +00:00
|
|
|
delete b;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test()
|
|
|
|
{
|
|
|
|
// 11110101 00010101 01100101 01111001 00010010 10001001 01110101 01001011
|
|
|
|
// F5 15 65 79 12 89 75 4B
|
|
|
|
|
|
|
|
// Read tests
|
|
|
|
|
2022-02-08 14:18:08 +00:00
|
|
|
static unsigned char const buf[] = {0xF5, 0x15, 0x65, 0x79, 0x12, 0x89, 0x75, 0x4B};
|
2008-04-29 12:55:25 +00:00
|
|
|
|
|
|
|
unsigned char const* p = buf;
|
2019-06-21 03:35:23 +00:00
|
|
|
size_t bit_offset = 7;
|
|
|
|
size_t bits_available = 64;
|
2008-04-29 12:55:25 +00:00
|
|
|
|
|
|
|
// 11110:101 0:001010:1 01100101: 01111001
|
|
|
|
// 0:00:1:0010 10001001 01110101 01001:011
|
|
|
|
print_values(p - buf, bit_offset, bits_available);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 5);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 4);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 6);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 9);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 9);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 2);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 1);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 0);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 25);
|
|
|
|
|
|
|
|
try {
|
2022-02-08 14:18:08 +00:00
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 4);
|
2008-04-29 12:55:25 +00:00
|
|
|
} catch (std::exception& e) {
|
2022-02-08 14:18:08 +00:00
|
|
|
std::cout << "exception: " << e.what() << std::endl;
|
|
|
|
print_values(p - buf, bit_offset, bits_available);
|
2008-04-29 12:55:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 3);
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
|
|
|
// 11110101 00010101 01100101 01111001: 00010010 10001001 01110101 01001011
|
|
|
|
|
|
|
|
p = buf;
|
|
|
|
bit_offset = 7;
|
|
|
|
bits_available = 64;
|
|
|
|
print_values(p - buf, bit_offset, bits_available);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 32);
|
|
|
|
test_read_bits(buf, p, bit_offset, bits_available, 32);
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
|
|
|
BitStream b(buf, 8);
|
|
|
|
std::cout << b.getBits(32) << std::endl;
|
|
|
|
b.reset();
|
|
|
|
std::cout << b.getBits(32) << std::endl;
|
|
|
|
std::cout << b.getBits(32) << std::endl;
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
|
|
|
b.reset();
|
|
|
|
std::cout << b.getBits(6) << std::endl;
|
|
|
|
b.skipToNextByte();
|
|
|
|
std::cout << b.getBits(8) << std::endl;
|
|
|
|
b.skipToNextByte();
|
|
|
|
std::cout << b.getBits(8) << std::endl;
|
|
|
|
std::cout << std::endl;
|
2018-01-13 23:13:18 +00:00
|
|
|
b.reset();
|
|
|
|
std::cout << b.getBitsSigned(3) << std::endl;
|
|
|
|
std::cout << b.getBitsSigned(6) << std::endl;
|
|
|
|
std::cout << b.getBitsSigned(5) << std::endl;
|
|
|
|
std::cout << b.getBitsSigned(1) << std::endl;
|
|
|
|
std::cout << b.getBitsSigned(17) << std::endl;
|
|
|
|
std::cout << std::endl;
|
2008-04-29 12:55:25 +00:00
|
|
|
|
|
|
|
// Write tests
|
|
|
|
|
|
|
|
// 11110:101 0:001010:1 01100101: 01111001
|
|
|
|
// 0:00:1:0010 10001001 01110101 01001:011
|
|
|
|
|
|
|
|
unsigned char ch = 0;
|
|
|
|
bit_offset = 7;
|
2023-05-20 12:24:10 +00:00
|
|
|
auto* bp = new Pl_Buffer("buffer");
|
2008-04-29 12:55:25 +00:00
|
|
|
|
|
|
|
test_write_bits(ch, bit_offset, 30UL, 5, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 10UL, 4, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 10UL, 6, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 16059UL, 0, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 357UL, 9, bp);
|
|
|
|
print_buffer(bp);
|
|
|
|
|
|
|
|
test_write_bits(ch, bit_offset, 242UL, 9, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 0UL, 2, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 1UL, 1, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 5320361UL, 25, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 3UL, 3, bp);
|
|
|
|
|
|
|
|
print_buffer(bp);
|
|
|
|
test_write_bits(ch, bit_offset, 4111820153UL, 32, bp);
|
|
|
|
test_write_bits(ch, bit_offset, 310998347UL, 32, bp);
|
|
|
|
print_buffer(bp);
|
|
|
|
|
|
|
|
BitWriter bw(bp);
|
|
|
|
bw.writeBits(30UL, 5);
|
|
|
|
bw.flush();
|
|
|
|
bw.flush();
|
2019-06-21 03:35:23 +00:00
|
|
|
bw.writeBitsInt(0xAB, 8);
|
2008-04-29 12:55:25 +00:00
|
|
|
bw.flush();
|
|
|
|
print_buffer(bp);
|
2018-01-13 23:13:18 +00:00
|
|
|
bw.writeBitsSigned(-1, 3); // 111
|
|
|
|
bw.writeBitsSigned(-12, 6); // 110100
|
|
|
|
bw.writeBitsSigned(4, 3); // 100
|
|
|
|
bw.writeBitsSigned(-4, 3); // 100
|
|
|
|
bw.writeBitsSigned(-1, 1); // 1
|
|
|
|
bw.flush();
|
|
|
|
print_buffer(bp);
|
2008-04-29 12:55:25 +00:00
|
|
|
|
|
|
|
delete bp;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
try {
|
2022-02-08 14:18:08 +00:00
|
|
|
test();
|
2008-04-29 12:55:25 +00:00
|
|
|
} catch (std::exception& e) {
|
2022-02-08 14:18:08 +00:00
|
|
|
std::cout << "unexpected exception: " << e.what() << std::endl;
|
|
|
|
exit(2);
|
2008-04-29 12:55:25 +00:00
|
|
|
}
|
|
|
|
std::cout << "done" << std::endl;
|
|
|
|
return 0;
|
|
|
|
}
|