version 0.3.18
[fms.git] / src / freenet / captcha / freeimage / bitmap.cpp
1 #include "../../../../include/freenet/captcha/freeimage/bitmap.h"\r
2 \r
3 #include <cmath>\r
4 #include <cstdlib>\r
5 \r
6 namespace FreeImage\r
7 {\r
8 \r
9 Bitmap::Bitmap()\r
10 {\r
11         m_bmp=0;\r
12 }\r
13 \r
14 Bitmap::Bitmap(const Bitmap &bmp)\r
15 {\r
16         m_bmp=0;\r
17         *this=bmp;\r
18 }\r
19 \r
20 Bitmap::Bitmap(const std::string &typestr, const std::string &filename)\r
21 {\r
22         m_bmp=0;\r
23         Load(typestr,filename);\r
24 }\r
25 \r
26 Bitmap::Bitmap(FIBITMAP *bmp):m_bmp(bmp)\r
27 {\r
28 \r
29 }\r
30 \r
31 Bitmap::Bitmap(const int width, const int height, const int bpp)\r
32 {\r
33         m_bmp=FreeImage_Allocate(width,height,bpp,0,0,0);\r
34 }\r
35 \r
36 Bitmap::~Bitmap()\r
37 {\r
38         Destroy();\r
39 }\r
40 \r
41 void Bitmap::AALine(const int x1, const int y1, const int x2, const int y2, const RGBQUAD color)\r
42 {\r
43         RGBQUAD tempcol;\r
44         int height=Height();\r
45         int width=Width();\r
46         int fromx=x1;\r
47         int fromy=y1;\r
48         int tox=x2;\r
49         int toy=y2;\r
50         double sx=x2-x1;\r
51         double sy=y2-y1;\r
52 \r
53         if(fabs(sx)<=0.8 && fabs(sy)<=0.8)\r
54         {\r
55                 return;\r
56         }\r
57 \r
58         double hypot=sqrt((sx*sx)+(sy*sy));\r
59         sx/=hypot;\r
60         sy/=hypot;\r
61 \r
62         fromx<0 ? fromx=0 : false;\r
63         fromx>=width ? fromx=width-1 : false;\r
64         tox<0 ? tox=0 : false;\r
65         tox>=width ? tox=width-1 : false;\r
66         fromy<0 ? fromy=0 : false;\r
67         fromy>=height ? fromy=height-1 : false;\r
68         toy<0 ? toy=0 : false;\r
69         toy>=height ? toy=height-1 : false;\r
70 \r
71         int lx=fromx;\r
72         int rx=tox;\r
73         if(rx<lx)\r
74         {\r
75                 std::swap(rx,lx);\r
76         }\r
77         int ty=fromy;\r
78         int by=toy;\r
79         if(by<ty)\r
80         {\r
81                 std::swap(ty,by);\r
82         }\r
83 \r
84         for(int i=lx; i<=rx; i++)\r
85         {\r
86                 for(int j=ty; j<=by; j++)\r
87                 {\r
88                         double ii=0;\r
89                         double jj=0;\r
90                         double dx=0.25;\r
91                         double dy=0.25;\r
92                         double x=i-1.5*dx;\r
93                         double y=j-1.5*dy;\r
94                         double temp=0;\r
95                         \r
96                         for(ii=-2; ii<=1; ii++)\r
97                         {\r
98                                 for(jj=-2; jj<=1; jj++)\r
99                                 {\r
100                                         x=i+ii*dx+0.5*dx;\r
101                                         y=j+jj*dy+0.5*dy;\r
102                                         double temp1 = LineFunction( sx, sy , fromx, fromy, x,y );\r
103                                         temp1<=0.5 ? temp1=1.0 : temp1=0.0;\r
104                                         temp+=temp1;\r
105                                 }\r
106                         }\r
107 \r
108                         temp/=16.0;\r
109                         double minval=0.03125;\r
110 \r
111                         if(temp>minval)\r
112                         {\r
113                                 FreeImage_GetPixelColor(m_bmp,i,(height-1)-j,&tempcol);\r
114                                 tempcol.rgbRed=((1.0-temp)*((double)tempcol.rgbRed)+temp*((double)color.rgbRed));\r
115                                 tempcol.rgbGreen=((1.0-temp)*((double)tempcol.rgbGreen)+temp*((double)color.rgbGreen));\r
116                                 tempcol.rgbBlue=((1.0-temp)*((double)tempcol.rgbBlue)+temp*((double)color.rgbBlue));\r
117                                 FreeImage_SetPixelColor(m_bmp,i,(height-1)-j,&tempcol);\r
118                         }\r
119 \r
120                 }\r
121         }\r
122 \r
123 }\r
124 \r
125 void Bitmap::Blit(const Bitmap &bmp, const int destx, const int desty, const int sourcex, const int sourcey, const int w, const int h, const int alpha)\r
126 {\r
127         if(m_bmp && bmp.m_bmp)\r
128         {\r
129                 int width=w;\r
130                 int height=h;\r
131                 if(destx+width-1>=Width())\r
132                 {\r
133                         width=Width()-destx+1;\r
134                 }\r
135                 if(desty+height-1>=Height())\r
136                 {\r
137                         height=Height()-desty+1;\r
138                 }\r
139                 FIBITMAP *temp=FreeImage_Copy(bmp.m_bmp,sourcex,sourcey,sourcex+width,sourcey+height);\r
140                 FreeImage_Paste(m_bmp,temp,destx,desty,alpha);\r
141                 FreeImage_Unload(temp);\r
142         }\r
143 }\r
144 \r
145 void Bitmap::BlitTrans(const Bitmap &bmp, const int destx, const int desty, const int sourcex, const int sourcey, const int w, const int h)\r
146 {\r
147         if(m_bmp && bmp.m_bmp)\r
148         {\r
149                 RGBQUAD sourcecol;\r
150                 RGBQUAD destcol;\r
151                 int sourcew=bmp.Width();\r
152                 int sourceh=bmp.Height();\r
153                 int destw=Width();\r
154                 int desth=Height();\r
155                 int dx=destx;\r
156                 int dy=desty;\r
157                 double alpha=0.0;\r
158                 for(int y=sourcey; y<sourcey+h; y++, dy++)\r
159                 {\r
160                         dx=destx;\r
161                         for(int x=sourcex; x<sourcex+w; x++, dx++)\r
162                         {\r
163                                 if(y>=0 && y<sourceh && x>=0 && x<sourcew && dx>=0 && dx<destw && dy>=0 && dy<desth)\r
164                                 {\r
165                                         FreeImage_GetPixelColor(bmp.m_bmp,x,(sourceh-1)-y,&sourcecol);\r
166                                         if(sourcecol.rgbReserved==255)          // opaque\r
167                                         {\r
168                                                 FreeImage_SetPixelColor(m_bmp,dx,(desth-1)-dy,&sourcecol);\r
169                                         }\r
170                                         else if(sourcecol.rgbReserved>0)        // some translucency\r
171                                         {\r
172                                                 FreeImage_GetPixelColor(m_bmp,dx,(desth-1)-dy,&destcol);\r
173                                                 alpha=(double)sourcecol.rgbReserved/255.0;\r
174                                                 sourcecol.rgbRed=(sourcecol.rgbRed*alpha)+(destcol.rgbRed*(1.0-alpha));\r
175                                                 sourcecol.rgbGreen=(sourcecol.rgbGreen*alpha)+(destcol.rgbGreen*(1.0-alpha));\r
176                                                 sourcecol.rgbBlue=(sourcecol.rgbBlue*alpha)+(destcol.rgbBlue*(1.0-alpha));\r
177                                                 sourcecol.rgbReserved<destcol.rgbReserved ? sourcecol.rgbReserved=destcol.rgbReserved : false;\r
178                                                 FreeImage_SetPixelColor(m_bmp,dx,(desth-1)-dy,&sourcecol);\r
179                                         }\r
180                                 }\r
181                         }\r
182                 }\r
183         }\r
184 }\r
185 \r
186 void Bitmap::Clear(RGBQUAD color)\r
187 {\r
188         if(m_bmp)\r
189         {\r
190                 int h=FreeImage_GetHeight(m_bmp);\r
191                 int w=FreeImage_GetWidth(m_bmp);\r
192                 for(int y=0; y<h; y++)\r
193                 {\r
194                         for(int x=0; x<w; x++)\r
195                         {\r
196                                 FreeImage_SetPixelColor(m_bmp,x,y,&color);\r
197                         }\r
198                 }\r
199         }\r
200 }\r
201 \r
202 void Bitmap::ClearTransparent()\r
203 {\r
204         if(m_bmp)\r
205         {\r
206                 RGBQUAD color;\r
207                 color.rgbRed=0;\r
208                 color.rgbGreen=0;\r
209                 color.rgbBlue=0;\r
210                 color.rgbReserved=0;\r
211                 int h=Height();\r
212                 int w=Width();\r
213                 for(int y=0; y<h; y++)\r
214                 {\r
215                         for(int x=0; x<w; x++)\r
216                         {\r
217                                 FreeImage_SetPixelColor(m_bmp,x,y,&color);\r
218                         }\r
219                 }\r
220         }\r
221 }\r
222 \r
223 void Bitmap::ConvertBPP(const int bpp)\r
224 {\r
225         if(m_bmp)\r
226         {\r
227                 FIBITMAP *temp;\r
228                 switch(bpp)\r
229                 {\r
230                 case 2:\r
231                         temp=FreeImage_ConvertToGreyscale(m_bmp);\r
232                         Destroy();\r
233                         m_bmp=temp;\r
234                         break;\r
235                 case 4:\r
236                         temp=FreeImage_ConvertTo4Bits(m_bmp);\r
237                         Destroy();\r
238                         m_bmp=temp;\r
239                         break;\r
240                 case 8:\r
241                         temp=FreeImage_ConvertTo8Bits(m_bmp);\r
242                         Destroy();\r
243                         m_bmp=temp;\r
244                         break;\r
245                 case 16:\r
246                         temp=FreeImage_ConvertTo16Bits565(m_bmp);\r
247                         Destroy();\r
248                         m_bmp=temp;\r
249                         break;\r
250                 case 24:\r
251                         temp=FreeImage_ConvertTo24Bits(m_bmp);\r
252                         Destroy();\r
253                         m_bmp=temp;\r
254                         break;\r
255                 case 32:\r
256                 default:\r
257                         temp=FreeImage_ConvertTo32Bits(m_bmp);\r
258                         Destroy();\r
259                         m_bmp=temp;\r
260                         break;\r
261                 }\r
262         }\r
263 }\r
264 \r
265 const bool Bitmap::Create(const int width, const int height, const int bpp)\r
266 {\r
267         Destroy();\r
268         m_bmp=FreeImage_Allocate(width,height,bpp,0,0,0);\r
269         if(m_bmp)\r
270         {\r
271                 return true;\r
272         }\r
273         return false;\r
274 }\r
275 \r
276 void Bitmap::Destroy()\r
277 {\r
278         if(m_bmp)\r
279         {\r
280                 FreeImage_Unload(m_bmp);\r
281                 m_bmp=0;\r
282         }\r
283 }\r
284 \r
285 void Bitmap::FastLine(const int x1, const int y1, const int x2, const int y2, RGBQUAD color)\r
286 {\r
287         if(m_bmp)\r
288         {\r
289                 int width=Width();\r
290                 int height=Height();\r
291                 int fromx=x1;\r
292                 int fromy=y1;\r
293                 int tox=x2;\r
294                 int toy=y2;\r
295 \r
296                 fromx<0 ? fromx=0 : false;\r
297                 fromx>=width ? fromx=width-1 : false;\r
298                 tox<0 ? tox=0 : false;\r
299                 tox>=width ? tox=width-1 : false;\r
300                 fromy<0 ? fromy=0 : false;\r
301                 fromy>=height ? fromy=height-1 : false;\r
302                 toy<0 ? toy=0 : false;\r
303                 toy>=height ? toy=height-1 : false;\r
304 \r
305                 int dx=tox-fromx;\r
306                 int dy=toy-fromy;\r
307 \r
308                 if(dx==0 && dy==0)\r
309                 {\r
310                         return;\r
311                 }\r
312 \r
313                 int xinc1=1;\r
314                 if(dx<0)\r
315                 {\r
316                         xinc1=-1;\r
317                         dx=-dx;\r
318                 }\r
319                 int yinc1=1;\r
320                 if(dy<0)\r
321                 {\r
322                         yinc1=-1;\r
323                         dy=-dy;\r
324                 }\r
325 \r
326                 int x=fromx;\r
327                 int y=fromy;\r
328                 int xinc2=xinc1;\r
329                 int yinc2=yinc1;\r
330 \r
331                 double den;\r
332                 double num;\r
333                 int numadd;\r
334                 int numpixels;\r
335 \r
336                 if(dx>=dy)\r
337                 {\r
338                         xinc1=0;\r
339                         yinc2=0;\r
340                         den=dx+0.0;\r
341                         num=0.5*dx;\r
342                         numadd=dy;\r
343                         numpixels=dx;\r
344                 }\r
345                 else\r
346                 {\r
347                         xinc2=0;\r
348                         yinc1=0;\r
349                         den=dy+0.0;\r
350                         num=0.5*dy;\r
351                         numadd=dx;\r
352                         numpixels=dy;\r
353                 }\r
354 \r
355                 int cpixel;\r
356                 for(cpixel=0; cpixel<=numpixels; cpixel++)\r
357                 {\r
358                         FreeImage_SetPixelColor(m_bmp,x,(height-1)-y,&color);\r
359                         num+=numadd;\r
360                         if(num>=den)\r
361                         {\r
362                                 num=-den;\r
363                                 x+=xinc1;\r
364                                 y+=yinc1;\r
365                         }\r
366                         x+=xinc2;\r
367                         y+=yinc2;\r
368                 }\r
369         }\r
370 }\r
371 \r
372 RGBQUAD Bitmap::GetPixel(const int x, const int y) const\r
373 {\r
374         RGBQUAD color;\r
375         color.rgbRed=0;\r
376         color.rgbGreen=0;\r
377         color.rgbBlue=0;\r
378         color.rgbReserved=0;\r
379 \r
380         if(m_bmp && x>=0 && x<Width() && y>=0 && y<Height())\r
381         {\r
382                 FreeImage_GetPixelColor(m_bmp,x,Height()-1-y,&color);\r
383         }\r
384 \r
385         return color;\r
386 \r
387 }\r
388 \r
389 const int Bitmap::GetPixelIndex(const int x, const int y) const\r
390 {\r
391         if(m_bmp)\r
392         {\r
393                 BYTE index;\r
394                 FreeImage_GetPixelIndex(m_bmp,x,Height()-1-y,&index);\r
395                 return index;\r
396         }\r
397         else\r
398         {\r
399                 return -1;\r
400         }\r
401 }\r
402 \r
403 void Bitmap::HorizontalOffset(const int y, const double shift)\r
404 {\r
405         if(m_bmp)\r
406         {\r
407                 int width=Width();\r
408                 int height=Height();\r
409                 int startx=width-1;\r
410                 int endx=ceil(shift);\r
411                 int dx=-1;\r
412                 int offset1=-(floor(shift));\r
413                 int offset2=-(ceil(shift));\r
414                 RGBQUAD color1;\r
415                 RGBQUAD color2;\r
416                 RGBQUAD newcolor;\r
417                 double part2=shift-floor(shift);\r
418                 double part1=1.0-part2;\r
419 \r
420                 if(shift<0)\r
421                 {\r
422                         startx=0;\r
423                         endx=width-1-ceil(abs(shift));\r
424                         dx=1;\r
425                         offset1=-ceil(shift);\r
426                         offset2=-floor(shift);\r
427                         part2=abs(shift-ceil(shift));\r
428                         part1=1.0-part2;\r
429                 }\r
430 \r
431                 FreeImage_GetPixelColor(m_bmp,startx+offset1,(height-1)-y,&color1);\r
432                 for(int x=startx+dx; x!=endx; x+=dx)\r
433                 {\r
434                         FreeImage_GetPixelColor(m_bmp,x+offset2,(height-1)-y,&color2);\r
435                         \r
436                         newcolor.rgbRed=(color1.rgbRed*part1)+(color2.rgbRed*part2);\r
437                         newcolor.rgbGreen=(color1.rgbGreen*part1)+(color2.rgbGreen*part2);\r
438                         newcolor.rgbBlue=(color1.rgbBlue*part1)+(color2.rgbBlue*part2);\r
439 \r
440                         FreeImage_SetPixelColor(m_bmp,x,(height-1)-y,&newcolor);\r
441 \r
442                         color1=color2;\r
443                 }\r
444         }\r
445 }\r
446 \r
447 void Bitmap::Line(const int x1, const int y1, const int x2, const int y2, const RGBQUAD color)\r
448 {\r
449         if(m_bmp)\r
450         {\r
451                 if(x1!=x2 && y1!=y2)\r
452                 {\r
453                         AALine(x1,y1,x2,y2,color);\r
454                 }\r
455                 else\r
456                 {\r
457                         FastLine(x1,y1,x2,y2,color);\r
458                 }\r
459         }\r
460 }\r
461 \r
462 double Bitmap::LineFunction(const double slopex, const double slopey, const int startx, const int starty, const double testx, const double testy)\r
463 {\r
464         return fabs(slopex*(testy-starty)-slopey*(testx-startx));\r
465 }\r
466 \r
467 const bool Bitmap::Load(const std::string &typestr, const std::string &filename)\r
468 {\r
469         Destroy();\r
470         FREE_IMAGE_FORMAT type=FIF_BMP;\r
471         if(typestr.find("png")!=std::string::npos)\r
472         {\r
473                 type=FIF_PNG;\r
474         }\r
475         m_bmp=FreeImage_Load(type,filename.c_str(),0);\r
476         if(m_bmp)\r
477         {\r
478                 return true;\r
479         }\r
480         return false;\r
481 }\r
482 \r
483 const bool Bitmap::LoadFromMemory(const std::string &typestr, std::vector<unsigned char> &data)\r
484 {\r
485         bool loaded=false;\r
486         Destroy();\r
487         if(data.size()>0)\r
488         {\r
489                 FREE_IMAGE_FORMAT type=FIF_BMP;\r
490                 if(typestr.find("png")!=std::string::npos)\r
491                 {\r
492                         type=FIF_PNG;\r
493                 }\r
494 \r
495                 FIMEMORY *mem=FreeImage_OpenMemory((BYTE *)&data[0],data.size());\r
496                 m_bmp=FreeImage_LoadFromMemory(type,mem,0);\r
497                 if(m_bmp)\r
498                 {\r
499                         loaded=true;\r
500                 }\r
501                 FreeImage_CloseMemory(mem);\r
502         }\r
503         return loaded;\r
504 }\r
505 \r
506 Bitmap &Bitmap::operator=(const Bitmap &rhs)\r
507 {\r
508         if(this!=&rhs)\r
509         {\r
510                 Destroy();\r
511                 if(rhs.Width()>0 && rhs.Height()>0)\r
512                 {\r
513                         m_bmp=FreeImage_Allocate(rhs.Width(),rhs.Height(),rhs.BPP(),0,0,0);\r
514                         //FIBITMAP *temp=FreeImage_Copy(rhs.m_bmp,0,0,rhs.Width()-1,rhs.Height()-1);\r
515                         //FreeImage_Paste(m_bmp,rhs.m_bmp,0,0,-1);\r
516                         //FreeImage_Unload(temp);\r
517                         Blit(rhs,0,0,0,0,rhs.Width(),rhs.Height(),-1);\r
518                 }\r
519         }\r
520         return *this;\r
521 }\r
522 \r
523 void Bitmap::PutPixel(const int x, const int y, RGBQUAD color)\r
524 {\r
525         if(m_bmp && x>=0 && x<FreeImage_GetWidth(m_bmp) && y>=0 && y<FreeImage_GetHeight(m_bmp))\r
526         {\r
527                 FreeImage_SetPixelColor(m_bmp,x,(Height()-1)-y,&color);\r
528         }\r
529 }\r
530 \r
531 void Bitmap::Rect(const int x1, const int y1, const int w, const int h, const bool filled, RGBQUAD color)\r
532 {\r
533         if(m_bmp)\r
534         {\r
535                 int height=Height();\r
536                 int width=Width();\r
537                 for(int y=y1; y<y1+h; y++)\r
538                 {\r
539                         if(y>=0 && y<height)\r
540                         {\r
541                                 for(int x=x1; x<x1+w; x++)\r
542                                 {\r
543                                         if(x>=0 && x<width)\r
544                                         {\r
545                                                 if(x==x1 || x==x1+w-1 || y==y1 || y==y1+h-1 || filled)\r
546                                                 {\r
547                                                         FreeImage_SetPixelColor(m_bmp,x,(height-1)-y,&color);\r
548                                                 }\r
549                                         }\r
550                                 }\r
551                         }\r
552                 }\r
553         }\r
554 }\r
555 \r
556 void Bitmap::Rotate(const double angle, const int shiftx, const int shifty, const int originx, const int originy)\r
557 {\r
558         if(m_bmp)\r
559         {\r
560                 int height=Height();\r
561                 FIBITMAP *old=m_bmp;\r
562                 m_bmp=FreeImage_RotateEx(m_bmp,angle,shiftx,-shifty,originx,(height-1)-originy,true);\r
563                 FreeImage_Unload(old);\r
564         }\r
565 }\r
566 \r
567 const bool Bitmap::Save(const std::string &filename) const\r
568 {\r
569         if(m_bmp)\r
570         {\r
571                 FREE_IMAGE_FORMAT type=FIF_BMP;\r
572 \r
573                 if(filename.find(".png")!=std::string::npos)\r
574                 {\r
575                         type=FIF_PNG;\r
576                 }\r
577 \r
578                 if(FreeImage_Save(type,m_bmp,filename.c_str(),0))\r
579                 {\r
580                         return true;\r
581                 }\r
582         }\r
583         return false;\r
584 }\r
585 \r
586 const bool Bitmap::SaveToMemory(const std::string &typestr, std::vector<unsigned char> &data) const\r
587 {\r
588         bool saved=false;\r
589         if(m_bmp)\r
590         {\r
591                 FREE_IMAGE_FORMAT type=FIF_BMP;\r
592                 if(typestr.find("png")!=std::string::npos)\r
593                 {\r
594                         type=FIF_PNG;\r
595                 }\r
596                 FIMEMORY *mem=FreeImage_OpenMemory(0,0);\r
597                 if(FreeImage_SaveToMemory(type,m_bmp,mem,0))\r
598                 {\r
599                         FreeImage_SeekMemory(mem,0,SEEK_END);\r
600                         data.resize(FreeImage_TellMemory(mem));\r
601                         FreeImage_SeekMemory(mem,0,SEEK_SET);\r
602                         FreeImage_ReadMemory(&data[0],1,data.size(),mem);\r
603                         saved=true;\r
604                 }\r
605                 FreeImage_CloseMemory(mem);\r
606         }\r
607         return saved;\r
608 }\r
609 \r
610 void Bitmap::SetTransparent()\r
611 {\r
612         if(m_bmp)\r
613         {\r
614                 FreeImage_SetTransparent(m_bmp,true);\r
615         }\r
616 }\r
617 \r
618 void Bitmap::VerticalOffset(const int x, const double shift)\r
619 {\r
620         if(m_bmp)\r
621         {\r
622                 int width=Width();\r
623                 int height=Height();\r
624                 int starty=width-1;\r
625                 int endy=ceil(shift);\r
626                 int dy=-1;\r
627                 int offset1=-(floor(shift));\r
628                 int offset2=-(ceil(shift));\r
629                 RGBQUAD color1;\r
630                 RGBQUAD color2;\r
631                 RGBQUAD newcolor;\r
632                 double part2=shift-floor(shift);\r
633                 double part1=1.0-part2;\r
634 \r
635                 if(shift<0)\r
636                 {\r
637                         starty=0;\r
638                         endy=width-1-ceil(abs(shift));\r
639                         dy=1;\r
640                         offset1=-ceil(shift);\r
641                         offset2=-floor(shift);\r
642                         part2=abs(shift-ceil(shift));\r
643                         part1=1.0-part2;\r
644                 }\r
645 \r
646                 FreeImage_GetPixelColor(m_bmp,x,(height-1)-(starty+offset1),&color1);\r
647                 for(int y=starty+dy; y!=endy; y+=dy)\r
648                 {\r
649                         FreeImage_GetPixelColor(m_bmp,x,(height-1)-(y+offset2),&color2);\r
650                         \r
651                         newcolor.rgbRed=(color1.rgbRed*part1)+(color2.rgbRed*part2);\r
652                         newcolor.rgbGreen=(color1.rgbGreen*part1)+(color2.rgbGreen*part2);\r
653                         newcolor.rgbBlue=(color1.rgbBlue*part1)+(color2.rgbBlue*part2);\r
654 \r
655                         FreeImage_SetPixelColor(m_bmp,x,(height-1)-y,&newcolor);\r
656 \r
657                         color1=color2;\r
658                 }\r
659         }\r
660 }\r
661 \r
662 }       // namespace FreeImage\r