diff --git a/.gitignore b/.gitignore index 78ed462..a1b98e3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,7 @@ log logs _build -doc/specs/ -doc/src/egd.xml -doc/src/egd_ug.xml -doc/src/ref_man.xml +/doc/ .rebar3 _* diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2a9090e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Change log + +## Version 0.10.1 (February 09, 2025) + +- Align to OTP 24: use `erlang:crc32/1` instead of `zlib:crc32/2`, as the later + one has been deprecated in OTP 24 and was removed in OTP 27. +- Convert documentation from `erl_docgen` style XML files to `ex_doc` style + Markdown files. + +## Previous versions + +- 0.10.0: Add `egd_font:load_binary/1` +- 0.9.1: Reinstate `priv_dir` with fonts +- 0.9.0: Initial commit or [erlang/egd](https://github.com/erlang/egd) diff --git a/README.md b/README.md index 8bd5328..b9edf6e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,128 @@ -Erlang Graphical Drawer -===== +# Erlang Graphical Drawer -Erlang Graphical Drawer is an interface for 2d-image rendering and is used by Percept to generate dynamic graphs to its web -pages. All code is pure erlang, no drivers needed. +Erlang Graphical Drawer ([egd](https://github.com/erlang/egd)) is an interface +for 2d-image rendering and is used by +[Percept](https://github.com/erlang/percept) to generate dynamic graphs to +its web pages. All code is pure Erlang, no drivers needed. -Build ------ +The library is intended for small to medium image sizes with low complexity for +optimal performance. The library handles horizontal lines better then vertical +lines. - $ rebar3 compile +The foremost purpose for this module is to enable users to generate images from +Erlang code and/or datasets and to send these images to either files or web +servers. + +## File example + +Drawing examples: + +```erlang +-module(img). + +-export([do/0]). + +do() -> + Im = egd:create(200,200), + Red = egd:color({255,0,0}), + Green = egd:color({0,255,0}), + Blue = egd:color({0,0,255}), + Black = egd:color({0,0,0}), + Yellow = egd:color({255,255,0}), + + % Line and fillRectangle + + egd:filledRectangle(Im, {20,20}, {180,180}, Red), + egd:line(Im, {0,0}, {200,200}, Black), + + egd:save(egd:render(Im, png), "test1.png"), + + egd:filledEllipse(Im, {45, 60}, {55, 70}, Yellow), + egd:filledEllipse(Im, {145, 60}, {155, 70}, Blue), + + egd:save(egd:render(Im, png), "test2.png"), + + R = 80, + X0 = 99, + Y0 = 99, + + Pts = [ {X0 + trunc(R*math:cos(A*math:pi()*2/360)), + Y0 + trunc(R*math:sin(A*math:pi()*2/360)) + } || A <- lists:seq(0,359,5)], + lists:map( + fun({X,Y}) -> + egd:rectangle(Im, {X-5, Y-5}, {X+5,Y+5}, Green) + end, Pts), + + egd:save(egd:render(Im, png), "test3.png"), + + % Text + Filename = filename:join([code:priv_dir(egd), "fonts", "6x11_latin1.wingsfont"]), + Font = egd_font:load(Filename), + {W,H} = egd_font:size(Font), + String = "egd says hello", + Length = length(String), + + egd:text(Im, {round(100 - W*Length/2), 200 - H - 5}, Font, String, Black), + + egd:save(egd:render(Im, png), "test4.png"), + + egd:destroy(Im). +``` + +First save: + +![test1.png](assets/test1.gif) + +Second save: + +![test2.png](assets/test2.gif) + +Third save: + +![test3.png](assets/test3.gif) + +Fourth save: + +![test4.png](assets/test4.gif) + +## ESI example + +Using `egd` with [inets](https://www.erlang.org/doc/apps/inets/) ESI to generate +images on the fly: + +```erlang +-module(img_esi). + +-export([image/3]). + +image(SessionID, _Env, _Input) -> + mod_esi:deliver(SessionID, header()), + Binary = my_image(), + mod_esi:deliver(SessionID, binary_to_list(Binary)). + +my_image() -> + Im = egd:create(300,20), + Black = egd:color({0,0,0}), + Red = egd:color({255,0,0}), + egd:filledRectangle(Im, {30,14}, {270,19}, Red), + egd:rectangle(Im, {30,14}, {270,19}, Black), + + Filename = filename:join([code:priv_dir(egd), "fonts", "6x11_latin1.wingsfont"]), + Font = egd_font:load(Filename), + egd:text(Im, {30, 0}, Font, "egd with esi callback", Black), + Bin = egd:render(Im, png), + egd:destroy(Im), + Bin. + +header() -> + "Content-Type: image/png\r\n\r\n". +``` + +Result: + +![Example of result](assets/img_esi_result.gif) + +For more information regarding ESI, please see +[inets](https://www.erlang.org/doc/apps/inets/) application +[mod_esi](https://www.erlang.org/doc/apps/inets/mod_esi.html#). diff --git a/doc/src/img_esi_result.gif b/assets/img_esi_result.gif similarity index 100% rename from doc/src/img_esi_result.gif rename to assets/img_esi_result.gif diff --git a/doc/src/test1.gif b/assets/test1.gif similarity index 100% rename from doc/src/test1.gif rename to assets/test1.gif diff --git a/doc/src/test2.gif b/assets/test2.gif similarity index 100% rename from doc/src/test2.gif rename to assets/test2.gif diff --git a/doc/src/test3.gif b/assets/test3.gif similarity index 100% rename from doc/src/test3.gif rename to assets/test3.gif diff --git a/doc/src/test4.gif b/assets/test4.gif similarity index 100% rename from doc/src/test4.gif rename to assets/test4.gif diff --git a/doc/src/book.xml b/doc/src/book.xml deleted file mode 100644 index 106d8a2..0000000 --- a/doc/src/book.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - -
- - 2007 - 2016 - Ericsson AB, All Rights Reserved - - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - The Initial Developer of the Original Code is Ericsson AB. - - - Percept - Björn-Egil Dahlberg - - 2007-11-02 - 0.5.0 - book.xml -
- - - Erlang Graphics Draw - - - - - - - - - - - - - - -
- diff --git a/doc/src/egd_ug.xmlsrc b/doc/src/egd_ug.xmlsrc deleted file mode 100644 index 85d41ad..0000000 --- a/doc/src/egd_ug.xmlsrc +++ /dev/null @@ -1,90 +0,0 @@ - - - - -
- - 2007 - 2016 - Ericsson AB, All Rights Reserved - - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - The Initial Developer of the Original Code is Ericsson AB. - - - egd - Björn-Egil Dahlberg - - 2007-11-03 - A - egd_ug.xml -
-
- Introduction -

- The egd module is an interface for 2d-image rendering and is used by - Percept to generate dynamic graphs to its web pages. All code is pure - erlang, no drivers needed. -

-

- The library is intended for small to medium image sizes with low - complexity for optimal performance. The library handles horizontal - lines better then vertical lines. -

-

- The foremost purpose for this module is to enable users to - generate images from erlang code and/or datasets and to - send these images to either files or web servers. -

-
-
- File example -

Drawing examples:

- -

First save.

- - test1.png - - -

Second save.

- - test2.png - - -

Third save.

- - test3.png - - -

Fourth save.

- - test4.png - -
-
- ESI example -

Using egd with inets ESI to generate images on the fly:

- - - Example of result. - -

- For more information regarding ESI, please see inets application - mod_esi. -

-
-
- - diff --git a/doc/src/img.erl b/doc/src/img.erl deleted file mode 100644 index d8aac7a..0000000 --- a/doc/src/img.erl +++ /dev/null @@ -1,50 +0,0 @@ --module(img). - --export([do/0]). - -do() -> - Im = egd:create(200,200), - Red = egd:color({255,0,0}), - Green = egd:color({0,255,0}), - Blue = egd:color({0,0,255}), - Black = egd:color({0,0,0}), - Yellow = egd:color({255,255,0}), - - % Line and fillRectangle - - egd:filledRectangle(Im, {20,20}, {180,180}, Red), - egd:line(Im, {0,0}, {200,200}, Black), - - egd:save(egd:render(Im, png), "/home/egil/test1.png"), - - egd:filledEllipse(Im, {45, 60}, {55, 70}, Yellow), - egd:filledEllipse(Im, {145, 60}, {155, 70}, Blue), - - egd:save(egd:render(Im, png), "/home/egil/test2.png"), - - R = 80, - X0 = 99, - Y0 = 99, - - Pts = [ { X0 + trunc(R*math:cos(A*math:pi()*2/360)), - Y0 + trunc(R*math:sin(A*math:pi()*2/360)) - } || A <- lists:seq(0,359,5)], - lists:map( - fun({X,Y}) -> - egd:rectangle(Im, {X-5, Y-5}, {X+5,Y+5}, Green) - end, Pts), - - egd:save(egd:render(Im, png), "/home/egil/test3.png"), - - % Text - Filename = filename:join([code:priv_dir(egd), "fonts", "6x11_latin1.wingsfont"]), - Font = egd_font:load(Filename), - {W,H} = egd_font:size(Font), - String = "egd says hello", - Length = length(String), - - egd:text(Im, {round(100 - W*Length/2), 200 - H - 5}, Font, String, Black), - - egd:save(egd:render(Im, png), "/home/egil/test4.png"), - - egd:destroy(Im). diff --git a/doc/src/img_esi.erl b/doc/src/img_esi.erl deleted file mode 100644 index e979681..0000000 --- a/doc/src/img_esi.erl +++ /dev/null @@ -1,25 +0,0 @@ --module(img_esi). - --export([image/3]). - -image(SessionID, _Env, _Input) -> - mod_esi:deliver(SessionID, header()), - Binary = my_image(), - mod_esi:deliver(SessionID, binary_to_list(Binary)). - -my_image() -> - Im = egd:create(300,20), - Black = egd:color({0,0,0}), - Red = egd:color({255,0,0}), - egd:filledRectangle(Im, {30,14}, {270,19}, Red), - egd:rectangle(Im, {30,14}, {270,19}, Black), - - Filename = filename:join([code:priv_dir(percept), "fonts", "6x11_latin1.wingsfont"]), - Font = egd_font:load(Filename), - egd:text(Im, {30, 0}, Font, "egd with esi callback", Black), - Bin = egd:render(Im, png), - egd:destroy(Im), - Bin. - -header() -> - "Content-Type: image/png\r\n\r\n". diff --git a/doc/src/notes.xml b/doc/src/notes.xml deleted file mode 100644 index 306a524..0000000 --- a/doc/src/notes.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - -
- - 2007 - 2016 - Ericsson AB, All Rights Reserved - - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - The Initial Developer of the Original Code is Ericsson AB. - - - Erlang Graphics Draw Release Notes - otp_appnotes - nil - nil - nil - notes.xml -
-

This document describes the changes made to the Erlang Graphics Draw application.

- -
diff --git a/doc/src/part.xml b/doc/src/part.xml deleted file mode 100644 index 072ef32..0000000 --- a/doc/src/part.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - -
- - 2007 - 2016 - Ericsson AB, All Rights Reserved - - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - The Initial Developer of the Original Code is Ericsson AB. - - - Percept User's Guide - Björn-Egil Dahlberg - - 2007-11-02 - 0.5.0 - part.xml -
- -

- Percept is an acronym for Percept - erlang - concurrency profiling tool. -

-

- It is a tool to visualize application level concurrency and - identify concurrency bottlenecks. -

-
- -
diff --git a/doc/src/ref_man.xml b/doc/src/ref_man.xml deleted file mode 100644 index 09b2e1d..0000000 --- a/doc/src/ref_man.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - -
- - 2007 - 2016 - Ericsson AB, All Rights Reserved - - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - The Initial Developer of the Original Code is Ericsson AB. - - - Percept Reference Manual - Edoc - - 2007-11-02 - 1.0 - ref_man.xml -
- -

- Percept is an acronym for Percept - erlang - concurrency profiling tool. -

-

- It is a tool to visualize application level concurrency and - identify concurrency bottlenecks. -

-
- -
diff --git a/rebar.config b/rebar.config index aaff67a..cf44189 100644 --- a/rebar.config +++ b/rebar.config @@ -7,4 +7,17 @@ {otpdoc_opts, [{edoc_modules, [egd]}]}. +{project_plugins, [rebar3_ex_doc]}. +{hex, [{doc, ex_doc}]}. +{ex_doc, [ + {extras, [ + {"CHANGELOG.md", #{title => "Changelog"}}, + {"README.md", #{title => "Overview"}}, + {"LICENSE", #{title => "License"}} + ]}, + {main, "README.md"}, + {source_url, "https://github.com/KornelH/egd"}, + {assets, #{"assets" => "assets"}} +]}. + %% vim: ft=erlang diff --git a/src/egd.app.src b/src/egd.app.src index d7a0328..47e26b0 100644 --- a/src/egd.app.src +++ b/src/egd.app.src @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2016. All Rights Reserved. +%% Copyright Ericsson AB 2007-2025. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,8 +19,8 @@ %% {application, egd, - [{description, "Erlang Graphics Draw"}, - {vsn, git}, + [{description, "Erlang Graphical Drawer"}, + {vsn, "0.10.1"}, {registered, []}, {applications, [kernel, stdlib]}, @@ -30,9 +30,12 @@ egd_png, egd_primitives, egd_render]}, - {maintainers, []}, - {licenses, []}, - {links, []} + %% hex.pm properties + {pkg_name, egd24}, % reserve name 'egd' for the original author, however + % ownership can be transferred later too: + % https://hexdocs.pm/rebar3_hex/rebar3_hex_owner.html + {licenses, ["Apache-2.0"]}, + {links, [{"GitHub","https://github.com/KornelH/egd"}]} ]}. %% vim: ft=erlang diff --git a/src/egd.erl b/src/egd.erl index fe52da7..a00667b 100644 --- a/src/egd.erl +++ b/src/egd.erl @@ -40,22 +40,57 @@ %% Type definitions %%========================================================================== -%% @type egd_image() -%% @type font() -%% @type point() = {integer(), integer()} -%% @type color() -%% @type render_option() = {render_engine, opaque} | {render_engine, alpha} - -type egd_image() :: pid(). --type point() :: {non_neg_integer(), non_neg_integer()}. +-type image_type() :: png | raw_bitmap | eps. +-type font() :: term(). +%% Internal font representation returned by {@link egd_font:load/1} or +%% {@link egd_font:load_binary/1} + +-type point() :: {X::non_neg_integer(), Y::non_neg_integer()}. -type render_option() :: {'render_engine', 'opaque'} | {'render_engine', 'alpha'}. --type color() :: {float(), float(), float(), float()}. + +-type color3() :: {Red::byte(), Green::byte(), Blue::byte()}. +-type color4() :: {Red::byte(), Green::byte(), Blue::byte(), Alpha::byte()}. +-type colorNameSimple() :: aqua | black | blue | fuchia | gray | green | lime | + maroon | navy | olive | purple | red | silver | teal | + white | yellow. +%% HTML default colors + +-type colorNameExtended() :: + aliceblue | antiquewhite | aquamarine | azure | beige | bisque | + blanchedalmond | blueviolet | brown | burlywood | cadetblue | + chartreuse | chocolate | coral | cornflowerblue | cornsilk | crimson | + cyan | darkblue | darkcyan | darkgoldenrod | darkgray | darkgreen | + darkkhaki | darkmagenta | darkolivegreen | darkorange | darkorchid | + darkred | darksalmon | darkseagreen | darkslateblue | darkslategray | + darkturquoise | darkviolet | deeppink | deepskyblue | dimgray | + dodgerblue | firebrick | floralwhite | forestgreen | fuchsia | + gainsboro | ghostwhite | gold | goldenrod | greenyellow | honeydew | + hotpink | indianred | indigo | ivory | khaki | lavender | + lavenderblush | lawngreen | lemonchiffon | lightblue | lightcoral | + lightcyan | lightgoldenrodyellow | lightgreen | lightgrey | lightpink | + lightsalmon | lightseagreen | lightskyblue | lightslategray | + lightsteelblue | lightyellow | limegreen | linen | magenta | + mediumaquamarine | mediumblue | mediumorchid | mediumpurple | + mediumseagreen | mediumslateblue | mediumspringgreen | mediumturquoise | + mediumvioletred | midnightblue | mintcream | mistyrose | moccasin | + navajowhite | oldlace | olivedrab | orange | orangered | orchid | + palegoldenrod | palegreen | paleturquoise | palevioletred | papayawhip | + peachpuff | peru | pink | plum | powderblue | rosybrown | royalblue | + saddlebrown | salmon | sandybrown | seagreen | seashell | sienna | + skyblue | slateblue | slategray | snow | springgreen | steelblue | tan | + thistle | tomato | turquoise | violet | wheat | whitesmoke | + yellowgreen. +%% HTML color extensions + +-type colorName() :: colorNameSimple() | colorNameExtended(). +-type color() :: color3() | color4() | colorName() | + {colorName(), Alpha::byte()}. %%========================================================================== %% Interface functions %%========================================================================== -%% @spec create(integer(), integer()) -> egd_image() %% @doc Creates an image area and returns its reference. -spec create(Width :: integer(), Height :: integer()) -> egd_image(). @@ -64,7 +99,6 @@ create(Width,Height) -> spawn_link(fun() -> init(trunc(Width),trunc(Height)) end). -%% @spec destroy(egd_image()) -> ok %% @doc Destroys the image. -spec destroy(Image :: egd_image()) -> ok. @@ -73,7 +107,6 @@ destroy(Image) -> cast(Image, destroy). -%% @spec render(egd_image()) -> binary() %% @equiv render(Image, png, [{render_engine, opaque}]) -spec render(Image :: egd_image()) -> binary(). @@ -81,121 +114,148 @@ destroy(Image) -> render(Image) -> render(Image, png, [{render_engine, opaque}]). -%% @spec render(egd_image(), png | raw_bitmap) -> binary() %% @equiv render(Image, Type, [{render_engine, opaque}]) +-spec render(Image :: egd_image(), Type :: image_type()) -> binary(). + render(Image, Type) -> render(Image, Type, [{render_engine, opaque}]). -%% @spec render(egd_image(), png | raw_bitmap, [render_option()]) -> binary() %% @doc Renders a binary from the primitives specified by egd_image(). The -%% binary can either be a raw bitmap with rgb tripplets or a binary in png +%% binary can either be a raw bitmap with rgb triplets or a binary in png %% format. --spec render( - Image :: egd_image(), - Type :: 'png' | 'raw_bitmap' | 'eps', - Options :: [render_option()]) -> binary(). +-spec render(Image :: egd_image(), + Type :: image_type(), + Options :: [render_option()]) -> binary(). render(Image, Type, Options) -> {render_engine, RenderType} = proplists:lookup(render_engine, Options), call(Image, {render, Type, RenderType}). -%% @spec information(egd_image()) -> ok %% @hidden %% @doc Writes out information about the image. This is a debug feature %% mainly. +-spec information(Image :: egd_image()) -> ok. + information(Pid) -> cast(Pid, information). -%% @spec line(egd_image(), point(), point(), color()) -> ok %% @doc Creates a line object from P1 to P2 in the image. --spec line( - Image :: egd_image(), - P1 :: point(), - P2 :: point(), - Color :: color()) -> 'ok'. +-spec line(Image :: egd_image(), + Point1 :: point(), + Point2 :: point(), + Color :: color()) -> ok. line(Image, P1, P2, Color) -> cast(Image, {line, P1, P2, Color}). -%% @spec color( Value | Name ) -> color() -%% where -%% Value = {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} -%% Name = black | silver | gray | white | maroon | red | purple | fuchia | green | lime | olive | yellow | navy | blue | teal | aqua %% @doc Creates a color reference. --spec color(Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) -> - color(). +-spec color(Color :: color()) -> color4(). color(Color) -> egd_primitives:color(Color). -%% @spec color(egd_image(), {byte(), byte(), byte()}) -> color() %% @doc Creates a color reference. %% @hidden +-spec color(_Image :: egd_image(), Color :: color()) -> color4(). + color(_Image, Color) -> egd_primitives:color(Color). -%% @spec text(egd_image(), point(), font(), string(), color()) -> ok %% @doc Creates a text object. +-spec text(Image :: egd_image(), + Point :: point(), + Font :: font(), + Text :: string(), + Color :: color()) -> ok. + text(Image, P, Font, Text, Color) -> cast(Image, {text, P, Font, Text, Color}). -%% @spec rectangle(egd_image(), point(), point(), color()) -> ok %% @doc Creates a rectangle object. +-spec rectangle(Image :: egd_image(), + Point1 :: point(), + Point2 :: point(), + Color :: color()) -> ok. + rectangle(Image, P1, P2, Color) -> cast(Image, {rectangle, P1, P2, Color}). -%% @spec filledRectangle(egd_image(), point(), point(), color()) -> ok %% @doc Creates a filled rectangle object. +-spec filledRectangle(Image :: egd_image(), + Point1 :: point(), + Point2 :: point(), + Color :: color()) -> ok. + filledRectangle(Image, P1, P2, Color) -> cast(Image, {filled_rectangle, P1, P2, Color}). -%% @spec filledEllipse(egd_image(), point(), point(), color()) -> ok %% @doc Creates a filled ellipse object. +-spec filledEllipse(Image :: egd_image(), + Point1 :: point(), + Point2 :: point(), + Color :: color()) -> ok. + filledEllipse(Image, P1, P2, Color) -> cast(Image, {filled_ellipse, P1, P2, Color}). -%% @spec filledTriangle(egd_image(), point(), point(), point(), color()) -> ok %% @hidden %% @doc Creates a filled triangle object. +-spec filledTriangle(Image :: egd_image(), + Point1 :: point(), + Point2 :: point(), + Point3 :: point(), + Color :: color()) -> ok. + filledTriangle(Image, P1, P2, P3, Color) -> cast(Image, {filled_triangle, P1, P2, P3, Color}). -%% @spec polygon(egd_image(), [point()], color()) -> ok %% @hidden %% @doc Creates a filled filled polygon object. +-spec polygon(Image :: egd_image(), Points :: [point()], Color :: color()) -> ok. + polygon(Image, Pts, Color) -> cast(Image, {polygon, Pts, Color}). -%% @spec arc(egd_image(), point(), point(), color()) -> ok %% @hidden %% @doc Creates an arc with radius of bbx corner. +-spec arc(Image :: egd_image(), + Point1 :: point(), + Point2 :: point(), + Color :: color()) -> ok. + arc(Image, P1, P2, Color) -> cast(Image, {arc, P1, P2, Color}). -%% @spec arc(egd_image(), point(), point(), integer(), color()) -> ok %% @hidden %% @doc Creates an arc. +-spec arc(Image :: egd_image(), + Point1 :: point(), + Point2 :: point(), + Radius :: integer(), + Color :: color()) -> ok. + arc(Image, P1, P2, D, Color) -> cast(Image, {arc, P1, P2, D, Color}). -%% @spec save(binary(), string()) -> ok %% @doc Saves the binary to file. +-spec save(RenderedImage :: binary(), Filename :: string()) -> ok. + save(Binary, Filename) when is_binary(Binary) -> ok = file:write_file(Filename, Binary), ok. diff --git a/src/egd_png.erl b/src/egd_png.erl index fe66051..4d55cf4 100644 --- a/src/egd_png.erl +++ b/src/egd_png.erl @@ -58,20 +58,17 @@ -define(get1p8(Idx),((Idx) band 1)). binary(W, H, Bitmap) when is_binary(Bitmap) -> - Z = zlib:open(), - Binary = bitmap2png(W, H, Bitmap, Z), - zlib:close(Z), - Binary. + bitmap2png(W, H, Bitmap). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Begin Tainted -bitmap2png(W, H, Bitmap,Z) -> - HDR = create_chunk(<<"IHDR",W:32,H:32,8:8,(png_type(r8g8b8)):8,0:8,0:8,0:8>>,Z), - DATA = create_chunk(["IDAT",compress_image(0,3*W,Bitmap,[])],Z), - END = create_chunk(<<"IEND">>,Z), +bitmap2png(W, H, Bitmap) -> + HDR = create_chunk(<<"IHDR",W:32,H:32,8:8,(png_type(r8g8b8)):8,0:8,0:8,0:8>>), + DATA = create_chunk(["IDAT",compress_image(0,3*W,Bitmap,[])]), + END = create_chunk(<<"IEND">>), list_to_binary([?MAGIC,HDR,DATA,END]). compress_image(I,RowLen, Bin, Acc) -> @@ -95,11 +92,11 @@ filter_row(Row,_RowLen) -> %png_type(r8g8b8a8) -> ?TRUECOLOUR_A; png_type(r8g8b8) -> ?TRUECOLOUR. -create_chunk(Bin,Z) when is_list(Bin) -> - create_chunk(list_to_binary(Bin),Z); -create_chunk(Bin,Z) when is_binary(Bin) -> +create_chunk(Bin) when is_list(Bin) -> + create_chunk(list_to_binary(Bin)); +create_chunk(Bin) when is_binary(Bin) -> Sz = size(Bin)-4, - Crc = zlib:crc32(Z,Bin), + Crc = erlang:crc32(Bin), <>. % End tainted