25#include <opencv2/opencv.hpp>
27#include "boost/thread.hpp"
36 ConvertBuffer(uchar* _srcBuff,
void* _dstBuff,
const int _width,
const int _height,
const int _sbpl,
const int _dbpl,
const int _bpp) :
47 ConvertBuffer(uchar* _srcBuff, uchar* _srcbuff8,
void* _dstBuff,
const int _width,
const int _height,
const int _sbpl,
const int _abpl,
const int _dbpl,
const int _bpp) :
70ConversionTools::ConversionTools()
75class bitmapToMat :
public cv::ParallelLoopBody
78 bitmapToMat(
const ConvertBuffer _conv)
82 void operator()(
const cv::Range& range)
const
84 const int start = range.start;
85 const int end = range.end;
87 unsigned int destByte;
90 for (y = start; y < end; y++)
92 for (x = 0; x < conv.width; x++)
94 srcByte = (x * conv.bpp) + (conv.sbpl * y);
95 destByte = (x * conv.bpp) + (conv.dbpl * y);
97 ((uchar*)conv.dstBuff)[destByte] = conv.srcBuff[srcByte];
100 ((uchar*)conv.dstBuff)[destByte + 1] = conv.srcBuff[srcByte + 1];
101 ((uchar*)conv.dstBuff)[destByte + 2] = conv.srcBuff[srcByte + 2];
108 bitmapToMat& operator=(
const bitmapToMat&);
110 const ConvertBuffer conv;
113class bitmapToMatBGR :
public cv::ParallelLoopBody
116 bitmapToMatBGR(
const ConvertBuffer _conv)
120 void operator()(
const cv::Range& range)
const
122 const int start = range.start;
123 const int end = range.end;
124 unsigned int srcByte;
125 unsigned int destByte;
128 for (y = start; y < end; y++)
130 for (x = 0; x < conv.width; x++)
132 srcByte = (x * conv.bpp) + (conv.sbpl * y);
133 destByte = (x * conv.bpp) + (conv.dbpl * y);
135 ((uchar*)conv.dstBuff)[destByte] = conv.srcBuff[srcByte + 2];
136 ((uchar*)conv.dstBuff)[destByte + 1] = conv.srcBuff[srcByte + 1];
137 ((uchar*)conv.dstBuff)[destByte + 2] = conv.srcBuff[srcByte];
143 bitmapToMat& operator=(
const bitmapToMat&);
145 const ConvertBuffer conv;
148class bitmapToMat4 :
public cv::ParallelLoopBody
151 bitmapToMat4(
const ConvertBuffer _conv)
155 void operator()(
const cv::Range& range)
const
157 const int start = range.start;
158 const int end = range.end;
159 unsigned int srcByte;
160 unsigned int srcByte8;
161 unsigned int destByte;
164 for (y = start; y < end; y++)
166 for (x = 0; x < conv.width; x++)
168 srcByte = (x * conv.bpp) + (conv.sbpl * y);
169 destByte = (x * 4) + (conv.dbpl * y);
170 srcByte8 = x + (conv.abpl * y);
172 ((uchar*)conv.dstBuff)[destByte] = conv.srcBuff[srcByte];
173 ((uchar*)conv.dstBuff)[destByte + 1] = conv.srcBuff[srcByte + 1];
174 ((uchar*)conv.dstBuff)[destByte + 2] = conv.srcBuff[srcByte + 2];
175 ((uchar*)conv.dstBuff)[destByte + 3] = conv.srcbuff8[srcByte8];
181 bitmapToMat4& operator=(
const bitmapToMat4&);
183 const ConvertBuffer conv;
186class matToBitmap4 :
public cv::ParallelLoopBody
189 matToBitmap4(
const ConvertBuffer _conv)
193 void operator()(
const cv::Range& range)
const
195 const int start = range.start;
196 const int end = range.end;
197 unsigned int srcByte;
198 unsigned int destByte;
199 unsigned int destByte8;
203 for (y = start; y < end; y++)
205 for (x = 0; x < conv.width; x++)
207 srcByte = (x * 4) + (conv.sbpl * y);
208 destByte = (x * conv.bpp) + (conv.dbpl * y);
209 destByte8 = x + (conv.abpl * y);
211 ((uchar*)conv.dstBuff)[destByte] = conv.srcBuff[srcByte];
212 ((uchar*)conv.dstBuff)[destByte + 1] = conv.srcBuff[srcByte + 1];
213 ((uchar*)conv.dstBuff)[destByte + 2] = conv.srcBuff[srcByte + 2];
214 ((uchar*)conv.srcbuff8)[destByte8] = conv.srcBuff[srcByte + 3];
220 matToBitmap4& operator=(
const matToBitmap4&);
222 const ConvertBuffer conv;
235 if (scolBitmap == 0 || scolBitmap8 == 0)
241 cv::Mat inmat[] = { mrgb, ma };
242 int from_to[] = { 0,0, 1,1, 2,2, 3,3 };
243 cv::mixChannels(inmat, 2, &mat, 1, from_to, 4);
264 int sbpl = scolBitmap->TailleW * scolBitmap->BytesPP;
265 int dbpl = scolBitmap->BPL;
268 memcpy(scolBitmap->bits, mat.data, scolBitmap->TailleW * scolBitmap->TailleH * scolBitmap->BytesPP);
271 ConvertBuffer conv(mat.data, scolBitmap->bits, scolBitmap->TailleW, scolBitmap->TailleH, sbpl, dbpl, scolBitmap->BytesPP);
274 cv::parallel_for_(cv::Range(0, scolBitmap->TailleH), bitmapToMat(conv));
284 int sbpl = scolBitmap->TailleW * scolBitmap->BytesPP;
285 int dbpl = scolBitmap->BPL;
289 memcpy(scolBitmap->bits, mat.data, scolBitmap->TailleW * scolBitmap->TailleH * scolBitmap->BytesPP);
293 ConvertBuffer conv(mat.data, scolBitmap->bits, scolBitmap->TailleW, scolBitmap->TailleH, sbpl, dbpl, scolBitmap->BytesPP);
296 cv::parallel_for_(cv::Range(0, scolBitmap->TailleH), bitmapToMatBGR(conv));
302 if (scolBitmap == 0 || scolBitmap8== 0)
310 cv::Mat out[] = { mrgb, ma };
313 int from_to[] = { 0,0, 1,1, 2,2, 3,3 };
314 cv::mixChannels(&mat, 1, out, 2, from_to, 4);
331 BlendBuffer(cv::Mat& mbase,
const cv::Mat& mtop,
float _mix)
335 width = (int)mbase.cols;
336 height = (int)mbase.rows;
337 mix = MAX(MIN(_mix, 1.0f), 0.0f);
338 bpp = mbase.channels();
349class blenderRGBA :
public cv::ParallelLoopBody
352 blenderRGBA(
const BlendBuffer _conv)
356 void operator()(
const cv::Range& range)
const
358 const int start = range.start;
359 const int end = range.end;
361 if (conv.base->channels() == 4)
363 typedef cv::Vec<uchar, 4> VT;
364 cv::MatIterator_<VT> it1 = conv.base->begin<VT>() + (start * conv.width);
365 cv::MatConstIterator_<VT> it1_end = conv.base->begin<VT>() + (end * conv.width);
366 cv::MatConstIterator_<VT> it2 = conv.top.begin<VT>() + (start * conv.width);
373 for (; it1 != it1_end; ++it1, ++it2)
379 alpha_base = ((float)(pix1[3])) / 255.0f;
380 alpha_top = conv.mix * ((float)(pix2[3])) / 255.0f;
381 alpha_final = alpha_top + alpha_base * (1.0f - alpha_top);
384 float r_base = (pix1[0] * alpha_base) * (1.0f - alpha_top);
385 float g_base = (pix1[1] * alpha_base) * (1.0f - alpha_top);
386 float b_base = (pix1[2] * alpha_base) * (1.0f - alpha_top);
388 float r_top = pix2[0] * alpha_top;
389 float g_top = pix2[1] * alpha_top;
390 float b_top = pix2[2] * alpha_top;
392 result[0] = (uchar)((r_top + r_base) / alpha_final);
393 result[1] = (uchar)((g_top + g_base) / alpha_final);
394 result[2] = (uchar)((b_top + b_base) / alpha_final);
395 result[3] = (uchar)(alpha_final * 255.0f);
400 else if (conv.base->channels() == 3)
402 typedef cv::Vec<uchar, 3> VT;
403 cv::MatIterator_<VT> it1 = conv.base->begin<VT>() + (start * conv.width);
404 cv::MatConstIterator_<VT> it1_end = conv.base->begin<VT>() + (end * conv.width);
405 cv::MatConstIterator_<VT> it2 = conv.top.begin<VT>() + (start * conv.width);
412 for (; it1 != it1_end; ++it1, ++it2)
419 alpha_top = conv.mix;
420 alpha_final = alpha_top + alpha_base * (1.0f - alpha_top);
423 float r_base = (pix1[0] * alpha_base) * (1.0f - alpha_top);
424 float r_top = pix2[0] * alpha_top;
425 float g_base = (pix1[1] * alpha_base) * (1.0f - alpha_top);
426 float b_base = (pix1[2] * alpha_base) * (1.0f - alpha_top);
427 float g_top = pix2[1] * alpha_top;
428 float b_top = pix2[2] * alpha_top;
430 result[0] = (uchar)((r_top + r_base) / alpha_final);
431 result[1] = (uchar)((g_top + g_base) / alpha_final);
432 result[2] = (uchar)((b_top + b_base) / alpha_final);
439 typedef cv::Vec<uchar, 1> VT;
440 cv::MatIterator_<VT> it1 = conv.base->begin<VT>() + (start * conv.width);
441 cv::MatConstIterator_<VT> it1_end = conv.base->begin<VT>() + (end * conv.width);
442 cv::MatConstIterator_<VT> it2 = conv.top.begin<VT>() + (start * conv.width);
449 for (; it1 != it1_end; ++it1, ++it2)
456 alpha_top = conv.mix;
457 alpha_final = alpha_top + alpha_base * (1.0f - alpha_top);
460 float r_base = (pix1[0] * alpha_base) * (1.0f - alpha_top);
461 float r_top = pix2[0] * alpha_top;
462 result[0] = (uchar)((r_top + r_base) / alpha_final);
470 blenderRGBA& operator=(
const blenderRGBA&);
471 const BlendBuffer conv;
476 if (base.rows != top.rows || base.cols != top.cols)
479 BlendBuffer conv(base, top, mix);
480 cv::parallel_for_(cv::Range(0, base.rows), blenderRGBA(conv));
486 BlendBufferSep(cv::Mat& mbase, cv::Mat& mabase,
const cv::Mat& mtop,
const cv::Mat& matop,
float _mix)
492 width = (int)mbase.cols;
493 height = (int)mbase.rows;
494 mix = MAX(MIN(_mix, 1.0f), 0.0f);
495 bpp = mbase.channels();
509class blenderRGBASep :
public cv::ParallelLoopBody
512 blenderRGBASep(
const BlendBufferSep _conv)
516 void operator()(
const cv::Range& range)
const
518 const int start = range.start;
519 const int end = range.end;
521 typedef cv::Vec<uchar, 3> VT;
522 cv::MatIterator_<VT> it1 = conv.base->begin<VT>() + (start * conv.width);
523 cv::MatIterator_<uchar> it1a = conv.abase->begin<uchar>() + (start * conv.width);
524 cv::MatConstIterator_<VT> it1_end = conv.base->begin<VT>() + (end * conv.width);
525 cv::MatConstIterator_<VT> it2 = conv.top.begin<VT>() + (start * conv.width);
526 cv::MatConstIterator_<uchar> it2a = conv.atop.begin<uchar>() + (start * conv.width);
533 for (; it1 != it1_end; ++it1, ++it2, ++it1a, ++it2a)
540 alpha_base = ((float)(pix1a)) / 255.0f;
541 alpha_top = conv.mix * ((float)(pix2a)) / 255.0f;
542 alpha_final = alpha_top + alpha_base * (1.0f - alpha_top);
545 float r_base = (pix1[0] * alpha_base) * (1.0f - alpha_top);
546 float r_top = pix2[0] * alpha_top;
547 result[0] = (uchar)((r_top + r_base) / alpha_final);
549 float g_base = (pix1[1] * alpha_base) * (1.0f - alpha_top);
550 float b_base = (pix1[2] * alpha_base) * (1.0f - alpha_top);
551 float g_top = pix2[1] * alpha_top;
552 float b_top = pix2[2] * alpha_top;
554 result[1] = (uchar)((g_top + g_base) / alpha_final);
555 result[2] = (uchar)((b_top + b_base) / alpha_final);
558 *it1a = (uchar)(alpha_final * 255.0f);
563 blenderRGBASep& operator=(
const blenderRGBASep&);
564 const BlendBufferSep conv;
569 if (base.rows != top.rows || base.cols != top.cols || abase.cols != atop.cols || abase.cols != atop.cols)
572 BlendBufferSep conv(base, abase, top, atop, mix);
573 cv::parallel_for_(cv::Range(0, base.rows), blenderRGBASep(conv));
578 int align = width * nbcomponents;
580 align += 4 - (align % 4);
587 if (scolBitmap->bits == 0)
592 int bitsType = CV_8UC3;
593 switch (scolBitmap->BytesPP)
608 return cv::Mat(scolBitmap->TailleH, scolBitmap->TailleW, bitsType, (
void*)scolBitmap->bits, align);
615 int bitsType = CV_8UC3;
616 switch (nbcomponents)
632 return cv::Mat(height, width, bitsType, (
void*)buffer, align32);
634 return cv::Mat(height, width, bitsType, (
void*)buffer);
640 int swidth = src.cols;
641 int sheight = src.rows;
642 int dwidth = dst.cols;
643 int dheight = dst.rows;
645 if ((swidth == 0) || (sheight == 0) || (dwidth == 0) || (dheight == 0))
651 srect.width += drect.x;
652 drect.width += drect.x;
655 else if (drect.x >= dwidth)
661 srect.height += drect.y;
662 drect.height += drect.y;
665 else if (drect.y >= dheight)
670 srect.width += srect.x;
671 drect.width += srect.x;
675 else if (srect.x >= swidth)
680 srect.height += srect.y;
681 drect.height += srect.y;
685 else if (srect.y >= sheight)
688 if ((srect.width <= 0) || (drect.width <= 0))
691 if (srect.width + srect.x > swidth)
693 drect.width -= (srect.width + srect.x) - swidth;
694 srect.width -= (srect.width + srect.x) - swidth;
695 if ((srect.width <= 0) || (drect.width <= 0))
699 if (drect.width + drect.x > dwidth)
701 srect.width -= (drect.width + drect.x) - dwidth;
702 drect.width -= (drect.width + drect.x) - dwidth;
703 if ((srect.width <= 0) || (drect.width <= 0))
707 if ((srect.height <= 0) || (drect.height <= 0))
710 if (srect.height + srect.y > sheight)
712 drect.height -= (srect.height + srect.y) - sheight;
713 srect.height -= (srect.height + srect.y) - sheight;
714 if ((srect.height <= 0) || (drect.height <= 0))
718 if (drect.height + drect.y > dheight)
720 srect.height -= (drect.height + drect.y) - dheight;
721 drect.height -= (drect.height + drect.y) - dheight;
722 if ((srect.height <= 0) || (drect.height <= 0))