Created
January 11, 2024 12:16
-
-
Save MartijnBraam/9dde585614b916199427063c18f6afa8 to your computer and use it in GitHub Desktop.
bmd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Copyright 2021 - 2022, Martijn Braam and the OpenAtem contributors | |
SPDX-License-Identifier: LGPL-3.0-only | |
*/ | |
#include <stdint.h> | |
#include <malloc.h> | |
#define PY_SSIZE_T_CLEAN | |
#define RLE_HEADER 0xFEFEFEFEFEFEFEFE | |
const double bt709_coeff_r = 0.2126; | |
const double bt709_coeff_g = 0.7152; | |
const double bt709_coeff_b = 0.0722; | |
const double bt709_coeff_ri = 1.0 - bt709_coeff_r; | |
const double bt709_coeff_bi = 1.0 - bt709_coeff_b; | |
const double bt709_coeff_bg = bt709_coeff_b / bt709_coeff_g; | |
const double bt709_coeff_rg = bt709_coeff_r / bt709_coeff_g; | |
const int y_offset = 16 << 8; | |
const int y_range = 219; | |
const int cr_offset = 128 << 8; | |
const int cr_range = 224; | |
const int cr_middle = 224 / 2; | |
const double bt709_ri_range = bt709_coeff_ri / cr_middle; | |
const double bt709_bi_range = bt709_coeff_bi / cr_middle; | |
unsigned short | |
clamp(unsigned short v, unsigned short min, unsigned short max) | |
{ | |
const short t = v < min ? min : v; | |
return t > max ? max : t; | |
} | |
int | |
main() | |
{ | |
unsigned int width = 2; | |
unsigned int height = 1; | |
int data_length = 8; | |
unsigned char *buffer = (unsigned char *) malloc(8); | |
buffer[0] = 0xFF; // R | |
buffer[1] = 0x00; // G | |
buffer[2] = 0x00; // B | |
buffer[3] = 0xFF; // A | |
buffer[4] = 0xFF; // R | |
buffer[5] = 0x00; // G | |
buffer[6] = 0x00; // B | |
buffer[7] = 0xFF; // A | |
char *outbuffer = (char *) malloc(data_length); | |
char *writepointer = outbuffer; | |
int pixel_size = 8; | |
for (int i = 0; i < data_length; i += pixel_size) { | |
// Convert RGBA 8888 to 10-bit BT.709 Y'CbCrA | |
float r1 = (float) buffer[0] / 255; | |
float g1 = (float) buffer[1] / 255; | |
float b1 = (float) buffer[2] / 255; | |
float r2 = (float) buffer[4] / 255; | |
float g2 = (float) buffer[5] / 255; | |
float b2 = (float) buffer[6] / 255; | |
printf("INPUT:\n"); | |
printf(" 1 = %f %f %f\n", r1, g1, b1); | |
printf(" 2 = %f %f %f\n", r2, g2, b2); | |
printf(" R = %f %f %f\n", 1.0f, 0.0f, 0.0f); | |
float y1 = (0.2126 * r1) + (0.7152 * g1) + (0.0722 * b1); | |
float y2 = (0.2126 * r2) + (0.7152 * g2) + (0.0722 * b2); | |
float cb = (b2 - y2) / 1.8556; | |
float cr = (r2 - y2) / 1.5748; | |
printf("YCbCr:\n"); | |
printf(" 1 = %f %f %f\n", y1, cb, cr); | |
printf(" 2 = %f %f %f\n", y2, cb, cr); | |
printf(" R = %f %f %f\n", 0.212600f, -0.114572f, 0.5f); | |
unsigned short a10a = ((buffer[3] << 2) * 219 / 255) + (15 << 2) + 1; | |
unsigned short a10b = ((buffer[7] << 2) * 219 / 255) + (15 << 2) + 1; | |
unsigned short y10a = clamp((unsigned short) (y1 * 876) + 64, 64, 940); | |
unsigned short y10b = clamp((unsigned short) (y2 * 876) + 64, 64, 940); | |
unsigned short cb10 = clamp((unsigned short) (cb * 896) + 512, 44, 960); | |
unsigned short cr10 = clamp((unsigned short) (cr * 896) + 512, 44, 960); | |
printf("Integers:\n"); | |
printf(" 1 = %d %d %d %d\n", y10a, cb10, cr10, a10a); | |
printf(" 2 = %d %d %d %d\n", y10b, cb10, cr10, a10b); | |
printf(" R = %d %d %d %d\n", 250, 410, 960, 937); | |
writepointer[0] = (unsigned char) (a10a >> 4); | |
writepointer[1] = (unsigned char) (((a10a & 0x0f) << 4) | (cb10 >> 6)); | |
writepointer[2] = (unsigned char) (((cb10 & 0x3f) << 2) | (y10a >> 8)); | |
writepointer[3] = (unsigned char) (y10a & 0xff); | |
writepointer[4] = (unsigned char) (a10b >> 4); | |
writepointer[5] = (unsigned char) (((a10b & 0x0f) << 4) | (cr10 >> 6)); | |
writepointer[6] = (unsigned char) (((cr10 & 0x3f) << 2) | (y10b >> 8)); | |
writepointer[7] = (unsigned char) (y10b & 0xff); | |
printf("Packed:\n"); | |
printf(" %X %X %X %X %X %X %X %X\n", | |
writepointer[0] & 0xFF, writepointer[1] & 0xFF, writepointer[2] & 0xFF, writepointer[3] & 0xFF, | |
writepointer[4] & 0xFF, writepointer[5] & 0xFF, writepointer[6] & 0xFF, writepointer[7] & 0xFF); | |
printf(" 3A 96 68 FA 3A 9F 0 FA\n"); | |
writepointer += pixel_size; | |
buffer += pixel_size; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment