polovy
Error when rendring in :egd (UndefinedFunctionError) function :zlib.crc32/2 is undefined or private
Hi,
I am going through some tutorials, and I’m trying to generate an Identicon, but Im getting an error when trying to run the program. The program is compiling with no issues, but it looks like it errors when executing :egd.render(image) - when I comment it out there is no error. I had a look at the code and I cannot find anything wrong. EGD has been installed from the git repo.
Error:
09:55:06.606 [error] Process #PID<0.141.0> raised an exception
** (UndefinedFunctionError) function :zlib.crc32/2 is undefined or private
:zlib.crc32(#Reference<0.1358207439.4254203912.140130>, <<73, 72, 68, 82, 0, 0, 0, 250, 0, 0, 0, 250, 8, 2, 0, 0, 0>>)
(egd 0.10.0) d:/Dropbox/Projects/Programming/Elixir/maps/deps/egd/src/egd_png.erl:102: :egd_png.create_chunk/2
(egd 0.10.0) d:/Dropbox/Projects/Programming/Elixir/maps/deps/egd/src/egd_png.erl:72: :egd_png.bitmap2png/4
(egd 0.10.0) d:/Dropbox/Projects/Programming/Elixir/maps/deps/egd/src/egd_png.erl:62: :egd_png.binary/3
(egd 0.10.0) d:/Dropbox/Projects/Programming/Elixir/maps/deps/egd/src/egd.erl:240: :egd.loop/1
** (EXIT from #PID<0.140.0>) shell process exited with reason: an exception was raised:
** (UndefinedFunctionError) function :zlib.crc32/2 is undefined or private
:zlib.crc32(#Reference<0.1358207439.4254203912.140130>, <<73, 72, 68, 82, 0, 0, 0, 250, 0, 0, 0, 250, 8, 2, 0, 0, 0>>)
(egd 0.10.0) d:/Dropbox/Projects/Programming/Elixir/maps/deps/egd/src/egd_png.erl:102: :egd_png.create_chunk/2
(egd 0.10.0) d:/Dropbox/Projects/Programming/Elixir/maps/deps/egd/src/egd_png.erl:72: :egd_png.bitmap2png/4
(egd 0.10.0) d:/Dropbox/Projects/Programming/Elixir/maps/deps/egd/src/egd_png.erl:62: :egd_png.binary/3
(egd 0.10.0) d:/Dropbox/Projects/Programming/Elixir/maps/deps/egd/src/egd.erl:240: :egd.loop/1
Program:
defmodule Maps do
def main(input) do
input
|> hashstring
|> pick_color
|> build_grid
|> filter_odd
|> build_pixel_map
|> draw_image
|> save_image(input)
end
def save_image(image, input) do
File.write("#{input}.png", image)
end
def draw_image(%Identicon.Image{color: color, pixel_map: pixel_map}) do
image = :egd.create(250, 250)
fill = :egd.color(color)
Enum.each pixel_map, fn({start, stop}) ->
:egd.filledRectangle(image, start, stop, fill)
end
:egd.render(image)
end
def build_pixel_map(%Identicon.Image{grid: grid} = image) do
pix_map = Enum.map grid, fn({_code, index}) ->
horizontal = rem(index, 5) *50
vertical = div(index, 5) *50
top_left = {horizontal, vertical}
bottom_right = {horizontal+50, vertical+50}
{top_left, bottom_right}
end
%Identicon.Image{image | pixel_map: pix_map}
end
def filter_odd(%Identicon.Image{grid: grid} = image) do
grid = Enum.filter grid, fn({code, _index}) ->
rem(code, 2) == 0
end
%Identicon.Image{image | grid: grid}
end
def build_grid(%Identicon.Image{hex: hex}= image) do
grid =
hex
|> Enum.chunk_every(3, 2, :discard)
|> Enum.map(&mirror_row/1)
|> List.flatten
|> Enum.with_index
%Identicon.Image{image | grid: grid}
end
def mirror_row(row) do
# [123, 34, 22]
[first, second | _tail] = row
# [123, 34, 22, 34, 123]
row ++ [second, first]
end
def pick_color(%Identicon.Image{hex: [red, green, blue | _tail]} = image) do
%Identicon.Image{image | color: {red, green, blue}}
end
def hashstring(string) do
hex = :crypto.hash(:md5, string)
|> :binary.bin_to_list
%Identicon.Image{hex: hex}
end
end
'''
Struct:
defmodule Identicon.Image do
defstruct hex: nil, color: nil, grid: nil, pixel_map: nil
end
Thanks.
The :egd
Most Liked
juhalehtonen
Hi @polovy !
I believe the issue you’re facing is due to the fact that the :egd library uses zlib:crc32/2, but that was removed in Erlang/OTP 27. Can you confirm this is a version you’re using (via elixir --version)?
Your code seems to be working as intended when an older version of Erlang/OTP is used, as those versions still retain zlib:crc32/2.
If you “just” want to run your code to see that it is working, you can downgrade your version of Erlang/OTP to below 27. Otherwise, you’ll need to look into either patching the :egd library to use the built-in :erlang.crc32/1, or to look for other ways to perform this part of the job :egd is doing for you.
thatcherhubbard
I really like the Grider Elixir course on Udemy and there’s a reasonably easy (if not best practices) way around this if you’ve got OTP27 on your machine.
You can change your deps to refer directly to the local copy of EGD, and then change the one line that calls zlib:crc32:
In mix.exs, change {:egd, github: "erlang/egd"} to {:egd, path: "deps/egd"}.
In your project directory (probably identicon), run a mix deps.compile.
Then find deps/egd/src/dgd_png.erl and change Crc = zlib:crc32(Z,Bin), to Crc = erlang:crc32(Bin).
I’ll see about getting a PR opened against EGD when I can figure out how to get the test suite to run properly.
Last Post!
nifalconi
Hello, adding to the answer of @thatcherhubbard
the change is
create_chunk(Bin,_Z) when is_list(Bin) ->
create_chunk(list_to_binary(Bin),_Z);
create_chunk(Bin,_Z) when is_binary(Bin) ->
Sz = size(Bin)-4,
Crc = erlang:crc32(Bin),
<<Sz:32,Bin/binary,Crc:32>>.
As there are previous references to zlib there.
Thanks @thatcherhubbard for making the suggestion. A life savior there.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









