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 }