2 * @file microdia-bayer.c
3 * @author Nicolas VIVIEN
7 * @brief Driver for Microdia USB video camera
9 * @note Copyright (C) Nicolas VIVIEN
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
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
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>
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)))
52 void raw6270_2i420(uint8_t *, uint8_t *, struct microdia_coord
*,
53 struct microdia_coord
*, const int, const int, const int);
54 void raw6270_2RGB24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
55 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
);
56 void raw6270_2BGR24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
57 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
);
58 void microdia_getraw(uint8_t *, uint8_t *, int);
60 void microdia_raw2i420(uint8_t *, uint8_t *, struct microdia_coord
*,
61 struct microdia_coord
*, const int, const int, const int);
62 void microdia_raw2bgr24(uint8_t *, uint8_t *, struct microdia_coord
*,
63 struct microdia_coord
*, const int, const int, const int);
64 void microdia_b2rgb24(uint8_t *, uint8_t *,
65 struct microdia_coord
*, struct microdia_coord
*,
66 const int, const int, const int);
67 void microdia_b2rgb32(uint8_t *, uint8_t *,
68 struct microdia_coord
*, struct microdia_coord
*,
69 const int, const int, const int);
70 void microdia_b2bgr24(uint8_t *, uint8_t *,
71 struct microdia_coord
*, struct microdia_coord
*,
72 const int, const int, const int);
73 void microdia_b2bgr32(uint8_t *, uint8_t *,
74 struct microdia_coord
*, struct microdia_coord
*,
75 const int, const int, const int);
77 void microdia_b2uyvy(uint8_t *, uint8_t *,
78 struct microdia_coord
*, struct microdia_coord
*,
79 const int, const int, const int);
80 void microdia_b2yuyv(uint8_t *, uint8_t *,
81 struct microdia_coord
*, struct microdia_coord
*,
82 const int, const int, const int);
85 void microdia_correct_brightness(uint8_t *, const int, const int,
89 static signed short microdia_yuv_interp
[256][8] = {
90 {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},
91 {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},
92 {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},
93 {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},
94 {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},
95 {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},
96 {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},
97 {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},
98 {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},
99 {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},
100 {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},
101 {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},
102 {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},
103 {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},
104 {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},
105 {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},
106 {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},
107 {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},
108 {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},
109 {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},
110 {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},
111 {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},
112 {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},
113 {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},
114 {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},
115 {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},
116 {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},
117 {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},
118 {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},
119 {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},
120 {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},
121 {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},
122 {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},
123 {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},
124 {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},
125 {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},
126 {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},
127 {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},
128 {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},
129 {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},
130 {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},
131 {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},
132 {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},
133 {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},
134 {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},
135 {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},
136 {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},
137 {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},
138 {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},
139 {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},
140 {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},
141 {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},
142 {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},
143 {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},
144 {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},
145 {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},
146 {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},
147 {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},
148 {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},
149 {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},
150 {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},
151 {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},
152 {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},
153 {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}
158 * @brief Decompress a frame
160 * This function permits to decompress a frame from the video stream.
162 * @param dev Device structure
164 * @returns 0 if all is OK
166 int microdia_decompress(struct usb_microdia
*dev
)
173 struct microdia_frame_buf
*framebuf
;
178 framebuf
= dev
->read_frame
;
180 if (framebuf
== NULL
)
183 if (dev
->flip_detect
) {
184 dev
->flip_detect(dev
);
186 image
= dev
->image_data
;
187 image
+= dev
->images
[dev
->fill_image
].offset
;
189 data
= framebuf
->data
;
190 size
= framebuf
->filled
;
192 switch (dev
->resolution
) {
197 /*case MICRODIA_128x96:
201 case MICRODIA_160x120
:
205 /*case MICRODIA_213x160:
209 case MICRODIA_320x240
:
213 case MICRODIA_640x480
:
217 case MICRODIA_800x600
:
221 case MICRODIA_1024x768
:
225 case MICRODIA_1280x1024
:
234 switch (dev
->vsettings
.palette
) {
235 case MICRODIA_PALETTE_RGB24
:
236 if(dev
->webcam_model
== MICRODIA_6270
237 || dev
->webcam_model
== MICRODIA_627B
)
239 raw6270_2RGB24(data
, image
, &dev
->image
, &dev
->view
,
240 dev
->vsettings
.hflip
, dev
->vsettings
.vflip
, factor
);
243 microdia_raw2bgr24(data
, image
, &dev
->image
, &dev
->view
,
244 dev
->vsettings
.hflip
, dev
->vsettings
.vflip
, factor
);
248 case MICRODIA_PALETTE_BGR24
:
249 if(dev
->webcam_model
== MICRODIA_6270
250 || dev
->webcam_model
== MICRODIA_627B
)
252 raw6270_2BGR24(data
, image
, &dev
->image
, &dev
->view
,
253 dev
->vsettings
.hflip
, dev
->vsettings
.vflip
, factor
);
256 microdia_raw2bgr24(data
, image
, &dev
->image
, &dev
->view
,
257 dev
->vsettings
.hflip
, dev
->vsettings
.vflip
, factor
);
262 case MICRODIA_PALETTE_RGB32:
264 microdia_b2rgb32(data, image, &dev->image, &dev->view,
265 dev->vsettings.hflip, dev->vsettings.vflip, factor);
268 case MICRODIA_PALETTE_BGR32:
269 microdia_b2bgr32(data, image, &dev->image, &dev->view,
270 dev->vsettings.hflip, dev->vsettings.vflip, factor);
273 case MICRODIA_PALETTE_UYVY:
274 microdia_b2uyvy(data, image, &dev->image, &dev->view,
275 dev->vsettings.hflip, dev->vsettings.vflip, factor);
278 case MICRODIA_PALETTE_YUYV:
279 microdia_b2yuyv(data, image, &dev->image, &dev->view,
280 dev->vsettings.hflip, dev->vsettings.vflip, factor);
283 case MICRODIA_PALETTE_I420
:
284 if(dev
->webcam_model
== MICRODIA_6270
285 || dev
->webcam_model
== MICRODIA_627B
)
287 raw6270_2i420(data
, image
, &dev
->image
, &dev
->view
,
288 dev
->vsettings
.hflip
, dev
->vsettings
.vflip
, factor
);
291 microdia_raw2i420(data
, image
, &dev
->image
, &dev
->view
,
292 dev
->vsettings
.hflip
, dev
->vsettings
.vflip
, factor
);
296 microdia_getraw(data
, image
, size
);
300 //microdia_correct_brightness(image, dev->view.x, dev->view.y,
301 // dev->vsettings.brightness, dev->vsettings.palette, dev->vsettings.depth);
308 * @brief Correct the brightness of an image.
310 * This function permits to correct the brightness of an image.
312 * @param img Buffer to RGB/YUV data
313 * @param width Width of frame
314 * @param height Height of frame
315 * @param brightness Brightness correction
317 * @param depth Color depth
319 * @retval rgb Buffer to RGB/YUV data
321 void microdia_correct_brightness(uint8_t *img
, const int width
, const int height
,
322 const int brightness
, int palette
, int depth
)
329 case MICRODIA_PALETTE_RGB24
:
330 case MICRODIA_PALETTE_BGR24
:
331 case MICRODIA_PALETTE_RGB32
:
332 case MICRODIA_PALETTE_BGR32
:
333 depth
= (depth
== 24) ? 3 : 4;
335 if (brightness
>= 32767) {
336 x
= (brightness
- 32767) / 256;
338 for (i
= 0; i
< (width
* height
* depth
); i
++) {
339 if ((*(img
+ i
) + (unsigned char) x
) > 255)
342 *(img
+ i
) += (unsigned char) x
;
346 x
= (32767 - brightness
) / 256;
348 for (i
= 0; i
< (width
* height
* depth
); i
++) {
349 if ((unsigned char) x
> *(img
+ i
))
352 *(img
+ i
) -= (unsigned char) x
;
358 case MICRODIA_PALETTE_UYVY
:
361 if (brightness
>= 32767) {
362 x
= (brightness
- 32767) / 256;
364 for (i
= 1; i
< (width
* height
* depth
); i
=i
+depth
) {
365 if ((*(img
+ i
) + (unsigned char) x
) > 255)
368 *(img
+ i
) += (unsigned char) x
;
372 x
= (32767 - brightness
) / 256;
374 for (i
= 1; i
< (width
* height
* depth
); i
=i
+depth
) {
375 if ((unsigned char) x
> *(img
+ i
))
378 *(img
+ i
) -= (unsigned char) x
;
384 case MICRODIA_PALETTE_YUYV
:
387 if (brightness
>= 32767) {
388 x
= (brightness
- 32767) / 256;
390 for (i
= 0; i
< (width
* height
* depth
); i
=i
+depth
) {
391 if ((*(img
+ i
) + (unsigned char) x
) > 255)
394 *(img
+ i
) += (unsigned char) x
;
398 x
= (32767 - brightness
) / 256;
400 for (i
= 0; i
< (width
* height
* depth
); i
=i
+depth
) {
401 if ((unsigned char) x
> *(img
+ i
))
404 *(img
+ i
) -= (unsigned char) x
;
414 * @brief This function permits to get the raw data. (without treatments)
416 * @param bayer Buffer with the bayer data
417 * @param size Length of bayer buffer
419 * @retval raw Buffer with the data from video sensor
421 void microdia_getraw(uint8_t *bayer
, uint8_t *raw
,
423 memcpy(raw
, bayer
, size
);
426 /* Table to translate Y offset to UV offset */
427 static int UVTranslate
[32] = {0, 1, 2, 3,
436 void microdia_raw2bgr24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
437 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
439 int i
= 0, x
= 0, y
= 0;
440 unsigned char *buf
= raw
;
441 unsigned char *buf3
= rgb
;
444 fwidth
= image
->x
/ factor
;
445 fheight
= image
->y
/ factor
;
447 while (i
< (image
->x
* image
->y
+ (image
->x
* image
->y
) / 2)) {
449 for (tile
= 0; tile
< 4; tile
++) {
452 for (subY
= 0; subY
< 4; subY
++) {
453 for (subX
= 0; subX
< 8; subX
++) {
454 int subI
= i
+ tile
* 32 + 8 * subY
+ subX
;
455 int subU
= i
+ 128 + UVTranslate
[tile
* 8 + 4 * (subY
>> 1) + (subX
>> 1)];
456 int subV
= subU
+ 32;
458 int relX
= x
+ (((tile
== 0) || (tile
== 1)) ? 0 : 8) + subX
; //tile 0, 1 to into left comumn
459 int relY
= y
+ (((tile
== 0) || (tile
== 2)) ? 0 : 4) + subY
; //tile 0, 2 go into top row
462 relX
= image
->x
- relX
;
465 relY
= image
->y
- relY
;
471 relX
+= (view
->x
- fwidth
) >> 1;
472 relY
+= (view
->y
- fheight
) >> 1;
473 if ((relX
< view
->x
) && (relY
< view
->y
)) {
480 ptr
= buf3
+ relY
* view
->x
* 3 + relX
* 3;
481 *ptr
= CLIP((298 * c
+ 516 * d
+ 128) >> 8, 0, 255);
483 *ptr
= CLIP((298 * c
- 100 * d
- 208 * e
+ 128) >> 8, 0, 255);
485 *ptr
= CLIP((298 * c
+ 409 * e
+ 128) >> 8, 0, 255);
500 void microdia_raw2i420(uint8_t *raw
, uint8_t *i420
, struct microdia_coord
*image
,
501 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
503 int i
= 0, x
= 0, y
= 0;
504 unsigned char *buf
= raw
;
505 unsigned char *buf3
= i420
;
508 fwidth
= image
->x
/ factor
;
509 fheight
= image
->y
/ factor
;
511 //printk(KERN_INFO "image: %d %d, view: %d %d factor: %d\n", image->x, image->y, view->x, view->y, factor);
513 while (i
< (image
->x
* image
->y
+ (image
->x
* image
->y
) / 2)) {
515 for (tile
= 0; tile
< 4; tile
++) {
518 for (subY
= 0; subY
< 4; subY
++) {
519 for (subX
= 0; subX
< 8; subX
++) {
520 int subI
= i
+ tile
* 32 + 8 * subY
+ subX
;
521 int subU
= i
+ 128 + UVTranslate
[tile
* 8 + 4 * (subY
>> 1) + (subX
>> 1)];
522 int subV
= subU
+ 32;
524 int relX
= x
+ (((tile
== 0) || (tile
== 1)) ? 0 : 8) + subX
; //tile 0, 1 to into left comumn
525 int relY
= y
+ (((tile
== 0) || (tile
== 2)) ? 0 : 4) + subY
; //tile 0, 2 go into top row
528 relX
= image
->x
- relX
;
531 relY
= image
->y
- relY
;
537 relX
+= (view
->x
- fwidth
) >> 1;
538 relY
+= (view
->y
- fheight
) >> 1;
539 if ((relX
< view
->x
) && (relY
< view
->y
)) {
542 ptr
= buf3
+ relY
* view
->x
+ relX
;
544 ptr
= (buf3
+ (view
->x
* view
->y
) + (relY
/ 2) * (view
->x
/ 2) + (relX
/ 2));
546 ptr
= (buf3
+ (view
->x
* view
->y
) + (view
->x
* view
->y
/ 4) + (relY
/ 2) *
547 (view
->x
/ 2)+ (relX
/ 2));
566 * @brief This function permits to convert an image from 6270 raw format to i420
567 * @param raw Buffer with the bayer data
568 * @param image Size of image
569 * @param view Size of view
570 * @param hflip Horizontal flip - not implemented
571 * @param vflip Vertical flip - not implemented
572 * @param factor Factor of redimensioning - not used factor is recalculate to do any non standard transformations
574 * @retval i420 Buffer with the i420 data
575 Format of stream is uvyy,uvyy - repeated 320 times for 640x480
576 y - repeated 640 times for 640x480
577 First 1280 bytes is maybe dumy ***FIX ME***
580 void raw6270_2i420(uint8_t *raw
, uint8_t *i420
, struct microdia_coord
*image
,
581 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
583 int i
, j
, YIndex
= 0, UVIndex
= 0;
584 unsigned char *y
, *u
, *v
;
587 //For fast calculations
589 //Skip first 1280 bytes strange dummy bytes
592 x_div_2
=image
->x
/ 2; //for fast calculation if x=640 x_div_2=320
593 y_div_2
=image
->y
/ 2; //for fast calculation if y=480 y_div_4=240
596 u
= i420
+ view
->x
* view
->y
;
597 v
= i420
+ view
->x
* view
->y
+ (view
->x
>> 1) * (view
->y
>> 1);
599 hshift
= view
->x
- (image
->x
/ factor
);
601 vshift
= view
->y
- (image
->y
/ factor
);
604 YIndex
= vshift
* view
->x
+ hshift
;
605 UVIndex
= (vshift
>> 1) * (view
->x
>> 1) + (hshift
>> 1);
606 //we skipped 1280 bytes, it's almost two lines
607 for (i
= 0; i
< y_div_2
- 1; i
++) {
608 for (j
= 0; j
< x_div_2
; j
++) {
615 YIndex
+= ((j
* 2) % factor
) == 0 ? 1 : 0;
618 YIndex
+= ((j
* 2 + 1) % factor
) == 0 ? 1 : 0;
619 UVIndex
+= (j
% factor
) == 0 ? 1 : 0;
622 YIndex
-= (image
->x
/ factor
);
623 if ((i
* 2) % factor
== 0) YIndex
+= view
->x
+ hshift
;
624 else YIndex
+= hshift
;
626 for (j
= 0; j
< image
->x
; j
++) {
629 YIndex
+= (j
% factor
) == 0 ? 1 : 0;
632 YIndex
-= (image
->x
/ factor
);
633 if ((i
* 2 + 1) % factor
== 0) YIndex
+= view
->x
+ hshift
;
634 else YIndex
+= hshift
;
636 UVIndex
-= (hshift
>> 1);
637 UVIndex
-= x_div_2
/ factor
;
638 if (i
% factor
== 0) UVIndex
+= (view
->x
>> 1) + (hshift
>> 1);
639 else UVIndex
+= (hshift
>> 1);
645 * @brief This function permits to convert an image from 6270 raw format to BGR24
646 * @param raw Buffer with the bayer data
647 * @param image Size of image
648 * @param view Size of view
649 * @param hflip Horizontal flip - not implemented yet
650 * @param vflip Vertical flip - not implemented yet
651 * @param factor Factor of redimensioning - not used factor is recalculate to do any non standard transformations
653 * @retval rgb Buffer with the rgb data
654 Format of stream is uvyy,uvyy - repeated 320 times for 640x480
655 y - repeated 640 times for 640x480
656 First 1280 bytes is maybe dumy ***FIX ME***
659 void raw6270_2BGR24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
660 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
663 //Maybe is not necesery to use long variables but I not sure in this moment
664 long y11
,y12
,y21
,y22
, u
, v
,y
,C
,D
,E
;
665 long ScaleIncX
,ScaleIncY
;
666 long pointerIncX
,pointerIncY
;
672 //For fast calculations
674 //Skip first 1280 bytes strange dummy bytes
677 x_div_2
=image
->x
/ 2; //for fast calculation if x=640 x_div_2=320
678 y_div_2
=image
->y
/ 2; //for fast calculation if y=480 y_div_4=240
679 incX
=3*view
->x
; //Incrementation koeficient for next row
683 //Because I can't use float ratio is multiply by 1000 then 1000 is equal of increment image (X or Y) with 1
684 ScaleIncX
=(1000*view
->x
)/image
->x
;
685 ScaleIncY
=(1000*view
->y
)/image
->y
;
689 out_row2
=out_row1
+incX
;
690 //we skipped 1280 bytes, it's almost two lines
692 for (i
= 0; i
< y_div_2
-1; i
++) {
694 for (j
= 0; j
< x_div_2
; j
++) {
696 pointerIncX
+=ScaleIncX
;
698 u
=(unsigned char)(*bufUVYY
);
700 v
=(unsigned char)(*bufUVYY
);
702 y11
=(unsigned char)(*bufUVYY
);
704 y12
=(unsigned char)(*bufUVYY
);
706 y21
=(unsigned char)(*bufY
);
708 y22
=(unsigned char)(*bufY
);
711 if((pointerIncX
>999)&&(pointerIncY
>499)){
718 *out_row1
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
720 *out_row1
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
722 *out_row1
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
732 *out_row1
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
734 *out_row1
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
736 *out_row1
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
740 //Second row of stream is displayed only if image is greath than half
749 *out_row2
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
751 *out_row2
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
753 *out_row2
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
762 *out_row2
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
764 *out_row2
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
766 *out_row2
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
771 //this comparation can be optimized and moved in if((pointerIncX>999)&&(pointerIncY>499))
774 //Use 2 rows only if vertical ratio > 0.5 (increment is ratio*1000)
777 out_row1
=out_row1
+incX
;
778 out_row2
=out_row2
+incX
;
782 pointerIncY
+= ScaleIncY
;
783 bufUVYY
=bufUVYY
+image
->x
;
784 bufY
=bufY
+2*image
->x
;
792 * @brief This function permits to convert an image from 6270 raw format to RGB24
793 * @brief The same function as convert to BGR24 but only B and R is change order
794 * @param raw Buffer with the bayer data
795 * @param image Size of image
796 * @param view Size of view
797 * @param hflip Horizontal flip
798 * @param vflip Vertical flip
799 * @param factor Factor of redimensioning
801 * @retval rgb Buffer with the rgb data
802 Format of stream is uvyy,uvyy - repeated 320 times for 640x480
803 y - repeated 640 times for 640x480
804 First 1280 bytes is maybe dumy ***FIX ME***
807 void raw6270_2RGB24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
808 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
811 //Maybe is not necesery to use long variables but I not sure in this moment
812 long y11
,y12
,y21
,y22
, u
, v
,y
,C
,D
,E
;
813 long ScaleIncX
,ScaleIncY
;
814 long pointerIncX
,pointerIncY
;
820 //For fast calculations
822 //Skip first 1280 bytes strange dummy bytes
825 x_div_2
=image
->x
/ 2; //for fast calculation if x=640 x_div_2=320
826 y_div_2
=image
->y
/ 2; //for fast calculation if y=480 y_div_4=240
831 //Because I can't use float ratio is multiply by 1000 then 1000 is equal of increment image (X or Y) with 1
832 ScaleIncX
=(1000*view
->x
)/image
->x
;
833 ScaleIncY
=(1000*view
->y
)/image
->y
;
837 out_row2
=out_row1
+incX
;
838 //we skipped 1280 bytes, it's almost two lines
840 for (i
= 0; i
< y_div_2
-1; i
++) {
842 for (j
= 0; j
< x_div_2
; j
++) {
844 pointerIncX
+=ScaleIncX
;
846 u
=(unsigned char)(*bufUVYY
);
848 v
=(unsigned char)(*bufUVYY
);
850 y11
=(unsigned char)(*bufUVYY
);
852 y12
=(unsigned char)(*bufUVYY
);
854 y21
=(unsigned char)(*bufY
);
856 y22
=(unsigned char)(*bufY
);
859 if((pointerIncX
>999)&&(pointerIncY
>499)){
866 *out_row1
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
868 *out_row1
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
870 *out_row1
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
880 *out_row1
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
882 *out_row1
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
884 *out_row1
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
888 //Second row of stream is displayed only if image is greath than half
897 *out_row2
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
899 *out_row2
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
901 *out_row2
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
910 *out_row2
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
912 *out_row2
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
914 *out_row2
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
919 //this comparation can be optimized and moved in if((pointerIncX>999)&&(pointerIncY>499))
922 //Use 2 rows only if vertical ratio > 0.5 (increment is ratio*1000)
925 out_row1
=out_row1
+incX
;
926 out_row2
=out_row2
+incX
;
930 pointerIncY
+= ScaleIncY
;
931 bufUVYY
=bufUVYY
+image
->x
;
932 bufY
=bufY
+2*image
->x
;
939 * @brief This function permits to convert an image from bayer to RGB24
941 * @param bayer Buffer with the bayer data
942 * @param image Size of image
943 * @param view Size of view
944 * @param hflip Horizontal flip
945 * @param vflip Vertical flip
946 * @param factor Factor of redimensioning
948 * @retval rgb Buffer with the RGB data
950 void microdia_b2rgb24(uint8_t *bayer
, uint8_t *rgb
,
951 struct microdia_coord
*image
,
952 struct microdia_coord
*view
,
953 const int hflip
, const int vflip
,
957 int x
, y
; // Position in bayer image
958 int i
, j
; // Position in rgb image
960 int width
= image
->x
;
961 int height
= image
->y
;
963 int nwidth
= width
/ factor
;
964 int nheight
= height
/ factor
;
971 // Calculate the initial position (on Y axis)
981 // Calculate the initial position (on X axis)
994 // Skip the first line
997 // To center vertically the image in the view
998 rgb
+= ((view
->y
- nheight
) / 2) * view
->x
* 3;
1000 // To center horizontally the image in the view
1001 rgb
+= ((view
->x
- nwidth
) / 2) * 3;
1003 // Clean the first line
1004 memset(rgb
, 0, nwidth
* 3);
1008 // For each rgb line without the borders (first and last line)
1009 for (j
=0, y
=starty
; j
<nheight
-2; j
++, y
=y
+stepy
) {
1010 // Go to the start of line
1011 b
= bayer
+ y
* width
+ offset
;
1013 // Offset to center horizontally the image in the view
1014 rgb
+= (view
->x
- nwidth
) * 3;
1017 // Skip the first pixel
1022 // GBGBGB : Line process...
1023 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1025 *rgb
++ = (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1026 *rgb
++ = (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1030 *rgb
++ = (*(b
-width
) + *(b
+width
)) >> 1;
1032 *rgb
++ = (*(b
-1) + *(b
+1)) >> 1;
1038 // Skip the last pixel
1044 // Skip the first pixel
1049 // RGRGRG : Line process...
1050 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1052 *rgb
++ = (*(b
-1) + *(b
+1)) >> 1;
1054 *rgb
++ = (*(b
-width
) + *(b
+width
)) >> 1;
1058 *rgb
++ = (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1059 *rgb
++ = (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1065 // Skip the last pixel
1072 // Clean the last line
1073 memset(rgb
, 0, nwidth
* 3);
1078 * @brief This function permits to convert an image from bayer to RGB32
1080 * @param bayer Buffer with the bayer data
1081 * @param image Size of image
1082 * @param view Size of view
1083 * @param hflip Horizontal flip
1084 * @param vflip Vertical flip
1085 * @param factor Factor of redimensioning
1087 * @retval rgb Buffer with the RGB data
1089 void microdia_b2rgb32(uint8_t *bayer
, uint8_t *rgb
,
1090 struct microdia_coord
*image
,
1091 struct microdia_coord
*view
,
1092 const int hflip
, const int vflip
,
1096 int x
, y
; // Position in bayer image
1097 int i
, j
; // Position in rgb image
1099 int width
= image
->x
;
1100 int height
= image
->y
;
1102 int nwidth
= width
/ factor
;
1103 int nheight
= height
/ factor
;
1110 // Calculate the initial position (on Y axis)
1112 starty
= height
- 2;
1120 // Calculate the initial position (on X axis)
1133 // Skip the first line
1136 // To center vertically the image in the view
1137 rgb
+= ((view
->y
- nheight
) / 2) * view
->x
* 4;
1139 // To center horizontally the image in the view
1140 rgb
+= ((view
->x
- nwidth
) / 2) * 4;
1142 // Clean the first line
1143 memset(rgb
, 0, nwidth
* 4);
1147 // For each rgb line without the borders (first and last line)
1148 for (j
=0, y
=starty
; j
<nheight
-2; j
++, y
=y
+stepy
) {
1149 // Go to the start of line
1150 b
= bayer
+ y
* width
+ offset
;
1152 // Offset to center horizontally the image in the view
1153 rgb
+= (view
->x
- nwidth
) * 4;
1156 // Skip the first pixel
1162 // GBGBGB : Line process...
1163 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1165 *rgb
++ = (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1166 *rgb
++ = (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1171 *rgb
++ = (*(b
-width
) + *(b
+width
)) >> 1;
1173 *rgb
++ = (*(b
-1) + *(b
+1)) >> 1;
1180 // Skip the last pixel
1187 // Skip the first pixel
1193 // RGRGRG : Line process...
1194 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1196 *rgb
++ = (*(b
-1) + *(b
+1)) >> 1;
1198 *rgb
++ = (*(b
-width
) + *(b
+width
)) >> 1;
1203 *rgb
++ = (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1204 *rgb
++ = (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1211 // Skip the last pixel
1219 // Clean the last line
1220 memset(rgb
, 0, nwidth
* 4);
1225 * @brief This function permits to convert an image from bayer to BGR24
1227 * @param bayer Buffer with the bayer data
1228 * @param image Size of image
1229 * @param view Size of view
1230 * @param hflip Horizontal flip
1231 * @param vflip Vertical flip
1232 * @param factor Factor of redimensioning
1234 * @retval bgr Buffer with the BGR data
1236 void microdia_b2bgr24(uint8_t *bayer
, uint8_t *bgr
,
1237 struct microdia_coord
*image
,
1238 struct microdia_coord
*view
,
1239 const int hflip
, const int vflip
,
1243 int x
, y
; // Position in bayer image
1244 int i
, j
; // Position in bgr image
1246 int width
= image
->x
;
1247 int height
= image
->y
;
1249 int nwidth
= width
/ factor
;
1250 int nheight
= height
/ factor
;
1257 // Calculate the initial position (on Y axis)
1259 starty
= height
- 2;
1267 // Calculate the initial position (on X axis)
1280 // Skip the first line
1283 // To center vertically the image in the view
1284 bgr
+= ((view
->y
- nheight
) / 2) * view
->x
* 3;
1286 // To center horizontally the image in the view
1287 bgr
+= ((view
->x
- nwidth
) / 2) * 3;
1289 // Clean the first line
1290 memset(bgr
, 0, nwidth
* 3);
1294 // For each bgr line without the borders (first and last line)
1295 for (j
=0, y
=starty
; j
<nheight
-2; j
++, y
=y
+stepy
) {
1296 // Go to the start of line
1297 b
= bayer
+ y
* width
+ offset
;
1299 // Offset to center horizontally the image in the view
1300 bgr
+= (view
->x
- nwidth
) * 3;
1303 // Skip the first pixel
1308 // GBGBGB : Line process...
1309 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1312 *bgr
++ = (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1313 *bgr
++ = (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1316 *bgr
++ = (*(b
-1) + *(b
+1)) >> 1;
1318 *bgr
++ = (*(b
-width
) + *(b
+width
)) >> 1;
1324 // Skip the last pixel
1330 // Skip the first pixel
1335 // RGRGRG : Line process...
1336 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1338 *bgr
++ = (*(b
-width
) + *(b
+width
)) >> 1;
1340 *bgr
++ = (*(b
-1) + *(b
+1)) >> 1;
1343 *bgr
++ = (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1344 *bgr
++ = (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1351 // Skip the last pixel
1358 // Clean the last line
1359 memset(bgr
, 0, nwidth
* 3);
1364 * @brief This function permits to convert an image from bayer to BGR32
1366 * @param bayer Buffer with the bayer data
1367 * @param image Size of image
1368 * @param view Size of view
1369 * @param hflip Horizontal flip
1370 * @param vflip Vertical flip
1371 * @param factor Factor of redimensioning
1373 * @retval bgr Buffer with the BGR data
1375 void microdia_b2bgr32(uint8_t *bayer
, uint8_t *bgr
,
1376 struct microdia_coord
*image
,
1377 struct microdia_coord
*view
,
1378 const int hflip
, const int vflip
,
1382 int x
, y
; // Position in bayer image
1383 int i
, j
; // Position in bgr image
1385 int width
= image
->x
;
1386 int height
= image
->y
;
1388 int nwidth
= width
/ factor
;
1389 int nheight
= height
/ factor
;
1396 // Calculate the initial position (on Y axis)
1398 starty
= height
- 2;
1406 // Calculate the initial position (on X axis)
1419 // Skip the first line
1422 // To center vertically the image in the view
1423 bgr
+= ((view
->y
- nheight
) / 2) * view
->x
* 4;
1425 // To center horizontally the image in the view
1426 bgr
+= ((view
->x
- nwidth
) / 2) * 4;
1428 // Clean the first line
1429 memset(bgr
, 0, nwidth
* 4);
1433 // For each bgr line without the borders (first and last line)
1434 for (j
=0, y
=starty
; j
<nheight
-2; j
++, y
=y
+stepy
) {
1435 // Go to the start of line
1436 b
= bayer
+ y
* width
+ offset
;
1438 // Offset to center horizontally the image in the view
1439 bgr
+= (view
->x
- nwidth
) * 4;
1442 // Skip the first pixel
1448 // GBGBGB : Line process...
1449 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1452 *bgr
++ = (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1453 *bgr
++ = (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1457 *bgr
++ = (*(b
-1) + *(b
+1)) >> 1;
1459 *bgr
++ = (*(b
-width
) + *(b
+width
)) >> 1;
1466 // Skip the last pixel
1473 // Skip the first pixel
1479 // RGRGRG : Line process...
1480 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1482 *bgr
++ = (*(b
-width
) + *(b
+width
)) >> 1;
1484 *bgr
++ = (*(b
-1) + *(b
+1)) >> 1;
1488 *bgr
++ = (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1489 *bgr
++ = (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1497 // Skip the last pixel
1505 // Clean the last line
1506 memset(bgr
, 0, nwidth
* 4);
1511 * @brief This function permits to convert an image from bayer to YUV (UYVY)
1513 * @param bayer Buffer with the bayer data
1514 * @param image Size of image
1515 * @param view Size of view
1516 * @param hflip Horizontal flip
1517 * @param vflip Vertical flip
1518 * @param factor Factor of redimensioning
1520 * @retval yuv Buffer with the YUV data
1522 void microdia_b2uyvy(uint8_t *bayer
, uint8_t *yuv
,
1523 struct microdia_coord
*image
,
1524 struct microdia_coord
*view
,
1525 const int hflip
, const int vflip
,
1529 int x
, y
; // Position in bayer image
1530 int i
, j
; // Position in yuv image
1535 int width
= image
->x
;
1536 int height
= image
->y
;
1538 int nwidth
= width
/ factor
;
1539 int nheight
= height
/ factor
;
1546 // Calculate the initial position (on Y axis)
1548 starty
= height
- 2;
1556 // Calculate the initial position (on X axis)
1568 // Background color...
1569 memset(yuv
, 16, width
* 2);
1570 for (i
=0; i
<width
*2; i
=i
+2, *(yuv
+i
)=128);
1571 for (i
=1; i
<height
; i
++)
1572 memcpy(yuv
+i
*width
*2, yuv
, width
*2);
1574 // Skip the first line
1577 // To center vertically the image in the view
1578 yuv
+= ((view
->y
- nheight
) / 2) * view
->x
* 2;
1580 // To center horizontally the image in the view
1581 yuv
+= ((view
->x
- nwidth
) / 2) * 2;
1583 // Clean the first line
1584 memset(yuv
, 16, nwidth
* 2);
1585 for (i
=0; i
<nwidth
*2; i
=i
+2, *(yuv
+i
)=128);
1589 // For each yuv line without the borders (first and last line)
1590 for (j
=0, y
=starty
; j
<nheight
-2; j
++, y
=y
+stepy
) {
1591 // Go to the start of line
1592 b
= bayer
+ y
* width
+ offset
;
1594 // Offset to center horizontally the image in the view
1595 yuv
+= (view
->x
- nwidth
) * 2;
1598 // Skip the first pixel
1602 // GBGBGB : Line process...
1603 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1605 pR
= (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1606 pG
= (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1610 pR
= (*(b
-width
) + *(b
+width
)) >> 1;
1612 pB
= (*(b
-1) + *(b
+1)) >> 1;
1615 pY
= microdia_yuv_interp
[pR
][0] + microdia_yuv_interp
[pG
][1] + microdia_yuv_interp
[pB
][2];
1616 pU
= microdia_yuv_interp
[pR
][3] + microdia_yuv_interp
[pG
][4] + microdia_yuv_interp
[pB
][5];
1617 pV
= microdia_yuv_interp
[pR
][5] + microdia_yuv_interp
[pG
][6] + microdia_yuv_interp
[pB
][7];
1619 pY
= CLIP(pY
, 0,255);
1620 pU
= CLIP(pU
, -127,127);
1621 pV
= CLIP(pV
, -127,127);
1624 *yuv
++ = (112 * pU
)/127 + 128; // U
1625 *yuv
++ = (219 * pY
)/255 + 16; // Y
1628 *yuv
++ = (112 * pV
)/127 + 128; // V
1629 *yuv
++ = (219 * pY
)/255 + 16; // Y
1635 // Skip the last pixel
1640 // Skip the first pixel
1644 // RGRGRG : Line process...
1645 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1647 pR
= (*(b
-1) + *(b
+1)) >> 1;
1649 pB
= (*(b
-width
) + *(b
+width
)) >> 1;
1653 pG
= (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1654 pB
= (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1657 pY
= microdia_yuv_interp
[pR
][0] + microdia_yuv_interp
[pG
][1] + microdia_yuv_interp
[pB
][2];
1658 pU
= microdia_yuv_interp
[pR
][3] + microdia_yuv_interp
[pG
][4] + microdia_yuv_interp
[pB
][5];
1659 pV
= microdia_yuv_interp
[pR
][5] + microdia_yuv_interp
[pG
][6] + microdia_yuv_interp
[pB
][7];
1661 pY
= CLIP(pY
, 0,255);
1662 pU
= CLIP(pU
, -127,127);
1663 pV
= CLIP(pV
, -127,127);
1666 *yuv
++ = (112 * pU
)/127 + 128; // U
1667 *yuv
++ = (219 * pY
)/255 + 16; // Y
1670 *yuv
++ = (112 * pV
)/127 + 128; // V
1671 *yuv
++ = (219 * pY
)/255 + 16; // Y
1677 // Skip the last pixel
1683 // Clean the last line
1684 memset(yuv
, 16, nwidth
* 2);
1685 for (i
=0; i
<nwidth
*2; i
=i
+2, *(yuv
+i
)=128);
1690 * @brief This function permits to convert an image from bayer to YUV (YUYV)
1692 * @param bayer Buffer with the bayer data
1693 * @param image Size of image
1694 * @param view Size of view
1695 * @param hflip Horizontal flip
1696 * @param vflip Vertical flip
1697 * @param factor Factor of redimensioning
1699 * @retval yuv Buffer with the YUV data
1701 void microdia_b2yuyv(uint8_t *bayer
, uint8_t *yuv
,
1702 struct microdia_coord
*image
,
1703 struct microdia_coord
*view
,
1704 const int hflip
, const int vflip
,
1708 int x
, y
; // Position in bayer image
1709 int i
, j
; // Position in yuv image
1714 int width
= image
->x
;
1715 int height
= image
->y
;
1717 int nwidth
= width
/ factor
;
1718 int nheight
= height
/ factor
;
1725 // Calculate the initial position (on Y axis)
1727 starty
= height
- 2;
1735 // Calculate the initial position (on X axis)
1747 // Background color...
1748 memset(yuv
, 128, width
* 2);
1749 for (i
=0; i
<width
*2; i
=i
+2, *(yuv
+i
)=16);
1750 for (i
=1; i
<height
; i
++)
1751 memcpy(yuv
+i
*width
*2, yuv
, width
*2);
1753 // Skip the first line
1756 // To center vertically the image in the view
1757 yuv
+= ((view
->y
- nheight
) / 2) * view
->x
* 2;
1759 // To center horizontally the image in the view
1760 yuv
+= ((view
->x
- nwidth
) / 2) * 2;
1762 // Clean the first line
1763 memset(yuv
, 128, nwidth
* 2);
1764 for (i
=0; i
<nwidth
*2; i
=i
+2, *(yuv
+i
)=16);
1768 // For each yuv line without the borders (first and last line)
1769 for (j
=0, y
=starty
; j
<nheight
-2; j
++, y
=y
+stepy
) {
1770 // Go to the start of line
1771 b
= bayer
+ y
* width
+ offset
;
1773 // Offset to center horizontally the image in the view
1774 yuv
+= (view
->x
- nwidth
) * 2;
1777 // Skip the first pixel
1781 // GBGBGB : Line process...
1782 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1784 pR
= (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1785 pG
= (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1789 pR
= (*(b
-width
) + *(b
+width
)) >> 1;
1791 pB
= (*(b
-1) + *(b
+1)) >> 1;
1794 pY
= microdia_yuv_interp
[pR
][0] + microdia_yuv_interp
[pG
][1] + microdia_yuv_interp
[pB
][2];
1795 pU
= microdia_yuv_interp
[pR
][3] + microdia_yuv_interp
[pG
][4] + microdia_yuv_interp
[pB
][5];
1796 pV
= microdia_yuv_interp
[pR
][5] + microdia_yuv_interp
[pG
][6] + microdia_yuv_interp
[pB
][7];
1798 pY
= CLIP(pY
, 0,255);
1799 pU
= CLIP(pU
, -127,127);
1800 pV
= CLIP(pV
, -127,127);
1803 *yuv
++ = (219 * pY
)/255 + 16; // Y
1804 *yuv
++ = (112 * pU
)/127 + 128; // U
1807 *yuv
++ = (219 * pY
)/255 + 16; // Y
1808 *yuv
++ = (112 * pV
)/127 + 128; // V
1814 // Skip the last pixel
1819 // Skip the first pixel
1823 // RGRGRG : Line process...
1824 for (i
=0, x
=startx
; i
<nwidth
-2; i
++, x
=x
+stepx
) {
1826 pR
= (*(b
-1) + *(b
+1)) >> 1;
1828 pB
= (*(b
-width
) + *(b
+width
)) >> 1;
1832 pG
= (*(b
-width
) + *(b
-1) + *(b
+1) + *(b
+width
)) >> 2;
1833 pB
= (*(b
-width
-1) + *(b
-width
+1) + *(b
+width
-1) + *(b
+width
+1)) >> 2;
1836 pY
= microdia_yuv_interp
[pR
][0] + microdia_yuv_interp
[pG
][1] + microdia_yuv_interp
[pB
][2];
1837 pU
= microdia_yuv_interp
[pR
][3] + microdia_yuv_interp
[pG
][4] + microdia_yuv_interp
[pB
][5];
1838 pV
= microdia_yuv_interp
[pR
][5] + microdia_yuv_interp
[pG
][6] + microdia_yuv_interp
[pB
][7];
1840 pY
= CLIP(pY
, 0,255);
1841 pU
= CLIP(pU
, -127,127);
1842 pV
= CLIP(pV
, -127,127);
1845 *yuv
++ = (219 * pY
)/255 + 16; // Y
1846 *yuv
++ = (112 * pU
)/127 + 128; // U
1849 *yuv
++ = (219 * pY
)/255 + 16; // Y
1850 *yuv
++ = (112 * pV
)/127 + 128; // V
1856 // Skip the last pixel
1862 // Clean the last line
1863 memset(yuv
, 128, nwidth
* 2);
1864 for (i
=0; i
<nwidth
*2; i
=i
+2, *(yuv
+i
)=16);