#include <windows.h>
#include
<iostream>
#include
<math.h>
#include
<assert.h>
#include
<omp.h>
using namespace std;
#define M_PI 3.14159265358979323846
struct RBG{
BYTE b,g,r;
}mm[
2000][2000],aftr[7000][8000];
struct fRBG{
double b,g,r;
}aft[
7000][8000];

struct HSI{
double h,s,i;
}hs[
2000][2000];
BITMAPFILEHEADER bh;
BITMAPINFOHEADER bi;
__inline
double Min( double a,double b,double c){
double d = min(a,b);
return min(d,c);
}
__inline
double SUMRBG(double a,double b,double c){
return (double)a+b+c<=0?0:( (double)a+b+c);
}
__inline
void NormalRGB(double& a,double& b,double& c){


a
/=255;
b
/=255;
c
/=255;
}
void toHSI(){
double sita;
double bug,bug2;
double x,y,r,I;
fRBG tmp;
memset(hs,
0,sizeof(hs));

for(int i = 0; i < bi.biHeight; i++)
for(int j = 0; j < bi.biWidth; j++){

tmp.b
= mm[i][j].b;
tmp.r
= mm[i][j].r;
tmp.g
= mm[i][j].g;

x
= tmp.r-(tmp.g+tmp.b)*cos(M_PI/3);
y
= (tmp.g-tmp.b)*sin(M_PI/3);

r
= sqrt(x*x+y*y);
sita
= atan(y/x);

I
= sqrt(tmp.r*tmp.r+tmp.g*tmp.g+tmp.b*tmp.b);
hs[i][j].h
= sita;
hs[i][j].s
= r;
hs[i][j].i
= I;

}
}
fRBG getRGB(HSI
& t){
fRBG ret;
ret.b
= ret.g = ret.r = 0;

double h,s,i,x,y,ta,tb,r,g,b;
h
= t.h;
s
= t.s;
i
= t.i;

x
= s*cos(h);
y
= s*sin(h);
ta
= x - y/1.7320508075688772935274463415059;
tb
= x + y/1.7320508075688772935274463415059;

r
= ((ta+tb)+sqrt((ta+tb)*(ta+tb)+3*(i*i-ta*ta-tb*tb)))/3;
g
= r - ta;
b
= r - tb;
ret.r
= r;
ret.g
= g;
ret.b
= b;

return ret;
}
double getDuoLine(double a,double b,double ap){
return a*( 1 - ap) + b*(ap);
}
bool isSameH(double a,double b){
if(b == 0)
return true;
double m = 2* M_PI;
bool is = false;
if(a <= m / 3 ){
if(b <= m / 3)
return true;
else return false;
}
if(a <= m / 3 * 2){
if(b > m/ 3 && b <= m / 3 *2 )
return true;
else return false;
}
if(b > m/3*2)
return true;
else return false;

}
__inline
float lanczos(int filter_size, float x) {
if (x <= -filter_size || x >= filter_size)
return 0.0f; // Outside of the window.

if (x > -1e-8 &&
x
< 1e-8)
return 1.0f; // Special case the discontinuity at the origin.
float xpi = x * M_PI;
return (sin(xpi)* filter_size / xpi) * // sinc(x)
sin(xpi / filter_size) / (xpi ); // sinc(x/filter_size)
}
__inline
float spline4(float t){
if(t < -2 || t > 2)
return 0;
if(fabs(t) <1e-8)
return 1;
if(t < 0)
return (t+1)*(t+1)-1;
if(t > 0)
return 1 - (t - 1)*(t - 1);
}

void toRBG(){
HSI t,t1;
double th,tw,y1,y2;
const double objH = bi.biHeight*4;
const double objW = bi.biWidth * 4;
for(int i = 0; i < objH; i++){
printf(
"\b\b\b\b\b%.1lf",i*1.0/objH);

#pragma omp parallel for
for(int j = 0; j < (int)objW; j++){
double aw = bi.biHeight / objH *i;
double ah = bi.biWidth / objW *j ;
double cnt = 0;
HSI t2;
//三次卷积


t2.h
= t2.i = t2.s = cnt=0;
/*
for(int k = int(aw)-1 ; k <= int(aw)+2;k++)
for(int t= int(ah)-1;t <= int(ah)+2;t++){
if(k < 0 || t < 0)
continue;

y1 = spline4(aw - k);
y2 = spline4(ah - t);
// y1 = y1 < 0?0:y1;
// y2 = y2 < 0?0:y2;

t2.h += y2*y1*hs[k][t].h;
t2.s += y2*y1*hs[k][t].s;
t2.i += y2*y1*hs[k][t].i;

}
*/
//二次插值

t.h
= getDuoLine(hs[int(aw)][int(ah)].h,hs[int(aw)+1][int(ah)].h,aw - int(aw));
t.s
= getDuoLine(hs[int(aw)][int(ah)].s,hs[int(aw)+1][int(ah)].s,aw - int(aw));
t.i
= getDuoLine(hs[int(aw)][int(ah)].i,hs[int(aw)+1][int(ah)].i,aw - int(aw));

t1.h
= getDuoLine(hs[int(aw)][int(ah)+1].h,hs[int(aw)+1][int(ah)+1].h,aw - int(aw));
t1.s
= getDuoLine(hs[int(aw)][int(ah)+1].s,hs[int(aw)+1][int(ah)+1].s,aw - int(aw));
t1.i
= getDuoLine(hs[int(aw)][int(ah)+1].i,hs[int(aw)+1][int(ah)+1].i,aw - int(aw));

t2.h
= getDuoLine(t.h,t1.h,ah - int(ah));
t2.s
= getDuoLine(t.s,t1.s,ah - int(ah));
t2.i
= getDuoLine(t.i,t1.i,ah - int(ah));

//不变换
// t2.i = hs[int(aw)][int(ah)].i;
// t2.s = hs[int(aw)][int(ah)].s;
// t2.h = hs[int(aw)][int(ah)].h;
//
/*
if(cnt!=0){
t2.h *= cnt;
t2.i *= cnt;
t2.s *= cnt;
}
*/
/*
if(t2.h < 0)
t2.h = 0;
if(t2.i < 0)
t2.i = 0;
if(t2.s < 0)
t2.s = 0;
*/
aft[i][j]
= getRGB(t2);
aftr[i][j].r
= int(aft[i][j].r)&255;
aftr[i][j].g
= int(aft[i][j].g)&255;
aftr[i][j].b
= int(aft[i][j].b)&255;
if(aftr[i][j].r >= 250)
aftr[i][j].r
= 250;
if(aftr[i][j].g >= 250)
aftr[i][j].g
= 250;
if(aftr[i][j].b >= 250)
aftr[i][j].b
= 250;

}
}
}
void readBMP(){

FILE
* fp = fopen("d:/1.bmp","rb");
fread(
&bh,sizeof(bh),1,fp);
fread(
&bi,sizeof(bi),1,fp);
for(int i = 0 ;i < bi.biHeight; i ++)
fread(
&mm[i],sizeof(RBG),bi.biWidth,fp);

fclose(fp);
}
void writeBMP(){

bi.biHeight
*= 4;
bi.biWidth
*= 4;

FILE
* fp = fopen("d:/2.bmp","wb");
fwrite(
&bh,sizeof(bh),1,fp);
fwrite(
&bi,sizeof(bi),1,fp);
for(int i = 0 ;i < bi.biHeight; i ++)
fwrite(
&aftr[i],sizeof(RBG),bi.biWidth,fp);

fclose(fp);
}
int main(){
readBMP();
toHSI();
toRBG();
writeBMP();
return 0;
}