1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include "precomp.hpp"
43 #include "utils.hpp"
44
45 #define SCALE 14
46 #define cR (int)(0.299*(1 << SCALE) + 0.5)
47 #define cG (int)(0.587*(1 << SCALE) + 0.5)
48 #define cB ((1 << SCALE) - cR - cG)
49
icvCvt_BGR2Gray_8u_C3C1R(const uchar * rgb,int rgb_step,uchar * gray,int gray_step,CvSize size,int _swap_rb)50 void icvCvt_BGR2Gray_8u_C3C1R( const uchar* rgb, int rgb_step,
51 uchar* gray, int gray_step,
52 CvSize size, int _swap_rb )
53 {
54 int i;
55 int swap_rb = _swap_rb ? 2 : 0;
56 for( ; size.height--; gray += gray_step )
57 {
58 for( i = 0; i < size.width; i++, rgb += 3 )
59 {
60 int t = descale( rgb[swap_rb]*cB + rgb[1]*cG + rgb[swap_rb^2]*cR, SCALE );
61 gray[i] = (uchar)t;
62 }
63
64 rgb += rgb_step - size.width*3;
65 }
66 }
67
68
icvCvt_BGRA2Gray_16u_CnC1R(const ushort * rgb,int rgb_step,ushort * gray,int gray_step,CvSize size,int ncn,int _swap_rb)69 void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* rgb, int rgb_step,
70 ushort* gray, int gray_step,
71 CvSize size, int ncn, int _swap_rb )
72 {
73 int i;
74 int swap_rb = _swap_rb ? 2 : 0;
75 for( ; size.height--; gray += gray_step )
76 {
77 for( i = 0; i < size.width; i++, rgb += ncn )
78 {
79 int t = descale( rgb[swap_rb]*cB + rgb[1]*cG + rgb[swap_rb^2]*cR, SCALE );
80 gray[i] = (ushort)t;
81 }
82
83 rgb += rgb_step - size.width*ncn;
84 }
85 }
86
87
icvCvt_BGRA2Gray_8u_C4C1R(const uchar * rgba,int rgba_step,uchar * gray,int gray_step,CvSize size,int _swap_rb)88 void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* rgba, int rgba_step,
89 uchar* gray, int gray_step,
90 CvSize size, int _swap_rb )
91 {
92 int i;
93 int swap_rb = _swap_rb ? 2 : 0;
94 for( ; size.height--; gray += gray_step )
95 {
96 for( i = 0; i < size.width; i++, rgba += 4 )
97 {
98 int t = descale( rgba[swap_rb]*cB + rgba[1]*cG + rgba[swap_rb^2]*cR, SCALE );
99 gray[i] = (uchar)t;
100 }
101
102 rgba += rgba_step - size.width*4;
103 }
104 }
105
106
icvCvt_Gray2BGR_8u_C1C3R(const uchar * gray,int gray_step,uchar * bgr,int bgr_step,CvSize size)107 void icvCvt_Gray2BGR_8u_C1C3R( const uchar* gray, int gray_step,
108 uchar* bgr, int bgr_step, CvSize size )
109 {
110 int i;
111 for( ; size.height--; gray += gray_step )
112 {
113 for( i = 0; i < size.width; i++, bgr += 3 )
114 {
115 bgr[0] = bgr[1] = bgr[2] = gray[i];
116 }
117 bgr += bgr_step - size.width*3;
118 }
119 }
120
121
icvCvt_Gray2BGR_16u_C1C3R(const ushort * gray,int gray_step,ushort * bgr,int bgr_step,CvSize size)122 void icvCvt_Gray2BGR_16u_C1C3R( const ushort* gray, int gray_step,
123 ushort* bgr, int bgr_step, CvSize size )
124 {
125 int i;
126 for( ; size.height--; gray += gray_step/sizeof(gray[0]) )
127 {
128 for( i = 0; i < size.width; i++, bgr += 3 )
129 {
130 bgr[0] = bgr[1] = bgr[2] = gray[i];
131 }
132 bgr += bgr_step/sizeof(bgr[0]) - size.width*3;
133 }
134 }
135
136
icvCvt_BGRA2BGR_8u_C4C3R(const uchar * bgra,int bgra_step,uchar * bgr,int bgr_step,CvSize size,int _swap_rb)137 void icvCvt_BGRA2BGR_8u_C4C3R( const uchar* bgra, int bgra_step,
138 uchar* bgr, int bgr_step,
139 CvSize size, int _swap_rb )
140 {
141 int i;
142 int swap_rb = _swap_rb ? 2 : 0;
143 for( ; size.height--; )
144 {
145 for( i = 0; i < size.width; i++, bgr += 3, bgra += 4 )
146 {
147 uchar t0 = bgra[swap_rb], t1 = bgra[1];
148 bgr[0] = t0; bgr[1] = t1;
149 t0 = bgra[swap_rb^2]; bgr[2] = t0;
150 }
151 bgr += bgr_step - size.width*3;
152 bgra += bgra_step - size.width*4;
153 }
154 }
155
156
icvCvt_BGRA2BGR_16u_C4C3R(const ushort * bgra,int bgra_step,ushort * bgr,int bgr_step,CvSize size,int _swap_rb)157 void icvCvt_BGRA2BGR_16u_C4C3R( const ushort* bgra, int bgra_step,
158 ushort* bgr, int bgr_step,
159 CvSize size, int _swap_rb )
160 {
161 int i;
162 int swap_rb = _swap_rb ? 2 : 0;
163 for( ; size.height--; )
164 {
165 for( i = 0; i < size.width; i++, bgr += 3, bgra += 4 )
166 {
167 ushort t0 = bgra[swap_rb], t1 = bgra[1];
168 bgr[0] = t0; bgr[1] = t1;
169 t0 = bgra[swap_rb^2]; bgr[2] = t0;
170 }
171 bgr += bgr_step/sizeof(bgr[0]) - size.width*3;
172 bgra += bgra_step/sizeof(bgra[0]) - size.width*4;
173 }
174 }
175
176
icvCvt_BGRA2RGBA_8u_C4R(const uchar * bgra,int bgra_step,uchar * rgba,int rgba_step,CvSize size)177 void icvCvt_BGRA2RGBA_8u_C4R( const uchar* bgra, int bgra_step,
178 uchar* rgba, int rgba_step, CvSize size )
179 {
180 int i;
181 for( ; size.height--; )
182 {
183 for( i = 0; i < size.width; i++, bgra += 4, rgba += 4 )
184 {
185 uchar t0 = bgra[0], t1 = bgra[1];
186 uchar t2 = bgra[2], t3 = bgra[3];
187 rgba[0] = t2; rgba[1] = t1;
188 rgba[2] = t0; rgba[3] = t3;
189 }
190 bgra += bgra_step - size.width*4;
191 rgba += rgba_step - size.width*4;
192 }
193 }
194
icvCvt_BGRA2RGBA_16u_C4R(const ushort * bgra,int bgra_step,ushort * rgba,int rgba_step,CvSize size)195 void icvCvt_BGRA2RGBA_16u_C4R( const ushort* bgra, int bgra_step,
196 ushort* rgba, int rgba_step, CvSize size )
197 {
198 int i;
199 for( ; size.height--; )
200 {
201 for( i = 0; i < size.width; i++, bgra += 4, rgba += 4 )
202 {
203 ushort t0 = bgra[0], t1 = bgra[1];
204 ushort t2 = bgra[2], t3 = bgra[3];
205
206 rgba[0] = t2; rgba[1] = t1;
207 rgba[2] = t0; rgba[3] = t3;
208 }
209 bgra += bgra_step/sizeof(bgra[0]) - size.width*4;
210 rgba += rgba_step/sizeof(rgba[0]) - size.width*4;
211 }
212 }
213
214
icvCvt_BGR2RGB_8u_C3R(const uchar * bgr,int bgr_step,uchar * rgb,int rgb_step,CvSize size)215 void icvCvt_BGR2RGB_8u_C3R( const uchar* bgr, int bgr_step,
216 uchar* rgb, int rgb_step, CvSize size )
217 {
218 int i;
219 for( ; size.height--; )
220 {
221 for( i = 0; i < size.width; i++, bgr += 3, rgb += 3 )
222 {
223 uchar t0 = bgr[0], t1 = bgr[1], t2 = bgr[2];
224 rgb[2] = t0; rgb[1] = t1; rgb[0] = t2;
225 }
226 bgr += bgr_step - size.width*3;
227 rgb += rgb_step - size.width*3;
228 }
229 }
230
231
icvCvt_BGR2RGB_16u_C3R(const ushort * bgr,int bgr_step,ushort * rgb,int rgb_step,CvSize size)232 void icvCvt_BGR2RGB_16u_C3R( const ushort* bgr, int bgr_step,
233 ushort* rgb, int rgb_step, CvSize size )
234 {
235 int i;
236 for( ; size.height--; )
237 {
238 for( i = 0; i < size.width; i++, bgr += 3, rgb += 3 )
239 {
240 ushort t0 = bgr[0], t1 = bgr[1], t2 = bgr[2];
241 rgb[2] = t0; rgb[1] = t1; rgb[0] = t2;
242 }
243 bgr += bgr_step - size.width*3;
244 rgb += rgb_step - size.width*3;
245 }
246 }
247
248
249 typedef unsigned short ushort;
250
icvCvt_BGR5552Gray_8u_C2C1R(const uchar * bgr555,int bgr555_step,uchar * gray,int gray_step,CvSize size)251 void icvCvt_BGR5552Gray_8u_C2C1R( const uchar* bgr555, int bgr555_step,
252 uchar* gray, int gray_step, CvSize size )
253 {
254 int i;
255 for( ; size.height--; gray += gray_step, bgr555 += bgr555_step )
256 {
257 for( i = 0; i < size.width; i++ )
258 {
259 int t = descale( ((((ushort*)bgr555)[i] << 3) & 0xf8)*cB +
260 ((((ushort*)bgr555)[i] >> 2) & 0xf8)*cG +
261 ((((ushort*)bgr555)[i] >> 7) & 0xf8)*cR, SCALE );
262 gray[i] = (uchar)t;
263 }
264 }
265 }
266
267
icvCvt_BGR5652Gray_8u_C2C1R(const uchar * bgr565,int bgr565_step,uchar * gray,int gray_step,CvSize size)268 void icvCvt_BGR5652Gray_8u_C2C1R( const uchar* bgr565, int bgr565_step,
269 uchar* gray, int gray_step, CvSize size )
270 {
271 int i;
272 for( ; size.height--; gray += gray_step, bgr565 += bgr565_step )
273 {
274 for( i = 0; i < size.width; i++ )
275 {
276 int t = descale( ((((ushort*)bgr565)[i] << 3) & 0xf8)*cB +
277 ((((ushort*)bgr565)[i] >> 3) & 0xfc)*cG +
278 ((((ushort*)bgr565)[i] >> 8) & 0xf8)*cR, SCALE );
279 gray[i] = (uchar)t;
280 }
281 }
282 }
283
284
icvCvt_BGR5552BGR_8u_C2C3R(const uchar * bgr555,int bgr555_step,uchar * bgr,int bgr_step,CvSize size)285 void icvCvt_BGR5552BGR_8u_C2C3R( const uchar* bgr555, int bgr555_step,
286 uchar* bgr, int bgr_step, CvSize size )
287 {
288 int i;
289 for( ; size.height--; bgr555 += bgr555_step )
290 {
291 for( i = 0; i < size.width; i++, bgr += 3 )
292 {
293 int t0 = (((ushort*)bgr555)[i] << 3) & 0xf8;
294 int t1 = (((ushort*)bgr555)[i] >> 2) & 0xf8;
295 int t2 = (((ushort*)bgr555)[i] >> 7) & 0xf8;
296 bgr[0] = (uchar)t0; bgr[1] = (uchar)t1; bgr[2] = (uchar)t2;
297 }
298 bgr += bgr_step - size.width*3;
299 }
300 }
301
302
icvCvt_BGR5652BGR_8u_C2C3R(const uchar * bgr565,int bgr565_step,uchar * bgr,int bgr_step,CvSize size)303 void icvCvt_BGR5652BGR_8u_C2C3R( const uchar* bgr565, int bgr565_step,
304 uchar* bgr, int bgr_step, CvSize size )
305 {
306 int i;
307 for( ; size.height--; bgr565 += bgr565_step )
308 {
309 for( i = 0; i < size.width; i++, bgr += 3 )
310 {
311 int t0 = (((ushort*)bgr565)[i] << 3) & 0xf8;
312 int t1 = (((ushort*)bgr565)[i] >> 3) & 0xfc;
313 int t2 = (((ushort*)bgr565)[i] >> 8) & 0xf8;
314 bgr[0] = (uchar)t0; bgr[1] = (uchar)t1; bgr[2] = (uchar)t2;
315 }
316 bgr += bgr_step - size.width*3;
317 }
318 }
319
320
icvCvt_CMYK2BGR_8u_C4C3R(const uchar * cmyk,int cmyk_step,uchar * bgr,int bgr_step,CvSize size)321 void icvCvt_CMYK2BGR_8u_C4C3R( const uchar* cmyk, int cmyk_step,
322 uchar* bgr, int bgr_step, CvSize size )
323 {
324 int i;
325 for( ; size.height--; )
326 {
327 for( i = 0; i < size.width; i++, bgr += 3, cmyk += 4 )
328 {
329 int c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3];
330 c = k - ((255 - c)*k>>8);
331 m = k - ((255 - m)*k>>8);
332 y = k - ((255 - y)*k>>8);
333 bgr[2] = (uchar)c; bgr[1] = (uchar)m; bgr[0] = (uchar)y;
334 }
335 bgr += bgr_step - size.width*3;
336 cmyk += cmyk_step - size.width*4;
337 }
338 }
339
340
icvCvt_CMYK2Gray_8u_C4C1R(const uchar * cmyk,int cmyk_step,uchar * gray,int gray_step,CvSize size)341 void icvCvt_CMYK2Gray_8u_C4C1R( const uchar* cmyk, int cmyk_step,
342 uchar* gray, int gray_step, CvSize size )
343 {
344 int i;
345 for( ; size.height--; )
346 {
347 for( i = 0; i < size.width; i++, cmyk += 4 )
348 {
349 int c = cmyk[0], m = cmyk[1], y = cmyk[2], k = cmyk[3];
350 c = k - ((255 - c)*k>>8);
351 m = k - ((255 - m)*k>>8);
352 y = k - ((255 - y)*k>>8);
353 int t = descale( y*cB + m*cG + c*cR, SCALE );
354 gray[i] = (uchar)t;
355 }
356 gray += gray_step;
357 cmyk += cmyk_step - size.width*4;
358 }
359 }
360
361
CvtPaletteToGray(const PaletteEntry * palette,uchar * grayPalette,int entries)362 void CvtPaletteToGray( const PaletteEntry* palette, uchar* grayPalette, int entries )
363 {
364 int i;
365 for( i = 0; i < entries; i++ )
366 {
367 icvCvt_BGR2Gray_8u_C3C1R( (uchar*)(palette + i), 0, grayPalette + i, 0, cvSize(1,1) );
368 }
369 }
370
371
FillGrayPalette(PaletteEntry * palette,int bpp,bool negative)372 void FillGrayPalette( PaletteEntry* palette, int bpp, bool negative )
373 {
374 int i, length = 1 << bpp;
375 int xor_mask = negative ? 255 : 0;
376
377 for( i = 0; i < length; i++ )
378 {
379 int val = (i * 255/(length - 1)) ^ xor_mask;
380 palette[i].b = palette[i].g = palette[i].r = (uchar)val;
381 palette[i].a = 0;
382 }
383 }
384
385
IsColorPalette(PaletteEntry * palette,int bpp)386 bool IsColorPalette( PaletteEntry* palette, int bpp )
387 {
388 int i, length = 1 << bpp;
389
390 for( i = 0; i < length; i++ )
391 {
392 if( palette[i].b != palette[i].g ||
393 palette[i].b != palette[i].r )
394 return true;
395 }
396
397 return false;
398 }
399
400
FillUniColor(uchar * data,uchar * & line_end,int step,int width3,int & y,int height,int count3,PaletteEntry clr)401 uchar* FillUniColor( uchar* data, uchar*& line_end,
402 int step, int width3,
403 int& y, int height,
404 int count3, PaletteEntry clr )
405 {
406 do
407 {
408 uchar* end = data + count3;
409
410 if( end > line_end )
411 end = line_end;
412
413 count3 -= (int)(end - data);
414
415 for( ; data < end; data += 3 )
416 {
417 WRITE_PIX( data, clr );
418 }
419
420 if( data >= line_end )
421 {
422 line_end += step;
423 data = line_end - width3;
424 if( ++y >= height ) break;
425 }
426 }
427 while( count3 > 0 );
428
429 return data;
430 }
431
432
FillUniGray(uchar * data,uchar * & line_end,int step,int width,int & y,int height,int count,uchar clr)433 uchar* FillUniGray( uchar* data, uchar*& line_end,
434 int step, int width,
435 int& y, int height,
436 int count, uchar clr )
437 {
438 do
439 {
440 uchar* end = data + count;
441
442 if( end > line_end )
443 end = line_end;
444
445 count -= (int)(end - data);
446
447 for( ; data < end; data++ )
448 {
449 *data = clr;
450 }
451
452 if( data >= line_end )
453 {
454 line_end += step;
455 data = line_end - width;
456 if( ++y >= height ) break;
457 }
458 }
459 while( count > 0 );
460
461 return data;
462 }
463
464
FillColorRow8(uchar * data,uchar * indices,int len,PaletteEntry * palette)465 uchar* FillColorRow8( uchar* data, uchar* indices, int len, PaletteEntry* palette )
466 {
467 uchar* end = data + len*3;
468 while( (data += 3) < end )
469 {
470 *((PaletteEntry*)(data-3)) = palette[*indices++];
471 }
472 PaletteEntry clr = palette[indices[0]];
473 WRITE_PIX( data - 3, clr );
474 return data;
475 }
476
477
FillGrayRow8(uchar * data,uchar * indices,int len,uchar * palette)478 uchar* FillGrayRow8( uchar* data, uchar* indices, int len, uchar* palette )
479 {
480 int i;
481 for( i = 0; i < len; i++ )
482 {
483 data[i] = palette[indices[i]];
484 }
485 return data + len;
486 }
487
488
FillColorRow4(uchar * data,uchar * indices,int len,PaletteEntry * palette)489 uchar* FillColorRow4( uchar* data, uchar* indices, int len, PaletteEntry* palette )
490 {
491 uchar* end = data + len*3;
492
493 while( (data += 6) < end )
494 {
495 int idx = *indices++;
496 *((PaletteEntry*)(data-6)) = palette[idx >> 4];
497 *((PaletteEntry*)(data-3)) = palette[idx & 15];
498 }
499
500 int idx = indices[0];
501 PaletteEntry clr = palette[idx >> 4];
502 WRITE_PIX( data - 6, clr );
503
504 if( data == end )
505 {
506 clr = palette[idx & 15];
507 WRITE_PIX( data - 3, clr );
508 }
509 return end;
510 }
511
512
FillGrayRow4(uchar * data,uchar * indices,int len,uchar * palette)513 uchar* FillGrayRow4( uchar* data, uchar* indices, int len, uchar* palette )
514 {
515 uchar* end = data + len;
516 while( (data += 2) < end )
517 {
518 int idx = *indices++;
519 data[-2] = palette[idx >> 4];
520 data[-1] = palette[idx & 15];
521 }
522
523 int idx = indices[0];
524 uchar clr = palette[idx >> 4];
525 data[-2] = clr;
526
527 if( data == end )
528 {
529 clr = palette[idx & 15];
530 data[-1] = clr;
531 }
532 return end;
533 }
534
535
FillColorRow1(uchar * data,uchar * indices,int len,PaletteEntry * palette)536 uchar* FillColorRow1( uchar* data, uchar* indices, int len, PaletteEntry* palette )
537 {
538 uchar* end = data + len*3;
539
540 while( (data += 24) < end )
541 {
542 int idx = *indices++;
543 *((PaletteEntry*)(data - 24)) = palette[(idx & 128) != 0];
544 *((PaletteEntry*)(data - 21)) = palette[(idx & 64) != 0];
545 *((PaletteEntry*)(data - 18)) = palette[(idx & 32) != 0];
546 *((PaletteEntry*)(data - 15)) = palette[(idx & 16) != 0];
547 *((PaletteEntry*)(data - 12)) = palette[(idx & 8) != 0];
548 *((PaletteEntry*)(data - 9)) = palette[(idx & 4) != 0];
549 *((PaletteEntry*)(data - 6)) = palette[(idx & 2) != 0];
550 *((PaletteEntry*)(data - 3)) = palette[(idx & 1) != 0];
551 }
552
553 int idx = indices[0] << 24;
554 for( data -= 24; data < end; data += 3, idx += idx )
555 {
556 PaletteEntry clr = palette[idx < 0];
557 WRITE_PIX( data, clr );
558 }
559
560 return data;
561 }
562
563
FillGrayRow1(uchar * data,uchar * indices,int len,uchar * palette)564 uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette )
565 {
566 uchar* end = data + len;
567
568 while( (data += 8) < end )
569 {
570 int idx = *indices++;
571 *((uchar*)(data - 8)) = palette[(idx & 128) != 0];
572 *((uchar*)(data - 7)) = palette[(idx & 64) != 0];
573 *((uchar*)(data - 6)) = palette[(idx & 32) != 0];
574 *((uchar*)(data - 5)) = palette[(idx & 16) != 0];
575 *((uchar*)(data - 4)) = palette[(idx & 8) != 0];
576 *((uchar*)(data - 3)) = palette[(idx & 4) != 0];
577 *((uchar*)(data - 2)) = palette[(idx & 2) != 0];
578 *((uchar*)(data - 1)) = palette[(idx & 1) != 0];
579 }
580
581 int idx = indices[0] << 24;
582 for( data -= 8; data < end; data++, idx += idx )
583 {
584 data[0] = palette[idx < 0];
585 }
586
587 return data;
588 }
589
590
591 CV_IMPL void
cvConvertImage(const CvArr * srcarr,CvArr * dstarr,int flags)592 cvConvertImage( const CvArr* srcarr, CvArr* dstarr, int flags )
593 {
594 CvMat* temp = 0;
595
596 CV_FUNCNAME( "cvConvertImage" );
597
598 __BEGIN__;
599
600 CvMat srcstub, *src;
601 CvMat dststub, *dst;
602 int src_cn, dst_cn, swap_rb = flags & CV_CVTIMG_SWAP_RB;
603
604 CV_CALL( src = cvGetMat( srcarr, &srcstub ));
605 CV_CALL( dst = cvGetMat( dstarr, &dststub ));
606
607 src_cn = CV_MAT_CN( src->type );
608 dst_cn = CV_MAT_CN( dst->type );
609
610 if( src_cn != 1 && src_cn != 3 && src_cn != 4 )
611 CV_ERROR( CV_BadNumChannels, "Source image must have 1, 3 or 4 channels" );
612
613 if( CV_MAT_DEPTH( dst->type ) != CV_8U )
614 CV_ERROR( CV_BadDepth, "Destination image must be 8u" );
615
616 if( CV_MAT_CN(dst->type) != 1 && CV_MAT_CN(dst->type) != 3 )
617 CV_ERROR( CV_BadNumChannels, "Destination image must have 1 or 3 channels" );
618
619 if( !CV_ARE_DEPTHS_EQ( src, dst ))
620 {
621 int src_depth = CV_MAT_DEPTH(src->type);
622 double scale = src_depth <= CV_8S ? 1 : src_depth <= CV_32S ? 1./256 : 255;
623 double shift = src_depth == CV_8S || src_depth == CV_16S ? 128 : 0;
624
625 if( !CV_ARE_CNS_EQ( src, dst ))
626 {
627 temp = cvCreateMat( src->height, src->width,
628 (src->type & CV_MAT_CN_MASK)|(dst->type & CV_MAT_DEPTH_MASK));
629 cvConvertScale( src, temp, scale, shift );
630 src = temp;
631 }
632 else
633 {
634 cvConvertScale( src, dst, scale, shift );
635 src = dst;
636 }
637 }
638
639 if( src_cn != dst_cn || (src_cn == 3 && swap_rb) )
640 {
641 uchar *s = src->data.ptr, *d = dst->data.ptr;
642 int s_step = src->step, d_step = dst->step;
643 int code = src_cn*10 + dst_cn;
644 CvSize size(src->cols, src->rows);
645
646 if( CV_IS_MAT_CONT(src->type & dst->type) )
647 {
648 size.width *= size.height;
649 size.height = 1;
650 s_step = d_step = /*CV_STUB_STEP*/ (1 << 30);
651 }
652
653 switch( code )
654 {
655 case 13:
656 icvCvt_Gray2BGR_8u_C1C3R( s, s_step, d, d_step, size );
657 break;
658 case 31:
659 icvCvt_BGR2Gray_8u_C3C1R( s, s_step, d, d_step, size, swap_rb );
660 break;
661 case 33:
662 assert( swap_rb );
663 icvCvt_RGB2BGR_8u_C3R( s, s_step, d, d_step, size );
664 break;
665 case 41:
666 icvCvt_BGRA2Gray_8u_C4C1R( s, s_step, d, d_step, size, swap_rb );
667 break;
668 case 43:
669 icvCvt_BGRA2BGR_8u_C4C3R( s, s_step, d, d_step, size, swap_rb );
670 break;
671 default:
672 CV_ERROR( CV_StsUnsupportedFormat, "Unsupported combination of input/output formats" );
673 }
674 src = dst;
675 }
676
677 if( flags & CV_CVTIMG_FLIP )
678 {
679 CV_CALL( cvFlip( src, dst, 0 ));
680 }
681 else if( src != dst )
682 {
683 CV_CALL( cvCopy( src, dst ));
684 }
685
686 __END__;
687
688 cvReleaseMat( &temp );
689 }
690