Skip to content

Commit 51f4fa3

Browse files
committed
Add vips_foreign_find_load_source & vips_foreign_find_save_target
1 parent 973400b commit 51f4fa3

File tree

6 files changed

+118
-2
lines changed

6 files changed

+118
-2
lines changed

c_src/vips_foreign.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,71 @@ ERL_NIF_TERM nif_foreign_find_save(ErlNifEnv *env, int argc,
135135
return ret;
136136
}
137137

138+
139+
ERL_NIF_TERM nif_foreign_find_load_source(ErlNifEnv *env, int argc,
140+
const ERL_NIF_TERM argv[]) {
141+
ASSERT_ARGC(argc, 1);
142+
143+
ErlNifTime start;
144+
ERL_NIF_TERM ret;
145+
VipsSource *source;
146+
const char *name;
147+
148+
start = enif_monotonic_time(ERL_NIF_USEC);
149+
150+
if (!erl_term_to_g_object(env, argv[0], (GObject **)&source)) {
151+
ret = make_error(env, "Failed to get VipsSource");
152+
goto exit;
153+
}
154+
155+
name = vips_foreign_find_load_source(source);
156+
157+
if (!name) {
158+
error("Failed to find the loader for the source. error: %s", vips_error_buffer());
159+
vips_error_clear();
160+
ret = make_error(env, "Failed to find loader for the source");
161+
goto exit;
162+
}
163+
164+
ret = make_ok(env, make_binary(env, name));
165+
166+
exit:
167+
notify_consumed_timeslice(env, start, enif_monotonic_time(ERL_NIF_USEC));
168+
return ret;
169+
}
170+
171+
ERL_NIF_TERM nif_foreign_find_save_target(ErlNifEnv *env, int argc,
172+
const ERL_NIF_TERM argv[]) {
173+
ASSERT_ARGC(argc, 1);
174+
175+
ErlNifTime start;
176+
ERL_NIF_TERM ret;
177+
char suffix[VIPS_PATH_MAX];
178+
const char *name;
179+
180+
start = enif_monotonic_time(ERL_NIF_USEC);
181+
182+
if (!get_binary(env, argv[0], suffix, VIPS_PATH_MAX)) {
183+
ret = make_error(env, "Failed to get suffix");
184+
goto exit;
185+
}
186+
187+
name = vips_foreign_find_save_target(suffix);
188+
189+
if (!name) {
190+
error("Failed to find saver for the target. error: %s", vips_error_buffer());
191+
vips_error_clear();
192+
ret = make_error(env, "Failed to find saver for the target");
193+
goto exit;
194+
}
195+
196+
ret = make_ok(env, make_binary(env, name));
197+
198+
exit:
199+
notify_consumed_timeslice(env, start, enif_monotonic_time(ERL_NIF_USEC));
200+
return ret;
201+
}
202+
138203
ERL_NIF_TERM nif_foreign_get_suffixes(ErlNifEnv *env, int argc,
139204
const ERL_NIF_TERM argv[]) {
140205
ASSERT_ARGC(argc, 0);

c_src/vips_foreign.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ ERL_NIF_TERM nif_foreign_find_load(ErlNifEnv *env, int argc,
1515
ERL_NIF_TERM nif_foreign_find_save(ErlNifEnv *env, int argc,
1616
const ERL_NIF_TERM argv[]);
1717

18+
ERL_NIF_TERM nif_foreign_find_load_source(ErlNifEnv *env, int argc,
19+
const ERL_NIF_TERM argv[]);
20+
21+
ERL_NIF_TERM nif_foreign_find_save_target(ErlNifEnv *env, int argc,
22+
const ERL_NIF_TERM argv[]);
23+
1824
ERL_NIF_TERM nif_foreign_get_suffixes(ErlNifEnv *env, int argc,
1925
const ERL_NIF_TERM argv[]);
2026

c_src/vix.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,12 @@ static ErlNifFunc nif_funcs[] = {
153153
0},
154154

155155
/* VipsForeign */
156-
{"nif_foreign_find_load", 1, nif_foreign_find_load, 0},
156+
{"nif_foreign_find_load", 1, nif_foreign_find_load, ERL_NIF_DIRTY_JOB_IO_BOUND}, // it might read bytes form the file
157157
{"nif_foreign_find_save", 1, nif_foreign_find_save, 0},
158158
{"nif_foreign_find_load_buffer", 1, nif_foreign_find_load_buffer, 0},
159159
{"nif_foreign_find_save_buffer", 1, nif_foreign_find_save_buffer, 0},
160+
{"nif_foreign_find_load_source", 1, nif_foreign_find_load_source, ERL_NIF_DIRTY_JOB_IO_BOUND}, // it might read bytes from source
161+
{"nif_foreign_find_save_target", 1, nif_foreign_find_save_target, 0},
160162
{"nif_foreign_get_suffixes", 0, nif_foreign_get_suffixes, 0},
161163
{"nif_foreign_get_loader_suffixes", 0, nif_foreign_get_loader_suffixes, 0},
162164

lib/vix/nif.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ defmodule Vix.Nif do
186186
def nif_foreign_find_save(_filename),
187187
do: :erlang.nif_error(:nif_library_not_loaded)
188188

189+
def nif_foreign_find_load_source(_source),
190+
do: :erlang.nif_error(:nif_library_not_loaded)
191+
192+
def nif_foreign_find_save_target(_suffix),
193+
do: :erlang.nif_error(:nif_library_not_loaded)
194+
189195
def nif_foreign_get_suffixes,
190196
do: :erlang.nif_error(:nif_library_not_loaded)
191197

lib/vix/vips/foreign.ex

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,46 @@
11
defmodule Vix.Vips.Foreign do
2-
alias Vix.Nif
32
@moduledoc false
43

4+
alias Vix.Nif
5+
6+
@type operation_name :: String.t()
7+
8+
@spec find_load_buffer(binary) :: {:ok, operation_name} | {:error, String.t()}
59
def find_load_buffer(bin) do
610
Nif.nif_foreign_find_load_buffer(bin)
711
end
812

13+
@spec find_save_buffer(String.t()) :: {:ok, operation_name} | {:error, String.t()}
914
def find_save_buffer(suffix) do
1015
Nif.nif_foreign_find_save_buffer(suffix)
1116
end
1217

18+
@doc """
19+
Returns Vips operation name which can load the passed file
20+
"""
21+
@spec find_load(String.t()) :: {:ok, operation_name} | {:error, String.t()}
1322
def find_load(filename) do
1423
Nif.nif_foreign_find_load(filename)
1524
end
1625

26+
@doc """
27+
Returns Vips operation name which can save an image to passed format
28+
"""
29+
@spec find_save(String.t()) :: {:ok, operation_name} | {:error, String.t()}
1730
def find_save(filename) do
1831
Nif.nif_foreign_find_save(filename)
1932
end
2033

34+
@spec find_load_source(Vix.Vips.Source.t()) :: {:ok, operation_name} | {:error, String.t()}
35+
def find_load_source(source) do
36+
Nif.nif_foreign_find_load_source(source)
37+
end
38+
39+
@spec find_save_target(String.t()) :: {:ok, operation_name} | {:error, String.t()}
40+
def find_save_target(suffix) do
41+
Nif.nif_foreign_find_save_target(suffix)
42+
end
43+
2144
def get_suffixes do
2245
with {:ok, suffixes} <- Nif.nif_foreign_get_suffixes() do
2346
{:ok, Enum.uniq(suffixes)}

test/vix/foreign_test.exs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,18 @@ defmodule Vix.Vips.ForeignTest do
2020
test "find_save" do
2121
assert {:ok, "VipsForeignSaveJpegFile"} = Foreign.find_save("puppies.jpg")
2222
end
23+
24+
test "find_load_source" do
25+
bin = File.read!(img_path("puppies.jpg"))
26+
27+
assert {pipe, source} = Vix.SourcePipe.new()
28+
assert :ok = Vix.SourcePipe.write(pipe, bin)
29+
assert :ok = Vix.SourcePipe.stop(pipe)
30+
31+
assert {:ok, "VipsForeignLoadJpegSource"} = Foreign.find_load_source(source)
32+
end
33+
34+
test "find_save_target" do
35+
assert {:ok, "VipsForeignSaveJpegTarget"} = Foreign.find_save_target(".jpg")
36+
end
2337
end

0 commit comments

Comments
 (0)