2021-11-01 04:40:58 +01:00
|
|
|
//
|
2021-12-18 06:38:30 +01:00
|
|
|
// fiv-io.h: image operations
|
2021-11-01 04:40:58 +01:00
|
|
|
//
|
2021-12-31 02:19:17 +01:00
|
|
|
// Copyright (c) 2021 - 2022, Přemysl Eric Janouch <p@janouch.name>
|
2021-11-01 04:40:58 +01:00
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
|
|
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
|
|
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
|
|
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
//
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cairo.h>
|
2021-11-21 16:03:54 +01:00
|
|
|
#include <gio/gio.h>
|
2021-12-18 06:38:30 +01:00
|
|
|
#include <glib.h>
|
2021-11-01 04:40:58 +01:00
|
|
|
|
2021-12-22 22:07:49 +01:00
|
|
|
// --- Colour management -------------------------------------------------------
|
|
|
|
|
|
|
|
// TODO(p): Make it possible to use Skia's skcms,
|
|
|
|
// which also supports premultiplied alpha.
|
2021-12-26 00:30:30 +01:00
|
|
|
// NOTE: Little CMS will probably start supporting premultiplied alpha in 2022.
|
2021-12-22 22:07:49 +01:00
|
|
|
typedef void *FivIoProfile;
|
|
|
|
FivIoProfile fiv_io_profile_new(const void *data, size_t len);
|
|
|
|
FivIoProfile fiv_io_profile_new_sRGB(void);
|
|
|
|
void fiv_io_profile_free(FivIoProfile self);
|
|
|
|
|
2021-12-28 19:58:14 +01:00
|
|
|
// From libwebp, verified to exactly match [x * a / 255].
|
|
|
|
#define PREMULTIPLY8(a, x) (((uint32_t) (x) * (uint32_t) (a) * 32897U) >> 23)
|
|
|
|
|
2021-12-22 22:07:49 +01:00
|
|
|
// --- Loading -----------------------------------------------------------------
|
|
|
|
|
2021-12-18 06:38:30 +01:00
|
|
|
extern const char *fiv_io_supported_media_types[];
|
2021-11-01 04:40:58 +01:00
|
|
|
|
2021-12-18 06:38:30 +01:00
|
|
|
char **fiv_io_all_supported_media_types(void);
|
2021-11-18 12:44:25 +01:00
|
|
|
|
2021-11-25 02:46:36 +01:00
|
|
|
// Userdata are typically attached to all Cairo surfaces in an animation.
|
|
|
|
|
2021-11-28 20:05:36 +01:00
|
|
|
/// GBytes with plain Exif/TIFF data.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_exif;
|
|
|
|
/// FivIoOrientation, as a uintptr_t.
|
|
|
|
extern cairo_user_data_key_t fiv_io_key_orientation;
|
2021-11-25 02:46:36 +01:00
|
|
|
/// GBytes with plain ICC profile data.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_icc;
|
2021-12-16 00:28:37 +01:00
|
|
|
/// GBytes with plain XMP data.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_xmp;
|
2021-12-28 19:37:15 +01:00
|
|
|
/// GBytes with a WebP's THUM chunk, used for our thumbnails.
|
|
|
|
extern cairo_user_data_key_t fiv_io_key_thum;
|
2021-11-25 02:46:36 +01:00
|
|
|
|
|
|
|
/// The next frame in a sequence, as a surface, in a chain, pre-composited.
|
|
|
|
/// There is no wrap-around.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_frame_next;
|
2021-11-26 20:54:08 +01:00
|
|
|
/// The previous frame in a sequence, as a surface, in a chain, pre-composited.
|
|
|
|
/// This is a weak pointer that wraps around, and needn't be present
|
|
|
|
/// for static images.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_frame_previous;
|
2021-11-25 02:46:36 +01:00
|
|
|
/// Frame duration in milliseconds as an intptr_t.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_frame_duration;
|
2021-11-26 00:46:00 +01:00
|
|
|
/// How many times to repeat the animation, or zero for +inf, as a uintptr_t.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_loops;
|
2021-11-25 02:46:36 +01:00
|
|
|
|
2021-11-27 02:49:26 +01:00
|
|
|
/// The first frame of the next page, as a surface, in a chain.
|
|
|
|
/// There is no wrap-around.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_page_next;
|
2021-11-27 02:49:26 +01:00
|
|
|
/// The first frame of the previous page, as a surface, in a chain.
|
|
|
|
/// There is no wrap-around. This is a weak pointer.
|
2021-12-18 06:38:30 +01:00
|
|
|
extern cairo_user_data_key_t fiv_io_key_page_previous;
|
2021-11-27 02:49:26 +01:00
|
|
|
|
2021-12-22 10:59:03 +01:00
|
|
|
cairo_surface_t *fiv_io_open(
|
2021-12-30 21:47:28 +01:00
|
|
|
const gchar *uri, FivIoProfile profile, gboolean enhance, GError **error);
|
2021-12-22 10:59:03 +01:00
|
|
|
cairo_surface_t *fiv_io_open_from_data(const char *data, size_t len,
|
2021-12-30 21:47:28 +01:00
|
|
|
const gchar *uri, FivIoProfile profile, gboolean enhance, GError **error);
|
2021-11-25 02:46:36 +01:00
|
|
|
|
2021-12-31 02:19:17 +01:00
|
|
|
// --- Filesystem --------------------------------------------------------------
|
|
|
|
|
|
|
|
#define FIV_TYPE_IO_MODEL (fiv_io_model_get_type())
|
|
|
|
G_DECLARE_FINAL_TYPE(FivIoModel, fiv_io_model, FIV, IO_MODEL, GObject)
|
|
|
|
|
|
|
|
/// Loads a directory. Clears itself even on failure.
|
|
|
|
gboolean fiv_io_model_open(FivIoModel *self, GFile *directory, GError **error);
|
|
|
|
|
|
|
|
/// Returns the current location as a GFile.
|
|
|
|
/// There is no ownership transfer, and the object may be NULL.
|
|
|
|
GFile *fiv_io_model_get_location(FivIoModel *self);
|
|
|
|
|
|
|
|
GPtrArray *fiv_io_model_get_files(FivIoModel *self);
|
|
|
|
GPtrArray *fiv_io_model_get_subdirectories(FivIoModel *self);
|
2021-11-25 02:46:36 +01:00
|
|
|
|
2021-12-14 05:03:55 +01:00
|
|
|
// --- Export ------------------------------------------------------------------
|
|
|
|
|
2021-12-28 18:51:00 +01:00
|
|
|
typedef struct WebPConfig WebPConfig;
|
|
|
|
|
|
|
|
/// Encodes a Cairo surface as a WebP bitstream, following the configuration.
|
|
|
|
/// The result needs to be freed using WebPFree/WebPDataClear().
|
|
|
|
unsigned char *fiv_io_encode_webp(
|
|
|
|
cairo_surface_t *surface, const WebPConfig *config, size_t *len);
|
|
|
|
|
2021-12-26 19:41:42 +01:00
|
|
|
/// Saves the page as a lossless WebP still picture or animation.
|
2021-12-14 05:03:55 +01:00
|
|
|
/// If no exact frame is specified, this potentially creates an animation.
|
2021-12-18 06:38:30 +01:00
|
|
|
gboolean fiv_io_save(cairo_surface_t *page, cairo_surface_t *frame,
|
2021-12-26 01:24:09 +01:00
|
|
|
FivIoProfile target, const gchar *path, GError **error);
|
2021-12-14 05:03:55 +01:00
|
|
|
|
2021-11-26 00:16:12 +01:00
|
|
|
// --- Metadata ----------------------------------------------------------------
|
|
|
|
|
|
|
|
// https://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf Table 6
|
2021-12-18 06:38:30 +01:00
|
|
|
typedef enum _FivIoOrientation {
|
|
|
|
FivIoOrientationUnknown = 0,
|
|
|
|
FivIoOrientation0 = 1,
|
|
|
|
FivIoOrientationMirror0 = 2,
|
|
|
|
FivIoOrientation180 = 3,
|
|
|
|
FivIoOrientationMirror180 = 4,
|
|
|
|
FivIoOrientationMirror270 = 5,
|
|
|
|
FivIoOrientation90 = 6,
|
|
|
|
FivIoOrientationMirror90 = 7,
|
|
|
|
FivIoOrientation270 = 8
|
|
|
|
} FivIoOrientation;
|
|
|
|
|
2021-12-28 23:10:45 +01:00
|
|
|
/// Returns whether dimensions need to be swapped for rendering.
|
|
|
|
gboolean fiv_io_orientation_is_sideways(FivIoOrientation orientation);
|
|
|
|
|
|
|
|
/// Returns a rendering matrix for a surface. Dimensions need to be pre-swapped.
|
|
|
|
cairo_matrix_t fiv_io_orientation_matrix(
|
|
|
|
FivIoOrientation orientation, double width, double height);
|
|
|
|
|
|
|
|
/// Extracts the orientation field from Exif, if there's any.
|
2021-12-18 06:38:30 +01:00
|
|
|
FivIoOrientation fiv_io_exif_orientation(const guint8 *exif, gsize len);
|
2021-11-26 00:16:12 +01:00
|
|
|
|
2021-12-14 05:03:55 +01:00
|
|
|
/// Save metadata attached by this module in Exiv2 format.
|
2021-12-18 06:38:30 +01:00
|
|
|
gboolean fiv_io_save_metadata(
|
2021-12-14 05:03:55 +01:00
|
|
|
cairo_surface_t *page, const gchar *path, GError **error);
|