1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
// SPDX-License-Identifier: MIT
// Image instance: pixel data and meta info.
// Copyright (C) 2021 Artem Senichev <artemsen@gmail.com>
#pragma once
#include "array.h"
#include "list.h"
#include "render.h"
// File name used for image, that is read from stdin through pipe
#define LDRSRC_STDIN "stdin://"
#define LDRSRC_STDIN_LEN (sizeof(LDRSRC_STDIN) - 1)
// Special prefix used to load images from external command output
#define LDRSRC_EXEC "exec://"
#define LDRSRC_EXEC_LEN (sizeof(LDRSRC_EXEC) - 1)
/** Image frame. */
struct imgframe {
struct pixmap pm; ///< Frame data
size_t duration; ///< Frame duration in milliseconds (animation)
};
/** Image meta info. */
struct imginfo {
char* key; ///< Key name
char* value; ///< Value
};
struct imgdata;
/** Decoder specific handlers. */
struct imgdec {
/**
* Custom rendering function.
* @param img image container
* @param scale scale of the image
* @param x,y destination left top coordinates
* @param dst destination pixmap
*/
void (*render)(struct imgdata* img, double scale, ssize_t x, ssize_t y,
struct pixmap* dst);
/**
* Custom flip function.
* @param img image container
* @param vertical set to true for vertical flip, otherwise horizontal
*/
void (*flip)(struct imgdata* img, bool vertical);
/**
* Custom rotate function.
* @param img image container
* @param angle rotation angle (only 90, 180, 270)
*/
void (*rotate)(struct imgdata* img, size_t angle);
/**
* Free decoder internal data.
* @param img image container
*/
void (*free)(struct imgdata* img);
/** Decoder internal data. */
void* data;
};
/** Image data container. */
struct imgdata {
char* parent; ///< Parent directory name
char* format; ///< Format description
struct array* frames; ///< Frames (RGBA pixmaps)
struct array* info; ///< Meta info
struct pixmap thumbnail; ///< Image thumbnail
struct imgdec decoder; ///< Decoder specific handlers
};
/** Image context. */
struct image {
struct list list; ///< Links to prev/next entry in the image list
char* source; ///< Image source (e.g. path to the image file)
const char* name; ///< Name of the image file
size_t index; ///< Index of the image
size_t file_size; ///< Size of the image file
time_t file_time; ///< File modification time
struct imgdata* data; ///< Image data container
};
/** Image loading status. */
enum image_status {
imgload_success, ///< Image was decoded successfully
imgload_unsupported, ///< Unsupported format
imgload_fmterror, ///< Invalid data format
imgload_unknown ///< Unknown errors
};
/** Thumbnail aspect ratio. */
enum thumb_aspect {
aspect_fit, ///< Fit image into a square thumbnail
aspect_fill, ///< Fill square thumbnail with the image
aspect_keep, ///< Adjust thumbnail size to the aspect ratio of the image
};
/** Image data types. */
#define IMGDATA_FRAMES (1 << 0)
#define IMGDATA_THUMB (1 << 1)
#define IMGDATA_INFO (1 << 2)
#define IMGDATA_ALL (IMGDATA_FRAMES | IMGDATA_THUMB | IMGDATA_INFO)
#define IMGDATA_SELF (1 << 3 | IMGDATA_ALL)
/**
* Get list of supported image formats.
* @return list of supported formats
*/
const char* image_formats(void);
/**
* Create empty image instance.
* @param source image source
* @return image context or NULL on errors
*/
struct image* image_create(const char* source);
/**
* Clear image data.
* @param img image context
* @param mask data type to clean (`IMGDATA_*`)
*/
bool image_clear(struct image* img, size_t mask);
/**
* Free image data.
* @param img image context
* @param mask data type to free (`IMGDATA_*`)
*/
void image_free(struct image* img, size_t mask);
/**
* Load image from specified source.
* @param img image context
* @return loading status
*/
enum image_status image_load(struct image* img);
/**
* Attach image data container (move from another instance).
* @param img target image instance
* @param from adopted image instance
*/
void image_attach(struct image* img, struct image* from);
/**
* Export image to a file.
* @param img image context
* @param frame frame index
* @param path path to write the file
* @return true if image has frame data
*/
bool image_export(const struct image* img, size_t frame, const char* path);
/**
* Render image.
* @param img image context
* @param frame frame index
* @param scaler scale filter to use
* @param scale scale of the image
* @param mt flag to use multithreaded rendering
* @param x,y destination left top coordinates
* @param dst destination pixmap
*/
void image_render(struct image* img, size_t frame, enum aa_mode scaler,
double scale, bool mt, ssize_t x, ssize_t y,
struct pixmap* dst);
/**
* Check if image has frame data.
* @param img image context
* @return true if image has frame data
*/
bool image_has_frames(const struct image* img);
/**
* Check if image has meta info data.
* @param img image context
* @return true if image has meta info
*/
bool image_has_info(const struct image* img);
/**
* Flip image vertically.
* @param img image context
*/
void image_flip_vertical(struct image* img);
/**
* Flip image horizontally.
* @param img image context
*/
void image_flip_horizontal(struct image* img);
/**
* Rotate image.
* @param img image context
* @param angle rotation angle (only 90, 180, or 270)
*/
void image_rotate(struct image* img, size_t angle);
/**
* Create thumbnail.
* @param img image context
* @param size thumbnail size in pixels
* @param aspect thumbnail aspect ratio (fit/fill/keep)
* @param aa_mode anti-aliasing mode
* @return true if thumbnail created
*/
bool image_thumb_create(struct image* img, size_t size,
enum thumb_aspect aspect, enum aa_mode aa_mode);
/**
* Load thumbnail from specified file.
* @param img image context
* @param path path to the thumbnail file to load
* @return true if thumbnail loaded
*/
bool image_thumb_load(struct image* img, const char* path);
/**
* Save thumbnail to specified file.
* @param img image context
* @param path path to the thumbnail file
* @return true if thumbnail saved
*/
bool image_thumb_save(const struct image* img, const char* path);
/**
* Get image thumbnail pixmap.
* @param img image context
* @return thumbnail pixmap or NULL if image doesn't have thumbnail
*/
const struct pixmap* image_thumb_get(const struct image* img);
/**
* Set image format description.
* @param img image data container
* @param fmt format description
*/
void image_set_format(struct imgdata* img, const char* fmt, ...)
__attribute__((format(printf, 2, 3)));
/**
* Add meta info property.
* @param img image data container
* @param key property name
* @param fmt value format
*/
void image_add_info(struct imgdata* img, const char* key, const char* fmt, ...)
__attribute__((format(printf, 3, 4)));
/**
* Create multiple empty frames.
* @param img image data container
* @param num total number of frames
* @return pointer to the frame array or NULL on errors
*/
struct array* image_alloc_frames(struct imgdata* img, size_t num);
/**
* Create single frame and allocate pixmap.
* @param img image data container
* @param format pixmap format
* @param width,height frame size in px
* @return pointer to the pixmap associated with the frame, or NULL on errors
*/
struct pixmap* image_alloc_frame(struct imgdata* img, enum pixmap_format format,
size_t width, size_t height);
|