0001:
0002:
0003:
0004:
0005:
0006: #include "ipcommon.h"
0007:
0008:
0009:
0010:
0011: int lcm(int a,int b)
0012: {
0013: int x=a,y=b,c;
0014: if(a<=0||b<=0) return 1;
0015: if(a<b) swapv(a,b);
0016: if(a<b){ c=a; a=b; b=c; }
0017: while(b!=0){ c=a%b; a=b; b=c; }
0018: return (x*y/a);
0019: }
0020:
0021:
0022:
0023: void init_random()
0024: {
0025: int seed = time(NULL);
0026: if(seed<1) seed=1;
0027: srand(seed);
0028: }
0029: int random_int(int n)
0030: {
0031: return rint((double)rand()/((double)RAND_MAX+1.0)*n);
0032: }
0033:
0034:
0035:
0036: void swapv(int c1,int c2)
0037: {
0038: int c=c1; c1=c2; c2=c;
0039: }
0040:
0041: void swap_point(POINT p1,POINT p2)
0042: {
0043: POINT p={0,0};
0044: p.x = p1.x; p.x = p1.y;
0045: p1.x = p2.x; p1.y = p2.y;
0046: p2.x = p.x; p2.y = p.y;
0047: }
0048:
0049:
0050:
0051: int colcmp(LPBYTE inb,CPIXEL c)
0052: {
0053: if(*(inb+2)==c.r && *(inb+1)==c.g && *(inb+0)==c.b)
0054: return 1;
0055: return 0;
0056: }
0057:
0058:
0059:
0060: void setcol(LPBYTE inb,CPIXEL c)
0061: {
0062: *(inb+2) = c.r;
0063: *(inb+1) = c.g;
0064: *(inb+0) = c.b;
0065: }
0066:
0067:
0068:
0069: double calc_distance(POINT p1,POINT p2)
0070: {
0071: return sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
0072: }
0073: double calc_distance(int x1,int y1,int x2,int y2)
0074: {
0075: return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
0076: }
0077:
0078:
0079:
0080: double calc_mean(int n,double* a)
0081: {
0082: int i; double mean=0;
0083: for(i=0;i<n;i++) mean += a[i];
0084: return mean/n;
0085: }
0086:
0087:
0088:
0089: double calc_sd(int n,double* a)
0090: {
0091: int i;
0092: double sd=0,mean=calc_mean(n,a);
0093: for(i=0;i<n;i++) sd+=(a[i]*a[i]);
0094: sd -= n*mean*mean;
0095: sd /= (double)n;
0096: return sqrt(sd);
0097: }
0098:
0099:
0100:
0101: void standalize_data(int n,double* a)
0102: {
0103: int i;
0104: double mv=calc_mean(n,a);
0105: double sd=calc_sd(n,a);
0106: for(i=0;i<n;i++)
0107: a[i] = (a[i]-mv)/sd;
0108: }
0109:
0110:
0111:
0112: void normalize_data(int n,double* a)
0113: {
0114: int i; double maxv,minv;
0115: maxv = -10000.; minv = 10000.;
0116: for(i=0;i<n;i++){
0117: if(a[i]-maxv > 0) maxv = a[i];
0118: if(a[i]-minv < 0) minv = a[i];
0119: }
0120:
0121: for(i=0;i<n;i++)
0122: a[i] = maxv*(a[i]-minv) / fabs(maxv-minv);
0123: }
0124:
0125:
0126:
0127:
0128: BYTE rgb2gray(BYTE r,BYTE g,BYTE b)
0129: {
0130: int gray=rint(r*0.299+g*0.587+b*0.144);
0131: if(gray>iWHITE) gray=iWHITE;
0132: return gray;
0133: }
0134:
0135:
0136:
0137: void rgb2yuv(BYTE r,BYTE g,BYTE b,BYTE &y,BYTE &u,BYTE &v)
0138: {
0139: double yv,uv,vv;
0140: yv = (0.2989 *(r+175.45)+0.5871*(g-132.40)+0.1140*(b+221.74));
0141: uv = (0.5115 *(r+175.45)-0.4283*(g-132.40)-0.0832*(b+221.74));
0142: vv = (-0.1726*(r+175.45)-0.3389*(g-132.40)+0.5114*(b+221.74));
0143: if(yv>iWHITE) yv=iWHITE; if(yv<0) yv=0;
0144: if(uv>iWHITE) uv=iWHITE; if(uv<0) uv=0;
0145: if(vv>iWHITE) vv=iWHITE; if(vv<0) vv=0;
0146: y = (BYTE)yv; u = (BYTE)uv; v = (BYTE)vv;
0147: }
0148: BYTE rgb2y(BYTE r,BYTE g,BYTE b)
0149: {
0150: double yv;
0151: yv = (0.2989 *(r+175.45)+0.5871*(g-132.40)+0.1140*(b+221.74));
0152: if(yv>iWHITE) yv=iWHITE; if(yv<0) yv=0;
0153: return (BYTE)yv;
0154: }
0155: BYTE rgb2u(BYTE r,BYTE g,BYTE b)
0156: {
0157: double uv;
0158: uv = (0.5115 *(r+175.45)-0.4283*(g-132.40)-0.0832*(b+221.74));
0159: if(uv>iWHITE) uv=iWHITE; if(uv<0) uv=0;
0160: return (BYTE)uv;
0161: }
0162: BYTE rgb2v(BYTE r,BYTE g,BYTE b)
0163: {
0164: double vv;
0165: vv = (-0.1726*(r+175.45)-0.3389*(g-132.40)+0.5114*(b+221.74));
0166: if(vv>iWHITE) vv=iWHITE; if(vv<0) vv=0;
0167: return (BYTE)vv;
0168: }
0169:
0170:
0171:
0172: void rgb2rth(BYTE r,BYTE g,BYTE b,BYTE &rho,BYTE &th)
0173: {
0174:
0175: BYTE y,u,v;
0176: rgb2yuv(r,g,b,y,u,v);
0177:
0178: double tmp1,tmp2,rhov,thv;
0179: tmp1=u-128.; tmp2=v-128.;
0180: rhov = sqrt(tmp1*tmp1+tmp2*tmp2);
0181: thv = rad2deg(atan2(tmp1,tmp2));
0182: if(rhov<0) rhov=0; if(rhov>180) rhov=180;
0183: if(thv<0) thv+=360; if(thv>360) thv-=360;
0184: rhov = (double)iWHITE*(rhov)/(180.);
0185: thv = (double)iWHITE*(thv) /(360.);
0186: rho = (BYTE)rhov;
0187: th = (BYTE)thv;
0188: }
0189: BYTE rgb2rho(BYTE r,BYTE g,BYTE b)
0190: {
0191:
0192: BYTE y,u,v;
0193: rgb2yuv(r,g,b,y,u,v);
0194:
0195: double tmp1,tmp2,rhov;
0196: tmp1=u-128.; tmp2=v-128.;
0197: rhov = sqrt(tmp1*tmp1+tmp2*tmp2);
0198: if(rhov<0) rhov=0; if(rhov>180) rhov=180;
0199: rhov = (double)iWHITE*(rhov)/(180.);
0200: return (BYTE)rhov;
0201: }
0202: BYTE rgb2theta(BYTE r,BYTE g,BYTE b)
0203: {
0204:
0205: BYTE y,u,v;
0206: rgb2yuv(r,g,b,y,u,v);
0207:
0208: double tmp1,tmp2,thv;
0209: tmp1=u-128.; tmp2=v-128.;
0210: thv = rad2deg(atan2(tmp1,tmp2));
0211: if(thv<0) thv+=360; if(thv>360) thv-=360;
0212: thv = (double)iWHITE*(thv) /(360.);
0213: return (BYTE)thv;
0214: }
0215:
0216:
0217:
0218:
0219: void draw_circle(LPBYTE oBuf,POINT cp,int radius)
0220: {
0221: int xs,ys,th,th_max;
0222: double cirstep;
0223:
0224: th_max = rint(2*M_PI*radius);
0225: cirstep = 360./th_max;
0226: for(th=0;th<th_max/2.;th++){
0227: xs = rint(cp.x + radius * cos(deg2rad(cirstep*th)));
0228: ys = rint(cp.y + radius * sin(deg2rad(cirstep*th)));
0229: if(ip_safe(xs,ys,iWidth,iHeight))
0230: oBuf[XY1D(xs,ys,iWidth)] = iWHITE;
0231: xs = rint(cp.x + radius * cos(deg2rad(360-cirstep*th)));
0232: ys = rint(cp.y + radius * sin(deg2rad(360-cirstep*th)));
0233: if(ip_safe(xs,ys,iWidth,iHeight))
0234: oBuf[XY1D(xs,ys,iWidth)] = iWHITE;
0235: }
0236: }
0237:
0238:
0239:
0240: void draw_line(LPBYTE oBuf,POINT p1,POINT p2,int col)
0241: {
0242: draw_line(oBuf,p1.x,p1.y,p2.x,p2.y,col);
0243: }
0244: void draw_line(LPBYTE oBuf,int x1,int y1,int x2,int y2,int col)
0245: {
0246: int xp,yp;
0247: double distance,step,t;
0248: int dx1,dx2,dy1,dy2;
0249: dx1 = x1; dx2 = x2; dy1 = y1; dy2 = y2;
0250:
0251: if(scrossln(&dx1,&y1,&x2,&y2)==0) return;
0252:
0253: t = 0.0;
0254: distance = calc_distance(dx1,dy1,dx2,dy2);
0255: step = 1.0/(1.5*distance);
0256: while(t<0.5){
0257: xp = rint(t*dx2 + (1.0-t)*dx1);
0258: yp = rint(t*dy2 + (1.0-t)*dy1);
0259: if(ip_safe(xp,yp,iWidth,iHeight))
0260: oBuf[XY1D(xp,yp,iWidth)] = col;
0261: xp = rint((1.0-t)*dx2 + t*dx1);
0262: yp = rint((1.0-t)*dy2 + t*dy1);
0263: if(ip_safe(xp,yp,iWidth,iHeight))
0264: oBuf[XY1D(xp,yp,iWidth)] = col;
0265: t = t + step;
0266: }
0267: }
0268: void c_draw_line(LPBYTE oBuf,int x1,int y1,int x2,int y2)
0269: {
0270: CPIXEL col={iWHITE,iWHITE,iWHITE};
0271: c_draw_line(oBuf,x1,y1,x2,y2,col);
0272: }
0273: void c_draw_line(LPBYTE oBuf,int x1,int y1,int x2,int y2,CPIXEL col)
0274: {
0275: int xp,yp;
0276: double distance,step,t;
0277: int dx1,dx2,dy1,dy2;
0278: dx1 = x1; dx2 = x2; dy1 = y1; dy2 = y2;
0279:
0280: if(scrossln(&dx1,&y1,&x2,&y2)==0) return;
0281:
0282: t = 0.0;
0283: distance = calc_distance(dx1,dy1,dx2,dy2);
0284: step = 1.0/(1.5*distance);
0285: while(t<0.5){
0286: xp = rint(t*dx2 + (1.0-t)*dx1);
0287: yp = rint(t*dy2 + (1.0-t)*dy1);
0288: if(ip_safe(xp,yp,iWidth,iHeight)){
0289: oBuf[XY1D(xp*3,yp,iLength)+0] = col.b;
0290: oBuf[XY1D(xp*3,yp,iLength)+1] = col.g;
0291: oBuf[XY1D(xp*3,yp,iLength)+2] = col.r;
0292: }
0293: xp = rint((1.0-t)*dx2 + t*dx1);
0294: yp = rint((1.0-t)*dy2 + t*dy1);
0295: if(ip_safe(xp,yp,iWidth,iHeight)){
0296: oBuf[XY1D(xp*3,yp,iLength)+0] = col.b;
0297: oBuf[XY1D(xp*3,yp,iLength)+1] = col.g;
0298: oBuf[XY1D(xp*3,yp,iLength)+2] = col.r;
0299: }
0300: t = t + step;
0301: }
0302: }
0303:
0304:
0305:
0306: int croslnxc(int x1,int y1,int x2,int y2,int xc,int *yc)
0307: {
0308: double wk;
0309: if(y1 == y2){ *yc = y1; return 1; }
0310: if(x1 == x2){ *yc = 0; return -1; }
0311: if(x1 != x2){
0312: wk = (y2-y1)/(x2-x1);
0313: *yc = rint(wk*(xc-x1)+y1);
0314: return 1;
0315: }
0316: return 0;
0317: }
0318:
0319:
0320:
0321: int croslnyc(int x1,int y1,int x2,int y2,int yc,int *xc)
0322: {
0323: double wk;
0324: if(x1 == x2){ *xc = x1; return 1; }
0325: if(y1 == y2){ *xc = 0; return -1; }
0326: if(x1 != x2){
0327: wk = (y2-y1)/(x2-x1);
0328: *xc = rint(x1+(yc-y1)/wk);
0329: return 1;
0330: }
0331: return 0;
0332: }
0333:
0334:
0335:
0336:
0337: int scrossln(int* x1,int* y1,int* x2,int* y2)
0338: {
0339: int dx1,dx2,dy1,dy2;
0340: int i,is,ip,mkp1,mkp2;
0341: int wk,xc,yc,xw1,xw2,yw1,yw2;
0342: int xx[2],yy[2],ds1[2],ds2[2];
0343: int gr_wnx[2],gr_wny[2];
0344:
0345:
0346:
0347: dx1 = *x1; dx2 = *x2; dy1 = *y1; dy2 = *y2;
0348: for(i=0;i<2;i++){
0349: xx[i] =0; yy[i] =0; ds1[i]=0; ds2[i]=0;
0350: }
0351: xw1=gr_wnx[0]=0; xw2=gr_wnx[1]=iWidth;
0352: yw1=gr_wny[0]=0; yw2=gr_wny[1]=iHeight;
0353: mkp1=mkp2=0;
0354:
0355:
0356:
0357: if(dx1>=xw1 && dx1<=xw2 && dy1>=yw1 && dy1<=yw2){
0358: *x1 = dx1; *y1 = dy1;
0359: mkp1 = 1;
0360: }
0361: if(dx2>=xw1 && dx2<=xw2 && dy2>=yw1 && dy2<=yw2){
0362: *x2 = dx2; *y2 = dy2;
0363: mkp2 = 1;
0364: }
0365:
0366:
0367:
0368: if(mkp1 == 1 && mkp2 == 1) return 1;
0369: ip = 0;
0370:
0371:
0372:
0373: for(i=0;i<2;i++){
0374: wk=gr_wnx[i];
0375: is=croslnxc(dx1,dy1,dx2,dy2,wk,&yc);
0376: if(is == 1 && yc>=yw1 && yc<=yw2){
0377: xx[ip] = wk; yy[ip] = yc;
0378: ip++;
0379: }
0380: }
0381:
0382:
0383:
0384: if(ip<2){
0385: for(i=0;i<2;i++){
0386: wk=gr_wny[i];
0387: is=croslnyc(dx1,dy1,dx2,dy2,wk,&xc);
0388: if(is == 1 && xc>=xw1 && xc<=xw2){
0389: xx[ip] = xc; yy[ip] = wk;
0390: ip++;
0391: }
0392: }
0393: }
0394:
0395:
0396:
0397:
0398: if(ip==0) return 0;
0399:
0400:
0401:
0402: for(i=0;i<2;i++){
0403: ds1[i] = ((xx[i]-dx1)*(xx[i]-dx1)+(yy[i]-dy1)*(yy[i]-dy1));
0404: ds2[i] = ((xx[i]-dx2)*(xx[i]-dx2)+(yy[i]-dy2)*(yy[i]-dy2));
0405: }
0406: if(mkp1 == 0){
0407: if(ds1[0]<ds1[1]){
0408: *x1 = xx[0]; *y1 = yy[0];
0409: }
0410: if(ds1[0]>ds1[1]){
0411: *x1 = xx[1]; *y1 = yy[1];
0412: }
0413: }
0414: if(mkp2 == 0){
0415: if(ds2[0]<ds2[1]){
0416: *x2 = xx[0]; *y2 = yy[0];
0417: }
0418: if(ds2[0]>ds2[1]){
0419: *x2 = xx[1]; *y2 = yy[1];
0420: }
0421: }
0422: return 1;
0423: }
0424:
0425:
0426:
0427: void mark_template_area(LPBYTE inBuf,POINT tp,int txsize,int tysize)
0428: {
0429: CPIXEL col={175,175,175},cBLK={0,0,0};
0430: int x,y,xstep=5,ystep=5;
0431: for(y=tp.y;y<tp.y+tysize;y++) for(x=tp.x;x<tp.x+txsize;x++){
0432: if(ip_safe(x,y,iWidth,iHeight)){
0433: inBuf[XY1D(3*x,y,iLength)+0] = iWHITE-inBuf[XY1D(3*x,y,iLength)+0];
0434: inBuf[XY1D(3*x,y,iLength)+1] = iWHITE-inBuf[XY1D(3*x,y,iLength)+1];
0435: inBuf[XY1D(3*x,y,iLength)+2] = iWHITE-inBuf[XY1D(3*x,y,iLength)+2];
0436: }
0437: }
0438:
0439: for(y=tp.y;y<tp.y+tysize;y+=ystep){
0440: c_draw_line(inBuf,tp.x,y,tp.x+txsize,y,col);
0441: }
0442: for(x=tp.x;x<tp.x+txsize;x+=xstep){
0443: c_draw_line(inBuf,x,tp.y,x,tp.y+tysize,col);
0444: }
0445: #if 0
0446:
0447: for(y=tp.y;y<=tp.y+tysize;y+=tysize){
0448: c_draw_line(inBuf,tp.x,y,tp.x+txsize,y,cBLK);
0449: }
0450: for(x=tp.x;x<=tp.x+txsize;x+=txsize){
0451: c_draw_line(inBuf,x,tp.y,x,tp.y+tysize,cBLK);
0452: }
0453: #endif
0454: }
0455:
0456:
0457:
0458:
0459:
0460:
0461: void make_histogram(LPBYTE inBuf)
0462: {
0463: int x,y;
0464: FillMemory(iGHist,sizeof(UINT)*iMAX_GRAY,0);
0465: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++)
0466: iGHist[inBuf[XY1D(x,y,iWidth)]]++;
0467: }
0468: void c_make_histogram(LPBYTE inBuf)
0469: {
0470: int i,x,y;
0471: for(i=0;i<3;i++)
0472: FillMemory(iCHist[i],sizeof(UINT)*iMAX_GRAY,0);
0473: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
0474: iCHist[0][inBuf[XY1D(x*3,y,iLength)+2]]++;
0475: iCHist[1][inBuf[XY1D(x*3,y,iLength)+1]]++;
0476: iCHist[2][inBuf[XY1D(x*3,y,iLength)+0]]++;
0477: }
0478: }
0479:
0480:
0481:
0482: void GrayToColor(LPBYTE iGray,LPBYTE iColor)
0483: {
0484: int x,y;
0485: int iadd=((iWidth*3)%4)?(4-(iWidth*3)%4):0;
0486:
0487: for(y=0;y<iHeight;y++){
0488: for(x=0;x<iWidth;x++) {
0489: FillMemory(iColor+XY1D(x*3,y,iLength),sizeof(CPIXEL),
0490: iGray[XY1D(x,y,iWidth)]);
0491: }
0492: FillMemory(iColor+XY1D(x*3,y,iLength),sizeof(BYTE)*iadd,0);
0493: }
0494: }
0495:
0496:
0497:
0498: void RGBToColor(LPBYTE icol,LPBYTE iR,LPBYTE iG,LPBYTE iB)
0499: {
0500: int x,y;
0501: int iadd=((iWidth*3)%4)?(4-(iWidth*3)%4):0;
0502:
0503: for(y=0;y<iHeight;y++){
0504: for(x=0;x<iWidth;x++) {
0505: icol[XY1D(x*3,y,iLength)+2] = iR[XY1D(x,y,iWidth)];
0506: icol[XY1D(x*3,y,iLength)+1] = iG[XY1D(x,y,iWidth)];
0507: icol[XY1D(x*3,y,iLength)+0] = iB[XY1D(x,y,iWidth)];
0508: }
0509: FillMemory(icol+XY1D(x*3,y,iLength),sizeof(BYTE)*iadd,0);
0510: }
0511: }
0512:
0513:
0514:
0515: void toGray(LPBYTE inBuf,int csel)
0516: {
0517: int i,j; BYTE gray,r,g,b;
0518: FillMemory(iGHist,sizeof(UINT)*512,0);
0519:
0520: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
0521:
0522: if(csel <= COLOR_B){
0523: switch(csel){
0524: case COLOR_R: gray = inBuf[XY1D(j*3,i,iLength) + 2]; break;
0525: case COLOR_G: gray = inBuf[XY1D(j*3,i,iLength) + 1]; break;
0526: case COLOR_B: gray = inBuf[XY1D(j*3,i,iLength) + 0]; break;
0527: }
0528: } else {
0529: r = inBuf[XY1D(j*3,i,iLength) + 2];
0530: g = inBuf[XY1D(j*3,i,iLength) + 1];
0531: b = inBuf[XY1D(j*3,i,iLength) + 0];
0532: switch(csel){
0533: case COLOR_Y: gray = rgb2y(r,g,b); break;
0534: case COLOR_U: gray = rgb2u(r,g,b); break;
0535: case COLOR_V: gray = rgb2v(r,g,b); break;
0536: case COLOR_RHO: gray = rgb2rho(r,g,b); break;
0537: case COLOR_THETA: gray = rgb2theta(r,g,b); break;
0538: case COLOR_GRAY: gray = rgb2gray(r,g,b); break;
0539: }
0540: }
0541: iGHist[gray]++;
0542: inBuf[XY1D(j,i,iWidth)] = gray;
0543: }
0544: FillMemory(inBuf+iSize,sizeof(BYTE)*(biSize-iSize),0);
0545: }
0546:
0547:
0548:
0549: void toGray()
0550: {
0551: int i,j; BYTE r,g,b,gray;
0552: FillMemory(iGHist,sizeof(UINT)*512,0);
0553:
0554: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
0555: b=lpOrgBMP[XY1D(j*3,i,iLength)+0];
0556: g=lpOrgBMP[XY1D(j*3,i,iLength)+1];
0557: r=lpOrgBMP[XY1D(j*3,i,iLength)+2];
0558: gray=rgb2gray(r,g,b);
0559: iGHist[gray]++;
0560: FillMemory(lpBMP+XY1D(j*3,i,iLength),sizeof(BYTE)*3,gray);
0561: }
0562: }
0563:
0564:
0565:
0566: LPBYTE GetGray(int csel)
0567: {
0568: int i,j; BYTE r,g,b,gray;
0569: LPBYTE iGray=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
0570: FillMemory(iGHist,sizeof(UINT)*512,0);
0571: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
0572:
0573: if(csel <= COLOR_B){
0574: switch(csel){
0575: case COLOR_R: gray = lpOrgBMP[XY1D(j*3,i,iLength) + 2]; break;
0576: case COLOR_G: gray = lpOrgBMP[XY1D(j*3,i,iLength) + 1]; break;
0577: case COLOR_B: gray = lpOrgBMP[XY1D(j*3,i,iLength) + 0]; break;
0578: }
0579: } else {
0580: r = lpOrgBMP[XY1D(j*3,i,iLength) + 2];
0581: g = lpOrgBMP[XY1D(j*3,i,iLength) + 1];
0582: b = lpOrgBMP[XY1D(j*3,i,iLength) + 0];
0583: switch(csel){
0584: case COLOR_GRAY: gray = rgb2gray(r,g,b); break;
0585: case COLOR_Y: gray = rgb2y(r,g,b); break;
0586: case COLOR_U: gray = rgb2u(r,g,b); break;
0587: case COLOR_V: gray = rgb2v(r,g,b); break;
0588: case COLOR_RHO: gray = rgb2rho(r,g,b); break;
0589: case COLOR_THETA: gray = rgb2theta(r,g,b); break;
0590: }
0591: }
0592: iGray[j+i*iWidth] = gray;
0593: iGHist[gray]++;
0594: }
0595: return iGray;
0596: }
0597: LPBYTE GetColor()
0598: {
0599: LPBYTE iColor=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*biSize);
0600: CopyMemory(iColor,lpOrgBMP,sizeof(BYTE)*biSize);
0601: return iColor;
0602: }
0603:
0604:
0605:
0606: void affine_transform(LPBYTE inBuf,int intp_opt,
0607: double zx,double zy,
0608: double deg,double px,double py)
0609:
0610:
0611:
0612: {
0613: int i,j,xc=iWidth/2,yc=iHeight/2;
0614: double x,y,u,v,r,c,s;
0615: LPBYTE ib;
0616:
0617: ib=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
0618: CopyMemory(ib,inBuf,sizeof(BYTE)*iSize);
0619: FillMemory(inBuf,sizeof(BYTE)*iSize,0);
0620:
0621: r = deg2rad(deg); c = cos(r); s = sin(r);
0622:
0623: for(i=-yc;i<yc;i++) for(j=-xc;j<xc;j++){
0624: v = i-py; u = j-px;
0625: y = (u*s+v*c)/zy; x = (u*c-v*s)/zx;
0626:
0627: inBuf[XY1D(j+xc,i+yc,iWidth)] =
0628: image_interpolation(ib,intp_opt,x,y,xc,yc);
0629: }
0630: GlobalFree(ib);
0631: }
0632: void c_affine_transform(LPBYTE inCBuf,int intp_opt,
0633: double zx,double zy,
0634: double deg,double px,double py)
0635:
0636:
0637:
0638: {
0639: int i,j,xc=iWidth/2,yc=iHeight/2;
0640: double x,y,u,v,r,c,s;
0641: CPIXEL rgb;
0642: LPBYTE icb;
0643:
0644: icb=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*biSize);
0645: CopyMemory(icb,inCBuf,sizeof(BYTE)*biSize);
0646: FillMemory(inCBuf,sizeof(BYTE)*biSize,0);
0647:
0648: r = deg2rad(deg); c = cos(r); s = sin(r);
0649:
0650: for(i=-yc;i<yc;i++) for(j=-xc;j<xc;j++){
0651: v = i-py; u = j-px;
0652: y = (u*s+v*c)/zy; x = (u*c-v*s)/zx;
0653:
0654: rgb = c_image_interpolation(icb,intp_opt,x,y,xc,yc);
0655: inCBuf[XY1D((j+xc)*3,i+yc,iLength) + 0] = rgb.b;
0656: inCBuf[XY1D((j+xc)*3,i+yc,iLength) + 1] = rgb.g;
0657: inCBuf[XY1D((j+xc)*3,i+yc,iLength) + 2] = rgb.r;
0658: }
0659: GlobalFree(icb);
0660: }
0661:
0662:
0663:
0664: BYTE image_interpolation(LPBYTE ib,int intp_opt,
0665: double x,double y,int xc,int yc)
0666: {
0667: int i,m,n,gray;
0668:
0669: BYTE p1,p2,p3,p4; double p,q;
0670:
0671: double c[8],sum;
0672:
0673: if(intp_opt>INTP_NN){
0674: if(y>0) m=(int)y; else m=(int)(y-1);
0675: if(x>0) n=(int)x; else n=(int)(x-1);
0676: } else {
0677: m = rint(y); n = rint(x);
0678: }
0679:
0680: if(!ip_safe(n+xc,m+yc,iWidth,iHeight))
0681: return 0;
0682:
0683: switch(intp_opt){
0684: case INTP_NN:
0685: gray = ib[XY1D(n+xc,m+yc,iWidth)];
0686: break;
0687: case INTP_LN:
0688: if(!ip_safe(n+xc+1,m+yc+1,iWidth,iHeight))
0689: return 0;
0690:
0691: q = y-m; p = x-n;
0692: p1 = ib[XY1D(n+xc ,m+yc ,iWidth)];
0693: p2 = ib[XY1D(n+xc+1,m+yc ,iWidth)];
0694: p3 = ib[XY1D(n+xc ,m+yc+1,iWidth)];
0695: p4 = ib[XY1D(n+xc+1,m+yc+1,iWidth)];
0696: gray = rint((1.0-q)*((1.0-p)*p1+p*p2) + q*((1.0-p)*p3+p*p4));
0697: break;
0698: case INTP_BCC:
0699: if(!ip_safe(n+xc+2,m+yc+2,iWidth,iHeight) ||
0700: !ip_safe(n+xc-1,m+yc-1,iWidth,iHeight))
0701: return 0;
0702:
0703: c[0]=(m-1)-y; c[1]=m-y;
0704: c[2]=(m+1)-y; c[3]=(m+2)-y;
0705: c[4]=(n-1)-x; c[5]=n-x;
0706: c[6]=(n+1)-x; c[7]=(n+2)-x;
0707:
0708: for(i=0;i<8;i++){
0709: if(c[i]<0) c[i]=-c[i];
0710: if(0<=c[i] && c[i]<1)
0711: c[i]=1-2*c[i]*c[i]+c[i]*c[i]*c[i];
0712: else if(1<=c[i] && c[i]<2)
0713: c[i]=4-8*c[i]+5*c[i]*c[i]-c[i]*c[i]*c[i];
0714: else if(2<=c[i]) c[i]=0;
0715: }
0716:
0717: sum = 0;
0718: sum += c[0]*c[4]*ib[XY1D(n+xc-1,m+yc-1,iWidth)];
0719: sum += c[0]*c[5]*ib[XY1D(n+xc ,m+yc-1,iWidth)];
0720: sum += c[0]*c[6]*ib[XY1D(n+xc+1,m+yc-1,iWidth)];
0721: sum += c[0]*c[7]*ib[XY1D(n+xc+2,m+yc-1,iWidth)];
0722: sum += c[1]*c[4]*ib[XY1D(n+xc-1,m+yc ,iWidth)];
0723: sum += c[1]*c[5]*ib[XY1D(n+xc ,m+yc ,iWidth)];
0724: sum += c[1]*c[6]*ib[XY1D(n+xc+1,m+yc ,iWidth)];
0725: sum += c[1]*c[7]*ib[XY1D(n+xc+2,m+yc ,iWidth)];
0726: sum += c[2]*c[4]*ib[XY1D(n+xc-1,m+yc+1,iWidth)];
0727: sum += c[2]*c[5]*ib[XY1D(n+xc ,m+yc+1,iWidth)];
0728: sum += c[2]*c[6]*ib[XY1D(n+xc+1,m+yc+1,iWidth)];
0729: sum += c[2]*c[7]*ib[XY1D(n+xc+2,m+yc+1,iWidth)];
0730: sum += c[3]*c[4]*ib[XY1D(n+xc-1,m+yc+2,iWidth)];
0731: sum += c[3]*c[5]*ib[XY1D(n+xc ,m+yc+2,iWidth)];
0732: sum += c[3]*c[6]*ib[XY1D(n+xc+1,m+yc+2,iWidth)];
0733: sum += c[3]*c[7]*ib[XY1D(n+xc+2,m+yc+2,iWidth)];
0734: if(sum<0) sum = 0; if(sum>iWHITE) sum = iWHITE;
0735: gray = rint(sum);
0736: break;
0737: }
0738: if(gray<0) gray=0; if(gray>iWHITE) gray=iWHITE;
0739: return (BYTE)gray;
0740: }
0741: CPIXEL c_image_interpolation(LPBYTE icb,int intp_opt,
0742: double x,double y,int xc,int yc)
0743: {
0744: CPIXEL rgb={0,0,0};
0745: int i,m,n,gray,r,g,b;
0746:
0747: BYTE p1,p2,p3,p4; double p,q;
0748:
0749: double c[8],sum;
0750:
0751: if(intp_opt>INTP_NN){
0752: if(y>0) m=(int)y; else m=(int)(y-1);
0753: if(x>0) n=(int)x; else n=(int)(x-1);
0754: } else {
0755: m = rint(y); n = rint(x);
0756: }
0757:
0758: if(!ip_safe(n+xc,m+yc,iWidth,iHeight))
0759: return rgb;
0760:
0761: switch(intp_opt){
0762: case INTP_NN:
0763: r = icb[XY1D((n+xc)*3,m+yc,iLength)+2];
0764: g = icb[XY1D((n+xc)*3,m+yc,iLength)+1];
0765: b = icb[XY1D((n+xc)*3,m+yc,iLength)+0];
0766: break;
0767: case INTP_LN:
0768: if(!ip_safe(n+xc+1,m+yc+1,iWidth,iHeight))
0769: return rgb;
0770:
0771: for(i=0;i<3;i++){
0772: q = y-m; p = x-n;
0773: p1 = icb[XY1D((n+xc )*3,m+yc ,iLength)+i];
0774: p2 = icb[XY1D((n+xc+1)*3,m+yc ,iLength)+i];
0775: p3 = icb[XY1D((n+xc )*3,m+yc+1,iLength)+i];
0776: p4 = icb[XY1D((n+xc+1)*3,m+yc+1,iLength)+i];
0777: gray = rint((1.0-q)*((1.0-p)*p1+p*p2) + q*((1.0-p)*p3+p*p4));
0778: switch(i){
0779: case 0: b = gray; break;
0780: case 1: g = gray; break;
0781: case 2: r = gray; break;
0782: }
0783: }
0784: break;
0785: case INTP_BCC:
0786: if(!ip_safe(n+xc+2,m+yc+2,iWidth,iHeight) ||
0787: !ip_safe(n+xc-1,m+yc-1,iWidth,iHeight))
0788: return rgb;
0789:
0790: c[0]=(m-1)-y; c[1]=m-y;
0791: c[2]=(m+1)-y; c[3]=(m+2)-y;
0792: c[4]=(n-1)-x; c[5]=n-x;
0793: c[6]=(n+1)-x; c[7]=(n+2)-x;
0794:
0795: for(i=0;i<8;i++){
0796: if(c[i]<0) c[i]=-c[i];
0797: if(0<=c[i] && c[i]<1)
0798: c[i]=1-2*c[i]*c[i]+c[i]*c[i]*c[i];
0799: else if(1<=c[i] && c[i]<2)
0800: c[i]=4-8*c[i]+5*c[i]*c[i]-c[i]*c[i]*c[i];
0801: else if(2<=c[i]) c[i]=0;
0802: }
0803:
0804: for(i=0;i<3;i++){
0805: sum = 0;
0806: sum += c[0]*c[4]*icb[XY1D((n+xc-1)*3,m+yc-1,iLength)+i];
0807: sum += c[0]*c[5]*icb[XY1D((n+xc )*3,m+yc-1,iLength)+i];
0808: sum += c[0]*c[6]*icb[XY1D((n+xc+1)*3,m+yc-1,iLength)+i];
0809: sum += c[0]*c[7]*icb[XY1D((n+xc+2)*3,m+yc-1,iLength)+i];
0810: sum += c[1]*c[4]*icb[XY1D((n+xc-1)*3,m+yc ,iLength)+i];
0811: sum += c[1]*c[5]*icb[XY1D((n+xc )*3,m+yc ,iLength)+i];
0812: sum += c[1]*c[6]*icb[XY1D((n+xc+1)*3,m+yc ,iLength)+i];
0813: sum += c[1]*c[7]*icb[XY1D((n+xc+2)*3,m+yc ,iLength)+i];
0814: sum += c[2]*c[4]*icb[XY1D((n+xc-1)*3,m+yc+1,iLength)+i];
0815: sum += c[2]*c[5]*icb[XY1D((n+xc )*3,m+yc+1,iLength)+i];
0816: sum += c[2]*c[6]*icb[XY1D((n+xc+1)*3,m+yc+1,iLength)+i];
0817: sum += c[2]*c[7]*icb[XY1D((n+xc+2)*3,m+yc+1,iLength)+i];
0818: sum += c[3]*c[4]*icb[XY1D((n+xc-1)*3,m+yc+2,iLength)+i];
0819: sum += c[3]*c[5]*icb[XY1D((n+xc )*3,m+yc+2,iLength)+i];
0820: sum += c[3]*c[6]*icb[XY1D((n+xc+1)*3,m+yc+2,iLength)+i];
0821: sum += c[3]*c[7]*icb[XY1D((n+xc+2)*3,m+yc+2,iLength)+i];
0822: if(sum<0) sum = 0; if(sum>iWHITE) sum = iWHITE;
0823: gray = rint(sum);
0824: switch(i){
0825: case 0: b = gray; break;
0826: case 1: g = gray; break;
0827: case 2: r = gray; break;
0828: }
0829: }
0830: break;
0831: }
0832: if(r<0) r=0; if(r>iWHITE) r=iWHITE;
0833: if(g<0) g=0; if(g>iWHITE) g=iWHITE;
0834: if(b<0) b=0; if(b>iWHITE) b=iWHITE;
0835: rgb.r = r; rgb.g = g; rgb.b = b;
0836: return rgb;
0837: }
0838:
0839:
0840:
0841: void nn_scale(LPBYTE inBuf,double zx,double zy)
0842: {
0843: int i,j,m,n;
0844: int xsize=(zx>1.0)?iWidth : rint(iWidth*zx);
0845: LPBYTE ib;
0846:
0847: ib=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
0848: CopyMemory(ib,inBuf,sizeof(BYTE)*iSize);
0849: FillMemory(inBuf,sizeof(BYTE)*iSize,0);
0850:
0851: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++){
0852: m = rint(i/zy); n = rint(j/zx);
0853: if(ip_safe(n,m,iWidth,iHeight))
0854: inBuf[XY1D(j,i,xsize)] = ib[XY1D(n,m,iWidth)];
0855: else
0856: inBuf[XY1D(j,i,xsize)] = 0;
0857: }
0858: GlobalFree(ib);
0859: }
0860:
0861:
0862:
0863: void linear_scale(LPBYTE inBuf,double zx,double zy)
0864: {
0865: int i,j,m,n;
0866: int p1,p2,p3,p4,d;
0867: int xsize=(zx>1.0)?iWidth:rint(iWidth*zx);
0868: double x,y,p,q;
0869: LPBYTE ib;
0870:
0871: ib=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
0872: CopyMemory(ib,inBuf,sizeof(BYTE)*iSize);
0873: FillMemory(inBuf,sizeof(BYTE)*iSize,0);
0874:
0875: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++){
0876: y = i/zy; x = j/zx;
0877: m = (int)(y); n = (int)(x);
0878: q = y-m; p = x-n;
0879: if(ip_safe(n,m,iWidth,iHeight) &&
0880: ip_safe(n+1,m+1,iWidth,iHeight)){
0881: p1 = ib[XY1D(n ,m ,iWidth)];
0882: p2 = ib[XY1D(n+1,m ,iWidth)];
0883: p3 = ib[XY1D(n ,m+1,iWidth)];
0884: p4 = ib[XY1D(n+1,m+1,iWidth)];
0885: d = rint((1.0-q)*((1.0-p)*p1+p*p2) + q*((1.0-p)*p3+p*p4));
0886: if(d<0) d=0; if(d>iWHITE) d=iWHITE;
0887: } else d = 0;
0888: inBuf[XY1D(j,i,xsize)] = d;
0889: }
0890: GlobalFree(ib);
0891: }
0892:
0893:
0894:
0895: void bcc_scale(LPBYTE inBuf,double zx,double zy)
0896: {
0897: int i,j,k,m,n,d;
0898: int xsize=(zx>1.0)?iWidth : rint(iWidth*zx);
0899: double x,y,c[8],sum;
0900: LPBYTE ib;
0901:
0902: ib=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
0903: CopyMemory(ib,inBuf,sizeof(BYTE)*iSize);
0904: FillMemory(inBuf,sizeof(BYTE)*iSize,0);
0905:
0906: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++){
0907: y = i/zy; x = j/zx;
0908: m = (int)(y); n = (int)(x);
0909: if(ip_safe(n-1,m-1,iWidth,iHeight) &&
0910: ip_safe(n+2,m+2,iWidth,iHeight)){
0911:
0912: c[0]=(m-1)-y; c[1]=m-y;
0913: c[2]=(m+1)-y; c[3]=(m+2)-y;
0914: c[4]=(n-1)-x; c[5]=n-x;
0915: c[6]=(n+1)-x; c[7]=(n+2)-x;
0916:
0917: for(k=0;k<8;k++){
0918: if(c[k]<0) c[k]=-c[k];
0919: if(0<=c[k] && c[k]<1)
0920: c[k]=1-2*c[k]*c[k]+c[k]*c[k]*c[k];
0921: else if(1<=c[k] && c[k]<2)
0922: c[k]=4-8*c[k]+5*c[k]*c[k]-c[k]*c[k]*c[k];
0923: else if(2<=c[k]) c[k]=0;
0924: }
0925:
0926: sum = 0;
0927: sum += c[0]*c[4]*ib[XY1D(n-1,m-1,iWidth)];
0928: sum += c[0]*c[5]*ib[XY1D(n ,m-1,iWidth)];
0929: sum += c[0]*c[6]*ib[XY1D(n+1,m-1,iWidth)];
0930: sum += c[0]*c[7]*ib[XY1D(n+2,m-1,iWidth)];
0931: sum += c[1]*c[4]*ib[XY1D(n-1,m ,iWidth)];
0932: sum += c[1]*c[5]*ib[XY1D(n ,m ,iWidth)];
0933: sum += c[1]*c[6]*ib[XY1D(n+1,m ,iWidth)];
0934: sum += c[1]*c[7]*ib[XY1D(n+2,m ,iWidth)];
0935: sum += c[2]*c[4]*ib[XY1D(n-1,m+1,iWidth)];
0936: sum += c[2]*c[5]*ib[XY1D(n ,m+1,iWidth)];
0937: sum += c[2]*c[6]*ib[XY1D(n+1,m+1,iWidth)];
0938: sum += c[2]*c[7]*ib[XY1D(n+2,m+1,iWidth)];
0939: sum += c[3]*c[4]*ib[XY1D(n-1,m+2,iWidth)];
0940: sum += c[3]*c[5]*ib[XY1D(n ,m+2,iWidth)];
0941: sum += c[3]*c[6]*ib[XY1D(n+1,m+2,iWidth)];
0942: sum += c[3]*c[7]*ib[XY1D(n+2,m+2,iWidth)];
0943: if(sum<0) sum = 0; if(sum>iWHITE) sum = iWHITE;
0944: d = rint(sum);
0945: } else d=0;
0946: inBuf[XY1D(j,i,xsize)] = d;
0947: }
0948: }
0949:
0950:
0951:
0952:
0953: void sqm_scale(LPBYTE inBuf,double zx,double zy)
0954: {
0955: int i,x,y,x1,x2,y1,y2;
0956: int lcm_x,lcm_y,p_count,meanp;
0957: int xsize,ysize,oxsize,oysize;
0958: LPBYTE oneline;
0959:
0960: xsize = oxsize = rint(iWidth*zx);
0961: ysize = oysize = rint(iHeight*zy);
0962: if(xsize%2) xsize--; if(ysize%2) ysize--;
0963:
0964: lcm_x = lcm(iWidth ,xsize);
0965: lcm_y = lcm(iHeight,ysize);
0966: x1 = lcm_x / iWidth; y1 = lcm_y / iHeight;
0967: x2 = lcm_x / xsize; y2 = lcm_y / ysize;
0968:
0969: if(xsize>iWidth ) xsize = oxsize = iWidth;
0970: if(ysize>iHeight) ysize = oysize = iHeight;
0971:
0972:
0973:
0974: oneline=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iWidth*x1);
0975: for(y=0;y<iHeight;y++){
0976: for(x=0;x<iWidth;x++)
0977: for(i=0;i<x1;i++)
0978: oneline[x*x1+i] = inBuf[XY1D(x,y,iWidth)];
0979: for(x=0;x<xsize;x++) {
0980: meanp = p_count = 0;
0981: for(i=0;i<x2;i++){
0982: if(x*x2+i < x1*iWidth){
0983: p_count ++;
0984: meanp += oneline[x*x2+i];
0985: }
0986: }
0987: if(p_count) meanp /= p_count;
0988: inBuf[XY1D(x,y,oxsize)] = meanp;
0989: }
0990: for(x=xsize;x<iWidth;x++)
0991: inBuf[XY1D(x,y,oxsize)] = 0;
0992: }
0993: GlobalFree(oneline);
0994:
0995:
0996:
0997: oneline=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iHeight*y1);
0998: for(x=0;x<xsize;x++){
0999: for(y=0;y<iHeight;y++)
1000: for(i=0;i<y1;i++)
1001: oneline[y*y1+i] = inBuf[XY1D(x,y,oxsize)];
1002: for(y=0;y<ysize;y++) {
1003: meanp = p_count = 0;
1004: for(i=0;i<y2;i++){
1005: if(y*y2+i < y1*iHeight){
1006: p_count ++;
1007: meanp += oneline[y*y2+i];
1008: }
1009: }
1010: if(p_count) meanp /= p_count;
1011: inBuf[XY1D(x,y,oxsize)] = meanp;
1012: }
1013: for(y=ysize;y<iHeight;y++)
1014: inBuf[XY1D(x,y,oxsize)] = 0;
1015: }
1016: GlobalFree(oneline);
1017: }
1018: void c_sqm_scale(LPBYTE inBuf,double zx,double zy)
1019: {
1020: int i,x,y,x1,x2,y1,y2;
1021: int lcm_x,lcm_y,p_count,meanp[3];
1022: int bxsize,xsize,ysize,oxsize,oysize;
1023: LPBYTE oneline;
1024:
1025: xsize = oxsize = rint(iWidth*zx);
1026: ysize = oysize = rint(iHeight*zy);
1027: if(xsize%2) xsize--; if(ysize%2) ysize--;
1028:
1029: lcm_x = lcm(iWidth ,xsize);
1030: lcm_y = lcm(iHeight,ysize);
1031: x1 = lcm_x / iWidth; y1 = lcm_y / iHeight;
1032: x2 = lcm_x / xsize; y2 = lcm_y / ysize;
1033:
1034: if(xsize>iWidth ) xsize = oxsize = iWidth;
1035: if(ysize>iHeight) ysize = oysize = iHeight;
1036:
1037: if((oxsize*3)%4==0) bxsize = oxsize*3;
1038: else bxsize = oxsize*3+(4-(oxsize*3)%4);
1039:
1040:
1041:
1042: oneline=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iLength*x1);
1043: for(y=0;y<iHeight;y++){
1044: for(x=0;x<iWidth;x++)
1045: for(i=0;i<x1;i++){
1046: oneline[(x*x1+i)*3+0] = inBuf[XY1D(x*3,y,iLength)+0];
1047: oneline[(x*x1+i)*3+1] = inBuf[XY1D(x*3,y,iLength)+1];
1048: oneline[(x*x1+i)*3+2] = inBuf[XY1D(x*3,y,iLength)+2];
1049: }
1050: for(x=0;x<xsize;x++) {
1051: p_count = 0;
1052: for(i=0;i<3;i++) meanp[i] = 0;
1053: for(i=0;i<x2;i++){
1054: if((x*x2+i)*3 < x1*iLength){
1055: p_count ++;
1056: meanp[0] += oneline[(x*x2+i)*3+0];
1057: meanp[1] += oneline[(x*x2+i)*3+1];
1058: meanp[2] += oneline[(x*x2+i)*3+2];
1059: }
1060: }
1061: if(p_count) {
1062: meanp[0] /= p_count;
1063: meanp[1] /= p_count;
1064: meanp[2] /= p_count;
1065: }
1066: inBuf[XY1D(x*3,y,bxsize)+0] = meanp[0];
1067: inBuf[XY1D(x*3,y,bxsize)+1] = meanp[1];
1068: inBuf[XY1D(x*3,y,bxsize)+2] = meanp[2];
1069: }
1070: for(x=xsize*3;x<bxsize;x++)
1071: inBuf[XY1D(x,y,bxsize)] = 0;
1072: }
1073: GlobalFree(oneline);
1074:
1075:
1076:
1077: oneline=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iHeight*y1*3);
1078: for(x=0;x<xsize;x++){
1079: for(y=0;y<iHeight;y++)
1080: for(i=0;i<y1;i++){
1081: oneline[(y*y1+i)*3+0] = inBuf[XY1D(x*3,y,bxsize)+0];
1082: oneline[(y*y1+i)*3+1] = inBuf[XY1D(x*3,y,bxsize)+1];
1083: oneline[(y*y1+i)*3+2] = inBuf[XY1D(x*3,y,bxsize)+2];
1084: }
1085: for(y=0;y<ysize;y++) {
1086: for(i=0;i<3;i++) meanp[i] = 0;
1087: p_count = 0;
1088: for(i=0;i<y2;i++){
1089: if((y*y2+i)*3 < y1*iHeight*3){
1090: p_count ++;
1091: meanp[0] += oneline[(y*y2+i)*3+0];
1092: meanp[1] += oneline[(y*y2+i)*3+1];
1093: meanp[2] += oneline[(y*y2+i)*3+2];
1094: }
1095: }
1096: if(p_count){
1097: meanp[0] /= p_count;
1098: meanp[1] /= p_count;
1099: meanp[2] /= p_count;
1100: }
1101: inBuf[XY1D(x*3,y,bxsize)+0] = meanp[0];
1102: inBuf[XY1D(x*3,y,bxsize)+1] = meanp[1];
1103: inBuf[XY1D(x*3,y,bxsize)+2] = meanp[2];
1104: }
1105: for(y=ysize;y<iHeight;y++) {
1106: inBuf[XY1D(x*3,y,bxsize)+0] = 0;
1107: inBuf[XY1D(x*3,y,bxsize)+1] = 0;
1108: inBuf[XY1D(x*3,y,bxsize)+2] = 0;
1109: }
1110: }
1111: GlobalFree(oneline);
1112: }
1113:
1114:
1115:
1116: LPBYTE scale_large(LPBYTE inb,double zx,double zy)
1117: {
1118: int i,j,xc,yc,xsz,ysz,isz; double x,y;
1119: LPBYTE outb;
1120:
1121: xsz = rint(iWidth*zx); ysz = rint(iHeight*zy);
1122: isz = xsz*ysz; xc = xsz/2; yc = ysz/2;
1123:
1124: outb=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*isz);
1125:
1126: for(i=-yc;i<yc;i++) for(j=-xc;j<xc;j++){
1127: y = i/zy; x = j/zx;
1128:
1129: outb[XY1D(j+xc,i+yc,xsz)] =
1130: image_interpolation(inb,INTP_LN,x,y,xc,yc);
1131: }
1132: return outb;
1133: }
1134:
1135:
1136:
1137: void IPfunc_OR(LPBYTE iDst,LPBYTE iAdd)
1138: {
1139: int x,y;
1140: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++) {
1141: iDst[XY1D(x,y,iWidth)] = (iDst[XY1D(x,y,iWidth)] |
1142: iAdd[XY1D(x,y,iWidth)]) ? iWHITE:iBLACK;
1143: }
1144: }
1145:
1146:
1147:
1148: void IPfunc_median(LPBYTE inBuf)
1149: {
1150: int i,x,y,px,py;
1151: BYTE c[9];
1152: LPBYTE ib=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
1153: CopyMemory(ib,inBuf,sizeof(BYTE)*iSize);
1154:
1155: for(y=1;y<iHeight-1;y++) for(x=1;x<iWidth-1;x++){
1156: for(i=0;i<8;i++){
1157: px = x+offset8[i].x;
1158: py = y+offset8[i].y;
1159: c[i] = ib[XY1D(px,py,iWidth)];
1160: }
1161: inBuf[XY1D(x,y,iWidth)] = median(c);
1162: }
1163: GlobalFree(ib);
1164: }
1165: BYTE median(BYTE c[9])
1166: {
1167: int i,j;
1168: for(j=0;j<8;j++) for(i=0;i<8;i++){
1169: if(c[i+1]<c[i]) swapv(c[i],c[i+1]);
1170: }
1171: return c[4];
1172: }
1173:
1174:
1175:
1176: void toDither(LPBYTE inBuf)
1177: {
1178: static int DITHER_BSZ = 4;
1179: static int DITHER_NL = 16;
1180: double width;
1181: BYTE new_gray;
1182: int x_block,y_block;
1183: int x,y,i,j,m,n,px,py;
1184: static int dither_matrix[4][4]={
1185: { 0, 8, 2,10},
1186: {12, 4,14, 6},
1187: { 3,11, 1, 9},
1188: {15, 7,13, 5}
1189: };
1190:
1191:
1192:
1193: width = iWHITE/(double)DITHER_NL;
1194: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
1195: new_gray=rint(inBuf[XY1D(x,y,iWidth)]/width);
1196: if(new_gray > DITHER_NL-1)
1197: new_gray = DITHER_NL-1;
1198: inBuf[XY1D(x,y,iWidth)] = new_gray;
1199: }
1200:
1201:
1202:
1203: x_block=iWidth / DITHER_BSZ;
1204: y_block=iHeight / DITHER_BSZ;
1205: if(iWidth % DITHER_BSZ) x_block++;
1206: if(iHeight % DITHER_BSZ) y_block++;
1207: for(i=0;i<y_block;i++) for(j=0;j<x_block;j++){
1208: x=j*DITHER_BSZ;
1209: y=i*DITHER_BSZ;
1210: for(m=0;m<DITHER_BSZ;m++) for(n=0;n<DITHER_BSZ;n++){
1211: px=x+n; py=y+m;
1212: if(ip_safe(px,py,iWidth,iHeight)){
1213: if(inBuf[XY1D(px,py,iWidth)] <= dither_matrix[m][n])
1214: inBuf[XY1D(px,py,iWidth)]=0;
1215: else inBuf[XY1D(px,py,iWidth)]=iWHITE;
1216: }
1217: }
1218: }
1219: }
1220:
1221:
1222:
1223: void linear_transform(LPBYTE inBuf)
1224: {
1225: int x,y,minv,maxv; BYTE gray;
1226:
1227: minv = 10000; maxv = 0;
1228: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
1229: if(inBuf[XY1D(x,y,iWidth)]<minv) minv=inBuf[XY1D(x,y,iWidth)];
1230: if(inBuf[XY1D(x,y,iWidth)]>maxv) maxv=inBuf[XY1D(x,y,iWidth)];
1231: }
1232:
1233: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
1234: gray = rint(iWHITE*(inBuf[XY1D(x,y,iWidth)]-minv)/
1235: (double)(maxv-minv));
1236: inBuf[XY1D(x,y,iWidth)] = gray;
1237: }
1238: }
1239:
1240:
1241:
1242:
1243: void reduce_color(LPBYTE inBuf,int iLevel)
1244: {
1245: int trhist[512],trans_table[512];
1246: int i,x,y,gray;
1247: int target_value;
1248: double gray_step;
1249:
1250: make_histogram(inBuf);
1251:
1252: target_value = rint(iSize/(double)(iLevel));
1253: FillMemory(trhist,sizeof(int)*512,0);
1254: FillMemory(trans_table,sizeof(int)*512,0);
1255: gray = 0;
1256: for(i=0;i<iMAX_GRAY;i++){
1257: if(trhist[gray] > target_value){
1258: gray++;
1259: if(gray>iLevel) gray=iLevel;
1260: }
1261: trans_table[i] = gray;
1262: trhist[gray] += iGHist[i];
1263: }
1264:
1265: gray_step = (double)(iWHITE) / (iLevel-1);
1266: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++)
1267: inBuf[XY1D(x,y,iWidth)] =
1268: rint(gray_step*trans_table[inBuf[XY1D(x,y,iWidth)]]);
1269: }
1270: void c_reduce_color(LPBYTE inBuf,int iLevel)
1271: {
1272: int trhist[3][512],trans_table[3][512];
1273: int i,x,y,r,g,b;
1274: int target_value;
1275: double gray_step;
1276:
1277: c_make_histogram(inBuf);
1278:
1279: target_value = rint(iSize/(double)(iLevel));
1280: for(i=0;i<3;i++){
1281: FillMemory(trhist[i],sizeof(int)*512,0);
1282: FillMemory(trans_table[i],sizeof(int)*512,0);
1283: }
1284: r = g = b = 0;
1285: for(i=0;i<iMAX_GRAY;i++){
1286: if(trhist[0][r] > target_value){
1287: r++; if(r>iLevel) r=iLevel;
1288: }
1289: if(trhist[1][g] > target_value){
1290: g++; if(g>iLevel) g=iLevel;
1291: }
1292: if(trhist[2][b] > target_value){
1293: b++; if(b>iLevel) b=iLevel;
1294: }
1295: trans_table[0][i] = r; trhist[0][r] += iCHist[0][i];
1296: trans_table[1][i] = g; trhist[1][g] += iCHist[1][i];
1297: trans_table[2][i] = b; trhist[2][b] += iCHist[2][i];
1298: }
1299:
1300: gray_step = (double)(iWHITE) / (iLevel-1);
1301: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
1302: inBuf[XY1D(x*3,y,iLength)+2] =
1303: rint(gray_step*trans_table[0][inBuf[XY1D(x*3,y,iLength)+2]]);
1304: inBuf[XY1D(x*3,y,iLength)+1] =
1305: rint(gray_step*trans_table[1][inBuf[XY1D(x*3,y,iLength)+1]]);
1306: inBuf[XY1D(x*3,y,iLength)+0] =
1307: rint(gray_step*trans_table[2][inBuf[XY1D(x*3,y,iLength)+0]]);
1308: }
1309: }
1310:
1311:
1312:
1313: void quantize(LPBYTE inBuf,int bit)
1314: {
1315: int x,y,rbit=CBIT-bit;
1316: if(rbit<=0) rbit = 1;
1317: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++)
1318: inBuf[XY1D(x,y,iWidth)] = (inBuf[XY1D(x,y,iWidth)]>>rbit)<<rbit;
1319: }
1320: void c_quantize(LPBYTE inBuf,int bit)
1321: {
1322: int x,y,rbit=CBIT-bit;
1323: if(rbit<=0) rbit = 1;
1324: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
1325: inBuf[XY1D(x*3,y,iLength)+2] =
1326: (inBuf[XY1D(x*3,y,iLength)+2]>>rbit)<<rbit;
1327: inBuf[XY1D(x*3,y,iLength)+1] =
1328: (inBuf[XY1D(x*3,y,iLength)+1]>>rbit)<<rbit;
1329: inBuf[XY1D(x*3,y,iLength)+0] =
1330: (inBuf[XY1D(x*3,y,iLength)+0]>>rbit)<<rbit;
1331: }
1332: }
1333:
1334:
1335:
1336: void spacial_filtering(LPBYTE inBuf,int iFlt[9],double iMag)
1337: {
1338: LPBYTE ib=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
1339: int i,x,y,px,py;
1340: double new_value,minv,maxv;
1341:
1342: CopyMemory(ib,inBuf,sizeof(BYTE)*iSize);
1343:
1344: minv = 10000.; maxv = 0.;
1345: for(y=1;y<iHeight-1;y++) for(x=1;x<iWidth-1;x++){
1346: new_value = 0.0;
1347: for(i=0;i<9;i++){
1348: px = x+offset9[i].x;
1349: py = y+offset9[i].y;
1350: new_value += iFlt[i] * ib[XY1D(px,py,iWidth)];
1351: }
1352: new_value = new_value / iMag;
1353: if(new_value < minv) minv = new_value;
1354: if(new_value > maxv) maxv = new_value;
1355: }
1356:
1357: for(y=1;y<iHeight-1;y++) for(x=1;x<iWidth-1;x++){
1358: new_value = 0.0;
1359: for(i=0;i<9;i++){
1360: px = x+offset9[i].x;
1361: py = y+offset9[i].y;
1362: new_value += iFlt[i]*ib[XY1D(px,py,iWidth)];
1363: }
1364: new_value = new_value / iMag;
1365: new_value = iWHITE / (maxv-minv) * (new_value-minv);
1366: inBuf[XY1D(x,y,iWidth)] = (BYTE)rint(new_value);
1367: }
1368: GlobalFree(ib);
1369: }
1370:
1371:
1372:
1373:
1374:
1375: void make_error_difusion_image(LPBYTE inBuf)
1376: {
1377: int x, y;
1378: double err1,err2,err3;
1379: double* buf=(double*)GlobalAlloc(GPTR,sizeof(double)*iWidth*2);
1380: double modified_gray;
1381:
1382: FillMemory(buf,sizeof(double)*iWidth*2,0);
1383:
1384: for(y=0;y<iHeight;y++){
1385: for(x=0;x<iWidth;x++){
1386:
1387: if(x==iWidth-1 || y==iHeight-1){
1388: if(inBuf[XY1D(x,y,iWidth)] <= iMAX_GRAY/2)
1389: inBuf[XY1D(x,y,iWidth)]=iBLACK;
1390: else
1391: inBuf[XY1D(x,y,iWidth)]=iWHITE;
1392: } else {
1393: modified_gray=inBuf[XY1D(x,y,iWidth)]+buf[x];
1394: err1=modified_gray - 0.0;
1395: err2=modified_gray - iWHITE;
1396: if(err1 * err1<err2 * err2){
1397: inBuf[XY1D(x,y,iWidth)]=0;
1398: err3=err1;
1399: } else {
1400: inBuf[XY1D(x,y,iWidth)]=iWHITE;
1401: err3=err2;
1402: }
1403:
1404: buf[x+1] =buf[x+1] + err3 * 3.0 / 8.0;
1405: buf[x+1+iWidth]=buf[x+1+iWidth]+ err3 * 2.0 / 8.0;
1406: buf[x +iWidth]=buf[x +iWidth]+ err3 * 3.0 / 8.0;
1407: }
1408: }
1409: for(x=0;x<iWidth;x++){
1410: buf[x]=buf[x+iWidth];
1411: buf[x+iWidth]=0.0;
1412: }
1413: }
1414: GlobalFree(buf);
1415: }
1416:
1417:
1418:
1419: void make_histogram_image(LPBYTE inBuf)
1420: {
1421: int i,j,data,max_frequency;
1422:
1423: make_histogram(inBuf);
1424:
1425: max_frequency=0;
1426: for(i=0;i<iMAX_GRAY;i++)
1427: if(iGHist[i] > max_frequency)
1428: max_frequency = iGHist[i];
1429:
1430: FillMemory(inBuf,sizeof(BYTE)*iSize,0);
1431: for(i=0;i<iMAX_GRAY;i++){
1432:
1433: data=rint(iWHITE*(double)iGHist[i]/(double)max_frequency);
1434: for(j=0;j<data;j++)
1435: inBuf[XY1D(i,j,iWidth)] = iWHITE;
1436: }
1437: }
1438:
1439:
1440:
1441:
1442:
1443: void draw_3D_graph(LPBYTE inBuf,int plot_step,double plot_ratio)
1444: {
1445: int x,y,lx1,lx2,ly1,ly2;
1446: int x_size,y_size;
1447: int plot_height;
1448: double xmag,ymag;
1449: LPBYTE ib=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
1450: CopyMemory(ib,inBuf,sizeof(BYTE)*iSize);
1451:
1452:
1453:
1454: x_size=iWidth + iHeight / 2;
1455: plot_height=rint(iMAX_GRAY*plot_ratio);
1456: y_size=iHeight + plot_height;
1457: xmag = (double)iWidth /(double)x_size;
1458: ymag = (double)iHeight/(double)y_size;
1459:
1460:
1461:
1462: FillMemory(inBuf,sizeof(BYTE)*iSize,0);
1463:
1464:
1465:
1466: for(y=0;y<iHeight;y++){
1467: if(y%plot_step == 0){
1468:
1469:
1470: for(x=0;x<iWidth;x++){
1471: lx1 = rint(xmag*(x+y/2));
1472: ly1 = rint(ymag*((y_size-1)-(plot_height+y)));
1473: lx2 = rint(xmag*(x+y/2));
1474: ly2 = rint(ymag*((y_size-1)-
1475: (plot_height+y-
1476: (ib[XY1D(x,y,iWidth)]*plot_ratio))));
1477: draw_line(inBuf,lx1,ly1,lx2,ly2,0);
1478: }
1479:
1480: for(x=0;x<iWidth-1;x++){
1481: lx1 = rint(xmag*(x+y/2));
1482: ly1 = rint(ymag*((y_size-1)-
1483: (plot_height+y-
1484: (ib[XY1D(x,y,iWidth)]*plot_ratio))));
1485: lx2 = rint(xmag*(x+y/2+1));
1486: ly2 = rint(ymag*((y_size-1)-
1487: (plot_height+y-
1488: (ib[XY1D(x+1,y,iWidth)]*plot_ratio))));
1489: draw_line(inBuf,lx1,ly1,lx2,ly2,iWHITE);
1490: }
1491: }
1492: }
1493: GlobalFree(ib);
1494: }