Packages

Library that enables programs to write Data Matrix barcodes of the modern ECC200 variety.

Current section

Files

Jump to
data_matrix lib datamatrix reed_solomon.ex
Raw

lib/datamatrix/reed_solomon.ex

defmodule DataMatrix.ReedSolomon do
@moduledoc false
import Bitwise
alias DataMatrix.GaloisField
@poly Code.eval_file("lib/datamatrix/static/polynomials.map") |> elem(0)
@blocks Code.eval_file("lib/datamatrix/static/interleaved_blocks.tuple") |> elem(0)
@error_codewords Code.eval_file("lib/datamatrix/static/total_error_codewords.tuple") |> elem(0)
@doc """
## Examples
iex> DataMatrix.ReedSolomon.encode(0, <<142, 164, 186>>)
<<114, 25, 5, 88, 102>>
"""
def encode(version, data) do
blocks = elem(@blocks, version)
errors = elem(@error_codewords, version)
length = div(errors, blocks)
coefficients = gen_poly(length)
0..(blocks - 1)
|> Stream.map(fn offset ->
:binary.bin_to_list(data)
|> Enum.drop(offset)
|> Enum.take_every(blocks)
|> Enum.reduce(
Stream.cycle([0]) |> Enum.take(length + 1),
fn codeword, acc ->
k = Enum.at(acc, 0) ^^^ codeword
acc =
for j <- 0..(length - 1),
do: Enum.at(acc, j + 1) ^^^ prod(k, elem(coefficients, length - j - 1))
Enum.concat(acc, [0])
end
)
|> Enum.take(length)
end)
|> Enum.zip()
|> Enum.flat_map(&Tuple.to_list(&1))
|> :binary.list_to_bin()
end
defp gen_poly(nc), do: Map.get(@poly, nc)
defp prod(0, _), do: 0
defp prod(_, 0), do: 0
defp prod(a, b) do
GaloisField.antilog(rem(GaloisField.log(a) + GaloisField.log(b), 255))
end
end