24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-06-04 21:27:16 +02:00

Feed whole image to eimp:identify/1

Fixes #2859
This commit is contained in:
Evgeny Khramtsov 2019-04-14 17:05:16 +03:00
parent 6dac0a602e
commit 009b9a1fd0

View File

@ -111,7 +111,8 @@
external_secret :: binary()}). external_secret :: binary()}).
-record(media_info, -record(media_info,
{type :: atom(), {path :: binary(),
type :: atom(),
height :: integer(), height :: integer(),
width :: integer()}). width :: integer()}).
@ -780,10 +781,10 @@ parse_http_request(#request{host = Host, path = Path}) ->
store_file(Path, Request, FileMode, DirMode, GetPrefix, Slot, Thumbnail) -> store_file(Path, Request, FileMode, DirMode, GetPrefix, Slot, Thumbnail) ->
case do_store_file(Path, Request, FileMode, DirMode) of case do_store_file(Path, Request, FileMode, DirMode) of
ok when Thumbnail -> ok when Thumbnail ->
case identify(Path) of case read_image(Path) of
{ok, MediaInfo} -> {ok, Data, MediaInfo} ->
case convert(Path, MediaInfo) of case convert(Data, MediaInfo) of
{ok, OutPath, OutMediaInfo} -> {ok, #media_info{path = OutPath} = OutMediaInfo} ->
[UserDir, RandDir | _] = Slot, [UserDir, RandDir | _] = Slot,
FileName = filename:basename(OutPath), FileName = filename:basename(OutPath),
URL = str:join([GetPrefix, UserDir, URL = str:join([GetPrefix, UserDir,
@ -888,30 +889,31 @@ format_error(Reason) ->
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Image manipulation stuff. %% Image manipulation stuff.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
-spec identify(binary()) -> {ok, media_info()} | pass. -spec read_image(binary()) -> {ok, binary(), media_info()} | pass.
identify(Path) -> read_image(Path) ->
try case file:read_file(Path) of
{ok, Fd} = file:open(Path, [read, raw]), {ok, Data} ->
{ok, Data} = file:read(Fd, 1024), case eimp:identify(Data) of
case eimp:identify(Data) of {ok, Info} ->
{ok, Info} -> {ok, Data,
{ok, #media_info{ #media_info{
path = Path,
type = proplists:get_value(type, Info), type = proplists:get_value(type, Info),
width = proplists:get_value(width, Info), width = proplists:get_value(width, Info),
height = proplists:get_value(height, Info)}}; height = proplists:get_value(height, Info)}};
{error, Why} -> {error, Why} ->
?DEBUG("Cannot identify type of ~s: ~s", ?DEBUG("Cannot identify type of ~s: ~s",
[Path, eimp:format_error(Why)]), [Path, eimp:format_error(Why)]),
pass pass
end end;
catch _:{badmatch, {error, Reason}} -> {error, Reason} ->
?DEBUG("Failed to read file ~s: ~s", ?DEBUG("Failed to read file ~s: ~s",
[Path, format_error(Reason)]), [Path, format_error(Reason)]),
pass pass
end. end.
-spec convert(binary(), media_info()) -> {ok, binary(), media_info()} | pass. -spec convert(binary(), media_info()) -> {ok, binary(), media_info()} | pass.
convert(Path, #media_info{type = T, width = W, height = H} = Info) -> convert(InData, #media_info{path = Path, type = T, width = W, height = H} = Info) ->
if W * H >= 25000000 -> if W * H >= 25000000 ->
?DEBUG("The image ~s is more than 25 Mpix", [Path]), ?DEBUG("The image ~s is more than 25 Mpix", [Path]),
pass; pass;
@ -926,27 +928,20 @@ convert(Path, #media_info{type = T, width = W, height = H} = Info) ->
H > W -> {round(W*300/H), 300}; H > W -> {round(W*300/H), 300};
true -> {300, 300} true -> {300, 300}
end, end,
OutInfo = #media_info{type = T, width = W1, height = H1}, OutInfo = #media_info{path = OutPath, type = T, width = W1, height = H1},
case file:read_file(Path) of case eimp:convert(InData, T, [{scale, {W1, H1}}]) of
{ok, Data} -> {ok, OutData} ->
case eimp:convert(Data, T, [{scale, {W1, H1}}]) of case file:write_file(OutPath, OutData) of
{ok, OutData} -> ok ->
case file:write_file(OutPath, OutData) of {ok, OutInfo};
ok ->
{ok, OutPath, OutInfo};
{error, Why} ->
?ERROR_MSG("Failed to write to ~s: ~s",
[OutPath, format_error(Why)]),
pass
end;
{error, Why} -> {error, Why} ->
?ERROR_MSG("Failed to convert ~s to ~s: ~s", ?ERROR_MSG("Failed to write to ~s: ~s",
[Path, OutPath, eimp:format_error(Why)]), [OutPath, format_error(Why)]),
pass pass
end; end;
{error, Why} -> {error, Why} ->
?ERROR_MSG("Failed to read file ~s: ~s", ?ERROR_MSG("Failed to convert ~s to ~s: ~s",
[Path, format_error(Why)]), [Path, OutPath, eimp:format_error(Why)]),
pass pass
end end
end. end.