Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pnmimagetypes/colrops.c

Go to the documentation of this file.
00001 /* Filename: colrops.c
00002  * Created by:  
00003  *
00004  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
00005  *
00006  * PANDA 3D SOFTWARE
00007  * Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008  *
00009  * All use of this software is subject to the terms of the Panda 3d
00010  * Software license.  You should have received a copy of this license
00011  * along with this source code; you will also find a current copy of
00012  * the license at http://www.panda3d.org/license.txt .
00013  *
00014  * To contact the maintainers of this program write to
00015  * panda3d@yahoogroups.com .
00016  *
00017  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00018 
00019 /*
00020  * Integer operations on COLR scanlines
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              /* maximum shift for gamma table */
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                 /* set brightness correction */
00052 {
00053         double  mult;
00054         register int    i, j;
00055                                         /* allocate tables */
00056         if (g_bval == NULL && (g_bval =
00057                         (BYTE (*)[256])bmalloc((MAXGSHIFT+1)*256)) == NULL)
00058                 return(-1);
00059                                         /* compute colr -> gamb mapping */
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                 /* set inverse brightness correction */
00072 {
00073         double  mult;
00074         register int    i, j;
00075                                         /* allocate tables */
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                                         /* compute gamb -> colr mapping */
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)                        /* set gamma conversion */
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                 /* convert scanline of colrs to gamma bytes */
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         /* convert gamma bytes to colr scanline */
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         /* shift a scanline of colors by 2^adjust */
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 /* normalize a scanline of colrs */
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 }

Generated on Fri May 2 00:43:11 2003 for Panda by doxygen1.3