libsstvenc
Asynchronous Analogue SSTV encoder
Loading...
Searching...
No Matches
yuv.c
Go to the documentation of this file.
1
6/*
7 * © Stuart Longland VK4MSL
8 * SPDX-License-Identifier: MIT
9 */
10
11#include <libsstvenc/yuv.h>
12#include <stddef.h>
13
14uint8_t sstvenc_yuv_calc_y(uint8_t r, uint8_t g, uint8_t b) {
15 return (16.0
16 + (.003906
17 * ((65.738 * (double)r) + (129.057 * (double)g)
18 + (25.064 * (double)b))))
19 + 0.5;
20}
21
22uint8_t sstvenc_yuv_calc_u(uint8_t r, uint8_t g, uint8_t b) {
23 return (128.0
24 + (.003906
25 * ((112.439 * (double)r) + (-94.154 * (double)g)
26 + (-18.285 * (double)b))))
27 + 0.5;
28}
29
30uint8_t sstvenc_yuv_calc_v(uint8_t r, uint8_t g, uint8_t b) {
31 return (128.0
32 + (.003906
33 * ((-37.945 * (double)r) + (-74.494 * (double)g)
34 + (112.439 * (double)b))))
35 + 0.5;
36}
37
38uint8_t sstvenc_rgb_calc_r(uint8_t y, uint8_t u, uint8_t v) {
39 return (0.003906
40 * ((298.082 * ((double)y - 16.0))
41 + (408.583 * ((double)u - 128.0))))
42 + 0.5;
43}
44
45uint8_t sstvenc_rgb_calc_g(uint8_t y, uint8_t u, uint8_t v) {
46 return (0.003906
47 * ((298.082 * ((double)y - 16.0))
48 + (-100.291 * ((double)v - 128.0))
49 + (-208.12 * ((double)u - 128.0))))
50 + 0.5;
51}
52
53uint8_t sstvenc_rgb_calc_b(uint8_t y, uint8_t u, uint8_t v) {
54 return (0.003906
55 * ((298.082 * ((double)y - 16.0))
56 + (516.411 * ((double)v - 128.0))))
57 + 0.5;
58}
59
60void sstvenc_rgb_to_mono(uint8_t* dest, const uint8_t* src, uint16_t width,
61 uint16_t height) {
62 size_t sz = (size_t)width * (size_t)height;
63 while (sz) {
64 /* Convert and write out YUV */
65 dest[0] = sstvenc_yuv_calc_y(src[0], src[1], src[2]);
66
67 dest += 1;
68 src += 3;
69 sz--;
70 }
71}
72
73void sstvenc_rgb_to_yuv(uint8_t* dest, const uint8_t* src, uint16_t width,
74 uint16_t height) {
75 size_t sz = (size_t)width * (size_t)height;
76 while (sz) {
77 /* Pull out RGB values */
78 const uint8_t r = src[0], g = src[1], b = src[2];
79
80 /* Convert and write out YUV */
81 dest[0] = sstvenc_yuv_calc_y(r, g, b); /* Y */
82 dest[1] = sstvenc_yuv_calc_u(r, g, b); /* U */
83 dest[2] = sstvenc_yuv_calc_v(r, g, b); /* V */
84
85 dest += 3;
86 src += 3;
87 sz--;
88 }
89}
90
91void sstvenc_yuv_to_rgb(uint8_t* dest, const uint8_t* src, uint16_t width,
92 uint16_t height) {
93 size_t sz = (size_t)width * (size_t)height;
94 while (sz) {
95 /* Pull out YUV values */
96 const uint8_t y = src[0], u = src[1], v = src[2];
97
98 /* Convert and write out RGB */
99 dest[0] = sstvenc_rgb_calc_r(y, u, v); /* R */
100 dest[1] = sstvenc_rgb_calc_g(y, u, v); /* G */
101 dest[2] = sstvenc_rgb_calc_b(y, u, v); /* B */
102
103 dest += 3;
104 src += 3;
105 sz--;
106 }
107}
108
109void sstvenc_yuv_to_mono(uint8_t* dest, const uint8_t* src, uint16_t width,
110 uint16_t height) {
111 size_t sz = (size_t)width * (size_t)height;
112 while (sz) {
113 /* Extract Y out of YUV */
114 dest[0] = src[0];
115
116 dest += 1;
117 src += 3;
118 sz--;
119 }
120}
121
122void sstvenc_mono_to_rgb(uint8_t* dest, const uint8_t* src, uint16_t width,
123 uint16_t height) {
124 size_t sz = (size_t)width * (size_t)height;
125 while (sz) {
126 /* Work backwards so we don't overwrite the source */
127 const uint8_t src_pos = sz - 1;
128 const uint8_t dest_pos = src_pos * 3;
129
130 dest[dest_pos + 0] = src[src_pos]; /* R */
131 dest[dest_pos + 1] = src[src_pos]; /* G */
132 dest[dest_pos + 2] = src[src_pos]; /* B */
133
134 sz--;
135 }
136}
137
138void sstvenc_mono_to_yuv(uint8_t* dest, const uint8_t* src, uint16_t width,
139 uint16_t height) {
140 size_t sz = (size_t)width * (size_t)height;
141 while (sz) {
142 /* Work backwards so we don't overwrite the source */
143 const uint8_t src_pos = sz - 1;
144 const uint8_t dest_pos = src_pos * 3;
145
146 dest[dest_pos + 0] = src[src_pos]; /* Y */
147 dest[dest_pos + 1] = 0; /* U */
148 dest[dest_pos + 2] = 0; /* V */
149
150 sz--;
151 }
152}
153
uint8_t sstvenc_rgb_calc_g(uint8_t r, uint8_t g, uint8_t b)
Definition yuv.c:45
void sstvenc_yuv_to_mono(uint8_t *dest, const uint8_t *src, uint16_t width, uint16_t height)
Definition yuv.c:109
uint8_t sstvenc_rgb_calc_b(uint8_t r, uint8_t g, uint8_t b)
Definition yuv.c:53
uint8_t sstvenc_yuv_calc_v(uint8_t r, uint8_t g, uint8_t b)
Definition yuv.c:30
void sstvenc_yuv_to_rgb(uint8_t *dest, const uint8_t *src, uint16_t width, uint16_t height)
Definition yuv.c:91
uint8_t sstvenc_yuv_calc_y(uint8_t r, uint8_t g, uint8_t b)
Definition yuv.c:14
void sstvenc_rgb_to_mono(uint8_t *dest, const uint8_t *src, uint16_t width, uint16_t height)
Definition yuv.c:60
uint8_t sstvenc_yuv_calc_u(uint8_t r, uint8_t g, uint8_t b)
Definition yuv.c:22
uint8_t sstvenc_rgb_calc_r(uint8_t r, uint8_t g, uint8_t b)
Definition yuv.c:38
void sstvenc_mono_to_rgb(uint8_t *dest, const uint8_t *src, uint16_t width, uint16_t height)
Definition yuv.c:122
void sstvenc_mono_to_yuv(uint8_t *dest, const uint8_t *src, uint16_t width, uint16_t height)
Definition yuv.c:138
void sstvenc_rgb_to_yuv(uint8_t *dest, const uint8_t *src, uint16_t width, uint16_t height)
Definition yuv.c:73