Fix warnings and errors when compiled under rt kernel
[microdia.git] / microdia-decoder.c
bloba93aba5ceb1f53326828e695dbdf5f00dce93324
1 /**
2 * @file microdia-decoder.c
3 * @author Nicolas VIVIEN
4 * @date 2008-02-01
5 * @version v0.0.0
7 * @brief Driver for Microdia 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
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/kernel.h>
31 #include <linux/version.h>
32 #include <linux/errno.h>
33 #include <linux/slab.h>
34 #include <linux/kref.h>
36 #include <linux/usb.h>
37 #include <media/v4l2-common.h>
39 #include "microdia.h"
42 #define MAX(a, b) ((a) > (b) ? (a) : (b))
43 #define MIN(a, b) ((a) < (b) ? (a) : (b))
44 #define CLIP(a, low, high) MAX((low), MIN((high), (a)))
46 void raw6270_2i420(uint8_t *, uint8_t *, struct microdia_coord *,
47 struct microdia_coord *, const int, const int,
48 const int);
50 void raw6270_2RGB24(uint8_t *raw, uint8_t *rgb, struct microdia_coord *image,
51 struct microdia_coord *view, const int hflip,
52 const int vflip, const int factor);
54 void raw6270_2BGR24(uint8_t *raw, uint8_t *rgb, struct microdia_coord *image,
55 struct microdia_coord *view, const int hflip,
56 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,
62 const int);
64 void microdia_raw2bgr24(uint8_t *, uint8_t *, struct microdia_coord *,
65 struct microdia_coord *, const int, const int,
66 const int);
68 void microdia_correct_brightness(uint8_t *, const int, const int,
69 const int, int);
71 /**
72 * @brief Decompress a frame
74 * This function permits to decompress a frame from the video stream.
76 * @param dev Device structure
77 * @param buffer Image data
79 * @returns 0 if all is OK
81 int microdia_decompress(struct usb_microdia *dev, struct v4l2_buffer *buffer)
83 int factor;
84 int vflip;
85 int hflip;
86 int ret = 0;
88 void *data;
89 void *image;
91 if (dev == NULL) {
92 ret = -EFAULT;
93 goto done;
96 if (dev->flip_detect)
97 dev->flip_detect(dev);
99 if (dev->set_hvflip) {
100 hflip = 0;
101 vflip = 0;
102 } else {
103 hflip = dev->vsettings.hflip;
104 vflip = dev->vsettings.vflip;
107 image = dev->queue.scratch;
109 data = dev->queue.mem + buffer->m.offset;
110 memcpy(image, data, MICRODIA_FRAME_SIZE);
112 switch (dev->resolution) {
113 case MICRODIA_80x60:
114 factor = 8;
115 break;
117 case MICRODIA_160x120:
118 factor = 4;
119 break;
121 case MICRODIA_320x240:
122 factor = 2;
123 break;
125 case MICRODIA_640x480:
126 case MICRODIA_800x600:
127 case MICRODIA_1024x768:
128 case MICRODIA_1280x1024:
129 factor = 1;
130 break;
132 default:
133 ret = -EFAULT;
134 goto done;
137 switch (dev->vsettings.format.pixelformat) {
138 case V4L2_PIX_FMT_RGB24:
139 if (dev->webcam_model ==
140 CAMERA_MODEL(USB_0C45_VID, USB_6270_PID) ||
141 dev->webcam_model ==
142 CAMERA_MODEL(USB_0C45_VID, USB_627B_PID) ||
143 dev->webcam_model ==
144 CAMERA_MODEL(USB_0C45_VID, USB_6288_PID) ||
145 dev->webcam_model ==
146 CAMERA_MODEL(USB_0C45_VID, USB_62B3_PID) ||
147 dev->webcam_model ==
148 CAMERA_MODEL(USB_0C45_VID, USB_62BB_PID) ||
149 dev->webcam_model ==
150 CAMERA_MODEL(USB_145F_VID, USB_013D_PID)) {
151 raw6270_2RGB24(image, data, &dev->image, &dev->view,
152 hflip, vflip, factor);
154 break;
155 case V4L2_PIX_FMT_BGR24:
156 if (dev->webcam_model ==
157 CAMERA_MODEL(USB_0C45_VID, USB_6270_PID) ||
158 dev->webcam_model ==
159 CAMERA_MODEL(USB_0C45_VID, USB_627B_PID) ||
160 dev->webcam_model ==
161 CAMERA_MODEL(USB_0C45_VID, USB_6288_PID) ||
162 dev->webcam_model ==
163 CAMERA_MODEL(USB_0C45_VID, USB_62B3_PID) ||
164 dev->webcam_model ==
165 CAMERA_MODEL(USB_0C45_VID, USB_62BB_PID) ||
166 dev->webcam_model ==
167 CAMERA_MODEL(USB_145F_VID, USB_013D_PID)) {
168 raw6270_2BGR24(image, data, &dev->image, &dev->view,
169 hflip, vflip, factor);
170 } else {
171 microdia_raw2bgr24(image, data, &dev->image, &dev->view,
172 hflip, vflip, factor);
174 break;
175 case V4L2_PIX_FMT_YUV420:
176 if (dev->webcam_model ==
177 CAMERA_MODEL(USB_0C45_VID, USB_6270_PID) ||
178 dev->webcam_model ==
179 CAMERA_MODEL(USB_0C45_VID, USB_627B_PID) ||
180 dev->webcam_model ==
181 CAMERA_MODEL(USB_0C45_VID, USB_6288_PID) ||
182 dev->webcam_model ==
183 CAMERA_MODEL(USB_0C45_VID, USB_62B3_PID) ||
184 dev->webcam_model ==
185 CAMERA_MODEL(USB_0C45_VID, USB_62BB_PID) ||
186 dev->webcam_model ==
187 CAMERA_MODEL(USB_145F_VID, USB_013D_PID)) {
188 raw6270_2i420(image, data, &dev->image, &dev->view,
189 hflip, vflip, factor);
190 } else {
191 microdia_raw2i420(image, data, &dev->image, &dev->view,
192 hflip, vflip, factor);
194 break;
195 case V4L2_PIX_FMT_YUYV:
196 default:
197 break;
200 buffer->bytesused = dev->vsettings.format.sizeimage;
201 done:
202 return ret;
207 * @brief Correct the brightness of an image.
209 * This function permits to correct the brightness of an image.
211 * @param img Buffer to RGB/YUV data
212 * @param width Width of frame
213 * @param height Height of frame
214 * @param brightness Brightness correction
215 * @param palette
217 * @retval rgb Buffer to RGB/YUV data
219 void microdia_correct_brightness(uint8_t *img, const int width,
220 const int height, const int brightness,
221 int palette)
223 int i;
224 int x;
225 int depth;
227 switch (palette) {
228 case V4L2_PIX_FMT_RGB24:
229 case V4L2_PIX_FMT_BGR24:
230 depth = 24;
231 case V4L2_PIX_FMT_RGB32:
232 case V4L2_PIX_FMT_BGR32:
233 depth = (depth == 24) ? 3 : 4;
235 if (brightness >= 32767) {
236 x = (brightness - 32767) / 256;
238 for (i = 0; i < (width * height * depth); i++) {
239 if ((*(img + i) + (unsigned char) x) > 255)
240 *(img + i) = 255;
241 else
242 *(img + i) += (unsigned char) x;
244 } else {
245 x = (32767 - brightness) / 256;
246 for (i = 0; i < (width * height * depth); i++) {
247 if ((unsigned char) x > *(img + i))
248 *(img + i) = 0;
249 else
250 *(img + i) -= (unsigned char) x;
253 break;
255 case V4L2_PIX_FMT_UYVY:
256 depth = 2;
258 if (brightness >= 32767) {
259 x = (brightness - 32767) / 256;
261 for (i = 1; i < (width * height * depth); i += depth) {
262 if ((*(img + i) + (unsigned char) x) > 255)
263 *(img + i) = 255;
264 else
265 *(img + i) += (unsigned char) x;
267 } else {
268 x = (32767 - brightness) / 256;
270 for (i = 1; i < (width * height * depth); i += depth) {
271 if ((unsigned char) x > *(img + i))
272 *(img + i) = 0;
273 else
274 *(img + i) -= (unsigned char) x;
278 break;
280 case V4L2_PIX_FMT_YUYV:
281 depth = 2;
283 if (brightness >= 32767) {
284 x = (brightness - 32767) / 256;
286 for (i = 0; i < (width * height * depth); i += depth) {
287 if ((*(img + i) + (unsigned char) x) > 255)
288 *(img + i) = 255;
289 else
290 *(img + i) += (unsigned char) x;
292 } else {
293 x = (32767 - brightness) / 256;
295 for (i = 0; i < (width * height * depth); i += depth) {
296 if ((unsigned char) x > *(img + i))
297 *(img + i) = 0;
298 else
299 *(img + i) -= (unsigned char) x;
303 break;
309 * @brief This function permits to get the raw data. (without treatments)
311 * @param bayer Buffer with the bayer data
312 * @param size Length of bayer buffer
314 * @retval raw Buffer with the data from video sensor
316 void microdia_getraw(uint8_t *bayer, uint8_t *raw,
317 int size) {
318 memcpy(raw, bayer, size);
321 /* Table to translate Y offset to UV offset */
322 static int UVTranslate[32] = {
323 0, 1, 2, 3,
324 8, 9, 10, 11,
325 16, 17, 18, 19,
326 24, 25, 26, 27,
327 4, 5, 6, 7,
328 12, 13, 14, 15,
329 20, 21, 22, 23,
330 28, 29, 30, 31
333 static int Y_coords_624x[128][2] = {
334 { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 0}, { 5, 0}, { 6, 0}, { 7, 0},
335 { 0, 1}, { 1, 1}, { 2, 1}, { 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7, 1},
336 { 0, 2}, { 1, 2}, { 2, 2}, { 3, 2}, { 4, 2}, { 5, 2}, { 6, 2}, { 7, 2},
337 { 0, 3}, { 1, 3}, { 2, 3}, { 3, 3}, { 4, 3}, { 5, 3}, { 6, 3}, { 7, 3},
339 { 0, 4}, { 1, 4}, { 2, 4}, { 3, 4}, { 4, 4}, { 5, 4}, { 6, 4}, { 7, 4},
340 { 0, 5}, { 1, 5}, { 2, 5}, { 3, 5}, { 4, 5}, { 5, 5}, { 6, 5}, { 7, 5},
341 { 0, 6}, { 1, 6}, { 2, 6}, { 3, 6}, { 4, 6}, { 5, 6}, { 6, 6}, { 7, 6},
342 { 0, 7}, { 1, 7}, { 2, 7}, { 3, 7}, { 4, 7}, { 5, 7}, { 6, 7}, { 7, 7},
344 { 8, 0}, { 9, 0}, {10, 0}, {11, 0}, {12, 0}, {13, 0}, {14, 0}, {15, 0},
345 { 8, 1}, { 9, 1}, {10, 1}, {11, 1}, {12, 1}, {13, 1}, {14, 1}, {15, 1},
346 { 8, 2}, { 9, 2}, {10, 2}, {11, 2}, {12, 2}, {13, 2}, {14, 2}, {15, 2},
347 { 8, 3}, { 9, 3}, {10, 3}, {11, 3}, {12, 3}, {13, 3}, {14, 3}, {15, 3},
349 { 8, 4}, { 9, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15, 4},
350 { 8, 5}, { 9, 5}, {10, 5}, {11, 5}, {12, 5}, {13, 5}, {14, 5}, {15, 5},
351 { 8, 6}, { 9, 6}, {10, 6}, {11, 6}, {12, 6}, {13, 6}, {14, 6}, {15, 6},
352 { 8, 7}, { 9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15, 7}
355 void microdia_raw2bgr24(uint8_t *raw, uint8_t *rgb,
356 struct microdia_coord *image,
357 struct microdia_coord *view, const int hflip,
358 const int vflip, const int factor)
360 int i = 0, x = 0, y = 0;
361 unsigned char *buf = raw;
362 unsigned char *buf3 = rgb;
363 int fwidth, fheight;
365 fwidth = image->x / factor;
366 fheight = image->y / factor;
368 while (i < (image->x * image->y + (image->x * image->y) / 2)) {
369 int tile = 0;
370 for (tile = 0; tile < 4; tile++) {
371 int subX = 0;
372 int subY = 0;
373 for (subY = 0; subY < 4; subY++) {
374 for (subX = 0; subX < 8; subX++) {
375 int subI = i + tile * 32 + 8 * subY + subX;
376 int subU = i + 128 + UVTranslate[tile * 8 + 4 * (subY >> 1) + (subX >> 1)];
377 int subV = subU + 32;
379 int relX = x + (((tile == 0) || (tile == 1)) ? 0 : 8) + subX; /* tile 0, 1 to into left column*/
380 int relY = y + (((tile == 0) || (tile == 2)) ? 0 : 4) + subY; /* tile 0, 2 go into top row */
382 if (hflip)
383 relX = image->x - relX;
384 if (vflip)
385 relY = image->y - relY;
387 relX /= factor;
388 relY /= factor;
390 relX += (view->x - fwidth) >> 1;
391 relY += (view->y - fheight) >> 1;
392 if ((relX < view->x) && (relY < view->y)) {
393 unsigned char *ptr;
394 int c, d, e;
395 c = buf[subI] - 16;
396 d = buf[subU] - 128;
397 e = buf[subV] - 128;
399 ptr = buf3 + relY * view->x * 3 + relX * 3;
400 *ptr = CLIP((298 * c + 516 * d + 128) >> 8, 0, 255);
401 ptr++;
402 *ptr = CLIP((298 * c - 100 * d - 208 * e + 128) >> 8, 0, 255);
403 ptr++;
404 *ptr = CLIP((298 * c + 409 * e + 128) >> 8, 0, 255);
410 i += 192;
411 x += 16;
412 if (x >= image->x) {
413 x = 0;
414 y += 8;
419 void microdia_raw2i420(uint8_t *raw, uint8_t *i420,
420 struct microdia_coord *image,
421 struct microdia_coord *view, const int hflip,
422 const int vflip, const int factor)
424 int i = 0, x = 0, y = 0, j, relX, relY, x_div2, y_div2;
425 unsigned char *buf = raw, *ptr;
426 unsigned char *buf3 = i420;
427 int fwidth = image->x / factor, fheight = image->y / factor;
428 int view_size = view->x * view->y;
429 int view_size_div4 = view_size >> 2;
430 int x_padding = (view->x - fwidth) >> 1;
431 int y_padding = (view->y - fheight) >> 1;
432 int x_padding_div2 = x_padding >> 1;
433 int y_padding_div2 = y_padding >> 1;
434 int image_x_div2 = image->x >> 1;
435 int image_y_div2 = image->y >> 1;
436 int view_x_div2 = view->x >> 1;
438 while (i < (image->x * image->y + (image->x * image->y) / 2)) {
439 for (j = 0; j < 128; j++) {
440 relX = x + Y_coords_624x[j][0];
441 relY = y + Y_coords_624x[j][1];
442 if (hflip)
443 relX = image->x - relX - 1;
444 if (vflip)
445 relY = image->y - relY - 1;
447 switch (factor) {
449 case 1:
450 break;
451 case 2:
452 relX >>= 1;
453 relY >>= 1;
454 break;
455 case 4:
456 relX >>= 2;
457 relY >>= 2;
458 break;
459 case 8:
460 relX >>= 3;
461 relY >>= 3;
462 break;
463 default:
464 relX /= factor;
465 relY /= factor;
466 break;
469 relX += x_padding;
470 relY += y_padding;
472 if ((relX < view->x) && (relY < view->y)) {
473 ptr = buf3 + relY * view->x + relX;
474 *ptr = buf[i + j];
478 x_div2 = x >> 1;
479 y_div2 = y >> 1;
480 for (j = 0; j < 32; j++) {
481 relX = (x_div2) + (j & 0x07);
482 relY = (y_div2) + (j >> 3);
483 if (hflip)
484 relX = image_x_div2 - relX - 1;
485 if (vflip)
486 relY = image_y_div2 - relY - 1;
488 relX += x_padding_div2;
489 relY += y_padding_div2;
491 switch (factor) {
493 case 1:
494 break;
495 case 2:
496 relX >>= 1;
497 relY >>= 1;
498 break;
499 case 4:
500 relX >>= 2;
501 relY >>= 2;
502 break;
503 case 8:
504 relX >>= 3;
505 relY >>= 3;
506 break;
507 default:
508 relX /= factor;
509 relY /= factor;
510 break;
513 if ((relX < view->x) && (relY < view->y)) {
514 ptr = buf3 + view_size +
515 relY * (view_x_div2) + relX;
516 *ptr = buf[i + 128 + j];
517 ptr += view_size_div4;
518 *ptr = buf[i + 160 + j];
523 i += 192;
524 x += 16;
525 if (x >= image->x) {
526 x = 0;
527 y += 8;
534 * @brief This function permits to convert an image from 6270 raw format to i420
535 * @param raw Buffer with the bayer data
536 * @param image Size of image
537 * @param view Size of view
538 * @param hflip Horizontal flip - not implemented
539 * @param vflip Vertical flip - not implemented
540 * @param factor Factor of redimensioning - not used factor is recalculate
541 to do any non standard transformations
543 * @retval i420 Buffer with the i420 data
544 * Format of stream is uvyy,uvyy - repeated 320 times for 640x480
545 y - repeated 640 times for 640x480
546 First 1280 bytes is maybe dummy ***FIXME***
549 void raw6270_2i420(uint8_t *raw, uint8_t *i420, struct microdia_coord *image,
550 struct microdia_coord *view, const int hflip,
551 const int vflip, const int factor)
553 int i, j, YIndex = 0, UVIndex = 0;
554 unsigned char *y, *u, *v;
555 uint8_t *buf;
556 int hshift, vshift;
557 /* For fast calculations */
558 int x_div_2, y_div_2;
559 /* Skip first 1280 bytes strange dummy bytes */
560 raw += 1280;
562 x_div_2 = image->x / 2; /* for fast calculation if x=640 x_div_2=320 */
563 y_div_2 = image->y / 2; /* for fast calculation if y=480 y_div_4=240 */
564 buf = raw;
565 y = i420;
566 u = i420 + view->x * view->y;
567 v = i420 + view->x * view->y + (view->x >> 1) * (view->y >> 1);
569 hshift = view->x - (image->x / factor);
570 hshift >>= 1;
571 vshift = view->y - (image->y / factor);
572 vshift >>= 1;
574 YIndex = vshift * view->x + hshift;
575 UVIndex = (vshift >> 1) * (view->x >> 1) + (hshift >> 1);
576 /* we skipped 1280 bytes, it's almost two lines */
577 for (i = 0; i < y_div_2 - 1; i++) {
578 for (j = 0; j < x_div_2; j++) {
579 u[UVIndex] = *buf;
580 buf++;
581 v[UVIndex] = *buf;
582 buf++;
583 y[YIndex] = *buf;
584 buf++;
585 YIndex += ((j * 2) % factor) == 0 ? 1 : 0;
586 y[YIndex] = *buf;
587 buf++;
588 YIndex += ((j * 2 + 1) % factor) == 0 ? 1 : 0;
589 UVIndex += (j % factor) == 0 ? 1 : 0;
591 YIndex -= hshift;
592 YIndex -= (image->x / factor);
593 if ((i * 2) % factor == 0)
594 YIndex += view->x + hshift;
595 else
596 YIndex += hshift;
598 for (j = 0; j < image->x; j++) {
599 y[YIndex] = *buf;
600 buf++;
601 YIndex += (j % factor) == 0 ? 1 : 0;
603 YIndex -= hshift;
604 YIndex -= (image->x / factor);
605 if ((i * 2 + 1) % factor == 0)
606 YIndex += view->x + hshift;
607 else
608 YIndex += hshift;
610 UVIndex -= (hshift >> 1);
611 UVIndex -= x_div_2 / factor;
612 if (i % factor == 0)
613 UVIndex += (view->x >> 1) + (hshift >> 1);
614 else
615 UVIndex += (hshift >> 1);
621 * @brief This function permits to convert an image from 6270 rawformat to BGR24
622 * @param raw Buffer with the bayer data
623 * @param image Size of image
624 * @param view Size of view
625 * @param hflip Horizontal flip - not implemented yet
626 * @param vflip Vertical flip - not implemented yet
627 * @param factor Factor of redimensioning - not used factor is recalculate
628 to do any non standard transformations
630 * @retval rgb Buffer with the rgb data
631 Format of stream is uvyy,uvyy - repeated 320 times for 640x480
632 y - repeated 640 times for 640x480
633 First 1280 bytes is maybe dumy ***FIXME***
636 void raw6270_2BGR24(uint8_t *raw, uint8_t *rgb, struct microdia_coord *image,
637 struct microdia_coord *view, const int hflip,
638 const int vflip, const int factor)
640 int i, j, incX;
641 /* Maybe is not necesery to use long variables but I not sure in this moment */
642 long y11, y12, y21, y22, u, v, y, C, D, E;
643 long ScaleIncX, ScaleIncY;
644 long pointerIncX, pointerIncY;
645 uint8_t *bufUVYY;
646 uint8_t *bufY;
647 uint8_t *out_row1;
648 uint8_t *out_row2;
650 /* For fast calculations*/
651 int x_div_2, y_div_2;
652 /* Skip first 1280 bytes strange dummy bytes */
653 raw += 1280;
655 x_div_2 = image->x / 2; /* for fast calculation if x=640 x_div_2=320 */
656 y_div_2 = image->y / 2; /* for fast calculation if y=480 y_div_4=240 */
657 incX = 3 * view->x; /* Incrementation koeficient for next row*/
658 bufUVYY = raw;
659 bufY = raw + 2 * image->x;
662 // Because I can't use float ratio is multiply by 1000
663 // then 1000 is equal of increment image (X or Y) with 1
665 ScaleIncX = (1000 * view->x) / image->x;
666 ScaleIncY = (1000 * view->y) / image->y;
668 out_row1 = rgb;
669 out_row2 = out_row1 + incX;
670 /* we skipped 1280 bytes, it's almost two lines*/
671 pointerIncY = 1000;
672 for (i = 0; i < y_div_2-1; i++) {
673 pointerIncX = 1000;
674 for (j = 0; j < x_div_2; j++) {
675 pointerIncX += ScaleIncX;
677 u = (unsigned char)(*bufUVYY);
678 bufUVYY++;
680 v = (unsigned char)(*bufUVYY);
681 bufUVYY++;
683 y11 = (unsigned char)(*bufUVYY);
684 bufUVYY++;
686 y12 = (unsigned char)(*bufUVYY);
687 bufUVYY++;
689 y21 = (unsigned char)(*bufY);
690 bufY++;
692 y22 = (unsigned char)(*bufY);
693 bufY++;
695 if ((pointerIncX > 999) && (pointerIncY > 499)) {
696 pointerIncX -= 1001;
697 y = y11;
698 C = y - 16;
699 D = u - 128;
700 E = v - 128;
702 *out_row1 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
703 out_row1++;
704 *out_row1 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
705 out_row1++;
706 *out_row1 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
707 out_row1++;
709 y = y12;
711 C = y - 16;
712 D = u - 128;
713 E = v - 128;
716 *out_row1 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
717 out_row1++;
718 *out_row1 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
719 out_row1++;
720 *out_row1 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
721 out_row1++;
724 // Second row of stream is displayed only
725 // if image is greath than half
727 if (ScaleIncY > 501) {
728 y = y21;
730 C = y - 16;
731 D = u - 128;
732 E = v - 128;
734 *out_row2 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
735 out_row2++;
736 *out_row2 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
737 out_row2++;
738 *out_row2 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
739 out_row2++;
741 y = y22;
743 C = y - 16;
744 D = u - 128;
745 E = v - 128;
747 *out_row2 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
748 out_row2++;
749 *out_row2 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
750 out_row2++;
751 *out_row2 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
752 out_row2++;
757 // this comparation can be optimized and moved in
758 // if((pointerIncX>999)&&(pointerIncY>499))
760 if (pointerIncY > 499)
761 pointerIncY -= 500;
763 // Use 2 rows only if
764 // vertical ratio > 0.5 (increment is ratio*1000)
766 if (ScaleIncY > 501) {
767 out_row1 = out_row1 + incX;
768 out_row2 = out_row2 + incX;
771 pointerIncY += ScaleIncY;
772 bufUVYY = bufUVYY + image->x;
773 bufY = bufY + 2 * image->x;
779 * @brief This function permits to convert an image from 6270 rawformat to RGB24
780 * @brief The same function as convert to BGR24 but only B and R is change order
781 * @param raw Buffer with the bayer data
782 * @param image Size of image
783 * @param view Size of view
784 * @param hflip Horizontal flip
785 * @param vflip Vertical flip
786 * @param factor Factor of redimensioning
788 * @retval rgb Buffer with the rgb data
789 Format of stream is uvyy,uvyy - repeated 320 times for 640x480
790 y - repeated 640 times for 640x480
791 First 1280 bytes is maybe dumy ***FIXME***
794 void raw6270_2RGB24(uint8_t *raw, uint8_t *rgb, struct microdia_coord *image,
795 struct microdia_coord *view, const int hflip,
796 const int vflip, const int factor)
798 int i, j, incX;
799 /* Maybe is not necesery to use long variables but I not sure in this moment */
800 long y11, y12, y21, y22, u, v, y, C, D, E;
801 long ScaleIncX, ScaleIncY;
802 long pointerIncX, pointerIncY;
803 uint8_t *bufUVYY;
804 uint8_t *bufY;
805 uint8_t *out_row1;
806 uint8_t *out_row2;
808 /* For fast calculations */
809 int x_div_2, y_div_2;
810 /* Skip first 1280 bytes strange dummy bytes */
811 raw += 1280;
813 x_div_2 = image->x / 2; /* for fast calculation if x=640 x_div_2=320 */
814 y_div_2 = image->y / 2; /* for fast calculation if y=480 y_div_4=240 */
815 incX = 3 * view->x;
816 bufUVYY = raw;
817 bufY = raw + 2 * image->x;
820 // Because I can't use float ratio is multiply by 1000 then
821 // 1000 is equal of increment image (X or Y) with 1
823 ScaleIncX = (1000*view->x) / image->x;
824 ScaleIncY = (1000*view->y) / image->y;
826 out_row1 = rgb;
827 out_row2 = out_row1 + incX;
828 /* we skipped 1280 bytes, it's almost two lines */
829 pointerIncY = 1000;
830 for (i = 0; i < y_div_2-1; i++) {
831 pointerIncX = 1000;
832 for (j = 0; j < x_div_2; j++) {
833 pointerIncX += ScaleIncX;
835 u = (unsigned char)(*bufUVYY);
836 bufUVYY++;
838 v = (unsigned char)(*bufUVYY);
839 bufUVYY++;
841 y11 = (unsigned char)(*bufUVYY);
842 bufUVYY++;
844 y12 = (unsigned char)(*bufUVYY);
845 bufUVYY++;
847 y21 = (unsigned char)(*bufY);
848 bufY++;
850 y22 = (unsigned char)(*bufY);
851 bufY++;
853 if ((pointerIncX > 999) && (pointerIncY > 499)) {
854 pointerIncX -= 1001;
855 y = y11;
856 C = y - 16;
857 D = u - 128;
858 E = v - 128;
860 *out_row1 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
861 out_row1++;
862 *out_row1 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
863 out_row1++;
864 *out_row1 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
865 out_row1++;
867 y = y12;
869 C = y - 16;
870 D = u - 128;
871 E = v - 128;
873 *out_row1 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
874 out_row1++;
875 *out_row1 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
876 out_row1++;
877 *out_row1 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
878 out_row1++;
881 // Second row of stream is displayed only
882 // if image is greath than half
884 if (ScaleIncY > 501) {
885 y = y21;
887 C = y - 16;
888 D = u - 128;
889 E = v - 128;
891 *out_row2 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
892 out_row2++;
893 *out_row2 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
894 out_row2++;
895 *out_row2 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
896 out_row2++;
898 y = y22;
900 C = y - 16;
901 D = u - 128;
902 E = v - 128;
904 *out_row2 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
905 out_row2++;
906 *out_row2 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
907 out_row2++;
908 *out_row2 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
909 out_row2++;
914 // this comparation can be optimized and moved in
915 // if((pointerIncX>999)&&(pointerIncY>499))
917 if (pointerIncY > 499)
918 pointerIncY -= 500;
919 /* Use 2 rows only if vertical ratio > 0.5 (increment is ratio*1000) */
920 if (ScaleIncY > 501) {
921 out_row1 = out_row1 + incX;
922 out_row2 = out_row2 + incX;
925 pointerIncY += ScaleIncY;
926 bufUVYY = bufUVYY + image->x;
927 bufY = bufY + 2 * image->x;