-module(qrkit@internal@rmqr).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/qrkit/internal/rmqr.gleam").
-export([version/1, width/1, height/1, rows/1, mask/1, dimensions/1, encode/4]).
-export_type([encoded/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-opaque encoded() :: {encoded,
integer(),
integer(),
integer(),
list(list(boolean()))}.
-file("src/qrkit/internal/rmqr.gleam", 26).
?DOC(false).
-spec version(encoded()) -> integer().
version(Encoded) ->
{encoded, Version, _, _, _} = Encoded,
Version.
-file("src/qrkit/internal/rmqr.gleam", 31).
?DOC(false).
-spec width(encoded()) -> integer().
width(Encoded) ->
{encoded, _, Width, _, _} = Encoded,
Width.
-file("src/qrkit/internal/rmqr.gleam", 36).
?DOC(false).
-spec height(encoded()) -> integer().
height(Encoded) ->
{encoded, _, _, Height, _} = Encoded,
Height.
-file("src/qrkit/internal/rmqr.gleam", 41).
?DOC(false).
-spec rows(encoded()) -> list(list(boolean())).
rows(Encoded) ->
{encoded, _, _, _, Rows} = Encoded,
Rows.
-file("src/qrkit/internal/rmqr.gleam", 49).
?DOC(false).
-spec mask(encoded()) -> integer().
mask(_) ->
4.
-file("src/qrkit/internal/rmqr.gleam", 196).
?DOC(false).
-spec validate_ecc(qrkit@types:error_correction()) -> {ok, nil} |
{error, qrkit@error:encode_error()}.
validate_ecc(Ecc) ->
case Ecc of
medium ->
{ok, nil};
high ->
{ok, nil};
_ ->
{error,
{incompatible_options,
<<"rMQR only supports M or H error correction levels"/utf8>>}}
end.
-file("src/qrkit/internal/rmqr.gleam", 223).
?DOC(false).
-spec classify_char(binary()) -> qrkit@types:mode().
classify_char(Char) ->
case qrkit@internal@mode:is_numeric_char(Char) of
true ->
numeric;
false ->
case qrkit@internal@mode:is_alphanumeric_char(Char) of
true ->
alphanumeric;
false ->
case qrkit@internal@mode:is_kanji_char(Char) of
true ->
kanji;
false ->
byte
end
end
end.
-file("src/qrkit/internal/rmqr.gleam", 238).
?DOC(false).
-spec refine_mode(qrkit@types:mode(), qrkit@types:mode()) -> qrkit@types:mode().
refine_mode(Current, Next) ->
case {Current, Next} of
{byte, _} ->
byte;
{_, byte} ->
byte;
{kanji, _} ->
byte;
{_, kanji} ->
byte;
{alphanumeric, numeric} ->
alphanumeric;
{numeric, alphanumeric} ->
alphanumeric;
{_, _} ->
Next
end.
-file("src/qrkit/internal/rmqr.gleam", 216).
?DOC(false).
-spec uniform_mode(list(binary()), qrkit@types:mode()) -> qrkit@types:mode().
uniform_mode(Chars, Best) ->
case Chars of
[] ->
Best;
[Char | Rest] ->
uniform_mode(Rest, refine_mode(Best, classify_char(Char)))
end.
-file("src/qrkit/internal/rmqr.gleam", 206).
?DOC(false).
-spec select_mode(binary(), qrkit@types:mode_preference()) -> {ok,
qrkit@types:mode()} |
{error, qrkit@error:encode_error()}.
select_mode(Text, Preference) ->
case Preference of
force_byte ->
{ok, byte};
auto ->
{ok, uniform_mode(qrkit@internal@util:characters(Text), numeric)}
end.
-file("src/qrkit/internal/rmqr.gleam", 291).
?DOC(false).
-spec lookup_int(list(integer()), integer()) -> integer().
lookup_int(Table, Index) ->
qrkit@internal@util:at_or(Table, Index, 0).
-file("src/qrkit/internal/rmqr.gleam", 295).
?DOC(false).
-spec mode_indicator(qrkit@types:mode()) -> integer().
mode_indicator(Selected_mode) ->
case Selected_mode of
numeric ->
2#001;
alphanumeric ->
2#010;
byte ->
2#011;
kanji ->
2#100
end.
-file("src/qrkit/internal/rmqr.gleam", 334).
?DOC(false).
-spec append_terminator(qrkit@internal@bitstream:bit_stream(), integer()) -> qrkit@internal@bitstream:bit_stream().
append_terminator(Stream, Capacity) ->
Remaining = Capacity - qrkit@internal@bitstream:length_bits(Stream),
Bits = case Remaining < 3 of
true ->
Remaining;
false ->
3
end,
case Bits =< 0 of
true ->
Stream;
false ->
qrkit@internal@bitstream:append_bits(Stream, 0, Bits)
end.
-file("src/qrkit/internal/rmqr.gleam", 356).
?DOC(false).
-spec do_pad_to_data(
qrkit@internal@bitstream:bit_stream(),
integer(),
integer()
) -> qrkit@internal@bitstream:bit_stream().
do_pad_to_data(Stream, Data_bytes, Index) ->
Current = erlang:length(qrkit@internal@bitstream:to_byte_list(Stream)),
case Current >= Data_bytes of
true ->
Stream;
false ->
Byte = case (Index rem 2) =:= 0 of
true ->
16#EC;
false ->
16#11
end,
do_pad_to_data(
qrkit@internal@bitstream:append_byte(Stream, Byte),
Data_bytes,
Index + 1
)
end.
-file("src/qrkit/internal/rmqr.gleam", 349).
?DOC(false).
-spec pad_to_data(qrkit@internal@bitstream:bit_stream(), integer()) -> qrkit@internal@bitstream:bit_stream().
pad_to_data(Stream, Data_bytes) ->
do_pad_to_data(Stream, Data_bytes, 0).
-file("src/qrkit/internal/rmqr.gleam", 397).
?DOC(false).
-spec draw_timing_borders(qrkit@internal@matrix:matrix(), integer(), integer()) -> qrkit@internal@matrix:matrix().
draw_timing_borders(Target, H_size, V_size) ->
Top_bottom = begin
_pipe = qrkit@internal@util:range(0, H_size - 1),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Col) ->
Dark = (Col rem 2) =:= 0,
_pipe@1 = Acc,
_pipe@2 = qrkit@internal@matrix:set(_pipe@1, 0, Col, Dark, true),
qrkit@internal@matrix:set(_pipe@2, V_size - 1, Col, Dark, true)
end
)
end,
_pipe@3 = qrkit@internal@util:range(0, V_size - 1),
gleam@list:fold(
_pipe@3,
Top_bottom,
fun(Acc@1, Row) ->
Dark@1 = (Row rem 2) =:= 0,
_pipe@4 = Acc@1,
_pipe@5 = qrkit@internal@matrix:set(_pipe@4, Row, 0, Dark@1, true),
qrkit@internal@matrix:set(_pipe@5, Row, H_size - 1, Dark@1, true)
end
).
-file("src/qrkit/internal/rmqr.gleam", 419).
?DOC(false).
-spec draw_top_left_finder(qrkit@internal@matrix:matrix()) -> qrkit@internal@matrix:matrix().
draw_top_left_finder(Target) ->
_pipe = qrkit@internal@util:range(0, 6),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Row) -> _pipe@1 = qrkit@internal@util:range(0, 6),
gleam@list:fold(
_pipe@1,
Acc,
fun(Acc2, Col) ->
Dark = ((((Row =:= 0) orelse (Row =:= 6)) orelse (Col =:= 0))
orelse (Col =:= 6))
orelse ((((Row >= 2) andalso (Row =< 4)) andalso (Col >= 2))
andalso (Col =< 4)),
qrkit@internal@matrix:set(Acc2, Row, Col, Dark, true)
end
) end
).
-file("src/qrkit/internal/rmqr.gleam", 435).
?DOC(false).
-spec draw_bottom_right_subfinder(
qrkit@internal@matrix:matrix(),
integer(),
integer()
) -> qrkit@internal@matrix:matrix().
draw_bottom_right_subfinder(Target, H_size, V_size) ->
_pipe = qrkit@internal@util:range(0, 4),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Row) -> _pipe@1 = qrkit@internal@util:range(0, 4),
gleam@list:fold(
_pipe@1,
Acc,
fun(Acc2, Col) ->
Dark = ((((Row =:= 0) orelse (Row =:= 4)) orelse (Col =:= 0))
orelse (Col =:= 4))
orelse ((Row =:= 2) andalso (Col =:= 2)),
qrkit@internal@matrix:set(
Acc2,
(V_size - 5) + Row,
(H_size - 5) + Col,
Dark,
true
)
end
) end
).
-file("src/qrkit/internal/rmqr.gleam", 451).
?DOC(false).
-spec draw_top_right_corner(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
draw_top_right_corner(Target, H_size) ->
_pipe = Target,
_pipe@1 = qrkit@internal@matrix:set(_pipe, 0, H_size - 2, true, true),
_pipe@2 = qrkit@internal@matrix:set(_pipe@1, 1, H_size - 2, false, true),
qrkit@internal@matrix:set(_pipe@2, 1, H_size - 1, true, true).
-file("src/qrkit/internal/rmqr.gleam", 458).
?DOC(false).
-spec draw_bottom_left_corner(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
draw_bottom_left_corner(Target, V_size) ->
_pipe = Target,
_pipe@1 = qrkit@internal@matrix:set(_pipe, V_size - 2, 0, true, true),
_pipe@2 = qrkit@internal@matrix:set(_pipe@1, V_size - 2, 1, false, true),
qrkit@internal@matrix:set(_pipe@2, V_size - 1, 1, true, true).
-file("src/qrkit/internal/rmqr.gleam", 465).
?DOC(false).
-spec draw_separator(qrkit@internal@matrix:matrix(), integer(), integer()) -> qrkit@internal@matrix:matrix().
draw_separator(Target, H_size, V_size) ->
With_right = begin
_pipe = qrkit@internal@util:range(0, 6),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Row) ->
qrkit@internal@matrix:set(Acc, Row, 7, false, true)
end
)
end,
case V_size > 7 of
false ->
With_right;
true ->
_pipe@1 = qrkit@internal@util:range(0, 7),
gleam@list:fold(
_pipe@1,
With_right,
fun(Acc@1, Col) -> case Col >= H_size of
true ->
Acc@1;
false ->
qrkit@internal@matrix:set(
Acc@1,
7,
Col,
false,
true
)
end end
)
end.
-file("src/qrkit/internal/rmqr.gleam", 504).
?DOC(false).
-spec alignment_row_for_width(integer()) -> {ok, integer()} | {error, nil}.
alignment_row_for_width(H_size) ->
case H_size of
43 ->
{ok, 0};
59 ->
{ok, 1};
77 ->
{ok, 2};
99 ->
{ok, 3};
139 ->
{ok, 4};
_ ->
{error, nil}
end.
-file("src/qrkit/internal/rmqr.gleam", 541).
?DOC(false).
-spec draw_alignment_column(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer()
) -> qrkit@internal@matrix:matrix().
draw_alignment_column(Target, Column, _, V_size) ->
With_line = begin
_pipe = qrkit@internal@util:range(0, V_size - 1),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Row) ->
Dark = (Row rem 2) =:= 0,
qrkit@internal@matrix:set(Acc, Row, Column, Dark, true)
end
)
end,
_pipe@1 = With_line,
_pipe@2 = qrkit@internal@matrix:set(_pipe@1, 1, Column - 1, true, true),
_pipe@3 = qrkit@internal@matrix:set(_pipe@2, 2, Column - 1, true, true),
_pipe@4 = qrkit@internal@matrix:set(_pipe@3, 1, Column + 1, true, true),
_pipe@5 = qrkit@internal@matrix:set(_pipe@4, 2, Column + 1, true, true),
_pipe@6 = qrkit@internal@matrix:set(
_pipe@5,
V_size - 3,
Column - 1,
true,
true
),
_pipe@7 = qrkit@internal@matrix:set(
_pipe@6,
V_size - 2,
Column - 1,
true,
true
),
_pipe@8 = qrkit@internal@matrix:set(
_pipe@7,
V_size - 3,
Column + 1,
true,
true
),
qrkit@internal@matrix:set(_pipe@8, V_size - 2, Column + 1, true, true).
-file("src/qrkit/internal/rmqr.gleam", 564).
?DOC(false).
-spec reserve_format_info(qrkit@internal@matrix:matrix(), integer(), integer()) -> qrkit@internal@matrix:matrix().
reserve_format_info(Target, H_size, V_size) ->
Left_main = begin
_pipe = qrkit@internal@util:range(0, 4),
gleam@list:fold(
_pipe,
Target,
fun(Acc_i, I) -> _pipe@1 = qrkit@internal@util:range(0, 2),
gleam@list:fold(
_pipe@1,
Acc_i,
fun(Acc_j, J) ->
qrkit@internal@matrix:set(
Acc_j,
I + 1,
J + 8,
false,
true
)
end
) end
)
end,
Left_extra = begin
_pipe@2 = qrkit@internal@util:range(1, 3),
gleam@list:fold(
_pipe@2,
Left_main,
fun(Acc, Row) ->
qrkit@internal@matrix:set(Acc, Row, 11, false, true)
end
)
end,
Right_main = begin
_pipe@3 = qrkit@internal@util:range(0, 4),
gleam@list:fold(
_pipe@3,
Left_extra,
fun(Acc_i@1, I@1) -> _pipe@4 = qrkit@internal@util:range(0, 2),
gleam@list:fold(
_pipe@4,
Acc_i@1,
fun(Acc_j@1, J@1) ->
qrkit@internal@matrix:set(
Acc_j@1,
(V_size - 6) + I@1,
(H_size - 8) + J@1,
false,
true
)
end
) end
)
end,
_pipe@5 = qrkit@internal@util:range(0, 2),
gleam@list:fold(
_pipe@5,
Right_main,
fun(Acc@1, K) ->
qrkit@internal@matrix:set(
Acc@1,
V_size - 6,
(H_size - 5) + K,
false,
true
)
end
).
-file("src/qrkit/internal/rmqr.gleam", 630).
?DOC(false).
-spec power_of_two(integer()) -> integer().
power_of_two(Index) ->
case Index =< 0 of
true ->
1;
false ->
2 * power_of_two(Index - 1)
end.
-file("src/qrkit/internal/rmqr.gleam", 626).
?DOC(false).
-spec bit_at(integer(), integer()) -> boolean().
bit_at(Byte, Position) ->
((case power_of_two(Position) of
0 -> 0;
Gleam@denominator -> Byte div Gleam@denominator
end) rem 2) =:= 1.
-file("src/qrkit/internal/rmqr.gleam", 608).
?DOC(false).
-spec codewords_to_bits(list(integer()), list(boolean())) -> list(boolean()).
codewords_to_bits(Codewords, Acc) ->
case Codewords of
[] ->
lists:reverse(Acc);
[Byte | Rest] ->
codewords_to_bits(
Rest,
[bit_at(Byte, 0),
bit_at(Byte, 1),
bit_at(Byte, 2),
bit_at(Byte, 3),
bit_at(Byte, 4),
bit_at(Byte, 5),
bit_at(Byte, 6),
bit_at(Byte, 7) |
Acc]
)
end.
-file("src/qrkit/internal/rmqr.gleam", 669).
?DOC(false).
-spec try_place(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
list({integer(), integer()}),
integer()
) -> {list({integer(), integer()}), integer()}.
try_place(Target, Row, Col, Acc, Collected) ->
case (Col < 0) orelse (Col >= qrkit@internal@matrix:width(Target)) of
true ->
{Acc, Collected};
false ->
case qrkit@internal@matrix:is_reserved(Target, Row, Col) of
true ->
{Acc, Collected};
false ->
{[{Row, Col} | Acc], Collected + 1}
end
end.
-file("src/qrkit/internal/rmqr.gleam", 686).
?DOC(false).
-spec advance(integer(), integer(), integer(), integer()) -> {integer(),
integer(),
integer()}.
advance(V_size, X, Y, Direction) ->
case Direction of
1 ->
case Y =:= 0 of
true ->
{X - 2, 0, 0};
false ->
{X, Y - 1, 1}
end;
_ ->
case Y =:= (V_size - 1) of
true ->
{X - 2, V_size - 1, 1};
false ->
{X, Y + 1, 0}
end
end.
-file("src/qrkit/internal/rmqr.gleam", 648).
?DOC(false).
-spec do_data_positions(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer(),
integer(),
integer(),
list({integer(), integer()})
) -> list({integer(), integer()}).
do_data_positions(Target, X, Y, Direction, Collected, Needed, Acc) ->
case (Collected >= Needed) orelse (X < 0) of
true ->
lists:reverse(Acc);
false ->
{Acc1, Count1} = try_place(Target, Y, X + 1, Acc, Collected),
{Acc2, Count2} = try_place(Target, Y, X, Acc1, Count1),
{Next_x, Next_y, Next_dir} = advance(
qrkit@internal@matrix:height(Target),
X,
Y,
Direction
),
do_data_positions(
Target,
Next_x,
Next_y,
Next_dir,
Count2,
Needed,
Acc2
)
end.
-file("src/qrkit/internal/rmqr.gleam", 637).
?DOC(false).
-spec data_positions(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer()
) -> list({integer(), integer()}).
data_positions(Target, H_size, V_size, Total_codewords) ->
Bits_needed = Total_codewords * 8,
Initial_x = H_size - 3,
do_data_positions(Target, Initial_x, V_size - 1, 1, 0, Bits_needed, []).
-file("src/qrkit/internal/rmqr.gleam", 701).
?DOC(false).
-spec write_bits(
qrkit@internal@matrix:matrix(),
list({integer(), integer()}),
list(boolean())
) -> qrkit@internal@matrix:matrix().
write_bits(Target, Positions, Bits) ->
case {Positions, Bits} of
{[{Row, Col} | Rest_positions], [Bit | Rest_bits]} ->
write_bits(
qrkit@internal@matrix:set(Target, Row, Col, Bit, false),
Rest_positions,
Rest_bits
);
{_, _} ->
Target
end.
-file("src/qrkit/internal/rmqr.gleam", 596).
?DOC(false).
-spec place_data(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer(),
list(integer())
) -> qrkit@internal@matrix:matrix().
place_data(Target, H_size, V_size, Total_codewords, Codewords) ->
Bits = codewords_to_bits(Codewords, []),
Positions = data_positions(Target, H_size, V_size, Total_codewords),
write_bits(Target, Positions, Bits).
-file("src/qrkit/internal/rmqr.gleam", 721).
?DOC(false).
-spec do_apply_mask(qrkit@internal@matrix:matrix(), integer(), integer()) -> qrkit@internal@matrix:matrix().
do_apply_mask(Target, Row, Col) ->
case Row >= qrkit@internal@matrix:height(Target) of
true ->
Target;
false ->
case Col >= qrkit@internal@matrix:width(Target) of
true ->
do_apply_mask(Target, Row + 1, 0);
false ->
case qrkit@internal@matrix:is_reserved(Target, Row, Col) of
true ->
do_apply_mask(Target, Row, Col + 1);
false ->
do_apply_mask(
qrkit@internal@matrix:'xor'(
Target,
Row,
Col,
(((Row div 2) + (Col div 3)) rem 2) =:= 0
),
Row,
Col + 1
)
end
end
end.
-file("src/qrkit/internal/rmqr.gleam", 717).
?DOC(false).
-spec apply_fixed_mask(qrkit@internal@matrix:matrix()) -> qrkit@internal@matrix:matrix().
apply_fixed_mask(Target) ->
do_apply_mask(Target, 0, 0).
-file("src/qrkit/internal/rmqr.gleam", 758).
?DOC(false).
-spec place_left_format(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
place_left_format(Target, Bits) ->
Main = begin
_pipe = qrkit@internal@util:range(0, 4),
gleam@list:fold(
_pipe,
Target,
fun(Acc_i, I) -> _pipe@1 = qrkit@internal@util:range(0, 2),
gleam@list:fold(
_pipe@1,
Acc_i,
fun(Acc_j, J) ->
Dark = bit_at(Bits, (J * 5) + I),
qrkit@internal@matrix:set(
Acc_j,
I + 1,
J + 8,
Dark,
true
)
end
) end
)
end,
_pipe@2 = Main,
_pipe@3 = qrkit@internal@matrix:set(_pipe@2, 1, 11, bit_at(Bits, 15), true),
_pipe@4 = qrkit@internal@matrix:set(_pipe@3, 2, 11, bit_at(Bits, 16), true),
qrkit@internal@matrix:set(_pipe@4, 3, 11, bit_at(Bits, 17), true).
-file("src/qrkit/internal/rmqr.gleam", 774).
?DOC(false).
-spec place_right_format(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer()
) -> qrkit@internal@matrix:matrix().
place_right_format(Target, Bits, H_size, V_size) ->
Main = begin
_pipe = qrkit@internal@util:range(0, 4),
gleam@list:fold(
_pipe,
Target,
fun(Acc_i, I) -> _pipe@1 = qrkit@internal@util:range(0, 2),
gleam@list:fold(
_pipe@1,
Acc_i,
fun(Acc_j, J) ->
Dark = bit_at(Bits, (J * 5) + I),
qrkit@internal@matrix:set(
Acc_j,
(V_size - 6) + I,
(H_size - 8) + J,
Dark,
true
)
end
) end
)
end,
_pipe@2 = Main,
_pipe@3 = qrkit@internal@matrix:set(
_pipe@2,
V_size - 6,
H_size - 5,
bit_at(Bits, 15),
true
),
_pipe@4 = qrkit@internal@matrix:set(
_pipe@3,
V_size - 6,
H_size - 4,
bit_at(Bits, 16),
true
),
qrkit@internal@matrix:set(
_pipe@4,
V_size - 6,
H_size - 3,
bit_at(Bits, 17),
true
).
-file("src/qrkit/internal/rmqr.gleam", 795).
?DOC(false).
-spec result_try(
{ok, ENZ} | {error, qrkit@error:encode_error()},
fun((ENZ) -> {ok, EOC} | {error, qrkit@error:encode_error()})
) -> {ok, EOC} | {error, qrkit@error:encode_error()}.
result_try(Result, Callback) ->
case Result of
{ok, Value} ->
Callback(Value);
{error, Error} ->
{error, Error}
end.
-file("src/qrkit/internal/rmqr.gleam", 189).
?DOC(false).
-spec dimensions(integer()) -> {ok, {integer(), integer()}} |
{error, qrkit@error:encode_error()}.
dimensions(Index) ->
case (Index >= 0) andalso (Index < 32) of
true ->
{ok,
{lookup_int(
[43,
59,
77,
99,
139,
43,
59,
77,
99,
139,
27,
43,
59,
77,
99,
139,
27,
43,
59,
77,
99,
139,
43,
59,
77,
99,
139,
43,
59,
77,
99,
139],
Index
),
lookup_int(
[7,
7,
7,
7,
7,
9,
9,
9,
9,
9,
11,
11,
11,
11,
11,
11,
13,
13,
13,
13,
13,
13,
15,
15,
15,
15,
15,
17,
17,
17,
17,
17],
Index
)}};
false ->
{error, {invalid_version, Index + 1}}
end.
-file("src/qrkit/internal/rmqr.gleam", 275).
?DOC(false).
-spec data_codewords(integer(), qrkit@types:error_correction()) -> integer().
data_codewords(Index, Ecc) ->
case Ecc of
high ->
lookup_int(
[3,
7,
10,
14,
24,
7,
11,
17,
22,
33,
5,
11,
15,
23,
29,
42,
7,
13,
20,
29,
35,
54,
15,
26,
31,
48,
69,
21,
28,
38,
56,
76],
Index
);
_ ->
lookup_int(
[6,
12,
20,
28,
44,
12,
21,
31,
42,
63,
7,
19,
31,
43,
57,
84,
12,
27,
38,
53,
73,
106,
33,
48,
67,
88,
127,
39,
56,
78,
100,
152],
Index
)
end.
-file("src/qrkit/internal/rmqr.gleam", 271).
?DOC(false).
-spec data_capacity_bits(integer(), qrkit@types:error_correction()) -> integer().
data_capacity_bits(Index, Ecc) ->
data_codewords(Index, Ecc) * 8.
-file("src/qrkit/internal/rmqr.gleam", 282).
?DOC(false).
-spec lookup_cci(qrkit@types:mode(), integer()) -> integer().
lookup_cci(Selected_mode, Index) ->
case Selected_mode of
numeric ->
lookup_int(
[4,
5,
6,
7,
7,
5,
6,
7,
7,
8,
4,
6,
7,
7,
8,
8,
5,
6,
7,
7,
8,
8,
7,
7,
8,
8,
9,
7,
8,
8,
8,
9],
Index
);
alphanumeric ->
lookup_int(
[3,
5,
5,
6,
6,
5,
5,
6,
6,
7,
4,
5,
6,
6,
7,
7,
5,
6,
6,
7,
7,
8,
6,
7,
7,
7,
8,
6,
7,
7,
8,
8],
Index
);
byte ->
lookup_int(
[3,
4,
5,
5,
6,
4,
5,
5,
6,
6,
3,
5,
5,
6,
6,
7,
4,
5,
6,
6,
7,
7,
6,
6,
7,
7,
7,
6,
6,
7,
7,
8],
Index
);
kanji ->
lookup_int(
[2,
3,
4,
5,
5,
3,
4,
5,
5,
6,
2,
4,
5,
5,
6,
6,
3,
5,
5,
6,
6,
7,
5,
5,
6,
6,
7,
5,
6,
6,
6,
7],
Index
)
end.
-file("src/qrkit/internal/rmqr.gleam", 173).
?DOC(false).
-spec check_version(
binary(),
qrkit@types:mode(),
qrkit@types:error_correction(),
integer()
) -> {ok, integer()} | {error, qrkit@error:encode_error()}.
check_version(Text, Selected_mode, Ecc, Candidate) ->
Count_bits = lookup_cci(Selected_mode, Candidate),
Data_bits = (3 + Count_bits) + qrkit@internal@mode:data_bits_length(
Text,
Selected_mode
),
Capacity = data_capacity_bits(Candidate, Ecc),
case Data_bits =< Capacity of
true ->
{ok, Candidate};
false ->
{error, {data_exceeds_capacity, Data_bits, Capacity}}
end.
-file("src/qrkit/internal/rmqr.gleam", 250).
?DOC(false).
-spec find_version(
binary(),
qrkit@types:mode(),
qrkit@types:error_correction(),
integer()
) -> {ok, integer()} | {error, qrkit@error:encode_error()}.
find_version(Text, Selected_mode, Ecc, Candidate) ->
case Candidate >= 32 of
true ->
{error, {data_exceeds_capacity, 0, 0}};
false ->
Count_bits = lookup_cci(Selected_mode, Candidate),
Data_bits = (3 + Count_bits) + qrkit@internal@mode:data_bits_length(
Text,
Selected_mode
),
Capacity = data_capacity_bits(Candidate, Ecc),
case Data_bits =< Capacity of
true ->
{ok, Candidate};
false ->
find_version(Text, Selected_mode, Ecc, Candidate + 1)
end
end.
-file("src/qrkit/internal/rmqr.gleam", 157).
?DOC(false).
-spec resolve_version(
binary(),
qrkit@types:mode(),
qrkit@types:error_correction(),
gleam@option:option(integer())
) -> {ok, integer()} | {error, qrkit@error:encode_error()}.
resolve_version(Text, Selected_mode, Ecc, Requested_version) ->
case Requested_version of
none ->
find_version(Text, Selected_mode, Ecc, 0);
{some, Value} ->
case (Value < 1) orelse (Value > 32) of
true ->
{error, {invalid_version, Value}};
false ->
check_version(Text, Selected_mode, Ecc, Value - 1)
end
end.
-file("src/qrkit/internal/rmqr.gleam", 304).
?DOC(false).
-spec create_codewords(
binary(),
qrkit@types:mode(),
qrkit@types:error_correction(),
integer()
) -> {ok, list(integer())} | {error, qrkit@error:encode_error()}.
create_codewords(Text, Selected_mode, Ecc, Index) ->
Count_bits = lookup_cci(Selected_mode, Index),
Count_value = qrkit@internal@mode:character_count(Text, Selected_mode),
result_try(
qrkit@internal@mode:encode(Text, Selected_mode, 0),
fun(Payload) ->
Capacity = data_capacity_bits(Index, Ecc),
Stream = begin
_pipe = qrkit@internal@bitstream:new(),
_pipe@1 = qrkit@internal@bitstream:append_bits(
_pipe,
mode_indicator(Selected_mode),
3
),
_pipe@2 = qrkit@internal@bitstream:append_bits(
_pipe@1,
Count_value,
Count_bits
),
_pipe@3 = qrkit@internal@bitstream:append_bytes(
_pipe@2,
Payload
),
append_terminator(_pipe@3, Capacity)
end,
case qrkit@internal@bitstream:length_bits(Stream) > Capacity of
true ->
{error,
{data_exceeds_capacity,
qrkit@internal@bitstream:length_bits(Stream),
Capacity}};
false ->
Aligned = qrkit@internal@bitstream:pad_to_byte_boundary(
Stream
),
Padded = pad_to_data(Aligned, data_codewords(Index, Ecc)),
Data_bytes = qrkit@internal@bitstream:to_byte_list(Padded),
Total = lookup_int(
[13,
21,
32,
44,
68,
21,
33,
49,
66,
99,
15,
31,
47,
67,
89,
132,
21,
41,
60,
85,
113,
166,
51,
74,
103,
136,
199,
61,
88,
122,
160,
232],
Index
),
Ec_count = Total - data_codewords(Index, Ecc),
Ec_bytes = qrkit@internal@reed_solomon:encode(
Data_bytes,
Ec_count
),
{ok, lists:append(Data_bytes, Ec_bytes)}
end
end
).
-file("src/qrkit/internal/rmqr.gleam", 741).
?DOC(false).
-spec place_format_info(
qrkit@internal@matrix:matrix(),
integer(),
qrkit@types:error_correction(),
integer(),
integer()
) -> qrkit@internal@matrix:matrix().
place_format_info(Target, Index, Ecc, H_size, V_size) ->
Table_index = case Ecc of
high ->
Index + 32;
_ ->
Index
end,
Left = lookup_int(
[16#1FAB2,
16#1E597,
16#1DBDD,
16#1C4F8,
16#1B86C,
16#1A749,
16#19903,
16#18626,
16#17F0E,
16#1602B,
16#15E61,
16#14144,
16#13DD0,
16#122F5,
16#11CBF,
16#1039A,
16#0F1CA,
16#0EEEF,
16#0D0A5,
16#0CF80,
16#0B314,
16#0AC31,
16#0927B,
16#08D5E,
16#07476,
16#06B53,
16#05519,
16#04A3C,
16#036A8,
16#0298D,
16#017C7,
16#008E2,
16#3F367,
16#3EC42,
16#3D208,
16#3CD2D,
16#3B1B9,
16#3AE9C,
16#390D6,
16#38FF3,
16#376DB,
16#369FE,
16#357B4,
16#34891,
16#33405,
16#32B20,
16#3156A,
16#30A4F,
16#2F81F,
16#2E73A,
16#2D970,
16#2C655,
16#2BAC1,
16#2A5E4,
16#29BAE,
16#2848B,
16#27DA3,
16#26286,
16#25CCC,
16#243E9,
16#23F7D,
16#22058,
16#21E12,
16#20137],
Table_index
),
Right = lookup_int(
[16#20A7B,
16#2155E,
16#22B14,
16#23431,
16#248A5,
16#25780,
16#269CA,
16#276EF,
16#28FC7,
16#290E2,
16#2AEA8,
16#2B18D,
16#2CD19,
16#2D23C,
16#2EC76,
16#2F353,
16#30103,
16#31E26,
16#3206C,
16#33F49,
16#343DD,
16#35CF8,
16#362B2,
16#37D97,
16#384BF,
16#39B9A,
16#3A5D0,
16#3BAF5,
16#3C661,
16#3D944,
16#3E70E,
16#3F82B,
16#003AE,
16#01C8B,
16#022C1,
16#03DE4,
16#04170,
16#05E55,
16#0601F,
16#07F3A,
16#08612,
16#09937,
16#0A77D,
16#0B858,
16#0C4CC,
16#0DBE9,
16#0E5A3,
16#0FA86,
16#108D6,
16#117F3,
16#129B9,
16#1369C,
16#14A08,
16#1552D,
16#16B67,
16#17442,
16#18D6A,
16#1924F,
16#1AC05,
16#1B320,
16#1CFB4,
16#1D091,
16#1EEDB,
16#1F1FE],
Table_index
),
With_left = place_left_format(Target, Left),
place_right_format(With_left, Right, H_size, V_size).
-file("src/qrkit/internal/rmqr.gleam", 515).
?DOC(false).
-spec do_draw_alignment_columns(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer(),
integer()
) -> qrkit@internal@matrix:matrix().
do_draw_alignment_columns(Target, H_size, V_size, H_version, Index) ->
case Index >= 4 of
true ->
Target;
false ->
Column = lookup_int(
[21,
0,
0,
0,
19,
39,
0,
0,
25,
51,
0,
0,
23,
49,
75,
0,
27,
55,
83,
111],
(H_version * 4) + Index
),
case Column of
0 ->
Target;
_ ->
do_draw_alignment_columns(
draw_alignment_column(Target, Column, H_size, V_size),
H_size,
V_size,
H_version,
Index + 1
)
end
end.
-file("src/qrkit/internal/rmqr.gleam", 488).
?DOC(false).
-spec draw_alignment_patterns(
qrkit@internal@matrix:matrix(),
integer(),
integer()
) -> qrkit@internal@matrix:matrix().
draw_alignment_patterns(Target, H_size, V_size) ->
case H_size > 27 of
false ->
Target;
true ->
case alignment_row_for_width(H_size) of
{error, _} ->
Target;
{ok, H_version} ->
do_draw_alignment_columns(
Target,
H_size,
V_size,
H_version,
0
)
end
end.
-file("src/qrkit/internal/rmqr.gleam", 374).
?DOC(false).
-spec build_matrix(
integer(),
qrkit@types:error_correction(),
integer(),
integer(),
integer(),
list(integer())
) -> qrkit@internal@matrix:matrix().
build_matrix(Index, Ecc, H_size, V_size, Total_codewords, Codewords) ->
Base = begin
_pipe = qrkit@internal@matrix:new(H_size, V_size),
_pipe@1 = draw_timing_borders(_pipe, H_size, V_size),
_pipe@2 = draw_top_left_finder(_pipe@1),
_pipe@3 = draw_bottom_right_subfinder(_pipe@2, H_size, V_size),
_pipe@4 = draw_top_right_corner(_pipe@3, H_size),
_pipe@5 = draw_bottom_left_corner(_pipe@4, V_size),
_pipe@6 = draw_separator(_pipe@5, H_size, V_size),
_pipe@7 = draw_alignment_patterns(_pipe@6, H_size, V_size),
reserve_format_info(_pipe@7, H_size, V_size)
end,
Placed = place_data(Base, H_size, V_size, Total_codewords, Codewords),
Masked = apply_fixed_mask(Placed),
place_format_info(Masked, Index, Ecc, H_size, V_size).
-file("src/qrkit/internal/rmqr.gleam", 135).
?DOC(false).
-spec encode(
binary(),
qrkit@types:error_correction(),
gleam@option:option(integer()),
qrkit@types:mode_preference()
) -> {ok, encoded()} | {error, qrkit@error:encode_error()}.
encode(Text, Ecc, Requested_version, Preference) ->
result_try(
validate_ecc(Ecc),
fun(_) ->
result_try(
select_mode(Text, Preference),
fun(Selected_mode) ->
result_try(
resolve_version(
Text,
Selected_mode,
Ecc,
Requested_version
),
fun(Chosen) ->
result_try(
create_codewords(
Text,
Selected_mode,
Ecc,
Chosen
),
fun(Codewords) ->
H_size = lookup_int(
[43,
59,
77,
99,
139,
43,
59,
77,
99,
139,
27,
43,
59,
77,
99,
139,
27,
43,
59,
77,
99,
139,
43,
59,
77,
99,
139,
43,
59,
77,
99,
139],
Chosen
),
V_size = lookup_int(
[7,
7,
7,
7,
7,
9,
9,
9,
9,
9,
11,
11,
11,
11,
11,
11,
13,
13,
13,
13,
13,
13,
15,
15,
15,
15,
15,
17,
17,
17,
17,
17],
Chosen
),
Total = lookup_int(
[13,
21,
32,
44,
68,
21,
33,
49,
66,
99,
15,
31,
47,
67,
89,
132,
21,
41,
60,
85,
113,
166,
51,
74,
103,
136,
199,
61,
88,
122,
160,
232],
Chosen
),
Final_matrix = build_matrix(
Chosen,
Ecc,
H_size,
V_size,
Total,
Codewords
),
{ok,
{encoded,
Chosen + 1,
H_size,
V_size,
qrkit@internal@matrix:rows(
Final_matrix
)}}
end
)
end
)
end
)
end
).