QuakeGod
2021-06-20 4b03ae5cf77da35e8cf7a7c4b508bba09307cc3a
提交 | 用户 | age
4b03ae 1 #include "stdafx.h"
Q 2 #include "ImageFunc.h"
3 #include <WinGDI.h>
4 #include <omp.h>
5 #include <math.h>
6 #include <intrin.h>
7 #include "../Functions.hpp"
8 #include "../MHashINI/MHash.hpp"
9 #define Pi 3.1415926535897932384626433
10
11 using namespace Gdiplus;
12 #pragma comment(lib,"gdiplus.lib")
13
14 int MyImage::AllocBuf(int width,int height,int stride,int PixelFormat1)
15 {    
16     if (ShowCache != NULL) { ::delete ShowCache; ShowCache = NULL; }
17     //stride ,以64字节对齐?
18     if (stride==0) {stride=(width+Stride_Align-1)&(-Stride_Align);}
19     if (buffer0!=NULL) 
20     {    
21         if (width==this->Width&&height==this->Height&&stride==this->Stride)
22         {
23             this->PixelFormat=PixelFormat1;
24             m_thumbImg.IsValid=0;
25             return true;    
26         }
27         delete[] buffer0;
28         delete[] buffer2;
29         delete[] buffer3;
30
31     }
32     buffer0=new unsigned char[stride*height+Stride_Align];
33     buffer=(void *)(((INT_PTR)buffer0+Stride_Align-1)&(INT_PTR)(-Stride_Align));
34     this->Width=width;
35     this->Height=height;
36     this->Stride=stride;
37     if (PixelFormat1!=0) this->PixelFormat=PixelFormat1;
38     else {this->PixelFormat=MyPixelType_Mono8;}
39     if (PixelFormat1 == MyPixelType_RGB8planar)
40     {
41         buffer2 = new unsigned char[stride*height + Stride_Align];
42         buffer3 = new unsigned char[stride*height + Stride_Align];
43     }
44     IsValid=true;
45
46     return true;
47 }
48
49 int MyImage::CopyFromGdipBitMap(Gdiplus::Bitmap * bitmap1)
50 {
51     if (bitmap1==NULL) {return -1;}
52     int w,h;
53     w=bitmap1->GetWidth();
54     h=bitmap1->GetHeight();
55     Rect rect1;
56     rect1.X=0;rect1.Y=0;rect1.Width=w;rect1.Height=h;
57     BitmapData bitmapData1;
58     
59     Gdiplus::PixelFormat pixelformat = bitmap1->GetPixelFormat();
60     if (pixelformat==PixelFormat8bppIndexed)
61     {
62         bitmap1->LockBits(&rect1,ImageLockModeRead,PixelFormat8bppIndexed,&bitmapData1);
63         int stride1=bitmapData1.Stride;
64         unsigned char * buf1=(unsigned char *)bitmapData1.Scan0;
65         int r=CopyFromBuf(buf1,w,h,stride1,MyPixelType_Mono8);
66     }else
67     {
68         bitmap1->LockBits(&rect1,ImageLockModeRead,PixelFormat32bppRGB,&bitmapData1);
69         int stride1=bitmapData1.Stride;
70         DWORD * buf1=(DWORD *)bitmapData1.Scan0;
71 //         this->AllocBuf(w,h);
72 //         int stride2=this->Stride;
73 //         unsigned char * pixels=(unsigned char *)buffer;
74 //         for (int i=0;i<h;i++)
75 //         {
76 //             int l1=i*stride1/4;
77 //             int l=i*stride2;
78 //             for (int j=0;j<w;j++)
79 //             {
80 //                 COLOR c1;
81 //                 c1.argb=buf1[l1+j];
82 //                 pixels[l+j]=RGBtoVI(c1.R,c1.G,c1.B);
83 //             }
84 //         }
85         int r=CopyFromBuf(buf1,w,h,stride1,MyPixelType_ARGB32);
86     }
87     bitmap1->UnlockBits(&bitmapData1);
88     return 1;
89 }
90
91 int MyImage::LoadFromBitmapFile(CString sFilePathName)
92 {
93     Bitmap bitmap1(sFilePathName);
94     this->CopyFromGdipBitMap(&bitmap1);
95     int j = sFilePathName.MakeUpper().Find(_T(".RAW"));
96     if ( j!= -1)
97     {
98         int k = this->PixelFormat;
99         if ( k == MyPixelType_Mono8)
100         {
101             this->PixelFormat = MyPixelType_BayerGR8;
102         }
103
104     }
105     return 0;
106 }
107
108 int MyImage::SaveToFile(CString sFilePathName)
109 {
110     if (this->PixelFormat == MyPixelType_RGB8planar)
111     {
112         return 0;
113
114     }if (this->PixelFormat == MyPixelType_ARGB32)
115     {
116         Bitmap * bitmap1=NULL;
117         ConvertTypeToGdipBitmap32(&bitmap1);
118         int r=SaveGdiPImageAsFile(bitmap1, sFilePathName);
119         return r;
120     }
121     else
122     {
123         int r = SaveBufferToBmpFile(buffer, Width, Height, Stride, sFilePathName, 0, 0);
124         return r;
125     }
126 }
127
128 int MyImage::LoadRegionFromFile(CString sFilePathName)
129 {
130     myregions.clear();
131     MHash RegionCfg;
132     RegionCfg.LoadFromFile(sFilePathName);
133     
134     int k = _tstoi(RegionCfg["Regions"]["TotalRegion"]);
135     for (int i = 0; i < k; i++)
136     {
137         MyRegion thisRegion;
138
139         CString RegionNo;
140         RegionNo.Format(_T("Region%d"), i + 1);
141         thisRegion.IsValid = _tstoi(RegionCfg[RegionNo]["IsValid"]);
142         thisRegion.RegionStr = RegionCfg[RegionNo]["Str"];
143         thisRegion.RegionColor = _tstoi(RegionCfg[RegionNo]["Color"]);
144         int PtCount=_tstoi(RegionCfg[RegionNo]["PtCount"]);
145
146         CString ResultStr[10];
147         for (int j = 0; j < PtCount; j++)
148         {
149             CString PtNo;
150             PtNo.Format(_T("Pt%d"), j + 1);
151             CString thisptstr = RegionCfg[RegionNo][PtNo];
152             Split(thisptstr, _T(","), ResultStr);
153             MyPoint thispt;
154             thispt.X = _tstoi(ResultStr[0]);
155             thispt.Y = _tstoi(ResultStr[1]);
156             thisRegion.pts.push_back(thispt);
157         }
158         myregions.push_back(thisRegion);
159     }
160     return 0;
161 }
162 int MyImage::SaveRegionToFile(CString sFilePathName)
163 {
164     CString s1;
165     MHash RegionCfg;
166     int k = myregions.size();
167     s1.Format(_T("%d"), k);
168     RegionCfg["Regions"]["TotalRegion"]=s1;
169     for (int i = 0; i < k; i++)
170     {
171         MyRegion thisRegion;
172         thisRegion = myregions.at(i);
173
174         CString RegionNo;
175         RegionNo.Format(_T("Region%d"), i + 1);
176         s1.Format(_T("%d"), thisRegion.IsValid);
177         RegionCfg[RegionNo]["IsValid"]=s1;
178         RegionCfg[RegionNo]["Str"]=thisRegion.RegionStr;
179         s1.Format(_T("%d"), thisRegion.RegionColor);
180         RegionCfg[RegionNo]["Color"]=s1;
181
182         int PtCount = thisRegion.pts.size();
183         s1.Format(_T("%d"), PtCount);
184         RegionCfg[RegionNo]["PtCount"]=s1;
185
186         for (int j = 0; j < PtCount; j++)
187         {
188             CString PtNo;
189             MyPoint thispt;
190             PtNo.Format(_T("Pt%d"), j + 1);
191             thispt = thisRegion.pts.at(j);
192             s1.Format(_T("%d,%d"), thispt.X, thispt.Y);
193             RegionCfg[RegionNo][PtNo]=s1;
194         }
195     }
196     RegionCfg.SaveToFile(sFilePathName);
197     return 0;
198 }
199
200 int MyImage::CopyFromBuf(void * buf,int w,int h,int stride,int pixelformat)
201 {
202     if (stride==0)
203     {
204         stride=(w+Stride_Align-1)&(-Stride_Align);
205     }    
206     
207     SN=0;
208
209     if (pixelformat==MyPixelType_BayerGB8)
210     {
211         int bpp = stride/w;
212         int newstride = stride - 2*bpp;
213         AllocBuf(w-2,h-2,newstride,pixelformat);
214         for (int i=0; i<h-2; ++i)
215         {
216             memcpy((char*)buffer+i*newstride,(char*)buf+(i+1)*stride+bpp,newstride);
217         }
218         this->PixelFormat=MyPixelType_BayerGR8;
219     }else
220     {
221         AllocBuf(w,h,stride,pixelformat);
222         memcpy(buffer,buf,h*stride);
223     }
224 //    this->PixelFormat=pixelformat;
225     return true;
226 };
227
228 int MyImage::CopyFromBufR90(void * buf,int w,int h,int stride,int pixelformat)
229 {
230     AllocBuf(h,w,h,pixelformat);
231     for (int i=0;i<w;i++)
232     {
233         for (int j=0;j<h;j++)
234         {
235             ((UCHAR *)buffer)[i*Stride+j]=((UCHAR *)buf)[(j)*stride+(w-i-1)];
236         }
237     }
238 //    memcpy(buffer,buf,h*stride);
239     this->PixelFormat=MyPixelType_Mono8;
240     return true;
241 };
242
243 int MyImage::Meg3ImgIntoRGB8planar(MyImage & img1, MyImage &img2, MyImage & img3)
244 {
245     int nwidth, nheight, nstride;
246     nwidth = img1.Width;
247     nheight = img1.Height;
248     nstride = img1.Stride ;
249     this->PixelFormat = MyPixelType_RGB8planar;
250     AllocBuf(nwidth, nheight, nstride, MyPixelType_RGB8planar );
251
252     memcpy(buffer, img1.buffer, nwidth*nheight);
253     memcpy(buffer2, img2.buffer, nwidth*nheight);
254     memcpy(buffer3, img3.buffer, nwidth*nheight);
255     return 0;
256 }
257
258 int MyImage::Meg3ImgIntoRGB(MyImage & img1, MyImage &img2, MyImage & img3)
259 {
260     int nwidth, nheight, nstride;
261     nwidth = img1.Width;
262     nheight = img1.Height;
263     nstride = img1.Stride * 4;
264     this->PixelFormat = MyPixelType_ARGB32;
265     AllocBuf(nwidth, nheight, nstride, MyPixelType_ARGB32);
266
267     for (int i = 0; i < nheight; i++)
268     {
269         unsigned char * line1 = (unsigned char *)img3.buffer + i*img1.Stride;
270         unsigned char * line2 = (unsigned char *)img2.buffer + i*img2.Stride;
271         unsigned char * line3 = (unsigned char *)img1.buffer + i*img3.Stride;
272         unsigned char  * line5 = (unsigned char *)buffer + i*nstride;
273         for (int j = 0; j < nwidth; j+=4)
274         {
275             line5[j*4 ] = line1[j];
276             line5[j*4+1] = line2[j];
277             line5[j*4+2] = line3[j];
278
279             line5[j * 4 + 4] = line1[j+1];
280             line5[j * 4 + 5] = line2[j+1];
281             line5[j * 4 + 6] = line3[j+1];
282
283             line5[j * 4 + 8] = line1[j+2];
284             line5[j * 4 + 9] = line2[j+2];
285             line5[j * 4 + 10] = line3[j+2];
286
287             line5[j * 4 + 12] = line1[j+3];
288             line5[j * 4 + 13] = line2[j+3];
289             line5[j * 4 + 14] = line3[j+3];
290             /*
291             c1.R = line1[j+4];
292             c1.G = line2[j + 4];
293             c1.B = line3[j + 4];
294             line5[j + 4] = c1.argb;
295             c2.R = line1[j + 5];
296             c2.G = line2[j + 5];
297             c2.B = line3[j + 5];
298             line5[j + 5] = c2.argb;
299             c3.R = line1[j + 6];
300             c3.G = line2[j + 6];
301             c3.B = line3[j + 6];
302             line5[j + 6] = c3.argb;
303             c4.R = line1[j + 7];
304             c4.G = line2[j + 7];
305             c4.B = line3[j + 7];
306             line5[j + 7] = c4.argb;
307             //*/
308         }
309     }
310     return 0;
311 }
312
313 int MyImage::CreateThumbImg(int Width, int Height,float startX, float startY , float swidth, float sheight )
314 {
315     if (!IsValid) return -1;
316     int nThumbWidth, nThumbHeight;
317     float nSrcStartX, nSrcStartY, nSrcWidth, nSrcHeight;
318     if (Width == 0 || Height == 0)
319     {
320         nThumbWidth = 1280;
321         nThumbHeight = 960;
322         nSrcStartX = 0; nSrcStartY = 0; nSrcWidth = this->Width; nSrcHeight = this->Height;
323     }
324     else
325     {
326         nThumbWidth = Width;
327         nThumbHeight = Height;
328         if (swidth == 0 || sheight == 0)
329         {
330             nSrcStartX = 0; nSrcStartY = 0; nSrcWidth = this->Width; nSrcHeight = this->Height;
331         }
332         else
333         {
334             nSrcStartX = startX; nSrcStartY = startY; 
335             nSrcWidth = swidth; nSrcHeight = sheight;
336         }
337     }
338     if (m_thumbImg.buffer&&m_thumbImg.nWidth != nThumbWidth || m_thumbImg.nHeight != nThumbHeight)
339     {
340         delete m_thumbImg.buffer; m_thumbImg.buffer = nullptr;
341     }
342     m_thumbImg.nWidth = nThumbWidth;
343     m_thumbImg.nHeight = nThumbHeight;
344     if (this->PixelFormat == MyPixelType_ARGB32)
345     {
346         if (m_thumbImg.buffer == 0)
347         {
348             m_thumbImg.buffer = new DWORD[nThumbWidth * nThumbHeight ];
349         }
350         for (int i = 0; i < nThumbHeight; i++)
351         {
352             DWORD * line1 = (DWORD *)buffer + int(i*nSrcHeight / nThumbHeight+nSrcStartY) * (Stride/4);
353             DWORD * tline1 = (DWORD *)m_thumbImg.buffer + i * nThumbWidth;
354             for (int j = 0; j < nThumbWidth; j++)
355             {
356                 tline1[j] = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
357                 //tline1[j] = 255;
358             }
359         }
360         m_thumbImg.IsValid = 1;
361     }
362     else if (this->PixelFormat == MyPixelType_RGB8planar)
363     {
364         if (m_thumbImg.buffer == 0)
365         {
366             m_thumbImg.buffer = new DWORD[(nThumbWidth+3)/4*4 * (nThumbHeight+1)/2*2];
367         }
368         for (int i = 0; i < nThumbHeight; i++)
369         {
370             unsigned char * line1 = (unsigned char *)buffer + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
371             unsigned char * line2 = (unsigned char *)buffer2 + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
372             unsigned char * line3 = (unsigned char *)buffer3 + int(i*nSrcHeight / nThumbHeight + nSrcStartY) * (Stride);
373
374
375             DWORD * tline1 = (DWORD *)m_thumbImg.buffer + i * nThumbWidth;
376             for (int j = 0; j < nThumbWidth; j++)
377             {
378                 COLOR * c1 = (COLOR *)&(tline1[j]);
379                 c1->R = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
380                 c1->G = line2[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
381                 c1->B = line3[int(j*nSrcWidth / nThumbWidth + nSrcStartX)];
382
383                 //tline1[j] = 255;
384             }
385         }
386         m_thumbImg.IsValid = 1;
387     }
388     else if (this->PixelFormat == MyPixelType_BayerGR8 || this->PixelFormat == MyPixelType_BayerGB8)
389     {
390         if (m_thumbImg.buffer == 0)
391         {
392             m_thumbImg.buffer = new unsigned char[(nThumbWidth + 3) / 4 * 4 * (nThumbHeight + 1) / 2 * 2];
393         }
394         
395         for (int i = 0; i < nThumbHeight; i+=2)
396         {
397             unsigned char * line1 = (unsigned char *)buffer + (int(i*nSrcHeight / nThumbHeight + nSrcStartY) & 0xfffffffe) * Stride;
398             unsigned char * tline1 = (unsigned char *)m_thumbImg.buffer + i * nThumbWidth;
399             unsigned char * line2 = (unsigned char *)buffer + ((int(i*nSrcHeight / nThumbHeight + nSrcStartY) & 0xfffffffe) + 1) * Stride;
400             unsigned char * tline2 = (unsigned char *)m_thumbImg.buffer + (i+1) * nThumbWidth;
401
402             for (int j = 0; j < nThumbWidth; j+=2)
403             {
404                 tline1[j] = line1[int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe];
405                 tline1[j + 1] = line1[(int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe) + 1];
406                 tline2[j] = line2[int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe];
407                 tline2[j + 1] = line2[(int(j*nSrcWidth / nThumbWidth + nSrcStartX) & 0xfffffffe) + 1];
408                 //tline1[j] = 255;//line1[(j*this->Width / nWidth)&0xfffffffe];
409                 //tline1[j+1] = 0;//line1[((j*this->Width / nWidth)&0xfffffffe)+1];
410                 //tline2[j] = 0;//line2[(j*this->Width / nWidth)&0xfffffffe];
411                 //tline2[j+1] = 255;//line2[((j*this->Width / nWidth)&0xfffffffe)+1];
412             }
413         }
414         m_thumbImg.IsValid = 1;
415     }
416     else
417     {
418         if (m_thumbImg.buffer == 0)
419         {
420             m_thumbImg.buffer = new unsigned char[nThumbWidth * nThumbHeight];
421         }
422         for (int i = 0; i < nThumbHeight; i++)
423         {
424             unsigned char * line1 = (unsigned char *)buffer + int(i*nSrcHeight / nThumbHeight+nSrcStartY) * Stride;
425             unsigned char * tline1 = (unsigned char *)m_thumbImg.buffer + i * nThumbWidth;
426             for (int j = 0; j < nThumbWidth; j++)
427             {
428                 tline1[j] = line1[int(j*nSrcWidth / nThumbWidth+nSrcStartX)];
429             }
430         }
431         m_thumbImg.IsValid = 1;
432     }
433
434     return 0;
435 }
436 int MyImage::DrawOnWindow(HWND hWnd,int Brightness,int Contrast)
437 {
438
439 /*
440     if (this->IsHistoValid)
441     {
442         Graphics gr1(bitmap1);
443         Pen pen1(Color(255,255,255,255),1);
444         for (int i=0;i<256;i++)
445         {
446             int Length=this->HistoArray[i]*512/this->MaxHistoCount;
447             if (Length>255) {Length=255;}
448             gr1.DrawLine(&pen1,i,256,i,1);
449         }
450     }
451 */
452     CString s1;
453     s1.Format(_T("SN:%d %s "),this->SN,this->Name);
454     s1+=InfoStr;
455     CString * Lable;
456     Lable = &s1;
457 //    DrawBitmapOnWindow(hWnd,bitmap1,&s1,&ResultStr);
458
459 //    if (bitmap1 == NULL) return 0;
460     if (hWnd == NULL) return 0;
461     if (!IsWindow(hWnd)) return 0;
462     if (!IsWindowVisible(hWnd)) return 0;
463
464     int srcw, srch;
465     srcw = this->Width;
466     srch = this->Height;
467     if (srcw == 0 || srch == 0) return 0;
468
469     RECT rect0;
470     GetClientRect(hWnd, &rect0);
471     int clientw, clienth;        //客户区实际的宽度和高度
472     clientw = rect0.right - rect0.left;
473     clienth = rect0.bottom - rect0.top;
474
475     SolidBrush brush1(Color(255, 0, 0, 0));        //写黑字
476     SolidBrush brush2(Color(255, 255, 255, 255));    //写白字
477     int w1, h1;    //图片在客户区显示时的宽度和高度,
478     //考虑到保持宽高比,与客户区大小不一定相同
479     int startx, starty;
480     //图片在客户区的起始位置;
481
482     if (srcw*rect0.bottom == srch*rect0.right)
483     {
484         w1 = clientw;
485         h1 = clienth;
486         startx = rect0.left;
487         starty = rect0.top;
488
489     }
490     else if (srcw*rect0.bottom>srch*rect0.right) //图片横向大,高度不满
491     {
492         w1 = clientw;
493         h1 = clientw*srch / srcw;
494         startx = rect0.left;
495         starty = rect0.top + (clienth - h1) / 2;
496     }
497     else //图片纵向大,宽度不满
498     {
499         w1 = clienth*srcw / srch;
500         h1 = clienth;
501         startx = rect0.left + (clientw - w1) / 2;
502         starty = rect0.top;
503     }
504     Bitmap *bitmap1 = NULL;
505     if (IsToRefreshCache||ShowCache != NULL && (ShowCache->GetWidth() != w1 || ShowCache->GetHeight() != h1))
506     {
507         ::delete ShowCache;
508         ShowCache = NULL;
509         IsToRefreshCache = 0;
510     }
511     if (ShowCache == NULL)
512     {
513         Rect rect4;
514         rect4.X = 0;
515         rect4.Y = 0;
516         rect4.Width = w1;
517         rect4.Height = h1;
518         ConvertTypeToGdipBitmap32(&bitmap1, Brightness, Contrast);
519         ShowCache = ::new Bitmap(w1, h1);
520         Graphics gr4(ShowCache);
521         gr4.DrawImage(bitmap1,rect4);
522
523         //------------ 显示 Region
524
525         int n = myregions.size();
526         for (int i = 0; i < n; i++)
527         {
528             MyRegion thisregion = myregions.at(i);
529             int k = thisregion.pts.size();
530             if (thisregion.IsValid)
531             {
532                 Pen pen1(Color(255,255,0,0), 1);
533                 MyPoint lastPt = thisregion.pts.at(k - 1);
534                 for (int j = 0; j < k; j++)
535                 {
536                     MyPoint pt1 = thisregion.pts.at(j);
537                     gr4.DrawRectangle(&pen1, pt1.X*w1 / srcw - 2, pt1.Y*h1 / srch - 2 , 4, 4);
538                     gr4.DrawLine(&pen1, pt1.X*w1 / srcw , pt1.Y*h1 / srch, lastPt.X*w1 / srcw, lastPt.Y*h1 / srch);
539                     lastPt = pt1;
540                 }
541             }
542         }
543         //-----------------------------------------------------------
544         ///*
545
546         if (Lable != NULL&&!Lable->IsEmpty())
547         {
548             CStringW sw1;
549             TToW(*Lable, sw1);
550             //    Pen pen1(Color(255,0,0,0),1);        //画黑线
551             Pen pen2(Color(128, 128, 128, 128), 0.5);  //画灰线
552
553             FontFamily fontfamily1(L"黑体");
554             int fontsize = h1 / 60;
555             if (fontsize<16) { fontsize = 16; }
556             Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
557             //        Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
558             StringFormat stringformat1;
559             stringformat1.SetAlignment(StringAlignmentNear);
560             stringformat1.SetLineAlignment(StringAlignmentNear);
561             gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(0.0f, 0.0f), &stringformat1, &brush1);
562             gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(2.0f, 2.0f), &stringformat1, &brush1);
563             gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(0.0f, 2.0f), &stringformat1, &brush1);
564             gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(2.0f, 0.0f), &stringformat1, &brush1);
565             gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(1.0f, 1.0f), &stringformat1, &brush2);
566         }
567         if (!ResultStr.IsEmpty())
568         {
569             CStringW sw1;
570             TToW(ResultStr, sw1);
571             //    Pen pen1(Color(255,0,0,0),1);        //画黑线
572             Pen pen2(Color(128, 128, 128, 128), 0.5);  //画灰线
573             SolidBrush brush3(Color(255, 0, 0, 0));        //写黑字
574             SolidBrush brush4(Color(128, 0, 255, 0));    //写绿字
575
576             FontFamily fontfamily1(L"黑体");
577             int fontsize = h1 / 4;
578             if (fontsize<48) { fontsize = 48; }
579             Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
580             //        Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
581             StringFormat stringformat1;
582             stringformat1.SetAlignment(StringAlignmentCenter);
583             stringformat1.SetLineAlignment(StringAlignmentCenter);
584             float centerx, centery;
585             centerx = (w1) / 2;
586             centery = (h1) / 2;
587             //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
588             //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
589             //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
590             //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
591             gr4.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(centerx + 1.0f, centery + 1.0f), &stringformat1, &brush4);
592         }
593
594         gr4.Flush();
595
596     }
597     Rect rect1;
598     rect1.X = startx;
599     rect1.Y = starty;
600     rect1.Width = w1;
601     rect1.Height = h1;
602
603     HDC hdc1 = GetDC(hWnd);
604     Graphics gr1(hdc1);
605
606     gr1.DrawImage(ShowCache, rect1);        //画图像
607     if (startx != 0)        //在图像的两侧画背景
608     {
609         gr1.FillRectangle(&brush1, 0, 0, startx, clienth);
610         gr1.FillRectangle(&brush1, startx + w1, 0, startx, clienth);
611     }
612     if (starty != 0)
613     {
614         gr1.FillRectangle(&brush1, 0, 0, clientw, starty);
615         gr1.FillRectangle(&brush1, 0, starty + h1, clientw, starty);
616     }
617
618     //    gr1.Flush();
619     //*/
620     ReleaseDC(hWnd, hdc1);
621
622     if (bitmap1!=NULL)     ::delete bitmap1;
623     return 1;
624 };
625 int MyImage::DrawThumbOnWindow(HWND hWnd, int Brightness, int Contrast)
626 {
627     if (!m_thumbImg.IsValid) CreateThumbImg();
628     Bitmap *bitmap1 = NULL;
629     ConvertThumbToGdipBitmap32(&bitmap1, Brightness, Contrast);
630     /*
631     if (this->IsHistoValid)
632     {
633     Graphics gr1(bitmap1);
634     Pen pen1(Color(255,255,255,255),1);
635     for (int i=0;i<256;i++)
636     {
637     int Length=this->HistoArray[i]*512/this->MaxHistoCount;
638     if (Length>255) {Length=255;}
639     gr1.DrawLine(&pen1,i,256,i,1);
640     }
641     }
642     */
643     CString s1;
644     s1.Format(_T("SN:%d %s "), this->SN, this->Name);
645     s1 += InfoStr;
646     DrawBitmapOnWindow(hWnd, bitmap1, &s1, &ResultStr);
647     ::delete bitmap1;
648     return 1;
649 };
650 int MyImage::ConvertTypeToGdipBitmap32(Gdiplus::Bitmap** bitmapdest,int Brightness,int Contrast)
651 {
652 /*
653         PixelType_Mono8
654         PixelType_BayerGB8
655         PixelType_BayerGB12
656         PixelType_YUV422packed
657         PixelType_YUV422_YUYV_Packed
658         PixelType_BayerGB12Packed
659 */
660     int i,j,k,l;
661     int w,h;
662     w=this->Width;
663     h=this->Height;
664     int pixeltype;
665     pixeltype=this->PixelFormat;
666     if (*bitmapdest==NULL)
667     {
668         *bitmapdest=::new Gdiplus::Bitmap(w,h);
669     }
670     else if ((*bitmapdest)->GetWidth()!=w&&(*bitmapdest)->GetHeight()!=h)
671     {
672         ::delete *bitmapdest;*bitmapdest=NULL;
673         *bitmapdest=::new Gdiplus::Bitmap(w,h);
674     }
675
676     unsigned char * srcpixel=(unsigned char *)buffer;
677     Gdiplus::BitmapData bitmapdata1;
678     bitmapdata1.PixelFormat=PixelFormat32bppRGB;
679     Gdiplus::Rect rect1(0,0,w,h);
680     Gdiplus::Status    GdipStatus=(*bitmapdest)->LockBits(&rect1,Gdiplus::ImageLockModeWrite,//|ImageLockModeUserInputBuf,
681                     PixelFormat32bppRGB,&bitmapdata1);//PixelFormat32bppRGB
682     if (GdipStatus!=Gdiplus::Ok)
683     {
684         CString Errs1;
685         Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
686 //        SysLog(Errs1);
687         return 0;
688     }
689     COLOR c1;
690     UINT * pixels;
691     pixels=(UINT *)bitmapdata1.Scan0;
692     int s=bitmapdata1.Stride;
693
694
695     if (pixeltype==MyPixelType_Mono8)
696     {
697         for (i=0;i<h;i++)
698         {
699             k=i*(int)Stride;
700             l=i*s/4;
701             for (j=0;j<w;j++)
702             {
703                 c1.R=srcpixel[k+j];
704                 c1.G=c1.R;
705                 c1.B=c1.R;
706                 pixels[l+j]=c1.argb;
707             }
708         }
709     }
710     if (pixeltype==MyPixelType_ARGB32)
711     {
712         memcpy(pixels,buffer,h*Stride);
713     }
714     if (pixeltype==MyPixelType_BayerGR8)
715     {
716         BayerGR8toRGB32(buffer,bitmapdata1.Scan0,w,h,Stride,bitmapdata1.Stride);
717     }
718     if (pixeltype==MyPixelType_BayerGB8)
719     {
720         BayerGB8toRGB32(buffer,bitmapdata1.Scan0,w,h,Stride,bitmapdata1.Stride);    
721     }
722     if (pixeltype==MyPixelType_BayerGB12)
723     {
724         Gdiplus::Bitmap* bitmapRaw8=NULL;
725
726         if (bitmapRaw8==NULL)
727         {
728             bitmapRaw8=::new Gdiplus::Bitmap(w,h,PixelFormat8bppIndexed);
729         }
730         if (bitmapRaw8->GetHeight()!=h||bitmapRaw8->GetWidth()!=w)
731         {
732             ::delete bitmapRaw8;
733             bitmapRaw8=::new Gdiplus::Bitmap(w,h,PixelFormat8bppIndexed);
734         }
735         Gdiplus::ColorPalette * pal1=(Gdiplus::ColorPalette *) new unsigned char[1048];
736         pal1->Flags=2;
737         pal1->Count=256;
738         int i;
739         for (i=0;i<256;i++)
740         {
741             pal1->Entries[i]=Gdiplus::Color::MakeARGB(255,i,i,i);
742         }
743
744         bitmapRaw8->SetPalette(pal1);
745         delete [] pal1;
746
747         Gdiplus::Rect rect1(0,0,w,h);
748         Gdiplus::BitmapData bitmapdataRaw8;
749         bitmapdataRaw8.PixelFormat=PixelFormat8bppIndexed;
750         Gdiplus::Status    GdipStatus=bitmapRaw8->LockBits(&rect1,Gdiplus::ImageLockModeWrite,PixelFormat8bppIndexed,&bitmapdataRaw8);
751         if (GdipStatus!=Gdiplus::Ok)
752         {
753             CString Errs1;
754             Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
755 //            SysLog(Errs1);
756             return 0;
757         }
758         Raw12ToRaw8(bitmapdataRaw8.Scan0,srcpixel,w,h);
759         bitmapRaw8->UnlockBits(&bitmapdataRaw8);
760                 
761         unsigned short *srcpixel2=(unsigned short *) srcpixel;
762         int r,g,b;    
763         for (i=0;i<h;i+=2)
764         {
765             k=i*(int)Stride/2;
766             l=i*s/4;
767     
768             //偶数行
769             for (j=0;j<w;j+=2)
770             {
771                 g=srcpixel2[k+j];
772                 b=srcpixel2[k+j+1];
773                 r=srcpixel2[k+Stride/2+j];
774                 c1.R=r>>4;
775                 c1.G=g>>4;
776                 c1.B=b>>4;
777                 pixels[l+j]=c1.argb;
778                 pixels[l+j+1]=c1.argb;
779             }
780             //奇数行
781             for (j=0;j<w;j+=2)
782             {
783                 g=srcpixel2[k+Stride/2+j+1];
784                 b=srcpixel2[k+j+1];
785                 r=srcpixel2[k+Stride/2+j];
786                 c1.R=r>>4;
787                 c1.G=g>>4;
788                 c1.B=b>>4;
789                 pixels[l+s/4+j]=c1.argb;
790                 pixels[l+s/4+j+1]=c1.argb;
791             }
792         }
793     }
794     if (pixeltype==MyPixelType_YUV422packed)
795     {
796         int y,u,v;
797         int r,g,b;
798         for (i=0;i<h;i++)
799         {
800             k=i*(int)Stride;
801             l=i*s/4;
802             for (j=0;j<w;j+=2)
803             {
804                 y=srcpixel[k+j*2+1];
805                 u=srcpixel[k+(j/2)*4];
806                 v=srcpixel[k+(j/2)*4+2];
807                 r=int(y+1.402*(v-128));
808                 g=int(y-0.34414*(u-128)-0.71414*(v-128));
809                 b=int(y+1.772*(u-128));
810                 if (r<0){r=0;}
811                 if (g<0) {g=0;}
812                 if (b<0) {b=0;}
813
814                 if (r>255){r=255;}
815                 if (g>255){g=255;}
816                 if (b>255) {b=255;}
817                 c1.R=r;
818                 c1.G=g;
819                 c1.B=b;
820                 pixels[l+j]=c1.argb;
821
822                 y=srcpixel[k+j*2+3];
823                 r=int(y+1.402*(v-128));
824                 g=int(y-0.34414*(u-128)-0.71414*(v-128));
825                 b=int(y+1.772*(u-128));
826                 if (r<0){r=0;}
827                 if (g<0) {g=0;}
828                 if (b<0) {b=0;}
829
830                 if (r>255){r=255;}
831                 if (g>255){g=255;}
832                 if (b>255) {b=255;}
833
834                 c1.R=r;
835                 c1.G=g;
836                 c1.B=b;
837                 pixels[l+j+1]=c1.argb;
838             }
839         }
840     }
841             
842     if (pixeltype==MyPixelType_YUV422_YUYV_Packed)
843     {
844         int y,u,v;
845         int r,g,b;
846         for (i=0;i<h;i++)
847         {
848             k=i*(int)Stride;
849             l=i*s/4;
850             for (j=0;j<w;j+=2)
851             {
852                 y=srcpixel[k+j*2];
853                 u=srcpixel[k+(j/2)*4+1];
854                 v=srcpixel[k+(j/2)*4+3];
855                 r=int(y+1.402*(v-128));
856                 g=int(y-0.34414*(u-128)-0.71414*(v-128));
857                 b=int(y+1.772*(u-128));
858                 if (r<0){r=0;}
859                 if (g<0) {g=0;}
860                 if (b<0) {b=0;}
861                 c1.R=(r>255?255:r);
862                 c1.G=(g>255?255:g);
863                 c1.B=(b>255?255:b);
864                 pixels[l+j]=c1.argb;
865
866                 y=srcpixel[k+j*2+2];
867                 r=int(y+1.402*(v-128));
868                 g=int(y-0.34414*(u-128)-0.71414*(v-128));
869                 b=int(y+1.772*(u-128));
870                 if (r<0){r=0;}
871                 if (g<0) {g=0;}
872                 if (b<0) {b=0;}
873                 c1.R=(r>255?255:r);
874                 c1.G=(g>255?255:g);
875                 c1.B=(b>255?255:b);
876                 pixels[l+j+1]=c1.argb;
877             }
878         }
879     }
880 //*/
881     if (this->PixelFormat==MyPixelType_BayerGB12_Packed)
882     {
883         //unsigned short *srcpixel2=(unsigned short *) srcpixel;        
884     /*            
885         int r,g,b;    
886         for (i=0;i<h;i+=2)
887         {
888             k=i*(int)stride;
889             l=i*s/4;
890             //偶数行
891             for (j=0;j<w;j+=2)
892             {
893                 g=((unsigned int)(srcpixel[k+j*3/2]&0xff)<<4)+((unsigned int)(srcpixel[k+j*3/2+1]&0xf));        //
894                 b=((unsigned int)(srcpixel[k+j*3/2+1]&0xf0)>>4)+(((unsigned int)srcpixel[k+j*3/2+2]&0xff)<<4);
895                 r=((unsigned int)srcpixel[k+stride+j*3/2]<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
896                 //b=g;
897                 //r=g;
898                 c1.R=r>>4;
899                 c1.G=g>>4;
900                 c1.B=b>>4;
901                 pixels[l+j]=c1.argb;
902                 pixels[l+j+1]=c1.argb;
903             }
904             //奇数行
905             for (j=0;j<w;j+=2)
906             {
907                 g=((unsigned int)(srcpixel[k+stride+j*3/2+2]&0xff)<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
908                 b=((unsigned int)(srcpixel[k+j*3/2+1]&0xf0)>>4)+((unsigned int)(srcpixel[k+j*3/2+2]&0xff)<<4);
909                 r=((unsigned int)srcpixel[k+stride+j*3/2]<<4)+((unsigned int)(srcpixel[k+stride+j*3/2+1]&0xf));
910                 c1.R=r>>4;
911                 c1.G=g>>4;
912                 c1.B=b>>4;
913                 pixels[l+s/4+j]=c1.argb;
914                 pixels[l+s/4+j+1]=c1.argb;
915             }
916         }        
917         */
918         double SysGamma=1.0f;
919         BayerGB12PackedToRGB32(pixels,srcpixel,w,h,(float)SysGamma);
920     }
921     (*bitmapdest)->UnlockBits(&bitmapdata1);
922     return 1;
923 }
924
925 int MyImage::ConvertThumbToGdipBitmap32(Gdiplus::Bitmap** bitmapdest, int Brightness, int Contrast)
926 {
927     /*
928     PixelType_Mono8
929     PixelType_BayerGB8
930     PixelType_BayerGB12
931     PixelType_YUV422packed
932     PixelType_YUV422_YUYV_Packed
933     PixelType_BayerGB12Packed
934     */
935     int i, j, k, l;
936     int w, h;
937     w = m_thumbImg.nWidth;
938     h = m_thumbImg.nHeight;
939     int pixeltype;
940     pixeltype = this->PixelFormat;
941     
942     if (*bitmapdest == NULL)
943     {
944         *bitmapdest = ::new Gdiplus::Bitmap(w, h);
945     }
946     else if ((*bitmapdest)->GetWidth() != w && (*bitmapdest)->GetHeight() != h)
947     {
948         ::delete *bitmapdest; *bitmapdest = NULL;
949         *bitmapdest = ::new Gdiplus::Bitmap(w, h);
950     }
951
952     unsigned char * srcpixel = (unsigned char *)m_thumbImg.buffer;
953     Gdiplus::BitmapData bitmapdata1;
954     bitmapdata1.PixelFormat = PixelFormat32bppRGB;
955     Gdiplus::Rect rect1(0, 0, w, h);
956     Gdiplus::Status    GdipStatus = (*bitmapdest)->LockBits(&rect1, Gdiplus::ImageLockModeWrite,//|ImageLockModeUserInputBuf,
957         PixelFormat32bppRGB, &bitmapdata1);//PixelFormat32bppRGB
958     if (GdipStatus != Gdiplus::Ok)
959     {
960         CString Errs1;
961         Errs1.Format(_T("Gdip LockBits Error %d \r\n"), GdipStatus);
962         //        SysLog(Errs1);
963         return 0;
964     }
965     COLOR c1;
966     UINT * pixels;
967     pixels = (UINT *)bitmapdata1.Scan0;
968     int s = bitmapdata1.Stride;
969
970
971     if (pixeltype == MyPixelType_Mono8)
972     {
973         for (i = 0; i<h; i++)
974         {
975             k = i*(int)m_thumbImg.nWidth;
976             l = i*s / 4;
977             for (j = 0; j<w; j++)
978             {
979                 c1.R = srcpixel[k + j];
980                 c1.G = c1.R;
981                 c1.B = c1.R;
982                 c1.A = 255;
983                 pixels[l + j] = c1.argb;
984             }
985         }
986     }
987     if (pixeltype == MyPixelType_ARGB32 || pixeltype == MyPixelType_RGB8planar)
988     {
989         memcpy(pixels, m_thumbImg.buffer, h*w * 4);
990     }
991     if (pixeltype == MyPixelType_BayerGR8)
992     {
993         BayerGR8toRGB32(m_thumbImg.buffer, bitmapdata1.Scan0, w, h, w, bitmapdata1.Stride);
994     }
995     if (pixeltype == MyPixelType_BayerGB8)
996     {
997         BayerGB8toRGB32(m_thumbImg.buffer, bitmapdata1.Scan0, w, h, w, bitmapdata1.Stride);
998     }
999     (*bitmapdest)->UnlockBits(&bitmapdata1);
1000     return 1;
1001 }
1002
1003 int GdipDrawRoundRect(Gdiplus::Graphics &gr1, Gdiplus::Pen &pen1, int x1, int y1, int x2, int y2, int r)
1004 {
1005     gr1.DrawLine(&pen1,x1+r,y1,x2-r,y1);
1006     gr1.DrawLine(&pen1,x1+r,y2,x2-r,y2);
1007     gr1.DrawLine(&pen1,x1,y1+r,x1,y2-r);
1008     gr1.DrawLine(&pen1,x2,y1+r,x2,y2-r);
1009     gr1.DrawArc(&pen1,x1,y1,r*2,r*2,180,90);
1010     gr1.DrawArc(&pen1,x2-2*r,y1,r*2,r*2,270,90);
1011     gr1.DrawArc(&pen1,x1,y2-r*2,r*2,r*2,90,90);
1012     gr1.DrawArc(&pen1,x2-r*2,y2-r*2,r*2,r*2,0,90);
1013     return 1;
1014 }
1015
1016 int SaveBufferToFile(void * pBuf, size_t nSize, CString sFilePathName)
1017 {
1018     CString sFilePath;
1019     int j;
1020     j = sFilePathName.ReverseFind(_T('\\'));
1021     sFilePath = sFilePathName.Left(j);
1022     SHCreateDirectoryEx(NULL, sFilePath, NULL);
1023     CFile file1;
1024     CFileException e1;
1025     j = file1.Open(sFilePathName, CFile::modeWrite | CFile::modeCreate, NULL, &e1);
1026     if (!j) { return 0; }
1027     file1.Write(pBuf, nSize);
1028     file1.Close();
1029     return 1;
1030 }
1031
1032 int SaveBufferToBmpFile(void * buf1,int width, int height, int stride, CString FilePathName,LONG XPelsPerMeter,LONG YPelsPerMeter)
1033 {
1034     //分解文件路径和文件名
1035     CString sFilePath;
1036     int j;
1037     j=FilePathName.ReverseFind(_T('\\'));
1038     sFilePath=FilePathName.Left(j);
1039     //检查是否有可用的磁盘空间
1040     ULARGE_INTEGER luse;
1041     ULARGE_INTEGER ltotal;
1042     ULARGE_INTEGER lfree;
1043
1044     double fuse,ftotal,ffree;
1045     GetDiskFreeSpaceEx(sFilePath,&luse,&ltotal,&lfree);
1046     fuse=luse.QuadPart/1024.0/1024.0/1024.0;
1047     ftotal=ltotal.QuadPart/1048576.0/1024.0;
1048     ffree=lfree.QuadPart/1048576.0/1024.0;
1049     if (fuse<1.0) {return false;} //如果可用空间小于1G,那么不存储文件。
1050     //创建目录
1051     SHCreateDirectoryEx(NULL,sFilePath,NULL);
1052
1053     //开始创建位图文件
1054     long newStride;
1055     newStride=((width+3)&0xfffc);
1056     BITMAPFILEHEADER header1;
1057 //    BITMAPINFO info1;
1058     BITMAPINFOHEADER infoheader1;
1059 //    RGBQUAD buf[256];
1060     header1.bfType=0x4d42;
1061     header1.bfSize=newStride*height+1078;
1062     header1.bfReserved1=0;
1063     header1.bfReserved2=0;
1064     header1.bfOffBits=1078;
1065
1066     infoheader1.biSize=40;
1067     infoheader1.biWidth=width;
1068     infoheader1.biHeight=height;
1069     infoheader1.biPlanes=1;
1070     infoheader1.biBitCount=8;
1071     infoheader1.biCompression=BI_RGB;
1072     infoheader1.biSizeImage=0;
1073     infoheader1.biXPelsPerMeter=XPelsPerMeter;
1074     infoheader1.biYPelsPerMeter=YPelsPerMeter;
1075     infoheader1.biClrUsed=0;
1076     infoheader1.biClrImportant=0;
1077     RGBQUAD pallette[256];
1078
1079     for (int i=0;i<256;i++)
1080     {
1081         pallette[i].rgbBlue=i;
1082         pallette[i].rgbGreen=i;
1083         pallette[i].rgbRed=i;
1084         pallette[i].rgbReserved=0;
1085     }
1086
1087     CFile file1;
1088     CFileException e1;
1089     j=file1.Open(FilePathName,CFile::modeWrite|CFile::modeCreate,NULL,&e1);
1090     if (!j) {return 0;}
1091     file1.Write(&header1,sizeof(header1));
1092     file1.Write(&infoheader1,sizeof(infoheader1));
1093     file1.Write(pallette,1024);
1094     for (int i=0;i<height;i++)
1095     {
1096         file1.Write((char *)buf1+(height-i-1)*stride,newStride);
1097     }
1098     file1.Close();
1099     return true;
1100 }
1101
1102 int DrawBitmapOnWindow(HWND DestWindow,Bitmap* srcbitmap,CString * Lable, CString * ResultStr, double scale)
1103 {
1104     if (srcbitmap==NULL) return 0;
1105     if (DestWindow==NULL) return 0;
1106     if (!IsWindow(DestWindow)) return 0;
1107     if (!IsWindowVisible(DestWindow)) return 0;
1108
1109     int srcw,srch;
1110     srcw=srcbitmap->GetWidth();
1111     srch=srcbitmap->GetHeight();
1112
1113     HDC hdc1=GetDC(DestWindow);
1114     Graphics gr1(hdc1);
1115     RECT rect0;
1116     GetClientRect(DestWindow,&rect0);
1117     int clientw,clienth;        //客户区实际的宽度和高度
1118     clientw=rect0.right-rect0.left;
1119     clienth=rect0.bottom-rect0.top;
1120
1121
1122     int w1,h1;    //图片在客户区显示时的宽度和高度,
1123                 //考虑到保持宽高比,与客户区大小不一定相同
1124     int startx,starty;
1125                 //图片在客户区的起始位置;
1126
1127     if (srcw*rect0.bottom==srch*rect0.right)    
1128     {
1129         w1=clientw;
1130         h1=clienth;
1131         startx=rect0.left;
1132         starty=rect0.top;
1133
1134     }else if (srcw*rect0.bottom>srch*rect0.right) //图片横向大,高度不满
1135     {
1136         w1=clientw;
1137         h1=clientw*srch/srcw;
1138         startx=rect0.left;
1139         starty=rect0.top+(clienth-h1)/2;
1140     }
1141     else //图片纵向大,宽度不满
1142     {
1143         w1=clienth*srcw/srch;
1144         h1=clienth;
1145         startx=rect0.left+(clientw-w1)/2;
1146         starty=rect0.top;
1147     }
1148     Rect rect1;
1149     rect1.X=startx;
1150     rect1.Y=starty;
1151     rect1.Width=w1;
1152     rect1.Height=h1;
1153
1154     SolidBrush brush1(Color(255,0,0,0));        //写黑字
1155     SolidBrush brush2(Color(255,255,255,255));    //写白字
1156
1157     gr1.DrawImage(srcbitmap,rect1);        //画图像
1158     if (startx!=0)        //在图像的两侧画背景
1159     {
1160         gr1.FillRectangle(&brush1,0,0,startx,clienth);
1161         gr1.FillRectangle(&brush1,startx+w1,0,startx,clienth);
1162     }
1163     if (starty!=0)
1164     {
1165         gr1.FillRectangle(&brush1,0,0,clientw,starty);
1166         gr1.FillRectangle(&brush1,0,starty+h1,clientw,starty);
1167     }
1168     ///*
1169     if (Lable!=NULL&&!Lable->IsEmpty())
1170     {
1171         CStringW sw1;
1172         TToW(*Lable,sw1);
1173         //    Pen pen1(Color(255,0,0,0),1);        //画黑线
1174         Pen pen2(Color(128,128,128,128),0.5);  //画灰线
1175
1176         FontFamily fontfamily1(L"黑体");
1177         int fontsize=h1/60;
1178         if (fontsize<16) {fontsize=16;}
1179         Gdiplus::Font font1(&fontfamily1,fontsize,FontStyleRegular);
1180 //        Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
1181         StringFormat stringformat1;
1182         stringformat1.SetAlignment(StringAlignmentNear);
1183         stringformat1.SetLineAlignment(StringAlignmentNear);
1184         gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+0.0f,starty+0.0f),&stringformat1,&brush1);
1185         gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+2.0f,starty+2.0f),&stringformat1,&brush1);
1186         gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+0.0f,starty+2.0f),&stringformat1,&brush1);
1187         gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+2.0f,starty+0.0f),&stringformat1,&brush1);
1188         gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(startx+1.0f,starty+1.0f),&stringformat1,&brush2);
1189     }
1190     if (ResultStr!=NULL&&!ResultStr->IsEmpty())
1191     {
1192         CStringW sw1;
1193         TToW(*ResultStr,sw1);
1194         //    Pen pen1(Color(255,0,0,0),1);        //画黑线
1195         Pen pen2(Color(128,128,128,128),0.5);  //画灰线
1196         SolidBrush brush3(Color(255,0,0,0));        //写黑字
1197         SolidBrush brush4(Color(128,0,255,0));    //写绿字
1198
1199         FontFamily fontfamily1(L"黑体");
1200         int fontsize=h1/4;
1201         if (fontsize<48) {fontsize=48;}
1202         Gdiplus::Font font1(&fontfamily1,fontsize,FontStyleRegular);
1203         //        Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
1204         StringFormat stringformat1;
1205         stringformat1.SetAlignment(StringAlignmentCenter);
1206         stringformat1.SetLineAlignment(StringAlignmentCenter);
1207         float centerx,centery;
1208         centerx=(rect0.right+rect0.left)/2;
1209         centery=(rect0.top+rect0.bottom)/2;
1210     //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
1211     //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
1212     //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
1213     //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
1214         gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+1.0f,centery+1.0f),&stringformat1,&brush4);
1215     }
1216 //    gr1.Flush();
1217 //*/
1218     ReleaseDC(DestWindow,hdc1);
1219     return 0;
1220 }
1221 int DrawImageOnWindow(HWND DestWindow, Image* srcimage, CString * Lable, CString * ResultStr, double scale)
1222 {
1223     if (srcimage == NULL) return 0;
1224     if (DestWindow == NULL) return 0;
1225     if (!IsWindow(DestWindow)) return 0;
1226     if (!IsWindowVisible(DestWindow)) return 0;
1227
1228     int srcw, srch;
1229     srcw = srcimage->GetWidth();
1230     srch = srcimage->GetHeight();
1231
1232     HDC hdc1 = GetDC(DestWindow);
1233     Graphics gr1(hdc1);
1234     RECT rect0;
1235     GetClientRect(DestWindow, &rect0);
1236     int clientw, clienth;        //客户区实际的宽度和高度
1237     clientw = rect0.right - rect0.left;
1238     clienth = rect0.bottom - rect0.top;
1239
1240
1241     int w1, h1;    //图片在客户区显示时的宽度和高度,
1242     //考虑到保持宽高比,与客户区大小不一定相同
1243     int startx, starty;
1244     //图片在客户区的起始位置;
1245
1246     if (srcw*rect0.bottom == srch*rect0.right)
1247     {
1248         w1 = clientw;
1249         h1 = clienth;
1250         startx = rect0.left;
1251         starty = rect0.top;
1252
1253     }
1254     else if (srcw*rect0.bottom>srch*rect0.right) //图片横向大,高度不满
1255     {
1256         w1 = clientw;
1257         h1 = clientw*srch / srcw;
1258         startx = rect0.left;
1259         starty = rect0.top + (clienth - h1) / 2;
1260     }
1261     else //图片纵向大,宽度不满
1262     {
1263         w1 = clienth*srcw / srch;
1264         h1 = clienth;
1265         startx = rect0.left + (clientw - w1) / 2;
1266         starty = rect0.top;
1267     }
1268     Rect rect1;
1269     rect1.X = startx;
1270     rect1.Y = starty;
1271     rect1.Width = w1;
1272     rect1.Height = h1;
1273
1274     SolidBrush brush1(Color(255, 0, 0, 0));        //写黑字
1275     SolidBrush brush2(Color(255, 255, 255, 255));    //写白字
1276
1277     gr1.DrawImage(srcimage, rect1);        //画图像
1278     if (startx != 0)        //在图像的两侧画背景
1279     {
1280         gr1.FillRectangle(&brush1, 0, 0, startx, clienth);
1281         gr1.FillRectangle(&brush1, startx + w1, 0, startx, clienth);
1282     }
1283     if (starty != 0)
1284     {
1285         gr1.FillRectangle(&brush1, 0, 0, clientw, starty);
1286         gr1.FillRectangle(&brush1, 0, starty + h1, clientw, starty);
1287     }
1288
1289     if (Lable != NULL&&!Lable->IsEmpty())
1290     {
1291         CStringW sw1;
1292         TToW(*Lable, sw1);
1293         //    Pen pen1(Color(255,0,0,0),1);        //画黑线
1294         Pen pen2(Color(128, 128, 128, 128), 0.5);  //画灰线
1295
1296         FontFamily fontfamily1(L"黑体");
1297         int fontsize = h1 / 60;
1298         if (fontsize<16) { fontsize = 16; }
1299         Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
1300         //        Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
1301         StringFormat stringformat1;
1302         stringformat1.SetAlignment(StringAlignmentNear);
1303         stringformat1.SetLineAlignment(StringAlignmentNear);
1304         gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 0.0f, starty + 0.0f), &stringformat1, &brush1);
1305         gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 2.0f, starty + 2.0f), &stringformat1, &brush1);
1306         gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 0.0f, starty + 2.0f), &stringformat1, &brush1);
1307         gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 2.0f, starty + 0.0f), &stringformat1, &brush1);
1308         gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(startx + 1.0f, starty + 1.0f), &stringformat1, &brush2);
1309     }
1310     if (ResultStr != NULL&&!ResultStr->IsEmpty())
1311     {
1312         CStringW sw1;
1313         TToW(*ResultStr, sw1);
1314         //    Pen pen1(Color(255,0,0,0),1);        //画黑线
1315         Pen pen2(Color(128, 128, 128, 128), 0.5);  //画灰线
1316         SolidBrush brush3(Color(255, 0, 0, 0));        //写黑字
1317         SolidBrush brush4(Color(128, 0, 255, 0));    //写绿字
1318
1319         FontFamily fontfamily1(L"黑体");
1320         int fontsize = h1 / 4;
1321         if (fontsize<48) { fontsize = 48; }
1322         Gdiplus::Font font1(&fontfamily1, fontsize, FontStyleRegular);
1323         //        Gdiplus::Font font2(&fontfamily1,16,FontStyleRegular);
1324         StringFormat stringformat1;
1325         stringformat1.SetAlignment(StringAlignmentCenter);
1326         stringformat1.SetLineAlignment(StringAlignmentCenter);
1327         float centerx, centery;
1328         centerx = (rect0.right + rect0.left) / 2;
1329         centery = (rect0.top + rect0.bottom) / 2;
1330         //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+0.0f),&stringformat1,&brush3);
1331         //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+2.0f),&stringformat1,&brush3);
1332         //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+0.0f,centery+2.0f),&stringformat1,&brush3);
1333         //    gr1.DrawString(sw1,sw1.GetLength(),&font1,Gdiplus::PointF(centerx+2.0f,centery+0.0f),&stringformat1,&brush3);
1334         gr1.DrawString(sw1, sw1.GetLength(), &font1, Gdiplus::PointF(centerx + 1.0f, centery + 1.0f), &stringformat1, &brush4);
1335     }
1336     //    gr1.Flush();
1337     ReleaseDC(DestWindow, hdc1);
1338     return 0;
1339 }
1340
1341 int LoadImageFromBuffer(void *pBuffer, ULONGLONG sizeImage, Gdiplus::Image ** ppimage1)
1342 {
1343     HGLOBAL hBuffer;
1344     hBuffer = GlobalAlloc(GMEM_MOVEABLE, sizeImage);
1345     if (hBuffer == NULL)
1346     {
1347         //s1.Format(_T("分配内存失败 \r\n")); MyLogger1.LogTxt(s1);
1348         return 0;
1349     }
1350 //    s1.Format(_T("分配内存成功 HGlobal %x\r\n"), hBuffer); MyLogger1.LogTxt(s1);
1351
1352     LPVOID pImageData = ::GlobalLock(hBuffer);
1353     if (pImageData == NULL)
1354     {
1355         //s1.Format(_T("锁定内存失败\r\n")); MyLogger1.LogTxt(s1);
1356         ::GlobalFree(hBuffer);
1357         return 0;
1358     }
1359     //s1.Format(_T("锁定内存成功 HGlobal %p\r\n"), pImageData); MyLogger1.LogTxt(s1);
1360
1361     memcpy(pImageData, pBuffer, sizeImage);
1362     ::GlobalUnlock(hBuffer);
1363     IStream *ps = NULL;
1364     Gdiplus::Image *pImg = NULL;
1365     if (::CreateStreamOnHGlobal(hBuffer, TRUE, &ps) == S_OK)
1366     {
1367         //s1.Format(_T("创建Stream成功 \r\n")); MyLogger1.LogTxt(s1);
1368         pImg = Gdiplus::Image::FromStream(ps);
1369         if (pImg != NULL)
1370         {
1371             int w, h;
1372             w = pImg->GetWidth();
1373             h = pImg->GetHeight();
1374             //s1.Format(_T("创建Image成功 W %d h %d \r\n"), w, h); MyLogger1.LogTxt(s1);
1375         }
1376         //_SanUiGdiImageValid(pImg);
1377         *ppimage1 = pImg;
1378         ps->Release();
1379         //::GlobalFree(hBuffer);
1380         return 1;
1381     }
1382     return 1;
1383 }
1384 int HistoGram::MakeHistoGram(Gdiplus::Bitmap * bitmap, int startx, int starty, int width, int height)
1385 {
1386     int i,w,h;
1387     if (width==0) {    w=bitmap->GetWidth();}
1388     else {w=width;}
1389     if (height==0) {h=bitmap->GetHeight();}
1390     else {h=height;}
1391
1392     totalpixels=0;
1393     maxRsample=0;
1394     maxRsampleindex=0;
1395     maxGsample=0;
1396     maxGsampleindex=0;
1397     maxBsample=0;
1398     maxBsampleindex=0;
1399     maxVsample=0;
1400     maxVsampleindex=0;
1401     totalRvalues=0;
1402     totalGvalues=0;
1403     totalBvalues=0;
1404     totalVvalues=0;
1405     minRvalue=255;
1406     maxRvalue=0;
1407     minGvalue=255;
1408     maxGvalue=0;
1409     minBvalue=255;
1410     maxBvalue=0;
1411     minVvalue=255;
1412     maxVvalue=0;
1413     for (i=0;i<256;i++)
1414     {
1415         Rsamples[i]=0;
1416         Gsamples[i]=0;
1417         Bsamples[i]=0;
1418         Vsamples[i]=0;
1419     }
1420     UINT * pixels;
1421     COLOR c1;
1422 //        BYTE R,G,B;
1423     BYTE V;
1424
1425     Gdiplus::BitmapData bitmapData0;
1426     Gdiplus::Rect rect0(startx,starty,w,h);
1427     Gdiplus::Status    GdipStatus=bitmap->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapData0);
1428     if (GdipStatus!=Gdiplus::Ok)
1429     {
1430         CString Errs1;
1431         Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
1432 //        SysLog(Errs1);
1433         return 0;
1434     }
1435 //        bitmap->UnlockBits(&bitmapData0);
1436 //        bitmap->LockBits(&rect0,ImageLockModeRead,PixelFormat32bppRGB,&bitmapData0);
1437     pixels=(UINT *)bitmapData0.Scan0;
1438     totalpixels=h*w;
1439     int step;step=totalpixels/1048576;
1440     if (step<1) {step=1;}
1441     step=1;
1442     int s=bitmapData0.Stride/4;
1443 //    int k;
1444     for (i=0;i<h;i+=step)
1445     {
1446         int k=i*s;
1447         for (int j=0;j<width;j++)
1448         {    
1449 ///*
1450             c1.argb =pixels[k+j];
1451             V=int(RGBtoVI(c1.R,c1.G,c1.B));
1452             Rsamples[c1.R]++;
1453             Gsamples[c1.G]++;
1454             Bsamples[c1.B]++;
1455             Vsamples[V]++;
1456         }
1457     }
1458     bitmap->UnlockBits(&bitmapData0);
1459 ///*
1460     totalpixels-=Vsamples[0];
1461     Rsamples[0]=0;
1462     Gsamples[0]=0;
1463     Bsamples[0]=0;
1464     Vsamples[0]=0;
1465     for (i=0;i<256;i++)
1466     {
1467         totalRvalues+=Rsamples[i]*i;
1468         totalGvalues+=Gsamples[i]*i;
1469         totalBvalues+=Bsamples[i]*i;
1470         totalVvalues+=Vsamples[i]*i;
1471         if (Rsamples[i]>0)
1472         {
1473             if (i<minRvalue) {minRvalue=i;}
1474             if (i>maxRvalue) {maxRvalue=i;}
1475             if (Rsamples[i]>maxRsample) {maxRsample=Rsamples[i];maxRsampleindex=i;}
1476         }
1477         if (Gsamples[i]>0)
1478         {
1479             if (i<minGvalue) {minGvalue=i;}
1480             if (i>maxGvalue) {maxGvalue=i;}
1481             if (Gsamples[i]>maxGsample) {maxGsample=Gsamples[i];maxGsampleindex=i;}
1482         }
1483         if (Bsamples[i]>0)
1484         {
1485             if (i<minBvalue) {minBvalue=i;}
1486             if (i>maxBvalue) {maxBvalue=i;}
1487             if (Bsamples[i]>maxBsample) {maxBsample=Bsamples[i];maxBsampleindex=i;}
1488         }
1489         if (Vsamples[i]>0)
1490         {
1491             if (i<minVvalue) {minVvalue=i;}
1492             if (i>maxVvalue) {maxVvalue=i;}
1493             if (Vsamples[i]>maxVsample) {maxVsample=Vsamples[i];maxVsampleindex=i;}
1494         }
1495
1496     }
1497 //*/        
1498
1499     if (0==totalpixels) {totalpixels=1;}
1500     aveRvalue=(float)totalRvalues/totalpixels;
1501     aveGvalue=(float)totalGvalues/totalpixels;
1502     aveBvalue=(float)totalBvalues/totalpixels;
1503     aveVvalue=(float)totalVvalues/totalpixels;
1504
1505     if (maxRsample==0) {maxRsample=1;}
1506     if (maxGsample==0) {maxGsample=1;}
1507     if (maxBsample==0) {maxBsample=1;}
1508     if (maxVsample==0) {maxVsample=1;}
1509
1510     return totalpixels;
1511 };
1512 //    HISTOGRAM();
1513 //    HISTOGRAM(Bitmap * bitmap);
1514 //    HISTOGRAM(Bitmap * bitmap)
1515 //     {
1516 //         MakeHistoGram(bitmap);
1517 //     };
1518 int HistoGram::getRpercentvalue(float percent)
1519 {
1520     int i,j;
1521     j=0;
1522     for (i=0;i<256;i++)
1523     {
1524         j+=Rsamples[i];
1525         if (j>=percent*totalpixels) {break;}
1526     }
1527     return i;
1528 }
1529
1530
1531 int HistoGram::getGpercentvalue(float percent)
1532 {
1533     int i,j;
1534     j=0;
1535     for (i=0;i<256;i++)
1536     {
1537         j+=Gsamples[i];
1538         if (j>=percent*totalpixels) {break;}
1539     }
1540     return i;
1541 }
1542
1543
1544 int HistoGram::getBpercentvalue(float percent)
1545 {
1546     int i,j;
1547     j=0;
1548     for (i=0;i<256;i++)
1549     {
1550         j+=Bsamples[i];
1551         if (j>=percent*totalpixels) {break;}
1552     }
1553     return i;
1554 }
1555
1556 int HistoGram::getVpercentvalue(float percent)
1557 {
1558     int i,j;
1559     j=0;
1560     for (i=0;i<256;i++)
1561     {
1562         j+=Vsamples[i];
1563         if (j>=percent*totalpixels) {break;}
1564     }
1565     return i;
1566 }
1567
1568 float HistoGram::GetMostRvalue()
1569 {
1570     float r;
1571     int i;
1572     i=maxRsampleindex;
1573     if (i==0)
1574     {
1575         r=float(Rsamples[i]*i+Rsamples[i+1]*(i+1))/(Rsamples[i]+Rsamples[i+1]);
1576         return r;
1577     }
1578     if (i==255)
1579     {
1580         r=float(Rsamples[i-1]*(i-1)+Rsamples[i]*(i))/(Rsamples[i-1]+Rsamples[i]);
1581         return r;
1582     }
1583     if (Rsamples[i-1]>Rsamples[i+1])
1584     {
1585         int sample1,samplemax,sample2;
1586         sample1=Rsamples[i-1];
1587         samplemax=Rsamples[i];
1588         sample2=Rsamples[i+1];
1589         r=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
1590     }
1591     else
1592     {
1593         int sample1,samplemax,sample2;
1594         sample2=Rsamples[i-1];
1595         samplemax=Rsamples[i];
1596         sample1=Rsamples[i+1];
1597         r=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
1598
1599     }
1600     //r=double(Rsamples[i-1]*(i-1)+Rsamples[i]*(i)+Rsamples[i+1]*(i+1))/(Rsamples[i-1]+Rsamples[i]+Rsamples[i+1]);
1601     return r;
1602 }
1603 float HistoGram::GetMostGvalue()
1604 {
1605     float g;
1606     int i;
1607     i=maxGsampleindex;
1608     if (i==0)
1609     {
1610         g=float(Gsamples[i]*i+Gsamples[i+1]*(i+1))/(Gsamples[i]+Gsamples[i+1]);
1611         return g;
1612     }
1613     if (i==255)
1614     {
1615         g=float(Gsamples[i-1]*(i-1)+Gsamples[i]*(i))/(Gsamples[i-1]+Gsamples[i]);
1616         return g;
1617     }
1618     if (Gsamples[i-1]>Gsamples[i+1])
1619     {
1620         int sample1,samplemax,sample2;
1621         sample1=Gsamples[i-1];
1622         samplemax=Gsamples[i];
1623         sample2=Gsamples[i+1];
1624         g=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
1625     }
1626     else
1627     {
1628         int sample1,samplemax,sample2;
1629         sample2=Gsamples[i-1];
1630         samplemax=Gsamples[i];
1631         sample1=Gsamples[i+1];
1632         g=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
1633
1634     }
1635 //    g=double(Gsamples[i-1]*(i-1)+Gsamples[i]*(i)+Gsamples[i+1]*(i+1))/(Gsamples[i-1]+Gsamples[i]+Gsamples[i+1]);
1636     return g;
1637 }
1638 float HistoGram::GetMostBvalue()
1639 {
1640     float b;
1641     int i;
1642     i=maxBsampleindex;
1643     if (i==0)
1644     {
1645         b=float(Bsamples[i]*i+Bsamples[i+1]*(i+1))/(Bsamples[i]+Bsamples[i+1]);
1646         return b;
1647     }
1648     if (i==255)
1649     {
1650         b=float(Bsamples[i-1]*(i-1)+Bsamples[i]*(i))/(Bsamples[i-1]+Bsamples[i]);
1651         return b;
1652     }
1653     if (Bsamples[i-1]>Bsamples[i+1])
1654     {
1655         int sample1,samplemax,sample2;
1656         sample1=Bsamples[i-1];
1657         samplemax=Bsamples[i];
1658         sample2=Bsamples[i+1];
1659         b=float(i)-float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
1660     }
1661     else
1662     {
1663         int sample1,samplemax,sample2;
1664         sample2=Bsamples[i-1];
1665         samplemax=Bsamples[i];
1666         sample1=Bsamples[i+1];
1667         b=float(i)+float((samplemax-sample2)-(samplemax-sample1))/(samplemax-sample2)/2;
1668
1669     }
1670
1671     b=float(Bsamples[i-1]*(i-1)+Bsamples[i]*(i)+Bsamples[i+1]*(i+1))/(Bsamples[i-1]+Bsamples[i]+Bsamples[i+1]);
1672     return b;
1673 }
1674
1675 int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,POINT srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
1676 {
1677     Gdiplus::PointF pt[4];
1678     for (int i=0;i<4;i++)
1679     {
1680         pt[i].X=float(srcpt[i].x);pt[i].Y=float(srcpt[i].y);
1681     }
1682     return QuadRectTransForm(bitmapsrc,pt,bitmapdest,destrect);
1683 }
1684 int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,Gdiplus::Point srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
1685 {
1686     Gdiplus::PointF pt[4];
1687     for (int i=0;i<4;i++)
1688     {
1689         pt[i].X=float(srcpt[i].X);pt[i].Y=float(srcpt[i].X);
1690     }
1691     return QuadRectTransForm(bitmapsrc,pt,bitmapdest,destrect);
1692     return 1;
1693 }
1694
1695 UINT __cdecl TransFormThread(LPVOID pParam)
1696 {
1697     TransFormThreadDataStruct * mydata=(TransFormThreadDataStruct *)pParam;
1698     int w,h;
1699     w=mydata->destrect.Width;
1700     h=mydata->destrect.Height;
1701
1702     Gdiplus::PointF startpt,endpt,curpt;
1703
1704     Gdiplus::PointF    leftdelta,rightDelta;
1705     Gdiplus::PointF    leftstart,rightstart;
1706     Gdiplus::PointF    curstart,curdelta;
1707     int i,j,k,l;
1708
1709     int curx,cury;    //最临近的像素? 左上角的像素
1710     COLORf c1f;
1711     COLOR c1;
1712     COLOR src[2][2];
1713     float jitx,jity,remainx,remainy;
1714     UINT * myDestPixels=mydata->destpixels;
1715     int myno=mydata->ThreadNo;
1716     double time1=GetTickCountmS();
1717     for (i=mydata->starth;i<mydata->endh;i++)
1718     {
1719     
1720         startpt.X=(mydata->srcpt[0].X*(h-i)+mydata->srcpt[3].X*(i))/(float)h;
1721         startpt.Y=(mydata->srcpt[0].Y*(h-i)+mydata->srcpt[3].Y*(i))/(float)h;
1722
1723         endpt.X=(mydata->srcpt[1].X*(h-i)+mydata->srcpt[2].X*(i))/(float)h;
1724         endpt.Y=(mydata->srcpt[1].Y*(h-i)+mydata->srcpt[2].Y*(i))/(float)h;
1725         
1726
1727         l=i*mydata->deststride;
1728         for (j=0;j<w;j++)
1729         {
1730             curpt.X=(startpt.X*(w-j)+endpt.X*(j))/w;
1731             curpt.Y=(startpt.Y*(w-j)+endpt.Y*(j))/w;
1732             curx=int(curpt.X);     cury=int(curpt.Y);
1733             if (curx<0||curx>=mydata->srcw-1) {continue;}
1734             if (cury<0||cury>=mydata->srch-1) {continue;}
1735             jitx=curpt.X-curx;     jity=curpt.Y-cury;        //双线性插值
1736             remainx=1.0f-jitx;    remainy=1.0f-jity;
1737             double remainxremainy=remainx*remainy;
1738             double jitxremainy=jitx*remainy;
1739             double remainxjity=remainx*jity;
1740             double jitxjity=jitx*jity;
1741             k=cury*mydata->srcstride;
1742             src[0][0].argb = mydata->srcpixels[k+curx];
1743             src[0][1].argb = mydata->srcpixels[k+curx+1];
1744             src[1][0].argb = mydata->srcpixels[k+mydata->srcstride+curx];
1745             src[1][1].argb = mydata->srcpixels[k+mydata->srcstride+curx+1];
1746
1747             c1f.R=float( src[0][0].R*remainxremainy+src[0][1].R*jitxremainy+src[1][0].R*remainxjity+src[1][1].R*jitxjity);
1748             c1f.G=float( src[0][0].G*remainxremainy+src[0][1].G*jitxremainy+src[1][0].G*remainxjity+src[1][1].G*jitxjity);
1749             c1f.B=float( src[0][0].B*remainxremainy+src[0][1].B*jitxremainy+src[1][0].B*remainxjity+src[1][1].B*jitxjity);
1750             
1751             c1.R=int(c1f.R); c1.G=int(c1f.G); c1.B=int(c1f.B);c1.A=255;
1752             myDestPixels[l+j]=c1.argb; 
1753
1754             //srcpixels[cury*srcstride+curx]; //最邻近像素取值
1755         }
1756     }
1757     double time2=GetTickCountmS();
1758     double time3=time2-time1;
1759     mydata->Done=1;
1760     return 1000+myno;
1761 };
1762 int QuadRectTransForm(Gdiplus::Bitmap* bitmapsrc,Gdiplus::PointF srcpt[4],Gdiplus::Bitmap * bitmapdest,Gdiplus::Rect destrect)
1763 {
1764     Gdiplus::BitmapData bitmapdatasrc;
1765     Gdiplus::BitmapData bitmapdatadest;
1766     int srcw,srch;
1767     if (bitmapsrc==NULL) {return -1;}
1768     srcw=bitmapsrc->GetWidth();
1769     srch=bitmapsrc->GetHeight();
1770     Gdiplus::Rect rect1(0,0,srcw,srch);
1771     Gdiplus::Status sta1,sta2;
1772     sta1=bitmapsrc->LockBits(&rect1,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB,&bitmapdatasrc);
1773     if (sta1!=Gdiplus::Ok)
1774     {
1775         return -1;
1776     }
1777     sta2=bitmapdest->LockBits(&destrect,Gdiplus::ImageLockModeWrite,PixelFormat32bppARGB,&bitmapdatadest);
1778     if (sta2!=Gdiplus::Ok)
1779     {
1780         return -1;
1781     }
1782     UINT *srcpixels=(UINT *)bitmapdatasrc.Scan0;
1783     int srcstride=bitmapdatasrc.Stride/4;;
1784     UINT *destpixels=(UINT *)bitmapdatadest.Scan0;
1785     int deststride=bitmapdatadest.Stride/4;
1786     int w,h;
1787     w=destrect.Width;
1788     h=destrect.Height;
1789 #define ThreadCount 2
1790     TransFormThreadDataStruct TransFromThreadData[ThreadCount];
1791     for (int i=0;i<ThreadCount;i++)
1792     {
1793         TransFromThreadData[i].ThreadNo=i;
1794         TransFromThreadData[i].Done=0;
1795         TransFromThreadData[i].srcpixels=srcpixels;
1796         TransFromThreadData[i].srcstride=srcstride;
1797         TransFromThreadData[i].destpixels=destpixels;
1798         TransFromThreadData[i].deststride=deststride;
1799         TransFromThreadData[i].srcw=srcw;
1800         TransFromThreadData[i].srch=srch;
1801         TransFromThreadData[i].srcpt[0]=srcpt[0];
1802         TransFromThreadData[i].srcpt[1]=srcpt[1];
1803         TransFromThreadData[i].srcpt[2]=srcpt[2];
1804         TransFromThreadData[i].srcpt[3]=srcpt[3];
1805         TransFromThreadData[i].destrect=destrect;
1806         TransFromThreadData[i].starth=i*h/ThreadCount;
1807         TransFromThreadData[i].endh=(i+1)*h/ThreadCount;
1808     }
1809
1810     CWinThread * threads[ThreadCount];
1811     HANDLE hthreads[ThreadCount];
1812     CString s1;
1813     DWORD dwerr;
1814 //    CWinThread thread1(TransFormThread,(LPVOID)(&TransFromThreadData[0]));
1815 //    CWinThread thread2(TransFormThread,(LPVOID)(&TransFromThreadData[0]));
1816     for (int i=0;i<ThreadCount;i++)
1817     {
1818         threads[i]=AfxBeginThread(TransFormThread,(LPVOID)(&TransFromThreadData[i]),0,8192);
1819         if (threads[i]!=NULL)
1820         {
1821             hthreads[i]=threads[i]->m_hThread;
1822         }
1823         else
1824         {
1825             dwerr=GetLastError();
1826             s1.Format(_T("BeginThread %d fail %d \r\n"),i,dwerr);
1827 //            SysLog(s1);
1828         }
1829     }
1830 //    DWORD iRet;
1831 //        iRet=WaitForMultipleObjects(ThreadCount,hthreads,true,3000);
1832
1833     while(1)
1834     {
1835         int jumpout=1;
1836         for (int i=0;i<ThreadCount;i++)
1837         {
1838             if (TransFromThreadData[i].Done==0) jumpout=0;
1839         }
1840         if (jumpout) break;
1841         Sleep(10);
1842     };
1843
1844 /*
1845     PointF startpt,endpt,curpt;
1846
1847     PointF    leftdelta,rightDelta;
1848     PointF    leftstart,rightstart;
1849     PointF    curstart,curdelta;
1850     int i,j;//,k,l;
1851
1852     int curx,cury;    //最临近的像素? 左上角的像素
1853     COLORf c1f;
1854     COLOR c1;
1855     COLOR src[2][2];
1856     float jitx,jity,remainx,remainy;
1857
1858
1859
1860     for (i=0;i<h;i++)
1861     {
1862     
1863         startpt.X=(srcpt[0].X*(h-i)+srcpt[3].X*(i))/(float)h;
1864         startpt.Y=(srcpt[0].Y*(h-i)+srcpt[3].Y*(i))/(float)h;
1865
1866         endpt.X=(srcpt[1].X*(h-i)+srcpt[2].X*(i))/(float)h;
1867         endpt.Y=(srcpt[1].Y*(h-i)+srcpt[2].Y*(i))/(float)h;
1868         
1869
1870         for (j=0;j<w;j++)
1871         {
1872             curpt.X=(startpt.X*(w-j)+endpt.X*(j))/w;
1873             curpt.Y=(startpt.Y*(w-j)+endpt.Y*(j))/w;
1874             curx=int(curpt.X);     cury=int(curpt.Y);
1875             if (curx<0||curx>=srcw-1) {continue;}
1876             if (cury<0||cury>=srch-1) {continue;}
1877             jitx=curpt.X-curx;     jity=curpt.Y-cury;        //双线性插值
1878             remainx=1.0f-jitx;    remainy=1.0f-jity;
1879             double remainxremainy=remainx*remainy;
1880             double jitxremainy=jitx*remainy;
1881             double remainxjity=remainx*jity;
1882             double jitxjity=jitx*jity;
1883             src[0][0].argb = srcpixels[cury*srcstride+curx];
1884             src[0][1].argb = srcpixels[cury*srcstride+curx+1];
1885             src[1][0].argb = srcpixels[(cury+1)*srcstride+curx];
1886             src[1][1].argb = srcpixels[(cury+1)*srcstride+curx+1];
1887             //c1f.R= src[0][0].R*remainx*remainy+src[0][1].R*jitx*remainy+src[1][0].R*remainx*jity+src[1][1].R*jitx*jity;
1888             //c1f.G= src[0][0].G*remainx*remainy+src[0][1].G*jitx*remainy+src[1][0].G*remainx*jity+src[1][1].G*jitx*jity;
1889             //c1f.B= src[0][0].B*remainx*remainy+src[0][1].B*jitx*remainy+src[1][0].B*remainx*jity+src[1][1].B*jitx*jity;
1890             c1f.R= src[0][0].R*remainxremainy+src[0][1].R*jitxremainy+src[1][0].R*remainxjity+src[1][1].R*jitxjity;
1891             c1f.G= src[0][0].G*remainxremainy+src[0][1].G*jitxremainy+src[1][0].G*remainxjity+src[1][1].G*jitxjity;
1892             c1f.B= src[0][0].B*remainxremainy+src[0][1].B*jitxremainy+src[1][0].B*remainxjity+src[1][1].B*jitxjity;
1893             
1894             c1.R=int(c1f.R); c1.G=int(c1f.G); c1.B=int(c1f.B);c1.A=255;
1895             destpixels[i*deststride+j]=c1.argb; 
1896
1897             //srcpixels[cury*srcstride+curx]; //最邻近像素取值
1898         }
1899     }
1900 */
1901     bitmapdest->UnlockBits(&bitmapdatadest);
1902     bitmapsrc->UnlockBits(&bitmapdatasrc);
1903     return 1;
1904 }
1905
1906
1907 int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
1908 {
1909    UINT  num = 0;          // number of image encoders
1910    UINT  size = 0;         // size of the image encoder array in bytes
1911
1912    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;
1913
1914    Gdiplus::GetImageEncodersSize(&num, &size);
1915    if(size == 0)
1916       return -1;  // Failure
1917
1918    pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
1919    if(pImageCodecInfo == NULL)
1920       return -1;  // Failure
1921
1922    Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);
1923
1924    for(UINT j = 0; j < num; ++j)
1925    {
1926       if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
1927       {
1928          *pClsid = pImageCodecInfo[j].Clsid;
1929          free(pImageCodecInfo);
1930          return j;  // Success
1931       }    
1932    }
1933
1934    free(pImageCodecInfo);
1935    return -1;  // Failure
1936 }
1937 int SaveGdiPImageAsFile(Gdiplus::Bitmap * bitmap1, CString sFileName, double Ratio,int Quality)
1938 {
1939         
1940 //    double tick0=GetTickCountmS();
1941     CString s1;
1942     int w,h;
1943     if (Ratio==0) {Ratio=1;}
1944     if (bitmap1==NULL)
1945     {
1946         s1.Format(_T("源图像为空,不能保存\r\n"));
1947 //        SysLog(s1);
1948         return 0;
1949     }
1950     if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0)
1951     {
1952         s1.Format(_T("源图像为空,不能保存\r\n"));
1953 //        SysLog(s1);
1954         return 0;
1955     }
1956     CString sFilePath;
1957     sFilePath=sFileName.Left(sFileName.ReverseFind(_T('\\')));
1958     //检查是否有可用的磁盘空间
1959     ULARGE_INTEGER luse;
1960     ULARGE_INTEGER ltotal;
1961     ULARGE_INTEGER lfree;
1962
1963     double fuse,ftotal,ffree;
1964     GetDiskFreeSpaceEx(sFilePath,&luse,&ltotal,&lfree);
1965     fuse=luse.QuadPart/1024.0/1024.0/1024.0;
1966     ftotal=ltotal.QuadPart/1048576.0/1024.0;
1967     ffree=lfree.QuadPart/1048576.0/1024.0;
1968     if (fuse<2.0) {return 0;} //如果可用空间小于2G,那么不存储文件。
1969     //创建目录
1970     SHCreateDirectoryEx(NULL,sFilePath,NULL);
1971     //创建BMP文件
1972     w=int(bitmap1->GetWidth()*Ratio+0.5);
1973     h=int(bitmap1->GetHeight()*Ratio+0.5);
1974     Gdiplus::Bitmap bitmapsave(w,h,PixelFormat24bppRGB);
1975     Gdiplus::Graphics graphic3(&bitmapsave);
1976     graphic3.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
1977     graphic3.DrawImage(bitmap1,Gdiplus::Rect(0,0,w,h),0,0,bitmap1->GetWidth(),bitmap1->GetHeight(),Gdiplus::UnitPixel);    //比例缩放
1978     CLSID bmpClsid;
1979     CLSID gifClsid;
1980     CLSID pngClsid;
1981     CLSID jpegClsid;
1982     CLSID tifClsid;
1983     GetEncoderClsid(L"image/bmp", &bmpClsid);
1984     GetEncoderClsid(L"image/jpeg", &jpegClsid);
1985     GetEncoderClsid(L"image/gif", &gifClsid);
1986     GetEncoderClsid(L"image/tiff", &tifClsid);
1987     GetEncoderClsid(L"image/png", &pngClsid);
1988 //        int i,j;
1989 //        CString s1;
1990     CStringW sw1;
1991     CString s2;
1992     //FilePathName=Prsfilepath+_T("\\")+savedfilename;
1993     s1=sFileName;
1994         
1995     //    ::SysLog(s1);
1996     //    wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
1997     ULONG picquality=Quality;
1998     Gdiplus::EncoderParameters * pparas1 = (Gdiplus::EncoderParameters *) new byte[sizeof(EncoderParameters) + sizeof(EncoderParameter)];
1999
2000     pparas1->Count=1;
2001     pparas1->Parameter[0].Guid=Gdiplus::EncoderQuality;
2002     pparas1->Parameter[0].Type=Gdiplus::EncoderParameterValueTypeLong;
2003     pparas1->Parameter[0].NumberOfValues=1;
2004     pparas1->Parameter[0].Value=&picquality;
2005
2006     //pparas1->Count = 2;
2007     //ULONG value2 = EncoderValueCompressionLZW;
2008     //pparas1->Parameter[1].Guid = Gdiplus::EncoderCompression;
2009     //pparas1->Parameter[1].Type = Gdiplus::EncoderParameterValueTypeLong;
2010     //pparas1->Parameter[1].NumberOfValues = 1;
2011     //pparas1->Parameter[1].Value = &value2;
2012
2013     #ifdef UNICODE
2014         sw1.Format(L"%s",s1);
2015     #else
2016         WCHAR    wbuf1[1000];
2017         wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
2018         sw1.Format(L"%s",wbuf1);
2019     #endif
2020         if (sw1.Find(L".BMP") > 0)
2021         {
2022             bitmapsave.Save(sw1, &bmpClsid, pparas1);
2023         }
2024         else if (sw1.Find(L".JPG") > 0)
2025         {
2026             bitmapsave.Save(sw1, &jpegClsid, pparas1);
2027         }
2028         else if (sw1.Find(L".GIF") > 0)
2029         {
2030             bitmapsave.Save(sw1, &gifClsid, pparas1);
2031         }
2032         else if (sw1.Find(L".TIF") > 0)
2033         {
2034             bitmapsave.Save(sw1, &tifClsid, pparas1);
2035         }
2036         else if (sw1.Find(L".PNG") > 0)
2037         {
2038             bitmapsave.Save(sw1, &pngClsid, pparas1);
2039         }
2040         else
2041         {
2042             bitmapsave.Save(sw1, &bmpClsid, pparas1);
2043         }
2044 //        double tick1=GetTickCountmS();
2045         delete[] pparas1;
2046     return 1;
2047     
2048 }
2049 int SaveGdiPImageAsBuffer(Gdiplus::Image * image1, void ** ppBuffer, ULONGLONG *psizeImage, double Ratio, int Quality)
2050 {
2051
2052     //    double tick0=GetTickCountmS();
2053     CString s1;
2054     int w, h;
2055     if (Ratio == 0) { Ratio = 1; }
2056     if (image1 == NULL)
2057     {
2058         s1.Format(_T("源图像为空,不能保存\r\n"));
2059         //        SysLog(s1);
2060         return 0;
2061     }
2062
2063     w = int(image1->GetWidth()*Ratio + 0.5);
2064     h = int(image1->GetHeight()*Ratio + 0.5);
2065     Gdiplus::Bitmap bitmapsave(w, h, PixelFormat24bppRGB);
2066     Gdiplus::Graphics graphic3(&bitmapsave);
2067     graphic3.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
2068     graphic3.DrawImage(image1, Gdiplus::Rect(0, 0, w, h), 0, 0, image1->GetWidth(), image1->GetHeight(), Gdiplus::UnitPixel);    //比例缩放
2069     CLSID bmpClsid;
2070     CLSID gifClsid;
2071     CLSID pngClsid;
2072     CLSID jpegClsid;
2073     CLSID tifClsid;
2074     GetEncoderClsid(L"image/bmp", &bmpClsid);
2075     GetEncoderClsid(L"image/jpeg", &jpegClsid);
2076     GetEncoderClsid(L"image/gif", &gifClsid);
2077     GetEncoderClsid(L"image/tiff", &tifClsid);
2078     GetEncoderClsid(L"image/png", &pngClsid);
2079     //        int i,j;
2080     //        CString s1;
2081     CStringW sw1;
2082     CString s2;
2083     //FilePathName=Prsfilepath+_T("\\")+savedfilename;
2084
2085     //    ::SysLog(s1);
2086     //    wcscpy_s(wbuf1,1000,ToWChar(s1.GetBuffer(100)));
2087     ULONG picquality = Quality;
2088     Gdiplus::EncoderParameters paras1;
2089
2090     paras1.Count = 1;
2091     paras1.Parameter[0].Guid = Gdiplus::EncoderQuality;
2092     paras1.Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;
2093     paras1.Parameter[0].NumberOfValues = 1;
2094     paras1.Parameter[0].Value = &picquality;
2095
2096     IStream *ps2;
2097     CreateStreamOnHGlobal(NULL, TRUE, &ps2);
2098     bitmapsave.Save(ps2, &jpegClsid, &paras1);
2099     LARGE_INTEGER dlibMove;
2100     dlibMove.QuadPart = 0;
2101     ULARGE_INTEGER libNewPosition;
2102     ps2->Seek(dlibMove, STREAM_SEEK_END, &libNewPosition);
2103     int sizeImage;
2104     sizeImage = libNewPosition.QuadPart;
2105     ps2->Seek(dlibMove, STREAM_SEEK_SET, &libNewPosition);
2106     void * pBuffer = new char[sizeImage];
2107     DWORD dwRead;
2108     ps2->Read(pBuffer, sizeImage, &dwRead);
2109     *psizeImage = sizeImage;
2110     *ppBuffer = pBuffer;
2111
2112     return 1;
2113
2114 }
2115
2116 HSI RGBToHSI(COLOR c1)
2117 {
2118     float nMax,nMin,ndelMax;
2119     float ndelR,ndelG,ndelB;
2120     float nH,nS,nV;
2121     float nR,nB,nG;
2122     HSI hsb2;
2123     nR=c1.R/255.0f;
2124     nG=c1.G/255.0f;
2125     nB=c1.B/255.0f;
2126     nMax=max(nR,max(nG,nB));
2127     nMin=min(nR,min(nG,nB));
2128     ndelMax=nMax-nMin;
2129     nV=nMax;
2130     if (ndelMax==0) {nS=0;nH=0;} //最大值与最小值相等,纯色。
2131     else
2132     {
2133         nS=ndelMax/nMax;
2134         ndelR = (((nMax - nR) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
2135         ndelG = (((nMax - nG) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
2136         ndelB = (((nMax - nB) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
2137         if (nR==nMax)
2138         {
2139             nH = ndelB - ndelG;
2140         }
2141         else if (nG==nMax)
2142         {
2143             nH = (1.0f / 3) + ndelR - ndelB;
2144
2145         }
2146         else if (nB==nMax)
2147         {
2148              nH = (2.0f / 3) + ndelG - ndelR;
2149         }
2150         if (nH<0) {nH+=1;}
2151         if (nH>1) {nH-=1;}
2152
2153     }
2154     hsb2.H =(nH*240);
2155     hsb2.S =(nS*240);
2156     hsb2.I =(nV*240);
2157
2158     return hsb2 ;
2159 }
2160 /*  RGB?-----------?Lab
2161     (各分量数值范围:R/G/B: 0~255;   L: 0~100,  a/b:0~255)
2162
2163     RGB---?Lab:
2164     X = 0.412453*R + 0.357580*G + 0.180423*B;
2165     Y = 0.212671*R + 0.715160*G + 0.072169*B;
2166     Z = 0.019334*R + 0.119193*G + 0.950227*B;
2167
2168     X = X/(255*0.950456);
2169     Y = Y/255;   
2170     Z = Z/(255*1.088754);
2171     如果Y > 0.008856,则 :  
2172         fY = Y^(1/3);   
2173         fX = X^(1/3); 
2174         fZ = Z^(1/3); 
2175         L= 116*fY - 16;
2176     如果Y < 0.008856,则
2177         fY = 7.787*Y + 16/116;
2178         fX = 7.787*X + 16/116;
2179         fZ = 7.787*Z + 16/116;
2180         L= 903.3*Y;
2181     a = 500.0*(fX - fY) +128;
2182     b = 200.0*(fY - fZ) +128;
2183
2184 Lab---?RGB:
2185     a = a-128;
2186     b = b-128;
2187     fY = ((L + 16) / 116))^3;
2188     如果fY < 0.008856,则fY = L / 903.3; 
2189     Y = fY;
2190     如果fY > 0.008856,则fY = fY^(1/3);
2191     如果fY < 0.008856,则fY = 7.787 * fY + 16/116;     
2192     
2193     fX = a / 500 + fY;
2194     如果fX > 0.206893,则X = fX^(1/3);
2195     如果fX < 0.206893,则X = (fX - 16/116) / 7.787;   
2196     
2197     fZ = fY - b /200;
2198     如果fZ > 0.206893,则Z = fZ^(1/3);
2199     如果fX < 0.206893,则Z = (fZ - 16/116) / 7.787;
2200
2201     X = X * 0.950456 * 255; 
2202     Y = Y *255;
2203     Z = Z * 1.088754 * 255;
2204     R = 3.240479*X - 1.537150*Y - 0.498535*Z
2205     G =-0.969256*X + 1.875992*Y + 0.041556*Z;
2206     B = 0.055648*X - 0.204043*Y + 1.057311*Z;
2207
2208 */
2209
2210 /*
2211 从RGB到Lab色彩空间的转换 
2212 2008年七月27日 星期日, 03:35 - 键盘生涯 / Programming
2213 虽然若干年前就看过了关于色彩空间的介绍,但是直到今天才自己动手写代码做这件事情。虽然网络上已经有很多现成的例子,但是一则仅仅适用于浮点型的数据,另一方面,在实现上也有一些尚可优化之处。
2214
2215 色彩模型除了最常见的RGB以外,还有HSB、YCbCr、XYZ、Lab等。HSB一般仅仅作为图像处理过程中的临时模式,YCbCr常常用于图像的压缩处理,而XYZ则严格按照人眼对光信号的敏感度进行分布。
2216
2217 这里将要稍作讨论的便是Lab模型。网络上诸多的介绍都说Lab是基于XYZ的,故人们一般也只能找到XYZ和Lab之间的转换,而RGB到Lab的转换只能使用XYZ作为中间模式间接进行。可惜的是,这种现状源于误解。而在图像处理软件中(比如Photoshop),往往采用一个更为简单的算法。
2218
2219 我们可以先观察RGB到XYZ的转换:
2220 [X,Y,Z] = [M] * [R,G,B]
2221
2222 其中M为一3x3矩阵:
2223 [M] = [0.4125, 0.3576, 0.1805;
2224 0.2126, 0.7152, 0.0722;
2225 0.0193, 0.1192, 0.9505],
2226
2227 RGB是经过Gamma校正的色彩分量:R=g(r),G=g(g),B=g(b)。
2228 其中rgb为原始的色彩分量。
2229
2230 g是Gamma校正函数:
2231 当 x < 0.018 时,g(x) = 4.5318 * x
2232 当 x >= 0.018 时,g(x) = 1.099 * d^0.45 - 0.099
2233
2234 rgb以及RGB的取值范围则均为[0,1)。计算完成后,XYZ的取值范围则有所变化,分别是:[0, 0.9506),[0, 1),[0, 1.0890)。
2235
2236
2237 以及XYZ到Lab的转换:
2238 L = 116 * f(Y1) - 16
2239 a = 500 * (f(X1) - f(Y1))
2240 b = 200 * (f(Y1) - f(Z1))
2241
2242 其中f是一个类似Gamma函数的校正函数:
2243 当 x > 0.008856 时,f(x) = x^(1/3)
2244 当 x <= 0.008856 时,f(x) = ( 7.787 * x ) + ( 16 / 116 )
2245 X1、Y1、Z1分别是线性归一化之后的XYZ值,也就是说,它们的取值范围都是[0, 1)。此外,函数f的值域也和自变量一样都是[0, 1)。
2246
2247 计算完成后,L的取值范围[0, 100),而a和b则约为[-169, +169)和[-160, +160)。
2248
2249
2250 在观察这些貌似复杂的变换之前,我们必须确定的一个假设是:在图像处理软件中,非RGB色彩数据的绝对值并不重要,重要的是他们能够尽可能准确的还原成RGB图像以显示在屏幕等相关设备上。这个假设是我们的简化得以成立的理由。
2251
2252 上面的从XYZ到Lab的转换乍一看起来很奇怪,但若是仔细观察,不难发现L与Y1只是一个简单的同区间映射关系,这个映射其实可有可无(如果进行了映射反而必定导致色阶丢失)。
2253
2254 这样,我们取得的第一个简化是:L = Y1。
2255
2256 接下来接着看a和b的映射过程。大家不难发现,a和b其实是一个色差信号(跟Cb和Cr的性质差不多)。至于它们的转换系数500和200,大家可以完全忘记,因为他们的值域并不符合8位整数值的表达需要。我们将会稍后计算出合适的因数,使得a和b都处在[0, 255]的范围内。
2257
2258 因为XYZ必须归一化转为X1Y1Z1,那么我们其实可以在转换矩阵M中作出这个修改,令每行乘以一个系数以使得每行各数之和为1:
2259 [M1] = [0.4339, 0.3762 0.1899;
2260 0.2126, 0.7152, 0.0722;
2261 0.0177, 0.1095, 0.8728]
2262
2263 于是乎,我们得出一个半成品:
2264 L = Y1 = 0.2126 * R + 0.7152 * G + 0.0722 * B
2265 a = Fa * (X1 - Y1) + Da
2266 b = Fb * (Y1 - Z1) + Db
2267 其中的Fx是调整值域用的系数,Dx是一个正数,用来消除a和b的负值。Fx和Dx的选取必须令a和b满足值域在[0, 255]上的分布。
2268
2269 接下来我们来确定Fx和Dx的值。通过M1我们很容易计算出X1-Y1的值域(极端情况)为[-86.784, +86.784),而Y1-Z1的值域则为[-204.9536, +204.9536)。于是乎,Fa的值为1.4749,Fb的值为0.6245;Da和Db则都是128。
2270
2271 这时,代入M1有:
2272 L = Y1 = 0.2126 * R + 0.7152 * G + 0.0722 * B
2273 a = 1.4749 * (0.2213 * R - 0.3390 * G + 0.1177 * B) + 128
2274 b = 0.6245 * (0.1949 * R + 0.6057 * G - 0.8006 * B) + 128
2275 其中RGB和Lab的取值范围都是[0,255]。
2276
2277 最后的一点工作是算法的优化。我们可以将这个方程组转换成常整数乘法与移位的方式(相当于使用定点数)。为了方便阅读,我仍然将移位写为除法。
2278
2279 所以我们的最终结果为:
2280 L = Y1 = (13933 * R + 46871 * G + 4732 * B) div 2^16
2281 a = 377 * (14503 * R - 22218 * G + 7714 * B) div 2^24 + 128
2282 b = 160 * (12773 * R + 39695 * G - 52468 * B) div 2^24 + 128
2283
2284
2285 至于逆变换则可以用类似的方法推导出来:
2286 设L1=L,a1=(a-128)*174,b1=(b-128)*410,有:
2287 R = L1 + (a1 * 100922 + b1 * 17790) div 2^23
2288 G = L1 - (a1 * 30176 + b1 * 1481) div 2^23
2289 B = L1 + (a1 * 1740 - b1 * 37719) div 2^23
2290 其中RGB和Lab的取值范围都是[0,255],再经过逆Gamma函数取得原始的rgb
2291
2292
2293 以上的算法在Delphi中编译通过。经测试,运算得出的直方图与图片观感和我手头的Photoshop CS的结果非常相似,但也有一些幅度上的差别,且容以后慢慢细察。
2294
2295 当初为了寻觅一个简单的RGB直接转Lab算法而找遍网络皆不得,万不得已只好自力更生。其间虽费时一日,幸好也算略有所得。暂记于此,以利后人。其间或许难免错漏之处,还望达人不吝指点。
2296
2297
2298
2299 */
2300 Lab RGBfToLab(COLORf &c1f)
2301 {
2302     float X,Y,Z,fX,fY,fZ;
2303     Lab lab1;
2304     float R,G,B;
2305     R=c1f.R;
2306     G=c1f.G;
2307     B=c1f.B;
2308 //     if (!(R>=0)||!(R<=256))
2309 //     {
2310 //         lab1.L=0;lab1.a=0;lab1.b=0;
2311 //         return lab1;
2312 //     }
2313
2314     X = (0.0017017755110158063242130877282104f*R + 0.0014753702536507966372219765884924f*G + 0.00074442286278437743072179842839524f*B);
2315     Y = (0.00083400392156862745098039215686275f*R + 0.0028045490196078431372549019607843f*G + 0.00028301568627450980392156862745098f*B);
2316     Z = (0.000069638878794601218367014756605923f*R + 0.00042931968967440276305056325044635f*G + 0.0034226100589819764107392847380458f*B);
2317
2318     if (Y > 0.008856451679f)            // 进行修正, (6/29)^3 ,约 1/113;
2319     {  
2320         fY = pow(Y,(1.0f/3)); 
2321         lab1.L= 116*fY - 16;
2322     }
2323     else
2324     {
2325         fY = 7.787f*Y + 16.0f/116;
2326         lab1.L= 903.3f*Y;
2327     }
2328     if (X > 0.008856451679f)            // 进行修正, (6/29)^3 ,约 1/113;
2329         fX = pow(X,(1.0f/3));
2330     else    fX = 7.787f*X + 16.0f/116;
2331     
2332     if (Z > 0.008856451679f)            // 进行修正, (6/29)^3 ,约 1/113;
2333         fZ = pow(Z,(1.0f/3));
2334     else    fZ = 7.787f*Z + 16.0f/116;  
2335
2336     lab1.a = 500.0f*(fX - fY) +128;
2337     lab1.b = 200.0f*(fY - fZ) +128;
2338     return lab1;
2339
2340 }
2341 COLORf LabToRGBf(Lab lab1)
2342 {
2343     float X,Y,Z,fX,fY,fZ;
2344     COLORf c1f;
2345     float L,a,b;
2346     a = lab1.a-128;
2347     b = lab1.b-128;
2348     L=lab1.L;
2349     fY = pow(((L + 16) / 116.0f),3.0f);
2350     if (fY <= 0.008856f) {fY = L / 903.3f;} 
2351     Y = fY;
2352     if (Y > 0.008856f) {fY = pow(Y,(1.0f/3));}
2353     if (Y <= 0.008856f) {fY = 7.787f * Y + 16.0f/116;}     
2354     
2355     fX = a / 500 + fY;
2356     if (fX > 0.206893f) {X = pow(fX,(3.0f));}
2357     if (fX <= 0.206893f) {X = (fX - 16.0f/116) / 7.787f;}   
2358     
2359     fZ = fY - b /200;
2360     if (fZ > 0.206893f) {Z = pow(fZ,(3.0f));}
2361     if (fZ <= 0.206893f) {Z = (fZ - 16.0f/116) / 7.787f;}
2362
2363     X = X * 0.950456f * 255; 
2364     Y = Y *255;
2365     Z = Z * 1.088754f * 255;
2366
2367     c1f.R = 3.240479f*X - 1.537150f*Y - 0.498535f*Z;
2368     c1f.G =-0.969256f*X + 1.875992f*Y + 0.041556f*Z;
2369     c1f.B = 0.055648f*X - 0.204043f*Y + 1.057311f*Z;
2370     return c1f;
2371 }
2372 HSI RGBfToHSI(COLORf &c1)
2373 {
2374     float nMax,nMin,ndelMax;
2375     float ndelR,ndelG,ndelB;
2376     float nH,nS,nV;
2377     float nR,nB,nG;
2378     HSI hsb2;
2379     nR=c1.R/255.0f;
2380     nG=c1.G/255.0f;
2381     nB=c1.B/255.0f;
2382     if (!(nR>=0)||!(nR<=256))
2383     {
2384         hsb2.H=0;hsb2.S=0;hsb2.I=0;
2385         return hsb2;
2386     }
2387     nMax=max(nR,max(nG,nB));
2388     nMin=min(nR,min(nG,nB));
2389     ndelMax=nMax-nMin;
2390     nV=nMax;
2391
2392     if (ndelMax==0) {nS=0;nH=0;} //最大值与最小值相等,纯色。
2393     else
2394     {
2395         nS=ndelMax/nMax;
2396         ndelR = (((nMax - nR) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
2397         ndelG = (((nMax - nG) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
2398         ndelB = (((nMax - nB) / 6.0f) + (ndelMax / 2.0f)) / ndelMax;
2399         if (nR==nMax)
2400         {
2401             nH = ndelB - ndelG;
2402         }
2403         else if (nG==nMax)
2404         {
2405             nH = (1.0f / 3) + ndelR - ndelB;
2406
2407         }
2408         else if (nB==nMax)
2409         {
2410              nH = (2.0f / 3) + ndelG - ndelR;
2411         }
2412         if (nH<0) {nH+=1;}
2413         if (nH>1) {nH-=1;}
2414
2415     }
2416     hsb2.H =(nH*240);
2417     hsb2.S =(nS*240);
2418     hsb2.I =(nV*240);
2419
2420     return hsb2 ;
2421 }
2422
2423 DWORD HSIToRGB(HSI hsb1)
2424 {
2425     COLOR color2;
2426     float nH,nS,nV;
2427     float nR,nG,nB;
2428     float f,p,q,t;
2429     int k;
2430     nH=hsb1.H/240.0f;
2431     nS=hsb1.S/240.0f;
2432     nV=hsb1.I/240.0f;
2433     k = (int)( (int(hsb1.H) / 40) % 6);
2434     f = (hsb1.H / 40.0f) - k;
2435     p=nV*(1-nS);
2436     q=nV*(1-f*nS);
2437     t=nV*(1-(1-f)*nS);
2438     if (k==0)
2439     {
2440         nR=nV;nG=t;nB=p;
2441     } else if (k==1)
2442     {    nR=q;nG=nV;nB=p;
2443     } else if (k==2)
2444     {    nR=p;nG=nV;nB=t;
2445     } else if (k==3)
2446     {    nR=p;nG=q;nB=nV;
2447     } else if (k==4)
2448     {    nR=t;nG=p;nB=nV;}
2449     else if (k==5)
2450     {    nR=nV;nG=p;nB=q;}
2451     color2.R=int(nR*255);color2.G=int(nG*255);color2.B=int(nB*255);
2452     //R=nV*100;G=nV*100;B=nV*100;
2453
2454     return color2.argb ;
2455 }
2456
2457 COLORf HSIToRGBf(HSI hsb1)
2458 {
2459     COLORf color2;
2460     float nH,nS,nV;
2461     float nR,nG,nB;
2462     float f,p,q,t;
2463     int k;
2464     nH=hsb1.H/240.0f;
2465     nS=hsb1.S/240.0f;
2466     nV=hsb1.I/240.0f;
2467     k = (int)( (int(hsb1.H) / 40) % 6);
2468     f = (hsb1.H / 40.0f) - k;
2469     p=nV*(1-nS);
2470     q=nV*(1-f*nS);
2471     t=nV*(1-(1-f)*nS);
2472     if (k==0)
2473     {
2474         nR=nV;nG=t;nB=p;
2475     } else if (k==1)
2476     {    nR=q;nG=nV;nB=p;
2477     } else if (k==2)
2478     {    nR=p;nG=nV;nB=t;
2479     } else if (k==3)
2480     {    nR=p;nG=q;nB=nV;
2481     } else if (k==4)
2482     {    nR=t;nG=p;nB=nV;}
2483     else if (k==5)
2484     {    nR=nV;nG=p;nB=q;}
2485     color2.R=nR*255;color2.G=nG*255;color2.B=nB*255;
2486     //R=nV*100;G=nV*100;B=nV*100;
2487
2488     return color2 ;
2489 }
2490
2491 #define EVEN(x) ((srcbuf[(x)*3/2]<<4)+(srcbuf[(x)*3/2+1]&0xf))
2492 #define ODD(x)  (((*(unsigned short *)(&srcbuf[(x)*3/2+1]))>>4)&0x0fff)
2493 int Raw12toRaw16(void * dest,void * src,int width,int height)
2494 {
2495     int i,l;//,k,l;
2496     unsigned short int a,b;
2497     unsigned short int * destbuf=(unsigned short *)dest;
2498     unsigned char * srcbuf=(unsigned char *)src;
2499     l=width*height;
2500 //    memcpy(destbuf,srcbuf,l);
2501 //    memcpy(destbuf+width*height/2,srcbuf,l);
2502 //    return 0;
2503     for (i=0;i<l;i+=2)
2504     {
2505 //        a=(srcbuf[i*3/2]<<8)+((srcbuf[i*3/2+1]&0x0f)<<4);
2506 //        b=(srcbuf[i*3/2+2]<<8)+(srcbuf[i*3/2+1]&0xf0);
2507         a=EVEN(i)*16;
2508         b=ODD(i)*16;
2509         destbuf[i]=a;
2510         destbuf[i+1]=b;
2511     }
2512     return 0;
2513 }
2514
2515 int Raw12ToRaw8(void * dest, void * src, int width, int height)
2516 {
2517     int i,l;    //j,k,
2518     //    unsigned short int a,b;
2519     unsigned char * destbuf=(unsigned char *)dest;
2520     unsigned char * srcbuf=(unsigned char *)src;
2521     l=width*height;
2522     //    memcpy(destbuf,srcbuf,l);
2523     //    memcpy(destbuf+width*height/2,srcbuf,l);
2524     //    return 0;
2525     for (i=0;i<l;i+=2)
2526     {
2527         //        a=(srcbuf[i*3/2]<<8)+((srcbuf[i*3/2+1]&0x0f)<<4);
2528         //        b=(srcbuf[i*3/2+2]<<8)+(srcbuf[i*3/2+1]&0xf0);
2529         //a=EVEN(i)*16;
2530         //b=ODD(i)*16;
2531         destbuf[i]=srcbuf[i*3/2];
2532         destbuf[i+1]=srcbuf[i*3/2+2];
2533     }
2534     return 0;
2535 }
2536
2537 int BayerGB12PackedToRGB32(void * dest,void * src,int width,int height,float gamma)
2538 {
2539     int i,j,k,l,m,n,p;
2540 //    unsigned short int a,b;
2541     COLOR * destbuf=(COLOR *)dest;
2542     unsigned char * srcbuf=(unsigned char *)src;
2543 //    return 0;
2544     unsigned char LUTgamma[4096];
2545 for (i=0;i<4096;i++)
2546 {
2547     j=int(pow(i/4096.0f,gamma)*256+0.5);
2548     if (j>255) {j=255;}
2549     LUTgamma[i]=j;
2550
2551 }
2552     unsigned short int buf1[4][3200];
2553     unsigned short int G00,B01,G02,B03;
2554     unsigned short int R10,G11,R12,G13;
2555     unsigned short int G20,B21,G22,B23;
2556     unsigned short int R30,G31,R32,G33;
2557     
2558     for (i=0;i<3;i++)
2559     {
2560         l=i*width;
2561         for (j=0;j<width;j+=2)
2562         {
2563             buf1[i][j]=EVEN(l+j);buf1[i][j+1]=ODD(l+j);
2564         }
2565     }
2566
2567     for (i=0;i<height-2;i+=2)
2568     {
2569         l=i*width;
2570         m=l+width;
2571         n=m+width;
2572         p=n+width;
2573         for (j=0;j<width;j+=4)
2574         {
2575             k=*(unsigned *)(srcbuf+(n+j)*3/2);
2576             *((unsigned *)&buf1[(i+2)&0x3][j])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
2577             k=*(unsigned *)(srcbuf+(n+j+2)*3/2);
2578             *((unsigned *)&buf1[(i+2)&0x3][j+2])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
2579 //            buf1[(i+2)&0x3][j]=EVEN(n+j);buf1[(i+2)&0x3][j+1]=ODD(n+j);
2580 //            buf1[(i+2)&0x3][j+2]=EVEN(n+j+2);buf1[(i+2)&0x3][j+3]=ODD(n+j+2);
2581
2582         }
2583         for (j=0;j<width;j+=4)
2584         {
2585             k=*(unsigned *)(srcbuf+(p+j)*3/2);
2586             *((unsigned *)&buf1[(i+3)&0x3][j])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
2587             k=*(unsigned *)(srcbuf+(p+j+2)*3/2);
2588             *((unsigned *)&buf1[(i+3)&0x3][j+2])=(k<<4)&0x0fff0ff0|(k>>8)&0xf;
2589 //            buf1[(i+3)&0x3][j]=EVEN(p+j);buf1[(i+3)&0x3][j+1]=ODD(p+j);
2590 //            buf1[(i+3)&0x3][j+2]=EVEN(p+j+2);buf1[(i+3)&0x3][j+3]=ODD(p+j+2);
2591
2592         }
2593
2594         for (j=0;j<width-2;j+=2)
2595         {
2596         //    G00=EVEN(l+j);B01=ODD(l+j);G02=EVEN(l+j+2);B03=ODD(l+j+2);
2597         //    R10=EVEN(m+j);G11=ODD(m+j);R12=EVEN(m+j+2);G13=ODD(m+j+2);
2598         //    G20=EVEN(n+j);B21=ODD(n+j);G22=EVEN(n+j+2);B23=ODD(n+j+2);
2599         //    R30=EVEN(p+j);G31=ODD(p+j);R32=EVEN(p+j+2);G33=ODD(p+j+2);
2600             G00=buf1[(i+0)&3][j];B01=buf1[(i+0)&3][j+1];G02=buf1[(i+0)&3][j+2];B03=buf1[(i+0)&3][j+3];
2601             R10=buf1[(i+1)&3][j];G11=buf1[(i+1)&3][j+1];R12=buf1[(i+1)&3][j+2];G13=buf1[(i+1)&3][j+3];
2602             G20=buf1[(i+2)&3][j];B21=buf1[(i+2)&3][j+1];G22=buf1[(i+2)&3][j+2];B23=buf1[(i+2)&3][j+3];
2603             R30=buf1[(i+3)&3][j];G31=buf1[(i+3)&3][j+1];R32=buf1[(i+3)&3][j+2];G33=buf1[(i+3)&3][j+3];
2604 /*
2605             destbuf[l+j].B=LUTgamma[B01];destbuf[l+j].G=LUTgamma[(G00+G11)/2];destbuf[l+j].R=LUTgamma[R10];
2606             destbuf[l+j+1].B=LUTgamma[B01];destbuf[l+j+1].G=LUTgamma[(G11+G02)/2];destbuf[l+j+1].R=LUTgamma[R12];
2607
2608             destbuf[m+j].B=LUTgamma[B21];destbuf[m+j].G=LUTgamma[(G20+G11)/2];destbuf[m+j].R=LUTgamma[R10];
2609             destbuf[m+j+1].B=LUTgamma[B21];destbuf[m+j+1].G=LUTgamma[(G11+G22)/2];destbuf[m+j+1].R=LUTgamma[R12];
2610 */
2611
2612             destbuf[m+j+1].B=LUTgamma[(B01+B21)/2];
2613             destbuf[m+j+1].G=LUTgamma[G11];
2614             destbuf[m+j+1].R=LUTgamma[(R10+R12)/2];
2615
2616             destbuf[m+j+2].B=LUTgamma[(B01+B21+B03+B23)/4];
2617             if (abs(G02-G22)<abs(G11-G13)) {destbuf[m+j+2].G=LUTgamma[(G02+G22)/2];}
2618             else if (abs(G02-G22)>abs(G11-G13)) {destbuf[m+j+2].G=LUTgamma[(G11+G13)/2];}
2619             else {destbuf[m+j+2].G=LUTgamma[(G02+G22+G11+G13)/4];}
2620             destbuf[m+j+2].R=LUTgamma[R12];
2621
2622             destbuf[n+j+1].B=LUTgamma[B21];
2623             if (abs(G11-G31)<abs(G20-G22)) {destbuf[n+j+1].G=LUTgamma[(G11+G31)/2];}
2624             else if (abs(G11-G31)>abs(G20-G22)) {destbuf[n+j+1].G=LUTgamma[(G20+G22)/2];}
2625             else {destbuf[n+j+1].G=LUTgamma[(G11+G31+G20+G22)/4];}
2626             destbuf[n+j+1].R=LUTgamma[(R10+R30+R12+R32)/4];
2627
2628             destbuf[n+j+2].B=LUTgamma[(B21+B23)/2];
2629             destbuf[n+j+2].G=LUTgamma[G22];
2630             destbuf[n+j+2].R=LUTgamma[(R12+R32)/2];
2631
2632
2633         }
2634     }
2635     return 0;
2636 }
2637
2638 /*
2639
2640
2641                         R03=srcbuf[k+2]; 
2642         B12=srcbuf[l+1];G13=srcbuf[l+2];
2643         G22=srcbuf[m+1];R23=srcbuf[m+2];
2644         B32=srcbuf[n+1];
2645         
2646
2647         for (j=2;j<width-6;j+=2)
2648         {
2649             // 奇数行 
2650                         R01=R03;            G02=srcbuf[k+j+1];    R03=srcbuf[k+j+2];
2651             B10=B12;    G11=G13;            B12=srcbuf[l+j+1];    G13=srcbuf[l+j+2];
2652             G20=G22;    R21=R23;            G22=srcbuf[m+j+1];    R23=srcbuf[m+j+2];
2653             B30=B32;    G31=srcbuf[n+j];    B32=srcbuf[n+j+1];    
2654
2655 */
2656
2657 int BayerGB16toRGB64(void * dest,void * src,int width,int height)
2658 {
2659     int i,j,k,l,m,n,p,q,s;
2660     //unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
2661     unsigned short G00, B01, G02, B03, G04, B05;
2662     unsigned short R10, G11, R12, G13, R14, G15;
2663     unsigned short G20, B21, G22, B23, G24, B25;
2664     unsigned short R30, G31, R32, G33, R34, G35;
2665     unsigned short G40, B41, G42, B43, G44, B45;
2666     unsigned short R50, G51, R52, G53, R54, G55;
2667
2668     unsigned long long  * destbuf=(unsigned long long *) dest;
2669     unsigned short * srcbuf=(unsigned short *)src;
2670     s=width;
2671     G00=0;
2672 RGB16 pixel;
2673
2674     for (i=2;i<height-4;i+=2)
2675     {
2676         k=i*width-width-width;        //上一行
2677         l=i*width-width;                //当前行
2678         m=i*width;                //下一行
2679         n=m+width;                //下两行
2680         p=m+width+width;
2681         q=m+width+width+width;
2682                         B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
2683         R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
2684         G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
2685         R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
2686         G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
2687         R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
2688
2689         for (j=2;j<width-6;j+=2)
2690         {
2691             // 奇数行 
2692
2693                           B01=srcbuf[k+j+1];G02=srcbuf[k+j+2];B03=srcbuf[k+j+3];G04=srcbuf[k+j+4];B05=srcbuf[k+j+5];
2694         R10=srcbuf[l+j+0];G11=srcbuf[l+j+1];R12=srcbuf[l+j+2];G13=srcbuf[l+j+3];R14=srcbuf[l+j+4];G15=srcbuf[l+j+5];
2695         G20=srcbuf[m+j+0];B21=srcbuf[m+j+1];G22=srcbuf[m+j+2];B23=srcbuf[m+j+3];G24=srcbuf[m+j+4];B25=srcbuf[m+j+5];
2696         R30=srcbuf[n+j+0];G31=srcbuf[n+j+1];R32=srcbuf[n+j+2];G33=srcbuf[n+j+3];R34=srcbuf[n+j+4];G35=srcbuf[n+j+5];
2697         G40=srcbuf[p+j+0];B41=srcbuf[p+j+1];G42=srcbuf[p+j+2];B43=srcbuf[p+j+3];G44=srcbuf[p+j+4];B45=srcbuf[p+j+5];
2698         R50=srcbuf[q+j+0];G51=srcbuf[q+j+1];R52=srcbuf[q+j+2];G53=srcbuf[q+j+3];R54=srcbuf[q+j+4];G35=srcbuf[q+j+5];
2699
2700             pixel.B=(B21+B23)/2;
2701             pixel.G=G22;
2702             pixel.R=(R12+R32)/2;
2703             ((RGB16 *)(&destbuf[m+j]))->ARGB=pixel.ARGB ;
2704
2705             pixel.B=B23;
2706             //if (abs(signed(B03-B43))<abs(signed(B21-B25)))    {pixel.G=(G13+G33)/2;}
2707             //else{pixel.G=(G22+G24)/2;}
2708             if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) {pixel.G=(G13+G33)/2;}
2709             else {pixel.G=(G22+G24)/2;}
2710
2711             pixel.R=((unsigned int )R12+R32+R14+R34)/4;
2712             destbuf[m+j+1]=pixel.ARGB ;
2713             
2714             //偶数行
2715             pixel.B=((unsigned int )B21+B41+B23+B43)/4;
2716             if (abs(signed(R12-R52))<abs(signed(R30-R34)))    {    pixel.G=(G22+G42)/2;}
2717             else{pixel.G=(G31+G33)/2;}
2718             
2719             pixel.R=R32;
2720             destbuf[n+j]=pixel.ARGB ;
2721
2722             pixel.B=(B23+B43)/2;
2723             pixel.G=G33;
2724             pixel.R=(R32+R34)/2;
2725             destbuf[n+j+1]=pixel.ARGB ;
2726         }
2727     }
2728     return 0;
2729 }
2730 int RGB64toRGB32(void * destbuf,void * srcbuf,int width,int height)
2731 {
2732     int i,j,l,s;
2733     s=width;
2734     l=width*height;
2735     RGB16 * pixel=(RGB16 *)srcbuf;
2736     COLOR * c1=(COLOR *) destbuf;
2737     for (i=0;i<height;i++)
2738     {
2739         l=s*i;
2740         for (j=0;j<width;j++)
2741         {
2742             c1[l+j].R=pixel[l+j].R>>8;
2743             c1[l+j].G=pixel[l+j].G>>8;
2744             c1[l+j].B=pixel[l+j].B>>8;
2745             c1[l+j].A=pixel[l+j].A>>8;
2746         }
2747     }
2748     return 0;
2749 }
2750
2751 int RGB32toRGB64(void * destbuf,void * srcbuf,int width,int height)
2752 {
2753     int i,l;
2754     l=width*height;
2755     RGB16 * pixel=(RGB16 *)destbuf;
2756     COLOR * c1=(COLOR *)srcbuf;
2757     for (i=0;i<l;i++)
2758     {
2759         pixel[i].R=c1[i].R<<8;
2760         pixel[i].G=c1[i].G<<8;
2761         pixel[i].B=c1[i].B<<8;
2762         pixel[i].A=c1[i].A<<8;
2763     }
2764     return 0;
2765 }
2766 /*
2767 float CalHSIDistance(HSI hsb1, HSI hsb2)
2768 {
2769     float nH1,nH2,nS1,nS2,nV1,nV2;
2770     float delH,delS,delV;
2771     float kH,kS,kV;
2772     CString s1;
2773     float PercentH,PercentS,PercentV;
2774     PercentH=1.0f;PercentS=0.10f;PercentV=0.05f;
2775     kH=PercentH;//1.0f
2776     kS=PercentS;//0.4f;
2777     kV=PercentV;//0.1f;
2778     nH1=hsb1.H/240.0f;nH2=hsb2.H/240.0f;
2779     nS1=hsb1.S/240.0f;nS2=hsb2.S/240.0f;
2780     nV1=hsb1.I/240.0f;nV2=hsb2.I/240.0f;
2781     delH=nH1-nH2;
2782     delS=nS1-nS2;
2783     delV=nV1-nV2;
2784     float distance;
2785     if (delH<0) {delH+=1;}
2786     if (delH>0.5) {delH=1-delH;}
2787
2788     distance=sqrtf(kH*kH*delH*delH+kS*kS*delS*delS+kV*kV*delV*delV)*240.0f;
2789 //    s1.Format(_T("%d %d %d  %d %d %d %.3f %.3f %.3f %.3f\r\n"),hsb1.H,hsb1.S,hsb1.I,hsb2.H,hsb2.S,hsb2.I,delH,delS,delV,distance);
2790 //    SysLog(s1);
2791     return distance;
2792     return 0;
2793 }
2794 */
2795 /*
2796 float Calk(HSI hsb0,HSI hsb1,HSI hsb2)
2797 {
2798     float k;                    //计算空间点对直线的垂足位置,即垂足在直线上的两点之间的比例。
2799                                 //hsb0为空间点,hsb1和hsb2确定空间直线。
2800     float x0,x1,x2,y0,y1,y2,z0,z1,z2;
2801     float PercentH,PercentS,PercentV;
2802     PercentH=1.0f;PercentS=0.10f;PercentV=0.05f;
2803     x0=hsb0.H*PercentH;
2804     x1=hsb1.H*PercentH;
2805     x2=hsb2.H*PercentH;
2806     y0=hsb0.S*PercentS;
2807     y1=hsb1.S*PercentS;
2808     y2=hsb2.S*PercentS;
2809     z0=hsb0.I*PercentV;
2810     z1=hsb1.I*PercentV;
2811     z2=hsb2.I*PercentV;
2812     k=((x0-x1)*(x2-x1)+(y0-y1)*(y2-y1)+(z0-z1)*(z2-z1)) / ((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));
2813     return k;
2814 }
2815 */
2816 /*
2817 float CalPos(HSI hsb1)
2818 {
2819     float n;
2820     int i;
2821     int lastCheckedClass=0;
2822     float kPosition[maxClasses];
2823     HSI chsb1,chsb2;
2824     HSI hsbs[100];
2825     float Nf[100];
2826     float distancehsb[100];
2827     int TotalHsbs;
2828     float k;
2829     //先将所有颜色点统计出来;还有各颜色点对应的分值;
2830         TotalHsbs=0;
2831         for (i=0;i<TotalClasses;i++)
2832         {
2833             if (Classes[i].isChecked)
2834             {
2835                 hsbs[0]=Classes[i].hsb1;
2836                 Nf[0]=Classes[i].N1;
2837                 TotalHsbs++;
2838                 break;
2839             }
2840         }
2841         for (i=0;i<TotalClasses;i++)
2842         {
2843             if (Classes[i].isChecked)
2844             {
2845                 hsbs[TotalHsbs]=Classes[i].hsb2;
2846                 Nf[TotalHsbs]=Classes[i].N2;
2847                 TotalHsbs++;
2848             }
2849         }
2850     //然后找到距离最近的颜色点;
2851
2852         for (i=0;i<TotalHsbs;i++)
2853         {
2854             distancehsb[i]=CalHSIDistance(hsb1,hsbs[i]);
2855         }
2856     float mindistance;
2857     int mindistanceindex;
2858     mindistance=99999;
2859     mindistanceindex=0;
2860         for (i=0;i<TotalHsbs;i++)
2861         {
2862             if (distancehsb[i]<mindistance)
2863             {
2864                 mindistance=distancehsb[i];
2865                 mindistanceindex=i;
2866             }
2867         }
2868 //找到距离最近的点,index为i;
2869         //看看最近距离的点是否为边缘点。
2870         if (mindistance>=2.0f)
2871         {
2872             n=-1;
2873             return n;
2874         }
2875         if (mindistanceindex==0)
2876         {    //边缘点,也分落在边缘内和边缘外
2877             k=Calk(hsb1,hsbs[0],hsbs[1]);
2878             if (k<0)    //落在边缘点外
2879             {
2880                 n=(Nf[1]-Nf[0])*k+Nf[0];
2881                 return n;
2882             }
2883             else
2884             {            //落在边缘点内
2885                 n=(Nf[1]-Nf[0])*k+Nf[0];
2886                 return n;
2887             }
2888         }
2889         else if (mindistanceindex==TotalHsbs-1)
2890         {    //边缘点,也分落在边缘外和边缘内
2891             k=Calk(hsb1,hsbs[mindistanceindex-1],hsbs[mindistanceindex]);
2892             if (k>1)    //落在边缘点外
2893             {
2894                 n=(Nf[i]-Nf[mindistanceindex-1])*k+Nf[mindistanceindex-1];
2895                 return n;
2896             }
2897             else
2898             {            //落在边缘点内
2899                 n=(Nf[mindistanceindex]-Nf[mindistanceindex-1])*k+Nf[mindistanceindex-1];
2900                 return n;
2901             }
2902         }
2903         else
2904         {                //中间点
2905                         //要看靠中间点的哪端
2906             float k1,k2;
2907             float n1,n2;
2908             k1=Calk(hsb1,hsbs[mindistanceindex-1],hsbs[mindistanceindex]);
2909             k2=Calk(hsb1,hsbs[mindistanceindex],hsbs[mindistanceindex+1]);
2910             n1=(Nf[mindistanceindex]-Nf[mindistanceindex-1])*k1+Nf[mindistanceindex-1];
2911             n2=(Nf[mindistanceindex+1]-Nf[mindistanceindex])*k2+Nf[mindistanceindex];
2912             if (k1<=1&&k2<0) //处于一侧点。
2913             {
2914                 n=n1;
2915                 return n;
2916             }
2917             if (k1>1&&k2<0)    //处于两点之间,外弯
2918             {
2919                 n=Nf[i];
2920                 return n;
2921             }
2922             if (k1<=1&&k2>=0)    //处于两点之间,内弯
2923             {
2924                 n=(n1+n2)/2;
2925                 return n;
2926             }
2927             if (k1>=1&&k2>=0)    //处于另一侧点
2928             {
2929                 n=n2;
2930                 return n;
2931             }
2932             
2933         }
2934         for (i=0;i<TotalClasses;i++)
2935         {
2936             if (!Classes[i].isChecked) {continue;}
2937             chsb1=Classes[i].hsb1;
2938             chsb2=Classes[i].hsb2;
2939             kPosition[i]=Calk(hsb1,chsb1,chsb2);
2940             lastCheckedClass=i;
2941         }
2942         for (i=0;i<lastCheckedClass;i++)
2943         {
2944             if (!Classes[i].isChecked) {continue;}
2945             if (kPosition[i]<0) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;;break;}
2946             if (i==lastCheckedClass-1) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;break;}
2947             if (kPosition[i]>=0&&kPosition[i]<=1&&kPosition[i+1]<0) {n=kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i].N1;break;}
2948             if (kPosition[i]>=0&&kPosition[i]<=1&&kPosition[i+1]>=0&&kPosition[i+1]<=1) {n=(kPosition[i]*(Classes[i].N2-Classes[i].N1)+Classes[i+1].N1+kPosition[i+1]*(Classes[i+1].N2-Classes[i+1].N1)+Classes[i+1].N1)/2;break;}
2949             if (kPosition[i]>1&&kPosition[i+1]<0) 
2950             {
2951                 n=Classes[i].N2;break;
2952             }
2953         }
2954         return n;
2955 }
2956 */
2957 /*
2958         for (i=0;i<pt1total-1;i++)            //验证所有的点是不是都在一条线上。
2959         {
2960             startpt1=i;
2961             pt1valid[i]=1;
2962             continuepts1=2;                    //在一条线上的点的数量,最开始的两个点肯定在同一条线上。
2963
2964             for (j=i+1;j<pt1total;j++)
2965             {
2966
2967                 continuepts1=2;                    //在一条线上的点的数量,最开始的两个点肯定在同一条线上。
2968                 pt1valid[j]=1;
2969                 angle1=atan(((double)pt1[i].x-pt1[j].x)/((double)pt1[i].y-pt1[j].y));
2970                 endpt1=j;
2971                 for (k=j+1;k<pt1total;k++)    
2972                 {
2973
2974                     angle2=atan(((double)pt1[i].x-pt1[k].x)/((double)pt1[i].y-pt1[k].y));
2975                     distance=sqrt((double)(pt1[i].x-pt1[k].x)*(pt1[i].x-pt1[k].x)+(pt1[i].y-pt1[k].y)*(pt1[i].y-pt1[k].y));
2976                     intercept=distance*sin(abs(angle2-angle1));
2977                     //离开直线的距离,截距;
2978                     //if (abs(angle1-angle2)<maxangle)                //如果与第一个点的角度和原来的角度在一定范围内,认为在一条线上。
2979                     if (intercept<maxintercept)
2980                     {
2981                         pt1valid[k]=1;
2982                         endpt1=k;
2983                         continuepts1++;
2984                     }
2985                     else
2986                     {
2987                         pt1valid[k]=0;
2988                     }
2989                 }
2990
2991                 if (continuepts1>=4)            //如果在3个点或以上在同一条线上,认为是一条有效的线。
2992                 {
2993                     line1found=1;
2994                     break;
2995                 }
2996                 else                            //否则重新找线。
2997                 {
2998                     pt1valid[j]=0;
2999                     for (k=j+1;k<pt1total;k++)
3000                     {
3001                         pt1valid[k]=0;
3002                     }
3003                 }
3004             }
3005             if (line1found) {break;}
3006             pt1valid[i]=0;
3007         }
3008 */
3009 int BayerGR8toRGB32(void * src,void * dest,int width,int height,int stride1,int stride2)
3010 {
3011     int w=width,h=height;
3012 //    unsigned char * srcpixel=(unsigned char *)srcbuf;
3013 //    DWORD *  pixels=(DWORD *)destbuf;
3014
3015
3016     //unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
3017
3018
3019     DWORD  * destbuf=(DWORD *) dest;
3020     unsigned char * srcbuf=(unsigned char *)src;
3021 //    s=width;
3022     DWORD w2=stride2/4;
3023
3024
3025 #pragma omp parallel for
3026     for (int i=2;i<height-4;i+=2)
3027     {
3028         unsigned char G00, B01, G02, B03, G04, B05;
3029         unsigned char R10, G11, R12, G13, R14, G15;
3030         unsigned char G20, B21, G22, B23, G24, B25;
3031         unsigned char R30, G31, R32, G33, R34, G35;
3032         unsigned char G40, B41, G42, B43, G44, B45;
3033         unsigned char R50, G51, R52, G53, R54, G55;
3034
3035         COLOR pixel;
3036         unsigned char *line0=srcbuf+i*stride1-stride1-stride1;
3037         unsigned char *line1=srcbuf+i*stride1-stride1;
3038         unsigned char *line2=srcbuf+i*stride1;
3039         unsigned char *line3=srcbuf+i*stride1+stride1;
3040         unsigned char *line4=srcbuf+i*stride1+stride1+stride1;
3041         unsigned char *line5=srcbuf+i*stride1+stride1+stride1+stride1;
3042         int ll=i*w2;
3043         int lll=i*w2+w2;
3044         for (int j=2;j<width-4;j+=2)
3045         {
3046             // 奇数行 
3047
3048             pixel.R=(line2[j-1]+line2[j+1])/2;
3049             pixel.G=line2[j];
3050             pixel.B=(line1[j]+line3[j])/2;
3051             ((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
3052
3053             pixel.R=line2[j+1];
3054             //if (abs(signed(B03-B43))<abs(signed(B21-B25)))    {pixel.G=(G13+G33)/2;}
3055             //else{pixel.G=(G22+G24)/2;}
3056             if (abs(signed(line0[j+1]+line4[j+1]-line2[j+1]*2))<abs(signed(line2[j-1]+line2[j+3]-line2[j+1]*2))) { pixel.G=(line1[j+1]+line3[j+1])/2; }
3057             else { pixel.G=(line2[j]+line2[j+2])/2; }
3058
3059             pixel.B=((unsigned int )line1[j]+line3[j]+line1[j+2]+line3[j+2])/4;
3060             destbuf[ll+j+1]=pixel.argb ;
3061
3062             //偶数行
3063             pixel.R=((unsigned int )line2[j-1]+line4[j-1]+line2[j+1]+line4[j+1])/4;
3064             //    if (abs(signed(R12-R52))<abs(signed(R30-R34)))    {    pixel.G=(G22+G42)/2;}
3065             //    else{pixel.G=(G31+G33)/2;}
3066             if (abs(signed(line1[j]+line5[j]-line3[j]*2))<abs(signed(line3[j-2]+line3[j+2]-line3[j]*2))) { pixel.G=(line2[j]+line4[j])/2; }
3067             else { pixel.G=(line3[j-1]+line3[j+1])/2; }
3068             pixel.B=line3[j];
3069             destbuf[lll+j]=pixel.argb ;
3070
3071             pixel.R=(line2[j+1]+line4[j+1])/2;
3072             pixel.G=line3[j+1];
3073             pixel.B=(line3[j]+line3[j+2])/2;
3074             destbuf[lll+j+1]=pixel.argb ;
3075         }
3076
3077         continue;
3078
3079         int k,l,m,n,p,q;//,s;
3080
3081         k=i*stride1-stride1-stride1;        //上一行
3082         l=i*stride1-stride1;                //当前行
3083         m=i*stride1;            //下一行
3084         n=m+stride1;                //下两行
3085         p=m+stride1+stride1;
3086         q=m+stride1+stride1+stride1;
3087                         B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
3088         R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
3089         G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
3090         R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
3091         G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
3092         R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
3093
3094         for (int j=2;j<width-4;j+=2)
3095         {
3096             // 奇数行 
3097
3098                               /*B01=srcbuf[k+j-1];*/G02=srcbuf[k+j+0];B03=srcbuf[k+j+1];//G04=srcbuf[k+j+2];B05=srcbuf[k+j+3];
3099             /*R10=srcbuf[l+j-2];*/G11=srcbuf[l+j-1];R12=srcbuf[l+j+0];G13=srcbuf[l+j+1];R14=srcbuf[l+j+2];//G15=srcbuf[l+j+3];
3100             G20=srcbuf[m+j-2];B21=srcbuf[m+j-1];G22=srcbuf[m+j+0];B23=srcbuf[m+j+1];G24=srcbuf[m+j+2];B25=srcbuf[m+j+3];
3101             R30=srcbuf[n+j-2];G31=srcbuf[n+j-1];R32=srcbuf[n+j+0];G33=srcbuf[n+j+1];R34=srcbuf[n+j+2];G35=srcbuf[n+j+3];
3102             /*G40=srcbuf[p+j-2];*/B41=srcbuf[p+j-1];G42=srcbuf[p+j+0];B43=srcbuf[p+j+1];G44=srcbuf[p+j+2];//B45=srcbuf[p+j+3];
3103             /*R50=srcbuf[q+j-2];G51=srcbuf[q+j-1];*/R52=srcbuf[q+j+0];G53=srcbuf[q+j+1];//R54=srcbuf[q+j+2];G35=srcbuf[q+j+3];
3104
3105             pixel.R=(B21+B23)/2;
3106             pixel.G=G22;
3107             pixel.B=(R12+R32)/2;
3108             ((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
3109
3110             pixel.R=B23;
3111             //if (abs(signed(B03-B43))<abs(signed(B21-B25)))    {pixel.G=(G13+G33)/2;}
3112             //else{pixel.G=(G22+G24)/2;}
3113             if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) { pixel.G=(G13+G33)/2; }
3114             else { pixel.G=(G22+G24)/2; }
3115
3116             pixel.B=((unsigned int )R12+R32+R14+R34)/4;
3117             destbuf[i*w2+j+1]=pixel.argb ;
3118
3119             //偶数行
3120             pixel.R=((unsigned int )B21+B41+B23+B43)/4;
3121         //    if (abs(signed(R12-R52))<abs(signed(R30-R34)))    {    pixel.G=(G22+G42)/2;}
3122         //    else{pixel.G=(G31+G33)/2;}
3123             if (abs(signed(R12+R52-R32*2))<abs(signed(R30+R34-R32*2))) { pixel.G=(G22+G42)/2; }
3124             else { pixel.G=(G31+G33)/2; }
3125             pixel.B=R32;
3126             destbuf[i*w2+w2+j]=pixel.argb ;
3127
3128             pixel.R=(B23+B43)/2;
3129             pixel.G=G33;
3130             pixel.B=(R32+R34)/2;
3131             destbuf[i*w2+w2+j+1]=pixel.argb ;
3132         }
3133     }
3134     return 0;
3135
3136 /*
3137
3138     for (int i=0;i<h;i+=2)
3139     {
3140         COLOR c1;
3141         int k=i*(int)stride1;
3142         //偶数行
3143         int l=i*stride2/4;
3144         for (int j=0;j<w;j+=2)
3145         {
3146             c1.G=srcpixel[k+j];
3147             c1.B=srcpixel[k+j+1];
3148             c1.R=srcpixel[k+stride1+j];
3149             pixels[l+j]=c1.argb;
3150             pixels[l+j+1]=c1.argb;
3151         }                    
3152         //奇数行
3153         l=(i+1)*stride2/4;
3154         for (int j=0;j<w;j+=2)
3155         {
3156             c1.G=srcpixel[k+stride1+j+1];
3157             c1.B=srcpixel[k+j+1];
3158             c1.R=srcpixel[k+stride1+j];
3159             pixels[l+j]=c1.argb;
3160             pixels[l+j+1]=c1.argb;
3161         }
3162     }
3163     return 1;
3164 */
3165 }
3166 int BayerGB8toRGB32(void * src,void * dest,int width,int height,int stride1,int stride2)
3167 {
3168     int w=width,h=height;
3169 //    unsigned char * srcpixel=(unsigned char *)srcbuf;
3170 //    DWORD *  pixels=(DWORD *)destbuf;
3171
3172
3173     //unsigned short R,G,B,R1,R2,R3,R4,G1,G2,G3,G4,B1,B2,B3,B4;
3174
3175
3176     DWORD  * destbuf=(DWORD *) dest;
3177     unsigned char * srcbuf=(unsigned char *)src;
3178 //    s=width;
3179     DWORD w2=stride2/4;
3180
3181
3182 #pragma omp parallel for
3183     for (int i=2;i<height-4;i+=2)
3184     {
3185         unsigned char G00, B01, G02, B03, G04, B05;
3186         unsigned char R10, G11, R12, G13, R14, G15;
3187         unsigned char G20, B21, G22, B23, G24, B25;
3188         unsigned char R30, G31, R32, G33, R34, G35;
3189         unsigned char G40, B41, G42, B43, G44, B45;
3190         unsigned char R50, G51, R52, G53, R54, G55;
3191
3192         COLOR pixel;
3193         unsigned char *line0=srcbuf+i*stride1-stride1-stride1;
3194         unsigned char *line1=srcbuf+i*stride1-stride1;
3195         unsigned char *line2=srcbuf+i*stride1;
3196         unsigned char *line3=srcbuf+i*stride1+stride1;
3197         unsigned char *line4=srcbuf+i*stride1+stride1+stride1;
3198         unsigned char *line5=srcbuf+i*stride1+stride1+stride1+stride1;
3199
3200         for (int j=2;j<width-4;j+=2)
3201         {
3202             // 奇数行 
3203
3204             pixel.B=(line2[j-1]+line2[j+1])/2;
3205             pixel.G=line2[j];
3206             pixel.R=(line1[j]+line3[j])/2;
3207             ((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
3208
3209             pixel.B=line2[j+1];
3210             //if (abs(signed(B03-B43))<abs(signed(B21-B25)))    {pixel.G=(G13+G33)/2;}
3211             //else{pixel.G=(G22+G24)/2;}
3212             if (abs(signed(line0[j+1]+line4[j+1]-line2[j+1]*2))<abs(signed(line2[j-1]+line2[j+3]-line2[j+1]*2))) { pixel.G=(line1[j+1]+line3[j+1])/2; }
3213             else { pixel.G=(line2[j]+line2[j+2])/2; }
3214
3215             pixel.R=((unsigned int )line1[j]+line3[j]+line1[j+2]+line3[j+2])/4;
3216             destbuf[i*w2+j+1]=pixel.argb ;
3217
3218             //偶数行
3219             pixel.B=((unsigned int )line2[j-1]+line4[j-1]+line2[j+1]+line4[j+1])/4;
3220             //    if (abs(signed(R12-R52))<abs(signed(R30-R34)))    {    pixel.G=(G22+G42)/2;}
3221             //    else{pixel.G=(G31+G33)/2;}
3222             if (abs(signed(line1[j]+line5[j]-line3[j]*2))<abs(signed(line3[j-2]+line3[j+2]-line3[j]*2))) { pixel.G=(line2[j]+line4[j])/2; }
3223             else { pixel.G=(line3[j-1]+line3[j+1])/2; }
3224             pixel.R=line3[j];
3225             destbuf[i*w2+w2+j]=pixel.argb ;
3226
3227             pixel.B=(line2[j+1]+line4[j+1])/2;
3228             pixel.G=line3[j+1];
3229             pixel.R=(line3[j]+line3[j+2])/2;
3230             destbuf[i*w2+w2+j+1]=pixel.argb ;
3231         }
3232
3233         continue;
3234
3235         int k,l,m,n,p,q;//,s;
3236
3237         k=i*stride1-stride1-stride1;        //上一行
3238         l=i*stride1-stride1;                //当前行
3239         m=i*stride1;            //下一行
3240         n=m+stride1;                //下两行
3241         p=m+stride1+stride1;
3242         q=m+stride1+stride1+stride1;
3243                         B01=srcbuf[k+1];G02=srcbuf[k+2];B03=srcbuf[k+3];G04=srcbuf[k+4];B05=srcbuf[k+5];
3244         R10=srcbuf[l+0];G11=srcbuf[l+1];R12=srcbuf[l+2];G13=srcbuf[l+3];R14=srcbuf[l+4];G15=srcbuf[l+5];
3245         G20=srcbuf[m+0];B21=srcbuf[m+1];G22=srcbuf[m+2];B23=srcbuf[m+3];G24=srcbuf[m+4];B25=srcbuf[m+5];
3246         R30=srcbuf[n+0];G31=srcbuf[n+1];R32=srcbuf[n+2];G33=srcbuf[n+3];R34=srcbuf[n+4];G35=srcbuf[n+5];
3247         G40=srcbuf[p+0];B41=srcbuf[p+1];G42=srcbuf[p+2];B43=srcbuf[p+3];G44=srcbuf[p+4];B45=srcbuf[p+5];
3248         R50=srcbuf[q+0];G51=srcbuf[q+1];R52=srcbuf[q+2];G53=srcbuf[q+3];R54=srcbuf[q+4];G55=srcbuf[q+5];
3249
3250         for (int j=2;j<width-4;j+=2)
3251         {
3252             // 奇数行 
3253
3254                               /*B01=srcbuf[k+j-1];*/G02=srcbuf[k+j+0];B03=srcbuf[k+j+1];//G04=srcbuf[k+j+2];B05=srcbuf[k+j+3];
3255             /*R10=srcbuf[l+j-2];*/G11=srcbuf[l+j-1];R12=srcbuf[l+j+0];G13=srcbuf[l+j+1];R14=srcbuf[l+j+2];//G15=srcbuf[l+j+3];
3256             G20=srcbuf[m+j-2];B21=srcbuf[m+j-1];G22=srcbuf[m+j+0];B23=srcbuf[m+j+1];G24=srcbuf[m+j+2];B25=srcbuf[m+j+3];
3257             R30=srcbuf[n+j-2];G31=srcbuf[n+j-1];R32=srcbuf[n+j+0];G33=srcbuf[n+j+1];R34=srcbuf[n+j+2];G35=srcbuf[n+j+3];
3258             /*G40=srcbuf[p+j-2];*/B41=srcbuf[p+j-1];G42=srcbuf[p+j+0];B43=srcbuf[p+j+1];G44=srcbuf[p+j+2];//B45=srcbuf[p+j+3];
3259             /*R50=srcbuf[q+j-2];G51=srcbuf[q+j-1];*/R52=srcbuf[q+j+0];G53=srcbuf[q+j+1];//R54=srcbuf[q+j+2];G35=srcbuf[q+j+3];
3260
3261             pixel.B=(B21+B23)/2;
3262             pixel.G=G22;
3263             pixel.R=(R12+R32)/2;
3264             ((COLOR *)(&destbuf[i*w2+j]))->argb=pixel.argb ;
3265
3266             pixel.B=B23;
3267             //if (abs(signed(B03-B43))<abs(signed(B21-B25)))    {pixel.G=(G13+G33)/2;}
3268             //else{pixel.G=(G22+G24)/2;}
3269             if (abs(signed(B03+B43-B23*2))<abs(signed(B21+B25-B23*2))) { pixel.G=(G13+G33)/2; }
3270             else { pixel.G=(G22+G24)/2; }
3271
3272             pixel.R=((unsigned int )R12+R32+R14+R34)/4;
3273             destbuf[i*w2+j+1]=pixel.argb ;
3274
3275             //偶数行
3276             pixel.B=((unsigned int )B21+B41+B23+B43)/4;
3277         //    if (abs(signed(R12-R52))<abs(signed(R30-R34)))    {    pixel.G=(G22+G42)/2;}
3278         //    else{pixel.G=(G31+G33)/2;}
3279             if (abs(signed(R12+R52-R32*2))<abs(signed(R30+R34-R32*2))) { pixel.G=(G22+G42)/2; }
3280             else { pixel.G=(G31+G33)/2; }
3281             pixel.R=R32;
3282             destbuf[i*w2+w2+j]=pixel.argb ;
3283
3284             pixel.B=(B23+B43)/2;
3285             pixel.G=G33;
3286             pixel.R=(R32+R34)/2;
3287             destbuf[i*w2+w2+j+1]=pixel.argb ;
3288         }
3289     }
3290     return 0;
3291
3292 /*
3293
3294     for (int i=0;i<h;i+=2)
3295     {
3296         COLOR c1;
3297         int k=i*(int)stride1;
3298         //偶数行
3299         int l=i*stride2/4;
3300         for (int j=0;j<w;j+=2)
3301         {
3302             c1.G=srcpixel[k+j];
3303             c1.B=srcpixel[k+j+1];
3304             c1.R=srcpixel[k+stride1+j];
3305             pixels[l+j]=c1.argb;
3306             pixels[l+j+1]=c1.argb;
3307         }                    
3308         //奇数行
3309         l=(i+1)*stride2/4;
3310         for (int j=0;j<w;j+=2)
3311         {
3312             c1.G=srcpixel[k+stride1+j+1];
3313             c1.B=srcpixel[k+j+1];
3314             c1.R=srcpixel[k+stride1+j];
3315             pixels[l+j]=c1.argb;
3316             pixels[l+j+1]=c1.argb;
3317         }
3318     }
3319     return 1;
3320 */
3321 }
3322 int BayerGB8toRGB24(void * srcbuf,void * destbuf,int width,int height,int stride,int stride2)
3323 {
3324     int w=width,h=height;
3325     int Stride=stride;
3326     int s=stride2;
3327     unsigned char * srcpixel=(unsigned char *)srcbuf;
3328     unsigned char * pixels=(unsigned char *)destbuf;
3329
3330 #pragma omp parallel for
3331     for (int i=0;i<h;i+=2)
3332     {
3333         COLOR c1;
3334         int k=i*(int)Stride;
3335         //偶数行
3336         int l=i*s;
3337         for (int j=0;j<w;j+=2)
3338         {
3339             c1.G=srcpixel[k+j];
3340             c1.B=srcpixel[k+j+1];
3341             c1.R=srcpixel[k+Stride+j];
3342             pixels[l+(j)*3+0]=c1.B;    pixels[l+(j)*3+1]=c1.G;    pixels[l+(j)*3+2]=c1.R;
3343             pixels[l+(j+1)*3+0]=c1.B;    pixels[l+(j+1)*3+1]=c1.G;    pixels[l+(j+1)*3+2]=c1.R;
3344         }                    
3345         //奇数行
3346         l=(i+1)*s;
3347         for (int j=0;j<w;j+=2)
3348         {
3349             c1.G=srcpixel[k+Stride+j+1];
3350             c1.B=srcpixel[k+j+1];
3351             c1.R=srcpixel[k+Stride+j];
3352             pixels[l+(j)*3+0]=c1.B;    pixels[l+(j)*3+1]=c1.G;    pixels[l+(j)*3+2]=c1.R;
3353             pixels[l+(j+1)*3+0]=c1.B;    pixels[l+(j+1)*3+1]=c1.G;    pixels[l+(j+1)*3+2]=c1.R;
3354         }
3355     }
3356     return 1;
3357 }
3358
3359 int SecWhiteBalance::LoadWBParamFromFile(CString sFilePathName)
3360 {
3361     CString s1;
3362 //    s1.Format(_T("从文件 %s 加载白平衡矫正模板 \r\n"),sFilePathName);
3363 //    SysLog(s1);
3364     int j=0;
3365     Gdiplus::Bitmap bitmap1(sFilePathName);
3366     
3367     if (bitmap1.GetWidth()!=0)
3368     {j=ReadWBParamFromBmp(&bitmap1);}
3369     return j;
3370 }
3371
3372 int SecWhiteBalance::ReadWBParamFromBmp(Gdiplus::Bitmap * bitmap1)
3373 {
3374
3375 //    double tick0=GetTickCountmS();
3376     if (bitmap1==NULL) {return 0;}
3377     if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0) {return 0;}
3378     int i,j,k;
3379     int w,h;
3380     w=bitmap1->GetWidth();
3381     h=bitmap1->GetHeight();
3382     if (0==w||0==h) 
3383     {return 0;}
3384
3385     Gdiplus::BitmapData bitmapdata0;
3386     UINT * pixels;
3387     Gdiplus::Rect rect0(0,0,w,h);
3388
3389     Gdiplus::Status    GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
3390     if (GdipStatus!=Gdiplus::Ok)
3391     {
3392         CString Errs1;
3393         Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
3394 //        SysLog(Errs1);
3395         return 0;
3396     }
3397     pixels=(UINT *)bitmapdata0.Scan0 ;
3398
3399 //    xsecs=w/xstep;
3400 //    ysecs=h/ystep;
3401 //    int m,n;
3402     COLOR c1;
3403 //    int secR,secG,secB,secV;
3404 //    float aveR,aveG,aveB,aveV;
3405     float totalaveR,totalaveG,totalaveB;
3406     totalaveR=0;totalaveG=0;totalaveB=0;
3407     for (i=0;i<wbysecs;i++)
3408     {
3409         for (j=0;j<wbxsecs;j++)
3410         {
3411             wbsectotalR[i][j]=0;
3412             wbsectotalG[i][j]=0;
3413             wbsectotalB[i][j]=0;
3414             wbsecsamples[i][j]=0;
3415         }
3416     }
3417     int xsec,ysec;
3418     for (i=0;i<h;i++)
3419     {
3420         k=i*w;
3421         ysec=i*wbysecs/h;
3422         for (j=0;j<w;j++)
3423         {
3424             xsec=j*wbxsecs/w;
3425             c1.argb =pixels[k+j];
3426             wbsectotalR[ysec][xsec]+=c1.R;
3427             wbsectotalG[ysec][xsec]+=c1.G;
3428             wbsectotalB[ysec][xsec]+=c1.B;
3429             wbsecsamples[ysec][xsec]++;
3430         }
3431     }
3432     float wbV;
3433     wbtotalV=0;
3434     for (i=0;i<wbysecs;i++)
3435     {
3436         for (j=0;j<wbxsecs;j++)
3437         {
3438             wbsecR[i][j]=(float)wbsectotalR[i][j]/wbsecsamples[i][j];
3439             wbsecG[i][j]=(float)wbsectotalG[i][j]/wbsecsamples[i][j];
3440             wbsecB[i][j]=(float)wbsectotalB[i][j]/wbsecsamples[i][j];
3441             //wbV=wbsecR[i][j]*0.299f+wbsecG[i][j]*0.587f+wbsecB[i][j]*0.114f;
3442             wbV=RGBtoVf(wbsecR[i][j],wbsecG[i][j],wbsecB[i][j]);
3443             wbtotalV+=wbV;
3444         }
3445     }
3446     wbaveV=wbtotalV/(wbysecs*wbxsecs);
3447 //    wbaveV=128.0f;
3448     /*
3449     for (i=0;i<ysecs;i++)
3450     {    yoff=i*ystep*w;
3451         for (j=0;j<xsecs;j++)
3452         {
3453             xoff=j*xstep;
3454             secV=0;
3455             secR=0;secG=0;secB=0;
3456             for(k=0;k<ystep;k++)
3457             {
3458                 m=yoff+k*w;
3459                 for (l=0;l<xstep;l++)
3460                 {
3461                     secR+=c1.R ;
3462                     secG+=c1.G;
3463                     secB+=c1.B;
3464                 }
3465             }
3466             aveR=(float)secR/(xstep*ystep);
3467             aveG=(float)secG/(xstep*ystep);
3468             aveB=(float)secB/(xstep*ystep);
3469             
3470             aveV=secV/(xstep*ystep);
3471             bright[i][j]=aveV;
3472             wbR[i][j]=aveR;
3473             wbG[i][j]=aveG;
3474             wbB[i][j]=aveB;
3475             totalaveR+=aveR;
3476             totalaveG+=aveG;
3477             totalaveB+=aveB;
3478         }
3479     }
3480 //*/
3481     bitmap1->UnlockBits(&bitmapdata0);
3482 //    double tick1=GetTickCountmS();
3483
3484     CString s1;
3485 //    s1.Format(_T("创建白平衡数组,w,h %d %d  用时 %.2fmS\r\n"),w,h,tick1-tick0);
3486 //    SysLog(s1);
3487     wbcorrloaded=1;
3488     autowbcorronopen=1;
3489
3490 //    ((CButton *)GetDlgItem(IDC_CHECK_WBCORR))->SetCheck(true);
3491
3492     return 1;
3493 }
3494
3495 int SecWhiteBalance::LoadBayerWBParamFromFile(CString sFilePathName)
3496 {
3497     CString s1;
3498     //    s1.Format(_T("从文件 %s 加载白平衡矫正模板 \r\n"),sFilePathName);
3499     //    SysLog(s1);
3500     int j=0;
3501     Gdiplus::Bitmap bitmap1(sFilePathName);
3502
3503     if (bitmap1.GetWidth()!=0)
3504     {j=ReadBayerWBParamFromBmp(&bitmap1);}
3505     return j;
3506 }
3507 int SecWhiteBalance::ReadBayerWBParamFromBmp(Gdiplus::Bitmap * bitmap1)
3508 {
3509
3510 //    double tick0=GetTickCountmS();
3511     if (bitmap1==NULL) {return 0;}
3512     if (bitmap1->GetWidth()==0||bitmap1->GetHeight()==0) {return 0;}
3513     int i,j,k;
3514     int w,h;
3515     w=bitmap1->GetWidth();
3516     h=bitmap1->GetHeight();
3517     if (0==w||0==h) 
3518     {return 0;}
3519
3520     Gdiplus::BitmapData bitmapdata0;
3521     unsigned char * pixels;
3522     Gdiplus::Rect rect0(0,0,w,h);
3523
3524     Gdiplus::Status    GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat8bppIndexed,&bitmapdata0);
3525     if (GdipStatus!=Gdiplus::Ok)
3526     {
3527         CString Errs1;
3528         Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
3529 //        SysLog(Errs1);
3530         return 0;
3531     }
3532     pixels=(unsigned char *)bitmapdata0.Scan0 ;
3533     int stride=bitmapdata0.Stride;
3534 //    xsecs=w/xstep;
3535 //    ysecs=h/ystep;
3536 //    int m,n;
3537     //COLOR c1;
3538
3539 //    int secR,secG,secB,secV;
3540 //    float aveR,aveG,aveB,aveV;
3541     float totalaveR,totalaveG,totalaveB;
3542     totalaveR=0;totalaveG=0;totalaveB=0;
3543     for (i=0;i<wbysecs;i++)
3544     {
3545         for (j=0;j<wbxsecs;j++)
3546         {
3547             wbsectotalR[i][j]=0;
3548             wbsectotalG[i][j]=0;
3549             wbsectotalB[i][j]=0;
3550             wbsecsamples[i][j]=0;
3551         }
3552     }
3553     int xsec,ysec;
3554     for (i=0;i<h;i+=2)
3555     {
3556         k=i*stride;
3557         ysec=i*wbysecs/h;
3558         for (j=0;j<w;j+=2)
3559         {
3560             xsec=j*wbxsecs/w;
3561             unsigned char c1,c2,c3,c4;
3562             c1 = pixels[k+j];
3563             c2 = pixels[k+j+1];
3564             c3 = pixels[k+stride+j];
3565             c4 = pixels[k+stride+j+1];
3566
3567             wbsectotalG[ysec][xsec]+=c1;
3568             wbsectotalR[ysec][xsec]+=c2;
3569             wbsectotalB[ysec][xsec]+=c3;
3570             wbsectotalG2[ysec][xsec]+=c4;
3571             wbsecsamples[ysec][xsec]++;
3572         }
3573     }
3574     bitmap1->UnlockBits(&bitmapdata0);
3575     float wbV;
3576     wbtotalV=0;
3577     for (i=0;i<wbysecs;i++)
3578     {
3579         for (j=0;j<wbxsecs;j++)
3580         {
3581             wbsecR[i][j]=(float)wbsectotalR[i][j]/wbsecsamples[i][j];
3582             wbsecG[i][j]=(float)wbsectotalG[i][j]/wbsecsamples[i][j];
3583             wbsecB[i][j]=(float)wbsectotalB[i][j]/wbsecsamples[i][j];
3584             wbsecG2[i][j]=(float)wbsectotalG2[i][j]/wbsecsamples[i][j];
3585             //wbV=wbsecR[i][j]*0.299f+wbsecG[i][j]*0.587f+wbsecB[i][j]*0.114f;
3586             wbV=RGBtoVf(wbsecR[i][j],wbsecG[i][j],wbsecB[i][j]);
3587             wbtotalV+=wbV;
3588         }
3589     }
3590     wbaveV=wbtotalV/(wbysecs*wbxsecs);
3591     /*  保存成一个BMP
3592     Bitmap bitmap2(wbxsecs,wbysecs);
3593     BitmapData bitmapdata2;
3594     bitmap2.LockBits(&Rect(0,0,wbxsecs,wbysecs),ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata2);
3595     UINT * pixels2=(UINT *)bitmapdata2.Scan0;
3596     int stride2=bitmapdata2.Stride;
3597     for (int i=0;i<wbysecs;i++)
3598     {
3599         for (int j=0;j<wbxsecs;j++)
3600         {
3601             COLOR c2;
3602             c2.R=wbsecR[i][j];
3603             c2.G=wbsecG[i][j];
3604             c2.B=wbsecB[i][j];
3605             pixels2[i*stride2/4+j]=c2.argb;
3606         }
3607     }
3608     bitmap2.UnlockBits(&bitmapdata2);
3609     SaveGdiPImageAsFile(&bitmap2,_T("D:\\1\\aa.bmp"));
3610     */
3611     BrightnessCorr=1.0f;
3612     for (i=0;i<wbysecs;i++)
3613     {    
3614         for (j=0;j<wbxsecs;j++)
3615         {
3616             float wbR=wbsecR[i][j];
3617             float wbG=wbsecG[i][j];
3618             float wbB=wbsecB[i][j];
3619             float wbG2=wbsecG2[i][j];
3620             if (wbR<32) {wbR=32;}
3621             if (wbG<32) {wbG=32;}
3622             if (wbB<32) {wbB=32;}
3623             if (wbG2<32) {wbG2=32;}
3624             float wbRcorr,wbGcorr,wbBcorr,wbG2corr;
3625
3626             if (TargetLight==0)
3627             {
3628                 wbRcorr=int(128.0f*wbaveV*BrightnessCorr/wbR);
3629                 wbGcorr=int(128.0f*wbaveV*BrightnessCorr/wbG);
3630                 wbBcorr=int(128.0f*wbaveV*BrightnessCorr/wbB);
3631                 wbG2corr=int(128.0f*wbaveV*BrightnessCorr/wbG2);
3632             }
3633             else if (TargetLightR*TargetLightG*TargetLightB==0)
3634             {
3635                 wbRcorr=int(128.0f*TargetLight*BrightnessCorr/wbR);
3636                 wbGcorr=int(128.0f*TargetLight*BrightnessCorr/wbG);
3637                 wbBcorr=int(128.0f*TargetLight*BrightnessCorr/wbB);
3638                 wbG2corr=int(128.0f*TargetLight*BrightnessCorr/wbG2);
3639             }else
3640             {
3641                 wbRcorr=int(128.0f*TargetLightR*BrightnessCorr/wbR);
3642                 wbGcorr=int(128.0f*TargetLightG*BrightnessCorr/wbG);
3643                 wbBcorr=int(128.0f*TargetLightB*BrightnessCorr/wbB);
3644                 wbG2corr=int(128.0f*TargetLightG*BrightnessCorr/wbG2);
3645             }
3646             wbsecRcorr[i][j]=wbRcorr;
3647             wbsecGcorr[i][j]=wbGcorr;
3648             wbsecBcorr[i][j]=wbBcorr;
3649             wbsecG2corr[i][j]=wbG2corr;
3650         }
3651     }
3652 /*
3653     Bitmap bitmap3(wbxsecs,wbysecs);
3654     BitmapData bitmapdata3;
3655     bitmap3.LockBits(&Rect(0,0,wbxsecs,wbysecs),ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata3);
3656     UINT * pixels3=(UINT *)bitmapdata3.Scan0;
3657     int stride3=bitmapdata3.Stride;
3658     for (int i=0;i<wbysecs;i++)
3659     {
3660         for (int j=0;j<wbxsecs;j++)
3661         {
3662             COLOR c2;
3663             c2.R=wbsecRcorr[i][j];
3664             c2.G=wbsecGcorr[i][j];
3665             c2.B=wbsecBcorr[i][j];
3666             pixels3[i*stride3/4+j]=c2.argb;
3667         }
3668     }
3669     bitmap3.UnlockBits(&bitmapdata3);
3670     SaveGdiPImageAsFile(&bitmap3,_T("D:\\1\\aa3.bmp"));
3671 */
3672 //    wbaveV=128.0f;
3673     /*
3674     for (i=0;i<ysecs;i++)
3675     {    yoff=i*ystep*w;
3676         for (j=0;j<xsecs;j++)
3677         {
3678             xoff=j*xstep;
3679             secV=0;
3680             secR=0;secG=0;secB=0;
3681             for(k=0;k<ystep;k++)
3682             {
3683                 m=yoff+k*w;
3684                 for (l=0;l<xstep;l++)
3685                 {
3686                     secR+=c1.R ;
3687                     secG+=c1.G;
3688                     secB+=c1.B;
3689                 }
3690             }
3691             aveR=(float)secR/(xstep*ystep);
3692             aveG=(float)secG/(xstep*ystep);
3693             aveB=(float)secB/(xstep*ystep);
3694             
3695             aveV=secV/(xstep*ystep);
3696             bright[i][j]=aveV;
3697             wbR[i][j]=aveR;
3698             wbG[i][j]=aveG;
3699             wbB[i][j]=aveB;
3700             totalaveR+=aveR;
3701             totalaveG+=aveG;
3702             totalaveB+=aveB;
3703         }
3704     }
3705 //*/
3706
3707 //    double tick1=GetTickCountmS();
3708
3709     CString s1;
3710 //    s1.Format(_T("创建白平衡数组,w,h %d %d  用时 %.2fmS\r\n"),w,h,tick1-tick0);
3711 //    SysLog(s1);
3712     wbcorrloaded=1;
3713     autowbcorronopen=1;
3714
3715 //    ((CButton *)GetDlgItem(IDC_CHECK_WBCORR))->SetCheck(true);
3716
3717     return 1;
3718 }
3719
3720 int SecWhiteBalance::WBCorrect(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
3721 {
3722     return WBCorrectVC(bitmap1,bitmap2, fRateR, fRateG, fRateB);
3723 }
3724 // 
3725 // int SecWhiteBalance::WBCorrect1(Gdiplus::Bitmap * bitmap1)
3726 // {
3727 //     if (this->wbcorrloaded==0) {return 0;}
3728 //     double tick0=GetTickCountmS();
3729 //     int i,j,k;
3730 //     if (bitmap1==NULL)
3731 //     {return 0;}
3732 //     int w,h;
3733 //     w=bitmap1->GetWidth();
3734 //     h=bitmap1->GetHeight();
3735 //     if (0==w||0==h) 
3736 //     {return 0;}
3737 //     Gdiplus::BitmapData bitmapdata0;
3738 //     UINT * pixels;
3739 //     Gdiplus::Rect rect0(0,0,w,h);
3740 // //    UINT * pixels2;
3741 //     COLOR * c2;
3742 //     Gdiplus::Status    GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead|Gdiplus::ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata0);
3743 //     if (GdipStatus!=Gdiplus::Ok)
3744 //     {
3745 //         CString Errs1;
3746 //         Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
3747 // //        SysLog(Errs1);
3748 //         return 0;
3749 //     }
3750 //     pixels=(UINT *)bitmapdata0.Scan0 ;
3751 //     int s=bitmapdata0.Stride/4;
3752 // /*
3753 //     threadinfo1[0].pParam1=this;
3754 //     threadinfo1[0].pParam2=0;
3755 //     threadinfo1[0].starty=0;
3756 //     threadinfo1[0].endy=wbysecs/2;
3757 //     threadinfo1[0].pixels=pixels;
3758 //     threadinfo1[0].h=h;
3759 //     threadinfo1[0].w=w;
3760 //     threadinfo1[0].torun=1;
3761 //     threadinfo1[0].stride=bitmapdata0.Stride;
3762 //     threadinfo1[0].finish=0;
3763 // 
3764 //     threadinfo1[1].pParam1=this;
3765 //     threadinfo1[1].pParam2=(LPVOID)1;
3766 //     threadinfo1[1].starty=wbysecs/2;
3767 //     threadinfo1[1].endy=wbysecs;
3768 //     threadinfo1[1].pixels=pixels;
3769 //     threadinfo1[1].h=h;
3770 //     threadinfo1[1].w=w;
3771 //     threadinfo1[1].torun=1;
3772 //     threadinfo1[1].stride=bitmapdata0.Stride;
3773 //     threadinfo1[1].finish=0;
3774 // */
3775 // //    CWinThread * thread1;
3776 // //    CWinThread * thread2;
3777 // /*
3778 //     thread1=AfxBeginThread(WBcorrThreadJumper,&(threadinfo1[0]),0,0,CREATE_SUSPENDED,0);
3779 //     thread2=AfxBeginThread(WBcorrThreadJumper,&(threadinfo1[1]),0,0,CREATE_SUSPENDED,0);
3780 // //    thread1->m_bAutoDelete=true;
3781 // //    thread2->m_bAutoDelete=true;
3782 // //    ::SetThreadAffinityMask(thread1->m_hThread,0x00000001);
3783 // //    ::SetThreadAffinityMask(thread2->m_hThread,0x00000002);
3784 //     thread1->ResumeThread();
3785 //     thread2->ResumeThread();
3786 //     for (i=0;i<10000;i++)
3787 //     {
3788 //         if (threadinfo1[0].finish==0||threadinfo1[1].finish==0)
3789 //         {
3790 //             Sleep(10);
3791 //         }
3792 //         else
3793 //         {
3794 //             break;
3795 //         }
3796 //     }
3797 // //*/
3798 // //    int xsec,ysec;
3799 // //    int m,n;
3800 // //    COLOR c1;
3801 // //    int secV;
3802 // //    int aveV;
3803 //     
3804 //     int yoff,ystep,xoff,xstep;
3805 //     int offset;
3806 //     float wbR,wbG,wbB;
3807 // //    short int R,G,B;
3808 //     short int wbRcorr,wbGcorr,wbBcorr;
3809 // //    if (0) 
3810 //         for (i=0;i<wbysecs;i++)
3811 //     {    yoff=i*h/wbysecs;
3812 //         ystep=(i+1)*h/wbysecs-yoff;
3813 //         for (j=0;j<wbxsecs;j++)
3814 //         {
3815 //             xoff=j*w/wbxsecs;
3816 //             xstep=(j+1)*w/wbxsecs-xoff;
3817 //             wbR=wbsecR[i][j];
3818 //             wbG=wbsecG[i][j];
3819 //             wbB=wbsecB[i][j];
3820 //             if (wbR<32) {wbR=32;}
3821 //             if (wbG<32) {wbG=32;}
3822 //             if (wbB<32) {wbB=32;}
3823 //             if (TargetLight==0)
3824 //             {
3825 //                 wbRcorr=int(128.0f*wbaveV*BrightnessCorr/wbR);
3826 //                 wbGcorr=int(128.0f*wbaveV*BrightnessCorr/wbG);
3827 //                 wbBcorr=int(128.0f*wbaveV*BrightnessCorr/wbB);
3828 //             }
3829 //             else if (TargetLightR*TargetLightG*TargetLightB==0)
3830 //             {
3831 //                 wbRcorr=int(128.0f*TargetLight*BrightnessCorr/wbR);
3832 //                 wbGcorr=int(128.0f*TargetLight*BrightnessCorr/wbG);
3833 //                 wbBcorr=int(128.0f*TargetLight*BrightnessCorr/wbB);
3834 //             }else
3835 //             {
3836 //                 wbRcorr=int(128.0f*TargetLightR*BrightnessCorr/wbR);
3837 //                 wbGcorr=int(128.0f*TargetLightG*BrightnessCorr/wbG);
3838 //                 wbBcorr=int(128.0f*TargetLightB*BrightnessCorr/wbB);
3839 //             }
3840 //             //continue;
3841 //             // 设置相乘系数
3842 //             /*
3843 //             __int64 corr = 0;
3844 //             corr = wbRcorr;
3845 //             corr = corr << 16;
3846 //             corr |= wbGcorr;
3847 //             corr = corr << 16;
3848 //             corr |= wbBcorr;
3849 //              _mm_empty();                            // 清空MMX寄存器。
3850 // 
3851 //             __m64 nNull = _m_from_int(0);           // null
3852 //             __m64 tmp = _m_from_int(0);             // 临时工作临时变量初始化
3853 // 
3854 //              __m64 nCoeff = Get_m64(corr);
3855 //              __m128 corr128;
3856 //              corr128.m128_u16[0]=wbBcorr;
3857 //              corr128.m128_u16[1]=wbGcorr;
3858 //              corr128.m128_u16[2]=wbRcorr;
3859 //              corr128.m128_u16[3]=0;
3860 //              corr128.m128_u16[4]=wbBcorr;
3861 //              corr128.m128_u16[5]=wbGcorr;
3862 //              corr128.m128_u16[6]=wbRcorr;
3863 //              corr128.m128_u16[7]=0;
3864 //              __m128 nCorr128=corr128;
3865 //              */
3866 // //             __m128 nNull128;
3867 // //             __m128 temp2;
3868 // 
3869 // 
3870 //    // DWORD* pIn = (DWORD*) pSource;          // 输入双字数组
3871 //   //  DWORD* pOut = (DWORD*) pDest;           // 输出双字数组
3872 // 
3873 // 
3874 //     //        _mm_set_ps(1.0f,2.0f,3.0f,4.0f);
3875 // 
3876 //             for (k=0;k<ystep;k++)
3877 //             {    
3878 //                 offset=(yoff+k)*s+xoff;
3879 //                 
3880 //                 //continue;
3881 //                     c2=(COLOR *)(pixels+offset);
3882 //                 //for (l=0;l<xstep;l++)
3883 //                 {//    pixels2=pixels+offset+l;
3884 //                     //continue;
3885 // /* ==============//C语言代码 =========== 109mS
3886 //                     R=c2->R*wbRcorr>>7;
3887 //                     if (R>255) {c1.R=255;}
3888 //                     else {c2->R=R;}
3889 //                     G=c2->G*wbGcorr>>7;
3890 //                     c2->G=min(255,G);
3891 //                     B=c2->B*wbBcorr>>7;
3892 //                     c2->B =min(255,B);
3893 //                     c2++;
3894 // //*/ //========================================
3895 //         
3896 // /* //======================MMX 代码==================================== 120mS
3897 //                     if (usemmx)
3898 //                     {
3899 //                     tmp = _m_from_int(c2->argb);                // tmp = *pIn (在tmp的低32位写入数据)
3900 // 
3901 //                     tmp = _mm_unpacklo_pi8(tmp, nNull );    //将tmp中低位的4个字节转化为字
3902 //                                                             //字的高位用nNull中对应位上的位值填充。 
3903 // 
3904 //                     tmp =  _mm_mullo_pi16 (tmp , nCoeff);   //将tmp中的每一个字相乘,将相乘结果的高位送到nCoeff,在tmp中只保留每个结果的低位。 
3905 // 
3906 //                     tmp = _mm_srli_pi16 (tmp , 7);          // 将tmp中的每一个字右移7位,相当于除以128
3907 // 
3908 //                     tmp = _mm_packs_pu16 (tmp, nNull);      // 使用饱和模式将tmp中的结果做如下处理:
3909 //                                                 //将tmp中的4个字转化为4个字节,并将这4个字节写到tmp中的低32位中 
3910 //                                                 // 同时,将nNull中的4个字转化为4个字节,并将这4个字节写到tmp的高32位中。
3911 // 
3912 //                     c2->argb = _m_to_int(tmp)|0xff000000;                 // *pOut = tmp (将tmp低32位的数据放入pOut数组中)
3913 //                     c2++;
3914 //                     }
3915 //  //*/  //=======================================================   
3916 // ////======================= SSE INTRIC 代码 ========================
3917 //                     //__m128 a1=_mm_setzero_ps();
3918 //                     //a1=_mm_load
3919 //                 //    __m128 a;
3920 //                 //    __m128i b;
3921 //                 //    __m128d c;
3922 //                 //    _mm_packuswb()
3923 // ///* //==================== SSE 汇编优化 ========================== 30mS
3924 //                     int xstep_2=xstep/2;
3925 // /*
3926 //                     _asm
3927 //                     {
3928 //                         //tmp=_m_from_int(c2->argb);
3929 //                     //start:
3930 //                         movq xmm0,mmword ptr[nNull];
3931 //                         movdqa xmm4,nCorr128;
3932 //                         mov eax,c2;
3933 //                         sub eax,4;
3934 //                         mov ecx,xstep;
3935 //                     loop1:
3936 //                         //mov edx,dword ptr [eax+ecx*4]
3937 //                         movd xmm1,dword ptr [eax+ecx*4]; //edx;
3938 //                     //    movd mm1,dword ptr [eax+ecx*4];
3939 //                     //    movq mmword ptr[tmp],mm0;
3940 //                         //tmp=_mm_unpacklo_pi8(tmp,nNull);
3941 //                         //movq xmm0,mmword ptr [nNull];
3942 //                     //    movdqa xmm2,xmm0
3943 //                         movaps xmm2,xmm0
3944 //                     //    movq mm0,mmword ptr [tmp];
3945 //                         movaps xmm3,xmm4
3946 // 
3947 //                         punpcklbw xmm1,xmm2;
3948 //                     //    movq mmword ptr [tmp],mm1;
3949 //                         // tmp=_mm_mull0_pi16(tmp,nCoeff);
3950 //                                                         //movdq xmm2,xmmword ptr [nCoeff]
3951 //                     //    movdqa xmm2,nCorr128;
3952 //                 
3953 //                     //    movq mm1,mmword ptr[tmp]
3954 //                         pmullw xmm1,xmm3;    注释
3955 //                     //    movq mmword ptr[tmp],mm1
3956 //                         // tmp = _mm_srli_pi16(tmp,7)
3957 //                     //    movq mm0,mmword ptr[tmp]
3958 //                         psrlw xmm1,7;
3959 //                     //    movq mmwordptr[tmp],mm1;
3960 //                         //tmp=_mm_packs_pu16(tmp,nNull);
3961 //                     //    movq mm0,mmword ptr [nNull]
3962 //                     //    movq mm1,mmword ptr [tmp]
3963 //                         packuswb xmm1,xmm2;
3964 //                     //    movq mmword ptr [tmp],mm1;
3965 //                         //c2->argb=_m_to_int(tmp)|0xff000000;
3966 //                     //    movq mm1,mmword ptr[tmp]
3967 //                         movd dword ptr [eax+ecx*4],xmm1;
3968 //                         //or edx,0ff000000h;
3969 //                         //mov dword ptr[eax+ecx*4],edx;
3970 //                         //mulps xmm3,xmm4;
3971 // 
3972 //                         loop loop1
3973 // 
3974 //                         //dec ebx;
3975 //                         //jne loop1;
3976 //                     }
3977 // */
3978 // //*///===============================================================
3979 //                 
3980 //                 }
3981 //             }
3982 //     //        _mm_empty();                            
3983 //         }
3984 //     }
3985 // 
3986 // 
3987 //     bitmap1->UnlockBits(&bitmapdata0);
3988 //     double tick1=GetTickCountmS();
3989 //     CString s1;
3990 // //    s1.Format(_T("白平衡修正完成 用时 %.2fmS\r\n"),tick1-tick0);
3991 // //    SysLog1(s1);
3992 //     return 1;
3993 // }
3994 int SecWhiteBalance::WBCorrectVC(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
3995 {
3996     if (bitmap2==NULL||bitmap1==bitmap2)
3997     {
3998         return WBCorrect1VC(bitmap1,fRateV, fRateR, fRateG, fRateB);
3999     }
4000     else 
4001     {
4002         return WBCorrect2VC(bitmap1,bitmap2,fRateV, fRateR, fRateG, fRateB);
4003     }
4004     return 0;
4005 }
4006
4007 int SecWhiteBalance::WBCorrect1VC(Gdiplus::Bitmap * bitmap1,float fRateV, float fRateR, float fRateG, float fRateB)
4008 {
4009     if (this->wbcorrloaded==0) {return 0;}
4010     double tick0=GetTickCountmS();
4011     int i,j,k;
4012     if (bitmap1==NULL)
4013     {return 0;}
4014     int w,h;
4015     w=bitmap1->GetWidth();
4016     h=bitmap1->GetHeight();
4017     if (0==w||0==h) 
4018     {return 0;}
4019     Gdiplus::BitmapData bitmapdata0;
4020     UINT * pixels;
4021     Gdiplus::Rect rect0(0,0,w,h);
4022     //    UINT * pixels2;
4023     COLOR * c2;
4024     Gdiplus::Status    GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead|Gdiplus::ImageLockModeWrite,PixelFormat32bppRGB,&bitmapdata0);
4025     if (GdipStatus!=Gdiplus::Ok)
4026     {
4027         CString Errs1;
4028         Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
4029         //        SysLog(Errs1);
4030         return 0;
4031     }
4032     pixels=(UINT *)bitmapdata0.Scan0 ;
4033     int s=bitmapdata0.Stride/4;
4034     int yoff,ystep,xoff,xstep;
4035     int offset;
4036     float wbR,wbG,wbB;
4037     short int R,G,B;
4038     short int wbRcorr,wbGcorr,wbBcorr;
4039     //    if (0) 
4040     for (i=0;i<wbysecs;i++)
4041
4042     {    yoff=i*h/wbysecs;
4043         ystep=(i+1)*h/wbysecs-yoff;
4044         for (j=0;j<wbxsecs;j++)
4045         {
4046             xoff=j*w/wbxsecs;
4047             xstep=(j+1)*w/wbxsecs-xoff;
4048             wbR=wbsecR[i][j];
4049             wbG=wbsecG[i][j];
4050             wbB=wbsecB[i][j];
4051             if (wbR<32) {wbR=32;}
4052             if (wbG<32) {wbG=32;}
4053             if (wbB<32) {wbB=32;}
4054             if (TargetLight==0)
4055             {
4056                 wbRcorr=int(128.0f*wbaveV*fRateV/wbR);
4057                 wbGcorr=int(128.0f*wbaveV*fRateV/wbG);
4058                 wbBcorr=int(128.0f*wbaveV*fRateV/wbB);
4059             }
4060             else if (TargetLightR*TargetLightG*TargetLightB==0)
4061             {
4062                 wbRcorr=int(128.0f*TargetLight*fRateV/wbR);
4063                 wbGcorr=int(128.0f*TargetLight*fRateV/wbG);
4064                 wbBcorr=int(128.0f*TargetLight*fRateV/wbB);
4065             }else
4066             {
4067                 wbRcorr=int(128.0f*TargetLightR*fRateR/wbR);
4068                 wbGcorr=int(128.0f*TargetLightG*fRateG/wbG);
4069                 wbBcorr=int(128.0f*TargetLightB*fRateB/wbB);
4070             }
4071             //wbRcorr=0;
4072             //wbGcorr=0;
4073             //wbBcorr=0;
4074                 for (k=0;k<ystep;k++)
4075                 {    
4076                     offset=(yoff+k)*s+xoff;
4077                 
4078                     //continue;
4079                         c2=(COLOR *)(pixels+offset);
4080                     for (int l=0;l<xstep;l++)
4081                     {//    pixels2=pixels+offset+l;
4082                         //continue;
4083                         R=c2->R*wbRcorr>>7;
4084                         c2->R=min(255,R);
4085                         G=c2->G*wbGcorr>>7;
4086                         c2->G=min(255,G);
4087                         B=c2->B*wbBcorr>>7;
4088                         c2->B =min(255,B);
4089                     //    c2->R=0;
4090                         c2++;
4091                     }
4092                 }
4093         }
4094     }
4095     bitmap1->UnlockBits(&bitmapdata0);
4096     double tick1=GetTickCountmS();
4097     return 1;
4098 }
4099 int SecWhiteBalance::WBCorrect2VC(Gdiplus::Bitmap * bitmap1,Gdiplus::Bitmap * bitmap2,float fRateV, float fRateR, float fRateG, float fRateB)
4100 {
4101     return 1;
4102 }
4103
4104 int SecWhiteBalance::WBBayerCorrect(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
4105 {
4106     return WBBayerCorrectVC(Image1, Image2, fRateV, fRateR, fRateG, fRateB);
4107 }
4108 int SecWhiteBalance::WBBayerCorrectVC(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
4109 {
4110     if (Image2==NULL||Image1==Image2)
4111     {
4112         return WBBayerCorrect1VC(Image1->buffer,Image1->GetWidth(),Image1->GetHeight(),Image1->Stride, fRateV, fRateR, fRateG, fRateB);
4113     }
4114     else 
4115     {
4116         return WBBayerCorrect2VC(Image1,Image2,fRateV, fRateR, fRateG, fRateB);
4117     }
4118     return 0;
4119 }
4120 int SecWhiteBalance::WBBayerCorrect1VC(void * buf1,int w,int h,int stride,float fRateV, float fRateR, float fRateG, float fRateB)
4121 {
4122     if (this->wbcorrloaded==0) {return 0;}
4123     double tick0=GetTickCountmS();
4124     int i,j,k;
4125     if (buf1==NULL)    {return 0;}
4126 //    int w,h;
4127 //    w=Image1->GetWidth();
4128 //    h=Image1->GetHeight();
4129     if (0==w||0==h) 
4130     {return 0;}
4131 //    Gdiplus::BitmapData bitmapdata0;
4132     unsigned char * pixels;
4133     pixels=(unsigned char *)buf1 ;
4134     int yoff,ystep,xoff,xstep;
4135     int offset;
4136 //    float wbR,wbG,wbB,wbG2;
4137     short int R,G,B,G2;
4138     short int wbRcorr,wbGcorr,wbBcorr,wbG2corr;
4139
4140     for (i=0;i<wbysecs;i++)
4141     {    yoff=i*(h/2)/wbysecs*2;
4142         ystep=(i+1)*(h/2)/wbysecs*2-yoff;
4143         for (j=0;j<wbxsecs;j++)
4144         {
4145             xoff=j*(w/2)/wbxsecs*2;
4146             xstep=(j+1)*(w/2)/wbxsecs*2-xoff;
4147             wbRcorr=wbsecRcorr[i][j]*fRateR;
4148             wbGcorr=wbsecGcorr[i][j]*fRateG;
4149             wbBcorr=wbsecBcorr[i][j]*fRateB;
4150             wbG2corr=wbsecG2corr[i][j]*fRateG;
4151             for (k=0;k<ystep;k+=2)
4152             {    
4153                 offset=(yoff+k)*stride+xoff;
4154                 unsigned char * c2;
4155                 //continue;
4156                 c2=(unsigned char *)(pixels+offset);
4157                 for (int l=0;l<xstep;l+=2)
4158                 {//    pixels2=pixels+offset+l;
4159                     //continue;
4160
4161                     G=(pixels[offset+l]*wbGcorr+64)/128;
4162                     pixels[offset+l]=min(255,G);;
4163                     R=(pixels[offset+l+1]*wbRcorr+64)/128;
4164                     pixels[offset+l+1]=min(255,R);
4165                     B=(pixels[offset+stride+l]*wbBcorr+64)/128;
4166                     pixels[offset+stride+l]=min(255,B);
4167                     G2=(pixels[offset+stride+l+1]*wbG2corr+64)/128;
4168                     pixels[offset+stride+l+1]=min(255,G2);
4169                 }
4170             }
4171         }
4172     }
4173     double tick1=GetTickCountmS();
4174     return 0;
4175 }
4176 int SecWhiteBalance::WBBayerCorrect2VC(MyImage * Image1,MyImage * Image2,float fRateV, float fRateR, float fRateG, float fRateB)
4177 {
4178     if (this->wbcorrloaded==0) {return -1;}
4179     double tick0=GetTickCountmS();
4180     int i,j,k;
4181     if (Image1==NULL)    {return -1;}
4182     if (!Image1->IsValid) {return -1;}
4183     int w,h;
4184     w=Image1->GetWidth();
4185     h=Image1->GetHeight();
4186     if (0==w||0==h) 
4187     {return 0;}
4188     int w2,h2;
4189     if (Image2==NULL) {return -1;}
4190     if (!Image2->IsValid){Image2->AllocBuf(w,h,w,MyImage::MyPixelType_BayerGR8);}
4191     w2=Image2->GetWidth();h2=Image2->GetHeight();
4192     if (w!=w2||h!=h2) {Image2->AllocBuf(w,h,w,MyImage::MyPixelType_BayerGR8);}
4193     unsigned char * pixels;
4194     pixels=(unsigned char *)Image1->GetBuffer();
4195     unsigned char * pixels2;
4196     pixels2=(unsigned char *)Image2->GetBuffer();
4197     int stride=Image1->GetStride();
4198     int yoff,ystep,xoff,xstep;
4199     int offset;
4200 //    float wbR,wbG,wbB,wbG2;
4201     short int R,G,B,G2;
4202     short int wbRcorr,wbGcorr,wbBcorr,wbG2corr;
4203
4204     for (i=0;i<wbysecs;i++)
4205     {    yoff=i*(h/2)/wbysecs*2;
4206         ystep=(i+1)*(h/2)/wbysecs*2-yoff;
4207         for (j=0;j<wbxsecs;j++)
4208         {
4209             xoff=j*(w/2)/wbxsecs*2;
4210             xstep=(j+1)*(w/2)/wbxsecs*2-xoff;
4211
4212             wbRcorr=wbsecRcorr[i][j]*fRateR;
4213             wbGcorr=wbsecGcorr[i][j]*fRateG;
4214             wbBcorr=wbsecBcorr[i][j]*fRateB;
4215             wbG2corr=wbsecG2corr[i][j]*fRateG;
4216             for (k=0;k<ystep;k+=2)
4217             {    
4218                 offset=(yoff+k)*stride+xoff;
4219                 unsigned char * c2;
4220                 //continue;
4221                 c2=(unsigned char *)(pixels+offset);
4222                 for (int l=0;l<xstep;l+=2)
4223                 {//    pixels2=pixels+offset+l;
4224                     //continue;
4225                     G=(pixels[offset+l]*wbGcorr+64)/128;
4226                     pixels2[offset+l]=min(255,G);;
4227                     R=(pixels[offset+l+1]*wbRcorr+64)/128;
4228                     pixels2[offset+l+1]=min(255,R);
4229                     B=(pixels[offset+stride+l]*wbBcorr+64)/128;
4230                     pixels2[offset+stride+l]=min(255,B);
4231                     G2=(pixels[offset+stride+l+1]*wbG2corr+64)/128;
4232                     pixels2[offset+stride+l+1]=min(255,G2);
4233                 }
4234             }
4235         }
4236     }
4237     double tick1=GetTickCountmS();
4238     return 0;
4239     return -1;
4240 }
4241
4242 int AveFilter(int inCount, int FilterSize, double inbuf[], double outbuf[])
4243 {
4244     return inCount;
4245 }
4246 int MidFilter(int inCount, int FilterSize, double inbuf[], double outbuf[])
4247 {
4248     return inCount;
4249 }
4250 int juanji(int incount,int corecount,double inbuf[], double outbuf[],double corebuf[])
4251 {
4252     int i,j;
4253     int k1=(corecount)/2;
4254     int k2=(corecount+1)/2;
4255     int l;
4256     double sum1;
4257     for (i=0;i<k1;i++)        //起始边缘处理
4258     {
4259         sum1=0;
4260         for (j=0;j<corecount;j++)
4261         {
4262             l=i-k1+j;
4263             if (l<0) {l=0;}
4264             sum1+=inbuf[l]*corebuf[j];
4265         }
4266         outbuf[i]=sum1;
4267     }
4268     for (i=k1;i<incount-k1;i++)        //正常值处理
4269     {
4270         sum1=0;
4271         for (j=0;j<corecount;j++)
4272         {
4273             l=i-k1+j;
4274             sum1+=inbuf[l]*corebuf[j];
4275         }
4276         outbuf[i]=sum1;
4277     //    outbuf[i]=inbuf[i];
4278     }
4279     for (i=incount-k1;i<incount;i++)    //结束边缘处理
4280     {
4281         sum1=0;
4282         for (j=0;j<corecount;j++)
4283         {
4284             l=i-k1+j;
4285             if (l>incount-1) {l=incount-1;}
4286             sum1+=inbuf[l]*corebuf[j];
4287         }
4288         outbuf[i]=sum1;
4289     }
4290     return i;
4291 }
4292
4293 int juanjiV(int incount,int corecount,int stride, int x, double inbuf[], double outbuf[],double corebuf[])
4294 {
4295     int i,j;
4296     int k1=(corecount)/2;
4297     int l;
4298     double sum1;
4299     for (i=0;i<incount;i++)
4300     {
4301         sum1=0;
4302         for (j=0;j<corecount;j++)
4303         {
4304             l=i-k1+j;
4305             if (l<0)
4306             {
4307                 l=0;
4308             }
4309             if (l>incount-1)
4310             {
4311                 l=incount-1;
4312             }
4313             sum1+=inbuf[l*stride + x]*corebuf[j];
4314         }
4315         outbuf[i*stride + x]=sum1;
4316     }
4317
4318     return i;
4319 }
4320
4321 int juanji2D(double inbuf[], int sizex, int sizey, int stride, double outbuf[], double corebuf[], int coresizex, int coresizey, int corestrie)
4322 {
4323     int halfcorex=coresizex/2;
4324     int halfcorey=coresizey/2;
4325
4326     //for (int i = 0; i < sizey; i++)        
4327     //{
4328     //    int l0 = i*stride;
4329     //    int startcory = (i - halfcorey < 0) ? halfcorey - i : 0;
4330     //    int endcory = (i + coresizey - 1 >= sizey) ? coresizey - (i + coresizey - sizey) : coresizey;
4331     //    for (int j = 0; j < sizex; j++)    
4332     //    {
4333     //        int startcorx = (j - halfcorex < 0) ? halfcorex - j : 0;;
4334     //        int endcorx = (j + coresizex - 1 >= sizex) ? coresizex - (j + coresizex - sizex) : coresizex;
4335     //        int l1 = l0 + j;
4336     //        outbuf[l1] = 0;
4337     //        for (int k = startcory; k < endcory; k++)
4338     //        {
4339     //            int l2 = l1 + (k - halfcorey)*stride;
4340
4341     //            for (int l = startcorx; l < endcorx; l++)
4342     //            {
4343     //                outbuf[l1] += inbuf[l2 + (l - halfcorex)] * corebuf[k*corestrie + l];
4344     //            }
4345     //        }
4346
4347     //    }
4348     //}
4349
4350     for (int i = 0; i < halfcorey; i++)
4351     {
4352         int l0 = i*stride;
4353         for (int j = 0; j < halfcorex; j++) outbuf[l0 + j] = 0;
4354         for (int j = sizex-halfcorex; j < sizex; j++) outbuf[l0 + j] = 0;
4355     }
4356
4357     for (int i = sizey-halfcorey; i < sizey; i++)
4358     {
4359         int l0 = i*stride;
4360         for (int j = 0; j < halfcorex; j++) outbuf[l0 + j] = 0;
4361         for (int j = sizex - halfcorex; j < sizex; j++) outbuf[l0 + j] = 0;
4362     }
4363
4364     for (int i=halfcorey;i<sizey-halfcorey;i++)        //正常运算
4365     {
4366         int l0=i*stride;
4367         for (int j=halfcorex;j<sizex-halfcorex;j++)
4368         {
4369             int l1=l0+j;
4370             outbuf[l1]=0;
4371             for (int k=0;k<coresizey;k++)
4372             {
4373                 int l2=l1+(k-halfcorey)*stride;
4374                 for (int l=0;l<coresizex;l++)
4375                 {
4376                     outbuf[l1]+=inbuf[l2+(l-halfcorex)]*corebuf[k*corestrie+l];
4377                 }
4378             }
4379         }
4380     }
4381
4382     return sizex*sizey;
4383 }
4384 // template <typename T>
4385 // int juanji2D3x3(T inbuf[], int sizex, int sizey, int stride, T outbuf[], T corebuf[3][3])
4386 // {
4387 // 
4388 //     for (int i=1;i<sizey-1;i++)        //正常运算//内部区域
4389 //     {
4390 //         int l0=(i-1)*stride;
4391 //         int l1=(i)*stride;
4392 //         int l2=(i+1)*stride;
4393 //         for (int j=1;j<sizex-1;j++)
4394 //         {
4395 //             T a1,a2,a3;
4396 //             a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
4397 //             a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
4398 //             a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
4399 //             outbuf[l1+j]=a1+a2+a3;
4400 //         }
4401 //     }
4402 //     for (int i=0;i<1;i++)        //处理边缘,上边缘,不包括左上角和右上角;
4403 //     {
4404 //         int l1=(i)*stride;
4405 //         int l2=(i+1)*stride;
4406 //         for (int j=1;j<sizex-1;j++)
4407 //         {
4408 //             outbuf[l1+j]=outbuf[l2+j];
4409 //         }
4410 //     }
4411 //     for (int i=sizey-1;i<sizey;i++)        //下边缘,不包括左下角和右下角
4412 //     {
4413 //         int l0=(i-1)*stride;
4414 //         int l1=(i)*stride;
4415 // 
4416 //         for (int j=1;j<sizex-1;j++)
4417 //         {
4418 //             outbuf[l1+j]=outbuf[l0+j];
4419 //         }
4420 //     }
4421 //     for (int i=1;i<sizey-1;i++)        //左边缘,不包括左上角和左下角
4422 //     {
4423 //         int l=(i)*stride;
4424 //         for (int j=0;j<1;j++)
4425 //         {
4426 //             outbuf[l+j]=outbuf[l+j+1];
4427 //         }
4428 //     }
4429 //     for (int i=1;i<sizey-1;i++)        //右边缘,不包括右上角和右下角
4430 //     {
4431 //         int l=(i)*stride;
4432 //         for (int j=sizex-1;j<sizex;j++)
4433 //         {
4434 //             outbuf[l+j]=outbuf[l+j-1];
4435 //         }
4436 //     }
4437 //     //四个角
4438 //     for (int i=0;i<1;i++)
4439 //     {
4440 //         int l1=(i)*stride;
4441 //         int l2=(i+1)*stride;
4442 //         for (int j=0;j<1;j++)
4443 //         {
4444 //             T a1,a2,a3;
4445 //             outbuf[l1+j]=(outbuf[l2+j]+outbuf[l1+j+1])/2;
4446 //         }
4447 //         for (int j=sizex-1;j<sizex;j++)
4448 //         {
4449 //             outbuf[l1+j]=(outbuf[l2+j]+outbuf[l1+j-1])/2;
4450 //         }
4451 //     }
4452 //     for (int i=sizey-1;i<sizey;i++)
4453 //     {
4454 //         int l0=(i-1)*stride;
4455 //         int l1=(i)*stride;
4456 //         for (int j=0;j<1;j++)
4457 //         {
4458 //             
4459 //             outbuf[l1+j]=(outbuf[l0+j]+outbuf[l1+j+1])/2;
4460 //         }
4461 //         for (int j=sizex-1;j<sizex;j++)
4462 //         {
4463 //             outbuf[l1+j]=(outbuf[l0+j]+outbuf[l1+j-1])/2;
4464 //         }
4465 //     }
4466 // 
4467 //     return sizex*sizey;
4468 // }
4469 template <typename T>
4470 int juanji2D3x3(T inbuf[], int sizex, int sizey, int stride, T outbuf[], T corebuf[3][3])
4471 {
4472
4473     for (int i=1;i<sizey-1;i++)        //正常运算//内部区域
4474     {
4475         int l0=(i-1)*stride;
4476         int l1=(i)*stride;
4477         int l2=(i+1)*stride;
4478         for (int j=1;j<sizex-1;j++)
4479         {
4480             T a1,a2,a3;
4481         //    __m256 m1,m2,m3;
4482         //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4483         //    m2=_mm256_loadu_ps(&corebuf);
4484                 a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
4485                 a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
4486                 a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
4487                 outbuf[l1+j]=a1+a2+a3;
4488         }
4489     }
4490     for (int i=0;i<1;i++)        //处理边缘,上边缘,不包括左上角和右上角;
4491     {
4492 //        int l0=(i)*stride;
4493         int l1=(i)*stride;
4494         int l2=(i+1)*stride;
4495         for (int j=1;j<sizex-1;j++)
4496         {
4497             T a1,a2,a3;
4498             //    __m256 m1,m2,m3;
4499             //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4500             //    m2=_mm256_loadu_ps(&corebuf);
4501             a1=(inbuf[l1+j-1]*2-inbuf[l2+j-1])*corebuf[0][0]+(inbuf[l1+j]*2-inbuf[l2+j])*corebuf[0][1]+(inbuf[l1+j+1]*2-inbuf[l2+j+1])*corebuf[0][2];
4502             a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
4503             a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
4504             outbuf[l1+j]=a1+a2+a3;
4505         }
4506     }
4507     for (int i=sizey-1;i<sizey;i++)        //下边缘,不包括左下角和右下角
4508     {
4509         int l0=(i-1)*stride;
4510         int l1=(i)*stride;
4511 //        int l2=(i)*stride;
4512
4513         for (int j=1;j<sizex-1;j++)
4514         {
4515             T a1,a2,a3;
4516             //    __m256 m1,m2,m3;
4517             //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4518             //    m2=_mm256_loadu_ps(&corebuf);
4519             a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
4520             a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
4521             a3=(inbuf[l1+j-1]*2-inbuf[l0+j-1])*corebuf[2][0]+(inbuf[l1+j]*2-inbuf[l0+j])*corebuf[2][1]+(inbuf[l1+j+1]*2-inbuf[l0+j+1])*corebuf[2][2];
4522             outbuf[l1+j]=a1+a2+a3;
4523         }
4524     }
4525     for (int i=1;i<sizey-1;i++)        //左边缘,不包括左上角和左下角
4526     {
4527         int l0=(i-1)*stride;
4528         int l1=(i)*stride;
4529         int l2=(i+1)*stride;
4530         for (int j=0;j<1;j++)
4531         {
4532             T a1,a2,a3;
4533             //    __m256 m1,m2,m3;
4534             //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4535             //    m2=_mm256_loadu_ps(&corebuf);
4536             a1=(inbuf[l0+j]*2-inbuf[l0+j+1])*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
4537             a2=(inbuf[l1+j]*2-inbuf[l1+j+1])*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
4538             a3=(inbuf[l2+j]*2-inbuf[l2+j+1])*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
4539             outbuf[l1+j]=a1+a2+a3;
4540         }
4541     }
4542     for (int i=1;i<sizey-1;i++)        //右边缘,不包括右上角和右下角
4543     {
4544         int l0=(i-1)*stride;
4545         int l1=(i)*stride;
4546         int l2=(i+1)*stride;
4547         for (int j=sizex-1;j<sizex;j++)
4548         {
4549             T a1,a2,a3;
4550             //    __m256 m1,m2,m3;
4551             //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4552             //    m2=_mm256_loadu_ps(&corebuf);
4553             a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+(inbuf[l0+j]*2-inbuf[l0+j-1])*corebuf[0][2];
4554             a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+(inbuf[l1+j]*2-inbuf[l1+j-1])*corebuf[1][2];
4555             a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+(inbuf[l2+j]*2-inbuf[l2+j-1])*corebuf[2][2];
4556             outbuf[l1+j]=a1+a2+a3;
4557         }
4558     }
4559     //四个角
4560     for (int i=0;i<1;i++)
4561     {
4562         int l0=(i)*stride;
4563         int l1=(i)*stride;
4564         int l2=(i+1)*stride;
4565         for (int j=0;j<1;j++)
4566         {
4567             T a1,a2,a3;
4568             //    __m256 m1,m2,m3;
4569             //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4570             //    m2=_mm256_loadu_ps(&corebuf);
4571             a1=inbuf[l0+j]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
4572             a2=inbuf[l1+j]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
4573             a3=inbuf[l2+j]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
4574             outbuf[l1+j]=a1+a2+a3;
4575         }
4576         for (int j=sizex-1;j<sizex;j++)
4577         {
4578             T a1,a2,a3;
4579             //    __m256 m1,m2,m3;
4580             //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4581             //    m2=_mm256_loadu_ps(&corebuf);
4582             a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
4583             a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
4584             a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
4585             outbuf[l1+j]=a1+a2+a3;
4586         }
4587     }
4588     for (int i=sizey-1;i<sizey;i++)
4589     {
4590         int l0=(i-1)*stride;
4591         int l1=(i)*stride;
4592         int l2=(i)*stride;
4593         for (int j=0;j<1;j++)
4594         {
4595             T a1,a2,a3;
4596             //    __m256 m1,m2,m3;
4597             //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4598             //    m2=_mm256_loadu_ps(&corebuf);
4599             a1=inbuf[l0+j]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
4600             a2=inbuf[l1+j]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
4601             a3=inbuf[l2+j]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
4602             outbuf[l1+j]=a1+a2+a3;
4603         }
4604         for (int j=sizex-1;j<sizex;j++)
4605         {
4606             T a1,a2,a3;
4607             //    __m256 m1,m2,m3;
4608             //    m1=_mm256_loadu_ps(&inbuf[l1+j-1]);
4609             //    m2=_mm256_loadu_ps(&corebuf);
4610             a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j]*corebuf[0][2];
4611             a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j]*corebuf[1][2];
4612             a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j]*corebuf[2][2];
4613             outbuf[l1+j]=a1+a2+a3;
4614         }
4615     }
4616
4617     return sizex*sizey;
4618 }
4619 template<> int juanji2D3x3(float inbuf[], int sizex, int sizey, int stride, float outbuf[], float corebuf[3][3])
4620 {
4621     __m256 km1,km2,km3;
4622     km1=_mm256_loadu_ps(corebuf[0]);
4623     km2=_mm256_loadu_ps(corebuf[1]);
4624     km3=_mm256_loadu_ps(corebuf[2]);
4625     km1=_mm256_shuffle_ps(km2,km3,0x4e);
4626 //    _mm256_rsqrt_ps()
4627     for (int i=1;i<sizey-1;i++)        //正常运算
4628     {
4629         int l0=(i-1)*stride;
4630         int l1=(i)*stride;
4631         int l2=(i+1)*stride;
4632         for (int j=1;j<sizex-1;j++)
4633         {
4634             float a1,a2,a3;
4635 //            __m256 m1,m2,m3,m4,m5,m6;
4636 //            m1=_mm256_loadu_ps(&inbuf[l0+j-1]);
4637 //            m2=_mm256_loadu_ps(&inbuf[l1+j-1]);
4638 //            m4=_mm256_mul_ps(m1,km1);
4639 //            m3=_mm256_loadu_ps(&inbuf[l2+j-1]);
4640 //            m5=_mm256_mul_ps(m2,km2);
4641 //            m6=_mm256_mul_ps(m3,km3);
4642 //            m1=_mm256_add_ps(m4,m5);
4643 //            m1=_mm256_add_ps(m1,m6);
4644 //            a1=m1.m256_f32[0];a2=m1.m256_f32[1];a3=m1.m256_f32[2];
4645             a1=inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2];
4646
4647             a2=inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2];
4648             a3=inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
4649
4650             outbuf[l1+j]=a1+a2+a3;
4651         }
4652     }
4653     for (int i=0;i<1;i++)        //处理边缘,所有的边缘等于0;
4654     {
4655         int l1=(i)*stride;
4656         for (int j=0;j<sizex;j++)
4657         {
4658             outbuf[l1+j]=0;
4659         }
4660     }
4661     for (int i=sizey-1;i<sizey;i++)
4662     {
4663         int l1=(i)*stride;
4664         for (int j=0;j<sizex;j++)
4665         {
4666             outbuf[l1+j]=0;
4667         }
4668     }
4669     for (int i=0;i<sizey;i++)
4670     {
4671         int l1=(i)*stride;
4672         for (int j=0;j<1;j++)
4673         {
4674             outbuf[l1+j]=0;
4675         }
4676     }
4677     for (int i=0;i<sizey;i++)
4678     {
4679         int l1=(i)*stride;
4680         for (int j=sizex-1;j<sizex;j++)
4681         {
4682             outbuf[l1+j]=0;
4683         }
4684     }
4685     return sizex*sizey;
4686 }
4687 void dummy1(void)
4688 {
4689     double a[1];
4690     double b[3][3];
4691     juanji2D3x3(a,1,1,1,a,b);
4692     float c[1];
4693     float d[3][3];
4694     juanji2D3x3(c,1,1,1,c,d);
4695 }
4696
4697 int DCT(double pt[], double dpt[],int size,int start,int end)
4698 {
4699     if (size&1) {size=size-1;}
4700     dpt[0]=0;
4701     for (int j=0;j<size;j++)
4702     {
4703         dpt[0]+=pt[j];
4704     }
4705     dpt[0]/=sqrt(double(size));
4706     for (int i=start;i<=end;i++)
4707     {
4708         dpt[i]=0;
4709         for (int j=0;j<size;j++)
4710         {
4711             dpt[i]+=pt[j]*cos((2*j+1)*i*3.1415926535897932384626433/(2*size));
4712         }
4713         dpt[i]/=sqrt(double(size)/2);
4714     }
4715     return 1;
4716 }
4717
4718 int DCT(float pt[], float dpt[],int size,int start,int end)
4719 {
4720     if (size&1) {size=size-1;}
4721     dpt[0]=0;
4722     for (int j=0;j<size;j++)
4723     {
4724         dpt[0]+=pt[j];
4725     }
4726     dpt[0]/=sqrt(float(size));
4727     for (int i=start;i<end;i++)
4728     {
4729         dpt[i]=0;
4730         for (int j=0;j<size;j++)
4731         {
4732             dpt[i]+=pt[j]*cos((2*j+1)*i*3.1415926535897932384626433f/2/size);
4733         }
4734         dpt[i]/=sqrt(float(size)/2);
4735     }
4736     return 1;
4737 }
4738
4739 int FDCT(double pt[], double dpt[],int size,int start,int end)
4740 {
4741     if (size&1) {size=size-1;}
4742     double * costab=new double[4*size+4];
4743     for (int i=0;i<=size;i++)
4744     {//计算余弦表
4745         double result1=cos(i*3.1415926535897932384626433/2/size);
4746         costab[i]=result1;
4747         costab[2*size-i]=-result1;
4748         costab[2*size+i]=-result1;
4749         costab[4*size-i]=result1;
4750     }
4751
4752     dpt[0]=0;
4753     for (int j=0;j<size;j++)
4754     {
4755         dpt[0]+=pt[j];
4756     }
4757     dpt[0]/=sqrt(double(size));
4758     for (int i=start;i<=end;i++)
4759     {
4760         dpt[i]=0;
4761         for (int j=0;j<size;j++)
4762         {
4763             dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)];
4764         }
4765         dpt[i]/=sqrt(double(size)/2);
4766     }
4767     delete [] costab;
4768     return 1;
4769 }
4770
4771 int FDCT(float pt[], float dpt[],int size,int start,int end)
4772 {
4773     if (size&1) {size=size-1;}
4774     dpt[0]=0;
4775     float * costab=new float[4*size+4];
4776     for (int i=0;i<size;i++)
4777     {//计算余弦表
4778         float result1=cosf(i*3.1415926535897932384626433f/2/size);
4779         costab[i]=result1;
4780         costab[2*size-i]=-result1;
4781         costab[2*size+i]=-result1;
4782         costab[4*size-i]=result1;
4783     }
4784
4785     for (int j=0;j<size;j++)
4786     {
4787         dpt[0]+=pt[j];
4788     }
4789     dpt[0]/=sqrt(float(size));
4790     for (int i=start;i<end;i++)
4791     {
4792         dpt[i]=0;
4793         for (int j=0;j<size;j++)
4794         {
4795             dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)];    //cos((2*j+1)*i*3.1415926f/2/size);
4796         }
4797         dpt[i]/=sqrt(float(size)/2);
4798     }
4799     delete [] costab;
4800     return 1;
4801 }
4802
4803 int FFDCT(double pt[], double dpt[],int size,int start,int end)
4804 {
4805     if (size&1) {size=size-1;}
4806     double * costab=new double[4*size+4];
4807     for (int i=0;i<size;i++)
4808     {//计算余弦表
4809         double result1=cos(i*3.1415926535897932384626433/2/size);
4810         costab[i]=result1;
4811         costab[2*size-i]=-result1;
4812         costab[2*size+i]=-result1;
4813         costab[4*size-i]=result1;
4814     }
4815
4816     dpt[0]=0;
4817     for (int j=0;j<size;j++)
4818     {
4819         dpt[0]+=pt[j];
4820     }
4821     dpt[0]/=sqrt(double(size));
4822     for (int i=start;i<=end;i++)
4823     {
4824         dpt[i]=0;
4825         int j;
4826         for (j=0;j<size-7;j+=8)
4827         {
4828             double temp[8];
4829             temp[0]=pt[j]*costab[(2*j+1)*i%(4*size)];
4830             temp[1]=pt[j+1]*costab[(2*j+3)*i%(4*size)];
4831             temp[2]=pt[j+2]*costab[(2*j+5)*i%(4*size)];
4832             temp[3]=pt[j+3]*costab[(2*j+7)*i%(4*size)];
4833             temp[4]=pt[j+4]*costab[(2*j+9)*i%(4*size)];
4834             temp[5]=pt[j+5]*costab[(2*j+11)*i%(4*size)];
4835             temp[6]=pt[j+6]*costab[(2*j+13)*i%(4*size)];
4836             temp[7]=pt[j+7]*costab[(2*j+15)*i%(4*size)];
4837
4838             dpt[i]+=temp[0]+temp[1]+temp[2]+temp[3]+temp[4]+temp[5]+temp[6]+temp[7];
4839         }
4840         for (;j<size;j++)
4841         {
4842             dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)];    //cos((2*j+1)*i*3.1415926f/2/size);
4843         }
4844         dpt[i]/=sqrt(double(size)/2);
4845     }
4846     delete [] costab;
4847     return 1;
4848 }
4849
4850 int FFDCT(float pt[], float dpt[],int size,int start,int end)
4851 {
4852     if (size&1) {size=size-1;}
4853     float * costab=new float[4*size];
4854     for (int i=0;i<size;i++)
4855     {//计算余弦表
4856         float result1=cosf(i*3.1415926535897932384626433f/2/size);
4857         costab[i]=result1;
4858         costab[2*size-1-i]=-result1;
4859         costab[2*size+i]=-result1;
4860         costab[4*size-1-i]=result1;
4861     }
4862
4863     dpt[0]=0;
4864     for (int j=0;j<size;j++)
4865     {
4866         dpt[0]+=pt[j];
4867     }
4868     dpt[0]/=sqrt(float(size));
4869     for (int i=start;i<=end;i++)
4870     {
4871         dpt[i]=0;
4872         int j;
4873         for (j=0;j<size-7;j+=8)
4874         {
4875             _CRT_ALIGN(32) float temp[8];
4876 //            _CRT_ALIGN(32) float results[8];
4877             temp[0]=pt[j]*costab[(2*j+1)*i%(4*size)];
4878             temp[1]=pt[j+1]*costab[(2*j+3)*i%(4*size)];
4879             temp[2]=pt[j+2]*costab[(2*j+5)*i%(4*size)];
4880             temp[3]=pt[j+3]*costab[(2*j+7)*i%(4*size)];
4881             temp[4]=pt[j+4]*costab[(2*j+9)*i%(4*size)];
4882             temp[5]=pt[j+5]*costab[(2*j+11)*i%(4*size)];
4883             temp[6]=pt[j+6]*costab[(2*j+13)*i%(4*size)];
4884             temp[7]=pt[j+7]*costab[(2*j+15)*i%(4*size)];
4885
4886 /*
4887             results[0]=costab[(2*j+1)*i%(2*size)];
4888             results[1]=costab[(2*j+3)*i%(2*size)];
4889             results[2]=costab[(2*j+5)*i%(2*size)];
4890             results[3]=costab[(2*j+6)*i%(2*size)];
4891             results[4]=costab[(2*j+9)*i%(2*size)];
4892             results[5]=costab[(2*j+11)*i%(2*size)];
4893             results[6]=costab[(2*j+13)*i%(2*size)];
4894             results[7]=costab[(2*j+15)*i%(2*size)];
4895             temp[0]=pt[j]*results[0];
4896             temp[1]=pt[j+1]*results[1];
4897             temp[2]=pt[j+2]*results[2];
4898             temp[3]=pt[j+3]*results[3];
4899             temp[4]=pt[j+4]*results[4];
4900             temp[5]=pt[j+5]*results[5];
4901             temp[6]=pt[j+6]*results[6];
4902             temp[7]=pt[j+7]*results[7];
4903 */
4904 //            __m256 a,b,c;
4905 //            a=_mm256_loadu_ps(&pt[j]);
4906 //            b=_mm256_loadu_ps(results);
4907 //            c=_mm256_mul_ps(a,b);
4908 //            _mm256_storeu_ps(temp,c);
4909             dpt[i]+=temp[0]+temp[1]+temp[2]+temp[3]+temp[4]+temp[5]+temp[6]+temp[7];
4910 //            dpt[i]+=((temp[0]+temp[1])+(temp[2]+temp[3]))+((temp[4]+temp[5])+(temp[6]+temp[7]));
4911         }
4912         for (;j<size;j++)
4913         {
4914             dpt[i]+=pt[j]*costab[(2*j+1)*i%(4*size)];    //cos((2*j+1)*i*3.1415926f/2/size);
4915         }
4916         dpt[i]/=sqrt(float(size)/2);
4917     }
4918     delete [] costab;
4919     return 1;
4920 }
4921
4922 /*
4923 int juanji2D3x3(float inbuf[], int sizex, int sizey, int stride, float outbuf[], float corebuf[3][3])
4924 {
4925
4926     for (int i=1;i<sizey-1;i++)        //正常运算
4927     {
4928         int l0=(i-1)*stride;
4929         int l1=(i)*stride;
4930         int l2=(i+1)*stride;
4931         for (int j=1;j<sizex-1;j++)
4932         {
4933             outbuf[l1+j]=
4934                 inbuf[l0+j-1]*corebuf[0][0]+inbuf[l0+j]*corebuf[0][1]+inbuf[l0+j+1]*corebuf[0][2]+
4935                 inbuf[l1+j-1]*corebuf[1][0]+inbuf[l1+j]*corebuf[1][1]+inbuf[l1+j+1]*corebuf[1][2]+
4936                 inbuf[l2+j-1]*corebuf[2][0]+inbuf[l2+j]*corebuf[2][1]+inbuf[l2+j+1]*corebuf[2][2];
4937         }
4938     }
4939     for (int i=0;i<1;i++)        //处理边缘,所有的边缘等于0;
4940     {
4941         int l1=(i)*stride;
4942         for (int j=0;j<sizex;j++)
4943         {
4944             outbuf[l1+j]=0;
4945         }
4946     }
4947     for (int i=sizey-1;i<sizey;i++)
4948     {
4949         int l1=(i)*stride;
4950         for (int j=0;j<sizex;j++)
4951         {
4952             outbuf[l1+j]=0;
4953         }
4954     }
4955     for (int i=0;i<sizey;i++)
4956     {
4957         int l1=(i)*stride;
4958         for (int j=0;j<1;j++)
4959         {
4960             outbuf[l1+j]=0;
4961         }
4962     }
4963     for (int i=0;i<sizey;i++)
4964     {
4965         int l1=(i)*stride;
4966         for (int j=sizex-1;j<sizex;j++)
4967         {
4968             outbuf[l1+j]=0;
4969         }
4970     }
4971     return sizex*sizey;
4972 }
4973 */
4974 int nihe(CPoint pt5[100],int pt5total,int pt5valid[100])
4975 {
4976     int i,j,k;//,l;
4977     int startpt,endpt;
4978     double angle1,angle2;
4979     double distance,intercept;
4980     double maxintercept=3;
4981     double totalintercept;
4982     int validpts;
4983     int maxstartpt,maxendpt;
4984     int maxvalidpts;
4985     double minintercept;
4986     maxvalidpts=0;
4987     int ptvalid[100];
4988     maxstartpt=0;
4989     maxendpt=1;
4990
4991     for (i=0;i<pt5total;i++)
4992     {
4993         ptvalid[i]=0;
4994     }
4995
4996     for (i=0;i<pt5total-1;i++)
4997     {
4998         startpt=i;
4999         ptvalid[i]=1;
5000         for (j=i+1;j<pt5total;j++)
5001         {
5002             validpts=0;
5003             endpt=j;
5004             angle1=atan(((double)pt5[i].x-pt5[j].x)/((double)pt5[i].y-pt5[j].y));
5005             totalintercept=0;
5006             ptvalid[j]=1;
5007             for (k=0;k<pt5total;k++)
5008             {
5009                 if (k==i) {continue;}
5010                 if (k==j) {continue;}
5011                 angle2=atan(((double)pt5[i].x-pt5[k].x)/((double)pt5[i].y-pt5[k].y));
5012                 distance=sqrt((double)(pt5[i].x-pt5[k].x)*(pt5[i].x-pt5[k].x)+(pt5[i].y-pt5[k].y)*(pt5[i].y-pt5[k].y));
5013                 intercept=distance*sin(abs(angle2-angle1));
5014                 if (intercept<maxintercept)
5015                 {
5016                     ptvalid[k]=1;
5017                     validpts++;
5018                     totalintercept+=intercept;
5019                 }
5020                 else
5021                 {
5022                     ptvalid[k]=0;
5023                 }
5024             }
5025             if ((validpts>maxvalidpts)||(validpts==maxvalidpts&&totalintercept<minintercept))
5026             {
5027                 maxvalidpts=validpts;
5028                 maxstartpt=startpt;
5029                 maxendpt=endpt;
5030                 minintercept=totalintercept;
5031                 for (k=0;k<pt5total;k++)
5032                 {
5033                     pt5valid[k]=ptvalid[k];
5034                 }
5035
5036             }
5037             ptvalid[j]=0;
5038         }
5039         ptvalid[i]=0;
5040     }
5041     return MAKELONG(maxstartpt,maxendpt);
5042 }
5043
5044 UINT __cdecl memcpyThread(LPVOID pParam)
5045 {
5046     MemcpyThreadDataStruct * p1=(MemcpyThreadDataStruct *)pParam;
5047     void * dest2,*src2;
5048     unsigned long size_t2;
5049     dest2=p1->dest;
5050     src2=p1->src;
5051     size_t2=p1->size;
5052     X_aligned_memcpy_sse2(dest2, src2, size_t2);
5053     p1->done=1;
5054     return 1000;
5055 }
5056
5057 void fastmemcpy(void* dest, const void* src, const unsigned long size_t)
5058 {
5059     void * dest2,* src2;
5060     unsigned long size_t2;
5061     src2=(void *)src;
5062     dest2=dest;
5063     size_t2=size_t;
5064     if (((UINT)dest)&0xf)
5065     {
5066         UINT delta;
5067
5068         dest2=(void *)((((UINT)dest)+15)&0xfffffff0);
5069         delta=(UINT)dest2-(UINT)dest;
5070         size_t2-=delta;
5071         src=(void *)((UINT(src))+delta);
5072     }
5073
5074     X_aligned_memcpy_sse2(dest2, src2, size_t2);
5075 }
5076 void fastmemcpyMT(void* dest, const void* src, const unsigned long size_t)
5077 {
5078     MemcpyThreadDataStruct threaddata[2];
5079     threaddata[0].src=(void *)src;
5080     threaddata[0].dest=dest;
5081     threaddata[0].size=size_t/2;
5082     threaddata[0].done=0;
5083
5084     threaddata[1].src=(unsigned char *)src+size_t/2;
5085     threaddata[1].dest=(unsigned char *)dest+size_t/2;
5086     threaddata[1].size=size_t/2;
5087     threaddata[1].done=0;
5088     AfxBeginThread(memcpyThread,LPVOID(&threaddata[0]));
5089     AfxBeginThread(memcpyThread,LPVOID(&threaddata[1]));
5090     while(1)
5091     {
5092         if (threaddata[0].done&&threaddata[1].done) {break;}
5093     }
5094
5095
5096 }
5097
5098 int GetLineSegmentPart(double startx, double starty, double endx, double endy, double numerator, double denominator, double & x1, double & y1)
5099 {
5100
5101     x1=(startx*(denominator-numerator)+endx*numerator)/denominator;
5102     y1=(starty*(denominator-numerator)+endy*numerator)/denominator;
5103     return 1;
5104 }
5105
5106 double LineSegmentDirection(PointD pt1,PointD pt2,PointD pt3)
5107 {
5108     PointD d1,d2;
5109     d1=pt3-pt1;d2=pt2-pt1;
5110     return d1.x*d2.y-d1.y*d2.x;
5111
5112 }
5113 int IsOnLineSegment(MyLineSegment linesegment1,PointD pt1)
5114 {
5115     double x_min,x_max,y_min,y_max;
5116     if (linesegment1.start.x<linesegment1.end.x)
5117     {
5118         x_min=linesegment1.start.x;
5119         x_max=linesegment1.end.x;
5120     }
5121     else
5122     {
5123         x_min=linesegment1.end.x;
5124         x_max=linesegment1.start.x;
5125     }
5126     if (linesegment1.start.y<linesegment1.end.y)
5127     {
5128         y_min=linesegment1.start.y;
5129         y_max=linesegment1.end.y;
5130     }
5131     else
5132     {
5133         y_min=linesegment1.end.y;
5134         y_max=linesegment1.start.y;
5135     }
5136     if (pt1.x<x_min||pt1.x>x_max||pt1.y<y_min||pt1.y>y_max)
5137         return false;
5138     else return true;
5139 }
5140
5141 int IsLineSegmentCross(MyLineSegment linesegment1, MyLineSegment linesegment2)
5142 {
5143     PointD pt1,pt2,pt3,pt4;
5144     pt1=linesegment1.start;pt2=linesegment1.end;
5145     pt3=linesegment2.start;pt4=linesegment2.end;
5146     double d1,d2,d3,d4;
5147     d1=LineSegmentDirection(pt3,pt4,pt1);
5148     d2=LineSegmentDirection(pt3,pt4,pt2);
5149     d3=LineSegmentDirection(pt1,pt2,pt3);
5150     d4=LineSegmentDirection(pt1,pt2,pt4);
5151     if (d1*d2<0&&d3*d4<0)
5152         return true;
5153     else if (d1==0&&IsOnLineSegment(linesegment2,pt1)) return true;
5154     else if (d2==0&&IsOnLineSegment(linesegment2,pt2)) return true;
5155     else if (d3==0&&IsOnLineSegment(linesegment1,pt3)) return true;
5156     else if (d4==0&&IsOnLineSegment(linesegment1,pt4)) return true;
5157     else return false;
5158 }
5159 /*
5160 int IsLineSegmentCross(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
5161 {
5162     PointD pt1,pt2,pt3,pt4;
5163     pt1=PointD(x1,y1);pt2=PointD(x2,y2);
5164     pt3=PointD(x3,y3);pt4=PointD(x4,y4);
5165     double d1,d2,d3,d4;
5166     d1=LineSegmentDirection(pt3,pt4,pt1);
5167     d2=LineSegmentDirection(pt3,pt4,pt2);
5168     d3=LineSegmentDirection(pt1,pt2,pt3);
5169     d4=LineSegmentDirection(pt1,pt2,pt4);
5170     if (d1*d2<0&&d3*d4<0)
5171         return true;
5172     else if (d1==0&&IsOnLineSegment(linesegment2,pt1)) return true;
5173     else if (d2==0&&IsOnLineSegment(linesegment2,pt2)) return true;
5174     else if (d3==0&&IsOnLineSegment(linesegment1,pt3)) return true;
5175     else if (d4==0&&IsOnLineSegment(linesegment1,pt4)) return true;
5176     else return false;
5177     return false;
5178 }
5179 */
5180 int Canny算法()
5181 {
5182     return 0;
5183 };
5184
5185 int Hough(MyImage& img1,stHoughResult res[],int MaxFound, double Threshold,int starta,int enda)
5186 {
5187     const int hough_space=256;
5188     int width=img1.Width;
5189     int height=img1.Height;
5190     int stride=img1.Stride;
5191
5192     int centerX=width/2;
5193     int centerY=height/2;
5194     double hough_interval=3.1415926535897932384626433/(double)hough_space;
5195
5196     int maxL=max(width,height);
5197     int max_length=(int)(1.41421356237*maxL);
5198     int hough_strides=(max_length+3)&0xfffffffc;
5199     unsigned char *pixels=(unsigned char *)img1.GetBuffer();
5200 /*
5201     //建立特征点的集合
5202     int TotalPixel=0;
5203     Point ptx[9999];
5204     unsigned char score1[9999];
5205     for (int i=0;i<height;i++)
5206     {
5207         for (int j=0;j<width;j++)
5208         {
5209             if (pixels[i*stride+j]==0) continue;
5210             if (TotalPixel<9999-1)
5211             {
5212                 ptx[TotalPixel].X=j;
5213                 ptx[TotalPixel].Y=i;
5214                 score1[TotalPixel]=pixels[i*stride+j];
5215                 TotalPixel++;
5216             }
5217         }
5218     }
5219 */
5220     //建立参数空间
5221     int *hough_2d=new int[hough_space*hough_strides];
5222     //参数空间清零
5223     for (int i=0;i<hough_space;i++)
5224     {
5225         for (int j=0;j<max_length;j++)
5226         {
5227             hough_2d[i*hough_strides+j]=0;
5228         }
5229     }
5230     int minb=999,maxb=0;
5231     //像素映射到参数空间
5232     for (int i=0;i<height;i++)
5233     {
5234         int n=i*stride;
5235         for (int j=0;j<width;j++)
5236         {
5237             unsigned char pixel=pixels[n+j];
5238             if (pixel==0) continue;
5239             int maxk=0;
5240             for (int cell=starta;cell<enda;cell++)
5241             {
5242                 maxk=(int)((j-centerX)*cos(cell*hough_interval-Pi/4)+(i-centerY)*sin(cell*hough_interval-Pi/4)+max_length/2);
5243                 //maxk+=max_length/2;
5244                 if (maxk>maxb) {maxb=maxk;}
5245                 if (maxk<minb) {minb=maxk;}
5246                 if (maxk<0||(maxk>=max_length))
5247                 {
5248                     continue;
5249                 }
5250                 hough_2d[cell*hough_strides+maxk]+=pixel;
5251             }
5252
5253         }
5254     }
5255     int max_hough=0;
5256     int max_x=0,max_y=0;
5257     //参数空间找最大值
5258     for (int i=starta;i<enda/*hough_space*/;i++)
5259     {
5260         for (int j=1;j<max_length-1;j++)
5261         {
5262             int thissum=0;
5263             for (int k=-1;k<2;k++)
5264             {
5265                 for (int l=-1;l<2;l++)
5266                 {
5267                     thissum+=hough_2d[i*hough_strides+j];
5268                 }
5269             }
5270             if (thissum>max_hough)
5271             {
5272                 max_hough=thissum;
5273                 max_x=j;max_y=i;
5274             }
5275         }
5276     }
5277     //找极值
5278     int totalfound=0;
5279     res[totalfound].Pt=PointD(max_y,max_x-max_length/2);
5280     res[totalfound].Score=max_hough;
5281     totalfound++;
5282     for (int i=starta+1;i<enda-1 /*hough_space-1*/;i++)
5283     {
5284         for (int j=1;j<max_length-1;j++)
5285         {
5286             int nofound=0;
5287             int thissum=0;
5288             for (int k=-1;k<2;k++)
5289             {
5290                 for (int l=-1;l<2;l++)
5291                 {
5292                     thissum+=hough_2d[i*hough_strides+j];
5293                 }
5294             }
5295             if (thissum<Threshold) continue;
5296             for (int k=-1;k<2;k++)
5297             {
5298                 for (int l=-1;l<2;l++)
5299                 {
5300                     if (k==0&&l==0) continue;
5301                     if (hough_2d[i*hough_strides+j]<hough_2d[(i+k)*hough_strides+(j+l)])
5302                     {
5303                         nofound=1;
5304                         break;
5305                     }
5306                 }
5307                 if (nofound) break;
5308             }
5309             if (nofound) continue;    //found but not peak
5310             if (totalfound<MaxFound-1)
5311             {
5312                 res[totalfound].Pt=PointD(i,j-max_length/2);
5313                 res[totalfound].Score=thissum;
5314                 totalfound++;
5315                 if (totalfound>=MaxFound) break;
5316             }
5317         }
5318     }
5319 /*
5320     //转换到图像显示
5321     char factor=max_hough/127;
5322     if (factor<1) {factor=1;}
5323     if (max_hough<1) {max_hough=1;}
5324     unsigned char *hough_2d2=new unsigned char[hough_space*hough_strides];
5325     int kk;
5326     for (int i=0;i<hough_space;i++)
5327     {
5328         for (int j=0;j<max_length;j++)
5329         {
5330             kk=hough_2d[i*hough_strides+j]*255*8/max_hough;
5331             hough_2d2[i*hough_strides+j]=kk;
5332         }
5333     }
5334     //保存图像
5335 //    SaveBufferToBmpFile(hough_2d2,max_length,hough_space,hough_strides,_T("d:\\1\\Hough001.bmp"));
5336     delete [] hough_2d2;
5337     //    vector <int> a;
5338 //*/
5339     delete [] hough_2d;
5340     return totalfound;
5341     return 0;
5342 }
5343
5344 int NewHough(MyImage& img1,stHoughResult res[],int MaxFound, double Threshold,int starta,int enda)
5345 {
5346     const int hough_space=256;
5347     int width=img1.Width;
5348     int height=img1.Height;
5349     int stride=img1.Stride;
5350
5351     int centerX=width/2;
5352     int centerY=height/2;
5353     double hough_interval=3.1415926535897932384626433/(double)hough_space;
5354
5355     int maxL=max(width,height);
5356     int max_length=(int)(1.41421356237*maxL);
5357     int hough_strides=(max_length+3)&0xfffffffc;
5358     unsigned char *pixels=(unsigned char *)img1.GetBuffer();
5359
5360     //建立特征点的集合
5361     int TotalPixel=0;
5362     Gdiplus::Point ptx[9999];
5363     unsigned char score1[9999];
5364     unsigned char used[9999];
5365     unsigned char used2[9999];
5366     for (int i=0;i<height;i++)
5367     {
5368         for (int j=0;j<width;j++)
5369         {
5370             if (pixels[i*stride+j]==0) continue;
5371             if (TotalPixel<9999-1)
5372             {
5373                 ptx[TotalPixel].X=j;
5374                 ptx[TotalPixel].Y=i;
5375                 score1[TotalPixel]=pixels[i*stride+j];
5376                 used[TotalPixel]=0;
5377                 used2[TotalPixel]=0;
5378                 TotalPixel++;
5379             }
5380         }
5381     }
5382     //变幻;
5383     int minL=10;
5384     int totalfound=0;
5385     double ee=0.5;
5386     int first,second;
5387     for (first=0;first<TotalPixel-30;first++)
5388     {
5389         if (used[first]) continue;
5390         for (second=first+10;second<TotalPixel;second++)
5391         {
5392             if (used[second]) continue;
5393             if (used2[second]) continue;
5394             int counterk=0;
5395             int x1,y1,x2,y2;
5396             x1=ptx[first].X;y1=ptx[first].Y;
5397             x2=ptx[second].X;y2=ptx[second].Y;
5398             //判断距离,如果距离小于minL,放弃
5399             int dx,dy,dl;
5400             dx=x2-x1;dy=y2-y1;
5401             dl=(dx)*dx+dy*dy;
5402             if (dl<minL*minL) continue;
5403             double theta,ro;
5404             if (y2==y1) {theta=Pi/2;}
5405             else {theta=atan((double)x2-x1/y2-y1);}
5406             ro=((x1-centerX)*cos(theta)+(y1-centerY)*sin(theta))+max_length/2;
5407             for (int k=first+1;k<TotalPixel;k++)
5408             {
5409                 if (used[k]) continue;
5410                 int x3,y3;
5411                 double ro3;
5412                 x3=ptx[k].X;y3=ptx[k].Y;
5413                 ro3=((x3-centerX)*cos(theta)+(y3-centerY)*sin(theta)+max_length/2);
5414                 if (fabs(ro-ro3)<ee)
5415                 {
5416                     used2[k]=1;
5417                     counterk++;
5418                 }
5419             }
5420             if (counterk>Threshold)
5421             {
5422                 for (int l=0;l<TotalPixel;l++)
5423                 {
5424                     if (used2[l]) used[l]=used2[l];
5425                 }
5426                 if (totalfound<1000-1)
5427                 {
5428                     res[totalfound].Pt=PointD(theta,ro-max_length/2);
5429                     res[totalfound].Score=counterk;
5430                     totalfound++;
5431                     if (totalfound>=MaxFound) break;
5432                 }
5433                 break;
5434             }
5435         }
5436     }
5437     return totalfound;
5438     return 0;
5439 }
5440 int TransRGBToBayerGR(Gdiplus::Bitmap * bitmap1,CString sFilePathname)
5441 {
5442     if (bitmap1==NULL) {return 0;}
5443     int w,h;
5444     w=bitmap1->GetWidth();
5445     h=bitmap1->GetHeight();
5446     if (0==w||0==h) {return 0;}
5447
5448     Gdiplus::BitmapData bitmapdata0;
5449     UINT * pixels;
5450     Gdiplus::Rect rect0(0,0,w,h);
5451
5452     Gdiplus::Status    GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
5453     if (GdipStatus!=Gdiplus::Ok)
5454     {
5455         CString Errs1;
5456         Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
5457         return 0;
5458     }
5459     pixels=(UINT *)bitmapdata0.Scan0 ;
5460     int stride=bitmapdata0.Stride/4;
5461     int stride2=(stride+63)&(-64);
5462     unsigned char * buf1=new unsigned char [h*stride2];
5463 //#pragma omp parallel for
5464     for (int i=0;i<h;i+=2)
5465     {
5466         COLOR c1;
5467         for (int j=0;j<w;j+=2)
5468         {
5469             c1.argb=pixels[i*stride+j];
5470             buf1[i*stride2+j]=c1.G;
5471             c1.argb=pixels[i*stride+j+1];
5472             buf1[i*stride2+j+1]=c1.R;
5473         }
5474         for (int j=0;j<w;j+=2)
5475         {
5476             c1.argb=pixels[(i+1)*stride+j];
5477             buf1[(i+1)*stride2+j]=c1.B;
5478             c1.argb=pixels[(i+1)*stride+j+1];
5479             buf1[(i+1)*stride2+j+1]=c1.G;
5480         }
5481     }
5482     bitmap1->UnlockBits(&bitmapdata0);
5483     SaveBufferToBmpFile(buf1,w,h,stride2,sFilePathname);
5484     delete []buf1;
5485     return true;
5486 }
5487 int TransRGBToBayerGR2(Gdiplus::Bitmap * bitmap1,CString sFilePathname)
5488 {
5489     if (bitmap1==NULL) {return 0;}
5490     int w,h;
5491     w=bitmap1->GetWidth();
5492     h=bitmap1->GetHeight();
5493     if (0==w||0==h) {return 0;}
5494
5495     Gdiplus::BitmapData bitmapdata0;
5496     UINT * pixels;
5497     Gdiplus::Rect rect0(0,0,w,h);
5498
5499     Gdiplus::Status    GdipStatus=bitmap1->LockBits(&rect0,Gdiplus::ImageLockModeRead,PixelFormat32bppRGB,&bitmapdata0);
5500     if (GdipStatus!=Gdiplus::Ok)
5501     {
5502         CString Errs1;
5503         Errs1.Format(_T("Gdip LockBits Error %d \r\n"),GdipStatus);
5504         return 0;
5505     }
5506     pixels=(UINT *)bitmapdata0.Scan0 ;
5507     int stride=bitmapdata0.Stride/4;
5508     unsigned char * buf1=new unsigned char [h*stride];
5509 #pragma omp parallel for
5510     for (int i=0;i<h;i+=2)
5511     {
5512         COLOR c1;
5513         for (int j=0;j<w;j+=2)
5514         {
5515             c1.argb=pixels[i*stride+j];
5516             buf1[(i/2)*stride+j/2]=c1.G;
5517             c1.argb=pixels[i*stride+j+1];
5518             buf1[(i/2)*stride+j/2+w/2]=c1.R;
5519         }
5520         for (int j=0;j<w;j+=2)
5521         {
5522             c1.argb=pixels[(i+1)*stride+j];
5523             buf1[(i/2+h/2)*stride+j/2]=c1.B;
5524             c1.argb=pixels[(i+1)*stride+j+1];
5525             buf1[(i/2+h/2)*stride+j/2+w/2]=c1.G;
5526         }
5527     }
5528     bitmap1->UnlockBits(&bitmapdata0);
5529     SaveBufferToBmpFile(buf1,w,h,stride,sFilePathname);
5530     delete [] buf1;
5531     return true;
5532 }
5533
5534 double RefCompare(double * buf1, int count1, double * buf2, int count2 ,int mode)
5535 {
5536     double refcount=0;
5537     int count=min(count1,count2);
5538     double a,b,c=0;
5539     for (int i=0;i<count;i++)
5540     {
5541         a=buf1[i];
5542         b=buf2[i];
5543         c+=(a-b)*(a-b);
5544     }
5545     refcount=sqrt(c);
5546     
5547     return refcount;
5548 }
5549 /*
5550 #include "opencv2/opencv.hpp"
5551 #ifdef _DEBUG
5552 #pragma comment(lib,"opencv_core341d.lib")
5553 #pragma comment(lib,"opencv_imgproc341d.lib")
5554 #pragma comment(lib,"opencv_imgcodecs341d.lib")
5555 #pragma comment(lib,"opencv_highgui341d.lib")
5556 #else
5557 #pragma comment(lib,"opencv_core341.lib")
5558 #pragma comment(lib,"opencv_imgproc341.lib")
5559 #pragma comment(lib,"opencv_imgcodecs341.lib")
5560 #pragma comment(lib,"opencv_highgui341.lib")
5561 #endif
5562 */
5563 #ifdef _WIN64
5564
5565 #include "E:\OpenCV3\opencv\build\include\opencv2\opencv.hpp"
5566 #ifdef _DEBUG
5567 #pragma comment(lib,"opencv_world310d.lib")
5568 #else
5569 #pragma comment(lib,"opencv_world310.lib")
5570 #endif
5571 int fdf1(double * pData, int width, int height, DftFilterPos filterPos[], int filterPosCount, int showstatus)
5572
5573     CString s1;
5574     double time1,time2;
5575     time1 = GetTickCountmS();
5576
5577     cv::Mat input(height,width,CV_64FC1,pData);
5578     
5579     int w=cv::getOptimalDFTSize(input.cols);  
5580     int h=cv::getOptimalDFTSize(input.rows);//获取最佳尺寸,快速傅立叶变换要求尺寸为2的n次方  
5581     cv::Mat padded;  
5582     cv::copyMakeBorder(input,padded,0,h-input.rows,0,w-input.cols,cv::BORDER_CONSTANT,cv::Scalar::all(0));//填充图像保存到padded中  
5583
5584     cv::Mat plane[]={cv::Mat_<float>(padded),cv::Mat::zeros(padded.size(),CV_32F)};//创建通道
5585     cv::Mat complexIm1;
5586     cv::Mat complexIm2;
5587     cv::Mat complexIm3;
5588
5589     time2=GetTickCountmS();
5590     s1.Format(_T("fdf init %.3fmS\r\n"),time2-time1);
5591     TRACE(s1);
5592
5593     if (showstatus)
5594     {
5595         cv::Mat T;
5596         plane[0].copyTo(T);
5597         cv::normalize(T,T,255,0,CV_MINMAX);
5598         cv::imwrite("D:\\1\\fdf_padded.bmp",cv::Mat_<uchar>(T));
5599     }
5600
5601     time1 = GetTickCountmS();
5602     //*******************************dft************************************ 
5603     cv::merge(plane,2,complexIm1);//合并通道  
5604     cv::dft(complexIm1,complexIm2);//进行傅立叶变换,结果保存在自身
5605     cv::split(complexIm2,plane);//分离通道
5606
5607     time2=GetTickCountmS();
5608     s1.Format(_T("fdf dft %.3fmS\r\n"),time2-time1);
5609     TRACE(s1);
5610
5611     if (1)
5612     {    
5613         time1 = GetTickCountmS();
5614         //*******************************shift************************************
5615         {
5616             int cx=plane[0].cols/2;
5617             int cy=plane[0].rows/2;
5618             cv::Mat temp;  
5619             cv::Mat part1(plane[0],cv::Rect(0,0,cx,cy));  
5620             cv::Mat part2(plane[0],cv::Rect(cx,0,cx,cy));  
5621             cv::Mat part3(plane[0],cv::Rect(0,cy,cx,cy));  
5622             cv::Mat part4(plane[0],cv::Rect(cx,cy,cx,cy));  
5623
5624             part1.copyTo(temp);  
5625             part4.copyTo(part1);  
5626             temp.copyTo(part4);  
5627
5628             part2.copyTo(temp);  
5629             part3.copyTo(part2);  
5630             temp.copyTo(part3);
5631         }
5632         {
5633             int cx=plane[0].cols/2;
5634             int cy=plane[0].rows/2;
5635             cv::Mat temp;
5636
5637             cv::Mat part1(plane[1],cv::Rect(0,0,cx,cy));  
5638             cv::Mat part2(plane[1],cv::Rect(cx,0,cx,cy));  
5639             cv::Mat part3(plane[1],cv::Rect(0,cy,cx,cy));  
5640             cv::Mat part4(plane[1],cv::Rect(cx,cy,cx,cy));  
5641
5642             part1.copyTo(temp);  
5643             part4.copyTo(part1);  
5644             temp.copyTo(part4);  
5645
5646             part2.copyTo(temp);  
5647             part3.copyTo(part2);  
5648             temp.copyTo(part3);
5649         }
5650         time2=GetTickCountmS();
5651         s1.Format(_T("fdf shift %.3fmS\r\n"),time2-time1);
5652         TRACE(s1);
5653     }
5654
5655     if (showstatus)
5656     {
5657         cv::Mat T;
5658         cv::magnitude(plane[0],plane[1],T);
5659         T+=cv::Scalar::all(1);
5660         cv::log(T,T);  
5661         cv::normalize(T,T,255,0,CV_MINMAX);
5662         cv::imwrite("D:\\1\\fdf_dft.bmp",cv::Mat_<uchar>(T));
5663     }
5664
5665     if (1)
5666     {
5667         time1 = GetTickCountmS();
5668         //*******************************filter************************************
5669         for (int k=0; k<filterPosCount; k++)
5670         {
5671             int startx = w/2 - filterPos[k].x - filterPos[k].w/2;
5672             int endx = w/2 - filterPos[k].x + filterPos[k].w/2;
5673             int starty = h/2 - filterPos[k].y - filterPos[k].h/2;
5674             int endy = h/2 - filterPos[k].y + filterPos[k].h/2;
5675
5676             if (startx<0) startx = 0;
5677             if (starty<0) starty = 0;
5678             if (endx>w) endx = w;
5679             if (endy>h) endy = h;
5680
5681             for (int i=starty; i<endy; ++i)
5682             {
5683                 float*p0=plane[0].ptr<float>(i);
5684                 for (int j=startx; j<endx; j++)
5685                 {
5686                     p0[j]=0;
5687                 }
5688
5689                 float*p1=plane[1].ptr<float>(i);
5690                 for (int j=startx; j<endx; j++)
5691                 {
5692                     p1[j]=0;
5693                 }
5694             }
5695         }
5696
5697         time2=GetTickCountmS();
5698         s1.Format(_T("fdf filter %.3fmS\r\n"),time2-time1);
5699         TRACE(s1);
5700     }
5701
5702     if (showstatus)
5703     {
5704         cv::Mat T;
5705         cv::magnitude(plane[0],plane[1],T);
5706         T+=cv::Scalar::all(1);
5707         cv::log(T,T);
5708         cv::normalize(T,T,255,0,CV_MINMAX);
5709         cv::imwrite("D:\\1\\fdf_dft_filtered.bmp",cv::Mat_<uchar>(T));
5710     }
5711
5712     if (1)
5713     {    
5714         time1 = GetTickCountmS();
5715         //*******************************shift************************************
5716         {
5717             int cx=plane[0].cols/2;
5718             int cy=plane[0].rows/2;
5719             cv::Mat temp;  
5720             cv::Mat part1(plane[0],cv::Rect(0,0,cx,cy));  
5721             cv::Mat part2(plane[0],cv::Rect(cx,0,cx,cy));  
5722             cv::Mat part3(plane[0],cv::Rect(0,cy,cx,cy));  
5723             cv::Mat part4(plane[0],cv::Rect(cx,cy,cx,cy));  
5724
5725             part1.copyTo(temp);  
5726             part4.copyTo(part1);  
5727             temp.copyTo(part4);  
5728
5729             part2.copyTo(temp);  
5730             part3.copyTo(part2);  
5731             temp.copyTo(part3);
5732         }
5733         {
5734             int cx=plane[0].cols/2;
5735             int cy=plane[0].rows/2;
5736             cv::Mat temp;
5737
5738             cv::Mat part1(plane[1],cv::Rect(0,0,cx,cy));  
5739             cv::Mat part2(plane[1],cv::Rect(cx,0,cx,cy));  
5740             cv::Mat part3(plane[1],cv::Rect(0,cy,cx,cy));  
5741             cv::Mat part4(plane[1],cv::Rect(cx,cy,cx,cy));  
5742
5743             part1.copyTo(temp);  
5744             part4.copyTo(part1);  
5745             temp.copyTo(part4);  
5746
5747             part2.copyTo(temp);  
5748             part3.copyTo(part2);  
5749             temp.copyTo(part3);
5750         }
5751
5752         time2=GetTickCountmS();
5753         s1.Format(_T("fdf ishift %.3fmS\r\n"),time2-time1);
5754         TRACE(s1);
5755     }
5756
5757     time1 = GetTickCountmS();
5758     //*****************************idft**************************************
5759     cv::merge(plane,2,complexIm2);
5760     cv::idft(complexIm2,complexIm3);//傅立叶逆变换  
5761     cv::split(complexIm3,plane);//结果也是复数
5762
5763     time2=GetTickCountmS();
5764     s1.Format(_T("fdf idft %.3fmS\r\n"),time2-time1);
5765     TRACE(s1);
5766
5767     time1 = GetTickCountmS();
5768     cv::Mat output;
5769     plane[0].copyTo(output);
5770     cv::normalize(output,output,255,0,CV_MINMAX);
5771     for (int i=0; i<height; ++i)
5772     {
5773         float*p0=output.ptr<float>(i);
5774         for (int j=0; j<width; ++j)
5775         {
5776             pData[i*width+j] = p0[j];
5777         }
5778     }
5779     time2=GetTickCountmS();
5780     s1.Format(_T("fdf output %.3fmS\r\n"),time2-time1);
5781     TRACE(s1);
5782
5783     if (showstatus)
5784     {
5785         cv::Mat T;
5786         plane[0].copyTo(T);
5787         cv::normalize(T,T,255,0,CV_MINMAX);  
5788         cv::imwrite("D:\\1\\fdf_idft.bmp",cv::Mat_<uchar>(T));
5789     }
5790
5791     return 0;  
5792 }
5793 #endif /* _WIN64 */
5794