-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpixel.h
More file actions
103 lines (93 loc) · 3.15 KB
/
Copy pathpixel.h
File metadata and controls
103 lines (93 loc) · 3.15 KB
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
/*
* pixel.h
* Map2Globe: Image to globe converter.
*
* Copyright (c) 2019-2023 Bryan Franklin. All rights reserved.
*/
#ifndef PIXEL_H
#define PIXEL_H
/* see: https://en.wikipedia.org/wiki/Inline_function#Nonstandard_extensions */
#ifdef _MSC_VER
#define forceinline __forceinline
#elif defined(__GNUC__)
#define forceinline inline __attribute__((__always_inline__))
#elif defined(__CLANG__)
#if __has_attribute(__always_inline__)
#define forceinline inline __attribute__((__always_inline__))
#else
#define forceinline inline
#endif
#else
#define forceinline inline
#endif
/* pixel with integer channel ranges from 0 to 255 */
typedef struct pixel
{
/* values 255*sqrt(linear value in [0:1]) */
/* see: https://youtu.be/LKnqECcg6Gw */
unsigned char r, g, b, a;
} pixel_t;
/* pixel with double channel ranges from 0 to 1 */
typedef struct dbl_pixel
{
/* values should be linear values in [0:1] */
double r, g, b, a;
} dbl_pixel_t;
#ifndef MIN
#define MIN(x,y) (((x)<(y))?(x):(y))
#endif /* MIN */
#ifndef MAX
#define MAX(x,y) (((x)>(y))?(x):(y))
#endif /* MAX */
#if 1
/* quadratic color model is what most software uses */
#define pixel_d2c(c,d) { (c).r = sqrt(MAX(0.0,MIN(1.0,(d).r)))*255; \
(c).g = sqrt(MAX(0.0,MIN(1.0,(d).g)))*255; \
(c).b = sqrt(MAX(0.0,MIN(1.0,(d).b)))*255; \
(c).a = sqrt(MAX(0.0,MIN(1.0,(d).a)))*255; }
#define pixel_c2d(d,c) { (d).r = pow((c).r/255.0,2.0); \
(d).g = pow((c).g/255.0,2.0); \
(d).b = pow((c).b/255.0,2.0); \
(d).a = pow((c).a/255.0,2.0); }
#else
/* use linear color model instead of quadratic */
#define pixel_d2c(c,d) { (c).r = MAX(0.0,MIN(1.0,(d).r))*255; \
(c).g = MAX(0.0,MIN(1.0,(d).g))*255; \
(c).b = MAX(0.0,MIN(1.0,(d).b))*255; \
(c).a = MAX(0.0,MIN(1.0,(d).a))*255; }
#define pixel_c2d(d,c) { (d).r = (c).r/255.0; \
(d).g = (c).g/255.0; \
(d).b = (c).b/255.0; \
(d).a = (c).a/255.0; }
#endif
static forceinline void pixel_add(pixel_t *res, pixel_t *a, pixel_t *b) {
res->r = a->r + b->r;
res->g = a->g + b->g;
res->b = a->b + b->b;
res->a = a->a + b->a;
}
static forceinline void pixel_scale(pixel_t *res, pixel_t *a, double scale) {
res->r = a->r * scale;
res->g = a->g * scale;
res->b = a->b * scale;
res->a = a->a * scale;
}
static forceinline void dbl_pixel_add(dbl_pixel_t *res, dbl_pixel_t *a, dbl_pixel_t *b) {
res->r = a->r + b->r;
res->g = a->g + b->g;
res->b = a->b + b->b;
res->a = a->a + b->a;
}
static forceinline void dbl_pixel_scale(dbl_pixel_t *res, dbl_pixel_t *a, double scale) {
res->r = a->r * scale;
res->g = a->g * scale;
res->b = a->b * scale;
res->a = a->a * scale;
}
static forceinline void dbl_pixel_channel_scale(dbl_pixel_t *res, dbl_pixel_t *a, dbl_pixel_t *scale) {
res->r = a->r * scale->r;
res->g = a->g * scale->g;
res->b = a->b * scale->b;
res->a = a->a * scale->a;
}
#endif /* PIXEL_H */