Release 1.2.1
[syntekdriver.git] / stk11xx-bayer.c
blob2b12a949645cc662144f25b9439881ff48f2e47c
1 /**
2 * @file stk11xx-bayer.c
3 * @author Martin ROOS
4 * @date 2006-01-14
5 * @version v1.2.0
7 * @brief Driver for Syntek USB video camera
9 * @note Copyright (C) Nicolas VIVIEN
11 * @par Licences
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * @par SubVersion
28 * $Date: $
29 * $Revision: $
30 * $Author: $
31 * $HeadURL: $
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>
42 #include <linux/usb.h>
43 #include <media/v4l2-common.h>
45 #include "stk11xx.h"
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)))
53 void stk11xx_b2rgb24(uint8_t *, uint8_t *,
54 struct stk11xx_coord *, struct stk11xx_coord *,
55 const int, const int, const int);
56 void stk11xx_b2rgb32(uint8_t *, uint8_t *,
57 struct stk11xx_coord *, struct stk11xx_coord *,
58 const int, const int, const int);
59 void stk11xx_b2bgr24(uint8_t *, uint8_t *,
60 struct stk11xx_coord *, struct stk11xx_coord *,
61 const int, const int, const int);
62 void stk11xx_b2bgr32(uint8_t *, uint8_t *,
63 struct stk11xx_coord *, struct stk11xx_coord *,
64 const int, const int, const int);
66 void stk11xx_b2uyvy(uint8_t *, uint8_t *,
67 struct stk11xx_coord *, struct stk11xx_coord *,
68 const int, const int, const int);
69 void stk11xx_b2yuyv(uint8_t *, uint8_t *,
70 struct stk11xx_coord *, struct stk11xx_coord *,
71 const int, const int, const int);
74 void stk11xx_correct_brightness(uint8_t *, const int, const int,
75 const int, int);
78 static 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}
146 /**
147 * @brief Decompress a frame
149 * This function permits to decompress a frame from the video stream.
151 * @param dev Device structure
153 * @returns 0 if all is OK
155 int stk11xx_decompress(struct usb_stk11xx *dev)
157 int factor;
159 void *data;
160 void *image;
161 struct stk11xx_frame_buf *framebuf;
163 if (dev == NULL)
164 return -EFAULT;
166 framebuf = dev->read_frame;
168 if (framebuf == NULL)
169 return -EFAULT;
171 image = dev->image_data;
172 image += dev->images[dev->fill_image].offset;
174 data = framebuf->data;
176 switch (dev->resolution) {
177 case STK11XX_80x60:
178 factor = 8;
179 break;
181 case STK11XX_128x96:
182 factor = 5;
183 break;
185 case STK11XX_160x120:
186 factor = 4;
187 break;
189 case STK11XX_213x160:
190 factor = 3;
191 break;
193 case STK11XX_320x240:
194 factor = 2;
195 break;
197 case STK11XX_640x480:
198 factor = 1;
199 break;
201 case STK11XX_800x600:
202 factor = 1;
203 break;
205 case STK11XX_1024x768:
206 factor = 1;
207 break;
209 case STK11XX_1280x1024:
210 factor = 1;
211 break;
213 default:
214 return -EFAULT;
218 switch (dev->vsettings.palette) {
219 case STK11XX_PALETTE_RGB24:
220 stk11xx_b2rgb24(data, image, &dev->image, &dev->view,
221 dev->vsettings.hflip, dev->vsettings.vflip, factor);
222 break;
224 case STK11XX_PALETTE_RGB32:
225 stk11xx_b2rgb32(data, image, &dev->image, &dev->view,
226 dev->vsettings.hflip, dev->vsettings.vflip, factor);
227 break;
229 case STK11XX_PALETTE_BGR24:
230 stk11xx_b2bgr24(data, image, &dev->image, &dev->view,
231 dev->vsettings.hflip, dev->vsettings.vflip, factor);
232 break;
234 case STK11XX_PALETTE_BGR32:
235 stk11xx_b2bgr32(data, image, &dev->image, &dev->view,
236 dev->vsettings.hflip, dev->vsettings.vflip, factor);
237 break;
239 case STK11XX_PALETTE_UYVY:
240 stk11xx_b2uyvy(data, image, &dev->image, &dev->view,
241 dev->vsettings.hflip, dev->vsettings.vflip, factor);
242 break;
244 case STK11XX_PALETTE_YUYV:
245 stk11xx_b2yuyv(data, image, &dev->image, &dev->view,
246 dev->vsettings.hflip, dev->vsettings.vflip, factor);
247 break;
250 // stk11xx_correct_brightness(image, dev->view.x, dev->view.y,
251 // dev->vsettings.brightness, dev->vsettings.depth);
253 return 0;
257 /**
258 * @brief Correct the brightness of an image.
260 * This function permits to correct the brightness of an image.
262 * @param rgb Buffer to RGB data
263 * @param width Width of frame
264 * @param height Height of frame
265 * @param brightness Brightness correction
266 * @param depth Color depth
268 * @retval rgb Buffer to RGB data
270 void stk11xx_correct_brightness(uint8_t *rgb, const int width, const int height,
271 const int brightness, int depth)
273 int i;
274 int x;
276 depth = (depth == 24) ? 3 : 4;
278 if (brightness >= 32767) {
279 x = (brightness - 32767) / 256;
281 for (i = 0; i < (width * height * depth); i++) {
282 if ((*(rgb + i) + (unsigned char) x) > 255)
283 *(rgb + i) = 255;
284 else
285 *(rgb + i) += (unsigned char) x;
288 else {
289 x = (32767 - brightness) / 256;
291 for (i = 0; i < (width * height * depth); i++) {
292 if ((unsigned char) x > *(rgb + i))
293 *(rgb + i) = 0;
294 else
295 *(rgb + i) -= (unsigned char) x;
301 /**
302 * @brief This function permits to convert an image from bayer to RGB24
304 * @param bayer Buffer with the bayer data
305 * @param image Size of image
306 * @param view Size of view
307 * @param hflip Horizontal flip
308 * @param vflip Vertical flip
309 * @param factor Factor of redimensioning
311 * @retval rgb Buffer with the RGB data
313 void stk11xx_b2rgb24(uint8_t *bayer, uint8_t *rgb,
314 struct stk11xx_coord *image,
315 struct stk11xx_coord *view,
316 const int hflip, const int vflip,
317 const int factor) {
318 uint8_t *b;
320 int x, y; // Position in bayer image
321 int i, j; // Position in rgb image
323 int width = image->x;
324 int height = image->y;
326 int nwidth = width / factor;
327 int nheight = height / factor;
329 int offset;
330 int startx, stepx;
331 int starty, stepy;
334 // Calculate the initial position (on Y axis)
335 if (vflip) {
336 starty = height - 2;
337 stepy = -factor;
339 else {
340 starty = 0;
341 stepy = factor;
344 // Calculate the initial position (on X axis)
345 if (hflip) {
346 startx = width - 1;
347 stepx = -factor;
348 offset = width - 2;
350 else {
351 startx = 0;
352 stepx = factor;
353 offset = 1;
357 // Skip the first line
358 bayer += width;
360 // To center vertically the image in the view
361 rgb += ((view->y - nheight) / 2) * view->x * 3;
363 // To center horizontally the image in the view
364 rgb += ((view->x - nwidth) / 2) * 3;
366 // Clean the first line
367 memset(rgb, 0, nwidth * 3);
368 rgb += nwidth * 3;
371 // For each rgb line without the borders (first and last line)
372 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
373 // Go to the start of line
374 b = bayer + y * width + offset;
376 // Offset to center horizontally the image in the view
377 rgb += (view->x - nwidth) * 3;
379 if (y & 0x1) {
380 // Skip the first pixel
381 *rgb++ = 0;
382 *rgb++ = 0;
383 *rgb++ = 0;
385 // GBGBGB : Line process...
386 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
387 if (x & 0x1) {
388 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
389 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
390 *rgb++ = *b;
392 else {
393 *rgb++ = (*(b-width) + *(b+width)) >> 1;
394 *rgb++ = *b;
395 *rgb++ = (*(b-1) + *(b+1)) >> 1;
398 b += stepx;
401 // Skip the last pixel
402 *rgb++ = 0;
403 *rgb++ = 0;
404 *rgb++ = 0;
406 else {
407 // Skip the first pixel
408 *rgb++ = 0;
409 *rgb++ = 0;
410 *rgb++ = 0;
412 // RGRGRG : Line process...
413 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
414 if (x & 0x1) {
415 *rgb++ = (*(b-1) + *(b+1)) >> 1;
416 *rgb++ = *b;
417 *rgb++ = (*(b-width) + *(b+width)) >> 1;
419 else {
420 *rgb++ = *b;
421 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
422 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
425 b += stepx;
428 // Skip the last pixel
429 *rgb++ = 0;
430 *rgb++ = 0;
431 *rgb++ = 0;
435 // Clean the last line
436 memset(rgb, 0, nwidth * 3);
440 /**
441 * @brief This function permits to convert an image from bayer to RGB32
443 * @param bayer Buffer with the bayer data
444 * @param image Size of image
445 * @param view Size of view
446 * @param hflip Horizontal flip
447 * @param vflip Vertical flip
448 * @param factor Factor of redimensioning
450 * @retval rgb Buffer with the RGB data
452 void stk11xx_b2rgb32(uint8_t *bayer, uint8_t *rgb,
453 struct stk11xx_coord *image,
454 struct stk11xx_coord *view,
455 const int hflip, const int vflip,
456 const int factor) {
457 uint8_t *b;
459 int x, y; // Position in bayer image
460 int i, j; // Position in rgb image
462 int width = image->x;
463 int height = image->y;
465 int nwidth = width / factor;
466 int nheight = height / factor;
468 int offset;
469 int startx, stepx;
470 int starty, stepy;
473 // Calculate the initial position (on Y axis)
474 if (vflip) {
475 starty = height - 2;
476 stepy = -factor;
478 else {
479 starty = 0;
480 stepy = factor;
483 // Calculate the initial position (on X axis)
484 if (hflip) {
485 startx = width - 1;
486 stepx = -factor;
487 offset = width - 2;
489 else {
490 startx = 0;
491 stepx = factor;
492 offset = 1;
496 // Skip the first line
497 bayer += width;
499 // To center vertically the image in the view
500 rgb += ((view->y - nheight) / 2) * view->x * 4;
502 // To center horizontally the image in the view
503 rgb += ((view->x - nwidth) / 2) * 4;
505 // Clean the first line
506 memset(rgb, 0, nwidth * 4);
507 rgb += nwidth * 4;
510 // For each rgb line without the borders (first and last line)
511 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
512 // Go to the start of line
513 b = bayer + y * width + offset;
515 // Offset to center horizontally the image in the view
516 rgb += (view->x - nwidth) * 4;
518 if (y & 0x1) {
519 // Skip the first pixel
520 *rgb++ = 0;
521 *rgb++ = 0;
522 *rgb++ = 0;
523 *rgb++ = 0;
525 // GBGBGB : Line process...
526 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
527 if (x & 0x1) {
528 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
529 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
530 *rgb++ = *b;
531 *rgb++ = 0;
533 else {
534 *rgb++ = (*(b-width) + *(b+width)) >> 1;
535 *rgb++ = *b;
536 *rgb++ = (*(b-1) + *(b+1)) >> 1;
537 *rgb++ = 0;
540 b += stepx;
543 // Skip the last pixel
544 *rgb++ = 0;
545 *rgb++ = 0;
546 *rgb++ = 0;
547 *rgb++ = 0;
549 else {
550 // Skip the first pixel
551 *rgb++ = 0;
552 *rgb++ = 0;
553 *rgb++ = 0;
554 *rgb++ = 0;
556 // RGRGRG : Line process...
557 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
558 if (x & 0x1) {
559 *rgb++ = (*(b-1) + *(b+1)) >> 1;
560 *rgb++ = *b;
561 *rgb++ = (*(b-width) + *(b+width)) >> 1;
562 *rgb++ = 0;
564 else {
565 *rgb++ = *b;
566 *rgb++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
567 *rgb++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
568 *rgb++ = 0;
571 b += stepx;
574 // Skip the last pixel
575 *rgb++ = 0;
576 *rgb++ = 0;
577 *rgb++ = 0;
578 *rgb++ = 0;
582 // Clean the last line
583 memset(rgb, 0, nwidth * 4);
587 /**
588 * @brief This function permits to convert an image from bayer to BGR24
590 * @param bayer Buffer with the bayer data
591 * @param image Size of image
592 * @param view Size of view
593 * @param hflip Horizontal flip
594 * @param vflip Vertical flip
595 * @param factor Factor of redimensioning
597 * @retval bgr Buffer with the BGR data
599 void stk11xx_b2bgr24(uint8_t *bayer, uint8_t *bgr,
600 struct stk11xx_coord *image,
601 struct stk11xx_coord *view,
602 const int hflip, const int vflip,
603 const int factor) {
604 uint8_t *b;
606 int x, y; // Position in bayer image
607 int i, j; // Position in bgr image
609 int width = image->x;
610 int height = image->y;
612 int nwidth = width / factor;
613 int nheight = height / factor;
615 int offset;
616 int startx, stepx;
617 int starty, stepy;
620 // Calculate the initial position (on Y axis)
621 if (vflip) {
622 starty = height - 2;
623 stepy = -factor;
625 else {
626 starty = 0;
627 stepy = factor;
630 // Calculate the initial position (on X axis)
631 if (hflip) {
632 startx = width - 1;
633 stepx = -factor;
634 offset = width - 2;
636 else {
637 startx = 0;
638 stepx = factor;
639 offset = 1;
643 // Skip the first line
644 bayer += width;
646 // To center vertically the image in the view
647 bgr += ((view->y - nheight) / 2) * view->x * 3;
649 // To center horizontally the image in the view
650 bgr += ((view->x - nwidth) / 2) * 3;
652 // Clean the first line
653 memset(bgr, 0, nwidth * 3);
654 bgr += nwidth * 3;
657 // For each bgr line without the borders (first and last line)
658 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
659 // Go to the start of line
660 b = bayer + y * width + offset;
662 // Offset to center horizontally the image in the view
663 bgr += (view->x - nwidth) * 3;
665 if (y & 0x1) {
666 // Skip the first pixel
667 *bgr++ = 0;
668 *bgr++ = 0;
669 *bgr++ = 0;
671 // GBGBGB : Line process...
672 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
673 if (x & 0x1) {
674 *bgr++ = *b;
675 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
676 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
678 else {
679 *bgr++ = (*(b-1) + *(b+1)) >> 1;
680 *bgr++ = *b;
681 *bgr++ = (*(b-width) + *(b+width)) >> 1;
684 b += stepx;
687 // Skip the last pixel
688 *bgr++ = 0;
689 *bgr++ = 0;
690 *bgr++ = 0;
692 else {
693 // Skip the first pixel
694 *bgr++ = 0;
695 *bgr++ = 0;
696 *bgr++ = 0;
698 // RGRGRG : Line process...
699 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
700 if (x & 0x1) {
701 *bgr++ = (*(b-width) + *(b+width)) >> 1;
702 *bgr++ = *b;
703 *bgr++ = (*(b-1) + *(b+1)) >> 1;
705 else {
706 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
707 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
708 *bgr++ = *b;
711 b += stepx;
714 // Skip the last pixel
715 *bgr++ = 0;
716 *bgr++ = 0;
717 *bgr++ = 0;
721 // Clean the last line
722 memset(bgr, 0, nwidth * 3);
726 /**
727 * @brief This function permits to convert an image from bayer to BGR32
729 * @param bayer Buffer with the bayer data
730 * @param image Size of image
731 * @param view Size of view
732 * @param hflip Horizontal flip
733 * @param vflip Vertical flip
734 * @param factor Factor of redimensioning
736 * @retval bgr Buffer with the BGR data
738 void stk11xx_b2bgr32(uint8_t *bayer, uint8_t *bgr,
739 struct stk11xx_coord *image,
740 struct stk11xx_coord *view,
741 const int hflip, const int vflip,
742 const int factor) {
743 uint8_t *b;
745 int x, y; // Position in bayer image
746 int i, j; // Position in bgr image
748 int width = image->x;
749 int height = image->y;
751 int nwidth = width / factor;
752 int nheight = height / factor;
754 int offset;
755 int startx, stepx;
756 int starty, stepy;
759 // Calculate the initial position (on Y axis)
760 if (vflip) {
761 starty = height - 2;
762 stepy = -factor;
764 else {
765 starty = 0;
766 stepy = factor;
769 // Calculate the initial position (on X axis)
770 if (hflip) {
771 startx = width - 1;
772 stepx = -factor;
773 offset = width - 2;
775 else {
776 startx = 0;
777 stepx = factor;
778 offset = 1;
782 // Skip the first line
783 bayer += width;
785 // To center vertically the image in the view
786 bgr += ((view->y - nheight) / 2) * view->x * 4;
788 // To center horizontally the image in the view
789 bgr += ((view->x - nwidth) / 2) * 4;
791 // Clean the first line
792 memset(bgr, 0, nwidth * 4);
793 bgr += nwidth * 4;
796 // For each bgr line without the borders (first and last line)
797 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
798 // Go to the start of line
799 b = bayer + y * width + offset;
801 // Offset to center horizontally the image in the view
802 bgr += (view->x - nwidth) * 4;
804 if (y & 0x1) {
805 // Skip the first pixel
806 *bgr++ = 0;
807 *bgr++ = 0;
808 *bgr++ = 0;
809 *bgr++ = 0;
811 // GBGBGB : Line process...
812 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
813 if (x & 0x1) {
814 *bgr++ = *b;
815 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
816 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
817 *bgr++ = 0;
819 else {
820 *bgr++ = (*(b-1) + *(b+1)) >> 1;
821 *bgr++ = *b;
822 *bgr++ = (*(b-width) + *(b+width)) >> 1;
823 *bgr++ = 0;
826 b += stepx;
829 // Skip the last pixel
830 *bgr++ = 0;
831 *bgr++ = 0;
832 *bgr++ = 0;
833 *bgr++ = 0;
835 else {
836 // Skip the first pixel
837 *bgr++ = 0;
838 *bgr++ = 0;
839 *bgr++ = 0;
840 *bgr++ = 0;
842 // RGRGRG : Line process...
843 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
844 if (x & 0x1) {
845 *bgr++ = (*(b-width) + *(b+width)) >> 1;
846 *bgr++ = *b;
847 *bgr++ = (*(b-1) + *(b+1)) >> 1;
848 *bgr++ = 0;
850 else {
851 *bgr++ = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
852 *bgr++ = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
853 *bgr++ = *b;
854 *bgr++ = 0;
857 b += stepx;
860 // Skip the last pixel
861 *bgr++ = 0;
862 *bgr++ = 0;
863 *bgr++ = 0;
864 *bgr++ = 0;
868 // Clean the last line
869 memset(bgr, 0, nwidth * 4);
873 /**
874 * @brief This function permits to convert an image from bayer to YUV (UYVY)
876 * @param bayer Buffer with the bayer data
877 * @param image Size of image
878 * @param view Size of view
879 * @param hflip Horizontal flip
880 * @param vflip Vertical flip
881 * @param factor Factor of redimensioning
883 * @retval yuv Buffer with the YUV data
885 void stk11xx_b2uyvy(uint8_t *bayer, uint8_t *yuv,
886 struct stk11xx_coord *image,
887 struct stk11xx_coord *view,
888 const int hflip, const int vflip,
889 const int factor) {
890 uint8_t *b;
892 int x, y; // Position in bayer image
893 int i, j; // Position in yuv image
895 int pR, pG, pB;
896 int pY, pU, pV;
898 int width = image->x;
899 int height = image->y;
901 int nwidth = width / factor;
902 int nheight = height / factor;
904 int offset;
905 int startx, stepx;
906 int starty, stepy;
909 // Calculate the initial position (on Y axis)
910 if (vflip) {
911 starty = height - 2;
912 stepy = -factor;
914 else {
915 starty = 0;
916 stepy = factor;
919 // Calculate the initial position (on X axis)
920 if (hflip) {
921 startx = width - 1;
922 stepx = -factor;
923 offset = width - 2;
925 else {
926 startx = 0;
927 stepx = factor;
928 offset = 1;
931 // Background color...
932 memset(yuv, 16, width * 2);
933 for (i=0; i<width*2; i=i+2, *(yuv+i)=128);
934 for (i=1; i<height; i++)
935 memcpy(yuv+i*width*2, yuv, width*2);
937 // Skip the first line
938 bayer += width;
940 // To center vertically the image in the view
941 yuv += ((view->y - nheight) / 2) * view->x * 2;
943 // To center horizontally the image in the view
944 yuv += ((view->x - nwidth) / 2) * 2;
946 // Clean the first line
947 memset(yuv, 16, nwidth * 2);
948 for (i=0; i<nwidth*2; i=i+2, *(yuv+i)=128);
949 yuv += nwidth * 2;
952 // For each yuv line without the borders (first and last line)
953 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
954 // Go to the start of line
955 b = bayer + y * width + offset;
957 // Offset to center horizontally the image in the view
958 yuv += (view->x - nwidth) * 2;
960 if (y & 0x1) {
961 // Skip the first pixel
962 *yuv++ = 128;
963 *yuv++ = 16;
965 // GBGBGB : Line process...
966 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
967 if (x & 0x1) {
968 pR = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
969 pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
970 pB = *b;
972 else {
973 pR = (*(b-width) + *(b+width)) >> 1;
974 pG = *b;
975 pB = (*(b-1) + *(b+1)) >> 1;
978 pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2];
979 pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5];
980 pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7];
982 pY = CLIP(pY, 0,255);
983 pU = CLIP(pU, -127,127);
984 pV = CLIP(pV, -127,127);
986 if (i % 2){
987 *yuv++ = (112 * pU)/127 + 128; // U
988 *yuv++ = (219 * pY)/255 + 16; // Y
990 else {
991 *yuv++ = (112 * pV)/127 + 128; // V
992 *yuv++ = (219 * pY)/255 + 16; // Y
995 b += stepx;
998 // Skip the last pixel
999 *yuv++ = 128;
1000 *yuv++ = 16;
1002 else {
1003 // Skip the first pixel
1004 *yuv++ = 128;
1005 *yuv++ = 16;
1007 // RGRGRG : Line process...
1008 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
1009 if (x & 0x1) {
1010 pR = (*(b-1) + *(b+1)) >> 1;
1011 pG = *b;
1012 pB = (*(b-width) + *(b+width)) >> 1;
1014 else {
1015 pR = *b;
1016 pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
1017 pB = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
1020 pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2];
1021 pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5];
1022 pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7];
1024 pY = CLIP(pY, 0,255);
1025 pU = CLIP(pU, -127,127);
1026 pV = CLIP(pV, -127,127);
1028 if (i % 2){
1029 *yuv++ = (112 * pU)/127 + 128; // U
1030 *yuv++ = (219 * pY)/255 + 16; // Y
1032 else {
1033 *yuv++ = (112 * pV)/127 + 128; // V
1034 *yuv++ = (219 * pY)/255 + 16; // Y
1037 b += stepx;
1040 // Skip the last pixel
1041 *yuv++ = 128;
1042 *yuv++ = 16;
1046 // Clean the last line
1047 memset(yuv, 16, nwidth * 2);
1048 for (i=0; i<nwidth*2; i=i+2, *(yuv+i)=128);
1052 /**
1053 * @brief This function permits to convert an image from bayer to YUV (YUYV)
1055 * @param bayer Buffer with the bayer data
1056 * @param image Size of image
1057 * @param view Size of view
1058 * @param hflip Horizontal flip
1059 * @param vflip Vertical flip
1060 * @param factor Factor of redimensioning
1062 * @retval yuv Buffer with the YUV data
1064 void stk11xx_b2yuyv(uint8_t *bayer, uint8_t *yuv,
1065 struct stk11xx_coord *image,
1066 struct stk11xx_coord *view,
1067 const int hflip, const int vflip,
1068 const int factor) {
1069 uint8_t *b;
1071 int x, y; // Position in bayer image
1072 int i, j; // Position in yuv image
1074 int pR, pG, pB;
1075 int pY, pU, pV;
1077 int width = image->x;
1078 int height = image->y;
1080 int nwidth = width / factor;
1081 int nheight = height / factor;
1083 int offset;
1084 int startx, stepx;
1085 int starty, stepy;
1088 // Calculate the initial position (on Y axis)
1089 if (vflip) {
1090 starty = height - 2;
1091 stepy = -factor;
1093 else {
1094 starty = 0;
1095 stepy = factor;
1098 // Calculate the initial position (on X axis)
1099 if (hflip) {
1100 startx = width - 1;
1101 stepx = -factor;
1102 offset = width - 2;
1104 else {
1105 startx = 0;
1106 stepx = factor;
1107 offset = 1;
1110 // Background color...
1111 memset(yuv, 128, width * 2);
1112 for (i=0; i<width*2; i=i+2, *(yuv+i)=16);
1113 for (i=1; i<height; i++)
1114 memcpy(yuv+i*width*2, yuv, width*2);
1116 // Skip the first line
1117 bayer += width;
1119 // To center vertically the image in the view
1120 yuv += ((view->y - nheight) / 2) * view->x * 2;
1122 // To center horizontally the image in the view
1123 yuv += ((view->x - nwidth) / 2) * 2;
1125 // Clean the first line
1126 memset(yuv, 128, nwidth * 2);
1127 for (i=0; i<nwidth*2; i=i+2, *(yuv+i)=16);
1128 yuv += nwidth * 2;
1131 // For each yuv line without the borders (first and last line)
1132 for (j=0, y=starty; j<nheight-2; j++, y=y+stepy) {
1133 // Go to the start of line
1134 b = bayer + y * width + offset;
1136 // Offset to center horizontally the image in the view
1137 yuv += (view->x - nwidth) * 2;
1139 if (y & 0x1) {
1140 // Skip the first pixel
1141 *yuv++ = 16;
1142 *yuv++ = 128;
1144 // GBGBGB : Line process...
1145 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
1146 if (x & 0x1) {
1147 pR = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
1148 pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
1149 pB = *b;
1151 else {
1152 pR = (*(b-width) + *(b+width)) >> 1;
1153 pG = *b;
1154 pB = (*(b-1) + *(b+1)) >> 1;
1157 pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2];
1158 pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5];
1159 pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7];
1161 pY = CLIP(pY, 0,255);
1162 pU = CLIP(pU, -127,127);
1163 pV = CLIP(pV, -127,127);
1165 if (i % 2){
1166 *yuv++ = (219 * pY)/255 + 16; // Y
1167 *yuv++ = (112 * pU)/127 + 128; // U
1169 else {
1170 *yuv++ = (219 * pY)/255 + 16; // Y
1171 *yuv++ = (112 * pV)/127 + 128; // V
1174 b += stepx;
1177 // Skip the last pixel
1178 *yuv++ = 16;
1179 *yuv++ = 128;
1181 else {
1182 // Skip the first pixel
1183 *yuv++ = 16;
1184 *yuv++ = 128;
1186 // RGRGRG : Line process...
1187 for (i=0, x=startx; i<nwidth-2; i++, x=x+stepx) {
1188 if (x & 0x1) {
1189 pR = (*(b-1) + *(b+1)) >> 1;
1190 pG = *b;
1191 pB = (*(b-width) + *(b+width)) >> 1;
1193 else {
1194 pR = *b;
1195 pG = (*(b-width) + *(b-1) + *(b+1) + *(b+width)) >> 2;
1196 pB = (*(b-width-1) + *(b-width+1) + *(b+width-1) + *(b+width+1)) >> 2;
1199 pY = stk11xx_yuv_interp[pR][0] + stk11xx_yuv_interp[pG][1] + stk11xx_yuv_interp[pB][2];
1200 pU = stk11xx_yuv_interp[pR][3] + stk11xx_yuv_interp[pG][4] + stk11xx_yuv_interp[pB][5];
1201 pV = stk11xx_yuv_interp[pR][5] + stk11xx_yuv_interp[pG][6] + stk11xx_yuv_interp[pB][7];
1203 pY = CLIP(pY, 0,255);
1204 pU = CLIP(pU, -127,127);
1205 pV = CLIP(pV, -127,127);
1207 if (i % 2){
1208 *yuv++ = (219 * pY)/255 + 16; // Y
1209 *yuv++ = (112 * pU)/127 + 128; // U
1211 else {
1212 *yuv++ = (219 * pY)/255 + 16; // Y
1213 *yuv++ = (112 * pV)/127 + 128; // V
1216 b += stepx;
1219 // Skip the last pixel
1220 *yuv++ = 16;
1221 *yuv++ = 128;
1225 // Clean the last line
1226 memset(yuv, 128, nwidth * 2);
1227 for (i=0; i<nwidth*2; i=i+2, *(yuv+i)=16);