1 // colourspace.h 2 // LiVES 3 // (c) G. Finch 2004 - 2020 <salsaman+lives@gmail.com> 4 // Released under the GPL 3 or later 5 // see file ../COPYING for licensing details 6 7 // headers for palette conversions 8 9 #ifndef HAS_LIVES_COLOURSPACE_H 10 #define HAS_LIVES_COLOURSPACE_H 11 12 #ifdef USE_16BIT_PCONV 13 #define USE_EXTEND 14 #endif 15 16 //#define WEED_ADVANCED_PALETTES 17 18 #define WEED_LEAF_CLIP "clip" 19 #define WEED_LEAF_FRAME "frame" 20 #define WEED_LEAF_HOST_PIXEL_DATA_CONTIGUOUS "host_contiguous" 21 #define WEED_LEAF_HOST_PIXBUF_SRC "host_pixbuf_src" 22 #define WEED_LEAF_HOST_SURFACE_SRC "host_surface_src" 23 #define WEED_LEAF_PIXEL_BITS "pixel_bits" 24 #define WEED_LEAF_HOST_FLAGS "host_flags" 25 #define WEED_LEAF_RESIZE_THREAD "res_thread" 26 #define WEED_LEAF_PROGSCAN "progscan" 27 28 #define DEF_SCREEN_GAMMA 1.4 // extra gammm boost 29 30 /// rowstride alignment values 31 #define ALIGN_MIN 4 32 #define ALIGN_DEF 16 33 34 // rgb / yuv conversion factors //////////// 35 #define FP_BITS 16 /// max fp bits 36 37 #ifdef USE_EXTEND 38 #define SCALE_FACTOR 65793. /// (2 ^ 24 - 1) / (2 ^ 8 - 1), also 0xFF * SCALE_FACTOR = 0xFFFFFF 39 #else 40 #define SCALE_FACTOR (1 << FP_BITS) 41 #endif 42 43 #define KR_YCBCR 0.2989 44 #define KB_YCBCR 0.114 45 46 #define KR_I240 0.212 47 #define KB_I240 0.087 48 49 #define KR_BT709 0.2126 50 #define KB_BT709 0.0722 51 52 #define KR_BT2020 0.2627 53 #define KB_BT2020 0.0593 54 55 #define YUV_CLAMP_MIN 16. 56 #define YUV_CLAMP_MINI 16 57 58 #define Y_CLAMP_MAX 235. 59 #define Y_CLAMP_MAXI 235 60 61 #define UV_CLAMP_MAX 240. 62 #define UV_CLAMP_MAXI 240 63 64 #define CLAMP_FACTOR_Y ((Y_CLAMP_MAX-YUV_CLAMP_MIN)/255.) // unclamped -> clamped 65 #define CLAMP_FACTOR_UV ((UV_CLAMP_MAX-YUV_CLAMP_MIN)/255.) // unclamped -> clamped 66 67 #define UV_BIAS 128. 68 69 #define MAX_THREADS 65536 70 71 typedef weed_plant_t weed_layer_t; 72 73 ///////////////////////////////////////////// 74 75 typedef struct { 76 float offs, lin, thresh, pf; 77 } gamma_const_t; 78 79 typedef struct { 80 uint8_t u0; 81 uint8_t y0; 82 uint8_t v0; 83 uint8_t y1; 84 } uyvy_macropixel; 85 86 typedef struct { 87 uint8_t y0; 88 uint8_t u0; 89 uint8_t y1; 90 uint8_t v0; 91 } yuyv_macropixel; 92 93 typedef struct { 94 uint8_t u2; 95 uint8_t y0; 96 uint8_t y1; 97 uint8_t v2; 98 uint8_t y2; 99 uint8_t y3; 100 } yuv411_macropixel; 101 102 typedef struct { 103 void *src; 104 void *srcp[4]; 105 size_t hsize; 106 size_t vsize; 107 boolean is_bottom; 108 size_t psize; 109 size_t xoffset; 110 int irowstrides[4]; 111 int orowstrides[4]; 112 void *dest; 113 void *destp[4]; 114 boolean in_alpha; 115 boolean out_alpha; 116 boolean in_clamping; 117 boolean out_clamping; 118 int in_subspace; 119 int out_subspace; 120 int in_sampling; 121 int out_sampling; 122 boolean alpha_first; 123 boolean is_422; 124 void *lut; 125 int thread_id; 126 } lives_cc_params; 127 128 #ifdef USE_SWSCALE 129 #include <libswscale/swscale.h> 130 131 typedef struct { 132 weed_layer_t *layer; 133 int thread_id; 134 int iheight; 135 int width; 136 double file_gamma; 137 struct SwsContext *swscale; 138 const uint8_t *ipd[4]; 139 const uint8_t *opd[4]; 140 const int *irw; 141 const int *orw; 142 int ret; 143 } lives_sw_params; 144 145 #endif 146 147 void rgb2hsv(uint8_t r, uint8_t g, uint8_t b, double *h, double *s, double *v); 148 void hsv2rgb(double h, double s, double v, uint8_t *r, uint8_t *g, uint8_t *b); 149 boolean pick_nice_colour(uint8_t r0, uint8_t g0, uint8_t b0, uint8_t *r1, uint8_t *g1, uint8_t *b1, 150 double max, double lmin, double lmax); 151 152 double cdist94(uint8_t r0, uint8_t g0, uint8_t b0, uint8_t r1, uint8_t g1, uint8_t b1); 153 154 #ifdef WEED_ADVANCED_PALETTES 155 #define LIVES_VCHAN_grey 2048 156 #define LIVES_VCHAN_mono_b 2049 157 #define LIVES_VCHAN_mono_w 2050 158 159 #define LIVES_VCHAN_cc 3000 160 #define LIVES_VCHAN_mm 3001 161 #define LIVES_VCHAN_yy 3002 162 #define LIVES_VCHAN_kk 3003 163 164 #define LIVES_VCHAN_xxx 4000 165 #define LIVES_VCHAN_yyy 4001 166 #define LIVES_VCHAN_zzz 4002 167 168 #define LIVES_VCHAN_hh 4000 169 #define LIVES_VCHAN_ss 4001 170 #define LIVES_VCHAN_vv 4002 171 172 /// for fun / testing 173 #define LIVES_PALETTE_ABGR32 6 174 #define LIVES_PALETTE_YUV121010 8211 175 #define LIVES_PALETTE_RGB48 9001 176 #define LIVES_PALETTE_RGBA64 9003 177 #define LIVES_PALETTE_YUVA420P 9512 178 #define LIVES_PALETTE_YVU422P 9522 179 #define LIVES_PALETTE_AYUV8888 9545 180 #define LIVES_PALETTE_YUVFLOAT 9564 181 #define LIVES_PALETTE_YUVAFLOAT 9565 182 183 const weed_macropixel_t *get_advanced_palette(int weed_palette); 184 boolean weed_palette_is_valid(int pal); 185 int get_simple_palette(weed_macropixel_t *mpx); 186 size_t pixel_size(int pal); 187 int weed_palette_get_pixels_per_macropixel(int pal); 188 int weed_palette_get_bits_per_macropixel(int pal); 189 int weed_palette_get_nplanes(int pal); 190 boolean weed_palette_is_rgb(int pal); 191 boolean weed_palette_is_yuv(int pal); 192 boolean weed_palette_is_alpha(int pal); 193 boolean weed_palette_has_alpha(int pal); 194 boolean weed_palette_is_float(int pal); 195 double weed_palette_get_plane_ratio_horizontal(int pal, int plane); 196 double weed_palette_get_plane_ratio_vertical(int pal, int plane); 197 198 int weed_palette_get_alpha_plane(int pal); 199 int weed_palette_get_alpha_offset(int pal); 200 boolean weed_palette_red_first(int pal); 201 boolean weed_palettes_rbswapped(int pal0, int pal1); 202 boolean weed_palette_has_alpha_first(int pal); 203 boolean weed_palette_has_alpha_last(int pal); 204 #endif 205 206 int32_t round_special(int32_t val); 207 208 void init_conversions(int intent); 209 210 void init_colour_engine(void); 211 212 double get_luma8(uint8_t r, uint8_t g, uint8_t b); 213 double get_luma16(uint16_t r, uint16_t g, uint16_t b); 214 215 /////////////////////////////////////// LAYERS /////////////////////////////////////// 216 217 #define WEED_PLANT_LAYER 128 218 219 #define WEED_LEAF_LAYER_TYPE "layer_type" 220 #define WEED_LAYER_TYPE_NONE 0 221 #define WEED_LAYER_TYPE_VIDEO 1 222 #define WEED_LAYER_TYPE_AUDIO 2 223 224 #define WEED_IS_LAYER(plant) (weed_plant_get_type(plant) == WEED_PLANT_LAYER) 225 226 // create / destroy / copy layers 227 weed_layer_t *weed_layer_new(int layer_type); 228 weed_layer_t *create_blank_layer(weed_layer_t *, const char *image_ext, int width, int height, int target_palette); 229 weed_layer_t *weed_layer_create(int width, int height, int *rowstrides, int current_palette); 230 weed_layer_t *weed_layer_create_full(int width, int height, int *rowstrides, int current_palette, 231 int YUV_clamping, int YUV_sampling, int YUV_subspace, int gamma_type); 232 weed_layer_t *weed_layer_copy(weed_layer_t *dlayer, weed_layer_t *slayer); 233 weed_layer_t *weed_layer_free(weed_layer_t *); 234 int weed_layer_unref(weed_layer_t *); 235 int weed_layer_ref(weed_layer_t *); 236 237 // lives specific 238 weed_layer_t *lives_layer_new_for_frame(int clip, frames_t frame); 239 240 void lives_layer_set_clip(weed_layer_t *, int clip); 241 void lives_layer_set_frame(weed_layer_t *, frames_t frame); 242 243 int lives_layer_get_clip(weed_layer_t *); 244 frames_t lives_layer_get_frame(weed_layer_t *); 245 246 // pixel_data 247 /// layer should be pre-set with palette, width in MACROPIXELS, and height 248 /// gamma_type will be set WEED_GAMMA_SRGB, old pixel_data will not be freed. 249 boolean create_empty_pixel_data(weed_layer_t *, boolean black_fill, boolean may_contig); 250 void pixel_data_planar_from_membuf(void **pixel_data, void *data, size_t size, int palette, boolean dest_contig); 251 void weed_layer_pixel_data_free(weed_layer_t *); 252 253 #define WEED_GAMMA_MONITOR 1024 254 #define WEED_GAMMA_FILE 1025 255 #define WEED_GAMMA_VARIANT 2048 256 #define WEED_LAYER_ALPHA_PREMULT 1 257 258 /// private flags 259 #define LIVES_LAYER_LOAD_IF_NEEDS_RESIZE 1 260 #define LIVES_LAYER_GET_SIZE_ONLY 2 261 262 // private flags bitfield 263 #define LIVES_LAYER_HAS_SIZE_NOW (1 << 16) 264 265 // layer transformation functions 266 void alpha_unpremult(weed_layer_t *, boolean un); 267 boolean copy_pixel_data(weed_layer_t *dst, weed_layer_t *src_or_null, size_t alignment); 268 boolean gamma_convert_layer(int gamma_type, weed_layer_t *); 269 boolean gamma_convert_layer_variant(double file_gamma, int tgamma, weed_layer_t *); 270 boolean gamma_convert_sub_layer(int gamma_type, double fileg, weed_layer_t *, int x, int y, 271 int width, int height, boolean may_thread); 272 boolean convert_layer_palette(weed_layer_t *, int outpl, int op_clamping); 273 boolean convert_layer_palette_with_sampling(weed_layer_t *, int outpl, int out_sampling); 274 boolean convert_layer_palette_full(weed_layer_t *, int outpl, int oclamping, int osampling, int osubspace, int tgamma); 275 void lives_layer_set_opaque(weed_layer_t *); 276 boolean consider_swapping(int *inpal, int *outpal); 277 278 /// widths in PIXELS 279 boolean resize_layer(weed_layer_t *, int width, int height, LiVESInterpType interp, int opal_hint, int oclamp_hint); 280 boolean letterbox_layer(weed_layer_t *, int nwidth, int nheight, int width, int height, LiVESInterpType interp, int tpal, 281 int tclamp); 282 boolean compact_rowstrides(weed_layer_t *); 283 284 void gamma_conv_params(int gamma_type, weed_layer_t *inst, boolean is_in); 285 286 // palette information functions 287 boolean weed_palette_is_lower_quality(int p1, int p2); 288 boolean rowstrides_differ(int n1, int *n1_array, int n2, int *n2_array); 289 290 // lives_painter (cairo) functions 291 boolean weed_palette_is_painter_palette(int pal); 292 lives_painter_t *layer_to_lives_painter(weed_layer_t *); 293 boolean lives_painter_to_layer(lives_painter_t *cairo, weed_layer_t *); 294 295 // pixbuf functions 296 #define weed_palette_is_pixbuf_palette(pal) ((pal == WEED_PALETTE_RGB24 || pal == WEED_PALETTE_RGBA32) ? TRUE : FALSE) 297 boolean lives_pixbuf_is_all_black(LiVESPixbuf *pixbuf); 298 void lives_pixbuf_set_opaque(LiVESPixbuf *pixbuf); 299 300 LiVESPixbuf *layer_to_pixbuf(weed_layer_t *, boolean realpalette, boolean fordisp); 301 boolean pixbuf_to_layer(weed_layer_t *, LiVESPixbuf *) WARN_UNUSED; 302 303 // layer info 304 int weed_layer_is_video(weed_layer_t *); 305 int weed_layer_is_audio(weed_layer_t *); 306 int weed_layer_get_palette(weed_layer_t *); 307 int weed_layer_get_palette_yuv(weed_layer_t *, int *clamping, int *sampling, int *subspace); 308 int weed_layer_get_yuv_clamping(weed_layer_t *); 309 int weed_layer_get_yuv_sampling(weed_layer_t *); 310 int weed_layer_get_yuv_subspace(weed_layer_t *); 311 uint8_t *weed_layer_get_pixel_data_packed(weed_layer_t *); 312 void **weed_layer_get_pixel_data(weed_layer_t *, int *nplanes); 313 float **weed_layer_get_audio_data(weed_layer_t *, int *naudchans); 314 int weed_layer_get_audio_rate(weed_layer_t *layer); 315 int weed_layer_get_naudchans(weed_layer_t *layer); 316 int weed_layer_get_audio_length(weed_layer_t *layer); 317 int *weed_layer_get_rowstrides(weed_layer_t *, int *nplanes); 318 int weed_layer_get_rowstride(weed_layer_t *); ///< for packed palettes 319 int weed_layer_get_width(weed_layer_t *); 320 int weed_layer_get_width_pixels(weed_layer_t *); 321 int weed_layer_get_height(weed_layer_t *); 322 int weed_layer_get_palette(weed_layer_t *); 323 int weed_layer_get_gamma(weed_layer_t *); 324 int weed_layer_get_flags(weed_layer_t *); 325 326 // weed_layer_get_rowstride 327 328 /// functions all return the input layer for convenience; no checking for valid values is done 329 /// if layer is NULL or not weed_layer then NULL is returned 330 weed_layer_t *weed_layer_set_palette(weed_layer_t *, int palette); 331 weed_layer_t *weed_layer_set_palette_yuv(weed_layer_t *, int palette, int clamping, int sampling, int subspace); 332 weed_layer_t *weed_layer_set_yuv_clamping(weed_layer_t *, int clamping); 333 weed_layer_t *weed_layer_set_yuv_sampling(weed_layer_t *, int sampling); 334 weed_layer_t *weed_layer_set_yuv_subspace(weed_layer_t *, int subspace); 335 weed_layer_t *weed_layer_set_gamma(weed_layer_t *, int gamma_type); 336 337 /// width in macropixels of the layer palette 338 weed_layer_t *weed_layer_set_width(weed_layer_t *, int width); 339 weed_layer_t *weed_layer_set_height(weed_layer_t *, int height); 340 weed_layer_t *weed_layer_set_size(weed_layer_t *, int width, int height); 341 weed_layer_t *weed_layer_set_rowstrides(weed_layer_t *, int *rowstrides, int nplanes); 342 weed_layer_t *weed_layer_set_rowstride(weed_layer_t *, int rowstride); 343 344 weed_layer_t *weed_layer_set_flags(weed_layer_t *, int flags); 345 346 weed_layer_t *weed_layer_set_pixel_data(weed_layer_t *, void **pixel_data, int nplanes); 347 weed_layer_t *weed_layer_set_pixel_data_packed(weed_layer_t *, void *pixel_data); 348 weed_layer_t *weed_layer_nullify_pixel_data(weed_layer_t *); 349 weed_layer_t *weed_layer_set_audio_data(weed_layer_t *, float **data, int arate, int naudchans, weed_size_t nsamps); 350 351 /// utility funcs for GUI 352 int resize_all(int fileno, int width, int height, lives_img_type_t imgtype, boolean do_back, int *nbad, int *nmiss); 353 354 #endif 355