diff --git a/codecs/scale_offset/README.md b/codecs/scale_offset/README.md index 56e30f8..92415e1 100644 --- a/codecs/scale_offset/README.md +++ b/codecs/scale_offset/README.md @@ -90,11 +90,12 @@ The following snippet of array metadata demonstrates the metadata for the `scale ### Uint16 range reduction -In this example, a `uint16` array with values in the range `[1000, 1255]` is shifted down by `1000` so that values fall in the range `[0, 255]`, then cast to `uint8` via the `cast_value` codec. +In this example, a `uint16` array with values in the range `[1000, 1255]` is shifted down by `1000` so that values fall in the range `[0, 255]`, then cast to `uint8` via the `cast_value` codec. Note that with these codecs,`fill_value` is constrained to the range `[1000, 1255]`. ```json { "data_type": "uint16", + "fill_value": 1000, "codecs": [ { "name": "scale_offset", @@ -113,6 +114,41 @@ In this example, a `uint16` array with values in the range `[1000, 1255]` is shi } ``` +Using a `cast_value` codec with a `scalar_map` makes it possible for any `fill_value` to be used by mapping it into the valid range without changing the data type. Here, first mapping the `fill_value` `0 → 1000` has equivalent behavior to the example above. + +```json +{ + "data_type": "uint16", + "fill_value": 0, + "codecs": [ + { + "name": "cast_value", + "configuration": { + "data_type": "uint16" + "scalar_map": { + "encode": [[0, 1000]], + "decode": [[1000, 0]] + } + } + }, + { + "name": "scale_offset", + "configuration": { + "offset": 1000 + } + }, + { + "name": "cast_value", + "configuration": { + "data_type": "uint8" + } + }, + "bytes" + ] +} +``` + + ### Float64 to uint8 with NaN preservation In this example, a `float64` array with values in the range `[0.0, 2540.0]` and a fill value of `NaN` is stored as `uint8`. The `scale_offset` codec maps values from `[0.0, 2540.0]` to `[1.0, 255.0]` by applying `(x - offset) * scale` with `offset = -10` and `scale = 0.1`, reserving `0` for `NaN`. The `cast_value` codec then casts to `uint8`, using `scalar_map` to explicitly map `NaN` to `0` on encode and `0` to `NaN` on decode. This ensures a lossless round-trip for the fill value. There is no such assurance for