include "bytedata.s7i";
const array array integer: reverseBits is [2] (
[0] (0, 2, 1, 3),
[0] (0, 4, 2, 6, 1, 5, 3, 7),
[0] (0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15),
[0] (0, 16, 8, 24, 4, 20, 12, 28, 2, 18, 10, 26, 6, 22, 14, 30,
1, 17, 9, 25, 5, 21, 13, 29, 3, 19, 11, 27, 7, 23, 15, 31),
[0] (0, 32, 16, 48, 8, 40, 24, 56, 4, 36, 20, 52, 12, 44, 28, 60,
2, 34, 18, 50, 10, 42, 26, 58, 6, 38, 22, 54, 14, 46, 30, 62,
1, 33, 17, 49, 9, 41, 25, 57, 5, 37, 21, 53, 13, 45, 29, 61,
3, 35, 19, 51, 11, 43, 27, 59, 7, 39, 23, 55, 15, 47, 31, 63),
[0] (0, 64, 32, 96, 16, 80, 48, 112, 8, 72, 40, 104, 24, 88, 56, 120,
4, 68, 36, 100, 20, 84, 52, 116, 12, 76, 44, 108, 28, 92, 60, 124,
2, 66, 34, 98, 18, 82, 50, 114, 10, 74, 42, 106, 26, 90, 58, 122,
6, 70, 38, 102, 22, 86, 54, 118, 14, 78, 46, 110, 30, 94, 62, 126,
1, 65, 33, 97, 17, 81, 49, 113 , 9, 73, 41, 105, 25, 89, 57, 121,
5, 69, 37, 101, 21, 85, 53, 117, 13, 77, 45, 109, 29, 93, 61, 125,
3, 67, 35, 99, 19, 83, 51, 115, 11, 75, 43, 107, 27, 91, 59, 123,
7, 71, 39, 103, 23, 87, 55, 119, 15, 79, 47, 111, 31, 95, 63, 127),
[0] ( 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255),
[0] ( 0, 256, 128, 384, 64, 320, 192, 448, 32, 288, 160, 416, 96, 352, 224, 480,
16, 272, 144, 400, 80, 336, 208, 464, 48, 304, 176, 432, 112, 368, 240, 496,
8, 264, 136, 392, 72, 328, 200, 456, 40, 296, 168, 424, 104, 360, 232, 488,
24, 280, 152, 408, 88, 344, 216, 472, 56, 312, 184, 440, 120, 376, 248, 504,
4, 260, 132, 388, 68, 324, 196, 452, 36, 292, 164, 420, 100, 356, 228, 484,
20, 276, 148, 404, 84, 340, 212, 468, 52, 308, 180, 436, 116, 372, 244, 500,
12, 268, 140, 396, 76, 332, 204, 460, 44, 300, 172, 428, 108, 364, 236, 492,
28, 284, 156, 412, 92, 348, 220, 476, 60, 316, 188, 444, 124, 380, 252, 508,
2, 258, 130, 386, 66, 322, 194, 450, 34, 290, 162, 418, 98, 354, 226, 482,
18, 274, 146, 402, 82, 338, 210, 466, 50, 306, 178, 434, 114, 370, 242, 498,
10, 266, 138, 394, 74, 330, 202, 458, 42, 298, 170, 426, 106, 362, 234, 490,
26, 282, 154, 410, 90, 346, 218, 474, 58, 314, 186, 442, 122, 378, 250, 506,
6, 262, 134, 390, 70, 326, 198, 454, 38, 294, 166, 422, 102, 358, 230, 486,
22, 278, 150, 406, 86, 342, 214, 470, 54, 310, 182, 438, 118, 374, 246, 502,
14, 270, 142, 398, 78, 334, 206, 462, 46, 302, 174, 430, 110, 366, 238, 494,
30, 286, 158, 414, 94, 350, 222, 478, 62, 318, 190, 446, 126, 382, 254, 510,
1, 257, 129, 385, 65, 321, 193, 449, 33, 289, 161, 417, 97, 353, 225, 481,
17, 273, 145, 401, 81, 337, 209, 465, 49, 305, 177, 433, 113, 369, 241, 497,
9, 265, 137, 393, 73, 329, 201, 457, 41, 297, 169, 425, 105, 361, 233, 489,
25, 281, 153, 409, 89, 345, 217, 473, 57, 313, 185, 441, 121, 377, 249, 505,
5, 261, 133, 389, 69, 325, 197, 453, 37, 293, 165, 421, 101, 357, 229, 485,
21, 277, 149, 405, 85, 341, 213, 469, 53, 309, 181, 437, 117, 373, 245, 501,
13, 269, 141, 397, 77, 333, 205, 461, 45, 301, 173, 429, 109, 365, 237, 493,
29, 285, 157, 413, 93, 349, 221, 477, 61, 317, 189, 445, 125, 381, 253, 509,
3, 259, 131, 387, 67, 323, 195, 451, 35, 291, 163, 419, 99, 355, 227, 483,
19, 275, 147, 403, 83, 339, 211, 467, 51, 307, 179, 435, 115, 371, 243, 499,
11, 267, 139, 395, 75, 331, 203, 459, 43, 299, 171, 427, 107, 363, 235, 491,
27, 283, 155, 411, 91, 347, 219, 475, 59, 315, 187, 443, 123, 379, 251, 507,
7, 263, 135, 391, 71, 327, 199, 455, 39, 295, 167, 423, 103, 359, 231, 487,
23, 279, 151, 407, 87, 343, 215, 471, 55, 311, 183, 439, 119, 375, 247, 503,
15, 271, 143, 399, 79, 335, 207, 463, 47, 303, 175, 431, 111, 367, 239, 495,
31, 287, 159, 415, 95, 351, 223, 479, 63, 319, 191, 447, 127, 383, 255, 511));
const func integer: reverseBits (in integer: size, in var integer: bits) is func
result
var integer: reversed is 0;
local
var integer: bitPos is 0;
begin
for bitPos range 1 to size do
reversed <<:= 1;
reversed +:= bits mod 2;
bits >>:= 1;
end for;
end func;
const type: lsbInBitStream is new struct
var integer: buffer is 0;
var integer: bitPos is 0;
var integer: bytePos is 1;
var integer: eofBitPos is 0;
var integer: eofBytePos is integer.last;
var string: striBuffer is "";
var integer: striBufferIncrease is 4096;
var integer: tailSize is 0;
var integer: limit is 0;
var file: inFile is STD_NULL;
end struct;
const type: lsbBitStream is lsbInBitStream;
const proc: show (in lsbInBitStream: inBitStream) is func
begin
writeln("buffer: " <& inBitStream.buffer radix 2);
writeln("bitPos: " <& inBitStream.bitPos);
writeln("bytePos: " <& inBitStream.bytePos);
writeln("eofBitPos: " <& inBitStream.eofBitPos);
writeln("eofBytePos: " <& inBitStream.eofBytePos);
writeln("striBuffer: " <& literal(inBitStream.striBuffer));
writeln("striBufferIncrease: " <& inBitStream.striBufferIncrease);
writeln("tailSize: " <& inBitStream.tailSize);
writeln("limit: " <& inBitStream.limit);
end func;
const proc: fillStriBuffer (inout lsbInBitStream: inBitStream) is func
begin
inBitStream.striBuffer := inBitStream.striBuffer[inBitStream.bytePos ..] &
gets(inBitStream.inFile, inBitStream.striBufferIncrease);
if not hasNext(inBitStream.inFile) then
inBitStream.striBuffer &:= "\16#ff;\16#ff;\16#ff;\16#ff;\16#ff;";
inBitStream.tailSize +:= 5;
inBitStream.eofBytePos := succ(length(inBitStream.striBuffer)) -
inBitStream.tailSize;
end if;
inBitStream.limit := max(0, length(inBitStream.striBuffer) - 4);
inBitStream.bytePos := 1;
end func;
const proc: fillBuffer (inout lsbInBitStream: inBitStream) is func
begin
if inBitStream.bytePos > inBitStream.limit then
fillStriBuffer(inBitStream);
end if;
inBitStream.buffer := bytes2Int(inBitStream.striBuffer[inBitStream.bytePos fixLen 5], UNSIGNED, LE);
end func;
const func lsbInBitStream: openLsbInBitStream (in file: inFile) is func
result
var lsbInBitStream: inBitStream is lsbInBitStream.value;
begin
inBitStream.inFile := inFile;
fillBuffer(inBitStream);
end func;
const func lsbInBitStream: openLsbBitStream (in file: inFile) is
return openLsbInBitStream(inFile);
const func lsbInBitStream: openLsbInBitStream (in string: stri) is func
result
var lsbInBitStream: inBitStream is lsbInBitStream.value;
begin
inBitStream.striBuffer := stri & "\16#ff;\16#ff;\16#ff;\16#ff;\16#ff;";
inBitStream.tailSize := 5;
inBitStream.eofBytePos := succ(length(inBitStream.striBuffer)) -
inBitStream.tailSize;
inBitStream.limit := length(inBitStream.striBuffer) - 4;
fillBuffer(inBitStream);
end func;
const func lsbInBitStream: openLsbBitStream (in string: stri) is
return openLsbInBitStream(stri);
const proc: close (inout lsbInBitStream: inBitStream) is func
begin
if inBitStream.inFile <> STD_NULL then
if inBitStream.bitPos <> 0 then
incr(inBitStream.bytePos);
end if;
seek(inBitStream.inFile, tell(inBitStream.inFile) -
succ(length(inBitStream.striBuffer) -
inBitStream.bytePos - inBitStream.tailSize));
end if;
end func;
const func integer: getBit (inout lsbInBitStream: inBitStream) is func
result
var integer: resultBit is 0;
begin
resultBit := (inBitStream.buffer >> inBitStream.bitPos) mod 2;
incr(inBitStream.bitPos);
if inBitStream.bitPos >= 8 then
inBitStream.bitPos := 0;
incr(inBitStream.bytePos);
if inBitStream.bytePos > inBitStream.limit then
fillStriBuffer(inBitStream);
end if;
inBitStream.buffer := (inBitStream.buffer >> 8) +
(bytes2Int(inBitStream.striBuffer[inBitStream.bytePos + 4 fixLen 1], UNSIGNED, LE) << 32);
end if;
end func;
const func integer: getBits (inout lsbInBitStream: inBitStream, in integer: bitWidth) is func
result
var integer: resultBits is 0;
local
var integer: bytePosDelta is 0;
begin
resultBits := (inBitStream.buffer >> inBitStream.bitPos) mod (1 << bitWidth);
inBitStream.bitPos +:= bitWidth;
bytePosDelta := inBitStream.bitPos mdiv 8;
if bytePosDelta <> 0 then
inBitStream.bitPos := inBitStream.bitPos mod 8;
inBitStream.bytePos +:= bytePosDelta;
if inBitStream.bytePos > inBitStream.limit then
fillStriBuffer(inBitStream);
end if;
if bytePosDelta = 1 then
inBitStream.buffer := (inBitStream.buffer >> 8) +
(bytes2Int(inBitStream.striBuffer[inBitStream.bytePos + 4 fixLen 1], UNSIGNED, LE) << 32);
elsif bytePosDelta = 2 then
inBitStream.buffer := (inBitStream.buffer >> 16) +
(bytes2Int(inBitStream.striBuffer[inBitStream.bytePos + 3 fixLen 2], UNSIGNED, LE) << 24);
else
inBitStream.buffer := bytes2Int(inBitStream.striBuffer[inBitStream.bytePos fixLen 5], UNSIGNED, LE);
end if;
end if;
end func;
const func integer: peekBits (inout lsbInBitStream: inBitStream, in integer: bitWidth) is
return (inBitStream.buffer >> inBitStream.bitPos) mod (1 << bitWidth);
const proc: skipBits (inout lsbInBitStream: inBitStream, in integer: bitWidth) is func
local
var integer: bytePosDelta is 0;
begin
inBitStream.bitPos +:= bitWidth;
bytePosDelta := inBitStream.bitPos mdiv 8;
if bytePosDelta <> 0 then
inBitStream.bitPos := inBitStream.bitPos mod 8;
inBitStream.bytePos +:= bytePosDelta;
if inBitStream.bytePos > inBitStream.limit then
fillStriBuffer(inBitStream);
end if;
if bytePosDelta = 1 then
inBitStream.buffer := (inBitStream.buffer >> 8) +
(bytes2Int(inBitStream.striBuffer[inBitStream.bytePos + 4 fixLen 1], UNSIGNED, LE) << 32);
elsif bytePosDelta = 2 then
inBitStream.buffer := (inBitStream.buffer >> 16) +
(bytes2Int(inBitStream.striBuffer[inBitStream.bytePos + 3 fixLen 2], UNSIGNED, LE) << 24);
else
inBitStream.buffer := bytes2Int(inBitStream.striBuffer[inBitStream.bytePos fixLen 5], UNSIGNED, LE);
end if;
end if;
end func;
const func boolean: eof (in lsbInBitStream: inBitStream) is
return inBitStream.bytePos >= inBitStream.eofBytePos and
(inBitStream.bytePos > inBitStream.eofBytePos or
inBitStream.bitPos > inBitStream.eofBitPos);
const func string: gets (inout lsbInBitStream: inBitStream, in integer: maxLength) is func
result
var string: striRead is "";
begin
if maxLength < 0 then
raise RANGE_ERROR;
else
if inBitStream.bitPos <> 0 then
incr(inBitStream.bytePos);
inBitStream.bitPos := 0;
end if;
if maxLength <> 0 then
if maxLength <= succ(length(inBitStream.striBuffer) - inBitStream.bytePos) then
striRead := inBitStream.striBuffer[inBitStream.bytePos fixLen maxLength];
inBitStream.bytePos +:= maxLength;
else
striRead := inBitStream.striBuffer[inBitStream.bytePos ..] &
gets(inBitStream.inFile, maxLength -
succ(length(inBitStream.striBuffer) - inBitStream.bytePos));
inBitStream.striBuffer := "";
inBitStream.limit := 0;
inBitStream.bytePos := 1;
end if;
end if;
fillBuffer(inBitStream);
end if;
end func;
const type: msbInBitStream is new struct
var integer: buffer is 0;
var integer: bitPos is 40;
var integer: bytePos is 1;
var integer: eofBitPos is 40;
var integer: eofBytePos is integer.last;
var string: striBuffer is "";
var integer: striBufferIncrease is 4096;
var integer: tailSize is 0;
var integer: limit is 0;
var file: inFile is STD_NULL;
end struct;
const type: msbBitStream is msbInBitStream;
const proc: show (in msbInBitStream: inBitStream) is func
begin
writeln("buffer: " <& inBitStream.buffer radix 2);
writeln("bitPos: " <& inBitStream.bitPos);
writeln("bytePos: " <& inBitStream.bytePos);
writeln("eofBitPos: " <& inBitStream.eofBitPos);
writeln("eofBytePos: " <& inBitStream.eofBytePos);
writeln("striBuffer: " <& literal(inBitStream.striBuffer));
writeln("striBufferIncrease: " <& inBitStream.striBufferIncrease);
writeln("tailSize: " <& inBitStream.tailSize);
writeln("limit: " <& inBitStream.limit);
end func;
const proc: fillStriBuffer (inout msbInBitStream: inBitStream) is func
begin
inBitStream.striBuffer := inBitStream.striBuffer[inBitStream.bytePos ..] &
gets(inBitStream.inFile, inBitStream.striBufferIncrease);
if not hasNext(inBitStream.inFile) then
inBitStream.striBuffer &:= "\16#ff;\16#ff;\16#ff;\16#ff;\16#ff;";
inBitStream.tailSize +:= 5;
inBitStream.eofBytePos := succ(length(inBitStream.striBuffer)) -
inBitStream.tailSize;
end if;
inBitStream.limit := max(0, length(inBitStream.striBuffer) - 4);
inBitStream.bytePos := 1;
end func;
const proc: fillBuffer (inout msbInBitStream: inBitStream) is func
begin
if inBitStream.bytePos > inBitStream.limit then
fillStriBuffer(inBitStream);
end if;
inBitStream.buffer := bytes2Int(inBitStream.striBuffer[inBitStream.bytePos fixLen 5], UNSIGNED, BE);
end func;
const func msbInBitStream: openMsbInBitStream (in file: inFile) is func
result
var msbInBitStream: inBitStream is msbInBitStream.value;
begin
inBitStream.inFile := inFile;
fillBuffer(inBitStream);
end func;
const func msbInBitStream: openMsbBitStream (in file: inFile) is
return openMsbInBitStream(inFile);
const func msbInBitStream: openMsbInBitStream (in string: stri) is func
result
var msbInBitStream: inBitStream is msbInBitStream.value;
begin
inBitStream.striBuffer := stri & "\16#ff;\16#ff;\16#ff;\16#ff;\16#ff;";
inBitStream.tailSize := 5;
inBitStream.eofBytePos := succ(length(inBitStream.striBuffer)) -
inBitStream.tailSize;
inBitStream.limit := length(inBitStream.striBuffer) - 4;
fillBuffer(inBitStream);
end func;
const func msbInBitStream: openMsbBitStream (in string: stri) is
return openMsbInBitStream(stri);
const proc: close (inout msbInBitStream: inBitStream) is func
begin
if inBitStream.inFile <> STD_NULL then
if inBitStream.bitPos <> 40 then
incr(inBitStream.bytePos);
end if;
seek(inBitStream.inFile, tell(inBitStream.inFile) -
succ(length(inBitStream.striBuffer) -
inBitStream.bytePos - inBitStream.tailSize));
end if;
end func;
const func integer: getBit (inout msbInBitStream: inBitStream) is func
result
var integer: resultBit is 0;
begin
decr(inBitStream.bitPos);
resultBit := (inBitStream.buffer >> inBitStream.bitPos) mod 2;
if inBitStream.bitPos <= 32 then
inBitStream.bitPos := inBitStream.bitPos + 8;
incr(inBitStream.bytePos);
if inBitStream.bytePos > inBitStream.limit then
fillStriBuffer(inBitStream);
end if;
inBitStream.buffer := ((inBitStream.buffer mod 2 ** 32) << 8) +
bytes2Int(inBitStream.striBuffer[inBitStream.bytePos + 4 fixLen 1], UNSIGNED, BE);
end if;
end func;
const func integer: getBits (inout msbInBitStream: inBitStream, in integer: bitWidth) is func
result
var integer: resultBits is 0;
local
var integer: bytePosDelta is 0;
begin
inBitStream.bitPos -:= bitWidth;
resultBits := (inBitStream.buffer >> inBitStream.bitPos) mod (1 << bitWidth);
if inBitStream.bitPos <= 32 then
bytePosDelta := 4 - pred(inBitStream.bitPos) mdiv 8;
inBitStream.bitPos := inBitStream.bitPos + 8 * bytePosDelta;
inBitStream.bytePos +:= bytePosDelta;
if inBitStream.bytePos > inBitStream.limit then
fillStriBuffer(inBitStream);
end if;
if bytePosDelta = 1 then
inBitStream.buffer := ((inBitStream.buffer mod 2 ** 32) << 8) +
bytes2Int(inBitStream.striBuffer[inBitStream.bytePos + 4 fixLen 1], UNSIGNED, BE);
else
inBitStream.buffer := bytes2Int(inBitStream.striBuffer[inBitStream.bytePos fixLen 5], UNSIGNED, BE);
end if;
end if;
end func;
const func integer: peekBits (inout msbInBitStream: inBitStream, in integer: bitWidth) is
return (inBitStream.buffer >> (inBitStream.bitPos - bitWidth)) mod (1 << bitWidth);
const proc: skipBits (inout msbInBitStream: inBitStream, in integer: bitWidth) is func
local
var integer: bytePosDelta is 0;
begin
inBitStream.bitPos -:= bitWidth;
if inBitStream.bitPos <= 32 then
bytePosDelta := 4 - pred(inBitStream.bitPos) mdiv 8;
inBitStream.bitPos := inBitStream.bitPos + 8 * bytePosDelta;
inBitStream.bytePos +:= bytePosDelta;
if inBitStream.bytePos > inBitStream.limit then
fillStriBuffer(inBitStream);
end if;
if bytePosDelta = 1 then
inBitStream.buffer := ((inBitStream.buffer mod 2 ** 32) << 8) +
bytes2Int(inBitStream.striBuffer[inBitStream.bytePos + 4 fixLen 1], UNSIGNED, BE);
else
inBitStream.buffer := bytes2Int(inBitStream.striBuffer[inBitStream.bytePos fixLen 5], UNSIGNED, BE);
end if;
end if;
end func;
const func boolean: eof (in msbInBitStream: inBitStream) is
return inBitStream.bytePos >= inBitStream.eofBytePos and
(inBitStream.bytePos > inBitStream.eofBytePos or
inBitStream.bitPos < inBitStream.eofBitPos);
const func string: gets (inout msbInBitStream: inBitStream, in integer: maxLength) is func
result
var string: striRead is "";
begin
if maxLength < 0 then
raise RANGE_ERROR;
else
if inBitStream.bitPos <> 40 then
incr(inBitStream.bytePos);
inBitStream.bitPos := 40;
end if;
if maxLength <> 0 then
if maxLength <= succ(length(inBitStream.striBuffer) - inBitStream.bytePos) then
striRead := inBitStream.striBuffer[inBitStream.bytePos fixLen maxLength];
inBitStream.bytePos +:= maxLength;
else
striRead := inBitStream.striBuffer[inBitStream.bytePos ..] &
gets(inBitStream.inFile, maxLength -
succ(length(inBitStream.striBuffer) - inBitStream.bytePos));
inBitStream.striBuffer := "";
inBitStream.limit := 0;
inBitStream.bytePos := 1;
end if;
end if;
fillBuffer(inBitStream);
end if;
end func;
const type: lsbOutBitStream is new struct
var integer: buffer is 0;
var integer: bitPos is 0;
var string: byteString is "";
end struct;
const proc: putBit (inout lsbOutBitStream: outBitStream, in integer: bit) is func
begin
outBitStream.buffer +:= bit << outBitStream.bitPos;
incr(outBitStream.bitPos);
if outBitStream.bitPos = 8 then
outBitStream.byteString &:= char(outBitStream.buffer);
outBitStream.bitPos := 0;
outBitStream.buffer := 0;
end if;
end func;
const proc: putBits (inout lsbOutBitStream: outBitStream, in integer: bits,
in integer: bitWidth) is func
begin
outBitStream.buffer +:= bits << outBitStream.bitPos;
outBitStream.bitPos +:= bitWidth;
while outBitStream.bitPos >= 8 do
outBitStream.byteString &:= char(outBitStream.buffer mod 256);
outBitStream.bitPos -:= 8;
outBitStream.buffer >>:= 8;
end while;
end func;
const func integer: length (in lsbOutBitStream: outBitStream) is
return length(outBitStream.byteString) * 8 + outBitStream.bitPos;
const proc: truncate (inout lsbOutBitStream: outBitStream, in integer: length) is func
local
var integer: bytePos is 0;
var integer: bitPos is 0;
begin
if length < 0 then
raise RANGE_ERROR;
else
bytePos := length mdiv 8;
bitPos := length mod 8;
if bytePos < length(outBitStream.byteString) then
outBitStream.buffer := ord(outBitStream.byteString[succ(bytePos)]) mod 2 ** bitPos;
outBitStream.byteString := outBitStream.byteString[.. bytePos];
elsif bytePos = length(outBitStream.byteString) then
if bitPos < outBitStream.bitPos then
outBitStream.buffer := outBitStream.buffer mod 2 ** bitPos;
end if;
else
outBitStream.byteString &:= char(outBitStream.buffer);
outBitStream.byteString &:= "\0;" mult bytePos - length(outBitStream.byteString);
outBitStream.buffer := 0;
end if;
outBitStream.bitPos := bitPos;
end if;
end func;
const proc: flush (inout lsbOutBitStream: outBitStream) is func
begin
if outBitStream.bitPos <> 0 then
outBitStream.byteString &:= char(outBitStream.buffer);
outBitStream.bitPos := 0;
end if;
outBitStream.buffer := 0;
end func;
const func string: getBytes (inout lsbOutBitStream: outBitStream) is func
result
var string: bytes is "";
begin
bytes := outBitStream.byteString;
outBitStream.byteString := "";
end func;
const proc: write (inout lsbOutBitStream: outBitStream, in string: stri) is func
begin
flush(outBitStream);
outBitStream.byteString &:= stri;
end func;
const type: msbOutBitStream is new struct
var integer: buffer is 0;
var integer: bitSize is 0;
var string: byteString is "";
end struct;
const proc: putBit (inout msbOutBitStream: outBitStream, in integer: bit) is func
begin
outBitStream.buffer <<:= 1;
outBitStream.buffer +:= bit;
incr(outBitStream.bitSize);
if outBitStream.bitSize = 8 then
outBitStream.byteString &:= char(outBitStream.buffer);
outBitStream.bitSize := 0;
outBitStream.buffer := 0;
end if;
end func;
const proc: putBits (inout msbOutBitStream: outBitStream, in integer: bits,
in integer: bitWidth) is func
local
var integer: bitShift is 0;
begin
outBitStream.buffer <<:= bitWidth;
outBitStream.buffer +:= bits;
outBitStream.bitSize +:= bitWidth;
if outBitStream.bitSize >= 8 then
bitShift := outBitStream.bitSize;
repeat
bitShift -:= 8;
outBitStream.byteString &:= char((outBitStream.buffer >> bitShift) mod 256);
until bitShift < 8;
outBitStream.bitSize := bitShift;
outBitStream.buffer := outBitStream.buffer mod 2 ** bitShift;
end if;
end func;
const func integer: length (in msbOutBitStream: outBitStream) is
return length(outBitStream.byteString) * 8 + outBitStream.bitSize;
const proc: truncate (inout msbOutBitStream: outBitStream, in integer: length) is func
local
var integer: bytePos is 0;
var integer: bitSize is 0;
begin
if length < 0 then
raise RANGE_ERROR;
else
bytePos := length mdiv 8;
bitSize := length mod 8;
if bytePos < length(outBitStream.byteString) then
outBitStream.buffer := ord(outBitStream.byteString[succ(bytePos)]) >> (8 - bitSize);
outBitStream.byteString := outBitStream.byteString[.. bytePos];
elsif bytePos = length(outBitStream.byteString) then
if bitSize < outBitStream.bitSize then
outBitStream.buffer >>:= outBitStream.bitSize - bitSize;
elsif bitSize > outBitStream.bitSize then
outBitStream.buffer <<:= bitSize - outBitStream.bitSize;
end if;
else
outBitStream.byteString &:= char(outBitStream.buffer << (8 - outBitStream.bitSize));
outBitStream.byteString &:= "\0;" mult bytePos - length(outBitStream.byteString);
outBitStream.buffer := 0;
end if;
outBitStream.bitSize := bitSize;
end if;
end func;
const proc: flush (inout msbOutBitStream: outBitStream) is func
begin
if outBitStream.bitSize <> 0 then
outBitStream.byteString &:= char(outBitStream.buffer << (8 - outBitStream.bitSize));
outBitStream.bitSize := 0;
end if;
outBitStream.buffer := 0;
end func;
const func string: getBytes (inout msbOutBitStream: outBitStream) is func
result
var string: bytes is "";
begin
bytes := outBitStream.byteString;
outBitStream.byteString := "";
end func;
const proc: write (inout msbOutBitStream: outBitStream, in string: stri) is func
begin
flush(outBitStream);
outBitStream.byteString &:= stri;
end func;
const proc: putBitLsb (inout string: stri, inout integer: bitPos, in integer: bit) is func
begin
if bitPos = 0 then
stri &:= chr(bit);
bitPos := 1;
else
stri @:= [length(stri)] chr(ord(stri[length(stri)]) + (bit << bitPos));
bitPos := succ(bitPos) mod 8;
end if;
end func;
const proc: putBitsLsb (inout string: stri, inout integer: bitPos, in var integer: bits,
in var integer: bitWidth) is func
local
var integer: bitsFree is 0;
begin
bitsFree := 8 - bitPos;
if bitsFree > bitWidth then
if bitPos = 0 then
stri &:= chr(bits << bitPos);
else
stri @:= [length(stri)] chr(ord(stri[length(stri)]) + (bits << bitPos));
end if;
bitPos +:= bitWidth;
else
if bitPos <> 0 then
stri @:= [length(stri)] chr(ord(stri[length(stri)]) + ((bits mod (1 << bitsFree)) << bitPos));
bits >>:= bitsFree;
bitWidth -:= bitsFree;
end if;
while bitWidth >= 8 do
stri &:= chr(bits mod 256);
bits >>:= 8;
bitWidth -:= 8;
end while;
if bitWidth >= 1 then
stri &:= chr(bits);
bitPos := bitWidth;
else
bitPos := 0;
end if;
end if;
end func;
const proc: putBitMsb (inout string: stri, inout integer: bitPos, in integer: bit) is func
begin
if bitPos = 0 then
stri &:= chr(bit << 7);
bitPos := 1;
else
stri @:= [length(stri)] chr(ord(stri[length(stri)]) + (bit << (7 - bitPos)));
bitPos := succ(bitPos) mod 8;
end if;
end func;
const proc: putBitsMsb (inout string: stri, inout integer: bitPos, in var integer: bits,
in var integer: bitWidth) is func
local
var integer: bitsFree is 0;
begin
bitsFree := 8 - bitPos;
if bitsFree > bitWidth then
if bitPos = 0 then
stri &:= chr(bits << (bitsFree - bitWidth));
else
stri @:= [length(stri)] chr(ord(stri[length(stri)]) + (bits << (bitsFree - bitWidth)));
end if;
bitPos +:= bitWidth;
else
if bitPos <> 0 then
bitWidth -:= bitsFree;
stri @:= [length(stri)] chr(ord(stri[length(stri)]) + (bits >> bitWidth));
bits := bits mod (1 << bitWidth);
end if;
while bitWidth >= 8 do
bitWidth -:= 8;
stri &:= chr(bits >> bitWidth);
bits := bits mod (1 << bitWidth);
end while;
if bitWidth >= 1 then
stri &:= chr(bits << (8 - bitWidth));
bitPos := bitWidth;
else
bitPos := 0;
end if;
end if;
end func;
const func integer: getBitLsb (inout file: inFile, inout integer: bitPos) is func
result
var integer: resultBit is 0;
begin
if bitPos = 8 then
inFile.bufferChar := getc(inFile);
resultBit := ord(inFile.bufferChar) mod 2;
bitPos := 1;
else
resultBit := (ord(inFile.bufferChar) >> bitPos) mod 2;
incr(bitPos);
end if;
end func;
const func integer: getBitsLsb (inout file: inFile, inout integer: bitPos,
in var integer: bitWidth) is func
result
var integer: resultBits is 0;
local
var integer: bitsInByte is 0;
var integer: bitsInResult is 0;
begin
if bitPos = 8 then
bitPos := 0;
inFile.bufferChar := getc(inFile);
end if;
bitsInByte := 8 - bitPos;
if bitsInByte >= bitWidth then
resultBits := (ord(inFile.bufferChar) >> bitPos) mod (1 << bitWidth);
bitPos +:= bitWidth;
else
resultBits := ord(inFile.bufferChar) mod 256 >> bitPos;
inFile.bufferChar := getc(inFile);
bitWidth -:= bitsInByte;
bitsInResult := bitsInByte;
while bitWidth > 8 do
resultBits +:= ord(inFile.bufferChar) << bitsInResult;
inFile.bufferChar := getc(inFile);
bitWidth -:= 8;
bitsInResult +:= 8;
end while;
resultBits +:= ord(inFile.bufferChar) mod (1 << bitWidth) << bitsInResult;
bitPos := bitWidth;
end if;
end func;
const proc: putBitLsb (inout file: outFile, inout integer: bitPos, in integer: bit) is func
begin
if bitPos = 7 then
write(outFile, chr(ord(outFile.bufferChar) + (bit << bitPos)));
outFile.bufferChar := '\0;';
bitPos := 0;
else
outFile.bufferChar := chr(ord(outFile.bufferChar) + (bit << bitPos));
incr(bitPos);
end if;
end func;
const proc: putBitsLsb (inout file: outFile, inout integer: bitPos, in var integer: bits,
in var integer: bitWidth) is func
local
var integer: bitsFree is 0;
begin
bitsFree := 8 - bitPos;
if bitsFree > bitWidth then
outFile.bufferChar := chr(ord(outFile.bufferChar) + (bits << bitPos));
bitPos +:= bitWidth;
else
write(outFile, chr(ord(outFile.bufferChar) + ((bits mod (1 << bitsFree)) << bitPos)));
bits >>:= bitsFree;
bitWidth -:= bitsFree;
while bitWidth >= 8 do
write(outFile, chr(bits mod 256));
bits >>:= 8;
bitWidth -:= 8;
end while;
if bitWidth >= 1 then
outFile.bufferChar := chr(bits);
bitPos := bitWidth;
else
outFile.bufferChar := '\0;';
bitPos := 0;
end if;
end if;
end func;
const func integer: getBitMsb (inout file: inFile, inout integer: bitPos) is func
result
var integer: resultBit is 0;
begin
if bitPos = 8 then
inFile.bufferChar := getc(inFile);
resultBit := (ord(inFile.bufferChar) >> 7) mod 2;
bitPos := 1;
else
resultBit := (ord(inFile.bufferChar) >> (7 - bitPos)) mod 2;
incr(bitPos);
end if;
end func;
const func integer: getBitsMsb (inout file: inFile, inout integer: bitPos,
in var integer: bitWidth) is func
result
var integer: resultBits is 0;
local
var integer: bitsInByte is 0;
begin
if bitPos = 8 then
bitPos := 0;
inFile.bufferChar := getc(inFile);
end if;
bitsInByte := 8 - bitPos;
if bitsInByte >= bitWidth then
resultBits := (ord(inFile.bufferChar) >> (bitsInByte - bitWidth)) mod (1 << bitWidth);
bitPos +:= bitWidth;
else
resultBits := ord(inFile.bufferChar) mod (1 << bitsInByte);
inFile.bufferChar := getc(inFile);
bitWidth -:= bitsInByte;
while bitWidth > 8 do
resultBits <<:= 8;
resultBits +:= ord(inFile.bufferChar);
inFile.bufferChar := getc(inFile);
bitWidth -:= 8;
end while;
resultBits <<:= bitWidth;
resultBits +:= (ord(inFile.bufferChar) >> (8 - bitWidth));
bitPos := bitWidth;
end if;
end func;
const proc: putBitMsb (inout file: outFile, inout integer: bitPos, in integer: bit) is func
begin
if bitPos = 7 then
write(outFile, chr(ord(outFile.bufferChar) + bit));
outFile.bufferChar := '\0;';
bitPos := 0;
else
outFile.bufferChar := chr(ord(outFile.bufferChar) + (bit << (7 - bitPos)));
incr(bitPos);
end if;
end func;
const proc: putBitsMsb (inout file: outFile, inout integer: bitPos, in var integer: bits,
in var integer: bitWidth) is func
local
var integer: bitsFree is 0;
begin
bitsFree := 8 - bitPos;
if bitsFree > bitWidth then
outFile.bufferChar := chr(ord(outFile.bufferChar) + (bits << (bitsFree - bitWidth)));
bitPos +:= bitWidth;
else
bitWidth -:= bitsFree;
write(outFile, chr(ord(outFile.bufferChar) + (bits >> bitWidth)));
bits := bits mod (1 << bitWidth);
while bitWidth >= 8 do
bitWidth -:= 8;
write(outFile, chr(bits >> bitWidth));
bits := bits mod (1 << bitWidth);
end while;
if bitWidth >= 1 then
outFile.bufferChar := chr(bits << (8 - bitWidth));
bitPos := bitWidth;
else
outFile.bufferChar := '\0;';
bitPos := 0;
end if;
end if;
end func;
const type: reverseBitStream is new struct
var string: data is "";
var integer: offset is 0;
end struct;
const func reverseBitStream: reverseBitStream (inout file: inFile, in integer: length) is func
result
var reverseBitStream: inBitStream is reverseBitStream.value;
begin
inBitStream.data := gets(inFile, length);
inBitStream.offset := pred(length(inBitStream.data) * 8);
end func;
const func integer: bitsStillInStream (in reverseBitStream: inBitStream) is
return succ(inBitStream.offset);
const func integer: bitsRead (in reverseBitStream: inBitStream) is
return pred(length(inBitStream.data) * 8) - inBitStream.offset;
const func integer: getBits (inout reverseBitStream: inBitStream, in integer: bitWidth) is func
result
var integer: resultBits is 0;
local
var integer: indexOfHighestByte is 0;
var integer: bitsLeftInHighestByte is 0;
var integer: keepBitsInHighestByte is 0;
var integer: valueFromHighestByte is 0;
var integer: spanningFullBytes is 0;
var integer: bitsFromLowestByte is 0;
var integer: indexOfLowestByte is 0;
var integer: startIndex is 0;
var integer: index is 0;
begin
if bitWidth <> 0 then
if inBitStream.offset >= 0 then
indexOfHighestByte := succ(inBitStream.offset mdiv 8);
bitsLeftInHighestByte := succ(inBitStream.offset mod 8);
if bitWidth < bitsLeftInHighestByte then
keepBitsInHighestByte := bitsLeftInHighestByte - bitWidth;
resultBits := (ord(inBitStream.data[indexOfHighestByte]) >> keepBitsInHighestByte) mod (1 << bitWidth);
else
valueFromHighestByte := ord(inBitStream.data[indexOfHighestByte]) mod (1 << bitsLeftInHighestByte);
if bitWidth = bitsLeftInHighestByte then
resultBits := valueFromHighestByte;
else
spanningFullBytes := (bitWidth - bitsLeftInHighestByte) mdiv 8;
bitsFromLowestByte := (bitWidth - bitsLeftInHighestByte) mod 8;
indexOfLowestByte := pred(indexOfHighestByte - spanningFullBytes);
if indexOfLowestByte >= 1 then
resultBits := ord(inBitStream.data[indexOfLowestByte]) >> (8 - bitsFromLowestByte);
else
startIndex := -indexOfLowestByte;
end if;
for index range startIndex to pred(spanningFullBytes) do
resultBits +:= ord(inBitStream.data[succ(indexOfLowestByte) + index]) << (index * 8 + bitsFromLowestByte);
end for;
resultBits +:= valueFromHighestByte << (spanningFullBytes * 8 + bitsFromLowestByte);
end if;
end if;
end if;
inBitStream.offset -:= bitWidth;
end if;
end func;