File: README.md

package info (click to toggle)
erlang-p1-eimp 1.0.9-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,512 kB
  • sloc: erlang: 570; ansic: 384; makefile: 70
file content (130 lines) | stat: -rw-r--r-- 4,245 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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.