convertBits function

List<int>? convertBits(
  1. List<int> data,
  2. int fromBits,
  3. int toBits, {
  4. bool pad = true,
})

Convert a list of integers from one bit size to another. This function takes a list of integers, 'data', and converts them from a given 'fromBits' size to a 'toBits' size, optionally padding the output list. It returns a new list of integers with the converted values or null if conversion is not possible due to invalid input.

Implementation

List<int>? convertBits(List<int> data, int fromBits, int toBits,
    {bool pad = true}) {
  int acc = 0;

  /// Accumulator to store intermediate values.
  int bits = 0;

  /// Number of bits in 'acc' that are valid.
  List<int> ret = [];

  /// Resulting list of converted integers.
  int maxv = (1 << toBits) - 1;

  /// Maximum value that can fit in 'toBits' bits.
  int maxAcc = (1 << (fromBits + toBits - 1)) - 1;

  /// Maximum accumulator value.

  /// Iterate through each value in the input 'data'.
  for (int value in data) {
    /// Check for invalid values.
    if (value < 0 || (value >> fromBits) > 0) {
      return null;
    }

    /// Update the accumulator with the new value and maintain 'bits'.
    acc = ((acc << fromBits) | value) & maxAcc;
    bits += fromBits;

    /// Extract and add full 'toBits' sized values to the result.
    while (bits >= toBits) {
      bits -= toBits;
      ret.add((acc >> bits) & maxv);
    }
  }

  /// Optionally pad the result if 'pad' is true.
  if (pad) {
    if (bits > 0) {
      ret.add((acc << (toBits - bits)) & maxv);
    }
  } else {
    /// Check for potential invalid padding or remaining bits.
    if (bits >= fromBits || ((acc << (toBits - bits)) & maxv) > 0) {
      return null;
    }
  }

  /// Return the converted list of integers.
  return ret;
}