Merge lp:~michihenning/thumbnailer/gstreamer-plugins into lp:thumbnailer/devel

Proposed by Michi Henning on 2017-02-03
Status: Merged
Approved by: James Henstridge on 2017-02-08
Approved revision: 379
Merged at revision: 371
Proposed branch: lp:~michihenning/thumbnailer/gstreamer-plugins
Merge into: lp:thumbnailer/devel
Prerequisite: lp:~michihenning/thumbnailer/snap
Diff against target: 257 lines (+106/-66)
6 files modified
CMakeLists.txt (+2/-2)
include/internal/env_vars.h (+2/-0)
snapcraft.yaml (+13/-1)
src/env_vars.cpp (+23/-0)
src/thumbnailer-admin/CMakeLists.txt (+0/-2)
src/vs-thumb/vs-thumb.cpp (+66/-61)
To merge this branch: bzr merge lp:~michihenning/thumbnailer/gstreamer-plugins
Reviewer Review Type Date Requested Status
James Henstridge 2017-02-03 Approve on 2017-02-08
unity-api-1-bot continuous-integration Approve on 2017-02-08
Review via email: mp+316309@code.launchpad.net

Commit message

Added gstreamer plugin dependencies.

Description of the change

Added gstreamer plugin dependencies.

To post a comment you must log in.
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:372
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/27/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1594
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1601
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1379
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1379/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1379
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1379/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1379
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1379/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1379
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1379/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1379
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1379/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1379
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1379/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/27/rebuild

review: Approve (continuous-integration)
James Henstridge (jamesh) wrote :

I don't think the GST_PLUGIN_PATH manipulation should be done here: instead, it probably belongs in the desktop-ubuntu-app-platform part.

In particular, I don't think we want to ignore the GStreamer plugins from ubuntu-app-platform: instead, GST_PLUGIN_PATH should be set to take plugins from our snap, and then ubuntu-app-platform second. That way we probably only need to ship libgstlibav.so, rather than an entire suite of elements.

review: Needs Fixing
Michi Henning (michihenning) wrote :

> I don't think the GST_PLUGIN_PATH manipulation should be done here: instead,
> it probably belongs in the desktop-ubuntu-app-platform part.

I can raise a bug for that, but I'm not sure I agree. ubuntu-app-platform can't really know where a snap chooses to install additional plugins; they could be in a different path.

> In particular, I don't think we want to ignore the GStreamer plugins from
> ubuntu-app-platform: instead, GST_PLUGIN_PATH should be set to take plugins
> from our snap, and then ubuntu-app-platform second. That way we probably only
> need to ship libgstlibav.so, rather than an entire suite of elements.

We are not ignoring them. desktop-launch sets GST_PLUGIN_SYSTEM_PATH, and vs-thumb sets GST_PLUGIN_PATH. According to the gstreamer doc, it first loads anything in GST_PLUGIN_PATH, and then anything in GST_PLUGIN_SYSTEM_PATH. (If we were ignoring the libs in ubuntu-app-platform, it wouldn't work at all, but .ogg video extraction definitely works.)

None of the libraries in the explicit list are in ubuntu-app-platform. They are basically all dependencies of gstreamer when it uses the codecs in libav.

I can't for the life of me figure out at the moment why .mp4 won't work. I keep getting "Your GStreamer installation is missing a plug-in."

unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:375
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/28/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1637
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1644
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1420
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1420/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1420
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1420/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1420
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1420/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1420
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1420/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1420
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1420/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1420
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1420/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/28/rebuild

review: Approve (continuous-integration)
376. By Michi Henning on 2017-02-08

Using build-packages and explicit copy into the stage area
for libav and libgpm now, so snapcraft works out the run-time
dependencies for us.

Michi Henning (michihenning) wrote :

Works on xenial and zesty now. squashfs size is 40 MB on xenial, 50 MB on zesty. Looks like we are dragging in loads of stuff still that's also in ubuntu-app-platform though. Just skimming, there are at least:

libogg.so.0, libtag.so.1, libwavpack.so.1, libX11.so.6, libQt5Core.so.5, libQt5DBus.so.5, libQt5Network.so.5, libXau.so.6, etc, etc...

unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:376
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/29/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1638
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1645
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1421
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1421/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1421
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1421/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1421
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1421/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1421
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1421/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1421
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1421/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1421
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1421/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/29/rebuild

review: Approve (continuous-integration)
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:377
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/30/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1639
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1646
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1422
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1422/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1422
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1422/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1422
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1422/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1422
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1422/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1422
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1422/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1422
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1422/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/30/rebuild

review: Approve (continuous-integration)
377. By Michi Henning on 2017-02-08

Removed libgpm2.

378. By Michi Henning on 2017-02-08

Merged parent.

James Henstridge (jamesh) wrote :

One small issue noted in an inline comment. Otherwise, everything else looks great.

review: Needs Fixing
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:378
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/31/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1640
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1647
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1423
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1423/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1423
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1423/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1423
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1423/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1423
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1423/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1423
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1423/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1423
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1423/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-thumbnailer-ci/31/rebuild

review: Approve (continuous-integration)
379. By Michi Henning on 2017-02-08

Moved gst_init() to beginning of vs-thumb main() and put included it
in try block.

James Henstridge (jamesh) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2017-02-03 07:35:46 +0000
3+++ CMakeLists.txt 2017-02-08 07:29:41 +0000
4@@ -47,8 +47,8 @@
5
6 add_definitions(-DQT_NO_KEYWORDS)
7
8-option(SnapBuild "Build for snap release")
9-if(${SnapBuild} OR "${SNAP_BUILD}")
10+option(SNAP_BUILD "Build for snap release")
11+if("${SNAP_BUILD}")
12 add_definitions(-DSNAP_BUILD=1)
13 endif()
14
15
16=== modified file 'include/internal/env_vars.h'
17--- include/internal/env_vars.h 2017-02-01 06:11:01 +0000
18+++ include/internal/env_vars.h 2017-02-08 07:29:41 +0000
19@@ -33,6 +33,8 @@
20
21 struct EnvVars
22 {
23+ static void set_snap_env();
24+
25 static int get_max_idle();
26 static QString get_ubuntu_server_url();
27 static QString get_util_dir();
28
29=== modified file 'snapcraft.yaml'
30--- snapcraft.yaml 2017-02-01 06:45:50 +0000
31+++ snapcraft.yaml 2017-02-08 07:29:41 +0000
32@@ -62,6 +62,8 @@
33 source: .
34 after:
35 - desktop-ubuntu-app-platform
36+ build-packages:
37+ - gstreamer1.0-libav # For H.264
38 filesets:
39 binaries:
40 - bin/*
41@@ -74,11 +76,21 @@
42 # TODO: This does not seem to have any effect. It is unclear right now how gsettings
43 # schemas need to be installed.
44 - share/glib-2.0/*
45+ gstreamer:
46+ # Libraries needed by the gstreamer plugins we use. Gstreamer loads these with dlopen().
47+ - usr/lib/*/gstreamer-1.0/libgstlibav.so
48 prime:
49 - $binaries
50 - $man
51 - $etc
52 - $share
53+ - $gstreamer
54 - ubuntu-app-platform
55 install: |
56- mkdir $SNAPCRAFT_PART_INSTALL/ubuntu-app-platform
57+ # Make sure we have a mount point for ubuntu-app-platform
58+ mkdir -p $SNAPCRAFT_PART_INSTALL/ubuntu-app-platform
59+ # Copy the libav plugin to the prime, so snapcraft runs ldd over it
60+ # and adds the dependencies of libgstlibav.so to the prime.
61+ plugin=$(echo /usr/lib/*/gstreamer-1.0/libgstlibav.so)
62+ mkdir -p $SNAPCRAFT_PART_INSTALL/$(dirname $plugin)
63+ cp $plugin $SNAPCRAFT_PART_INSTALL/$plugin
64
65=== modified file 'src/env_vars.cpp'
66--- src/env_vars.cpp 2017-02-03 07:35:46 +0000
67+++ src/env_vars.cpp 2017-02-08 07:29:41 +0000
68@@ -38,6 +38,29 @@
69 namespace internal
70 {
71
72+void EnvVars::set_snap_env()
73+{
74+#ifdef SNAP_BUILD
75+ char const* snap = getenv("SNAP");
76+ if (snap)
77+ {
78+ char const* arch = getenv("SNAP_LAUNCHER_ARCH_TRIPLET");
79+ if (!arch || !*arch)
80+ {
81+ throw runtime_error("Env var SNAP_LAUNCHER_ARCH_TRIPLET not set");
82+ }
83+
84+ string plugin_path = string(snap) + "/usr/lib/" + arch + "/gstreamer-1.0";
85+ char const* old_plugin_path = getenv("GST_PLUGIN_PATH");
86+ if (old_plugin_path && *old_plugin_path)
87+ {
88+ plugin_path += string(":") + old_plugin_path;
89+ }
90+ setenv("GST_PLUGIN_PATH", plugin_path.c_str(), 1);
91+ }
92+#endif
93+}
94+
95 int EnvVars::get_max_idle()
96 {
97 char const* c_idle_time = getenv(MAX_IDLE);
98
99=== modified file 'src/thumbnailer-admin/CMakeLists.txt'
100--- src/thumbnailer-admin/CMakeLists.txt 2016-02-25 07:14:21 +0000
101+++ src/thumbnailer-admin/CMakeLists.txt 2017-02-08 07:29:41 +0000
102@@ -20,8 +20,6 @@
103 shutdown.cpp
104 thumbnailer-admin.cpp
105 util.cpp
106- ${CMAKE_SOURCE_DIR}/src/file_io.cpp
107- ${CMAKE_SOURCE_DIR}/src/safe_strerror.cpp
108 ${CMAKE_SOURCE_DIR}/src/service/stats.cpp
109 ${interface_files}
110 )
111
112=== modified file 'src/vs-thumb/vs-thumb.cpp'
113--- src/vs-thumb/vs-thumb.cpp 2016-03-18 12:18:09 +0000
114+++ src/vs-thumb/vs-thumb.cpp 2017-02-08 07:29:41 +0000
115@@ -19,6 +19,7 @@
116
117 #include "thumbnailextractor.h"
118
119+#include <internal/env_vars.h>
120 #include <internal/trace.h>
121
122 #include <QUrl>
123@@ -57,69 +58,73 @@
124 {
125 char const * const progname = basename(argv[0]);
126
127- TraceMessageHandler message_handler(progname);
128-
129- gst_init(&argc, &argv);
130-
131- if (argc != 3)
132- {
133- cerr << "usage: " << progname << " source-file (output-file.tiff | fd:num)" << endl;
134- return 1;
135- }
136-
137- QUrl in_url(argv[1], QUrl::StrictMode);
138- if (!in_url.isValid())
139- {
140- cerr << progname << ": invalid input URL: " << argv[1] << endl;
141- return 2;
142- }
143-
144- QUrl out_url(argv[2], QUrl::StrictMode);
145- if (!out_url.isValid())
146- {
147- cerr << progname << ": invalid output URL: " << argv[2] << endl;
148- return 2;
149- }
150-
151- auto in_scheme = in_url.scheme();
152- if (in_scheme != "file")
153- {
154- cerr << progname << ": invalid input URL: " << argv[1] << " (invalid scheme name, requires \"file:\")" << endl;
155- return 2;
156- }
157-
158- auto out_scheme = out_url.scheme();
159- if (out_scheme != "file" && out_scheme != "fd")
160- {
161- cerr << progname << ": invalid output URL: " << argv[2]
162- << " (invalid scheme name, requires \"file:\" or \"fd:\")" << endl;
163- return 2;
164- }
165-
166- if (out_scheme == "file")
167- {
168- // Output file name must end in .tiff.
169- auto out_path = out_url.path();
170- if (!out_path.endsWith(".tiff", Qt::CaseInsensitive))
171- {
172- cerr << progname << ": invalid output file name: " << argv[2] << " (missing .tiff extension)" << endl;
173- return 2;
174- }
175- }
176- else
177- {
178- // For fd: scheme, path must parse as a number.
179- bool ok;
180- out_url.path().toInt(&ok);
181- if (!ok)
182- {
183- cerr << progname << ": invalid URL: " << argv[2] << " (expected a number for file descriptor)" << endl;
184- return 2;
185- }
186- }
187-
188 try
189 {
190+ TraceMessageHandler message_handler(progname);
191+
192+ // TODO: set_snap_env() sets GST_PLUGIN_PATH. It would be nice if
193+ // desktop-launch did this. Once it does, we can remove this again.
194+ EnvVars::set_snap_env(); // Must be called before gst_init().
195+
196+ gst_init(&argc, &argv);
197+
198+ if (argc != 3)
199+ {
200+ cerr << "usage: " << progname << " source-file (output-file.tiff | fd:num)" << endl;
201+ return 1;
202+ }
203+
204+ QUrl in_url(argv[1], QUrl::StrictMode);
205+ if (!in_url.isValid())
206+ {
207+ cerr << progname << ": invalid input URL: " << argv[1] << endl;
208+ return 2;
209+ }
210+
211+ QUrl out_url(argv[2], QUrl::StrictMode);
212+ if (!out_url.isValid())
213+ {
214+ cerr << progname << ": invalid output URL: " << argv[2] << endl;
215+ return 2;
216+ }
217+
218+ auto in_scheme = in_url.scheme();
219+ if (in_scheme != "file")
220+ {
221+ cerr << progname << ": invalid input URL: " << argv[1] << " (invalid scheme name, requires \"file:\")" << endl;
222+ return 2;
223+ }
224+
225+ auto out_scheme = out_url.scheme();
226+ if (out_scheme != "file" && out_scheme != "fd")
227+ {
228+ cerr << progname << ": invalid output URL: " << argv[2]
229+ << " (invalid scheme name, requires \"file:\" or \"fd:\")" << endl;
230+ return 2;
231+ }
232+
233+ if (out_scheme == "file")
234+ {
235+ // Output file name must end in .tiff.
236+ auto out_path = out_url.path();
237+ if (!out_path.endsWith(".tiff", Qt::CaseInsensitive))
238+ {
239+ cerr << progname << ": invalid output file name: " << argv[2] << " (missing .tiff extension)" << endl;
240+ return 2;
241+ }
242+ }
243+ else
244+ {
245+ // For fd: scheme, path must parse as a number.
246+ bool ok;
247+ out_url.path().toInt(&ok);
248+ if (!ok)
249+ {
250+ cerr << progname << ": invalid URL: " << argv[2] << " (expected a number for file descriptor)" << endl;
251+ return 2;
252+ }
253+ }
254+
255 extract_thumbnail(in_url, out_url);
256 }
257 catch (exception const& e)

Subscribers

People subscribed via source and target branches

to all changes: