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