-module(sparklinekit@internal@png).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/sparklinekit/internal/png.gleam").
-export([encode/3]).
-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).
-file("src/sparklinekit/internal/png.gleam", 73).
?DOC(false).
-spec prepend_row(list(sparklinekit@internal@color:rgba()), list(integer())) -> list(integer()).
prepend_row(Row, Acc) ->
case Row of
[] ->
Acc;
[{rgba, R, G, B, A} | Rest] ->
prepend_row(Rest, [A, B, G, R | Acc])
end.
-file("src/sparklinekit/internal/png.gleam", 66).
?DOC(false).
-spec do_build_scanlines(
list(list(sparklinekit@internal@color:rgba())),
list(integer())
) -> list(integer()).
do_build_scanlines(Rows, Acc) ->
case Rows of
[] ->
lists:reverse(Acc);
[Row | Rest] ->
do_build_scanlines(Rest, prepend_row(Row, [0 | Acc]))
end.
-file("src/sparklinekit/internal/png.gleam", 62).
?DOC(false).
-spec build_scanlines(list(list(sparklinekit@internal@color:rgba()))) -> list(integer()).
build_scanlines(Rows) ->
do_build_scanlines(Rows, []).
-file("src/sparklinekit/internal/png.gleam", 120).
?DOC(false).
-spec take_bytes(list(integer()), integer(), list(integer())) -> {list(integer()),
list(integer())}.
take_bytes(Values, Count, Acc) ->
case {Values, Count} of
{Rest, 0} ->
{lists:reverse(Acc), Rest};
{[Value | Rest@1], _} ->
take_bytes(Rest@1, Count - 1, [Value | Acc]);
{[], _} ->
{lists:reverse(Acc), []}
end.
-file("src/sparklinekit/internal/png.gleam", 188).
?DOC(false).
-spec byte_list_to_bit_array(list(integer())) -> bitstring().
byte_list_to_bit_array(Bytes) ->
_pipe = Bytes,
_pipe@1 = gleam@list:map(_pipe, fun(Byte) -> <<Byte>> end),
gleam_stdlib:bit_array_concat(_pipe@1).
-file("src/sparklinekit/internal/png.gleam", 194).
?DOC(false).
-spec prepend_reversed(list(DRO), list(DRO)) -> list(DRO).
prepend_reversed(Values, Acc) ->
case Values of
[] ->
Acc;
[Value | Rest] ->
prepend_reversed(Rest, [Value | Acc])
end.
-file("src/sparklinekit/internal/png.gleam", 201).
?DOC(false).
-spec u32_bytes(integer()) -> list(integer()).
u32_bytes(Value) ->
[erlang:'band'(erlang:'bsr'(Value, 24), 16#FF),
erlang:'band'(erlang:'bsr'(Value, 16), 16#FF),
erlang:'band'(erlang:'bsr'(Value, 8), 16#FF),
erlang:'band'(Value, 16#FF)].
-file("src/sparklinekit/internal/png.gleam", 210).
?DOC(false).
-spec low_byte(integer()) -> integer().
low_byte(Value) ->
erlang:'band'(Value, 16#FF).
-file("src/sparklinekit/internal/png.gleam", 214).
?DOC(false).
-spec high_byte(integer()) -> integer().
high_byte(Value) ->
erlang:'band'(erlang:'bsr'(Value, 8), 16#FF).
-file("src/sparklinekit/internal/png.gleam", 90).
?DOC(false).
-spec do_deflate_store_blocks(list(integer()), list(integer())) -> list(integer()).
do_deflate_store_blocks(Data, Acc) ->
case Data of
[] ->
case Acc of
[] ->
[1, 0, 0, 255, 255];
_ ->
lists:reverse(Acc)
end;
_ ->
{Chunk_bytes, Rest} = take_bytes(Data, 65535, []),
Final_flag = case Rest of
[] ->
1;
_ ->
0
end,
Length = erlang:length(Chunk_bytes),
Complement = 65535 - Length,
Header = [Final_flag,
low_byte(Length),
high_byte(Length),
low_byte(Complement),
high_byte(Complement)],
do_deflate_store_blocks(
Rest,
prepend_reversed(lists:append(Header, Chunk_bytes), Acc)
)
end.
-file("src/sparklinekit/internal/png.gleam", 86).
?DOC(false).
-spec deflate_store_blocks(list(integer())) -> list(integer()).
deflate_store_blocks(Data) ->
do_deflate_store_blocks(Data, []).
-file("src/sparklinekit/internal/png.gleam", 156).
?DOC(false).
-spec crc32_byte(integer(), integer()) -> integer().
crc32_byte(Crc, Remaining) ->
case Remaining =< 0 of
true ->
Crc;
false ->
Next = case erlang:'band'(Crc, 1) =:= 1 of
true ->
erlang:'bxor'(erlang:'bsr'(Crc, 1), 16#EDB88320);
false ->
erlang:'bsr'(Crc, 1)
end,
crc32_byte(Next, Remaining - 1)
end.
-file("src/sparklinekit/internal/png.gleam", 148).
?DOC(false).
-spec do_crc32(list(integer()), integer()) -> integer().
do_crc32(Bytes, Crc) ->
case Bytes of
[] ->
Crc;
[Byte | Rest] ->
do_crc32(Rest, crc32_byte(erlang:'bxor'(Crc, Byte), 8))
end.
-file("src/sparklinekit/internal/png.gleam", 143).
?DOC(false).
-spec crc32(list(integer())) -> integer().
crc32(Bytes) ->
_pipe = do_crc32(Bytes, 16#FFFFFFFF),
erlang:'bxor'(_pipe, 16#FFFFFFFF).
-file("src/sparklinekit/internal/png.gleam", 132).
?DOC(false).
-spec chunk(list(integer()), list(integer())) -> list(integer()).
chunk(Type_bytes, Data_bytes) ->
Crc = crc32(lists:append(Type_bytes, Data_bytes)),
lists:append(
u32_bytes(erlang:length(Data_bytes)),
lists:append(Type_bytes, lists:append(Data_bytes, u32_bytes(Crc)))
).
-file("src/sparklinekit/internal/png.gleam", 177).
?DOC(false).
-spec do_adler32(list(integer()), integer(), integer()) -> integer().
do_adler32(Bytes, S1, S2) ->
case Bytes of
[] ->
(S2 * 65536) + S1;
[Byte | Rest] ->
Next_s1 = case 65521 of
0 -> 0;
Gleam@denominator -> (S1 + Byte) rem Gleam@denominator
end,
Next_s2 = case 65521 of
0 -> 0;
Gleam@denominator@1 -> (S2 + Next_s1) rem Gleam@denominator@1
end,
do_adler32(Rest, Next_s1, Next_s2)
end.
-file("src/sparklinekit/internal/png.gleam", 173).
?DOC(false).
-spec adler32(list(integer())) -> integer().
adler32(Bytes) ->
do_adler32(Bytes, 1, 0).
-file("src/sparklinekit/internal/png.gleam", 80).
?DOC(false).
-spec zlib_store(list(integer())) -> list(integer()).
zlib_store(Data) ->
Checksum = adler32(Data),
_pipe = lists:append([120, 1], deflate_store_blocks(Data)),
lists:append(_pipe, u32_bytes(Checksum)).
-file("src/sparklinekit/internal/png.gleam", 28).
?DOC(false).
-spec encode(
list(list(sparklinekit@internal@color:rgba())),
integer(),
integer()
) -> bitstring().
encode(Pixels, Width, Height) ->
Actual_width = case Width < 1 of
true ->
1;
false ->
Width
end,
Actual_height = case Height < 1 of
true ->
1;
false ->
Height
end,
Scanlines = build_scanlines(Pixels),
Ihdr = lists:append(
u32_bytes(Actual_width),
lists:append(u32_bytes(Actual_height), [8, 6, 0, 0, 0])
),
Idat = zlib_store(Scanlines),
_pipe = lists:append(
[137, 80, 78, 71, 13, 10, 26, 10],
lists:append(
chunk([73, 72, 68, 82], Ihdr),
lists:append(
chunk([73, 68, 65, 84], Idat),
chunk([73, 69, 78, 68], [])
)
)
),
byte_list_to_bit_array(_pipe).