///|
/// Decode exactly one point record; the caller supplies the declared record length.
pub fn read_point(data : Bytes, format : Int32) -> Point raise LasError {
  let width = record_size(format)
  require(
    data.length() >= width && data.length() <= 65535,
    "invalid point record width",
  )
  let r = Reader::new(data, 0, data.length())
  let x = r.i32()
  let y = r.i32()
  let z = r.i32()
  let intensity = r.u16()
  let returns_byte = r.u8()
  let modern = format >= 6
  let return_number = returns_byte & (if modern { 15 } else { 7 })
  let returns = (returns_byte >> (if modern { 4 } else { 3 })) &
    (if modern { 15 } else { 7 })
  let class_byte = r.u8()
  let flags = if modern { class_byte & 15 } else { class_byte >> 5 }
  let classification = if modern { r.u8() } else { class_byte & 31 }
  let scanner_channel = if modern { (class_byte >> 4) & 3 } else { 0 }
  let scan_direction = ((if modern { class_byte } else { returns_byte }) & 64) !=
    0
  let edge = ((if modern { class_byte } else { returns_byte }) & 128) != 0
  let mut scan_angle = 0
  let mut user_data = 0
  if modern {
    user_data = r.u8()
    scan_angle = r.i16()
  } else {
    let raw = r.u8()
    scan_angle = if raw >= 128 { raw - 256 } else { raw }
    user_data = r.u8()
  }
  let source_id = r.u16()
  let gps_time = if format == 1 || format == 3 || modern {
    Some(r.f64())
  } else {
    None
  }
  let rgb = if format == 2 || format == 3 || format == 7 || format == 8 {
    Some((r.u16(), r.u16(), r.u16()))
  } else {
    None
  }
  let nir = if format == 8 { Some(r.u16()) } else { None }
  let extra = r.take(r.end - r.pos)
  let point = {
    x,
    y,
    z,
    intensity,
    return_number,
    returns,
    classification,
    flags,
    scanner_channel,
    scan_direction,
    edge,
    scan_angle,
    user_data,
    source_id,
    gps_time,
    rgb,
    nir,
    extra,
  }
  point.validate(format)
  point
}