Deduplicate rt_border_draw
[geeqie.git] / src / image-load-j2k.cc
index 79d3475..02199c9 100644 (file)
  * 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;
 
-typedef struct _ImageLoaderJ2K ImageLoaderJ2K;
-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);
 }
 
-typedef struct opj_buffer_info {
-    OPJ_BYTE* buf;
-    OPJ_BYTE* cur;
-    OPJ_SIZE_T len;
-} opj_buffer_info_t;
+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;
@@ -177,17 +195,19 @@ static gboolean image_loader_j2k_load(gpointer loader, const guchar *buf, gsize
        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);
@@ -264,9 +284,9 @@ static gboolean image_loader_j2k_load(gpointer loader, const guchar *buf, gsize
                        }
                }
 
-       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);
@@ -277,74 +297,42 @@ static gboolean image_loader_j2k_load(gpointer loader, const guchar *buf, gsize
        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)
-{
-       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;
-}
-
-static void image_loader_j2k_set_size(gpointer loader, int width, int height)
+void ImageLoaderJ2K::init(AreaUpdatedCb area_updated_cb, SizePreparedCb, AreaPreparedCb, gpointer data)
 {
-       ImageLoaderJ2K *ld = (ImageLoaderJ2K *) loader;
-       ld->requested_width = width;
-       ld->requested_height = height;
+       this->area_updated_cb = area_updated_cb;
+       this->data = data;
 }
 
-static GdkPixbuf* image_loader_j2k_get_pixbuf(gpointer loader)
+GdkPixbuf *ImageLoaderJ2K::get_pixbuf()
 {
-       ImageLoaderJ2K *ld = (ImageLoaderJ2K *) loader;
-       return ld->pixbuf;
+       return 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))
-{
-       return TRUE;
-}
-
-static void image_loader_j2k_abort(gpointer loader)
+ImageLoaderJ2K::~ImageLoaderJ2K()
 {
-       ImageLoaderJ2K *ld = (ImageLoaderJ2K *) loader;
-       ld->abort = TRUE;
+       if (pixbuf) g_object_unref(pixbuf);
 }
 
-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: */