Syntek USB Video Camera
stk11xx-bayer.c
Go to the documentation of this file.
1
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/kernel.h>
37#include <linux/version.h>
38#include <linux/errno.h>
39#include <linux/slab.h>
40#include <linux/kref.h>
41
42#include <linux/usb.h>
43#include <media/v4l2-common.h>
44
45#include "stk11xx.h"
46
47
48#define MAX(a,b) ((a)>(b)?(a):(b))
49#define MIN(a,b) ((a)<(b)?(a):(b))
50#define CLIP(a,low,high) MAX((low),MIN((high),(a)))
51
52
53void stk11xx_b2rgb24(uint8_t *, uint8_t *,
54 struct stk11xx_coord *, struct stk11xx_coord *,
55 const int, const int, const int);
56void stk11xx_b2rgb32(uint8_t *, uint8_t *,
57 struct stk11xx_coord *, struct stk11xx_coord *,
58 const int, const int, const int);
59void stk11xx_b2bgr24(uint8_t *, uint8_t *,
60 struct stk11xx_coord *, struct stk11xx_coord *,
61 const int, const int, const int);
62void stk11xx_b2bgr32(uint8_t *, uint8_t *,
63 struct stk11xx_coord *, struct stk11xx_coord *,
64 const int, const int, const int);
65
66void stk11xx_b2uyvy(uint8_t *, uint8_t *,
67 struct stk11xx_coord *, struct stk11xx_coord *,
68 const int, const int, const int);
69void stk11xx_b2yuyv(uint8_t *, uint8_t *,
70 struct stk11xx_coord *, struct stk11xx_coord *,
71 const int, const int, const int);
72
73
74void stk11xx_correct_brightness(uint8_t *, const int, const int,
75 const int, int, int);
76
77
78static signed short stk11xx_yuv_interp[256][8] = {
79 {0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0},{0,1,0,0,0,1,-1,0},
80 {1,2,0,0,-1,2,-1,0},{1,2,0,0,-1,2,-2,0},{1,3,0,-1,-1,3,-2,0},{2,3,0,-1,-2,3,-2,0},
81 {2,4,0,-1,-2,4,-3,0},{2,5,1,-1,-2,4,-3,0},{2,5,1,-1,-3,5,-4,0},{3,6,1,-1,-3,5,-4,0},
82 {3,6,1,-2,-3,6,-5,0},{3,7,1,-2,-4,6,-5,-1},{4,7,1,-2,-4,7,-5,-1},{4,8,1,-2,-4,7,-6,-1},
83 {4,9,1,-2,-5,8,-6,-1},{5,9,1,-2,-5,8,-7,-1},{5,10,2,-3,-5,9,-7,-1},{5,10,2,-3,-6,9,-7,-1},
84 {5,11,2,-3,-6,10,-8,-1},{6,11,2,-3,-6,10,-8,-1},{6,12,2,-3,-7,11,-9,-1},{6,13,2,-3,-7,11,-9,-1},
85 {7,13,2,-4,-7,12,-10,-1},{7,14,2,-4,-8,12,-10,-2},{7,14,2,-4,-8,13,-10,-2},{8,15,3,-4,-8,13,-11,-2},
86 {8,15,3,-4,-9,14,-11,-2},{8,16,3,-4,-9,14,-12,-2},{8,17,3,-5,-9,15,-12,-2},{9,17,3,-5,-10,15,-12,-2},
87 {9,18,3,-5,-10,16,-13,-2},{9,18,3,-5,-10,16,-13,-2},{10,19,3,-5,-11,17,-14,-2},{10,19,3,-5,-11,17,-14,-2},
88 {10,20,4,-6,-11,18,-15,-2},{11,20,4,-6,-12,18,-15,-3},{11,21,4,-6,-12,19,-15,-3},{11,22,4,-6,-12,19,-16,-3},
89 {11,22,4,-6,-13,20,-16,-3},{12,23,4,-6,-13,20,-17,-3},{12,23,4,-7,-13,21,-17,-3},{12,24,4,-7,-14,21,-18,-3},
90 {13,24,5,-7,-14,22,-18,-3},{13,25,5,-7,-14,22,-18,-3},{13,26,5,-7,-15,23,-19,-3},{14,26,5,-7,-15,23,-19,-3},
91 {14,27,5,-8,-15,24,-20,-3},{14,27,5,-8,-16,24,-20,-3},{14,28,5,-8,-16,25,-20,-4},{15,28,5,-8,-16,25,-21,-4},
92 {15,29,5,-8,-17,26,-21,-4},{15,30,6,-8,-17,26,-22,-4},{16,30,6,-9,-17,27,-22,-4},{16,31,6,-9,-18,27,-23,-4},
93 {16,31,6,-9,-18,28,-23,-4},{17,32,6,-9,-18,28,-23,-4},{17,32,6,-9,-19,29,-24,-4},{17,33,6,-9,-19,29,-24,-4},
94 {17,34,6,-10,-19,30,-25,-4},{18,34,6,-10,-20,30,-25,-4},{18,35,7,-10,-20,31,-25,-5},{18,35,7,-10,-20,31,-26,-5},
95 {19,36,7,-10,-21,32,-26,-5},{19,36,7,-10,-21,32,-27,-5},{19,37,7,-11,-21,33,-27,-5},{20,37,7,-11,-22,33,-28,-5},
96 {20,38,7,-11,-22,34,-28,-5},{20,39,7,-11,-22,34,-28,-5},{20,39,7,-11,-23,35,-29,-5},{21,40,8,-11,-23,35,-29,-5},
97 {21,40,8,-12,-23,36,-30,-5},{21,41,8,-12,-24,36,-30,-5},{22,41,8,-12,-24,37,-30,-6},{22,42,8,-12,-24,37,-31,-6},
98 {22,43,8,-12,-25,38,-31,-6},{23,43,8,-12,-25,38,-32,-6},{23,44,8,-13,-25,39,-32,-6},{23,44,9,-13,-26,39,-33,-6},
99 {23,45,9,-13,-26,40,-33,-6},{24,45,9,-13,-26,40,-33,-6},{24,46,9,-13,-27,41,-34,-6},{24,47,9,-14,-27,41,-34,-6},
100 {25,47,9,-14,-27,42,-35,-6},{25,48,9,-14,-28,42,-35,-6},{25,48,9,-14,-28,43,-36,-6},{26,49,9,-14,-28,43,-36,-7},
101 {26,49,10,-14,-29,44,-36,-7},{26,50,10,-15,-29,44,-37,-7},{26,51,10,-15,-29,45,-37,-7},{27,51,10,-15,-30,45,-38,-7},
102 {27,52,10,-15,-30,46,-38,-7},{27,52,10,-15,-30,46,-38,-7},{28,53,10,-15,-31,47,-39,-7},{28,53,10,-16,-31,47,-39,-7},
103 {28,54,10,-16,-31,48,-40,-7},{29,54,11,-16,-32,48,-40,-7},{29,55,11,-16,-32,49,-41,-7},{29,56,11,-16,-32,49,-41,-8},
104 {29,56,11,-16,-33,50,-41,-8},{30,57,11,-17,-33,50,-42,-8},{30,57,11,-17,-33,51,-42,-8},{30,58,11,-17,-34,51,-43,-8},
105 {31,58,11,-17,-34,52,-43,-8},{31,59,11,-17,-34,52,-43,-8},{31,60,12,-17,-35,53,-44,-8},{31,60,12,-18,-35,53,-44,-8},
106 {32,61,12,-18,-35,54,-45,-8},{32,61,12,-18,-36,54,-45,-8},{32,62,12,-18,-36,55,-46,-8},{33,62,12,-18,-36,55,-46,-9},
107 {33,63,12,-18,-37,56,-46,-9},{33,64,12,-19,-37,56,-47,-9},{34,64,12,-19,-37,57,-47,-9},{34,65,13,-19,-38,57,-48,-9},
108 {34,65,13,-19,-38,58,-48,-9},{34,66,13,-19,-38,58,-48,-9},{35,66,13,-19,-39,59,-49,-9},{35,67,13,-20,-39,59,-49,-9},
109 {35,68,13,-20,-39,60,-50,-9},{36,68,13,-20,-40,60,-50,-9},{36,69,13,-20,-40,61,-51,-9},{36,69,14,-20,-40,61,-51,-9},
110 {37,70,14,-20,-41,62,-51,-10},{37,70,14,-21,-41,62,-52,-10},{37,71,14,-21,-41,63,-52,-10},{37,72,14,-21,-42,63,-53,-10},
111 {38,72,14,-21,-42,64,-53,-10},{38,73,14,-21,-42,64,-54,-10},{38,73,14,-21,-43,65,-54,-10},{39,74,14,-22,-43,65,-54,-10},
112 {39,74,15,-22,-43,66,-55,-10},{39,75,15,-22,-44,66,-55,-10},{40,75,15,-22,-44,67,-56,-10},{40,76,15,-22,-44,67,-56,-10},
113 {40,77,15,-22,-45,68,-56,-11},{40,77,15,-23,-45,68,-57,-11},{41,78,15,-23,-45,69,-57,-11},{41,78,15,-23,-46,69,-58,-11},
114 {41,79,15,-23,-46,70,-58,-11},{42,79,16,-23,-46,70,-59,-11},{42,80,16,-23,-47,71,-59,-11},{42,81,16,-24,-47,71,-59,-11},
115 {43,81,16,-24,-47,72,-60,-11},{43,82,16,-24,-48,72,-60,-11},{43,82,16,-24,-48,73,-61,-11},{43,83,16,-24,-48,73,-61,-11},
116 {44,83,16,-24,-49,74,-61,-12},{44,84,16,-25,-49,74,-62,-12},{44,85,17,-25,-49,75,-62,-12},{45,85,17,-25,-50,75,-63,-12},
117 {45,86,17,-25,-50,76,-63,-12},{45,86,17,-25,-50,76,-64,-12},{46,87,17,-25,-51,77,-64,-12},{46,87,17,-26,-51,77,-64,-12},
118 {46,88,17,-26,-51,78,-65,-12},{46,89,17,-26,-52,78,-65,-12},{47,89,18,-26,-52,79,-66,-12},{47,90,18,-26,-52,79,-66,-12},
119 {47,90,18,-26,-53,80,-66,-13},{48,91,18,-27,-53,80,-67,-13},{48,91,18,-27,-53,81,-67,-13},{48,92,18,-27,-54,81,-68,-13},
120 {49,92,18,-27,-54,82,-68,-13},{49,93,18,-27,-54,82,-69,-13},{49,94,18,-28,-54,83,-69,-13},{49,94,19,-28,-55,83,-69,-13},
121 {50,95,19,-28,-55,84,-70,-13},{50,95,19,-28,-55,84,-70,-13},{50,96,19,-28,-56,85,-71,-13},{51,96,19,-28,-56,85,-71,-13},
122 {51,97,19,-29,-56,86,-72,-13},{51,98,19,-29,-57,86,-72,-14},{52,98,19,-29,-57,87,-72,-14},{52,99,19,-29,-57,87,-73,-14},
123 {52,99,20,-29,-58,88,-73,-14},{52,100,20,-29,-58,88,-74,-14},{53,100,20,-30,-58,89,-74,-14},{53,101,20,-30,-59,89,-74,-14},
124 {53,102,20,-30,-59,90,-75,-14},{54,102,20,-30,-59,90,-75,-14},{54,103,20,-30,-60,91,-76,-14},{54,103,20,-30,-60,91,-76,-14},
125 {55,104,20,-31,-60,92,-77,-14},{55,104,21,-31,-61,92,-77,-15},{55,105,21,-31,-61,93,-77,-15},{55,106,21,-31,-61,93,-78,-15},
126 {56,106,21,-31,-62,94,-78,-15},{56,107,21,-31,-62,94,-79,-15},{56,107,21,-32,-62,95,-79,-15},{57,108,21,-32,-63,95,-79,-15},
127 {57,108,21,-32,-63,96,-80,-15},{57,109,22,-32,-63,96,-80,-15},{58,109,22,-32,-64,97,-81,-15},{58,110,22,-32,-64,97,-81,-15},
128 {58,111,22,-33,-64,98,-82,-15},{58,111,22,-33,-65,98,-82,-16},{59,112,22,-33,-65,99,-82,-16},{59,112,22,-33,-65,99,-83,-16},
129 {59,113,22,-33,-66,100,-83,-16},{60,113,22,-33,-66,100,-84,-16},{60,114,23,-34,-66,101,-84,-16},{60,115,23,-34,-67,101,-84,-16},
130 {60,115,23,-34,-67,102,-85,-16},{61,116,23,-34,-67,102,-85,-16},{61,116,23,-34,-68,103,-86,-16},{61,117,23,-34,-68,103,-86,-16},
131 {62,117,23,-35,-68,104,-87,-16},{62,118,23,-35,-69,104,-87,-16},{62,119,23,-35,-69,105,-87,-17},{63,119,24,-35,-69,105,-88,-17},
132 {63,120,24,-35,-70,106,-88,-17},{63,120,24,-35,-70,106,-89,-17},{63,121,24,-36,-70,107,-89,-17},{64,121,24,-36,-71,107,-90,-17},
133 {64,122,24,-36,-71,108,-90,-17},{64,123,24,-36,-71,108,-90,-17},{65,123,24,-36,-72,109,-91,-17},{65,124,24,-36,-72,109,-91,-17},
134 {65,124,25,-37,-72,110,-92,-17},{66,125,25,-37,-73,110,-92,-17},{66,125,25,-37,-73,111,-92,-18},{66,126,25,-37,-73,111,-93,-18},
135 {66,127,25,-37,-74,112,-93,-18},{67,127,25,-37,-74,112,-94,-18},{67,128,25,-38,-74,113,-94,-18},{67,128,25,-38,-75,113,-95,-18},
136 {68,129,25,-38,-75,114,-95,-18},{68,129,26,-38,-75,114,-95,-18},{68,130,26,-38,-76,115,-96,-18},{69,130,26,-38,-76,115,-96,-18},
137 {69,131,26,-39,-76,116,-97,-18},{69,132,26,-39,-77,116,-97,-18},{69,132,26,-39,-77,117,-97,-19},{70,133,26,-39,-77,117,-98,-19},
138 {70,133,26,-39,-78,118,-98,-19},{70,134,27,-39,-78,118,-99,-19},{71,134,27,-40,-78,119,-99,-19},{71,135,27,-40,-79,119,-100,-19},
139 {71,136,27,-40,-79,120,-100,-19},{72,136,27,-40,-79,120,-100,-19},{72,137,27,-40,-80,121,-101,-19},{72,137,27,-40,-80,121,-101,-19},
140 {72,138,27,-41,-80,122,-102,-19},{73,138,27,-41,-81,122,-102,-19},{73,139,28,-41,-81,123,-103,-19},{73,140,28,-41,-81,123,-103,-20},
141 {74,140,28,-41,-82,124,-103,-20},{74,141,28,-42,-82,124,-104,-20},{74,141,28,-42,-82,125,-104,-20},{75,142,28,-42,-83,125,-105,-20},
142 {75,142,28,-42,-83,126,-105,-20},{75,143,28,-42,-83,126,-105,-20},{75,144,28,-42,-84,127,-106,-20},{76,144,29,-43,-84,127,-106,-20}
143};
144
145
156{
157 int factor;
158
159 void *data;
160 void *image;
161 struct stk11xx_frame_buf *framebuf;
162
163 if (dev == NULL)
164 return -EFAULT;
165
166 framebuf = dev->read_frame;
167
168 if (framebuf == NULL)
169 return -EFAULT;
170
171 image = dev->image_data;
172 image += dev->images[dev->fill_image].offset;
173
174 data = framebuf->data;
175
176 switch (dev->resolution) {
177 case STK11XX_80x60:
178 factor = 8;
179 break;
180
181 case STK11XX_128x96:
182 factor = 5;
183 break;
184
185 case STK11XX_160x120:
186 factor = 4;
187 break;
188
189 case STK11XX_213x160:
190 factor = 3;
191 break;
192
193 case STK11XX_320x240:
194 factor = 2;
195 break;
196
197 case STK11XX_640x480:
198 factor = 1;
199 break;
200
201 case STK11XX_720x576:
202 case STK11XX_800x600:
203 factor = 2;
204 break;
205
206 case STK11XX_1024x768:
207 factor = 2;
208 break;
209
210 case STK11XX_1280x1024:
211 factor = 1;
212 break;
213
214 default:
215 return -EFAULT;
216 }
217
218
219 switch (dev->vsettings.palette) {
220 case STK11XX_PALETTE_RGB24:
221 stk11xx_b2rgb24(data, image, &dev->image, &dev->view,
222 dev->vsettings.hflip, dev->vsettings.vflip, factor);
223 break;
224
225 case STK11XX_PALETTE_RGB32:
226 stk11xx_b2rgb32(data, image, &dev->image, &dev->view,
227 dev->vsettings.hflip, dev->vsettings.vflip, factor);
228 break;
229
230 case STK11XX_PALETTE_BGR24:
231 stk11xx_b2bgr24(data, image, &dev->image, &dev->view,
232 dev->vsettings.hflip, dev->vsettings.vflip, factor);
233 break;
234
235 case STK11XX_PALETTE_BGR32:
236 stk11xx_b2bgr32(data, image, &dev->image, &dev->view,
237 dev->vsettings.hflip, dev->vsettings.vflip, factor);
238 break;
239
240 case STK11XX_PALETTE_UYVY:
241 stk11xx_b2uyvy(data, image, &dev->image, &dev->view,
242 dev->vsettings.hflip, dev->vsettings.vflip, factor);
243 break;
244
245 case STK11XX_PALETTE_YUYV:
246 stk11xx_b2yuyv(data, image, &dev->image, &dev->view,
247 dev->vsettings.hflip, dev->vsettings.vflip, factor);
248 break;
249 }
250
251 stk11xx_correct_brightness(image, dev->view.x, dev->view.y,
253
254 return 0;
255}
256
257
271void stk11xx_correct_brightness(uint8_t *img, const int width, const int height,
272 const int brightness, int palette, int depth)
273{
274 int i;
275 int x;
276
277
278 switch (palette) {
279 case STK11XX_PALETTE_RGB24:
280 case STK11XX_PALETTE_BGR24:
281 case STK11XX_PALETTE_RGB32:
282 case STK11XX_PALETTE_BGR32:
283 depth = (depth == 24) ? 3 : 4;
284
285 if (brightness >= 32767) {
286 x = (brightness - 32767) / 256;
287
288 for (i = 0; i < (width * height * depth); i++) {
289 if ((*(img + i) + (unsigned char) x) > 255)
290 *(img + i) = 255;
291 else
292 *(img + i) += (unsigned char) x;
293 }
294 }
295 else {
296 x = (32767 - brightness) / 256;
297
298 for (i = 0; i < (width * height * depth); i++) {
299 if ((unsigned char) x > *(img + i))
300 *(img + i) = 0;
301 else
302 *(img + i) -= (unsigned char) x;
303 }
304 }
305
306 break;
307
308 case STK11XX_PALETTE_UYVY:
309 depth = 2;
310
311 if (brightness >= 32767) {
312 x = (brightness - 32767) / 256;
313
314 for (i = 1; i < (width * height * depth); i=i+depth) {
315 if ((*(img + i) + (unsigned char) x) > 255)
316 *(img + i) = 255;
317 else
318 *(img + i) += (unsigned char) x;
319 }
320 }
321 else {
322 x = (32767 - brightness) / 256;
323
324 for (i = 1; i < (width * height * depth); i=i+depth) {
325 if ((unsigned char) x > *(img + i))
326 *(img + i) = 0;
327 else
328 *(img + i) -= (unsigned char) x;
329 }
330 }
331
332 break;
333
334 case STK11XX_PALETTE_YUYV:
335 depth = 2;
336
337 if (brightness >= 32767) {
338 x = (brightness - 32767) / 256;
339
340 for (i = 0; i < (width * height * depth); i=i+depth) {
341 if ((*(img + i) + (unsigned char) x) > 255)
342 *(img + i) = 255;
343 else
344 *(img + i) += (unsigned char) x;
345 }
346 }
347 else {
348 x = (32767 - brightness) / 256;
349
350 for (i = 0; i < (width * height * depth); i=i+depth) {
351 if ((unsigned char) x > *(img + i))
352 *(img + i) = 0;
353 else
354 *(img + i) -= (unsigned char) x;
355 }
356 }
357
358 break;
359 }
360}
361
362
375void stk11xx_b2rgb24(uint8_t *bayer, uint8_t *rgb,
376 struct stk11xx_coord *image,
377 struct stk11xx_coord *view,
378 const int hflip, const int vflip,
379 const int factor) {
380 uint8_t *b;
381
382 int x, y; // Position in bayer image
383 int i, j; // Position in rgb image
384
385 int width = image->x;
386 int height = image->y;
387
388 int nwidth = width / factor;
389 int nheight = height / factor;
390
391 int offset;
392 int startx, stepx;
393 int starty, stepy;
394
395
396 // Calculate the initial position (on Y axis)
397 if (vflip) {
398 starty = height - 2;
399 stepy = -factor;
400 }
401 else {
402 starty = 0;
403 stepy = factor;
404 }
405
406 // Calculate the initial position (on X axis)
407 if (hflip) {
408 startx = width - 1;
409 stepx = -factor;
410 offset = width - 2;
411 }
412 else {
413 startx = 0;
414 stepx = factor;
415 offset = 1;
416 }
417
418
419 // Skip the first line
420 bayer += width;
421
422 // To center vertically the image in the view
423 rgb += ((view->y - nheight) / 2) * view->x * 3;
424
425 // To center horizontally the image in the view
426 rgb += ((view->x - nwidth) / 2) * 3;
427
428 // Clean the first line
429 memset(rgb, 0, nwidth * 3);
430 rgb += nwidth * 3;
431
432
433 // For each rgb line without the borders (first and last line)
434 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
435 // Go to the start of line
436 b = bayer + y * width + offset;
437
438 // Offset to center horizontally the image in the view
439 rgb += (view->x - nwidth) * 3;
440
441 if (y & 0x1) {
442 // Skip the first pixel
443 *rgb++ = 0;
444 *rgb++ = 0;
445 *rgb++ = 0;
446
447 // GBGBGB : Line process...
448 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
449 if (x & 0x1) {
450 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
451 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
452 *rgb++ = *b;
453 }
454 else {
455 *rgb++ = (*(b-width) + *(b+width)) >> 1;
456 *rgb++ = *b;
457 *rgb++ = (*(b-1) + *(b+1)) >> 1;
458 }
459
460 b += stepx;
461 }
462
463 // Skip the last pixel
464 *rgb++ = 0;
465 *rgb++ = 0;
466 *rgb++ = 0;
467 }
468 else {
469 // Skip the first pixel
470 *rgb++ = 0;
471 *rgb++ = 0;
472 *rgb++ = 0;
473
474 // RGRGRG : Line process...
475 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
476 if (x & 0x1) {
477 *rgb++ = (*(b-1) + *(b+1)) >> 1;
478 *rgb++ = *b;
479 *rgb++ = (*(b-width) + *(b+width)) >> 1;
480 }
481 else {
482 *rgb++ = *b;
483 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
484 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
485 }
486
487 b += stepx;
488 }
489
490 // Skip the last pixel
491 *rgb++ = 0;
492 *rgb++ = 0;
493 *rgb++ = 0;
494 }
495 }
496
497 // Clean the last line
498 memset(rgb, 0, nwidth * 3);
499}
500
501
514void stk11xx_b2rgb32(uint8_t *bayer, uint8_t *rgb,
515 struct stk11xx_coord *image,
516 struct stk11xx_coord *view,
517 const int hflip, const int vflip,
518 const int factor) {
519 uint8_t *b;
520
521 int x, y; // Position in bayer image
522 int i, j; // Position in rgb image
523
524 int width = image->x;
525 int height = image->y;
526
527 int nwidth = width / factor;
528 int nheight = height / factor;
529
530 int offset;
531 int startx, stepx;
532 int starty, stepy;
533
534
535 // Calculate the initial position (on Y axis)
536 if (vflip) {
537 starty = height - 2;
538 stepy = -factor;
539 }
540 else {
541 starty = 0;
542 stepy = factor;
543 }
544
545 // Calculate the initial position (on X axis)
546 if (hflip) {
547 startx = width - 1;
548 stepx = -factor;
549 offset = width - 2;
550 }
551 else {
552 startx = 0;
553 stepx = factor;
554 offset = 1;
555 }
556
557
558 // Skip the first line
559 bayer += width;
560
561 // To center vertically the image in the view
562 rgb += ((view->y - nheight) / 2) * view->x * 4;
563
564 // To center horizontally the image in the view
565 rgb += ((view->x - nwidth) / 2) * 4;
566
567 // Clean the first line
568 memset(rgb, 0, nwidth * 4);
569 rgb += nwidth * 4;
570
571
572 // For each rgb line without the borders (first and last line)
573 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
574 // Go to the start of line
575 b = bayer + y * width + offset;
576
577 // Offset to center horizontally the image in the view
578 rgb += (view->x - nwidth) * 4;
579
580 if (y & 0x1) {
581 // Skip the first pixel
582 *rgb++ = 0;
583 *rgb++ = 0;
584 *rgb++ = 0;
585 *rgb++ = 0;
586
587 // GBGBGB : Line process...
588 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
589 if (x & 0x1) {
590 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
591 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
592 *rgb++ = *b;
593 *rgb++ = 0;
594 }
595 else {
596 *rgb++ = (*(b-width) + *(b+width)) >> 1;
597 *rgb++ = *b;
598 *rgb++ = (*(b-1) + *(b+1)) >> 1;
599 *rgb++ = 0;
600 }
601
602 b += stepx;
603 }
604
605 // Skip the last pixel
606 *rgb++ = 0;
607 *rgb++ = 0;
608 *rgb++ = 0;
609 *rgb++ = 0;
610 }
611 else {
612 // Skip the first pixel
613 *rgb++ = 0;
614 *rgb++ = 0;
615 *rgb++ = 0;
616 *rgb++ = 0;
617
618 // RGRGRG : Line process...
619 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
620 if (x & 0x1) {
621 *rgb++ = (*(b-1) + *(b+1)) >> 1;
622 *rgb++ = *b;
623 *rgb++ = (*(b-width) + *(b+width)) >> 1;
624 *rgb++ = 0;
625 }
626 else {
627 *rgb++ = *b;
628 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
629 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
630 *rgb++ = 0;
631 }
632
633 b += stepx;
634 }
635
636 // Skip the last pixel
637 *rgb++ = 0;
638 *rgb++ = 0;
639 *rgb++ = 0;
640 *rgb++ = 0;
641 }
642 }
643
644 // Clean the last line
645 memset(rgb, 0, nwidth * 4);
646}
647
648
661void stk11xx_b2bgr24(uint8_t *bayer, uint8_t *bgr,
662 struct stk11xx_coord *image,
663 struct stk11xx_coord *view,
664 const int hflip, const int vflip,
665 const int factor) {
666 uint8_t *b;
667
668 int x, y; // Position in bayer image
669 int i, j; // Position in bgr image
670
671 int width = image->x;
672 int height = image->y;
673
674 int nwidth = width / factor;
675 int nheight = height / factor;
676
677 int offset;
678 int startx, stepx;
679 int starty, stepy;
680
681
682 // Calculate the initial position (on Y axis)
683 if (vflip) {
684 starty = height - 2;
685 stepy = -factor;
686 }
687 else {
688 starty = 0;
689 stepy = factor;
690 }
691
692 // Calculate the initial position (on X axis)
693 if (hflip) {
694 startx = width - 1;
695 stepx = -factor;
696 offset = width - 2;
697 }
698 else {
699 startx = 0;
700 stepx = factor;
701 offset = 1;
702 }
703
704
705 // Skip the first line
706 bayer += width;
707
708 // To center vertically the image in the view
709 bgr += ((view->y - nheight) / 2) * view->x * 3;
710
711 // To center horizontally the image in the view
712 bgr += ((view->x - nwidth) / 2) * 3;
713
714 // Clean the first line
715 memset(bgr, 0, nwidth * 3);
716 bgr += nwidth * 3;
717
718
719 // For each bgr line without the borders (first and last line)
720 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
721 // Go to the start of line
722 b = bayer + y * width + offset;
723
724 // Offset to center horizontally the image in the view
725 bgr += (view->x - nwidth) * 3;
726
727 if (y & 0x1) {
728 // Skip the first pixel
729 *bgr++ = 0;
730 *bgr++ = 0;
731 *bgr++ = 0;
732
733 // GBGBGB : Line process...
734 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
735 if (x & 0x1) {
736 *bgr++ = *b;
737 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
738 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
739 }
740 else {
741 *bgr++ = (*(b-1) + *(b+1)) >> 1;
742 *bgr++ = *b;
743 *bgr++ = (*(b-width) + *(b+width)) >> 1;
744 }
745
746 b += stepx;
747 }
748
749 // Skip the last pixel
750 *bgr++ = 0;
751 *bgr++ = 0;
752 *bgr++ = 0;
753 }
754 else {
755 // Skip the first pixel
756 *bgr++ = 0;
757 *bgr++ = 0;
758 *bgr++ = 0;
759
760 // RGRGRG : Line process...
761 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
762 if (x & 0x1) {
763 *bgr++ = (*(b-width) + *(b+width)) >> 1;
764 *bgr++ = *b;
765 *bgr++ = (*(b-1) + *(b+1)) >> 1;
766 }
767 else {
768 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
769 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
770 *bgr++ = *b;
771 }
772
773 b += stepx;
774 }
775
776 // Skip the last pixel
777 *bgr++ = 0;
778 *bgr++ = 0;
779 *bgr++ = 0;
780 }
781 }
782
783 // Clean the last line
784 memset(bgr, 0, nwidth * 3);
785}
786
787
800void stk11xx_b2bgr32(uint8_t *bayer, uint8_t *bgr,
801 struct stk11xx_coord *image,
802 struct stk11xx_coord *view,
803 const int hflip, const int vflip,
804 const int factor) {
805 uint8_t *b;
806
807 int x, y; // Position in bayer image
808 int i, j; // Position in bgr image
809
810 int width = image->x;
811 int height = image->y;
812
813 int nwidth = width / factor;
814 int nheight = height / factor;
815
816 int offset;
817 int startx, stepx;
818 int starty, stepy;
819
820
821 // Calculate the initial position (on Y axis)
822 if (vflip) {
823 starty = height - 2;
824 stepy = -factor;
825 }
826 else {
827 starty = 0;
828 stepy = factor;
829 }
830
831 // Calculate the initial position (on X axis)
832 if (hflip) {
833 startx = width - 1;
834 stepx = -factor;
835 offset = width - 2;
836 }
837 else {
838 startx = 0;
839 stepx = factor;
840 offset = 1;
841 }
842
843
844 // Skip the first line
845 bayer += width;
846
847 // To center vertically the image in the view
848 bgr += ((view->y - nheight) / 2) * view->x * 4;
849
850 // To center horizontally the image in the view
851 bgr += ((view->x - nwidth) / 2) * 4;
852
853 // Clean the first line
854 memset(bgr, 0, nwidth * 4);
855 bgr += nwidth * 4;
856
857
858 // For each bgr line without the borders (first and last line)
859 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
860 // Go to the start of line
861 b = bayer + y * width + offset;
862
863 // Offset to center horizontally the image in the view
864 bgr += (view->x - nwidth) * 4;
865
866 if (y & 0x1) {
867 // Skip the first pixel
868 *bgr++ = 0;
869 *bgr++ = 0;
870 *bgr++ = 0;
871 *bgr++ = 0;
872
873 // GBGBGB : Line process...
874 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
875 if (x & 0x1) {
876 *bgr++ = *b;
877 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
878 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
879 *bgr++ = 0;
880 }
881 else {
882 *bgr++ = (*(b-1) + *(b+1)) >> 1;
883 *bgr++ = *b;
884 *bgr++ = (*(b-width) + *(b+width)) >> 1;
885 *bgr++ = 0;
886 }
887
888 b += stepx;
889 }
890
891 // Skip the last pixel
892 *bgr++ = 0;
893 *bgr++ = 0;
894 *bgr++ = 0;
895 *bgr++ = 0;
896 }
897 else {
898 // Skip the first pixel
899 *bgr++ = 0;
900 *bgr++ = 0;
901 *bgr++ = 0;
902 *bgr++ = 0;
903
904 // RGRGRG : Line process...
905 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
906 if (x & 0x1) {
907 *bgr++ = (*(b-width) + *(b+width)) >> 1;
908 *bgr++ = *b;
909 *bgr++ = (*(b-1) + *(b+1)) >> 1;
910 *bgr++ = 0;
911 }
912 else {
913 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
914 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
915 *bgr++ = *b;
916 *bgr++ = 0;
917 }
918
919 b += stepx;
920 }
921
922 // Skip the last pixel
923 *bgr++ = 0;
924 *bgr++ = 0;
925 *bgr++ = 0;
926 *bgr++ = 0;
927 }
928 }
929
930 // Clean the last line
931 memset(bgr, 0, nwidth * 4);
932}
933
934
947void stk11xx_b2uyvy(uint8_t *bayer, uint8_t *yuv,
948 struct stk11xx_coord *image,
949 struct stk11xx_coord *view,
950 const int hflip, const int vflip,
951 const int factor) {
952 uint8_t *b;
953
954 int x, y; // Position in bayer image
955 int i, j; // Position in yuv image
956
957 int pR, pG, pB;
958 int pY, pU, pV;
959
960 int width = image->x;
961 int height = image->y;
962
963 int nwidth = width / factor;
964 int nheight = height / factor;
965
966 int offset;
967 int startx, stepx;
968 int starty, stepy;
969
970
971 // Calculate the initial position (on Y axis)
972 if (vflip) {
973 starty = height - 2;
974 stepy = -factor;
975 }
976 else {
977 starty = 0;
978 stepy = factor;
979 }
980
981 // Calculate the initial position (on X axis)
982 if (hflip) {
983 startx = width - 1;
984 stepx = -factor;
985 offset = width - 2;
986 }
987 else {
988 startx = 0;
989 stepx = factor;
990 offset = 1;
991 }
992
993 // Background color...
994 memset(yuv, 16, width * 2);
995 for (i=0; i<width*2; i=i+2, *(yuv+i)=128);
996 for (i=1; i<height; i++)
997 memcpy(yuv+i*width*2, yuv, width*2);
998
999 // Skip the first line
1000 bayer += width;
1001
1002 // To center vertically the image in the view
1003 yuv += ((view->y - nheight) / 2) * view->x * 2;
1004
1005 // To center horizontally the image in the view
1006 yuv += ((view->x - nwidth) / 2) * 2;
1007
1008 // Clean the first line
1009 memset(yuv, 16, nwidth * 2);
1010 for (i=0; i<nwidth*2; i=i+2, *(yuv+i)=128);
1011 yuv += nwidth * 2;
1012
1013
1014 // For each yuv line without the borders (first and last line)
1015 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
1016 // Go to the start of line
1017 b = bayer + y * width + offset;
1018
1019 // Offset to center horizontally the image in the view
1020 yuv += (view->x - nwidth) * 2;
1021
1022 if (y & 0x1) {
1023 // Skip the first pixel
1024 *yuv++ = 128;
1025 *yuv++ = 16;
1026
1027 // GBGBGB : Line process...
1028 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
1029 if (x & 0x1) {
1030 pR = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
1031 pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
1032 pB = *b;
1033 }
1034 else {
1035 pR = (*(b-width) + *(b+width)) >> 1;
1036 pG = *b;
1037 pB = (*(b-1) + *(b+1)) >> 1;
1038 }
1039
1040 pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2];
1041 pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5];
1042 pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7];
1043
1044 pY = CLIP(pY, 0,255);
1045 pU = CLIP(pU, -127,127);
1046 pV = CLIP(pV, -127,127);
1047
1048 if (i % 2){
1049 *yuv++ = (112 * pU)/127 + 128; // U
1050 *yuv++ = (219 * pY)/255 + 16; // Y
1051 }
1052 else {
1053 *yuv++ = (112 * pV)/127 + 128; // V
1054 *yuv++ = (219 * pY)/255 + 16; // Y
1055 }
1056
1057 b += stepx;
1058 }
1059
1060 // Skip the last pixel
1061 *yuv++ = 128;
1062 *yuv++ = 16;
1063 }
1064 else {
1065 // Skip the first pixel
1066 *yuv++ = 128;
1067 *yuv++ = 16;
1068
1069 // RGRGRG : Line process...
1070 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
1071 if (x & 0x1) {
1072 pR = (*(b-1) + *(b+1)) >> 1;
1073 pG = *b;
1074 pB = (*(b-width) + *(b+width)) >> 1;
1075 }
1076 else {
1077 pR = *b;
1078 pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
1079 pB = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
1080 }
1081
1082 pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2];
1083 pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5];
1084 pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7];
1085
1086 pY = CLIP(pY, 0,255);
1087 pU = CLIP(pU, -127,127);
1088 pV = CLIP(pV, -127,127);
1089
1090 if (i % 2){
1091 *yuv++ = (112 * pU)/127 + 128; // U
1092 *yuv++ = (219 * pY)/255 + 16; // Y
1093 }
1094 else {
1095 *yuv++ = (112 * pV)/127 + 128; // V
1096 *yuv++ = (219 * pY)/255 + 16; // Y
1097 }
1098
1099 b += stepx;
1100 }
1101
1102 // Skip the last pixel
1103 *yuv++ = 128;
1104 *yuv++ = 16;
1105 }
1106 }
1107
1108 // Clean the last line
1109 memset(yuv, 16, nwidth * 2);
1110 for (i=0; i<nwidth*2; i=i+2, *(yuv+i)=128);
1111}
1112
1113
1126void stk11xx_b2yuyv(uint8_t *bayer, uint8_t *yuv,
1127 struct stk11xx_coord *image,
1128 struct stk11xx_coord *view,
1129 const int hflip, const int vflip,
1130 const int factor) {
1131 uint8_t *b;
1132
1133 int x, y; // Position in bayer image
1134 int i, j; // Position in yuv image
1135
1136 int pR, pG, pB;
1137 int pY, pU, pV;
1138
1139 int width = image->x;
1140 int height = image->y;
1141
1142 int nwidth = width / factor;
1143 int nheight = height / factor;
1144
1145 int offset;
1146 int startx, stepx;
1147 int starty, stepy;
1148
1149
1150 // Calculate the initial position (on Y axis)
1151 if (vflip) {
1152 starty = height - 2;
1153 stepy = -factor;
1154 }
1155 else {
1156 starty = 0;
1157 stepy = factor;
1158 }
1159
1160 // Calculate the initial position (on X axis)
1161 if (hflip) {
1162 startx = width - 1;
1163 stepx = -factor;
1164 offset = width - 2;
1165 }
1166 else {
1167 startx = 0;
1168 stepx = factor;
1169 offset = 1;
1170 }
1171
1172 // Background color...
1173 memset(yuv, 128, width * 2);
1174 for (i=0; i<width*2; i=i+2, *(yuv+i)=16);
1175 for (i=1; i<height; i++)
1176 memcpy(yuv+i*width*2, yuv, width*2);
1177
1178 // Skip the first line
1179 bayer += width;
1180
1181 // To center vertically the image in the view
1182 yuv += ((view->y - nheight) / 2) * view->x * 2;
1183
1184 // To center horizontally the image in the view
1185 yuv += ((view->x - nwidth) / 2) * 2;
1186
1187 // Clean the first line
1188 memset(yuv, 128, nwidth * 2);
1189 for (i=0; i<nwidth*2; i=i+2, *(yuv+i)=16);
1190 yuv += nwidth * 2;
1191
1192
1193 // For each yuv line without the borders (first and last line)
1194 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
1195 // Go to the start of line
1196 b = bayer + y * width + offset;
1197
1198 // Offset to center horizontally the image in the view
1199 yuv += (view->x - nwidth) * 2;
1200
1201 if (y & 0x1) {
1202 // Skip the first pixel
1203 *yuv++ = 16;
1204 *yuv++ = 128;
1205
1206 // GBGBGB : Line process...
1207 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
1208 if (x & 0x1) {
1209 pR = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
1210 pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
1211 pB = *b;
1212 }
1213 else {
1214 pR = (*(b-width) + *(b+width)) >> 1;
1215 pG = *b;
1216 pB = (*(b-1) + *(b+1)) >> 1;
1217 }
1218
1219 pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2];
1220 pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5];
1221 pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7];
1222
1223 pY = CLIP(pY, 0,255);
1224 pU = CLIP(pU, -127,127);
1225 pV = CLIP(pV, -127,127);
1226
1227 if (i % 2){
1228 *yuv++ = (219 * pY)/255 + 16; // Y
1229 *yuv++ = (112 * pU)/127 + 128; // U
1230 }
1231 else {
1232 *yuv++ = (219 * pY)/255 + 16; // Y
1233 *yuv++ = (112 * pV)/127 + 128; // V
1234 }
1235
1236 b += stepx;
1237 }
1238
1239 // Skip the last pixel
1240 *yuv++ = 16;
1241 *yuv++ = 128;
1242 }
1243 else {
1244 // Skip the first pixel
1245 *yuv++ = 16;
1246 *yuv++ = 128;
1247
1248 // RGRGRG : Line process...
1249 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
1250 if (x & 0x1) {
1251 pR = (*(b-1) + *(b+1)) >> 1;
1252 pG = *b;
1253 pB = (*(b-width) + *(b+width)) >> 1;
1254 }
1255 else {
1256 pR = *b;
1257 pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
1258 pB = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
1259 }
1260
1261 pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2];
1262 pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5];
1263 pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7];
1264
1265 pY = CLIP(pY, 0,255);
1266 pU = CLIP(pU, -127,127);
1267 pV = CLIP(pV, -127,127);
1268
1269 if (i % 2){
1270 *yuv++ = (219 * pY)/255 + 16; // Y
1271 *yuv++ = (112 * pU)/127 + 128; // U
1272 }
1273 else {
1274 *yuv++ = (219 * pY)/255 + 16; // Y
1275 *yuv++ = (112 * pV)/127 + 128; // V
1276 }
1277
1278 b += stepx;
1279 }
1280
1281 // Skip the last pixel
1282 *yuv++ = 16;
1283 *yuv++ = 128;
1284 }
1285 }
1286
1287 // Clean the last line
1288 memset(yuv, 128, nwidth * 2);
1289 for (i=0; i<nwidth*2; i=i+2, *(yuv+i)=16);
1290}
1291
1292
void stk11xx_b2rgb32(uint8_t *, uint8_t *, struct stk11xx_coord *, struct stk11xx_coord *, const int, const int, const int)
This function permits to convert an image from bayer to RGB32.
void stk11xx_b2uyvy(uint8_t *, uint8_t *, struct stk11xx_coord *, struct stk11xx_coord *, const int, const int, const int)
This function permits to convert an image from bayer to YUV (UYVY)
void stk11xx_b2rgb24(uint8_t *, uint8_t *, struct stk11xx_coord *, struct stk11xx_coord *, const int, const int, const int)
This function permits to convert an image from bayer to RGB24.
void stk11xx_correct_brightness(uint8_t *, const int, const int, const int, int, int)
Correct the brightness of an image.
void stk11xx_b2bgr24(uint8_t *, uint8_t *, struct stk11xx_coord *, struct stk11xx_coord *, const int, const int, const int)
This function permits to convert an image from bayer to BGR24.
void stk11xx_b2bgr32(uint8_t *, uint8_t *, struct stk11xx_coord *, struct stk11xx_coord *, const int, const int, const int)
This function permits to convert an image from bayer to BGR32.
int stk11xx_decompress(struct usb_stk11xx *dev)
Decompress a frame.
void stk11xx_b2yuyv(uint8_t *, uint8_t *, struct stk11xx_coord *, struct stk11xx_coord *, const int, const int, const int)
This function permits to convert an image from bayer to YUV (YUYV)
static int hflip
static int vflip
static int brightness
Driver for Syntek USB video camera.
unsigned long offset
Definition stk11xx.h:274
struct stk11xx_video vsettings
Definition stk11xx.h:336