163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil/* 263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * vivid-color.c - A table that converts colors to various colorspaces 363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * The test pattern generator uses the tpg_colors for its test patterns. 563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * For testing colorspaces the first 8 colors of that table need to be 663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * converted to their equivalent in the target colorspace. 763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * The tpg_csc_colors[] table is the result of that conversion and since 963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * it is precalculated the colorspace conversion is just a simple table 1063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * lookup. 1163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 1263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * This source also contains the code used to generate the tpg_csc_colors 1363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * table. Run the following command to compile it: 1463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 1563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * gcc vivid-colors.c -DCOMPILE_APP -o gen-colors -lm 1663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 1763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * and run the utility. 1863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 1963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * Note that the converted colors are in the range 0x000-0xff0 (so times 16) 2063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * in order to preserve precision. 2163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 2263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 2363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 2463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * This program is free software; you may redistribute it and/or modify 2563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * it under the terms of the GNU General Public License as published by 2663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * the Free Software Foundation; version 2 of the License. 2763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * 2863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 3063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 3163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 3263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * SOFTWARE. 3663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil */ 3763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 3863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil#include <linux/videodev2.h> 3963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 4063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil#include "vivid-tpg-colors.h" 4163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 4263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil/* sRGB colors with range [0-255] */ 4363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilconst struct color tpg_colors[TPG_COLOR_MAX] = { 4463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil /* 4563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * Colors to test colorspace conversion: converting these colors 4663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil * to other colorspaces will never lead to out-of-gamut colors. 4763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil */ 4863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 191, 191, 191 }, /* TPG_COLOR_CSC_WHITE */ 4963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 191, 191, 50 }, /* TPG_COLOR_CSC_YELLOW */ 5063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 50, 191, 191 }, /* TPG_COLOR_CSC_CYAN */ 5163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 50, 191, 50 }, /* TPG_COLOR_CSC_GREEN */ 5263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 191, 50, 191 }, /* TPG_COLOR_CSC_MAGENTA */ 5363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 191, 50, 50 }, /* TPG_COLOR_CSC_RED */ 5463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 50, 50, 191 }, /* TPG_COLOR_CSC_BLUE */ 5563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 50, 50, 50 }, /* TPG_COLOR_CSC_BLACK */ 5663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 5763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil /* 75% colors */ 5863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 191, 191, 0 }, /* TPG_COLOR_75_YELLOW */ 5963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0, 191, 191 }, /* TPG_COLOR_75_CYAN */ 6063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0, 191, 0 }, /* TPG_COLOR_75_GREEN */ 6163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 191, 0, 191 }, /* TPG_COLOR_75_MAGENTA */ 6263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 191, 0, 0 }, /* TPG_COLOR_75_RED */ 6363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0, 0, 191 }, /* TPG_COLOR_75_BLUE */ 6463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 6563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil /* 100% colors */ 6663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 255, 255, 255 }, /* TPG_COLOR_100_WHITE */ 6763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 255, 255, 0 }, /* TPG_COLOR_100_YELLOW */ 6863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0, 255, 255 }, /* TPG_COLOR_100_CYAN */ 6963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0, 255, 0 }, /* TPG_COLOR_100_GREEN */ 7063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 255, 0, 255 }, /* TPG_COLOR_100_MAGENTA */ 7163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 255, 0, 0 }, /* TPG_COLOR_100_RED */ 7263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0, 0, 255 }, /* TPG_COLOR_100_BLUE */ 7363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0, 0, 0 }, /* TPG_COLOR_100_BLACK */ 7463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 7563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0, 0, 0 }, /* TPG_COLOR_RANDOM placeholder */ 7663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil}; 7763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 7863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil#ifndef COMPILE_APP 7963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 8063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil/* Generated table */ 8163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilconst struct color16 tpg_csc_colors[V4L2_COLORSPACE_SRGB + 1][TPG_COLOR_CSC_BLACK + 1] = { 8263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE170M][0] = { 2953, 2939, 2939 }, 8363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE170M][1] = { 2954, 2963, 585 }, 8463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE170M][2] = { 84, 2967, 2937 }, 8563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE170M][3] = { 93, 2990, 575 }, 8663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE170M][4] = { 3030, 259, 2933 }, 8763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE170M][5] = { 3031, 406, 557 }, 8863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE170M][6] = { 544, 428, 2931 }, 8963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE170M][7] = { 551, 547, 547 }, 9063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE240M][0] = { 2926, 2926, 2926 }, 9163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE240M][1] = { 2926, 2926, 857 }, 9263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE240M][2] = { 1594, 2901, 2901 }, 9363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE240M][3] = { 1594, 2901, 774 }, 9463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE240M][4] = { 2484, 618, 2858 }, 9563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE240M][5] = { 2484, 618, 617 }, 9663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE240M][6] = { 507, 507, 2832 }, 9763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SMPTE240M][7] = { 507, 507, 507 }, 9863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_REC709][0] = { 2939, 2939, 2939 }, 9963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_REC709][1] = { 2939, 2939, 547 }, 10063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_REC709][2] = { 547, 2939, 2939 }, 10163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_REC709][3] = { 547, 2939, 547 }, 10263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_REC709][4] = { 2939, 547, 2939 }, 10363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_REC709][5] = { 2939, 547, 547 }, 10463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_REC709][6] = { 547, 547, 2939 }, 10563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_REC709][7] = { 547, 547, 547 }, 10663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_M][0] = { 2894, 2988, 2808 }, 10763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_M][1] = { 2847, 3070, 843 }, 10863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_M][2] = { 1656, 2962, 2783 }, 10963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_M][3] = { 1572, 3045, 763 }, 11063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_M][4] = { 2477, 229, 2743 }, 11163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_M][5] = { 2422, 672, 614 }, 11263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_M][6] = { 725, 63, 2718 }, 11363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_M][7] = { 534, 561, 509 }, 11463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_BG][0] = { 2939, 2939, 2939 }, 11563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_BG][1] = { 2939, 2939, 621 }, 11663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_BG][2] = { 786, 2939, 2939 }, 11763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_BG][3] = { 786, 2939, 621 }, 11863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_BG][4] = { 2879, 547, 2923 }, 11963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_BG][5] = { 2879, 547, 547 }, 12063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_BG][6] = { 547, 547, 2923 }, 12163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_470_SYSTEM_BG][7] = { 547, 547, 547 }, 12263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SRGB][0] = { 3056, 3056, 3056 }, 12363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SRGB][1] = { 3056, 3056, 800 }, 12463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SRGB][2] = { 800, 3056, 3056 }, 12563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SRGB][3] = { 800, 3056, 800 }, 12663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SRGB][4] = { 3056, 800, 3056 }, 12763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SRGB][5] = { 3056, 800, 800 }, 12863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SRGB][6] = { 800, 800, 3056 }, 12963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil [V4L2_COLORSPACE_SRGB][7] = { 800, 800, 800 }, 13063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil}; 13163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 13263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil#else 13363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 13463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil/* This code generates the table above */ 13563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 13663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil#include <math.h> 13763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil#include <stdio.h> 13863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil#include <stdlib.h> 13963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 14063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic const double rec709_to_ntsc1953[3][3] = { 14163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0.6698, 0.2678, 0.0323 }, 14263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0.0185, 1.0742, -0.0603 }, 14363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0.0162, 0.0432, 0.8551 } 14463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil}; 14563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 14663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic const double rec709_to_ebu[3][3] = { 14763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0.9578, 0.0422, 0 }, 14863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0 , 1 , 0 }, 14963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0 , 0.0118, 0.9882 } 15063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil}; 15163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 15263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic const double rec709_to_170m[3][3] = { 15363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 1.0654, -0.0554, -0.0010 }, 15463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { -0.0196, 1.0364, -0.0167 }, 15563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0.0016, 0.0044, 0.9940 } 15663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil}; 15763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 15863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic const double rec709_to_240m[3][3] = { 15963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0.7151, 0.2849, 0 }, 16063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0.0179, 0.9821, 0 }, 16163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil { 0.0177, 0.0472, 0.9350 } 16263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil}; 16363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 16463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 16563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic void mult_matrix(double *r, double *g, double *b, const double m[3][3]) 16663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil{ 16763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil double ir, ig, ib; 16863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 16963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil ir = m[0][0] * (*r) + m[0][1] * (*g) + m[0][2] * (*b); 17063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil ig = m[1][0] * (*r) + m[1][1] * (*g) + m[1][2] * (*b); 17163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil ib = m[2][0] * (*r) + m[2][1] * (*g) + m[2][2] * (*b); 17263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = ir; 17363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = ig; 17463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = ib; 17563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil} 17663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 17763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic double transfer_srgb_to_rgb(double v) 17863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil{ 17963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil return (v <= 0.03928) ? v / 12.92 : pow((v + 0.055) / 1.055, 2.4); 18063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil} 18163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 18263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic double transfer_rgb_to_smpte240m(double v) 18363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil{ 18463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil return (v <= 0.0228) ? v * 4.0 : 1.1115 * pow(v, 0.45) - 0.1115; 18563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil} 18663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 18763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic double transfer_rgb_to_rec709(double v) 18863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil{ 18963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil return (v < 0.018) ? v * 4.5 : 1.099 * pow(v, 0.45) - 0.099; 19063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil} 19163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 19263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic double transfer_srgb_to_rec709(double v) 19363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil{ 19463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil return transfer_rgb_to_rec709(transfer_srgb_to_rgb(v)); 19563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil} 19663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 19763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilstatic void csc(enum v4l2_colorspace colorspace, double *r, double *g, double *b) 19863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil{ 19963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil /* Convert the primaries of Rec. 709 Linear RGB */ 20063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil switch (colorspace) { 20163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_SMPTE240M: 20263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = transfer_srgb_to_rgb(*r); 20363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = transfer_srgb_to_rgb(*g); 20463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = transfer_srgb_to_rgb(*b); 20563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil mult_matrix(r, g, b, rec709_to_240m); 20663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 20763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_SMPTE170M: 20863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = transfer_srgb_to_rgb(*r); 20963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = transfer_srgb_to_rgb(*g); 21063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = transfer_srgb_to_rgb(*b); 21163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil mult_matrix(r, g, b, rec709_to_170m); 21263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 21363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_470_SYSTEM_BG: 21463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = transfer_srgb_to_rgb(*r); 21563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = transfer_srgb_to_rgb(*g); 21663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = transfer_srgb_to_rgb(*b); 21763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil mult_matrix(r, g, b, rec709_to_ebu); 21863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 21963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_470_SYSTEM_M: 22063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = transfer_srgb_to_rgb(*r); 22163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = transfer_srgb_to_rgb(*g); 22263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = transfer_srgb_to_rgb(*b); 22363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil mult_matrix(r, g, b, rec709_to_ntsc1953); 22463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 22563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_SRGB: 22663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_REC709: 22763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil default: 22863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 22963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil } 23063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 23163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = ((*r) < 0) ? 0 : (((*r) > 1) ? 1 : (*r)); 23263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = ((*g) < 0) ? 0 : (((*g) > 1) ? 1 : (*g)); 23363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = ((*b) < 0) ? 0 : (((*b) > 1) ? 1 : (*b)); 23463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 23563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil /* Encode to gamma corrected colorspace */ 23663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil switch (colorspace) { 23763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_SMPTE240M: 23863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = transfer_rgb_to_smpte240m(*r); 23963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = transfer_rgb_to_smpte240m(*g); 24063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = transfer_rgb_to_smpte240m(*b); 24163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 24263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_SMPTE170M: 24363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_470_SYSTEM_M: 24463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_470_SYSTEM_BG: 24563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = transfer_rgb_to_rec709(*r); 24663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = transfer_rgb_to_rec709(*g); 24763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = transfer_rgb_to_rec709(*b); 24863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 24963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_SRGB: 25063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 25163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil case V4L2_COLORSPACE_REC709: 25263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil default: 25363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *r = transfer_srgb_to_rec709(*r); 25463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *g = transfer_srgb_to_rec709(*g); 25563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil *b = transfer_srgb_to_rec709(*b); 25663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil break; 25763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil } 25863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil} 25963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 26063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuilint main(int argc, char **argv) 26163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil{ 26263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil static const unsigned colorspaces[] = { 26363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 0, 26463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil V4L2_COLORSPACE_SMPTE170M, 26563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil V4L2_COLORSPACE_SMPTE240M, 26663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil V4L2_COLORSPACE_REC709, 26763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 0, 26863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil V4L2_COLORSPACE_470_SYSTEM_M, 26963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil V4L2_COLORSPACE_470_SYSTEM_BG, 27063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 0, 27163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil V4L2_COLORSPACE_SRGB, 27263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil }; 27363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil static const char * const colorspace_names[] = { 27463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "", 27563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "V4L2_COLORSPACE_SMPTE170M", 27663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "V4L2_COLORSPACE_SMPTE240M", 27763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "V4L2_COLORSPACE_REC709", 27863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "", 27963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "V4L2_COLORSPACE_470_SYSTEM_M", 28063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "V4L2_COLORSPACE_470_SYSTEM_BG", 28163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "", 28263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil "V4L2_COLORSPACE_SRGB", 28363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil }; 28463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil int i; 28563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil int c; 28663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 28763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil printf("/* Generated table */\n"); 28863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil printf("const struct color16 tpg_csc_colors[V4L2_COLORSPACE_SRGB + 1][TPG_COLOR_CSC_BLACK + 1] = {\n"); 28963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil for (c = 0; c <= V4L2_COLORSPACE_SRGB; c++) { 29063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil for (i = 0; i <= TPG_COLOR_CSC_BLACK; i++) { 29163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil double r, g, b; 29263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 29363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil if (colorspaces[c] == 0) 29463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil continue; 29563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 29663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil r = tpg_colors[i].r / 255.0; 29763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil g = tpg_colors[i].g / 255.0; 29863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil b = tpg_colors[i].b / 255.0; 29963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 30063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil csc(c, &r, &g, &b); 30163881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 30263881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil printf("\t[%s][%d] = { %d, %d, %d },\n", colorspace_names[c], i, 30363881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil (int)(r * 4080), (int)(g * 4080), (int)(b * 4080)); 30463881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil } 30563881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil } 30663881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil printf("};\n\n"); 30763881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil return 0; 30863881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil} 30963881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil 31063881df94d3ecbb0deafa0b77da62ff2f32961c4Hans Verkuil#endif 311