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, const int);
48 void raw6270_2RGB24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
49 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
);
50 void raw6270_2BGR24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
51 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
);
52 void microdia_getraw(uint8_t *, uint8_t *, int);
54 void microdia_raw2i420(uint8_t *, uint8_t *, struct microdia_coord
*,
55 struct microdia_coord
*, const int, const int, const int);
56 void microdia_raw2bgr24(uint8_t *, uint8_t *, struct microdia_coord
*,
57 struct microdia_coord
*, const int, const int, const int);
60 void microdia_correct_brightness(uint8_t *, const int, const int,
65 * @brief Decompress a frame
67 * This function permits to decompress a frame from the video stream.
69 * @param dev Device structure
70 * @param buffer Image data
72 * @returns 0 if all is OK
74 int microdia_decompress(struct usb_microdia
*dev
,
75 struct v4l2_buffer
*buffer
)
90 if (dev
->flip_detect
) {
91 dev
->flip_detect(dev
);
94 if (dev
->set_hvflip
) {
98 hflip
= dev
->vsettings
.hflip
;
99 vflip
= dev
->vsettings
.vflip
;
102 image
= dev
->queue
.scratch
;
104 data
= dev
->queue
.mem
+ buffer
->m
.offset
;
105 memcpy(image
, data
, MICRODIA_FRAME_SIZE
);
107 switch (dev
->resolution
) {
112 case MICRODIA_160x120
:
116 case MICRODIA_320x240
:
120 case MICRODIA_640x480
:
121 case MICRODIA_800x600
:
122 case MICRODIA_1024x768
:
123 case MICRODIA_1280x1024
:
132 switch (dev
->vsettings
.format
.pixelformat
) {
133 case V4L2_PIX_FMT_RGB24
:
134 if (dev
->webcam_model
== MICRODIA_6270
135 || dev
->webcam_model
== MICRODIA_627B
136 || dev
->webcam_model
== MICRODIA_6288
137 || dev
->webcam_model
== MICRODIA_62B3
) {
138 raw6270_2RGB24(image
, data
, &dev
->image
, &dev
->view
,
139 hflip
, vflip
, factor
);
142 case V4L2_PIX_FMT_BGR24
:
143 if (dev
->webcam_model
== MICRODIA_6270
144 || dev
->webcam_model
== MICRODIA_627B
145 || dev
->webcam_model
== MICRODIA_6288
146 || dev
->webcam_model
== MICRODIA_62B3
) {
147 raw6270_2BGR24(image
, data
, &dev
->image
, &dev
->view
,
148 hflip
, vflip
, factor
);
150 microdia_raw2bgr24(image
, data
, &dev
->image
, &dev
->view
,
151 hflip
, vflip
, factor
);
154 case V4L2_PIX_FMT_YUV420
:
155 if (dev
->webcam_model
== MICRODIA_6270
156 || dev
->webcam_model
== MICRODIA_627B
157 || dev
->webcam_model
== MICRODIA_6288
158 || dev
->webcam_model
== MICRODIA_62B3
) {
159 raw6270_2i420(image
, data
, &dev
->image
, &dev
->view
,
160 hflip
, vflip
, factor
);
162 microdia_raw2i420(image
, data
, &dev
->image
, &dev
->view
,
163 hflip
, vflip
, factor
);
166 case V4L2_PIX_FMT_YUYV
:
171 buffer
->bytesused
= dev
->vsettings
.format
.sizeimage
;
178 * @brief Correct the brightness of an image.
180 * This function permits to correct the brightness of an image.
182 * @param img Buffer to RGB/YUV data
183 * @param width Width of frame
184 * @param height Height of frame
185 * @param brightness Brightness correction
188 * @retval rgb Buffer to RGB/YUV data
190 void microdia_correct_brightness(uint8_t *img
, const int width
, const int height
,
191 const int brightness
, int palette
)
199 case V4L2_PIX_FMT_RGB24
:
200 case V4L2_PIX_FMT_BGR24
:
202 case V4L2_PIX_FMT_RGB32
:
203 case V4L2_PIX_FMT_BGR32
:
204 depth
= (depth
== 24) ? 3 : 4;
206 if (brightness
>= 32767) {
207 x
= (brightness
- 32767) / 256;
209 for (i
= 0; i
< (width
* height
* depth
); i
++) {
210 if ((*(img
+ i
) + (unsigned char) x
) > 255)
213 *(img
+ i
) += (unsigned char) x
;
217 x
= (32767 - brightness
) / 256;
219 for (i
= 0; i
< (width
* height
* depth
); i
++) {
220 if ((unsigned char) x
> *(img
+ i
))
223 *(img
+ i
) -= (unsigned char) x
;
229 case V4L2_PIX_FMT_UYVY
:
232 if (brightness
>= 32767) {
233 x
= (brightness
- 32767) / 256;
235 for (i
= 1; i
< (width
* height
* depth
); i
=i
+depth
) {
236 if ((*(img
+ i
) + (unsigned char) x
) > 255)
239 *(img
+ i
) += (unsigned char) x
;
243 x
= (32767 - brightness
) / 256;
245 for (i
= 1; i
< (width
* height
* depth
); i
=i
+depth
) {
246 if ((unsigned char) x
> *(img
+ i
))
249 *(img
+ i
) -= (unsigned char) x
;
255 case V4L2_PIX_FMT_YUYV
:
258 if (brightness
>= 32767) {
259 x
= (brightness
- 32767) / 256;
261 for (i
= 0; i
< (width
* height
* depth
); i
=i
+depth
) {
262 if ((*(img
+ i
) + (unsigned char) x
) > 255)
265 *(img
+ i
) += (unsigned char) x
;
269 x
= (32767 - brightness
) / 256;
271 for (i
= 0; i
< (width
* height
* depth
); i
=i
+depth
) {
272 if ((unsigned char) x
> *(img
+ i
))
275 *(img
+ i
) -= (unsigned char) x
;
285 * @brief This function permits to get the raw data. (without treatments)
287 * @param bayer Buffer with the bayer data
288 * @param size Length of bayer buffer
290 * @retval raw Buffer with the data from video sensor
292 void microdia_getraw(uint8_t *bayer
, uint8_t *raw
,
294 memcpy(raw
, bayer
, size
);
297 /* Table to translate Y offset to UV offset */
298 static int UVTranslate
[32] = {0, 1, 2, 3,
307 static int Y_coords_624x
[128][2] = {
308 { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 0}, { 5, 0}, { 6, 0}, { 7, 0},
309 { 0, 1}, { 1, 1}, { 2, 1}, { 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7, 1},
310 { 0, 2}, { 1, 2}, { 2, 2}, { 3, 2}, { 4, 2}, { 5, 2}, { 6, 2}, { 7, 2},
311 { 0, 3}, { 1, 3}, { 2, 3}, { 3, 3}, { 4, 3}, { 5, 3}, { 6, 3}, { 7, 3},
313 { 0, 4}, { 1, 4}, { 2, 4}, { 3, 4}, { 4, 4}, { 5, 4}, { 6, 4}, { 7, 4},
314 { 0, 5}, { 1, 5}, { 2, 5}, { 3, 5}, { 4, 5}, { 5, 5}, { 6, 5}, { 7, 5},
315 { 0, 6}, { 1, 6}, { 2, 6}, { 3, 6}, { 4, 6}, { 5, 6}, { 6, 6}, { 7, 6},
316 { 0, 7}, { 1, 7}, { 2, 7}, { 3, 7}, { 4, 7}, { 5, 7}, { 6, 7}, { 7, 7},
318 { 8, 0}, { 9, 0}, {10, 0}, {11, 0}, {12, 0}, {13, 0}, {14, 0}, {15, 0},
319 { 8, 1}, { 9, 1}, {10, 1}, {11, 1}, {12, 1}, {13, 1}, {14, 1}, {15, 1},
320 { 8, 2}, { 9, 2}, {10, 2}, {11, 2}, {12, 2}, {13, 2}, {14, 2}, {15, 2},
321 { 8, 3}, { 9, 3}, {10, 3}, {11, 3}, {12, 3}, {13, 3}, {14, 3}, {15, 3},
323 { 8, 4}, { 9, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15, 4},
324 { 8, 5}, { 9, 5}, {10, 5}, {11, 5}, {12, 5}, {13, 5}, {14, 5}, {15, 5},
325 { 8, 6}, { 9, 6}, {10, 6}, {11, 6}, {12, 6}, {13, 6}, {14, 6}, {15, 6},
326 { 8, 7}, { 9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15, 7}
329 void microdia_raw2bgr24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
330 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
332 int i
= 0, x
= 0, y
= 0;
333 unsigned char *buf
= raw
;
334 unsigned char *buf3
= rgb
;
337 fwidth
= image
->x
/ factor
;
338 fheight
= image
->y
/ factor
;
340 while (i
< (image
->x
* image
->y
+ (image
->x
* image
->y
) / 2)) {
342 for (tile
= 0; tile
< 4; tile
++) {
345 for (subY
= 0; subY
< 4; subY
++) {
346 for (subX
= 0; subX
< 8; subX
++) {
347 int subI
= i
+ tile
* 32 + 8 * subY
+ subX
;
348 int subU
= i
+ 128 + UVTranslate
[tile
* 8 + 4 * (subY
>> 1) + (subX
>> 1)];
349 int subV
= subU
+ 32;
351 int relX
= x
+ (((tile
== 0) || (tile
== 1)) ? 0 : 8) + subX
; //tile 0, 1 to into left comumn
352 int relY
= y
+ (((tile
== 0) || (tile
== 2)) ? 0 : 4) + subY
; //tile 0, 2 go into top row
355 relX
= image
->x
- relX
;
358 relY
= image
->y
- relY
;
364 relX
+= (view
->x
- fwidth
) >> 1;
365 relY
+= (view
->y
- fheight
) >> 1;
366 if ((relX
< view
->x
) && (relY
< view
->y
)) {
373 ptr
= buf3
+ relY
* view
->x
* 3 + relX
* 3;
374 *ptr
= CLIP((298 * c
+ 516 * d
+ 128) >> 8, 0, 255);
376 *ptr
= CLIP((298 * c
- 100 * d
- 208 * e
+ 128) >> 8, 0, 255);
378 *ptr
= CLIP((298 * c
+ 409 * e
+ 128) >> 8, 0, 255);
393 void microdia_raw2i420(uint8_t *raw
, uint8_t *i420
, struct microdia_coord
*image
,
394 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
396 int i
= 0, x
= 0, y
= 0, j
, relX
, relY
, x_div2
, y_div2
;
397 unsigned char *buf
= raw
, *ptr
;
398 unsigned char *buf3
= i420
;
399 int fwidth
= image
->x
/ factor
, fheight
= image
->y
/ factor
;
400 int view_size
= view
->x
* view
->y
;
401 int view_size_div4
= view_size
>> 2;
402 int x_padding
= (view
->x
- fwidth
) >> 1;
403 int y_padding
= (view
->y
- fheight
) >> 1;
404 int x_padding_div2
= x_padding
>> 1;
405 int y_padding_div2
= y_padding
>> 1;
406 int image_x_div2
= image
->x
>> 1;
407 int image_y_div2
= image
->y
>> 1;
408 int view_x_div2
= view
->x
>> 1;
410 while (i
< (image
->x
* image
->y
+ (image
->x
* image
->y
) / 2)) {
411 for (j
= 0; j
< 128; j
++) {
412 relX
= x
+ Y_coords_624x
[j
][0];
413 relY
= y
+ Y_coords_624x
[j
][1];
415 relX
= image
->x
- relX
- 1;
417 relY
= image
->y
- relY
- 1;
444 if ((relX
< view
->x
) && (relY
< view
->y
)) {
445 ptr
= buf3
+ relY
* view
->x
+ relX
;
452 for (j
= 0; j
< 32; j
++) {
453 relX
= (x_div2
) + (j
& 0x07);
454 relY
= (y_div2
) + (j
>> 3);
456 relX
= image_x_div2
- relX
- 1;
458 relY
= image_y_div2
- relY
- 1;
460 relX
+= x_padding_div2
;
461 relY
+= y_padding_div2
;
485 if ((relX
< view
->x
) && (relY
< view
->y
)) {
486 ptr
= buf3
+ view_size
+
487 relY
* (view_x_div2
) + relX
;
488 *ptr
= buf
[i
+ 128 + j
];
489 ptr
+= view_size_div4
;
490 *ptr
= buf
[i
+ 160 + j
];
507 * @brief This function permits to convert an image from 6270 raw format to i420
508 * @param raw Buffer with the bayer data
509 * @param image Size of image
510 * @param view Size of view
511 * @param hflip Horizontal flip - not implemented
512 * @param vflip Vertical flip - not implemented
513 * @param factor Factor of redimensioning - not used factor is recalculate to do any non standard transformations
515 * @retval i420 Buffer with the i420 data
516 Format of stream is uvyy,uvyy - repeated 320 times for 640x480
517 y - repeated 640 times for 640x480
518 First 1280 bytes is maybe dumy ***FIX ME***
521 void raw6270_2i420(uint8_t *raw
, uint8_t *i420
, struct microdia_coord
*image
,
522 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
524 int i
, j
, YIndex
= 0, UVIndex
= 0;
525 unsigned char *y
, *u
, *v
;
528 //For fast calculations
530 //Skip first 1280 bytes strange dummy bytes
533 x_div_2
=image
->x
/ 2; //for fast calculation if x=640 x_div_2=320
534 y_div_2
=image
->y
/ 2; //for fast calculation if y=480 y_div_4=240
537 u
= i420
+ view
->x
* view
->y
;
538 v
= i420
+ view
->x
* view
->y
+ (view
->x
>> 1) * (view
->y
>> 1);
540 hshift
= view
->x
- (image
->x
/ factor
);
542 vshift
= view
->y
- (image
->y
/ factor
);
545 YIndex
= vshift
* view
->x
+ hshift
;
546 UVIndex
= (vshift
>> 1) * (view
->x
>> 1) + (hshift
>> 1);
547 //we skipped 1280 bytes, it's almost two lines
548 for (i
= 0; i
< y_div_2
- 1; i
++) {
549 for (j
= 0; j
< x_div_2
; j
++) {
556 YIndex
+= ((j
* 2) % factor
) == 0 ? 1 : 0;
559 YIndex
+= ((j
* 2 + 1) % factor
) == 0 ? 1 : 0;
560 UVIndex
+= (j
% factor
) == 0 ? 1 : 0;
563 YIndex
-= (image
->x
/ factor
);
564 if ((i
* 2) % factor
== 0) YIndex
+= view
->x
+ hshift
;
565 else YIndex
+= hshift
;
567 for (j
= 0; j
< image
->x
; j
++) {
570 YIndex
+= (j
% factor
) == 0 ? 1 : 0;
573 YIndex
-= (image
->x
/ factor
);
574 if ((i
* 2 + 1) % factor
== 0) YIndex
+= view
->x
+ hshift
;
575 else YIndex
+= hshift
;
577 UVIndex
-= (hshift
>> 1);
578 UVIndex
-= x_div_2
/ factor
;
579 if (i
% factor
== 0) UVIndex
+= (view
->x
>> 1) + (hshift
>> 1);
580 else UVIndex
+= (hshift
>> 1);
586 * @brief This function permits to convert an image from 6270 raw format to BGR24
587 * @param raw Buffer with the bayer data
588 * @param image Size of image
589 * @param view Size of view
590 * @param hflip Horizontal flip - not implemented yet
591 * @param vflip Vertical flip - not implemented yet
592 * @param factor Factor of redimensioning - not used factor is recalculate to do any non standard transformations
594 * @retval rgb Buffer with the rgb data
595 Format of stream is uvyy,uvyy - repeated 320 times for 640x480
596 y - repeated 640 times for 640x480
597 First 1280 bytes is maybe dumy ***FIX ME***
600 void raw6270_2BGR24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
601 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
604 //Maybe is not necesery to use long variables but I not sure in this moment
605 long y11
,y12
,y21
,y22
, u
, v
,y
,C
,D
,E
;
606 long ScaleIncX
,ScaleIncY
;
607 long pointerIncX
,pointerIncY
;
613 //For fast calculations
615 //Skip first 1280 bytes strange dummy bytes
618 x_div_2
=image
->x
/ 2; //for fast calculation if x=640 x_div_2=320
619 y_div_2
=image
->y
/ 2; //for fast calculation if y=480 y_div_4=240
620 incX
=3*view
->x
; //Incrementation koeficient for next row
624 //Because I can't use float ratio is multiply by 1000 then 1000 is equal of increment image (X or Y) with 1
625 ScaleIncX
=(1000*view
->x
)/image
->x
;
626 ScaleIncY
=(1000*view
->y
)/image
->y
;
630 out_row2
=out_row1
+incX
;
631 //we skipped 1280 bytes, it's almost two lines
633 for (i
= 0; i
< y_div_2
-1; i
++) {
635 for (j
= 0; j
< x_div_2
; j
++) {
637 pointerIncX
+=ScaleIncX
;
639 u
=(unsigned char)(*bufUVYY
);
641 v
=(unsigned char)(*bufUVYY
);
643 y11
=(unsigned char)(*bufUVYY
);
645 y12
=(unsigned char)(*bufUVYY
);
647 y21
=(unsigned char)(*bufY
);
649 y22
=(unsigned char)(*bufY
);
652 if((pointerIncX
>999)&&(pointerIncY
>499)){
659 *out_row1
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
661 *out_row1
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
663 *out_row1
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
673 *out_row1
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
675 *out_row1
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
677 *out_row1
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
681 //Second row of stream is displayed only if image is greath than half
690 *out_row2
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
692 *out_row2
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
694 *out_row2
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
703 *out_row2
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
705 *out_row2
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
707 *out_row2
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
712 //this comparation can be optimized and moved in if((pointerIncX>999)&&(pointerIncY>499))
715 //Use 2 rows only if vertical ratio > 0.5 (increment is ratio*1000)
718 out_row1
=out_row1
+incX
;
719 out_row2
=out_row2
+incX
;
723 pointerIncY
+= ScaleIncY
;
724 bufUVYY
=bufUVYY
+image
->x
;
725 bufY
=bufY
+2*image
->x
;
733 * @brief This function permits to convert an image from 6270 raw format to RGB24
734 * @brief The same function as convert to BGR24 but only B and R is change order
735 * @param raw Buffer with the bayer data
736 * @param image Size of image
737 * @param view Size of view
738 * @param hflip Horizontal flip
739 * @param vflip Vertical flip
740 * @param factor Factor of redimensioning
742 * @retval rgb Buffer with the rgb data
743 Format of stream is uvyy,uvyy - repeated 320 times for 640x480
744 y - repeated 640 times for 640x480
745 First 1280 bytes is maybe dumy ***FIX ME***
748 void raw6270_2RGB24(uint8_t *raw
, uint8_t *rgb
, struct microdia_coord
*image
,
749 struct microdia_coord
*view
, const int hflip
, const int vflip
, const int factor
)
752 //Maybe is not necesery to use long variables but I not sure in this moment
753 long y11
,y12
,y21
,y22
, u
, v
,y
,C
,D
,E
;
754 long ScaleIncX
,ScaleIncY
;
755 long pointerIncX
,pointerIncY
;
761 //For fast calculations
763 //Skip first 1280 bytes strange dummy bytes
766 x_div_2
=image
->x
/ 2; //for fast calculation if x=640 x_div_2=320
767 y_div_2
=image
->y
/ 2; //for fast calculation if y=480 y_div_4=240
772 //Because I can't use float ratio is multiply by 1000 then 1000 is equal of increment image (X or Y) with 1
773 ScaleIncX
=(1000*view
->x
)/image
->x
;
774 ScaleIncY
=(1000*view
->y
)/image
->y
;
778 out_row2
=out_row1
+incX
;
779 //we skipped 1280 bytes, it's almost two lines
781 for (i
= 0; i
< y_div_2
-1; i
++) {
783 for (j
= 0; j
< x_div_2
; j
++) {
785 pointerIncX
+=ScaleIncX
;
787 u
=(unsigned char)(*bufUVYY
);
789 v
=(unsigned char)(*bufUVYY
);
791 y11
=(unsigned char)(*bufUVYY
);
793 y12
=(unsigned char)(*bufUVYY
);
795 y21
=(unsigned char)(*bufY
);
797 y22
=(unsigned char)(*bufY
);
800 if((pointerIncX
>999)&&(pointerIncY
>499)){
807 *out_row1
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
809 *out_row1
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
811 *out_row1
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
821 *out_row1
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
823 *out_row1
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
825 *out_row1
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
829 //Second row of stream is displayed only if image is greath than half
838 *out_row2
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
840 *out_row2
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
842 *out_row2
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
851 *out_row2
=CLIP((298 * C
+ 409 * E
+ 128) >> 8, 0, 255);
853 *out_row2
=CLIP((298 * C
- 100 * D
- 208 * E
+ 128) >> 8, 0, 255);
855 *out_row2
=CLIP((298 * C
+ 516 * D
+ 128) >> 8, 0, 255);
860 //this comparation can be optimized and moved in if((pointerIncX>999)&&(pointerIncY>499))
863 //Use 2 rows only if vertical ratio > 0.5 (increment is ratio*1000)
866 out_row1
=out_row1
+incX
;
867 out_row2
=out_row2
+incX
;
871 pointerIncY
+= ScaleIncY
;
872 bufUVYY
=bufUVYY
+image
->x
;
873 bufY
=bufY
+2*image
->x
;