2 * @file microdia-decoder.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
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>
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,
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,
64 void microdia_raw2bgr24(uint8_t *, uint8_t *, struct microdia_coord
*,
65 struct microdia_coord
*, const int, const int,
68 void microdia_correct_brightness(uint8_t *, const int, const int,
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
)
97 dev
->flip_detect(dev
);
99 if (dev
->set_hvflip
) {
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
) {
117 case MICRODIA_160x120
:
121 case MICRODIA_320x240
:
125 case MICRODIA_640x480
:
126 case MICRODIA_800x600
:
127 case MICRODIA_1024x768
:
128 case MICRODIA_1280x1024
:
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
) ||
142 CAMERA_MODEL(USB_0C45_VID
, USB_627B_PID
) ||
144 CAMERA_MODEL(USB_0C45_VID
, USB_6288_PID
) ||
146 CAMERA_MODEL(USB_0C45_VID
, USB_62B3_PID
) ||
148 CAMERA_MODEL(USB_0C45_VID
, USB_62BB_PID
) ||
150 CAMERA_MODEL(USB_145F_VID
, USB_013D_PID
)) {
151 raw6270_2RGB24(image
, data
, &dev
->image
, &dev
->view
,
152 hflip
, vflip
, factor
);
155 case V4L2_PIX_FMT_BGR24
:
156 if (dev
->webcam_model
==
157 CAMERA_MODEL(USB_0C45_VID
, USB_6270_PID
) ||
159 CAMERA_MODEL(USB_0C45_VID
, USB_627B_PID
) ||
161 CAMERA_MODEL(USB_0C45_VID
, USB_6288_PID
) ||
163 CAMERA_MODEL(USB_0C45_VID
, USB_62B3_PID
) ||
165 CAMERA_MODEL(USB_0C45_VID
, USB_62BB_PID
) ||
167 CAMERA_MODEL(USB_145F_VID
, USB_013D_PID
)) {
168 raw6270_2BGR24(image
, data
, &dev
->image
, &dev
->view
,
169 hflip
, vflip
, factor
);
171 microdia_raw2bgr24(image
, data
, &dev
->image
, &dev
->view
,
172 hflip
, vflip
, factor
);
175 case V4L2_PIX_FMT_YUV420
:
176 if (dev
->webcam_model
==
177 CAMERA_MODEL(USB_0C45_VID
, USB_6270_PID
) ||
179 CAMERA_MODEL(USB_0C45_VID
, USB_627B_PID
) ||
181 CAMERA_MODEL(USB_0C45_VID
, USB_6288_PID
) ||
183 CAMERA_MODEL(USB_0C45_VID
, USB_62B3_PID
) ||
185 CAMERA_MODEL(USB_0C45_VID
, USB_62BB_PID
) ||
187 CAMERA_MODEL(USB_145F_VID
, USB_013D_PID
)) {
188 raw6270_2i420(image
, data
, &dev
->image
, &dev
->view
,
189 hflip
, vflip
, factor
);
191 microdia_raw2i420(image
, data
, &dev
->image
, &dev
->view
,
192 hflip
, vflip
, factor
);
195 case V4L2_PIX_FMT_YUYV
:
200 buffer
->bytesused
= dev
->vsettings
.format
.sizeimage
;
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
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
,
228 case V4L2_PIX_FMT_RGB24
:
229 case V4L2_PIX_FMT_BGR24
:
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)
242 *(img
+ i
) += (unsigned char) x
;
245 x
= (32767 - brightness
) / 256;
246 for (i
= 0; i
< (width
* height
* depth
); i
++) {
247 if ((unsigned char) x
> *(img
+ i
))
250 *(img
+ i
) -= (unsigned char) x
;
255 case V4L2_PIX_FMT_UYVY
:
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)
265 *(img
+ i
) += (unsigned char) x
;
268 x
= (32767 - brightness
) / 256;
270 for (i
= 1; i
< (width
* height
* depth
); i
+= depth
) {
271 if ((unsigned char) x
> *(img
+ i
))
274 *(img
+ i
) -= (unsigned char) x
;
280 case V4L2_PIX_FMT_YUYV
:
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)
290 *(img
+ i
) += (unsigned char) x
;
293 x
= (32767 - brightness
) / 256;
295 for (i
= 0; i
< (width
* height
* depth
); i
+= depth
) {
296 if ((unsigned char) x
> *(img
+ i
))
299 *(img
+ i
) -= (unsigned char) x
;
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
,
318 memcpy(raw
, bayer
, size
);
321 /* Table to translate Y offset to UV offset */
322 static int UVTranslate
[32] = {
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
;
365 fwidth
= image
->x
/ factor
;
366 fheight
= image
->y
/ factor
;
368 while (i
< (image
->x
* image
->y
+ (image
->x
* image
->y
) / 2)) {
370 for (tile
= 0; tile
< 4; tile
++) {
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 */
383 relX
= image
->x
- relX
;
385 relY
= image
->y
- relY
;
390 relX
+= (view
->x
- fwidth
) >> 1;
391 relY
+= (view
->y
- fheight
) >> 1;
392 if ((relX
< view
->x
) && (relY
< view
->y
)) {
399 ptr
= buf3
+ relY
* view
->x
* 3 + relX
* 3;
400 *ptr
= CLIP((298 * c
+ 516 * d
+ 128) >> 8, 0, 255);
402 *ptr
= CLIP((298 * c
- 100 * d
- 208 * e
+ 128) >> 8, 0, 255);
404 *ptr
= CLIP((298 * c
+ 409 * e
+ 128) >> 8, 0, 255);
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];
443 relX
= image
->x
- relX
- 1;
445 relY
= image
->y
- relY
- 1;
472 if ((relX
< view
->x
) && (relY
< view
->y
)) {
473 ptr
= buf3
+ relY
* view
->x
+ relX
;
480 for (j
= 0; j
< 32; j
++) {
481 relX
= (x_div2
) + (j
& 0x07);
482 relY
= (y_div2
) + (j
>> 3);
484 relX
= image_x_div2
- relX
- 1;
486 relY
= image_y_div2
- relY
- 1;
488 relX
+= x_padding_div2
;
489 relY
+= y_padding_div2
;
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
];
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
;
557 /* For fast calculations */
558 int x_div_2
, y_div_2
;
559 /* Skip first 1280 bytes strange dummy bytes */
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 */
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
);
571 vshift
= view
->y
- (image
->y
/ factor
);
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
++) {
585 YIndex
+= ((j
* 2) % factor
) == 0 ? 1 : 0;
588 YIndex
+= ((j
* 2 + 1) % factor
) == 0 ? 1 : 0;
589 UVIndex
+= (j
% factor
) == 0 ? 1 : 0;
592 YIndex
-= (image
->x
/ factor
);
593 if ((i
* 2) % factor
== 0)
594 YIndex
+= view
->x
+ hshift
;
598 for (j
= 0; j
< image
->x
; j
++) {
601 YIndex
+= (j
% factor
) == 0 ? 1 : 0;
604 YIndex
-= (image
->x
/ factor
);
605 if ((i
* 2 + 1) % factor
== 0)
606 YIndex
+= view
->x
+ hshift
;
610 UVIndex
-= (hshift
>> 1);
611 UVIndex
-= x_div_2
/ factor
;
613 UVIndex
+= (view
->x
>> 1) + (hshift
>> 1);
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
)
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
;
650 /* For fast calculations*/
651 int x_div_2
, y_div_2
;
652 /* Skip first 1280 bytes strange dummy bytes */
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*/
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
;
669 out_row2
= out_row1
+ incX
;
670 /* we skipped 1280 bytes, it's almost two lines*/
672 for (i
= 0; i
< y_div_2
-1; i
++) {
674 for (j
= 0; j
< x_div_2
; j
++) {
675 pointerIncX
+= ScaleIncX
;
677 u
= (unsigned char)(*bufUVYY
);
680 v
= (unsigned char)(*bufUVYY
);
683 y11
= (unsigned char)(*bufUVYY
);
686 y12
= (unsigned char)(*bufUVYY
);
689 y21
= (unsigned char)(*bufY
);
692 y22
= (unsigned char)(*bufY
);
695 if ((pointerIncX
> 999) && (pointerIncY
> 499)) {
702 *out_row1
= CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
704 *out_row1
= CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
706 *out_row1
= CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
716 *out_row1
= CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
718 *out_row1
= CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
720 *out_row1
= CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
724 // Second row of stream is displayed only
725 // if image is greath than half
727 if (ScaleIncY
> 501) {
734 *out_row2
= CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
736 *out_row2
= CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
738 *out_row2
= CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
747 *out_row2
= CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
749 *out_row2
= CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
751 *out_row2
= CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
757 // this comparation can be optimized and moved in
758 // if((pointerIncX>999)&&(pointerIncY>499))
760 if (pointerIncY
> 499)
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
)
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
;
808 /* For fast calculations */
809 int x_div_2
, y_div_2
;
810 /* Skip first 1280 bytes strange dummy bytes */
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 */
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
;
827 out_row2
= out_row1
+ incX
;
828 /* we skipped 1280 bytes, it's almost two lines */
830 for (i
= 0; i
< y_div_2
-1; i
++) {
832 for (j
= 0; j
< x_div_2
; j
++) {
833 pointerIncX
+= ScaleIncX
;
835 u
= (unsigned char)(*bufUVYY
);
838 v
= (unsigned char)(*bufUVYY
);
841 y11
= (unsigned char)(*bufUVYY
);
844 y12
= (unsigned char)(*bufUVYY
);
847 y21
= (unsigned char)(*bufY
);
850 y22
= (unsigned char)(*bufY
);
853 if ((pointerIncX
> 999) && (pointerIncY
> 499)) {
860 *out_row1
= CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
862 *out_row1
= CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
864 *out_row1
= CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
873 *out_row1
= CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
875 *out_row1
= CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
877 *out_row1
= CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
881 // Second row of stream is displayed only
882 // if image is greath than half
884 if (ScaleIncY
> 501) {
891 *out_row2
= CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
893 *out_row2
= CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
895 *out_row2
= CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
904 *out_row2
= CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
906 *out_row2
= CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
908 *out_row2
= CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
914 // this comparation can be optimized and moved in
915 // if((pointerIncX>999)&&(pointerIncY>499))
917 if (pointerIncY
> 499)
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
;