diff --git a/Makefile b/Makefile index 427b63b..2916fd0 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ test: all clean: rm -f encode decode *.o {8000,11025,40000,44100,48000}.{ppm,wav} -encode: encode.o mmap_file.o +encode: encode.o mmap_file.o yuv.o -decode: decode.o mmap_file.o pcm.o wav.o alsa.o window.o ddc.o delay.o yuv.c +decode: decode.o mmap_file.o pcm.o wav.o alsa.o window.o ddc.o delay.o yuv.o diff --git a/decode.c b/decode.c index 6671a69..1457633 100644 --- a/decode.c +++ b/decode.c @@ -11,30 +11,7 @@ #include "ddc.h" #include "delay.h" #include "yuv.h" - -int64_t gcd(int64_t a, int64_t b) -{ - int64_t c; - while ((c = a % b)) { - a = b; - b = c; - } - return b; -} - -float fclampf(float x, float min, float max) -{ - float tmp = x < min ? min : x; - return tmp > max ? max : tmp; -} - -char *string_time(char *fmt) -{ - static char s[64]; - time_t now = time(0); - strftime(s, sizeof(s), fmt, localtime(&now)); - return s; -} +#include "utils.h" void process_line(uint8_t *pixel, uint8_t *y_pixel, uint8_t *uv_pixel, int y_width, int uv_width, int width, int height, int n) { diff --git a/encode.c b/encode.c index 6dec237..41ef1de 100644 --- a/encode.c +++ b/encode.c @@ -7,43 +7,8 @@ #include #include #include "mmap_file.h" - -float limit(float min, float max, float x) -{ - float tmp = x < min ? min : x; - return tmp > max ? max : tmp; -} -float lerp(float a, float b, float x) -{ - return a - a * x + b * x; -} -uint8_t R_YUV(uint8_t Y, uint8_t U, uint8_t V) -{ - (void)U; - return limit(0.0, 255.0, 0.003906 * ((298.082 * (Y - 16.0)) + (408.583 * (V - 128.0)))); -} -uint8_t G_YUV(uint8_t Y, uint8_t U, uint8_t V) -{ - return limit(0.0, 255.0, 0.003906 * ((298.082 * (Y - 16.0)) + (-100.291 * (U - 128.0)) + (-208.12 * (V - 128.0)))); -} -uint8_t B_YUV(uint8_t Y, uint8_t U, uint8_t V) -{ - (void)V; - return limit(0.0, 255.0, 0.003906 * ((298.082 * (Y - 16.0)) + (516.411 * (U - 128.0)))); -} - -uint8_t Y_RGB(uint8_t R, uint8_t G, uint8_t B) -{ - return limit(0.0, 255.0, 16.0 + (0.003906 * ((65.738 * R) + (129.057 * G) + (25.064 * B)))); -} -uint8_t V_RGB(uint8_t R, uint8_t G, uint8_t B) -{ - return limit(0.0, 255.0, 128.0 + (0.003906 * ((112.439 * R) + (-94.154 * G) + (-18.285 * B)))); -} -uint8_t U_RGB(uint8_t R, uint8_t G, uint8_t B) -{ - return limit(0.0, 255.0, 128.0 + (0.003906 * ((-37.945 * R) + (-74.494 * G) + (112.439 * B)))); -} +#include "yuv.h" +#include "utils.h" typedef struct { uint32_t ChunkID; @@ -145,9 +110,9 @@ int main(int argc, char **argv) } // Y for (int ticks = 0; ticks < (int)(0.088 * rate); ticks++) { - float xf = limit(0.0, 319.0, (320.0 * (float)ticks) / (0.088 * rate)); + float xf = fclampf((320.0 * (float)ticks) / (0.088 * rate), 0.0, 319.0); int x0 = xf; - int x1 = limit(0.0, 319.0, x0 + 1); + int x1 = fclampf(x0 + 1, 0.0, 319.0); int off0 = 3 * y * width + 3 * x0; int off1 = 3 * y * width + 3 * x1; uint8_t R0 = pixel[off0 + 0]; @@ -156,9 +121,9 @@ int main(int argc, char **argv) uint8_t R1 = pixel[off1 + 0]; uint8_t G1 = pixel[off1 + 1]; uint8_t B1 = pixel[off1 + 2]; - uint8_t R = lerp(R0, R1, xf - (float)x0); - uint8_t G = lerp(G0, G1, xf - (float)x0); - uint8_t B = lerp(B0, B1, xf - (float)x0); + uint8_t R = flerpf(R0, R1, xf - (float)x0); + uint8_t G = flerpf(G0, G1, xf - (float)x0); + uint8_t B = flerpf(B0, B1, xf - (float)x0); add_freq(1500.0 + 800.0 * Y_RGB(R, G, B) / 255.0); } // EVEN @@ -171,9 +136,9 @@ int main(int argc, char **argv) } // V for (int ticks = 0; ticks < (int)(0.044 * rate); ticks++) { - float xf = limit(0.0, 159.0, (160.0 * (float)ticks) / (0.044 * rate)); + float xf = fclampf((160.0 * (float)ticks) / (0.044 * rate), 0.0, 159.0); int x0 = xf; - int x1 = limit(0.0, 159.0, x0 + 1); + int x1 = fclampf(x0 + 1, 0.0, 159.0); int evn0 = 3 * y * width + 6 * x0; int evn1 = 3 * y * width + 6 * x1; int odd0 = 3 * (y + 1) * width + 6 * x0; @@ -184,9 +149,9 @@ int main(int argc, char **argv) uint8_t R1 = (pixel[evn1 + 0] + pixel[odd1 + 0] + pixel[evn1 + 3] + pixel[odd1 + 3]) / 4; uint8_t G1 = (pixel[evn1 + 1] + pixel[odd1 + 1] + pixel[evn1 + 4] + pixel[odd1 + 4]) / 4; uint8_t B1 = (pixel[evn1 + 2] + pixel[odd1 + 2] + pixel[evn1 + 5] + pixel[odd1 + 5]) / 4; - uint8_t R = lerp(R0, R1, xf - (float)x0); - uint8_t G = lerp(G0, G1, xf - (float)x0); - uint8_t B = lerp(B0, B1, xf - (float)x0); + uint8_t R = flerpf(R0, R1, xf - (float)x0); + uint8_t G = flerpf(G0, G1, xf - (float)x0); + uint8_t B = flerpf(B0, B1, xf - (float)x0); add_freq(1500.0 + 800.0 * V_RGB(R, G, B) / 255.0); } // ODD LINES @@ -201,9 +166,9 @@ int main(int argc, char **argv) } // Y for (int ticks = 0; ticks < (int)(0.088 * rate); ticks++) { - float xf = limit(0.0, 319.0, (320.0 * (float)ticks) / (0.088 * rate)); + float xf = fclampf((320.0 * (float)ticks) / (0.088 * rate), 0.0, 319.0); int x0 = xf; - int x1 = limit(0.0, 319.0, x0 + 1); + int x1 = fclampf(x0 + 1, 0.0, 319.0); int off0 = 3 * y * width + 3 * x0; int off1 = 3 * y * width + 3 * x1; uint8_t R0 = pixel[off0 + 0]; @@ -212,9 +177,9 @@ int main(int argc, char **argv) uint8_t R1 = pixel[off1 + 0]; uint8_t G1 = pixel[off1 + 1]; uint8_t B1 = pixel[off1 + 2]; - uint8_t R = lerp(R0, R1, xf - (float)x0); - uint8_t G = lerp(G0, G1, xf - (float)x0); - uint8_t B = lerp(B0, B1, xf - (float)x0); + uint8_t R = flerpf(R0, R1, xf - (float)x0); + uint8_t G = flerpf(G0, G1, xf - (float)x0); + uint8_t B = flerpf(B0, B1, xf - (float)x0); add_freq(1500.0 + 800.0 * Y_RGB(R, G, B) / 255.0); } // ODD @@ -227,9 +192,9 @@ int main(int argc, char **argv) } // U for (int ticks = 0; ticks < (int)(0.044 * rate); ticks++) { - float xf = limit(0.0, 159.0, (160.0 * (float)ticks) / (0.044 * rate)); + float xf = fclampf((160.0 * (float)ticks) / (0.044 * rate), 0.0, 159.0); int x0 = xf; - int x1 = limit(0.0, 159.0, x0 + 1); + int x1 = fclampf(x0 + 1, 0.0, 159.0); int evn0 = 3 * (y - 1) * width + 6 * x0; int evn1 = 3 * (y - 1) * width + 6 * x1; int odd0 = 3 * y * width + 6 * x0; @@ -240,9 +205,9 @@ int main(int argc, char **argv) uint8_t R1 = (pixel[evn1 + 0] + pixel[odd1 + 0] + pixel[evn1 + 3] + pixel[odd1 + 3]) / 4; uint8_t G1 = (pixel[evn1 + 1] + pixel[odd1 + 1] + pixel[evn1 + 4] + pixel[odd1 + 4]) / 4; uint8_t B1 = (pixel[evn1 + 2] + pixel[odd1 + 2] + pixel[evn1 + 5] + pixel[odd1 + 5]) / 4; - uint8_t R = lerp(R0, R1, xf - (float)x0); - uint8_t G = lerp(G0, G1, xf - (float)x0); - uint8_t B = lerp(B0, B1, xf - (float)x0); + uint8_t R = flerpf(R0, R1, xf - (float)x0); + uint8_t G = flerpf(G0, G1, xf - (float)x0); + uint8_t B = flerpf(B0, B1, xf - (float)x0); add_freq(1500.0 + 800.0 * U_RGB(R, G, B) / 255.0); } } diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..767bb1c --- /dev/null +++ b/utils.h @@ -0,0 +1,36 @@ + +#ifndef UTILS_H +#define UTILS_H +#include +#include + +int64_t gcd(int64_t a, int64_t b) +{ + int64_t c; + while ((c = a % b)) { + a = b; + b = c; + } + return b; +} + +float fclampf(float x, float min, float max) +{ + float tmp = x < min ? min : x; + return tmp > max ? max : tmp; +} + +float flerpf(float a, float b, float x) +{ + return a - a * x + b * x; +} + +char *string_time(char *fmt) +{ + static char s[64]; + time_t now = time(0); + strftime(s, sizeof(s), fmt, localtime(&now)); + return s; +} +#endif + diff --git a/yuv.c b/yuv.c index cb8934e..89eea09 100644 --- a/yuv.c +++ b/yuv.c @@ -1,7 +1,7 @@ #include "yuv.h" -uint8_t yuv_limit(float x) +uint8_t yuv_clamp(float x) { float tmp = x < 0.0 ? 0.0 : x; return tmp > 255.0 ? 255.0 : tmp; @@ -10,15 +10,28 @@ uint8_t yuv_limit(float x) uint8_t R_YUV(uint8_t Y, uint8_t U, uint8_t V) { (void)U; - return yuv_limit(0.003906 * ((298.082 * (Y - 16.0)) + (408.583 * (V - 128)))); + return yuv_clamp(0.003906 * ((298.082 * (Y - 16.0)) + (408.583 * (V - 128)))); } uint8_t G_YUV(uint8_t Y, uint8_t U, uint8_t V) { - return yuv_limit(0.003906 * ((298.082 * (Y - 16.0)) + (-100.291 * (U - 128)) + (-208.12 * (V - 128)))); + return yuv_clamp(0.003906 * ((298.082 * (Y - 16.0)) + (-100.291 * (U - 128)) + (-208.12 * (V - 128)))); } uint8_t B_YUV(uint8_t Y, uint8_t U, uint8_t V) { (void)V; - return yuv_limit(0.003906 * ((298.082 * (Y - 16.0)) + (516.411 * (U - 128)))); + return yuv_clamp(0.003906 * ((298.082 * (Y - 16.0)) + (516.411 * (U - 128)))); +} + +uint8_t Y_RGB(uint8_t R, uint8_t G, uint8_t B) +{ + return yuv_clamp(16.0 + (0.003906 * ((65.738 * R) + (129.057 * G) + (25.064 * B)))); +} +uint8_t V_RGB(uint8_t R, uint8_t G, uint8_t B) +{ + return yuv_clamp(128.0 + (0.003906 * ((112.439 * R) + (-94.154 * G) + (-18.285 * B)))); +} +uint8_t U_RGB(uint8_t R, uint8_t G, uint8_t B) +{ + return yuv_clamp(128.0 + (0.003906 * ((-37.945 * R) + (-74.494 * G) + (112.439 * B)))); } diff --git a/yuv.h b/yuv.h index 53c0629..feb2aca 100644 --- a/yuv.h +++ b/yuv.h @@ -6,4 +6,7 @@ uint8_t R_YUV(uint8_t, uint8_t, uint8_t); uint8_t G_YUV(uint8_t, uint8_t, uint8_t); uint8_t B_YUV(uint8_t, uint8_t, uint8_t); +uint8_t Y_RGB(uint8_t, uint8_t, uint8_t); +uint8_t V_RGB(uint8_t, uint8_t, uint8_t); +uint8_t U_RGB(uint8_t, uint8_t, uint8_t); #endif