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 }