Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

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