/* * CINELERRA * Copyright (C) 2008 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "bccolors.h" #include HSV::HSV() { } HSV::~HSV() { } YUV YUV::yuv; int HSV::rgb_to_hsv(float r, float g, float b, float &h, float &s, float &v) { float min = ((r < g) ? r : g) < b ? ((r < g) ? r : g) : b; float max = ((r > g) ? r : g) > b ? ((r > g) ? r : g) : b; float delta = max - min; if( max != 0 && delta != 0 ) { v = max; s = delta / max; h = r == max ? (g - b) / delta : // between yellow & magenta g == max ? 2 + (b - r) / delta : // between cyan & yellow 4 + (r - g) / delta; // between magenta & cyan if( (h*=60) < 0 ) h += 360; // degrees } else { // r = g = b h = 0; s = 0; v = max; } return 0; } int HSV::hsv_to_rgb(float &r, float &g, float &b, float h, float s, float v) { if( s == 0 ) { // achromatic (grey) r = g = b = v; return 0; } h /= 60; // sector 0 to 5 int i = (int)h; float f = h - i; // factorial part of h float p = v * (1 - s); float q = v * (1 - s * f); float t = v * (1 - s * (1 - f)); switch(i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; default: r = v; g = p; b = q; break; } return 0; } int HSV::yuv_to_hsv(int y, int u, int v, float &h, float &s, float &va, int max) { float r, g, b; int r_i, g_i, b_i; // if(max == 0xffff) // { // YUV::yuv.yuv_to_rgb_16(r_i, g_i, b_i, y, u, v); // } // else { YUV::yuv.yuv_to_rgb_8(r_i, g_i, b_i, y, u, v); } r = (float)r_i / max; g = (float)g_i / max; b = (float)b_i / max; float h2, s2, v2; HSV::rgb_to_hsv(r, g, b, h2, s2, v2); h = h2; s = s2; va = v2; return 0; } int HSV::hsv_to_yuv(int &y, int &u, int &v, float h, float s, float va, int max) { float r, g, b; int r_i, g_i, b_i; HSV::hsv_to_rgb(r, g, b, h, s, va); r = r * max + 0.5; g = g * max + 0.5; b = b * max + 0.5; r_i = (int)CLIP(r, 0, max); g_i = (int)CLIP(g, 0, max); b_i = (int)CLIP(b, 0, max); int y2, u2, v2; // if(max == 0xffff) // YUV::yuv.rgb_to_yuv_16(r_i, g_i, b_i, y2, u2, v2); // else YUV::yuv.rgb_to_yuv_8(r_i, g_i, b_i, y2, u2, v2); y = y2; u = u2; v = v2; return 0; } YUV::YUV() { for(int i = 0; i < 0x100; i++) { // compression rtoy_tab_8[i] = (int)(R_TO_Y * 0x100 * i); rtou_tab_8[i] = (int)(R_TO_U * 0x100 * i); rtov_tab_8[i] = (int)(R_TO_V * 0x100 * i); gtoy_tab_8[i] = (int)(G_TO_Y * 0x100 * i); gtou_tab_8[i] = (int)(G_TO_U * 0x100 * i); gtov_tab_8[i] = (int)(G_TO_V * 0x100 * i); btoy_tab_8[i] = (int)(B_TO_Y * 0x100 * i); btou_tab_8[i] = (int)(B_TO_U * 0x100 * i) + 0x8000; btov_tab_8[i] = (int)(B_TO_V * 0x100 * i) + 0x8000; } vtor_8 = &(vtor_tab_8[(0x100) / 2]); vtog_8 = &(vtog_tab_8[(0x100) / 2]); utog_8 = &(utog_tab_8[(0x100) / 2]); utob_8 = &(utob_tab_8[(0x100) / 2]); for(int i = (-0x100) / 2; i < (0x100) / 2; i++) { // decompression vtor_8[i] = (int)(V_TO_R * 0x100 * i); vtog_8[i] = (int)(V_TO_G * 0x100 * i); utog_8[i] = (int)(U_TO_G * 0x100 * i); utob_8[i] = (int)(U_TO_B * 0x100 * i); } for(int i = 0; i < 0x10000; i++) { // compression rtoy_tab_16[i] = (int)(R_TO_Y * 0x100 * i); rtou_tab_16[i] = (int)(R_TO_U * 0x100 * i); rtov_tab_16[i] = (int)(R_TO_V * 0x100 * i); gtoy_tab_16[i] = (int)(G_TO_Y * 0x100 * i); gtou_tab_16[i] = (int)(G_TO_U * 0x100 * i); gtov_tab_16[i] = (int)(G_TO_V * 0x100 * i); btoy_tab_16[i] = (int)(B_TO_Y * 0x100 * i); btou_tab_16[i] = (int)(B_TO_U * 0x100 * i) + 0x800000; btov_tab_16[i] = (int)(B_TO_V * 0x100 * i) + 0x800000; } vtor_16 = &(vtor_tab_16[(0x10000) / 2]); vtog_16 = &(vtog_tab_16[(0x10000) / 2]); utog_16 = &(utog_tab_16[(0x10000) / 2]); utob_16 = &(utob_tab_16[(0x10000) / 2]); for(int i = (-0x10000) / 2; i < (0x10000) / 2; i++) { // decompression vtor_16[i] = (int)(V_TO_R * 0x100 * i); vtog_16[i] = (int)(V_TO_G * 0x100 * i); utog_16[i] = (int)(U_TO_G * 0x100 * i); utob_16[i] = (int)(U_TO_B * 0x100 * i); } } YUV::~YUV() { }