Compare commits
13 Commits
91538aaba5
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
3bea18708f
|
|||
|
ed8ba147ba
|
|||
|
c221a00c33
|
|||
|
192ffa0de9
|
|||
|
bac9fce4e0
|
|||
|
2e9ea9b4e2
|
|||
|
b34fe63198
|
|||
|
3c8ddcaf26
|
|||
|
e3ec07a19f
|
|||
|
e57364cd97
|
|||
|
7330f07dd7
|
|||
|
d68e09525c
|
|||
|
115a7bab0f
|
@@ -38,6 +38,9 @@ You can get a package with the latest development version using Arch Linux's
|
|||||||
https://aur.archlinux.org/packages/fiv-git[AUR],
|
https://aur.archlinux.org/packages/fiv-git[AUR],
|
||||||
or as a https://git.janouch.name/p/nixexprs[Nix derivation].
|
or as a https://git.janouch.name/p/nixexprs[Nix derivation].
|
||||||
|
|
||||||
|
https://janouch.name/cd[Windows installers can be found here],
|
||||||
|
you want the _x86_64_ version.
|
||||||
|
|
||||||
Building and Running
|
Building and Running
|
||||||
--------------------
|
--------------------
|
||||||
Build-only dependencies:
|
Build-only dependencies:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ q:lang(en):after { content: "’"; }
|
|||||||
<p class="details">
|
<p class="details">
|
||||||
<span id="author">Přemysl Eric Janouch</span><br>
|
<span id="author">Přemysl Eric Janouch</span><br>
|
||||||
<span id="email"><a href="mailto:p@janouch.name">p@janouch.name</a></span><br>
|
<span id="email"><a href="mailto:p@janouch.name">p@janouch.name</a></span><br>
|
||||||
<span id="revnumber">version 0.0.0,</span>
|
<span id="revnumber">version 1.0.0,</span>
|
||||||
<span id="revdate">2023-04-17</span>
|
<span id="revdate">2023-04-17</span>
|
||||||
|
|
||||||
<p class="figure"><img src="fiv.webp" alt="fiv in browser and viewer modes">
|
<p class="figure"><img src="fiv.webp" alt="fiv in browser and viewer modes">
|
||||||
|
|||||||
BIN
docs/fiv.webp
BIN
docs/fiv.webp
Binary file not shown.
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 194 KiB |
@@ -828,9 +828,18 @@ thumbnailer_next(Thumbnailer *t)
|
|||||||
"--thumbnail", fiv_thumbnail_sizes[self->item_size].thumbnail_spec_name,
|
"--thumbnail", fiv_thumbnail_sizes[self->item_size].thumbnail_spec_name,
|
||||||
"--", uri, NULL};
|
"--", uri, NULL};
|
||||||
|
|
||||||
|
GSubprocessLauncher *launcher =
|
||||||
|
g_subprocess_launcher_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE);
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
gchar *prefix = g_win32_get_package_installation_directory_of_module(NULL);
|
||||||
|
g_subprocess_launcher_set_cwd(launcher, prefix);
|
||||||
|
g_free(prefix);
|
||||||
|
#endif
|
||||||
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
t->minion = g_subprocess_newv(t->target->icon ? argv_faster : argv_slower,
|
t->minion = g_subprocess_launcher_spawnv(
|
||||||
G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error);
|
launcher, t->target->icon ? argv_faster : argv_slower, &error);
|
||||||
|
g_object_unref(launcher);
|
||||||
if (error) {
|
if (error) {
|
||||||
g_warning("%s", error->message);
|
g_warning("%s", error->message);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
|
|||||||
@@ -185,15 +185,24 @@ info_spawn(GtkWidget *dialog, const char *path, GBytes *bytes_in)
|
|||||||
if (bytes_in)
|
if (bytes_in)
|
||||||
flags |= G_SUBPROCESS_FLAGS_STDIN_PIPE;
|
flags |= G_SUBPROCESS_FLAGS_STDIN_PIPE;
|
||||||
|
|
||||||
|
GSubprocessLauncher *launcher = g_subprocess_launcher_new(flags);
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
// Both to find wperl, and then to let wperl find the nearby exiftool.
|
||||||
|
gchar *prefix = g_win32_get_package_installation_directory_of_module(NULL);
|
||||||
|
g_subprocess_launcher_set_cwd(launcher, prefix);
|
||||||
|
g_free(prefix);
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO(p): Add a fallback to internal capabilities.
|
// TODO(p): Add a fallback to internal capabilities.
|
||||||
// The simplest is to specify the filename and the resolution.
|
// The simplest is to specify the filename and the resolution.
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GSubprocess *subprocess = g_subprocess_new(flags, &error,
|
GSubprocess *subprocess = g_subprocess_launcher_spawn(launcher, &error,
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
"wperl",
|
"wperl",
|
||||||
#endif
|
#endif
|
||||||
"exiftool", "-tab", "-groupNames", "-duplicates", "-extractEmbedded",
|
"exiftool", "-tab", "-groupNames", "-duplicates", "-extractEmbedded",
|
||||||
"--binary", "-quiet", "--", path, NULL);
|
"--binary", "-quiet", "--", path, NULL);
|
||||||
|
g_object_unref(launcher);
|
||||||
if (error) {
|
if (error) {
|
||||||
info_redirect_error(dialog, error);
|
info_redirect_error(dialog, error);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -400,7 +400,8 @@ fiv_io_cmm_argb32_premultiply(FivIoCmm *self,
|
|||||||
#else // ! HAVE_LCMS2 || LCMS_VERSION < 2130
|
#else // ! HAVE_LCMS2 || LCMS_VERSION < 2130
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fiv_io_cmm_argb32(FivIoCmm *, FivIoImage *, FivIoProfile *, FivIoProfile *)
|
fiv_io_cmm_argb32(G_GNUC_UNUSED FivIoCmm *self, G_GNUC_UNUSED FivIoImage *image,
|
||||||
|
G_GNUC_UNUSED FivIoProfile *source, G_GNUC_UNUSED FivIoProfile *target)
|
||||||
{
|
{
|
||||||
// TODO(p): Unpremultiply, transform, repremultiply. Or require lcms2>=2.13.
|
// TODO(p): Unpremultiply, transform, repremultiply. Or require lcms2>=2.13.
|
||||||
}
|
}
|
||||||
|
|||||||
15
fiv-io.c
15
fiv-io.c
@@ -42,6 +42,8 @@
|
|||||||
#include <libraw.h>
|
#include <libraw.h>
|
||||||
#if LIBRAW_VERSION >= LIBRAW_MAKE_VERSION(0, 21, 0)
|
#if LIBRAW_VERSION >= LIBRAW_MAKE_VERSION(0, 21, 0)
|
||||||
#define LIBRAW_OPIONS_NO_MEMERR_CALLBACK 0
|
#define LIBRAW_OPIONS_NO_MEMERR_CALLBACK 0
|
||||||
|
#else
|
||||||
|
#define rawparams params
|
||||||
#endif
|
#endif
|
||||||
#endif // HAVE_LIBRAW
|
#endif // HAVE_LIBRAW
|
||||||
#ifdef HAVE_RESVG
|
#ifdef HAVE_RESVG
|
||||||
@@ -59,6 +61,9 @@
|
|||||||
#ifdef HAVE_LIBTIFF
|
#ifdef HAVE_LIBTIFF
|
||||||
#include <tiff.h>
|
#include <tiff.h>
|
||||||
#include <tiffio.h>
|
#include <tiffio.h>
|
||||||
|
#ifndef TIFF_TMSIZE_T_MAX
|
||||||
|
#define TIFF_TMSIZE_T_MAX ((tmsize_t) (SIZE_MAX >> 1))
|
||||||
|
#endif
|
||||||
#endif // HAVE_LIBTIFF
|
#endif // HAVE_LIBTIFF
|
||||||
#ifdef HAVE_GDKPIXBUF
|
#ifdef HAVE_GDKPIXBUF
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
@@ -971,7 +976,7 @@ static uint32_t *
|
|||||||
parse_mpf_index_entries(const struct tiffer *T, struct tiffer_entry *entry)
|
parse_mpf_index_entries(const struct tiffer *T, struct tiffer_entry *entry)
|
||||||
{
|
{
|
||||||
uint32_t count = entry->remaining_count / 16;
|
uint32_t count = entry->remaining_count / 16;
|
||||||
uint32_t *offsets = g_malloc0_n(sizeof *offsets, count + 1), *out = offsets;
|
uint32_t *offsets = g_malloc0_n(count + 1, sizeof *offsets), *out = offsets;
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
// 5.2.3.3.3. Individual Image Data Offset
|
// 5.2.3.3.3. Individual Image Data Offset
|
||||||
uint32_t offset = parse_mpf_mpentry(entry->p + i * 16, T);
|
uint32_t offset = parse_mpf_mpentry(entry->p + i * 16, T);
|
||||||
@@ -1538,9 +1543,11 @@ load_libwebp_frame(WebPAnimDecoder *dec, const WebPAnimInfo *info,
|
|||||||
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
|
if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
|
||||||
memcpy(dst, buf, area * sizeof *dst);
|
memcpy(dst, buf, area * sizeof *dst);
|
||||||
} else {
|
} else {
|
||||||
uint32_t *src = (uint32_t *) buf;
|
const uint32_t *src = (const uint32_t *) buf;
|
||||||
for (uint64_t i = 0; i < area; i++)
|
for (uint64_t i = 0; i < area; i++) {
|
||||||
*dst++ = GUINT32_FROM_LE(*src++);
|
uint32_t value = *src++;
|
||||||
|
*dst++ = GUINT32_FROM_LE(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// info->bgcolor is not reliable.
|
// info->bgcolor is not reliable.
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ if [ "$#" -ne 2 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
xdg-open "$1$(fiv --thumbnail-for-search large "$2" \
|
xdg-open "$1$(fiv --thumbnail-for-search large "$2" \
|
||||||
| curl --silent --show-error --upload-file - https://transfer.sh/image \
|
| curl --silent --show-error --form 'files[]=@-' https://uguu.se/upload \
|
||||||
| jq --slurp --raw-input --raw-output @uri)"
|
| jq --raw-output '.files[] | .url | @uri')"
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ extract_libraw_unpack(libraw_data_t *iprc, int *flip, GError **error)
|
|||||||
// The main image's "flip" often matches up, but sometimes doesn't, e.g.:
|
// The main image's "flip" often matches up, but sometimes doesn't, e.g.:
|
||||||
// - Phase One/H 25/H25_Outdoor_.IIQ
|
// - Phase One/H 25/H25_Outdoor_.IIQ
|
||||||
// - Phase One/H 25/H25_IT8.7-2_Card.TIF
|
// - Phase One/H 25/H25_IT8.7-2_Card.TIF
|
||||||
*flip = iprc->sizes.flip
|
*flip = iprc->sizes.flip;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
fiv-view.c
11
fiv-view.c
@@ -646,7 +646,8 @@ reload_screen_cms_profile(FivView *self, GdkWindow *window)
|
|||||||
gchar *data = NULL;
|
gchar *data = NULL;
|
||||||
gsize length = 0;
|
gsize length = 0;
|
||||||
if (g_file_get_contents(path, &data, &length, NULL))
|
if (g_file_get_contents(path, &data, &length, NULL))
|
||||||
self->screen_cms_profile = fiv_io_profile_new(data, length);
|
self->screen_cms_profile = fiv_io_cmm_get_profile(
|
||||||
|
fiv_io_cmm_get_default(), data, length);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
g_free(path);
|
g_free(path);
|
||||||
@@ -850,6 +851,10 @@ gl_draw(FivView *self, cairo_t *cr)
|
|||||||
cliph = allocation.height;
|
cliph = allocation.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int scale = gtk_widget_get_scale_factor(GTK_WIDGET(self));
|
||||||
|
clipw *= scale;
|
||||||
|
cliph *= scale;
|
||||||
|
|
||||||
enum { SRC, DEST };
|
enum { SRC, DEST };
|
||||||
GLuint textures[2] = {};
|
GLuint textures[2] = {};
|
||||||
glGenTextures(2, textures);
|
glGenTextures(2, textures);
|
||||||
@@ -957,12 +962,14 @@ gl_draw(FivView *self, cairo_t *cr)
|
|||||||
// XXX: Native GdkWindows send this to the software fallback path.
|
// XXX: Native GdkWindows send this to the software fallback path.
|
||||||
// XXX: This only reliably alpha blends when using the software fallback,
|
// XXX: This only reliably alpha blends when using the software fallback,
|
||||||
// such as with a native window, because 7237f5d in GTK+ 3 is a regression.
|
// such as with a native window, because 7237f5d in GTK+ 3 is a regression.
|
||||||
|
// (Introduced in 3.24.39, reverted in 3.24.42.)
|
||||||
|
//
|
||||||
// We had to resort to rendering the checkerboard pattern in the shader.
|
// We had to resort to rendering the checkerboard pattern in the shader.
|
||||||
// Unfortunately, it is hard to retrieve the theme colours from CSS.
|
// Unfortunately, it is hard to retrieve the theme colours from CSS.
|
||||||
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(self));
|
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(self));
|
||||||
cairo_translate(cr, dx, dy);
|
cairo_translate(cr, dx, dy);
|
||||||
gdk_cairo_draw_from_gl(
|
gdk_cairo_draw_from_gl(
|
||||||
cr, window, textures[DEST], GL_TEXTURE, 1, 0, 0, clipw, cliph);
|
cr, window, textures[DEST], GL_TEXTURE, scale, 0, 0, clipw, cliph);
|
||||||
gdk_gl_context_make_current(self->gl_context);
|
gdk_gl_context_make_current(self->gl_context);
|
||||||
|
|
||||||
glDeleteBuffers(1, &vertex_buffer);
|
glDeleteBuffers(1, &vertex_buffer);
|
||||||
|
|||||||
10
meson.build
10
meson.build
@@ -1,7 +1,7 @@
|
|||||||
# vim: noet ts=4 sts=4 sw=4:
|
# vim: noet ts=4 sts=4 sw=4:
|
||||||
project('fiv', 'c',
|
project('fiv', 'c',
|
||||||
default_options : ['c_std=gnu99', 'warning_level=2'],
|
default_options : ['c_std=gnu99', 'warning_level=2'],
|
||||||
version : '0.1.0',
|
version : '1.0.0',
|
||||||
meson_version : '>=0.57')
|
meson_version : '>=0.57')
|
||||||
|
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
@@ -166,7 +166,7 @@ tiff_tables = custom_target('tiff-tables.h',
|
|||||||
|
|
||||||
desktops = ['fiv.desktop', 'fiv-browse.desktop']
|
desktops = ['fiv.desktop', 'fiv-browse.desktop']
|
||||||
iolib = static_library('fiv-io', 'fiv-io.c', 'fiv-io-cmm.c', 'xdg.c',
|
iolib = static_library('fiv-io', 'fiv-io.c', 'fiv-io-cmm.c', 'xdg.c',
|
||||||
tiff_tables,
|
tiff_tables, config,
|
||||||
dependencies : dependencies).extract_all_objects(recursive : true)
|
dependencies : dependencies).extract_all_objects(recursive : true)
|
||||||
exe = executable('fiv', 'fiv.c', 'fiv-view.c', 'fiv-context-menu.c',
|
exe = executable('fiv', 'fiv.c', 'fiv-view.c', 'fiv-context-menu.c',
|
||||||
'fiv-browser.c', 'fiv-sidebar.c', 'fiv-thumbnail.c', 'fiv-collection.c',
|
'fiv-browser.c', 'fiv-sidebar.c', 'fiv-thumbnail.c', 'fiv-collection.c',
|
||||||
@@ -363,10 +363,12 @@ elif meson.is_cross_build()
|
|||||||
'ProjectURL' : application_url,
|
'ProjectURL' : application_url,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
msi = meson.project_name() + '-' + meson.project_version() + \
|
||||||
|
'-' + host_machine.cpu() + '.msi'
|
||||||
custom_target('package',
|
custom_target('package',
|
||||||
output : 'fiv.msi',
|
output : msi,
|
||||||
command : [meson.current_source_dir() / 'msys2-package.sh',
|
command : [meson.current_source_dir() / 'msys2-package.sh',
|
||||||
host_machine.cpu(), 'fiv.msi', wxs],
|
host_machine.cpu(), msi, wxs],
|
||||||
env : ['MESON_BUILD_ROOT=' + meson.current_build_dir(),
|
env : ['MESON_BUILD_ROOT=' + meson.current_build_dir(),
|
||||||
'MESON_SOURCE_ROOT=' + meson.current_source_dir()],
|
'MESON_SOURCE_ROOT=' + meson.current_source_dir()],
|
||||||
console : true,
|
console : true,
|
||||||
|
|||||||
@@ -75,10 +75,15 @@ extract() {
|
|||||||
--exclude '*/share/man' --exclude '*/share/doc'
|
--exclude '*/share/man' --exclude '*/share/doc'
|
||||||
done < db.want
|
done < db.want
|
||||||
|
|
||||||
|
# Don't require Perl, which may not exist anymore on i686:
|
||||||
|
# https://github.com/msys2/MINGW-packages/pull/20085
|
||||||
|
if [ -d lib/perl5 ]
|
||||||
|
then
|
||||||
bsdtar -xf exiftool.tar.gz
|
bsdtar -xf exiftool.tar.gz
|
||||||
mv Image-ExifTool-*/exiftool bin
|
mv Image-ExifTool-*/exiftool bin
|
||||||
mv Image-ExifTool-*/lib/* lib/perl5/site_perl
|
mv Image-ExifTool-*/lib/* lib/perl5/site_perl
|
||||||
rm -rf Image-ExifTool-*
|
rm -rf Image-ExifTool-*
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
configure() {
|
configure() {
|
||||||
|
|||||||
@@ -12,15 +12,15 @@ fi
|
|||||||
|
|
||||||
# Copy binaries we directly or indirectly depend on.
|
# Copy binaries we directly or indirectly depend on.
|
||||||
cp -p "$msys2_root"/bin/*.dll .
|
cp -p "$msys2_root"/bin/*.dll .
|
||||||
cp -p "$msys2_root"/bin/wperl.exe .
|
cp -p "$msys2_root"/bin/wperl.exe . || :
|
||||||
cp -p "$msys2_root"/bin/exiftool .
|
cp -p "$msys2_root"/bin/exiftool . || :
|
||||||
# The console helper is only useful for debug builds.
|
# The console helper is only useful for debug builds.
|
||||||
cp -p "$msys2_root"/bin/gspawn-*-helper*.exe .
|
cp -p "$msys2_root"/bin/gspawn-*-helper*.exe .
|
||||||
cp -pR "$msys2_root"/etc/ .
|
cp -pR "$msys2_root"/etc/ .
|
||||||
|
|
||||||
mkdir -p lib
|
mkdir -p lib
|
||||||
cp -pR "$msys2_root"/lib/gdk-pixbuf-2.0/ lib
|
cp -pR "$msys2_root"/lib/gdk-pixbuf-2.0/ lib
|
||||||
cp -pR "$msys2_root"/lib/perl5/ lib
|
cp -pR "$msys2_root"/lib/perl5/ lib || :
|
||||||
mkdir -p share/glib-2.0/schemas
|
mkdir -p share/glib-2.0/schemas
|
||||||
cp -pR "$msys2_root"/share/glib-2.0/schemas/*.Settings.* share/glib-2.0/schemas
|
cp -pR "$msys2_root"/share/glib-2.0/schemas/*.Settings.* share/glib-2.0/schemas
|
||||||
mkdir -p share/icons
|
mkdir -p share/icons
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
export LC_ALL=C
|
export LC_ALL=C
|
||||||
cd "$MESON_BUILD_ROOT"
|
cd "$MESON_BUILD_ROOT"
|
||||||
arch=$1 msi=$2 files=package-files.wxs destdir=$(pwd)/package
|
arch=$1 msi=$2 files=package-files.wxs
|
||||||
|
destdir=$(pwd)/package/${msi%.*}
|
||||||
shift 2
|
shift 2
|
||||||
|
|
||||||
# We're being passed host_machine.cpu(), which will be either x86 or x86_64.
|
# We're being passed host_machine.cpu(), which will be either x86 or x86_64.
|
||||||
@@ -15,7 +16,7 @@ txt2rtf() {
|
|||||||
print "{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0 Tahoma;}}"
|
print "{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0 Tahoma;}}"
|
||||||
print "\\f0\\fs24{\\pard\\sa240"
|
print "\\f0\\fs24{\\pard\\sa240"
|
||||||
} {
|
} {
|
||||||
gsub(/\\/, "\\\\"); gsub(/{/, "\\{"); gsub(/}/, "\\}")
|
gsub(/\\/, "\\\\"); gsub(/[{]/, "\\{"); gsub(/[}]/, "\\}")
|
||||||
if (!$0) { print "\\par}{\\pard\\sa240"; prefix = "" }
|
if (!$0) { print "\\par}{\\pard\\sa240"; prefix = "" }
|
||||||
else { print prefix $0; prefix = " " }
|
else { print prefix $0; prefix = " " }
|
||||||
} END {
|
} END {
|
||||||
|
|||||||
Reference in New Issue
Block a user