Compare commits
4 Commits
a6560509d9
...
544722f8e0
Author | SHA1 | Date | |
---|---|---|---|
544722f8e0 | |||
00110a639a | |||
5af36f4954 | |||
ac72a72afc |
2
fiv-io.c
2
fiv-io.c
@ -1775,7 +1775,7 @@ open_libraw(const char *data, gsize len, GError **error)
|
|||||||
|
|
||||||
int width = image->width, height = image->height;
|
int width = image->width, height = image->height;
|
||||||
cairo_surface_t *surface =
|
cairo_surface_t *surface =
|
||||||
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
|
||||||
cairo_status_t surface_status = cairo_surface_status(surface);
|
cairo_status_t surface_status = cairo_surface_status(surface);
|
||||||
if (surface_status != CAIRO_STATUS_SUCCESS) {
|
if (surface_status != CAIRO_STATUS_SUCCESS) {
|
||||||
set_error(error, cairo_status_to_string(surface_status));
|
set_error(error, cairo_status_to_string(surface_status));
|
||||||
|
@ -281,6 +281,12 @@ fiv_thumbnail_extract(GFile *target, FivThumbnailSize max_size, GError **error)
|
|||||||
// TODO(p): Implement our own thumbnail extractors.
|
// TODO(p): Implement our own thumbnail extractors.
|
||||||
set_error(error, "unsupported file");
|
set_error(error, "unsupported file");
|
||||||
#else // HAVE_LIBRAW
|
#else // HAVE_LIBRAW
|
||||||
|
// In this case, g_mapped_file_get_contents() returns NULL, causing issues.
|
||||||
|
if (!g_mapped_file_get_length(mf)) {
|
||||||
|
set_error(error, "empty file");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
libraw_data_t *iprc = libraw_init(
|
libraw_data_t *iprc = libraw_init(
|
||||||
LIBRAW_OPIONS_NO_MEMERR_CALLBACK | LIBRAW_OPIONS_NO_DATAERR_CALLBACK);
|
LIBRAW_OPIONS_NO_MEMERR_CALLBACK | LIBRAW_OPIONS_NO_DATAERR_CALLBACK);
|
||||||
if (!iprc) {
|
if (!iprc) {
|
||||||
@ -290,12 +296,42 @@ fiv_thumbnail_extract(GFile *target, FivThumbnailSize max_size, GError **error)
|
|||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if ((err = libraw_open_buffer(iprc, (void *) g_mapped_file_get_contents(mf),
|
if ((err = libraw_open_buffer(iprc, (void *) g_mapped_file_get_contents(mf),
|
||||||
g_mapped_file_get_length(mf))) ||
|
g_mapped_file_get_length(mf)))) {
|
||||||
(err = libraw_unpack_thumb(iprc))) {
|
|
||||||
set_error(error, libraw_strerror(err));
|
set_error(error, libraw_strerror(err));
|
||||||
goto fail_libraw;
|
goto fail_libraw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LIBRAW_VERSION >= LIBRAW_MAKE_VERSION(0, 21, 0)
|
||||||
|
if (!iprc->thumbs_list.thumbcount) {
|
||||||
|
set_error(error, "no thumbnails found");
|
||||||
|
goto fail_libraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The old libraw_unpack_thumb() goes for the largest thumbnail,
|
||||||
|
// but we currently want the smallest thumbnail.
|
||||||
|
// TODO(p): To handle the ugly IFD0 thumbnail of NEF,
|
||||||
|
// try to go for the second smallest size. Remember to reflect tflip.
|
||||||
|
int best_index = 0;
|
||||||
|
float best_pixels = INFINITY;
|
||||||
|
for (int i = 0; i < iprc->thumbs_list.thumbcount; i++) {
|
||||||
|
float pixels = (float) iprc->thumbs_list.thumblist[i].twidth *
|
||||||
|
(float) iprc->thumbs_list.thumblist[i].theight;
|
||||||
|
if (pixels && pixels < best_pixels) {
|
||||||
|
best_index = i;
|
||||||
|
best_pixels = pixels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((err = libraw_unpack_thumb_ex(iprc, best_index))) {
|
||||||
|
set_error(error, libraw_strerror(err));
|
||||||
|
goto fail_libraw;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if ((err = libraw_unpack_thumb(iprc))) {
|
||||||
|
set_error(error, libraw_strerror(err));
|
||||||
|
goto fail_libraw;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
libraw_processed_image_t *image = libraw_dcraw_make_mem_thumb(iprc, &err);
|
libraw_processed_image_t *image = libraw_dcraw_make_mem_thumb(iprc, &err);
|
||||||
if (!image) {
|
if (!image) {
|
||||||
set_error(error, libraw_strerror(err));
|
set_error(error, libraw_strerror(err));
|
||||||
@ -447,6 +483,7 @@ fiv_thumbnail_produce_for_search(
|
|||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
produce_fallback(GFile *target, FivThumbnailSize size, GError **error)
|
produce_fallback(GFile *target, FivThumbnailSize size, GError **error)
|
||||||
{
|
{
|
||||||
|
// Note that this comes with a TOCTTOU problem.
|
||||||
goffset filesize = 0;
|
goffset filesize = 0;
|
||||||
GFileInfo *info = g_file_query_info(target,
|
GFileInfo *info = g_file_query_info(target,
|
||||||
G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_SIZE,
|
G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_STANDARD_SIZE,
|
||||||
@ -497,6 +534,13 @@ fiv_thumbnail_produce(GFile *target, FivThumbnailSize max_size, GError **error)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(p): Use open(O_RDONLY | O_NONBLOCK | _O_BINARY), fstat(),
|
||||||
|
// g_mapped_file_new_from_fd(), and reset the non-blocking flag on the file.
|
||||||
|
if (!S_ISREG(st.st_mode)) {
|
||||||
|
set_error(error, "not a regular file");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
GError *e = NULL;
|
GError *e = NULL;
|
||||||
GMappedFile *mf = g_mapped_file_new(path, FALSE, &e);
|
GMappedFile *mf = g_mapped_file_new(path, FALSE, &e);
|
||||||
if (!mf) {
|
if (!mf) {
|
||||||
@ -505,7 +549,13 @@ fiv_thumbnail_produce(GFile *target, FivThumbnailSize max_size, GError **error)
|
|||||||
return produce_fallback(target, max_size, error);
|
return produce_fallback(target, max_size, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In this case, g_mapped_file_get_bytes() has NULL data, causing issues.
|
||||||
gsize filesize = g_mapped_file_get_length(mf);
|
gsize filesize = g_mapped_file_get_length(mf);
|
||||||
|
if (!filesize) {
|
||||||
|
set_error(error, "empty file");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean color_managed = FALSE;
|
gboolean color_managed = FALSE;
|
||||||
cairo_surface_t *surface =
|
cairo_surface_t *surface =
|
||||||
render(target, g_mapped_file_get_bytes(mf), &color_managed, error);
|
render(target, g_mapped_file_get_bytes(mf), &color_managed, error);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user