/// <summary> /// Decode of the constrained whole number /// ITU-T X.691. 10.5. /// NOTE – (Tutorial) This subclause is referenced by other clauses, /// and itself references earlier clauses for the production of /// a nonnegative-binary-integer or a 2's-complement-binary-integer encoding. /// </summary> protected virtual long decodeConstraintNumber(long min, long max, BitArrayInputStream stream) { long result = 0; long valueRange = max - min; //!!!! int narrowedVal = value - min; !!! int maxBitLen = PERCoderUtils.getMaxBitLength(valueRange); if (valueRange == 0) { return(max); } // The rest of this Note addresses the ALIGNED variant. if (valueRange > 0 && valueRange < 256) { /* * 1. Where the range is less than or equal to 255, the value encodes * into a bit-field of the minimum size for the range. * 2. Where the range is exactly 256, the value encodes * into a single octet octet-aligned bit-field. */ skipAlignedBits(stream); result = stream.readBits(maxBitLen); result += min; } else if (valueRange > 0 && valueRange < 65536) { /* * 3. Where the range is 257 to 64K, the value encodes into * a two octet octet-aligned bit-field. */ skipAlignedBits(stream); result = stream.ReadByte() << 8; result = (int)result | stream.ReadByte(); result += min; } else { /* * 4. Where the range is greater than 64K, the range is ignored * and the value encodes into an octet-aligned bit-field * which is the minimum number of octets for the value. * In this latter case, later procedures (see 10.9) * also encode a length field (usually a single octet) to indicate * the length of the encoding. For the other cases, the length * of the encoding is independent of the value being encoded, * and is not explicitly encoded. */ int intLen = decodeConstraintLengthDeterminant(1, CoderUtils.getPositiveIntegerLength(valueRange), stream); skipAlignedBits(stream); result = (int)decodeIntegerValueAsBytes(intLen, stream); result += min; } return(result); }
/// <summary> /// Encoding of a constrained whole number /// ITU-T X.691. 10.5. /// NOTE – (Tutorial) This subclause is referenced by other clauses, /// and itself references earlier clauses for the production of /// a nonnegative-binary-integer or a 2's-complement-binary-integer encoding. /// </summary> protected virtual int encodeConstraintNumber(long val, long min, long max, BitArrayOutputStream stream) { int result = 0; long valueRange = max - min; long narrowedVal = val - min; int maxBitLen = PERCoderUtils.getMaxBitLength(valueRange); if (valueRange == 0) { return(result); } // The rest of this Note addresses the ALIGNED variant. if (valueRange > 0 && valueRange < 256) { /* * 1. Where the range is less than or equal to 255, the value encodes * into a bit-field of the minimum size for the range. * 2. Where the range is exactly 256, the value encodes * into a single octet octet-aligned bit-field. */ doAlign(stream); for (int i = maxBitLen - 1; i >= 0; i--) { int bitValue = (int)((narrowedVal >> i) & 0x1); stream.writeBit(bitValue); } result = 1; } else if (valueRange > 0 && valueRange < 65536) { /* * 3. Where the range is 257 to 64K, the value encodes into * a two octet octet-aligned bit-field. */ doAlign(stream); stream.WriteByte((byte)(narrowedVal >> 8)); stream.WriteByte((byte)(narrowedVal & 0xFF)); result = 2; } else { /* * 4. Where the range is greater than 64K, the range is ignored * and the value encodes into an octet-aligned bit-field * which is the minimum number of octets for the value. * In this latter case, later procedures (see 10.9) * also encode a length field (usually a single octet) to indicate * the length of the encoding. For the other cases, the length * of the encoding is independent of the value being encoded, * and is not explicitly encoded. */ result = encodeConstraintLengthDeterminant(CoderUtils.getIntegerLength(narrowedVal), 1, CoderUtils.getPositiveIntegerLength(valueRange), stream); doAlign(stream); result += encodeIntegerValueAsBytes(narrowedVal, stream); } return(result); }