Blender V2.61 - r43446

math_color_inline.c

Go to the documentation of this file.
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