-module(qrkit@internal@micro).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/qrkit/internal/micro.gleam").
-export([version/1, width/1, height/1, rows/1, mask/1, data_capacity_bits/2, ec_codewords/2, data_codewords/2, symbol_size/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(),
integer(),
list(list(boolean()))}.
-file("src/qrkit/internal/micro.gleam", 32).
?DOC(false).
-spec version(encoded()) -> integer().
version(Encoded) ->
{encoded, Version, _, _, _, _} = Encoded,
Version.
-file("src/qrkit/internal/micro.gleam", 37).
?DOC(false).
-spec width(encoded()) -> integer().
width(Encoded) ->
{encoded, _, Width, _, _, _} = Encoded,
Width.
-file("src/qrkit/internal/micro.gleam", 42).
?DOC(false).
-spec height(encoded()) -> integer().
height(Encoded) ->
{encoded, _, _, Height, _, _} = Encoded,
Height.
-file("src/qrkit/internal/micro.gleam", 47).
?DOC(false).
-spec rows(encoded()) -> list(list(boolean())).
rows(Encoded) ->
{encoded, _, _, _, _, Rows} = Encoded,
Rows.
-file("src/qrkit/internal/micro.gleam", 52).
?DOC(false).
-spec mask(encoded()) -> integer().
mask(Encoded) ->
{encoded, _, _, _, Mask, _} = Encoded,
Mask.
-file("src/qrkit/internal/micro.gleam", 177).
?DOC(false).
-spec mode_name(qrkit@types:mode()) -> binary().
mode_name(Selected_mode) ->
case Selected_mode of
numeric ->
<<"Numeric"/utf8>>;
alphanumeric ->
<<"Alphanumeric"/utf8>>;
byte ->
<<"Byte"/utf8>>;
kanji ->
<<"Kanji"/utf8>>
end.
-file("src/qrkit/internal/micro.gleam", 247).
?DOC(false).
-spec validate_ecc(qrkit@types:error_correction()) -> {ok, nil} |
{error, qrkit@error:encode_error()}.
validate_ecc(Ecc) ->
case Ecc of
low ->
{ok, nil};
medium ->
{ok, nil};
quartile ->
{ok, nil};
_ ->
{error,
{incompatible_options,
<<"Micro QR does not support the High error correction level"/utf8>>}}
end.
-file("src/qrkit/internal/micro.gleam", 275).
?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/micro.gleam", 290).
?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/micro.gleam", 267).
?DOC(false).
-spec detect_uniform_mode(list(binary()), qrkit@types:mode()) -> qrkit@types:mode().
detect_uniform_mode(Chars, Best) ->
case Chars of
[] ->
Best;
[Char | Rest] ->
detect_uniform_mode(Rest, refine_mode(Best, classify_char(Char)))
end.
-file("src/qrkit/internal/micro.gleam", 257).
?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,
detect_uniform_mode(
qrkit@internal@util:characters(Text),
numeric
)}
end.
-file("src/qrkit/internal/micro.gleam", 355).
?DOC(false).
-spec mode_supported(qrkit@types:mode(), integer()) -> boolean().
mode_supported(Selected_mode, Version) ->
case {Version, Selected_mode} of
{1, numeric} ->
true;
{1, _} ->
false;
{2, numeric} ->
true;
{2, alphanumeric} ->
true;
{2, _} ->
false;
{_, _} ->
true
end.
-file("src/qrkit/internal/micro.gleam", 365).
?DOC(false).
-spec mode_indicator_bits(integer()) -> integer().
mode_indicator_bits(Version) ->
Version - 1.
-file("src/qrkit/internal/micro.gleam", 369).
?DOC(false).
-spec mode_indicator_value(qrkit@types:mode()) -> integer().
mode_indicator_value(Selected_mode) ->
case Selected_mode of
numeric ->
0;
alphanumeric ->
1;
byte ->
2;
kanji ->
3
end.
-file("src/qrkit/internal/micro.gleam", 431).
?DOC(false).
-spec append_mode_indicator(
qrkit@internal@bitstream:bit_stream(),
qrkit@types:mode(),
integer()
) -> qrkit@internal@bitstream:bit_stream().
append_mode_indicator(Stream, Selected_mode, Version) ->
Bits = mode_indicator_bits(Version),
case Bits of
0 ->
Stream;
_ ->
qrkit@internal@bitstream:append_bits(
Stream,
mode_indicator_value(Selected_mode),
Bits
)
end.
-file("src/qrkit/internal/micro.gleam", 444).
?DOC(false).
-spec terminator_size(integer(), integer()) -> integer().
terminator_size(Version, Remaining) ->
Target = (Version * 2) + 1,
case Remaining < Target of
true ->
Remaining;
false ->
Target
end.
-file("src/qrkit/internal/micro.gleam", 465).
?DOC(false).
-spec pad_alternating(
qrkit@internal@bitstream:bit_stream(),
integer(),
integer()
) -> qrkit@internal@bitstream:bit_stream().
pad_alternating(Stream, Target_bytes, Index) ->
Current_bytes = erlang:length(qrkit@internal@bitstream:to_byte_list(Stream)),
case Current_bytes >= Target_bytes of
true ->
Stream;
false ->
Byte = case (Index rem 2) =:= 0 of
true ->
16#EC;
false ->
16#11
end,
pad_alternating(
qrkit@internal@bitstream:append_byte(Stream, Byte),
Target_bytes,
Index + 1
)
end.
-file("src/qrkit/internal/micro.gleam", 511).
?DOC(false).
-spec has_half_codeword(integer(), qrkit@types:error_correction()) -> boolean().
has_half_codeword(Version, Ecc) ->
case {Version, Ecc} of
{1, low} ->
true;
{3, low} ->
true;
{3, medium} ->
true;
{_, _} ->
false
end.
-file("src/qrkit/internal/micro.gleam", 576).
?DOC(false).
-spec reserve_format_info(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
reserve_format_info(Target, _) ->
Horizontal = begin
_pipe = qrkit@internal@util:range(1, 8),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Col) ->
qrkit@internal@matrix:set(Acc, 8, Col, false, true)
end
)
end,
_pipe@1 = qrkit@internal@util:range(1, 7),
gleam@list:fold(
_pipe@1,
Horizontal,
fun(Acc@1, Row) ->
qrkit@internal@matrix:set(Acc@1, Row, 8, false, true)
end
).
-file("src/qrkit/internal/micro.gleam", 647).
?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/micro.gleam", 643).
?DOC(false).
-spec bit_at(integer(), integer()) -> boolean().
bit_at(Value, Index) ->
((case power_of_two(Index) of
0 -> 0;
Gleam@denominator -> Value div Gleam@denominator
end) rem 2) =:= 1.
-file("src/qrkit/internal/micro.gleam", 627).
?DOC(false).
-spec append_byte_bits(integer(), integer(), integer(), list(boolean())) -> list(boolean()).
append_byte_bits(Byte, Bit_position, Remaining, Acc) ->
case Remaining =< 0 of
true ->
Acc;
false ->
append_byte_bits(
Byte,
Bit_position - 1,
Remaining - 1,
[bit_at(Byte, Bit_position) | Acc]
)
end.
-file("src/qrkit/internal/micro.gleam", 605).
?DOC(false).
-spec codewords_to_bits(
list(integer()),
integer(),
boolean(),
integer(),
list(boolean())
) -> list(boolean()).
codewords_to_bits(Codewords, Data_count, Half_codeword, Index, Acc) ->
case Codewords of
[] ->
lists:reverse(Acc);
[Byte | Rest] ->
Bit_count = case Half_codeword andalso ((Index + 1) =:= Data_count) of
true ->
4;
false ->
8
end,
Next_acc = append_byte_bits(Byte, 7, Bit_count, Acc),
codewords_to_bits(
Rest,
Data_count,
Half_codeword,
Index + 1,
Next_acc
)
end.
-file("src/qrkit/internal/micro.gleam", 695).
?DOC(false).
-spec maybe_take(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
list({integer(), integer()})
) -> list({integer(), integer()}).
maybe_take(Target, Row, Col, Acc) ->
case Col < 0 of
true ->
Acc;
false ->
case qrkit@internal@matrix:is_reserved(Target, Row, Col) of
true ->
Acc;
false ->
[{Row, Col} | Acc]
end
end.
-file("src/qrkit/internal/micro.gleam", 679).
?DOC(false).
-spec scan_column_pair(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer(),
list({integer(), integer()})
) -> {list({integer(), integer()}), integer(), integer()}.
scan_column_pair(Target, Col, Row, Inc, Acc) ->
With_right = maybe_take(Target, Row, Col, Acc),
With_both = maybe_take(Target, Row, Col - 1, With_right),
Next_row = Row + Inc,
case (Next_row < 0) orelse (Next_row >= qrkit@internal@matrix:height(Target)) of
true ->
{With_both, Row, 0 - Inc};
false ->
scan_column_pair(Target, Col, Next_row, Inc, With_both)
end.
-file("src/qrkit/internal/micro.gleam", 662).
?DOC(false).
-spec do_data_positions(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer(),
list({integer(), integer()})
) -> list({integer(), integer()}).
do_data_positions(Target, Col, Row, Inc, Acc) ->
case Col =< 0 of
true ->
lists:reverse(Acc);
false ->
{Next_acc, Last_row, Next_inc} = scan_column_pair(
Target,
Col,
Row,
Inc,
Acc
),
do_data_positions(Target, Col - 2, Last_row, Next_inc, Next_acc)
end.
-file("src/qrkit/internal/micro.gleam", 654).
?DOC(false).
-spec data_positions(qrkit@internal@matrix:matrix(), integer(), integer()) -> list({integer(),
integer()}).
data_positions(Target, Col, Row) ->
do_data_positions(Target, Col, Row, -1, []).
-file("src/qrkit/internal/micro.gleam", 711).
?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/micro.gleam", 810).
?DOC(false).
-spec micro_mask_at(integer(), integer(), integer()) -> boolean().
micro_mask_at(Mask, Row, Col) ->
case Mask of
0 ->
(Row rem 2) =:= 0;
1 ->
(((Row div 2) + (Col div 3)) rem 2) =:= 0;
2 ->
((((Row * Col) rem 2) + ((Row * Col) rem 3)) rem 2) =:= 0;
_ ->
((((Row + Col) rem 2) + ((Row * Col) rem 3)) rem 2) =:= 0
end.
-file("src/qrkit/internal/micro.gleam", 784).
?DOC(false).
-spec do_apply_mask(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer()
) -> qrkit@internal@matrix:matrix().
do_apply_mask(Target, Mask, 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, Mask, Row + 1, 0);
false ->
case qrkit@internal@matrix:is_reserved(Target, Row, Col) of
true ->
do_apply_mask(Target, Mask, Row, Col + 1);
false ->
do_apply_mask(
qrkit@internal@matrix:'xor'(
Target,
Row,
Col,
micro_mask_at(Mask, Row, Col)
),
Mask,
Row,
Col + 1
)
end
end
end.
-file("src/qrkit/internal/micro.gleam", 780).
?DOC(false).
-spec apply_mask(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
apply_mask(Target, Mask) ->
do_apply_mask(Target, Mask, 0, 0).
-file("src/qrkit/internal/micro.gleam", 847).
?DOC(false).
-spec do_count_dark_edge(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer(),
boolean(),
integer()
) -> integer().
do_count_dark_edge(Target, Axis, Current, To, Vertical, Acc) ->
case Current > To of
true ->
Acc;
false ->
Dark = case Vertical of
true ->
qrkit@internal@matrix:get(Target, Current, Axis);
false ->
qrkit@internal@matrix:get(Target, Axis, Current)
end,
Next_acc = case Dark of
true ->
Acc + 1;
false ->
Acc
end,
do_count_dark_edge(
Target,
Axis,
Current + 1,
To,
Vertical,
Next_acc
)
end.
-file("src/qrkit/internal/micro.gleam", 837).
?DOC(false).
-spec count_dark_edge(
qrkit@internal@matrix:matrix(),
integer(),
integer(),
integer(),
boolean()
) -> integer().
count_dark_edge(Target, Axis, From, To, Vertical) ->
do_count_dark_edge(Target, Axis, From, To, Vertical, 0).
-file("src/qrkit/internal/micro.gleam", 822).
?DOC(false).
-spec micro_penalty(qrkit@internal@matrix:matrix(), integer()) -> integer().
micro_penalty(Target, Size) ->
Last = Size - 1,
Dark_right = count_dark_edge(Target, Last, 1, Last, true),
Dark_bottom = count_dark_edge(Target, 1, Last, Last, false),
High = case Dark_right >= Dark_bottom of
true ->
Dark_right;
false ->
Dark_bottom
end,
Low = case Dark_right >= Dark_bottom of
true ->
Dark_bottom;
false ->
Dark_right
end,
(Low * 16) + High.
-file("src/qrkit/internal/micro.gleam", 882).
?DOC(false).
-spec place_horizontal_format(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
place_horizontal_format(Target, Bits) ->
_pipe = qrkit@internal@util:range(0, 7),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Index) ->
Col = Index + 1,
Dark = bit_at(Bits, 14 - Index),
qrkit@internal@matrix:set(Acc, 8, Col, Dark, true)
end
).
-file("src/qrkit/internal/micro.gleam", 891).
?DOC(false).
-spec place_vertical_format(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
place_vertical_format(Target, Bits) ->
_pipe = qrkit@internal@util:range(0, 6),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Index) ->
Row = 7 - Index,
Dark = bit_at(Bits, 6 - Index),
qrkit@internal@matrix:set(Acc, Row, 8, Dark, true)
end
).
-file("src/qrkit/internal/micro.gleam", 929).
?DOC(false).
-spec int_to_str(integer()) -> binary().
int_to_str(Value) ->
case Value of
1 ->
<<"1"/utf8>>;
2 ->
<<"2"/utf8>>;
3 ->
<<"3"/utf8>>;
4 ->
<<"4"/utf8>>;
_ ->
<<"?"/utf8>>
end.
-file("src/qrkit/internal/micro.gleam", 195).
?DOC(false).
-spec data_capacity_bits(integer(), qrkit@types:error_correction()) -> {ok,
integer()} |
{error, qrkit@error:encode_error()}.
data_capacity_bits(Version, Ecc) ->
case {Version, Ecc} of
{1, low} ->
{ok, 20};
{2, low} ->
{ok, 40};
{2, medium} ->
{ok, 32};
{3, low} ->
{ok, 84};
{3, medium} ->
{ok, 68};
{4, low} ->
{ok, 128};
{4, medium} ->
{ok, 112};
{4, quartile} ->
{ok, 80};
{_, _} ->
{error,
{incompatible_options,
<<<<"Micro QR M"/utf8, (int_to_str(Version))/binary>>/binary,
" does not support the requested error correction level"/utf8>>}}
end.
-file("src/qrkit/internal/micro.gleam", 218).
?DOC(false).
-spec ec_codewords(integer(), qrkit@types:error_correction()) -> {ok, integer()} |
{error, qrkit@error:encode_error()}.
ec_codewords(Version, Ecc) ->
case {Version, Ecc} of
{1, low} ->
{ok, 2};
{2, low} ->
{ok, 5};
{2, medium} ->
{ok, 6};
{3, low} ->
{ok, 6};
{3, medium} ->
{ok, 8};
{4, low} ->
{ok, 8};
{4, medium} ->
{ok, 10};
{4, quartile} ->
{ok, 14};
{_, _} ->
{error,
{incompatible_options,
<<<<"Micro QR M"/utf8, (int_to_str(Version))/binary>>/binary,
" does not support the requested error correction level"/utf8>>}}
end.
-file("src/qrkit/internal/micro.gleam", 378).
?DOC(false).
-spec char_count_bits_for_mode(qrkit@types:mode(), integer()) -> {ok, integer()} |
{error, qrkit@error:encode_error()}.
char_count_bits_for_mode(Selected_mode, Version) ->
case {Version, Selected_mode} of
{1, numeric} ->
{ok, 3};
{2, numeric} ->
{ok, 4};
{2, alphanumeric} ->
{ok, 3};
{3, numeric} ->
{ok, 5};
{3, alphanumeric} ->
{ok, 4};
{3, byte} ->
{ok, 4};
{3, kanji} ->
{ok, 3};
{4, numeric} ->
{ok, 6};
{4, alphanumeric} ->
{ok, 5};
{4, byte} ->
{ok, 5};
{4, kanji} ->
{ok, 4};
{_, _} ->
{error,
{incompatible_options,
<<"Mode is not supported by Micro QR M"/utf8,
(int_to_str(Version))/binary>>}}
end.
-file("src/qrkit/internal/micro.gleam", 333).
?DOC(false).
-spec encoded_bits(binary(), qrkit@types:mode(), integer()) -> {ok, integer()} |
{error, qrkit@error:encode_error()}.
encoded_bits(Text, Selected_mode, Version) ->
Mode_bits_count = mode_indicator_bits(Version),
case mode_supported(Selected_mode, Version) of
false ->
{error,
{incompatible_options,
<<"Mode not supported by Micro QR M"/utf8,
(int_to_str(Version))/binary>>}};
true ->
case char_count_bits_for_mode(Selected_mode, Version) of
{error, Error} ->
{error, Error};
{ok, Count_bits} ->
Data_bits = qrkit@internal@mode:data_bits_length(
Text,
Selected_mode
),
{ok, (Mode_bits_count + Count_bits) + Data_bits}
end
end.
-file("src/qrkit/internal/micro.gleam", 146).
?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) ->
case mode_supported(Selected_mode, Candidate) of
false ->
{error,
{incompatible_options,
<<<<<<<<"Micro QR M"/utf8, (int_to_str(Candidate))/binary>>/binary,
" does not support the "/utf8>>/binary,
(mode_name(Selected_mode))/binary>>/binary,
" mode"/utf8>>}};
true ->
case data_capacity_bits(Candidate, Ecc) of
{error, Error} ->
{error, Error};
{ok, Capacity} ->
case encoded_bits(Text, Selected_mode, Candidate) of
{error, Error@1} ->
{error, Error@1};
{ok, Required} ->
case Required =< Capacity of
true ->
{ok, Candidate};
false ->
{error,
{data_exceeds_capacity,
Required,
Capacity}}
end
end
end
end.
-file("src/qrkit/internal/micro.gleam", 490).
?DOC(false).
-spec data_codewords(integer(), qrkit@types:error_correction()) -> {ok,
integer()} |
{error, qrkit@error:encode_error()}.
data_codewords(Version, Ecc) ->
case data_capacity_bits(Version, Ecc) of
{ok, Bits} ->
{ok, (Bits + 7) div 8};
{error, Error} ->
{error, Error}
end.
-file("src/qrkit/internal/micro.gleam", 452).
?DOC(false).
-spec pad_to_capacity(
qrkit@internal@bitstream:bit_stream(),
integer(),
qrkit@types:error_correction()
) -> qrkit@internal@bitstream:bit_stream().
pad_to_capacity(Stream, Version, Ecc) ->
Aligned = qrkit@internal@bitstream:pad_to_byte_boundary(Stream),
Data_bytes_count = case data_codewords(Version, Ecc) of
{ok, Value} ->
Value;
{error, _} ->
0
end,
pad_alternating(Aligned, Data_bytes_count, 0).
-file("src/qrkit/internal/micro.gleam", 500).
?DOC(false).
-spec compute_ec(list(integer()), integer(), qrkit@types:error_correction()) -> {ok,
list(integer())} |
{error, qrkit@error:encode_error()}.
compute_ec(Data, Version, Ecc) ->
case ec_codewords(Version, Ecc) of
{ok, Degree} ->
{ok, qrkit@internal@reed_solomon:encode(Data, Degree)};
{error, Error} ->
{error, Error}
end.
-file("src/qrkit/internal/micro.gleam", 588).
?DOC(false).
-spec place_codewords(
qrkit@internal@matrix:matrix(),
list(integer()),
integer(),
qrkit@types:error_correction()
) -> qrkit@internal@matrix:matrix().
place_codewords(Target, Codewords, Version, Ecc) ->
Half = has_half_codeword(Version, Ecc),
Data_count = case data_codewords(Version, Ecc) of
{ok, Value} ->
Value;
{error, _} ->
0
end,
Bits = codewords_to_bits(Codewords, Data_count, Half, 0, []),
Positions = data_positions(
Target,
qrkit@internal@matrix:width(Target) - 1,
qrkit@internal@matrix:height(Target) - 1
),
write_bits(Target, Positions, Bits).
-file("src/qrkit/internal/micro.gleam", 910).
?DOC(false).
-spec symbol_number(integer(), qrkit@types:error_correction()) -> {ok,
integer()} |
{error, qrkit@error:encode_error()}.
symbol_number(Version, Ecc) ->
case {Version, Ecc} of
{1, low} ->
{ok, 0};
{2, low} ->
{ok, 1};
{2, medium} ->
{ok, 2};
{3, low} ->
{ok, 3};
{3, medium} ->
{ok, 4};
{4, low} ->
{ok, 5};
{4, medium} ->
{ok, 6};
{4, quartile} ->
{ok, 7};
{_, _} ->
{error,
{incompatible_options,
<<<<"Micro QR M"/utf8, (int_to_str(Version))/binary>>/binary,
" does not support the requested error correction level"/utf8>>}}
end.
-file("src/qrkit/internal/micro.gleam", 939).
?DOC(false).
-spec result_try(
{ok, DZL} | {error, qrkit@error:encode_error()},
fun((DZL) -> {ok, DZO} | {error, qrkit@error:encode_error()})
) -> {ok, DZO} | {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/micro.gleam", 401).
?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, Version) ->
result_try(
data_capacity_bits(Version, Ecc),
fun(Capacity) ->
result_try(
char_count_bits_for_mode(Selected_mode, Version),
fun(Count_bits) ->
Count_value = qrkit@internal@mode:character_count(
Text,
Selected_mode
),
result_try(
qrkit@internal@mode:encode(Text, Selected_mode, 0),
fun(Payload) ->
Stream = begin
_pipe = qrkit@internal@bitstream:new(),
_pipe@1 = append_mode_indicator(
_pipe,
Selected_mode,
Version
),
_pipe@2 = qrkit@internal@bitstream:append_bits(
_pipe@1,
Count_value,
Count_bits
),
qrkit@internal@bitstream:append_bytes(
_pipe@2,
Payload
)
end,
Total_bits = qrkit@internal@bitstream:length_bits(
Stream
),
case Total_bits > Capacity of
true ->
{error,
{data_exceeds_capacity,
Total_bits,
Capacity}};
false ->
Terminator_bits = terminator_size(
Version,
Capacity - Total_bits
),
With_terminator = qrkit@internal@bitstream:append_bits(
Stream,
0,
Terminator_bits
),
Padded = pad_to_capacity(
With_terminator,
Version,
Ecc
),
result_try(
{ok,
qrkit@internal@bitstream:to_byte_list(
Padded
)},
fun(Data_bytes) ->
result_try(
compute_ec(
Data_bytes,
Version,
Ecc
),
fun(Ec_bytes) ->
{ok,
lists:append(
Data_bytes,
Ec_bytes
)}
end
)
end
)
end
end
)
end
)
end
).
-file("src/qrkit/internal/micro.gleam", 549).
?DOC(false).
-spec draw_finder_module(qrkit@internal@matrix:matrix(), integer(), integer()) -> qrkit@internal@matrix:matrix().
draw_finder_module(Target, Row, Col) ->
Dark = case (Row =:= 7) orelse (Col =:= 7) of
true ->
false;
false ->
((((Row =:= 0) orelse (Row =:= (7 - 1))) orelse (Col =:= 0)) orelse (Col
=:= (7 - 1)))
orelse ((((Row >= 2) andalso (Row =< 4)) andalso (Col >= 2)) andalso (Col
=< 4))
end,
qrkit@internal@matrix:set(Target, Row, Col, Dark, true).
-file("src/qrkit/internal/micro.gleam", 541).
?DOC(false).
-spec draw_finder(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
draw_finder(Target, _) ->
_pipe = qrkit@internal@util:range(0, 7),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Row) -> _pipe@1 = qrkit@internal@util:range(0, 7),
gleam@list:fold(
_pipe@1,
Acc,
fun(Acc2, Col) -> draw_finder_module(Acc2, Row, Col) end
) end
).
-file("src/qrkit/internal/micro.gleam", 566).
?DOC(false).
-spec draw_timing(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
draw_timing(Target, Size) ->
_pipe = qrkit@internal@util:range(7 + 1, Size - 1),
gleam@list:fold(
_pipe,
Target,
fun(Acc, Index) ->
Dark = (Index rem 2) =:= 0,
_pipe@1 = Acc,
_pipe@2 = qrkit@internal@matrix:set(_pipe@1, 0, Index, Dark, true),
qrkit@internal@matrix:set(_pipe@2, Index, 0, Dark, true)
end
).
-file("src/qrkit/internal/micro.gleam", 187).
?DOC(false).
-spec symbol_size(integer()) -> {ok, integer()} |
{error, qrkit@error:encode_error()}.
symbol_size(Version) ->
case (Version >= 1) andalso (Version =< 4) of
true ->
{ok, (Version * 2) + 9};
false ->
{error, {invalid_version, Version}}
end.
-file("src/qrkit/internal/micro.gleam", 240).
?DOC(false).
-spec validate_version(integer()) -> {ok, nil} |
{error, qrkit@error:encode_error()}.
validate_version(Version) ->
case (Version >= 1) andalso (Version =< 4) of
true ->
{ok, nil};
false ->
{error, {invalid_version, Version}}
end.
-file("src/qrkit/internal/micro.gleam", 114).
?DOC(false).
-spec validate_requested(gleam@option:option(integer())) -> {ok, nil} |
{error, qrkit@error:encode_error()}.
validate_requested(Requested_version) ->
case Requested_version of
none ->
{ok, nil};
{some, Value} ->
validate_version(Value)
end.
-file("src/qrkit/internal/micro.gleam", 302).
?DOC(false).
-spec do_find_version(
binary(),
qrkit@types:mode(),
qrkit@types:error_correction(),
integer()
) -> {ok, integer()} | {error, qrkit@error:encode_error()}.
do_find_version(Text, Selected_mode, Ecc, Candidate) ->
case Candidate > 4 of
true ->
{error, {data_exceeds_capacity, 0, 0}};
false ->
case mode_supported(Selected_mode, Candidate) of
false ->
do_find_version(Text, Selected_mode, Ecc, Candidate + 1);
true ->
case data_capacity_bits(Candidate, Ecc) of
{error, _} ->
do_find_version(
Text,
Selected_mode,
Ecc,
Candidate + 1
);
{ok, Capacity} ->
case encoded_bits(Text, Selected_mode, Candidate) of
{error, _} ->
do_find_version(
Text,
Selected_mode,
Ecc,
Candidate + 1
);
{ok, Required} ->
case Required =< Capacity of
true ->
{ok, Candidate};
false ->
do_find_version(
Text,
Selected_mode,
Ecc,
Candidate + 1
)
end
end
end
end
end.
-file("src/qrkit/internal/micro.gleam", 131).
?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 ->
do_find_version(Text, Selected_mode, Ecc, 1);
{some, N} ->
check_version(Text, Selected_mode, Ecc, N)
end.
-file("src/qrkit/internal/micro.gleam", 900).
?DOC(false).
-spec format_bits(integer(), qrkit@types:error_correction(), integer()) -> integer().
format_bits(Version, Ecc, Mask) ->
case symbol_number(Version, Ecc) of
{ok, Number} ->
Index = (Number * 4) + Mask,
qrkit@internal@util:at_or(
[16#4445,
16#4172,
16#4E2B,
16#4B1C,
16#55AE,
16#5099,
16#5FC0,
16#5AF7,
16#6793,
16#62A4,
16#6DFD,
16#68CA,
16#7678,
16#734F,
16#7C16,
16#7921,
16#06DE,
16#03E9,
16#0CB0,
16#0987,
16#1735,
16#1202,
16#1D5B,
16#186C,
16#2508,
16#203F,
16#2F66,
16#2A51,
16#34E3,
16#31D4,
16#3E8D,
16#3BBA],
Index,
16#4445
);
{error, _} ->
16#4445
end.
-file("src/qrkit/internal/micro.gleam", 871).
?DOC(false).
-spec place_format_info(
qrkit@internal@matrix:matrix(),
integer(),
qrkit@types:error_correction(),
integer()
) -> qrkit@internal@matrix:matrix().
place_format_info(Target, Version, Ecc, Mask) ->
Bits = format_bits(Version, Ecc, Mask),
Horizontal = place_horizontal_format(Target, Bits),
place_vertical_format(Horizontal, Bits).
-file("src/qrkit/internal/micro.gleam", 736).
?DOC(false).
-spec do_choose_mask(
qrkit@internal@matrix:matrix(),
integer(),
qrkit@types:error_correction(),
integer(),
integer(),
integer(),
qrkit@internal@matrix:matrix(),
integer()
) -> {integer(), qrkit@internal@matrix:matrix()}.
do_choose_mask(
Target,
Version,
Ecc,
Size,
Candidate,
Best_mask,
Best_matrix,
Best_score
) ->
case Candidate > 3 of
true ->
{Best_mask, Best_matrix};
false ->
With_data = apply_mask(Target, Candidate),
Placed = place_format_info(With_data, Version, Ecc, Candidate),
Score = micro_penalty(Placed, Size),
case (Best_score < 0) orelse (Score > Best_score) of
true ->
do_choose_mask(
Target,
Version,
Ecc,
Size,
Candidate + 1,
Candidate,
Placed,
Score
);
false ->
do_choose_mask(
Target,
Version,
Ecc,
Size,
Candidate + 1,
Best_mask,
Best_matrix,
Best_score
)
end
end.
-file("src/qrkit/internal/micro.gleam", 727).
?DOC(false).
-spec choose_best_mask(
qrkit@internal@matrix:matrix(),
integer(),
qrkit@types:error_correction(),
integer()
) -> {integer(), qrkit@internal@matrix:matrix()}.
choose_best_mask(Target, Version, Ecc, Size) ->
do_choose_mask(Target, Version, Ecc, Size, 0, 0, Target, -1).
-file("src/qrkit/internal/micro.gleam", 520).
?DOC(false).
-spec build_matrix(integer(), qrkit@types:error_correction(), list(integer())) -> {ok,
{integer(), qrkit@internal@matrix:matrix()}} |
{error, qrkit@error:encode_error()}.
build_matrix(Chosen_version, Ecc, Codewords) ->
case symbol_size(Chosen_version) of
{error, Error} ->
{error, Error};
{ok, Size} ->
Base = begin
_pipe = qrkit@internal@matrix:new(Size, Size),
_pipe@1 = draw_finder(_pipe, Size),
_pipe@2 = draw_timing(_pipe@1, Size),
reserve_format_info(_pipe@2, Size)
end,
With_data = place_codewords(Base, Codewords, Chosen_version, Ecc),
{Best_mask, Masked} = choose_best_mask(
With_data,
Chosen_version,
Ecc,
Size
),
{ok,
{Best_mask,
place_format_info(Masked, Chosen_version, Ecc, Best_mask)}}
end.
-file("src/qrkit/internal/micro.gleam", 80).
?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_requested(Requested_version),
fun(_) ->
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_version) ->
result_try(
create_codewords(
Text,
Selected_mode,
Ecc,
Chosen_version
),
fun(Codewords) ->
case build_matrix(
Chosen_version,
Ecc,
Codewords
) of
{ok, {Best_mask, Final_matrix}} ->
{ok,
{encoded,
Chosen_version,
qrkit@internal@matrix:width(
Final_matrix
),
qrkit@internal@matrix:height(
Final_matrix
),
Best_mask,
qrkit@internal@matrix:rows(
Final_matrix
)}};
{error, Error} ->
{error, Error}
end
end
)
end
)
end
)
end
)
end
).