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