00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 #include <qimage.h>
00021 #include <math.h>
00022 
00023 void
00024 mult(float a[3][3], 
00025      float b[3][3], 
00026      float c[3][3]) 
00027 {
00028   int   x, y;       
00029   float temp[3][3]; 
00030 
00031 
00032  
00033 
00034 
00035 
00036   for (y = 0; y < 3; y ++)
00037     for (x = 0; x < 3; x ++)
00038       temp[y][x] = b[y][0] * a[0][x] +
00039                    b[y][1] * a[1][x] +
00040                    b[y][2] * a[2][x];
00041 
00042  
00043 
00044 
00045 
00046   memcpy(c, temp, sizeof(temp));
00047 }
00048 
00049 void
00050 saturate(float mat[3][3],   
00051          float sat)     
00052 {
00053   float smat[3][3];     
00054 
00055 
00056   smat[0][0] = (1.0 - sat) * 0.3086 + sat;
00057   smat[0][1] = (1.0 - sat) * 0.3086;
00058   smat[0][2] = (1.0 - sat) * 0.3086;
00059   smat[1][0] = (1.0 - sat) * 0.6094;
00060   smat[1][1] = (1.0 - sat) * 0.6094 + sat;
00061   smat[1][2] = (1.0 - sat) * 0.6094;
00062   smat[2][0] = (1.0 - sat) * 0.0820;
00063   smat[2][1] = (1.0 - sat) * 0.0820;
00064   smat[2][2] = (1.0 - sat) * 0.0820 + sat;
00065 
00066   mult(smat, mat, mat);
00067 }
00068 
00069 void
00070 xform(float mat[3][3],  
00071       float x,      
00072       float y,      
00073       float z,      
00074       float *tx,    
00075       float *ty,    
00076       float *tz)    
00077 {
00078   *tx = x * mat[0][0] + y * mat[1][0] + z * mat[2][0];
00079   *ty = x * mat[0][1] + y * mat[1][1] + z * mat[2][1];
00080   *tz = x * mat[0][2] + y * mat[1][2] + z * mat[2][2];
00081 }
00082 
00083 void
00084 xrotate(float mat[3][3],    
00085         float rs,       
00086         float rc)       
00087 {
00088   float rmat[3][3];     
00089 
00090 
00091   rmat[0][0] = 1.0;
00092   rmat[0][1] = 0.0;
00093   rmat[0][2] = 0.0;
00094 
00095   rmat[1][0] = 0.0;
00096   rmat[1][1] = rc;
00097   rmat[1][2] = rs;
00098 
00099   rmat[2][0] = 0.0;
00100   rmat[2][1] = -rs;
00101   rmat[2][2] = rc;
00102 
00103   mult(rmat, mat, mat);
00104 }
00105 
00106 void
00107 yrotate(float mat[3][3],    
00108         float rs,       
00109         float rc)       
00110 {
00111   float rmat[3][3];     
00112 
00113 
00114   rmat[0][0] = rc;
00115   rmat[0][1] = 0.0;
00116   rmat[0][2] = -rs;
00117 
00118   rmat[1][0] = 0.0;
00119   rmat[1][1] = 1.0;
00120   rmat[1][2] = 0.0;
00121 
00122   rmat[2][0] = rs;
00123   rmat[2][1] = 0.0;
00124   rmat[2][2] = rc;
00125 
00126   mult(rmat,mat,mat);
00127 }
00128 
00129 void
00130 zrotate(float mat[3][3],    
00131         float rs,       
00132         float rc)       
00133 {
00134   float rmat[3][3];     
00135 
00136 
00137   rmat[0][0] = rc;
00138   rmat[0][1] = rs;
00139   rmat[0][2] = 0.0;
00140 
00141   rmat[1][0] = -rs;
00142   rmat[1][1] = rc;
00143   rmat[1][2] = 0.0;
00144 
00145   rmat[2][0] = 0.0;
00146   rmat[2][1] = 0.0;
00147   rmat[2][2] = 1.0;
00148 
00149   mult(rmat,mat,mat);
00150 }
00151 
00152 void
00153 zshear(float mat[3][3], 
00154        float dx,    
00155        float dy)    
00156 {
00157   float smat[3][3]; 
00158 
00159 
00160   smat[0][0] = 1.0;
00161   smat[0][1] = 0.0;
00162   smat[0][2] = dx;
00163 
00164   smat[1][0] = 0.0;
00165   smat[1][1] = 1.0;
00166   smat[1][2] = dy;
00167 
00168   smat[2][0] = 0.0;
00169   smat[2][1] = 0.0;
00170   smat[2][2] = 1.0;
00171 
00172   mult(smat, mat, mat);
00173 }
00174 
00175 void
00176 huerotate(float mat[3][3],  
00177           float rot)        
00178 {
00179   float hmat[3][3] = {{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}};       
00180   float lx, ly, lz;     
00181   float xrs, xrc;       
00182   float yrs, yrc;       
00183   float zrs, zrc;       
00184   float zsx, zsy;       
00185 
00186 
00187  
00188 
00189 
00190 
00191   xrs = M_SQRT1_2;
00192   xrc = M_SQRT1_2;
00193   xrotate(hmat,xrs,xrc);
00194 
00195   yrs = -1.0 / sqrt(3.0);
00196   yrc = -M_SQRT2 * yrs;
00197   yrotate(hmat,yrs,yrc);
00198 
00199  
00200 
00201 
00202 
00203   xform(hmat, 0.3086, 0.6094, 0.0820, &lx, &ly, &lz);
00204   zsx = lx / lz;
00205   zsy = ly / lz;
00206   zshear(hmat, zsx, zsy);
00207 
00208  
00209 
00210 
00211 
00212   zrs = sin(rot * M_PI / 180.0);
00213   zrc = cos(rot * M_PI / 180.0);
00214 
00215   zrotate(hmat, zrs, zrc);
00216 
00217  
00218 
00219 
00220 
00221   zshear(hmat, -zsx, -zsy);
00222 
00223  
00224 
00225 
00226 
00227   yrotate(hmat, -yrs, yrc);
00228   xrotate(hmat, -xrs, xrc);
00229 
00230  
00231 
00232 
00233 
00234   mult(hmat, mat, mat);
00235 }
00236 
00237 void
00238 bright(float mat[3][3],
00239        float scale)
00240 {
00241   for (int i=0;i<3;i++)
00242     for (int j=0;j<3;j++)
00243       mat[i][j] *= scale;
00244 }
00245 
00246 
00247 
00248 QImage convertImage(const QImage& image, int hue, int saturation, int brightness, int gamma)
00249 {
00250     float   mat[3][3] = {{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0}};
00251     int lut[3][3][256];
00252     QRgb    c;
00253     int r,g,b,v,r2,g2,b2;
00254     float   gam = 1.0/(float(gamma)/1000.0);
00255     QImage  img(image);
00256 
00257     saturate(mat,saturation*0.01);
00258     huerotate(mat,(float)hue);
00259     bright(mat,brightness*0.01);
00260     for (int i = 0; i < 3; i ++)
00261       for (int j = 0; j < 3; j ++)
00262         for (int k = 0; k < 256; k ++)
00263         lut[i][j][k] = (int)(mat[i][j] * k + 0.5);
00264     
00265     img.detach();
00266     for (int i=0;i<image.width();i++)
00267        for (int j=0;j<image.height();j++)
00268        {
00269         c = image.pixel(i,j);
00270         r = qRed(c);
00271         g = qGreen(c);
00272         b = qBlue(c);
00273 
00274         v = lut[0][0][r] + lut[1][0][g] + lut[2][0][b];
00275         if (gamma != 1000) v = (int)rint(pow(v,gam));
00276         if (v < 0) r2 = 0;
00277         else if (v > 255) r2 = 255;
00278         else r2 = v;
00279 
00280         v = lut[0][1][r] + lut[1][1][g] + lut[2][1][b];
00281         if (gamma != 1000) v = (int)rint(pow(v,gam));
00282         if (v < 0) g2 = 0;
00283         else if (v > 255) g2 = 255;
00284         else g2 = v;
00285 
00286         v = lut[0][2][r] + lut[1][2][g] + lut[2][2][b];
00287         if (gamma != 1000) v = (int)rint(pow(v,gam));
00288         if (v < 0) b2 = 0;
00289         else if (v > 255) b2 = 255;
00290         else b2 = v;
00291 
00292         img.setPixel(i,j,qRgb(r2,g2,b2));
00293        }
00294     return img;
00295 }