conversions.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2000-2003 Damien Douxchamps <ddouxchamps@users.sf.net>
3  * Dan Dennedy <dan@dennedy.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19 
20 #include <string.h>
21 #include "cmvision/conversions.h"
22 
23 #if !defined (WIN32)
24  // This doesn't need to be extern on Windows (why does it need to be elsewhere?)
25  extern void swab();
26 #endif
27 
28 // The following #define is there for the users who experience green/purple
29 // images in the display. This seems to be a videocard driver problem.
30 
31 //#define YUYV // instead of the standard UYVY
32 #define UYVY // it conforms to the yuv422 structure in the cmvision class.
33 
34 // color conversion functions from Bart Nabbe.
35 // corrected by Damien: bad coeficients in YUV2RGB
36 #define YUV2RGB(y, u, v, r, g, b)\
37  r = y + ((v*1436) >>10);\
38  g = y - ((u*352 + v*731) >> 10);\
39  b = y + ((u*1814) >> 10);\
40  r = r < 0 ? 0 : r;\
41  g = g < 0 ? 0 : g;\
42  b = b < 0 ? 0 : b;\
43  r = r > 255 ? 255 : r;\
44  g = g > 255 ? 255 : g;\
45  b = b > 255 ? 255 : b
46 
47 
48 #define RGB2YUV(r, g, b, y, u, v)\
49  y = (306*r + 601*g + 117*b) >> 10;\
50  u = ((-172*r - 340*g + 512*b) >> 10) + 128;\
51  v = ((512*r - 429*g - 83*b) >> 10) + 128;\
52  y = y < 0 ? 0 : y;\
53  u = u < 0 ? 0 : u;\
54  v = v < 0 ? 0 : v;\
55  y = y > 255 ? 255 : y;\
56  u = u > 255 ? 255 : u;\
57  v = v > 255 ? 255 : v
58 
59 #define CLIP(in, out)\
60 {\
61  in = in < 0 ? 0 : in;\
62  in = in > 255 ? 255 : in;\
63  out=in;\
64 }
65 
66 /**********************************************************************
67  *
68  * CONVERSION FUNCTIONS TO UYVY
69  *
70  **********************************************************************/
71 
72 void
73 yuyv2uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
74 {
75 #ifdef YUYV
76  swab(src, dest, NumPixels << 1);
77 #else
78  memcpy(dest,src, NumPixels<<1);
79 #endif
80 }
81 
82 void
83 uyvy2yuyv(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
84 {
85 #ifdef YUYV
86  swab(src, dest, NumPixels << 1);
87 #else
88  memcpy(dest,src, NumPixels<<1);
89 #endif
90 }
91 void
92 uyyvyy2uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
93 {
94  register int i=NumPixels + (NumPixels >> 1)-1;
95  register int j=(NumPixels << 1)-1;
96  register int y0, y1, y2, y3, u, v;
97 
98  while (i > 0) {
99  y3 = src[i--];
100  y2 = src[i--];
101  v = src[i--];
102  y1 = src[i--];
103  y0 = src[i--];
104  u = src[i--];
105 #ifdef YUYV
106  dest[j--] = v;
107  dest[j--] = y3;
108  dest[j--] = u;
109  dest[j--] = y2;
110 
111  dest[j--] = v;
112  dest[j--] = y1;
113  dest[j--] = u;
114  dest[j--] = y0;
115 #else // UYVY
116  dest[j--] = y3;
117  dest[j--] = v;
118  dest[j--] = y2;
119  dest[j--] = u;
120 
121  dest[j--] = y1;
122  dest[j--] = v;
123  dest[j--] = y0;
124  dest[j--] = u;
125 #endif
126  }
127 }
128 
129 void
130 uyv2uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
131 {
132  register int i = NumPixels + (NumPixels << 1)-1;
133  register int j = (NumPixels << 1)-1;
134  register int y0, y1, u0, u1, v0, v1;
135 
136  while (i > 0) {
137  v1 = src[i--];
138  y1 = src[i--];
139  u1 = src[i--];
140  v0 = src[i--];
141  y0 = src[i--];
142  u0 = src[i--];
143 
144 #ifdef YUYV
145  dest[j--] = (v0+v1) >> 1;
146  dest[j--] = y1;
147  dest[j--] = (u0+u1) >> 1;
148  dest[j--] = y0;
149 #else // UYVY
150  dest[j--] = y1;
151  dest[j--] = (v0+v1) >> 1;
152  dest[j--] = y0;
153  dest[j--] = (u0+u1) >> 1;
154 #endif
155  }
156 }
157 
158 
159 void
160 y2uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
161 {
162  register int i= NumPixels-1;
163  register int j = (NumPixels << 1)-1;
164  register int y0, y1;
165 
166  while (i > 0) {
167  y1 = src[i--];
168  y0 = src[i--];
169 #ifdef YUYV
170  dest[j--] = 128;
171  dest[j--] = y1;
172  dest[j--] = 128;
173  dest[j--] = y0;
174 #else // UYVY
175  dest[j--] = y1;
176  dest[j--] = 128;
177  dest[j--] = y0;
178  dest[j--] = 128;
179 #endif
180  }
181 }
182 
183 void
184 y162uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits)
185 {
186  register int i = (NumPixels << 1)-1;
187  register int j = (NumPixels << 1)-1;
188  register int y0, y1;
189  //fprintf(stderr,"Conv: Pix: %d Bpp: %d\n",NumPixels, bits);
190  while (i > 0) {
191  //fprintf(stderr,"%d ",i);
192  y1 = src[i--];
193  y1 = (y1 + (((int)src[i--])<<8))>>(bits-8);
194  y0 = src[i--];
195  y0 = (y0 + (((int)src[i--])<<8))>>(bits-8);
196 #ifdef YUYV
197  dest[j--] = 128;
198  dest[j--] = y1;
199  dest[j--] = 128;
200  dest[j--] = y0;
201 #else // UYVY
202  dest[j--] = y1;
203  dest[j--] = 128;
204  dest[j--] = y0;
205  dest[j--] = 128;
206 #endif
207  }
208 }
209 
210 void
211 y162y (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits)
212 {
213  register int i = (NumPixels<<1)-1;
214  register int j = NumPixels-1;
215  register int y;
216 
217  while (i > 0) {
218  y = src[i--];
219  dest[j--] = (y + (src[i--]<<8))>>(bits-8);
220  }
221 }
222 
223 void
224 rgb2uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
225 {
226  register int i = NumPixels + ( NumPixels << 1 )-1;
227  register int j = (NumPixels << 1)-1;
228  register int y0, y1, u0, u1, v0, v1 ;
229  register int r, g, b;
230 
231  while (i > 0) {
232  b = (unsigned char) src[i--];
233  g = (unsigned char) src[i--];
234  r = (unsigned char) src[i--];
235  RGB2YUV (r, g, b, y0, u0 , v0);
236  b = (unsigned char) src[i--];
237  g = (unsigned char) src[i--];
238  r = (unsigned char) src[i--];
239  RGB2YUV (r, g, b, y1, u1 , v1);
240 #ifdef YUYV
241  dest[j--] = (v0+v1) >> 1;
242  dest[j--] = y0;
243  dest[j--] = (u0+u1) >> 1;
244  dest[j--] = y1;
245 #else // UYVY
246  dest[j--] = y0;
247  dest[j--] = (v0+v1) >> 1;
248  dest[j--] = y1;
249  dest[j--] = (u0+u1) >> 1;
250 #endif
251  }
252 }
253 
254 void
255 rgb482uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
256 {
257  register int i = ( (NumPixels + ( NumPixels << 1 )) << 1 ) -1;
258  register int j = (NumPixels << 1)-1;
259  register int y0, y1, u0, u1, v0, v1 ;
260  register int r, g, b;
261 
262  while (i > 0) {
263  i--;
264  b = (unsigned char) src[i--];
265  i--;
266  g = (unsigned char) src[i--];
267  i--;
268  r = (unsigned char) src[i--];
269  i--;
270  RGB2YUV (r, g, b, y0, u0 , v0);
271  b = (unsigned char) src[i--];
272  i--;
273  g = (unsigned char) src[i--];
274  i--;
275  r = (unsigned char) src[i--];
276  RGB2YUV (r, g, b, y1, u1 , v1);
277 
278 #ifdef YUYV
279  dest[j--] = (v0+v1) >> 1;
280  dest[j--] = y0;
281  dest[j--] = (u0+u1) >> 1;
282  dest[j--] = y1;
283 #else // UYVY
284  dest[j--] = y0;
285  dest[j--] = (v0+v1) >> 1;
286  dest[j--] = y1;
287  dest[j--] = (u0+u1) >> 1;
288 #endif
289  }
290 }
291 
292 /**********************************************************************
293  *
294  * CONVERSION FUNCTIONS TO RGB 24bpp
295  *
296  **********************************************************************/
297 
298 void
299 rgb482rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
300 {
301  register int i = ((NumPixels + ( NumPixels << 1 )) << 1)-1;
302  register int j = NumPixels + ( NumPixels << 1 ) -1;
303 
304  while (i > 0) {
305  i--;
306  dest[j--]=src[i--];
307  i--;
308  dest[j--]=src[i--];
309  i--;
310  dest[j--]=src[i--];
311  }
312 }
313 
314 
315 void
316 uyv2rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
317 {
318  register int i = NumPixels + ( NumPixels << 1 ) -1;
319  register int j = NumPixels + ( NumPixels << 1 ) -1;
320  register int y, u, v;
321  register int r, g, b;
322 
323  while (i > 0) {
324  v = (unsigned char) src[i--] - 128;
325  y = (unsigned char) src[i--];
326  u = (unsigned char) src[i--] - 128;
327  YUV2RGB (y, u, v, r, g, b);
328  dest[j--] = b;
329  dest[j--] = g;
330  dest[j--] = r;
331  }
332 }
333 
334 void
335 uyvy2rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
336 {
337  register int i = (NumPixels << 1)-1;
338  register int j = NumPixels + ( NumPixels << 1 ) -1;
339  register int y0, y1, u, v;
340  register int r, g, b;
341 
342  while (i > 0) {
343  y1 = (unsigned char) src[i--];
344  v = (unsigned char) src[i--] - 128;
345  y0 = (unsigned char) src[i--];
346  u = (unsigned char) src[i--] - 128;
347  YUV2RGB (y1, u, v, r, g, b);
348  dest[j--] = b;
349  dest[j--] = g;
350  dest[j--] = r;
351  YUV2RGB (y0, u, v, r, g, b);
352  dest[j--] = b;
353  dest[j--] = g;
354  dest[j--] = r;
355  }
356 }
357 
358 
359 void
360 uyyvyy2rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
361 {
362  register int i = NumPixels + ( NumPixels >> 1 )-1;
363  register int j = NumPixels + ( NumPixels << 1 )-1;
364  register int y0, y1, y2, y3, u, v;
365  register int r, g, b;
366 
367  while (i > 0) {
368  y3 = (unsigned char) src[i--];
369  y2 = (unsigned char) src[i--];
370  v = (unsigned char) src[i--] - 128;
371  y1 = (unsigned char) src[i--];
372  y0 = (unsigned char) src[i--];
373  u = (unsigned char) src[i--] - 128;
374  YUV2RGB (y3, u, v, r, g, b);
375  dest[j--] = b;
376  dest[j--] = g;
377  dest[j--] = r;
378  YUV2RGB (y2, u, v, r, g, b);
379  dest[j--] = b;
380  dest[j--] = g;
381  dest[j--] = r;
382  YUV2RGB (y1, u, v, r, g, b);
383  dest[j--] = b;
384  dest[j--] = g;
385  dest[j--] = r;
386  YUV2RGB (y0, u, v, r, g, b);
387  dest[j--] = b;
388  dest[j--] = g;
389  dest[j--] = r;
390  }
391 }
392 
393 void
394 y2rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
395 {
396  register int i = NumPixels-1;
397  register int j = NumPixels + ( NumPixels << 1 )-1;
398  register int y;
399 
400  while (i > 0) {
401  y = (unsigned char) src[i--];
402  dest[j--] = y;
403  dest[j--] = y;
404  dest[j--] = y;
405  }
406 }
407 
408 void
409 y162rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits)
410 {
411  register int i = (NumPixels << 1)-1;
412  register int j = NumPixels + ( NumPixels << 1 )-1;
413  register int y;
414 
415  while (i > 0) {
416  y = src[i--];
417  y = (y + (src[i--]<<8))>>(bits-8);
418  dest[j--] = y;
419  dest[j--] = y;
420  dest[j--] = y;
421  }
422 }
423 
424 /****************************************************************
425  * Color conversion functions for cameras that can *
426  * output raw-Bayer pattern images, such as some Basler and *
427  * Point Grey camera. Most of the algos presented here com from *
428  * http://ise0.Stanford.EDU/~tingchen/main.htm and have been *
429  * converted from Matlab to C and extended to all elementary *
430  * patterns. *
431  ****************************************************************/
432 
433 void
434 BayerNearestNeighbor(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type)
435 {
436  unsigned char *outR, *outG, *outB;
437  register int i,j;
438 
439  // sx and sy should be even
440  switch (type) {
441  case BAYER_PATTERN_GRBG:
442  case BAYER_PATTERN_BGGR:
443  outR=&dest[0];
444  outG=&dest[1];
445  outB=&dest[2];
446  break;
447  case BAYER_PATTERN_GBRG:
448  case BAYER_PATTERN_RGGB:
449  outR=&dest[2];
450  outG=&dest[1];
451  outB=&dest[0];
452  break;
453  default:
454  outR=NULL;outG=NULL;outB=NULL;
455  break;
456  }
457 
458  switch (type) {
459  case BAYER_PATTERN_GRBG: //-------------------------------------------
460  case BAYER_PATTERN_GBRG:
461  // copy original RGB data to output images
462  for (i=0;i<sy;i+=2) {
463  for (j=0;j<sx;j+=2) {
464  outG[(i*sx+j)*3]=src[i*sx+j];
465  outG[((i+1)*sx+(j+1))*3]=src[(i+1)*sx+(j+1)];
466  outR[(i*sx+j+1)*3]=src[i*sx+j+1];
467  outB[((i+1)*sx+j)*3]=src[(i+1)*sx+j];
468  }
469  }
470  // R channel
471  for (i=0;i<sy;i+=2) {
472  for (j=0;j<sx-1;j+=2) {
473  outR[(i*sx+j)*3]=outR[(i*sx+j+1)*3];
474  outR[((i+1)*sx+j+1)*3]=outR[(i*sx+j+1)*3];
475  outR[((i+1)*sx+j)*3]=outR[(i*sx+j+1)*3];
476  }
477  }
478  // B channel
479  for (i=0;i<sy-1;i+=2) { //every two lines
480  for (j=0;j<sx-1;j+=2) {
481  outB[(i*sx+j)*3]=outB[((i+1)*sx+j)*3];
482  outB[(i*sx+j+1)*3]=outB[((i+1)*sx+j)*3];
483  outB[((i+1)*sx+j+1)*3]=outB[((i+1)*sx+j)*3];
484  }
485  }
486  // using lower direction for G channel
487 
488  // G channel
489  for (i=0;i<sy-1;i+=2)//every two lines
490  for (j=1;j<sx;j+=2)
491  outG[(i*sx+j)*3]=outG[((i+1)*sx+j)*3];
492 
493  for (i=1;i<sy-2;i+=2)//every two lines
494  for (j=0;j<sx-1;j+=2)
495  outG[(i*sx+j)*3]=outG[((i+1)*sx+j)*3];
496 
497  // copy it for the next line
498  for (j=0;j<sx-1;j+=2)
499  outG[((sy-1)*sx+j)*3]=outG[((sy-2)*sx+j)*3];
500 
501  break;
502  case BAYER_PATTERN_BGGR: //-------------------------------------------
503  case BAYER_PATTERN_RGGB:
504  // copy original data
505  for (i=0;i<sy;i+=2) {
506  for (j=0;j<sx;j+=2) {
507  outB[(i*sx+j)*3]=src[i*sx+j];
508  outR[((i+1)*sx+(j+1))*3]=src[(i+1)*sx+(j+1)];
509  outG[(i*sx+j+1)*3]=src[i*sx+j+1];
510  outG[((i+1)*sx+j)*3]=src[(i+1)*sx+j];
511  }
512  }
513  // R channel
514  for (i=0;i<sy;i+=2){
515  for (j=0;j<sx-1;j+=2) {
516  outR[(i*sx+j)*3]=outR[((i+1)*sx+j+1)*3];
517  outR[(i*sx+j+1)*3]=outR[((i+1)*sx+j+1)*3];
518  outR[((i+1)*sx+j)*3]=outR[((i+1)*sx+j+1)*3];
519  }
520  }
521  // B channel
522  for (i=0;i<sy-1;i+=2) { //every two lines
523  for (j=0;j<sx-1;j+=2) {
524  outB[((i+1)*sx+j)*3]=outB[(i*sx+j)*3];
525  outB[(i*sx+j+1)*3]=outB[(i*sx+j)*3];
526  outB[((i+1)*sx+j+1)*3]=outB[(i*sx+j)*3];
527  }
528  }
529  // using lower direction for G channel
530 
531  // G channel
532  for (i=0;i<sy-1;i+=2)//every two lines
533  for (j=0;j<sx-1;j+=2)
534  outG[(i*sx+j)*3]=outG[((i+1)*sx+j)*3];
535 
536  for (i=1;i<sy-2;i+=2)//every two lines
537  for (j=0;j<sx-1;j+=2)
538  outG[(i*sx+j+1)*3]=outG[((i+1)*sx+j+1)*3];
539 
540  // copy it for the next line
541  for (j=0;j<sx-1;j+=2)
542  outG[((sy-1)*sx+j+1)*3]=outG[((sy-2)*sx+j+1)*3];
543 
544  break;
545 
546  default: //-------------------------------------------
547  break;
548  }
549 }
550 
551 
552 void
553 BayerEdgeSense(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type)
554 {
555  unsigned char *outR, *outG, *outB;
556  register int i,j;
557  int dh, dv;
558  int tmp;
559 
560  // sx and sy should be even
561  switch (type) {
562  case BAYER_PATTERN_GRBG:
563  case BAYER_PATTERN_BGGR:
564  outR=&dest[0];
565  outG=&dest[1];
566  outB=&dest[2];
567  break;
568  case BAYER_PATTERN_GBRG:
569  case BAYER_PATTERN_RGGB:
570  outR=&dest[2];
571  outG=&dest[1];
572  outB=&dest[0];
573  break;
574  default:
575  outR=NULL;outG=NULL;outB=NULL;
576  break;
577  }
578 
579  switch (type) {
580  case BAYER_PATTERN_GRBG://---------------------------------------------------------
581  case BAYER_PATTERN_GBRG:
582  // copy original RGB data to output images
583  for (i=0;i<sy;i+=2) {
584  for (j=0;j<sx;j+=2) {
585  outG[(i*sx+j)*3]=src[i*sx+j];
586  outG[((i+1)*sx+(j+1))*3]=src[(i+1)*sx+(j+1)];
587  outR[(i*sx+j+1)*3]=src[i*sx+j+1];
588  outB[((i+1)*sx+j)*3]=src[(i+1)*sx+j];
589  }
590  }
591  // process GREEN channel
592  for (i=3;i<sy-2;i+=2) {
593  for (j=2;j<sx-3;j+=2) {
594  dh=abs((outB[(i*sx+j-2)*3]+outB[(i*sx+j+2)*3])/2-outB[(i*sx+j)*3]);
595  dv=abs((outB[((i-2)*sx+j)*3]+outB[((i+2)*sx+j)*3])/2-outB[(i*sx+j)*3]);
596  if (dh<dv)
597  tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3])/2;
598  else {
599  if (dh>dv)
600  tmp=(outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/2;
601  else
602  tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3]+outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/4;
603  }
604  CLIP(tmp,outG[(i*sx+j)*3]);
605  }
606  }
607 
608  for (i=2;i<sy-3;i+=2) {
609  for (j=3;j<sx-2;j+=2) {
610  dh=abs((outR[(i*sx+j-2)*3]+outR[(i*sx+j+2)*3])/2-outR[(i*sx+j)*3]);
611  dv=abs((outR[((i-2)*sx+j)*3]+outR[((i+2)*sx+j)*3])/2-outR[(i*sx+j)*3]);
612  if (dh<dv)
613  tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3])/2;
614  else {
615  if (dh>dv)
616  tmp=(outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/2;
617  else
618  tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3]+outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/4;
619  }
620  CLIP(tmp,outG[(i*sx+j)*3]);
621  }
622  }
623  // process RED channel
624  for (i=0;i<sy-1;i+=2) {
625  for (j=2;j<sx-1;j+=2) {
626  tmp=outG[(i*sx+j)*3]+(outR[(i*sx+j-1)*3]-outG[(i*sx+j-1)*3]+
627  outR[(i*sx+j+1)*3]-outG[(i*sx+j+1)*3])/2;
628  CLIP(tmp,outR[(i*sx+j)*3]);
629  }
630  }
631  for (i=1;i<sy-2;i+=2) {
632  for (j=1;j<sx;j+=2) {
633  tmp=outG[(i*sx+j)*3]+(outR[((i-1)*sx+j)*3]-outG[((i-1)*sx+j)*3]+
634  outR[((i+1)*sx+j)*3]-outG[((i+1)*sx+j)*3])/2;
635  CLIP(tmp,outR[(i*sx+j)*3]);
636  }
637  for (j=2;j<sx-1;j+=2) {
638  tmp=outG[(i*sx+j)*3]+(outR[((i-1)*sx+j-1)*3]-outG[((i-1)*sx+j-1)*3]+
639  outR[((i-1)*sx+j+1)*3]-outG[((i-1)*sx+j+1)*3]+
640  outR[((i+1)*sx+j-1)*3]-outG[((i+1)*sx+j-1)*3]+
641  outR[((i+1)*sx+j+1)*3]-outG[((i+1)*sx+j+1)*3])/4;
642  CLIP(tmp,outR[(i*sx+j)*3]);
643  }
644  }
645 
646  // process BLUE channel
647  for (i=1;i<sy;i+=2) {
648  for (j=1;j<sx-2;j+=2) {
649  tmp=outG[(i*sx+j)*3]+(outB[(i*sx+j-1)*3]-outG[(i*sx+j-1)*3]+
650  outB[(i*sx+j+1)*3]-outG[(i*sx+j+1)*3])/2;
651  CLIP(tmp,outB[(i*sx+j)*3]);
652  }
653  }
654  for (i=2;i<sy-1;i+=2) {
655  for (j=0;j<sx-1;j+=2) {
656  tmp=outG[(i*sx+j)*3]+(outB[((i-1)*sx+j)*3]-outG[((i-1)*sx+j)*3]+
657  outB[((i+1)*sx+j)*3]-outG[((i+1)*sx+j)*3])/2;
658  CLIP(tmp,outB[(i*sx+j)*3]);
659  }
660  for (j=1;j<sx-2;j+=2) {
661  tmp=outG[(i*sx+j)*3]+(outB[((i-1)*sx+j-1)*3]-outG[((i-1)*sx+j-1)*3]+
662  outB[((i-1)*sx+j+1)*3]-outG[((i-1)*sx+j+1)*3]+
663  outB[((i+1)*sx+j-1)*3]-outG[((i+1)*sx+j-1)*3]+
664  outB[((i+1)*sx+j+1)*3]-outG[((i+1)*sx+j+1)*3])/4;
665  CLIP(tmp,outB[(i*sx+j)*3]);
666  }
667  }
668  break;
669 
670  case BAYER_PATTERN_BGGR: //---------------------------------------------------------
671  case BAYER_PATTERN_RGGB:
672  // copy original RGB data to output images
673  for (i=0;i<sy;i+=2) {
674  for (j=0;j<sx;j+=2) {
675  outB[(i*sx+j)*3]=src[i*sx+j];
676  outR[((i+1)*sx+(j+1))*3]=src[(i+1)*sx+(j+1)];
677  outG[(i*sx+j+1)*3]=src[i*sx+j+1];
678  outG[((i+1)*sx+j)*3]=src[(i+1)*sx+j];
679  }
680  }
681  // process GREEN channel
682  for (i=2;i<sy-2;i+=2) {
683  for (j=2;j<sx-3;j+=2) {
684  dh=abs((outB[(i*sx+j-2)*3]+outB[(i*sx+j+2)*3])/2-outB[(i*sx+j)*3]);
685  dv=abs((outB[((i-2)*sx+j)*3]+outB[((i+2)*sx+j)*3])/2-outB[(i*sx+j)*3]);
686  if (dh<dv)
687  tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3])/2;
688  else {
689  if (dh>dv)
690  tmp=(outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/2;
691  else
692  tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3]+outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/4;
693  }
694  CLIP(tmp,outG[(i*sx+j)*3]);
695  }
696  }
697  for (i=3;i<sy-3;i+=2) {
698  for (j=3;j<sx-2;j+=2) {
699  dh=abs((outR[(i*sx+j-2)*3]+outR[(i*sx+j+2)*3])/2-outR[(i*sx+j)*3]);
700  dv=abs((outR[((i-2)*sx+j)*3]+outR[((i+2)*sx+j)*3])/2-outR[(i*sx+j)*3]);
701  if (dh<dv)
702  tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3])/2;
703  else {
704  if (dh>dv)
705  tmp=(outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/2;
706  else
707  tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3]+outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/4;
708  }
709  CLIP(tmp,outG[(i*sx+j)*3]);
710  }
711  }
712  // process RED channel
713  for (i=1;i<sy-1;i+=2) { // G-points (1/2)
714  for (j=2;j<sx-1;j+=2) {
715  tmp=outG[(i*sx+j)*3]+(outR[(i*sx+j-1)*3]-outG[(i*sx+j-1)*3]+
716  outR[(i*sx+j+1)*3]-outG[(i*sx+j+1)*3])/2;
717  CLIP(tmp,outR[(i*sx+j)*3]);
718  }
719  }
720  for (i=2;i<sy-2;i+=2) {
721  for (j=1;j<sx;j+=2) { // G-points (2/2)
722  tmp=outG[(i*sx+j)*3]+(outR[((i-1)*sx+j)*3]-outG[((i-1)*sx+j)*3]+
723  outR[((i+1)*sx+j)*3]-outG[((i+1)*sx+j)*3])/2;
724  CLIP(tmp,outR[(i*sx+j)*3]);
725  }
726  for (j=2;j<sx-1;j+=2) { // B-points
727  tmp=outG[(i*sx+j)*3]+(outR[((i-1)*sx+j-1)*3]-outG[((i-1)*sx+j-1)*3]+
728  outR[((i-1)*sx+j+1)*3]-outG[((i-1)*sx+j+1)*3]+
729  outR[((i+1)*sx+j-1)*3]-outG[((i+1)*sx+j-1)*3]+
730  outR[((i+1)*sx+j+1)*3]-outG[((i+1)*sx+j+1)*3])/4;
731  CLIP(tmp,outR[(i*sx+j)*3]);
732  }
733  }
734 
735  // process BLUE channel
736  for (i=0;i<sy;i+=2) {
737  for (j=1;j<sx-2;j+=2) {
738  tmp=outG[(i*sx+j)*3]+(outB[(i*sx+j-1)*3]-outG[(i*sx+j-1)*3]+
739  outB[(i*sx+j+1)*3]-outG[(i*sx+j+1)*3])/2;
740  CLIP(tmp,outB[(i*sx+j)*3]);
741  }
742  }
743  for (i=1;i<sy-1;i+=2) {
744  for (j=0;j<sx-1;j+=2) {
745  tmp=outG[(i*sx+j)*3]+(outB[((i-1)*sx+j)*3]-outG[((i-1)*sx+j)*3]+
746  outB[((i+1)*sx+j)*3]-outG[((i+1)*sx+j)*3])/2;
747  CLIP(tmp,outB[(i*sx+j)*3]);
748  }
749  for (j=1;j<sx-2;j+=2) {
750  tmp=outG[(i*sx+j)*3]+(outB[((i-1)*sx+j-1)*3]-outG[((i-1)*sx+j-1)*3]+
751  outB[((i-1)*sx+j+1)*3]-outG[((i-1)*sx+j+1)*3]+
752  outB[((i+1)*sx+j-1)*3]-outG[((i+1)*sx+j-1)*3]+
753  outB[((i+1)*sx+j+1)*3]-outG[((i+1)*sx+j+1)*3])/4;
754  CLIP(tmp,outB[(i*sx+j)*3]);
755  }
756  }
757  break;
758  default: //---------------------------------------------------------
759  fprintf(stderr,"Bad bayer pattern ID\n");
760  break;
761  }
762 }
763 
764 void
765 BayerDownsample(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type)
766 {
767  unsigned char *outR, *outG, *outB;
768  register int i,j;
769  int tmp;
770 
771  sx*=2;
772  sy*=2;
773 
774  switch (type) {
775  case BAYER_PATTERN_GRBG:
776  case BAYER_PATTERN_BGGR:
777  outR=&dest[0];
778  outG=&dest[1];
779  outB=&dest[2];
780  break;
781  case BAYER_PATTERN_GBRG:
782  case BAYER_PATTERN_RGGB:
783  outR=&dest[2];
784  outG=&dest[1];
785  outB=&dest[0];
786  break;
787  default:
788  outR=NULL;outG=NULL;outB=NULL;
789  break;
790  }
791 
792  switch (type) {
793  case BAYER_PATTERN_GRBG://---------------------------------------------------------
794  case BAYER_PATTERN_GBRG:
795  for (i=0;i<sy;i+=2) {
796  for (j=0;j<sx;j+=2) {
797  tmp=((src[i*sx+j]+src[(i+1)*sx+(j+1)])>>1);
798  CLIP(tmp,outG[(((i*sx)>>2)+(j>>1))*3]);
799  tmp=src[i*sx+j+1];
800  CLIP(tmp,outR[(((i*sx)>>2)+(j>>1))*3]);
801  tmp=src[(i+1)*sx+j];
802  CLIP(tmp,outB[(((i*sx)>>2)+(j>>1))*3]);
803  }
804  }
805  break;
806  case BAYER_PATTERN_BGGR://---------------------------------------------------------
807  case BAYER_PATTERN_RGGB:
808  for (i=0;i<sy;i+=2) {
809  for (j=0;j<sx;j+=2) {
810  tmp=((src[(i+1)*sx+j]+src[i*sx+(j+1)])>>1);
811  CLIP(tmp,outG[(((i*sx)>>2)+(j>>1))*3]);
812  tmp=src[(i+1)*sx+j+1];
813  CLIP(tmp,outR[(((i*sx)>>2)+(j>>1))*3]);
814  tmp=src[i*sx+j];
815  CLIP(tmp,outB[(((i*sx)>>2)+(j>>1))*3]);
816  }
817  }
818  break;
819  default: //---------------------------------------------------------
820  fprintf(stderr,"Bad bayer pattern ID\n");
821  break;
822  }
823 
824 }
825 
826 // change a 16bit stereo image (8bit/channel) into two 8bit images on top
827 // of each other
828 void
829 StereoDecode(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
830 {
831  register int i = NumPixels-1;
832  register int j = (NumPixels>>1)-1;
833  register int k = NumPixels-1;
834  //fprintf(stderr,"NumPixels: %d\n",NumPixels);
835  while (i > 0) {
836  dest[k--] = src[i--];
837  dest[j--] = src[i--];
838  }
839 }
y162rgb
void y162rgb(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits)
Definition: conversions.c:409
rgb2uyvy
void rgb2uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:224
BAYER_PATTERN_RGGB
@ BAYER_PATTERN_RGGB
Definition: conversions.h:49
rgb482uyvy
void rgb482uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:255
BayerDownsample
void BayerDownsample(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type)
Definition: conversions.c:765
y162uyvy
void y162uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits)
Definition: conversions.c:184
BAYER_PATTERN_GBRG
@ BAYER_PATTERN_GBRG
Definition: conversions.h:50
uyyvyy2rgb
void uyyvyy2rgb(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:360
BayerNearestNeighbor
void BayerNearestNeighbor(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type)
Definition: conversions.c:434
BAYER_PATTERN_GRBG
@ BAYER_PATTERN_GRBG
Definition: conversions.h:48
y2uyvy
void y2uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:160
BAYER_PATTERN_BGGR
@ BAYER_PATTERN_BGGR
Definition: conversions.h:47
conversions.h
BayerEdgeSense
void BayerEdgeSense(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type)
Definition: conversions.c:553
bayer_pattern_t
bayer_pattern_t
Definition: conversions.h:45
uyv2rgb
void uyv2rgb(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:316
rgb482rgb
void rgb482rgb(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:299
YUV2RGB
#define YUV2RGB(y, u, v, r, g, b)
Definition: conversions.c:36
swab
void swab()
y2rgb
void y2rgb(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:394
StereoDecode
void StereoDecode(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:829
yuyv2uyvy
void yuyv2uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:73
uyyvyy2uyvy
void uyyvyy2uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:92
y162y
void y162y(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits)
Definition: conversions.c:211
CLIP
#define CLIP(in, out)
Definition: conversions.c:59
uyvy2rgb
void uyvy2rgb(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:335
NULL
#define NULL
Definition: cmvision.h:82
uyv2uyvy
void uyv2uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:130
RGB2YUV
#define RGB2YUV(r, g, b, y, u, v)
Definition: conversions.c:48
uyvy2yuyv
void uyvy2yuyv(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels)
Definition: conversions.c:83


cmvision
Author(s): Nate Koenig, Nate Koenig
autogenerated on Wed Mar 2 2022 00:03:25