* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "main.h"
-
-#include "image-load.h"
#include "image-load-j2k.h"
+#include <cstdlib>
+#include <cstring>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <glib-object.h>
+#include <glib.h>
+#include <openjpeg.h>
+
+#include "debug.h"
+#include "image-load.h"
+#include "intl.h"
#include "misc.h"
-#ifdef HAVE_J2K
+namespace
+{
+
+struct ImageLoaderJ2K : public ImageLoaderBackend
+{
+public:
+ ~ImageLoaderJ2K() override;
-#include "openjpeg.h"
+ void init(AreaUpdatedCb area_updated_cb, SizePreparedCb size_prepared_cb, AreaPreparedCb area_prepared_cb, gpointer data) override;
+ gboolean write(const guchar *buf, gsize &chunk_size, gsize count, GError **error) override;
+ GdkPixbuf *get_pixbuf() override;
+ gchar *get_format_name() override;
+ gchar **get_format_mime_types() override;
-struct ImageLoaderJ2K {
- ImageLoaderBackendCbAreaUpdated area_updated_cb;
- ImageLoaderBackendCbSize size_cb;
- ImageLoaderBackendCbAreaPrepared area_prepared_cb;
+private:
+ AreaUpdatedCb area_updated_cb;
gpointer data;
+
GdkPixbuf *pixbuf;
- guint requested_width;
- guint requested_height;
- gboolean abort;
};
-static void free_buffer(guchar *pixels, gpointer UNUSED(data))
+void free_buffer(guchar *pixels, gpointer)
{
g_free (pixels);
}
-struct opj_buffer_info {
- OPJ_BYTE* buf;
- OPJ_BYTE* cur;
- OPJ_SIZE_T len;
+struct opj_buffer_info_t {
+ OPJ_BYTE* buf;
+ OPJ_BYTE* cur;
+ OPJ_SIZE_T len;
};
-static OPJ_SIZE_T opj_read_from_buffer (void* pdst, OPJ_SIZE_T len, opj_buffer_info_t* psrc)
+OPJ_SIZE_T opj_read_from_buffer (void* pdst, OPJ_SIZE_T len, opj_buffer_info_t* psrc)
{
- OPJ_SIZE_T n = psrc->buf + psrc->len - psrc->cur;
+ OPJ_SIZE_T n = psrc->buf + psrc->len - psrc->cur;
- if (n) {
- if (n > len)
- n = len;
+ if (n)
+ {
+ if (n > len)
+ n = len;
- memcpy (pdst, psrc->cur, n);
- psrc->cur += n;
- }
- else
- n = (OPJ_SIZE_T)-1;
+ memcpy (pdst, psrc->cur, n);
+ psrc->cur += n;
+ }
+ else
+ n = static_cast<OPJ_SIZE_T>(-1);
- return n;
+ return n;
}
-static OPJ_SIZE_T opj_write_to_buffer (void* p_buffer, OPJ_SIZE_T p_nb_bytes,
+OPJ_SIZE_T opj_write_to_buffer (void* p_buffer, OPJ_SIZE_T p_nb_bytes,
opj_buffer_info_t* p_source_buffer)
{
- void* pbuf = p_source_buffer->buf;
- void* pcur = p_source_buffer->cur;
+ void* pbuf = p_source_buffer->buf;
+ void* pcur = p_source_buffer->cur;
- OPJ_SIZE_T len = p_source_buffer->len;
+ OPJ_SIZE_T len = p_source_buffer->len;
- if (0 == len)
- len = 1;
+ if (0 == len)
+ len = 1;
- OPJ_SIZE_T dist = (guchar *)pcur - (guchar *)pbuf, n = len - dist;
- g_assert (dist <= len);
+ OPJ_SIZE_T dist = static_cast<guchar *>(pcur) - static_cast<guchar *>(pbuf);
+ OPJ_SIZE_T n = len - dist;
+ g_assert (dist <= len);
- while (n < p_nb_bytes) {
- len *= 2;
- n = len - dist;
- }
+ while (n < p_nb_bytes)
+ {
+ len *= 2;
+ n = len - dist;
+ }
- if (len != p_source_buffer->len) {
- pbuf = malloc (len);
+ if (len != p_source_buffer->len)
+ {
+ pbuf = malloc (len);
- if (0 == pbuf)
- return (OPJ_SIZE_T)-1;
+ if (nullptr == pbuf)
+ return static_cast<OPJ_SIZE_T>(-1);
- if (p_source_buffer->buf) {
- memcpy (pbuf, p_source_buffer->buf, dist);
- free (p_source_buffer->buf);
- }
+ if (p_source_buffer->buf)
+ {
+ memcpy (pbuf, p_source_buffer->buf, dist);
+ free (p_source_buffer->buf);
+ }
- p_source_buffer->buf = static_cast<OPJ_BYTE *>(pbuf);
- p_source_buffer->cur = (guchar *)pbuf + dist;
- p_source_buffer->len = len;
- }
+ p_source_buffer->buf = static_cast<OPJ_BYTE *>(pbuf);
+ p_source_buffer->cur = static_cast<guchar *>(pbuf) + dist;
+ p_source_buffer->len = len;
+ }
- memcpy (p_source_buffer->cur, p_buffer, p_nb_bytes);
- p_source_buffer->cur += p_nb_bytes;
+ memcpy (p_source_buffer->cur, p_buffer, p_nb_bytes);
+ p_source_buffer->cur += p_nb_bytes;
- return p_nb_bytes;
+ return p_nb_bytes;
}
-static OPJ_SIZE_T opj_skip_from_buffer (OPJ_SIZE_T len, opj_buffer_info_t* psrc)
+OPJ_SIZE_T opj_skip_from_buffer (OPJ_SIZE_T len, opj_buffer_info_t* psrc)
{
- OPJ_SIZE_T n = psrc->buf + psrc->len - psrc->cur;
+ OPJ_SIZE_T n = psrc->buf + psrc->len - psrc->cur;
- if (n) {
- if (n > len)
- n = len;
+ if (n)
+ {
+ if (n > len)
+ n = len;
- psrc->cur += len;
- }
- else
- n = (OPJ_SIZE_T)-1;
+ psrc->cur += len;
+ }
+ else
+ n = static_cast<OPJ_SIZE_T>(-1);
- return n;
+ return n;
}
-static OPJ_BOOL opj_seek_from_buffer (OPJ_OFF_T len, opj_buffer_info_t* psrc)
+OPJ_BOOL opj_seek_from_buffer (OPJ_OFF_T len, opj_buffer_info_t* psrc)
{
- OPJ_SIZE_T n = psrc->len;
+ OPJ_SIZE_T n = psrc->len;
- if (n > (gulong)len)
- n = len;
+ if (n > static_cast<gulong>(len))
+ n = len;
- psrc->cur = psrc->buf + n;
+ psrc->cur = psrc->buf + n;
- return OPJ_TRUE;
+ return OPJ_TRUE;
}
opj_stream_t* OPJ_CALLCONV opj_stream_create_buffer_stream (opj_buffer_info_t* psrc, OPJ_BOOL input)
{
- if (!psrc)
- return 0;
+ if (!psrc)
+ return nullptr;
- opj_stream_t* ps = opj_stream_default_create (input);
+ opj_stream_t* ps = opj_stream_default_create (input);
- if (0 == ps)
- return 0;
+ if (nullptr == ps)
+ return nullptr;
- opj_stream_set_user_data (ps, psrc, 0);
- opj_stream_set_user_data_length (ps, psrc->len);
+ opj_stream_set_user_data (ps, psrc, nullptr);
+ opj_stream_set_user_data_length (ps, psrc->len);
- if (input)
- opj_stream_set_read_function (
- ps, (opj_stream_read_fn)opj_read_from_buffer);
- else
- opj_stream_set_write_function(
- ps,(opj_stream_write_fn) opj_write_to_buffer);
+ if (input)
+ opj_stream_set_read_function (
+ ps, reinterpret_cast<opj_stream_read_fn>(opj_read_from_buffer));
+ else
+ opj_stream_set_write_function(
+ ps,reinterpret_cast<opj_stream_write_fn>(opj_write_to_buffer));
- opj_stream_set_skip_function (
- ps, (opj_stream_skip_fn)opj_skip_from_buffer);
+ opj_stream_set_skip_function (
+ ps, reinterpret_cast<opj_stream_skip_fn>(opj_skip_from_buffer));
- opj_stream_set_seek_function (
- ps, (opj_stream_seek_fn)opj_seek_from_buffer);
+ opj_stream_set_seek_function (
+ ps, reinterpret_cast<opj_stream_seek_fn>(opj_seek_from_buffer));
- return ps;
+ return ps;
}
-static gboolean image_loader_j2k_load(gpointer loader, const guchar *buf, gsize count, GError **UNUSED(error))
+gboolean ImageLoaderJ2K::write(const guchar *buf, gsize &chunk_size, gsize count, GError **)
{
- ImageLoaderJ2K *ld = (ImageLoaderJ2K *) loader;
opj_stream_t *stream;
opj_codec_t *codec;
opj_dparameters_t parameters;
gint width;
gint height;
gint num_components;
- gint i, j, k;
+ gint i;
+ gint j;
+ gint k;
guchar *pixels;
gint bytes_per_pixel;
opj_buffer_info_t *decode_buffer;
guchar *buf_copy;
- stream = NULL;
- codec = NULL;
- image = NULL;
+ stream = nullptr;
+ codec = nullptr;
+ image = nullptr;
- buf_copy = (guchar *) g_malloc(count);
+ buf_copy = static_cast<guchar *>(g_malloc(count));
memcpy(buf_copy, buf, count);
decode_buffer = g_new0(opj_buffer_info_t, 1);
}
}
- ld->pixbuf = gdk_pixbuf_new_from_data(pixels, GDK_COLORSPACE_RGB, FALSE , 8, width, height, width * bytes_per_pixel, free_buffer, NULL);
+ pixbuf = gdk_pixbuf_new_from_data(pixels, GDK_COLORSPACE_RGB, FALSE , 8, width, height, width * bytes_per_pixel, free_buffer, nullptr);
- ld->area_updated_cb(loader, 0, 0, width, height, ld->data);
+ area_updated_cb(nullptr, 0, 0, width, height, data);
g_free(decode_buffer);
g_free(buf_copy);
if (stream)
opj_stream_destroy (stream);
+ chunk_size = count;
return TRUE;
}
-static gpointer image_loader_j2k_new(ImageLoaderBackendCbAreaUpdated area_updated_cb, ImageLoaderBackendCbSize size_cb, ImageLoaderBackendCbAreaPrepared area_prepared_cb, gpointer data)
+void ImageLoaderJ2K::init(AreaUpdatedCb area_updated_cb, SizePreparedCb, AreaPreparedCb, gpointer data)
{
- ImageLoaderJ2K *loader = g_new0(ImageLoaderJ2K, 1);
- loader->area_updated_cb = area_updated_cb;
- loader->size_cb = size_cb;
- loader->area_prepared_cb = area_prepared_cb;
- loader->data = data;
- return (gpointer) loader;
+ this->area_updated_cb = area_updated_cb;
+ this->data = data;
}
-static void image_loader_j2k_set_size(gpointer loader, int width, int height)
+GdkPixbuf *ImageLoaderJ2K::get_pixbuf()
{
- ImageLoaderJ2K *ld = (ImageLoaderJ2K *) loader;
- ld->requested_width = width;
- ld->requested_height = height;
+ return pixbuf;
}
-static GdkPixbuf* image_loader_j2k_get_pixbuf(gpointer loader)
-{
- ImageLoaderJ2K *ld = (ImageLoaderJ2K *) loader;
- return ld->pixbuf;
-}
-
-static gchar* image_loader_j2k_get_format_name(gpointer UNUSED(loader))
+gchar *ImageLoaderJ2K::get_format_name()
{
return g_strdup("j2k");
}
-static gchar** image_loader_j2k_get_format_mime_types(gpointer UNUSED(loader))
+gchar **ImageLoaderJ2K::get_format_mime_types()
{
- static const gchar *mime[] = {"image/jp2", NULL};
+ static const gchar *mime[] = {"image/jp2", nullptr};
return g_strdupv(const_cast<gchar **>(mime));
}
-static gboolean image_loader_j2k_close(gpointer UNUSED(loader), GError **UNUSED(error))
+ImageLoaderJ2K::~ImageLoaderJ2K()
{
- return TRUE;
+ if (pixbuf) g_object_unref(pixbuf);
}
-static void image_loader_j2k_abort(gpointer loader)
-{
- ImageLoaderJ2K *ld = (ImageLoaderJ2K *) loader;
- ld->abort = TRUE;
-}
-
-static void image_loader_j2k_free(gpointer loader)
-{
- ImageLoaderJ2K *ld = (ImageLoaderJ2K *) loader;
- if (ld->pixbuf) g_object_unref(ld->pixbuf);
- g_free(ld);
-}
+} // namespace
-void image_loader_backend_set_j2k(ImageLoaderBackend *funcs)
+std::unique_ptr<ImageLoaderBackend> get_image_loader_backend_j2k()
{
- funcs->loader_new = image_loader_j2k_new;
- funcs->set_size = image_loader_j2k_set_size;
- funcs->load = image_loader_j2k_load;
- funcs->write = NULL;
- funcs->get_pixbuf = image_loader_j2k_get_pixbuf;
- funcs->close = image_loader_j2k_close;
- funcs->abort = image_loader_j2k_abort;
- funcs->free = image_loader_j2k_free;
- funcs->get_format_name = image_loader_j2k_get_format_name;
- funcs->get_format_mime_types = image_loader_j2k_get_format_mime_types;
+ return std::make_unique<ImageLoaderJ2K>();
}
-#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */