namespace
{
-struct ImageLoaderTiff {
- ImageLoaderBackendCbAreaUpdated area_updated_cb;
- ImageLoaderBackendCbSize size_cb;
- ImageLoaderBackendCbAreaPrepared area_prepared_cb;
-
+struct ImageLoaderTiff : public ImageLoaderBackend
+{
+public:
+ ~ImageLoaderTiff() override;
+
+ void init(AreaUpdatedCb area_updated_cb, SizePreparedCb size_prepared_cb, AreaPreparedCb area_prepared_cb, gpointer data) override;
+ void set_size(int width, int height) override;
+ gboolean write(const guchar *buf, gsize &chunk_size, gsize count, GError **error) override;
+ GdkPixbuf *get_pixbuf() override;
+ void abort() override;
+ gchar *get_format_name() override;
+ gchar **get_format_mime_types() override;
+ void set_page_num(gint page_num) override;
+ gint get_page_total() override;
+
+private:
+ AreaUpdatedCb area_updated_cb;
+ SizePreparedCb size_prepared_cb;
+ AreaPreparedCb area_prepared_cb;
gpointer data;
GdkPixbuf *pixbuf;
guint requested_width;
guint requested_height;
- gboolean abort;
+ gboolean aborted;
+
+ gint page_num;
+ gint page_total;
+};
+struct GqTiffContext
+{
const guchar *buffer;
toff_t used;
toff_t pos;
- gint page_num;
- gint page_total;
};
void free_buffer (guchar *pixels, gpointer)
tsize_t tiff_load_read (thandle_t handle, tdata_t buf, tsize_t size)
{
- auto context = static_cast<ImageLoaderTiff *>(handle);
+ auto context = static_cast<GqTiffContext *>(handle);
if (context->pos + size > context->used)
return 0;
toff_t tiff_load_seek (thandle_t handle, toff_t offset, int whence)
{
- auto context = static_cast<ImageLoaderTiff *>(handle);
+ auto context = static_cast<GqTiffContext *>(handle);
switch (whence)
{
toff_t tiff_load_size (thandle_t handle)
{
- auto context = static_cast<ImageLoaderTiff *>(handle);
+ auto context = static_cast<GqTiffContext *>(handle);
return context->used;
}
int tiff_load_map_file (thandle_t handle, tdata_t *buf, toff_t *size)
{
- auto context = static_cast<ImageLoaderTiff *>(handle);
+ auto context = static_cast<GqTiffContext *>(handle);
*buf = const_cast<guchar *>(context->buffer);
*size = context->used;
{
}
-gboolean image_loader_tiff_write (gpointer loader, const guchar *buf, gsize &chunk_size, gsize count, GError **)
+gboolean ImageLoaderTiff::write(const guchar *buf, gsize &chunk_size, gsize count, GError **)
{
- auto lt = static_cast<ImageLoaderTiff *>(loader);
-
TIFF *tiff;
guchar *pixels = nullptr;
gint width;
guint32 rowsperstrip;
gint dircount = 0;
- lt->buffer = buf;
- lt->used = count;
- lt->pos = 0;
-
TIFFSetWarningHandler(nullptr);
- tiff = TIFFClientOpen ( "libtiff-geeqie", "r", lt,
+ GqTiffContext context{buf, count, 0};
+ tiff = TIFFClientOpen ( "libtiff-geeqie", "r", &context,
tiff_load_read, tiff_load_write,
tiff_load_seek, tiff_load_close,
tiff_load_size,
dircount++;
} while (TIFFReadDirectory(tiff));
- lt->page_total = dircount;
+ page_total = dircount;
- if (!TIFFSetDirectory(tiff, lt->page_num))
+ if (!TIFFSetDirectory(tiff, page_num))
{
DEBUG_1("Failed to open TIFF image");
TIFFClose(tiff);
return FALSE;
}
- lt->requested_width = width;
- lt->requested_height = height;
- lt->size_cb(loader, lt->requested_width, lt->requested_height, lt->data);
+ requested_width = width;
+ requested_height = height;
+ size_prepared_cb(nullptr, requested_width, requested_height, data);
pixels = static_cast<guchar *>(g_try_malloc (bytes));
return FALSE;
}
- lt->pixbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, TRUE, 8,
+ pixbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, TRUE, 8,
width, height, rowstride,
free_buffer, nullptr);
- if (!lt->pixbuf)
+ if (!pixbuf)
{
g_free (pixels);
DEBUG_1("Insufficient memory to open TIFF file");
return FALSE;
}
- lt->area_prepared_cb(loader, lt->data);
+ area_prepared_cb(nullptr, data);
if (TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &rowsperstrip))
{
int rows_to_write;
int i_row;
- if (lt->abort) {
+ if (aborted) {
break;
}
memcpy(top_line, bottom_line, line_bytes);
memcpy(bottom_line, wrk_line, line_bytes);
}
- lt->area_updated_cb(loader, 0, row, width, rows_to_write, lt->data);
+ area_updated_cb(nullptr, 0, row, width, rows_to_write, data);
}
g_free(wrk_line);
}
}
#endif
- lt->area_updated_cb(loader, 0, 0, width, height, lt->data);
+ area_updated_cb(nullptr, 0, 0, width, height, data);
}
TIFFClose(tiff);
}
-gpointer image_loader_tiff_new(ImageLoaderBackendCbAreaUpdated area_updated_cb, ImageLoaderBackendCbSize size_cb, ImageLoaderBackendCbAreaPrepared area_prepared_cb, gpointer data)
+void ImageLoaderTiff::init(AreaUpdatedCb area_updated_cb, SizePreparedCb size_prepared_cb, AreaPreparedCb area_prepared_cb, gpointer data)
{
- auto loader = g_new0(ImageLoaderTiff, 1);
-
- loader->area_updated_cb = area_updated_cb;
- loader->size_cb = size_cb;
- loader->area_prepared_cb = area_prepared_cb;
- loader->data = data;
- return loader;
+ this->area_updated_cb = area_updated_cb;
+ this->size_prepared_cb = size_prepared_cb;
+ this->area_prepared_cb = area_prepared_cb;
+ this->data = data;
}
-
-void image_loader_tiff_set_size(gpointer loader, int width, int height)
+void ImageLoaderTiff::set_size(int width, int height)
{
- auto lt = static_cast<ImageLoaderTiff *>(loader);
- lt->requested_width = width;
- lt->requested_height = height;
+ requested_width = width;
+ requested_height = height;
}
-GdkPixbuf* image_loader_tiff_get_pixbuf(gpointer loader)
+GdkPixbuf *ImageLoaderTiff::get_pixbuf()
{
- auto lt = static_cast<ImageLoaderTiff *>(loader);
- return lt->pixbuf;
+ return pixbuf;
}
-gchar* image_loader_tiff_get_format_name(gpointer)
+gchar *ImageLoaderTiff::get_format_name()
{
return g_strdup("tiff");
}
-gchar** image_loader_tiff_get_format_mime_types(gpointer)
+gchar **ImageLoaderTiff::get_format_mime_types()
{
static const gchar *mime[] = {"image/tiff", nullptr};
return g_strdupv(const_cast<gchar **>(mime));
}
-gboolean image_loader_tiff_close(gpointer, GError **)
+void ImageLoaderTiff::abort()
{
- return TRUE;
+ aborted = TRUE;
}
-void image_loader_tiff_abort(gpointer loader)
+ImageLoaderTiff::~ImageLoaderTiff()
{
- auto lt = static_cast<ImageLoaderTiff *>(loader);
- lt->abort = TRUE;
+ if (pixbuf) g_object_unref(pixbuf);
}
-void image_loader_tiff_free(gpointer loader)
+void ImageLoaderTiff::set_page_num(gint page_num)
{
- auto lt = static_cast<ImageLoaderTiff *>(loader);
- if (lt->pixbuf) g_object_unref(lt->pixbuf);
- g_free(lt);
+ this->page_num = page_num;
}
-void image_loader_tiff_set_page_num(gpointer loader, gint page_num)
+gint ImageLoaderTiff::get_page_total()
{
- auto lt = static_cast<ImageLoaderTiff *>(loader);
-
- lt->page_num = page_num;
-}
-
-gint image_loader_tiff_get_page_total(gpointer loader)
-{
- auto lt = static_cast<ImageLoaderTiff *>(loader);
-
- return lt->page_total;
+ return page_total;
}
} // namespace
-void image_loader_backend_set_tiff(ImageLoaderBackend *funcs)
+std::unique_ptr<ImageLoaderBackend> get_image_loader_backend_tiff()
{
- funcs->loader_new = image_loader_tiff_new;
- funcs->set_size = image_loader_tiff_set_size;
- funcs->write = image_loader_tiff_write;
- funcs->get_pixbuf = image_loader_tiff_get_pixbuf;
- funcs->close = image_loader_tiff_close;
- funcs->abort = image_loader_tiff_abort;
- funcs->free = image_loader_tiff_free;
-
- funcs->get_format_name = image_loader_tiff_get_format_name;
- funcs->get_format_mime_types = image_loader_tiff_get_format_mime_types;
-
- funcs->set_page_num = image_loader_tiff_set_page_num;
- funcs->get_page_total = image_loader_tiff_get_page_total;
+ return std::make_unique<ImageLoaderTiff>();
}
#endif