00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "color.h"
00020
00021 #ifndef NULL
00022 #define NULL 0
00023 #endif
00024
00025 #define bmalloc malloc
00026 #if !defined(WIN32_VC) && !defined(WIN64_VC)
00027 extern char *bmalloc(int);
00028 #else
00029 #include <malloc.h>
00030 #include <math.h>
00031 #endif
00032
00033 #define MAXGSHIFT 31
00034
00035 static BYTE *g_mant = NULL, *g_nexp = NULL;
00036
00037 static BYTE (*g_bval)[256] = NULL;
00038
00039 #ifndef pow
00040 #if !defined(WIN32_VC) && !defined(WIN64_VC)
00041 extern double pow(double, double);
00042 #endif
00043 #endif
00044
00045
00046 int setcolrcor(double (*f)(double, double), double a2)
00047
00048 {
00049 double mult;
00050 register int i, j;
00051
00052 if (g_bval == NULL && (g_bval =
00053 (BYTE (*)[256])bmalloc((MAXGSHIFT+1)*256)) == NULL)
00054 return(-1);
00055
00056 mult = 1.0/256.0;
00057 for (i = 0; i <= MAXGSHIFT; i++) {
00058 for (j = 0; j < 256; j++)
00059 g_bval[i][j] = (BYTE) (256.0 * (*f)((j+.5)*mult, a2));
00060 mult *= 0.5;
00061 }
00062 return(0);
00063 }
00064
00065
00066 int setcolrinv(double (*f)(double, double), double a2)
00067
00068 {
00069 double mult;
00070 register int i, j;
00071
00072 if (g_mant == NULL && (g_mant = (BYTE *)bmalloc(256)) == NULL)
00073 return(-1);
00074 if (g_nexp == NULL && (g_nexp = (BYTE *)bmalloc(256)) == NULL)
00075 return(-1);
00076
00077 i = 0;
00078 mult = 256.0;
00079 for (j = 255; j > 0; j--) {
00080 while ((g_mant[j] = (BYTE)(mult * (*f)(j/256.0, a2))) < 128) {
00081 i++;
00082 mult *= 2.0;
00083 }
00084 g_nexp[j] = i;
00085 }
00086 g_mant[0] = 0;
00087 g_nexp[0] = COLXS;
00088 return(0);
00089 }
00090
00091
00092 int setcolrgam(double g)
00093 {
00094 if (setcolrcor(pow, 1.0/g) < 0)
00095 return(-1);
00096 return(setcolrinv(pow, g));
00097 }
00098
00099
00100 int colrs_gambs(register COLR *scan, int len)
00101
00102 {
00103 register int i, expo;
00104
00105 if (g_bval == NULL)
00106 return(-1);
00107 while (len-- > 0) {
00108 expo = scan[0][EXP] - COLXS;
00109 if (expo < -MAXGSHIFT) {
00110 if (expo < -MAXGSHIFT-8) {
00111 scan[0][RED] =
00112 scan[0][GRN] =
00113 scan[0][BLU] = 0;
00114 } else {
00115 i = (-MAXGSHIFT-1) - expo;
00116 scan[0][RED] =
00117 g_bval[MAXGSHIFT][((scan[0][RED]>>i)+1)>>1];
00118 scan[0][GRN] =
00119 g_bval[MAXGSHIFT][((scan[0][GRN]>>i)+1)>>1];
00120 scan[0][BLU] =
00121 g_bval[MAXGSHIFT][((scan[0][BLU]>>i)+1)>>1];
00122 }
00123 } else if (expo > 0) {
00124 if (expo > 8) {
00125 scan[0][RED] =
00126 scan[0][GRN] =
00127 scan[0][BLU] = 255;
00128 } else {
00129 i = (scan[0][RED]<<1 | 1) << (expo-1);
00130 scan[0][RED] = i > 255 ? 255 : g_bval[0][i];
00131 i = (scan[0][GRN]<<1 | 1) << (expo-1);
00132 scan[0][GRN] = i > 255 ? 255 : g_bval[0][i];
00133 i = (scan[0][BLU]<<1 | 1) << (expo-1);
00134 scan[0][BLU] = i > 255 ? 255 : g_bval[0][i];
00135 }
00136 } else {
00137 scan[0][RED] = g_bval[-expo][scan[0][RED]];
00138 scan[0][GRN] = g_bval[-expo][scan[0][GRN]];
00139 scan[0][BLU] = g_bval[-expo][scan[0][BLU]];
00140 }
00141 scan[0][EXP] = COLXS;
00142 scan++;
00143 }
00144 return(0);
00145 }
00146
00147
00148 int gambs_colrs(register COLR *scan, int len)
00149
00150 {
00151 register int nexpo;
00152
00153 if (g_mant == NULL || g_nexp == NULL)
00154 return(-1);
00155 while (len-- > 0) {
00156 nexpo = g_nexp[scan[0][RED]];
00157 if (g_nexp[scan[0][GRN]] < nexpo)
00158 nexpo = g_nexp[scan[0][GRN]];
00159 if (g_nexp[scan[0][BLU]] < nexpo)
00160 nexpo = g_nexp[scan[0][BLU]];
00161 if (nexpo < g_nexp[scan[0][RED]])
00162 scan[0][RED] = g_mant[scan[0][RED]]
00163 >> (g_nexp[scan[0][RED]]-nexpo);
00164 else
00165 scan[0][RED] = g_mant[scan[0][RED]];
00166 if (nexpo < g_nexp[scan[0][GRN]])
00167 scan[0][GRN] = g_mant[scan[0][GRN]]
00168 >> (g_nexp[scan[0][GRN]]-nexpo);
00169 else
00170 scan[0][GRN] = g_mant[scan[0][GRN]];
00171 if (nexpo < g_nexp[scan[0][BLU]])
00172 scan[0][BLU] = g_mant[scan[0][BLU]]
00173 >> (g_nexp[scan[0][BLU]]-nexpo);
00174 else
00175 scan[0][BLU] = g_mant[scan[0][BLU]];
00176 scan[0][EXP] = COLXS - nexpo;
00177 scan++;
00178 }
00179 return(0);
00180 }
00181
00182
00183 void
00184 shiftcolrs(register COLR *scan, register int len, register int adjust)
00185
00186 {
00187 int minexp;
00188
00189 if (adjust == 0)
00190 return;
00191 minexp = adjust < 0 ? -adjust : 0;
00192 while (len-- > 0) {
00193 if (scan[0][EXP] <= minexp)
00194 scan[0][RED] = scan[0][GRN] = scan[0][BLU] =
00195 scan[0][EXP] = 0;
00196 else
00197 scan[0][EXP] += adjust;
00198 scan++;
00199 }
00200 }
00201
00202
00203 void
00204 normcolrs(register COLR *scan, int len, int adjust)
00205
00206 {
00207 register int c;
00208 register int shift;
00209
00210 while (len-- > 0) {
00211 shift = scan[0][EXP] + adjust - COLXS;
00212 if (shift > 0) {
00213 if (shift > 8) {
00214 scan[0][RED] =
00215 scan[0][GRN] =
00216 scan[0][BLU] = 255;
00217 } else {
00218 shift--;
00219 c = (scan[0][RED]<<1 | 1) << shift;
00220 scan[0][RED] = c > 255 ? 255 : c;
00221 c = (scan[0][GRN]<<1 | 1) << shift;
00222 scan[0][GRN] = c > 255 ? 255 : c;
00223 c = (scan[0][BLU]<<1 | 1) << shift;
00224 scan[0][BLU] = c > 255 ? 255 : c;
00225 }
00226 } else if (shift < 0) {
00227 if (shift < -8) {
00228 scan[0][RED] =
00229 scan[0][GRN] =
00230 scan[0][BLU] = 0;
00231 } else {
00232 shift = -1-shift;
00233 scan[0][RED] = ((scan[0][RED]>>shift)+1)>>1;
00234 scan[0][GRN] = ((scan[0][GRN]>>shift)+1)>>1;
00235 scan[0][BLU] = ((scan[0][BLU]>>shift)+1)>>1;
00236 }
00237 }
00238 scan[0][EXP] = COLXS - adjust;
00239 scan++;
00240 }
00241 }