Blender V2.61 - r43446
|
00001 /* 00002 * Jitter offset table 00003 * 00004 * 00005 * ***** BEGIN GPL LICENSE BLOCK ***** 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License 00009 * as published by the Free Software Foundation; either version 2 00010 * of the License, or (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software Foundation, 00019 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00020 * 00021 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00022 * All rights reserved. 00023 * 00024 * The Original Code is: all of this file. 00025 * 00026 * Contributor(s): none yet. 00027 * 00028 * ***** END GPL LICENSE BLOCK ***** 00029 */ 00030 00036 #include "gammaCorrectionTables.h" 00037 #include <stdlib.h> 00038 #include <math.h> 00039 00040 /* WARNING; optimized, cannot be used to do gamma(invgamma()) and expect */ 00041 /* result remain identical (ton) */ 00042 00043 /* gamma is only used here for correcting adding colors or alpha */ 00044 #define RE_DEFAULT_GAMMA 2.0 00045 00046 /* This 400 is sort of based on the number of intensity levels needed for */ 00047 /* the typical dynamic range of a medium, in this case CRTs. (Foley) */ 00048 /* (Actually, it says the number should be between 400 and 535.) */ 00049 #define RE_GAMMA_TABLE_SIZE 400 00050 00051 /* These indicate the status of the gamma lookup table --------------------- */ 00052 00053 static float gamma_range_table[RE_GAMMA_TABLE_SIZE + 1]; 00054 static float gamfactor_table[RE_GAMMA_TABLE_SIZE]; 00055 static float inv_gamma_range_table[RE_GAMMA_TABLE_SIZE + 1]; 00056 static float inv_gamfactor_table[RE_GAMMA_TABLE_SIZE]; 00057 static float color_domain_table[RE_GAMMA_TABLE_SIZE + 1]; 00058 static float color_step; 00059 static float inv_color_step; 00060 static float valid_gamma; 00061 static float valid_inv_gamma; 00062 00063 /* ------------------------------------------------------------------------- */ 00064 00065 float gammaCorrect(float c) 00066 { 00067 int i; 00068 float res = 0.0; 00069 00070 i = floor(c * inv_color_step); 00071 /* Clip to range [0,1]: outside, just do the complete calculation. */ 00072 /* We may have some performance problems here. Stretching up the LUT */ 00073 /* may help solve that, by exchanging LUT size for the interpolation. */ 00074 /* Negative colors are explicitly handled. */ 00075 if (i < 0) res = -pow(abs(c), valid_gamma); 00076 else if (i >= RE_GAMMA_TABLE_SIZE ) res = pow(c, valid_gamma); 00077 else res = gamma_range_table[i] + 00078 ( (c - color_domain_table[i]) * gamfactor_table[i]); 00079 00080 return res; 00081 } /* end of float gammaCorrect(float col) */ 00082 00083 /* ------------------------------------------------------------------------- */ 00084 00085 float invGammaCorrect(float col) 00086 { 00087 int i; 00088 float res = 0.0; 00089 00090 i = floor(col*inv_color_step); 00091 /* Negative colors are explicitly handled. */ 00092 if (i < 0) res = -pow(abs(col), valid_inv_gamma); 00093 else if (i >= RE_GAMMA_TABLE_SIZE) res = pow(col, valid_inv_gamma); 00094 else res = inv_gamma_range_table[i] + 00095 ( (col - color_domain_table[i]) * inv_gamfactor_table[i]); 00096 00097 return res; 00098 } /* end of float invGammaCorrect(float col) */ 00099 00100 00101 /* ------------------------------------------------------------------------- */ 00102 00103 void makeGammaTables(float gamma) 00104 { 00105 /* we need two tables: one forward, one backward */ 00106 int i; 00107 00108 valid_gamma = gamma; 00109 valid_inv_gamma = 1.0f / gamma; 00110 color_step = 1.0 / RE_GAMMA_TABLE_SIZE; 00111 inv_color_step = (float) RE_GAMMA_TABLE_SIZE; 00112 00113 /* We could squeeze out the two range tables to gain some memory. */ 00114 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++) { 00115 color_domain_table[i] = i * color_step; 00116 gamma_range_table[i] = pow(color_domain_table[i], 00117 valid_gamma); 00118 inv_gamma_range_table[i] = pow(color_domain_table[i], 00119 valid_inv_gamma); 00120 } 00121 00122 /* The end of the table should match 1.0 carefully. In order to avoid */ 00123 /* rounding errors, we just set this explicitly. The last segment may */ 00124 /* have a different length than the other segments, but our */ 00125 /* interpolation is insensitive to that. */ 00126 color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0; 00127 gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; 00128 inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0; 00129 00130 /* To speed up calculations, we make these calc factor tables. They are */ 00131 /* multiplication factors used in scaling the interpolation. */ 00132 for (i = 0; i < RE_GAMMA_TABLE_SIZE; i++ ) { 00133 gamfactor_table[i] = inv_color_step 00134 * (gamma_range_table[i + 1] - gamma_range_table[i]) ; 00135 inv_gamfactor_table[i] = inv_color_step 00136 * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]) ; 00137 } 00138 00139 } /* end of void makeGammaTables(float gamma) */ 00140 00141 00142 00143 /* ------------------------------------------------------------------------- */ 00144 00145 /* eof */