compress function

Uint8List? compress(
  1. List<int> v,
  2. int slen
)

Compress v into a bytestring of length slen.

Returns null when the encoding does not fit in slen bytes (the reference returns False in that case).

Implementation

Uint8List? compress(List<int> v, int slen) {
  // Bit string built as a list of 0/1, matching the reference's string `u`.
  final List<int> bits = <int>[];

  for (final int coef in v) {
    final int abs = coef.abs();

    // Sign bit: '1' if negative, else '0'.
    bits.add(coef < 0 ? 1 : 0);

    // 7 low bits of abs(coef), MSB-first.
    final int low = abs & 0x7f;
    for (int i = 6; i >= 0; i--) {
      bits.add((low >> i) & 1);
    }

    // High bits in unary: (abs >> 7) zeros, then a terminating '1'.
    final int high = abs >> 7;
    for (int i = 0; i < high; i++) {
      bits.add(0);
    }
    bits.add(1);
  }

  final int totalBits = 8 * slen;
  // The encoding is too long to fit.
  if (bits.length > totalBits) {
    return null;
  }

  // Zero-pad to the full byte length.
  while (bits.length < totalBits) {
    bits.add(0);
  }

  // Pack MSB-first into bytes.
  final Uint8List out = Uint8List(slen);
  for (int i = 0; i < slen; i++) {
    int byte = 0;
    for (int j = 0; j < 8; j++) {
      byte = (byte << 1) | bits[8 * i + j];
    }
    out[i] = byte;
  }
  return out;
}