Erlang Image Manipulation Process ================================= `eimp` is an Erlang/Elixir application for manipulating graphic images using external C libraries. It supports WebP, JPEG, PNG and GIF. # Requirements - GNU Make - GCC - Erlang/OTP 17 and higher - libgd - libwebp - libpng - libjpeg **NOTE**: It's hard to say which versions of the C libraries are required, but it seems like not too old versions should work well. # Install ``` $ ./configure $ make ``` Note that running the configure script is highly recommended, so you should consider adding it in pre-hooks of your rebar configuration. If no C libraries are found at compile time, the package will still be compiled. In this case the only usable function would be [get_type/1](#get_type1). # Application design The C code is compiled into external native binary called `eimp`, which is connected to Erlang VM using an external port. This is done because used C libraries are known not to be extremely stable, thus, if you wrap them into the emulator using a driver or NIF, they can crash the whole emulator. When being loaded, the application starts a single `eimp` process per CPU core and uses a round-robin pool to schedule tasks to them. Simple recovery mechanisms are also supported: - if a request to `eimp` process has failed, next `eimp` process in the pool is picked, until the pool is exhausted - if an `eimp` process is dead, it will be restarted automatically - an `eimp` process is protected against decompression bombs # Usage Before using the application you should start it with either `eimp:start()` or `application:start(eimp)`. # API Current API is simple and supports only a few functions: ### convert/2 ```erl -spec convert(In :: binary(), Format :: png|jpeg|webp|gif) -> {ok, Out :: binary()} | {error, Reason :: error_reason()}. ``` Shorthand for `convert(In, Format, [])`. ### convert/3 ```erl -spec convert(In :: binary(), Format :: png|jpeg|webp|gif, Options :: convert_opts()) -> {ok, Out :: binary()} | {error, Reason :: error_reason()}. ``` The function converts incoming data `In` into format `Format`. Note that you don't have to pass the format of incoming data, becasue it will be detected automatically using `get_type/1` function. In the case of an error you can use `Reason` to produce a human-readable diagnostic text using `format_error/1`. The function also accepts a proplist of `Options`. Currently available options are: - `{scale, {Width, Height}}`: scales image to the new `Width` and `Height`. No scaling is applied by default. **WARNING**: the maximum resolution of an incoming image is hardcoded to be 25Mpx. This is a protection against decompression bombs. ### identify/1 ```erl -spec identify(Img :: binary()) -> {ok, Info :: info()} | {error, error_reason()}. ``` The function returns information about image `Img`, where `Info` is represented as: ```erl [{type, Type :: img_type()}, {width, Width :: non_neg_integer()}, {height, Height :: non_neg_integer()}] ``` It is safe to assume that `Info` always contains all these properties. **NOTE**: If you only need to get a type of an image, you're better off using `get_type/1` function, because it doesn't involve interaction with `eimp` process and is, thus, much faster. ### format_error/1 ```erl -spec format_error(Reason :: error_reason()) -> binary(). ``` Creates diagnostic text from an error generated by `convert/2`. The `Reason` can have the following values: ```erl -type error_reason() :: unsupported_format | timeout | disconnected | encode_failure | decode_failure | transform_failure | image_too_big. ``` ### get_type/1 ```erl -spec get_type(Data :: binary()) -> png | jpeg | webp | gif | unknown. ``` Detects image format of `Data`. ### is_supported/1 ```erl -spec is_supported(Format :: atom()) -> boolean. ``` Returns `true` if `Format` is known and compiled and `false` otherwise. ### supported_formats/0 ```erl -spec supported_formats() -> [png | jpeg | webp | gif]. ``` Returns a list of all known and compiled formats.