Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: some of this file. 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 * */ 00025 00031 #include "BLI_math_color.h" 00032 #include "BLI_utildefines.h" 00033 00034 #ifndef BLI_MATH_COLOR_INLINE_H 00035 #define BLI_MATH_COLOR_INLINE_H 00036 00037 /******************************** Color Space ********************************/ 00038 00039 MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3]) 00040 { 00041 linear[0] = srgb_to_linearrgb(srgb[0]); 00042 linear[1] = srgb_to_linearrgb(srgb[1]); 00043 linear[2] = srgb_to_linearrgb(srgb[2]); 00044 } 00045 00046 MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3]) 00047 { 00048 srgb[0] = linearrgb_to_srgb(linear[0]); 00049 srgb[1] = linearrgb_to_srgb(linear[1]); 00050 srgb[2] = linearrgb_to_srgb(linear[2]); 00051 } 00052 00053 MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4]) 00054 { 00055 srgb_to_linearrgb_v3_v3(linear, srgb); 00056 linear[3] = srgb[3]; 00057 } 00058 00059 MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4]) 00060 { 00061 linearrgb_to_srgb_v3_v3(srgb, linear); 00062 srgb[3] = linear[3]; 00063 } 00064 00065 /* predivide versions to work on associated/premultipled alpha. if this should 00066 be done or not depends on the background the image will be composited over, 00067 ideally you would never do color space conversion on an image with alpha 00068 because it is ill defined */ 00069 00070 MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4]) 00071 { 00072 float alpha, inv_alpha; 00073 00074 if(srgb[3] == 1.0f || srgb[3] == 0.0f) { 00075 alpha = 1.0f; 00076 inv_alpha = 1.0f; 00077 } 00078 else { 00079 alpha = srgb[3]; 00080 inv_alpha = 1.0f/alpha; 00081 } 00082 00083 linear[0] = srgb_to_linearrgb(srgb[0] * inv_alpha) * alpha; 00084 linear[1] = srgb_to_linearrgb(srgb[1] * inv_alpha) * alpha; 00085 linear[2] = srgb_to_linearrgb(srgb[2] * inv_alpha) * alpha; 00086 linear[3] = srgb[3]; 00087 } 00088 00089 MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4]) 00090 { 00091 float alpha, inv_alpha; 00092 00093 if(linear[3] == 1.0f || linear[3] == 0.0f) { 00094 alpha = 1.0f; 00095 inv_alpha = 1.0f; 00096 } 00097 else { 00098 alpha = linear[3]; 00099 inv_alpha = 1.0f/alpha; 00100 } 00101 00102 srgb[0] = linearrgb_to_srgb(linear[0] * inv_alpha) * alpha; 00103 srgb[1] = linearrgb_to_srgb(linear[1] * inv_alpha) * alpha; 00104 srgb[2] = linearrgb_to_srgb(linear[2] * inv_alpha) * alpha; 00105 srgb[3] = linear[3]; 00106 } 00107 00108 /* LUT accelerated conversions */ 00109 00110 extern float BLI_color_from_srgb_table[256]; 00111 extern unsigned short BLI_color_to_srgb_table[0x10000]; 00112 00113 MINLINE unsigned short to_srgb_table_lookup(const float f) 00114 { 00115 union { 00116 float f; 00117 unsigned short us[2]; 00118 } tmp; 00119 tmp.f = f; 00120 #ifdef __BIG_ENDIAN__ 00121 return BLI_color_to_srgb_table[tmp.us[0]]; 00122 #else 00123 return BLI_color_to_srgb_table[tmp.us[1]]; 00124 #endif 00125 } 00126 00127 MINLINE void linearrgb_to_srgb_ushort4(unsigned short srgb[4], const float linear[4]) 00128 { 00129 srgb[0] = to_srgb_table_lookup(linear[0]); 00130 srgb[1] = to_srgb_table_lookup(linear[1]); 00131 srgb[2] = to_srgb_table_lookup(linear[2]); 00132 srgb[3] = FTOUSHORT(linear[3]); 00133 } 00134 00135 MINLINE void linearrgb_to_srgb_ushort4_predivide(unsigned short srgb[4], const float linear[4]) 00136 { 00137 float alpha, inv_alpha, t; 00138 int i; 00139 00140 if(linear[3] == 1.0f || linear[3] == 0.0f) { 00141 linearrgb_to_srgb_ushort4(srgb, linear); 00142 return; 00143 } 00144 00145 alpha = linear[3]; 00146 inv_alpha = 1.0f/alpha; 00147 00148 for(i=0; i<3; ++i) { 00149 t = linear[i] * inv_alpha; 00150 srgb[i] = (t < 1.0f)? to_srgb_table_lookup(t) * alpha : FTOUSHORT(linearrgb_to_srgb(t) * alpha); 00151 } 00152 00153 srgb[3] = FTOUSHORT(linear[3]); 00154 } 00155 00156 MINLINE void srgb_to_linearrgb_uchar4(float linear[4], const unsigned char srgb[4]) 00157 { 00158 linear[0] = BLI_color_from_srgb_table[srgb[0]]; 00159 linear[1] = BLI_color_from_srgb_table[srgb[1]]; 00160 linear[2] = BLI_color_from_srgb_table[srgb[2]]; 00161 linear[3] = srgb[3] * (1.0f/255.0f); 00162 } 00163 00164 MINLINE void srgb_to_linearrgb_uchar4_predivide(float linear[4], const unsigned char srgb[4]) 00165 { 00166 float alpha, inv_alpha; 00167 int i; 00168 00169 if(srgb[3] == 255 || srgb[3] == 0) { 00170 srgb_to_linearrgb_uchar4(linear, srgb); 00171 return; 00172 } 00173 00174 alpha = srgb[3] * (1.0f/255.0f); 00175 inv_alpha = 1.0f/alpha; 00176 00177 for(i=0; i<3; ++i) 00178 linear[i] = linearrgb_to_srgb(srgb[i] * inv_alpha) * alpha; 00179 00180 linear[3] = alpha; 00181 } 00182 00183 #endif /* BLI_MATH_COLOR_INLINE_H */ 00184