001: #include <stdio.h>
002: #include <stdlib.h>
003: #include <time.h>
004: #include <math.h>
005: #include <windows.h>
006: #include "wingui.h"
007: #include "ipcommon.h"
008:
009:
010:
011: void init_random()
012: {
013: int seed = time(NULL);
014: if(seed<1) seed=1;
015: srand(seed);
016: }
017: int random_int(int n)
018: {
019: return rint((double)rand()/((double)RAND_MAX+1.0)*n);
020: }
021:
022:
023:
024: void swapcol(BYTE c1,BYTE c2)
025: {
026: BYTE c = c1; c1 = c2; c2 = c;
027: }
028:
029:
030:
031: BYTE rgb2gray(BYTE r,BYTE g,BYTE b)
032: {
033: int gray=rint(r*0.299+g*0.587+b*0.144);
034: if(gray>iWHITE) gray=iWHITE;
035: return gray;
036: }
037:
038:
039:
040: void swap_point(POINT p1,POINT p2)
041: {
042: POINT p;
043: p.x = p1.x; p.x = p1.y;
044: p1.x = p2.x; p1.y = p2.y;
045: p2.x = p.x; p2.y = p.y;
046: }
047:
048:
049:
050: int colcmp(LPBYTE inb,CPIXEL c)
051: {
052: if(*(inb+2)==c.r && *(inb+1)==c.g && *(inb+0)==c.b)
053: return 1;
054: return 0;
055: }
056:
057:
058:
059: void setcol(LPBYTE inb,CPIXEL c)
060: {
061: *(inb+2) = c.r;
062: *(inb+1) = c.g;
063: *(inb+0) = c.b;
064: }
065:
066:
067:
068: double calc_distance(POINT p1,POINT p2)
069: {
070: return sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
071: }
072: double calc_distance(int x1,int y1,int x2,int y2)
073: {
074: return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
075: }
076:
077:
078:
079:
080: void draw_circle(LPBYTE oBuf,POINT cp,int radius)
081: {
082: int xp,yp,th,th_max;
083: double cirstep;
084:
085: th_max = rint(2*M_PI*radius);
086: cirstep = 360./th_max;
087: for(th=0;th<th_max;th++){
088: xp = rint(cp.x + radius * cos(deg2rad(cirstep*th)));
089: yp = rint(cp.y + radius * sin(deg2rad(cirstep*th)));
090: if(xp>=0 && xp<iWidth && yp>=0 && yp<iHeight)
091: oBuf[xp+yp*iWidth] = iWHITE;
092: }
093: }
094:
095:
096:
097: void draw_line(LPBYTE oBuf,POINT p1,POINT p2)
098: {
099: draw_line(oBuf,p1.x,p1.y,p2.x,p2.y);
100: }
101: void draw_line(LPBYTE oBuf,int x1,int y1,int x2,int y2)
102: {
103: int xp,yp;
104: double distance,step,t;
105: int dx1,dx2,dy1,dy2;
106: dx1 = x1; dx2 = x2; dy1 = y1; dy2 = y2;
107:
108: if(scrossln(&dx1,&y1,&x2,&y2)==0) return;
109:
110: t = 0.0;
111: distance = calc_distance(dx1,dy1,dx2,dy2);
112: step = 1.0/(1.5*distance);
113: while(t<1.0){
114: xp = rint(t*dx2 + (1.0-t)*dx1);
115: yp = rint(t*dy2 + (1.0-t)*dy1);
116: if(xp>=0 && xp<iWidth && yp>=0 && yp<iHeight)
117: oBuf[xp+yp*iWidth] = iWHITE;
118: t = t + step;
119: }
120: }
121:
122:
123:
124: int croslnxc(int x1,int y1,int x2,int y2,int xc,int *yc)
125: {
126: double wk;
127: if(y1 == y2){ *yc = y1; return 1; }
128: if(x1 == x2){ *yc = 0; return -1; }
129: if(x1 != x2){
130: wk = (y2-y1)/(x2-x1);
131: *yc = rint(wk*(xc-x1)+y1);
132: return 1;
133: }
134: return 0;
135: }
136:
137:
138:
139: int croslnyc(int x1,int y1,int x2,int y2,int yc,int *xc)
140: {
141: double wk;
142: if(x1 == x2){ *xc = x1; return 1; }
143: if(y1 == y2){ *xc = 0; return -1; }
144: if(x1 != x2){
145: wk = (y2-y1)/(x2-x1);
146: *xc = rint(x1+(yc-y1)/wk);
147: return 1;
148: }
149: return 0;
150: }
151:
152:
153:
154:
155: int scrossln(int* x1,int* y1,int* x2,int* y2)
156: {
157: int dx1,dx2,dy1,dy2;
158: int i,is,ip,mkp1,mkp2;
159: int wk,xc,yc,xw1,xw2,yw1,yw2;
160: int xx[2],yy[2],ds1[2],ds2[2];
161: int gr_wnx[2],gr_wny[2];
162:
163:
164:
165: dx1 = *x1; dx2 = *x2; dy1 = *y1; dy2 = *y2;
166: for(i=0;i<2;i++){
167: xx[i] =0; yy[i] =0; ds1[i]=0; ds2[i]=0;
168: }
169: xw1=gr_wnx[0]=0; xw2=gr_wnx[1]=iWidth;
170: yw1=gr_wny[0]=0; yw2=gr_wny[1]=iHeight;
171: mkp1=mkp2=0;
172:
173:
174:
175: if(dx1>=xw1 && dx1<=xw2 && dy1>=yw1 && dy1<=yw2){
176: *x1 = dx1; *y1 = dy1;
177: mkp1 = 1;
178: }
179: if(dx2>=xw1 && dx2<=xw2 && dy2>=yw1 && dy2<=yw2){
180: *x2 = dx2; *y2 = dy2;
181: mkp2 = 1;
182: }
183:
184:
185:
186: if(mkp1 == 1 && mkp2 == 1) return 1;
187: ip = 0;
188:
189:
190:
191: for(i=0;i<2;i++){
192: wk=gr_wnx[i];
193: is=croslnxc(dx1,dy1,dx2,dy2,wk,&yc);
194: if(is == 1 && yc>=yw1 && yc<=yw2){
195: xx[ip] = wk; yy[ip] = yc;
196: ip++;
197: }
198: }
199:
200:
201:
202: if(ip<2){
203: for(i=0;i<2;i++){
204: wk=gr_wny[i];
205: is=croslnyc(dx1,dy1,dx2,dy2,wk,&xc);
206: if(is == 1 && xc>=xw1 && xc<=xw2){
207: xx[ip] = xc; yy[ip] = wk;
208: ip++;
209: }
210: }
211: }
212:
213:
214:
215:
216: if(ip==0) return 0;
217:
218:
219:
220: for(i=0;i<2;i++){
221: ds1[i] = ((xx[i]-dx1)*(xx[i]-dx1)+(yy[i]-dy1)*(yy[i]-dy1));
222: ds2[i] = ((xx[i]-dx2)*(xx[i]-dx2)+(yy[i]-dy2)*(yy[i]-dy2));
223: }
224: if(mkp1 == 0){
225: if(ds1[0]<ds1[1]){
226: *x1 = xx[0]; *y1 = yy[0];
227: }
228: if(ds1[0]>ds1[1]){
229: *x1 = xx[1]; *y1 = yy[1];
230: }
231: }
232: if(mkp2 == 0){
233: if(ds2[0]<ds2[1]){
234: *x2 = xx[0]; *y2 = yy[0];
235: }
236: if(ds2[0]>ds2[1]){
237: *x2 = xx[1]; *y2 = yy[1];
238: }
239: }
240: return 1;
241: }
242:
243:
244:
245:
246: void GrayToColor(LPBYTE iGray,LPBYTE iColor)
247: {
248: int i,x,y;
249: int iadd = iLength-iWidth*3;
250:
251: for(y=0;y<iHeight;y++){
252: for(x=0;x<iWidth;x++) {
253: FillMemory(iColor+x*3+y*iLength,sizeof(BYTE)*3,iGray[x+y*iWidth]);
254: }
255: for(i=0;i<iadd;i++)
256: iColor[x*3+y*iLength + i] = 0;
257: }
258: }
259:
260:
261:
262: void toGray()
263: {
264: int i,j; BYTE r,g,b,gray;
265: FillMemory(iGHist,sizeof(UINT)*512,0);
266:
267: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
268: b=lpOrgBMP[j*3+i*iLength+0];
269: g=lpOrgBMP[j*3+i*iLength+1];
270: r=lpOrgBMP[j*3+i*iLength+2];
271: gray=rgb2gray(r,g,b);
272: iGHist[gray]++;
273: FillMemory(lpBMP+j*3+i*iLength,sizeof(BYTE)*3,gray);
274: }
275: }
276:
277:
278:
279: LPBYTE GetGray()
280: {
281: int i,j; BYTE r,g,b,gray;
282: LPBYTE iGray=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
283: FillMemory(iGHist,sizeof(UINT)*512,0);
284:
285: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
286: b=lpOrgBMP[j*3+i*iLength+0];
287: g=lpOrgBMP[j*3+i*iLength+1];
288: r=lpOrgBMP[j*3+i*iLength+2];
289: gray=rgb2gray(r,g,b);
290: if(gray>iWHITE) gray=iWHITE;
291: iGHist[gray]++;
292: iGray[j+i*iWidth] = gray;
293: }
294: return iGray;
295: }
296: LPBYTE GetColor(int csel)
297: {
298: int i,j; BYTE c;
299: LPBYTE iColor=(LPBYTE)GlobalAlloc(GPTR,sizeof(BYTE)*iSize);
300: FillMemory(iGHist,sizeof(UINT)*512,0);
301:
302: for(i=0;i<iHeight;i++) for(j=0;j<iWidth;j++) {
303: c = lpOrgBMP[j*3+i*iLength + csel];
304: iColor[j+i*iWidth] = c;
305: iGHist[c]++;
306: }
307: return iColor;
308: }
309:
310:
311:
312: void IPfunc_OR(LPBYTE iDst,LPBYTE iAdd)
313: {
314: int x,y;
315: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++) {
316: iDst[x+y*iWidth] = (iDst[x+y*iWidth] | iAdd[x+y*iWidth])?
317: iWHITE: iBLACK;
318: }
319: }
320:
321:
322:
323: void IPfunc_median(LPBYTE inBuf)
324: {
325: int i,x,y,px,py;
326: BYTE c[9];
327: LPBYTE tempBuf=(LPBYTE)GlobalAlloc(GPTR,iSize);
328: CopyMemory(tempBuf,inBuf,iSize);
329:
330: for(y=1;y<iHeight-1;y++) for(x=1;x<iWidth-1;x++){
331: for(i=0;i<8;i++){
332: px = x+offset8[i].x;
333: py = y+offset8[i].y;
334: c[i] = tempBuf[px+py*iWidth];
335: }
336: inBuf[x+y*iWidth] = median(c);
337: }
338: GlobalFree(tempBuf);
339: }
340: BYTE median(BYTE c[9])
341: {
342: int i,j;
343: for(j=0;j<8;j++) for(i=0;i<8;i++){
344: if(c[i+1]<c[i]) swapcol(c[i],c[i+1]);
345: }
346: return c[4];
347: }
348:
349:
350:
351: void toDither(LPBYTE inBuf)
352: {
353: static int DITHER_BSZ = 4;
354: static int DITHER_NL = 16;
355: double width;
356: BYTE new_gray;
357: int x_block,y_block;
358: int x,y,i,j,m,n,px,py;
359: static int dither_matrix[4][4]={
360: { 0, 8, 2,10},
361: {12, 4,14, 6},
362: { 3,11, 1, 9},
363: {15, 7,13, 5}
364: };
365:
366:
367:
368: width = iWHITE/(double)DITHER_NL;
369: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
370: new_gray=rint(inBuf[x+y*iWidth]/width);
371: if(new_gray > DITHER_NL-1)
372: new_gray = DITHER_NL-1;
373: inBuf[x+y*iWidth] = new_gray;
374: }
375:
376:
377:
378: x_block=iWidth / DITHER_BSZ;
379: y_block=iHeight / DITHER_BSZ;
380: if(iWidth % DITHER_BSZ) x_block++;
381: if(iHeight % DITHER_BSZ) y_block++;
382: for(i=0;i<y_block;i++) for(j=0;j<x_block;j++){
383: x=j*DITHER_BSZ;
384: y=i*DITHER_BSZ;
385: for(m=0;m<DITHER_BSZ;m++) for(n=0;n<DITHER_BSZ;n++){
386: px=x+n; py=y+m;
387: if(px>=0 && px<iWidth && py>=0 && py<iHeight){
388: if(inBuf[px+py*iWidth] <= dither_matrix[m][n])
389: inBuf[px+py*iWidth]=0;
390: else inBuf[px+py*iWidth]=iWHITE;
391: }
392: }
393: }
394: }
395:
396:
397:
398: void linear_transform(LPBYTE inBuf)
399: {
400: int x,y;
401: int minv,maxv;
402:
403: minv = 10000; maxv = 0;
404: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++){
405: if(inBuf[x+y*iWidth]<minv) minv=inBuf[x+y*iWidth];
406: if(inBuf[x+y*iWidth]>maxv) maxv=inBuf[x+y*iWidth];
407: }
408:
409: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++)
410: inBuf[x+y*iWidth] = (BYTE)rint((inBuf[x+y*iWidth]-minv)*
411: iWHITE/(double)(maxv-minv));
412: }
413:
414:
415:
416:
417:
418: void change_graylevel(LPBYTE inBuf,int iLevel)
419: {
420: int trhist[512],trans_table[512];
421: int i,x,y,gray;
422: int target_value;
423: double gray_step;
424:
425: target_value = rint(iSize/(double)iLevel);
426: FillMemory(trhist,512,0);
427: FillMemory(trans_table,512,0);
428: gray = 0;
429: for(i=0;i<iMAX_GRAY;i++){
430: if(abs(target_value-trhist[gray]) <
431: abs(target_value-(trhist[gray] + iGHist[i]))){
432: gray ++;
433: if(gray>=iLevel) gray=iLevel-1;
434: }
435: trans_table[i] = gray;
436: trhist[gray] += iGHist[i];
437: }
438:
439: gray_step = (double)(iWHITE+1) / iLevel;
440: for(y=0;y<iHeight;y++) for(x=0;x<iWidth;x++)
441: inBuf[x+y*iWidth] = (BYTE)rint(
442: trans_table[inBuf[x+y*iWidth]] * gray_step);
443: }
444:
445:
446:
447: void spacial_filtering(LPBYTE inBuf,int iFlt[9],double iMag)
448: {
449: LPBYTE tempBuf=(LPBYTE)GlobalAlloc(GPTR,iSize);
450: int i,x,y,px,py;
451: double new_value,minv,maxv;
452:
453: CopyMemory(tempBuf,inBuf,iSize);
454:
455: minv = 10000.; maxv = 0.;
456: for(y=1;y<iHeight-1;y++) for(x=1;x<iWidth-1;x++){
457: new_value = 0.0;
458: for(i=0;i<9;i++){
459: px = x+offset9[i].x;
460: py = y+offset9[i].y;
461: new_value += iFlt[i] * tempBuf[px+py*iWidth];
462: }
463: new_value = new_value / iMag;
464: if(new_value < minv) minv = new_value;
465: if(new_value > maxv) maxv = new_value;
466: }
467:
468: for(y=1;y<iHeight-1;y++) for(x=1;x<iWidth-1;x++){
469: new_value = 0.0;
470: for(i=0;i<9;i++){
471: px = x+offset9[i].x;
472: py = y+offset9[i].y;
473: new_value += iFlt[i] * tempBuf[px+py*iWidth];
474: }
475: new_value = new_value / iMag;
476: new_value = iWHITE / (maxv-minv) * (new_value-minv);
477: inBuf[x+y*iWidth] = (BYTE)rint(new_value);
478: }
479: GlobalFree(tempBuf);
480: }