Change 624f to support bayer format
[microdia.git] / microdia-decoder.c
blob993884566aa1c874cf2307605e2d6f5215d61210
1 /**
2 * @file microdia-decoder.c
3 * @author Nicolas VIVIEN
4 * @date 2008-02-01
6 * @brief Decoder for device specific image formats
8 * @note Copyright (C) Nicolas VIVIEN
10 * @par Licences
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/kernel.h>
30 #include <linux/version.h>
31 #include <linux/errno.h>
32 #include <linux/slab.h>
33 #include <linux/kref.h>
35 #include <linux/usb.h>
36 #include <media/v4l2-common.h>
38 #include "microdia.h"
39 #include "sn9c20x.h"
41 #define MAX(a, b) ((a) > (b) ? (a) : (b))
42 #define MIN(a, b) ((a) < (b) ? (a) : (b))
43 #define CLIP(a, low, high) MAX((low), MIN((high), (a)))
45 void raw6270_2i420(uint8_t *, uint8_t *, int,
46 int, const int, const int);
48 void raw6270_2RGB24(uint8_t *raw, uint8_t *rgb, int width,
49 int height, const int hflip,
50 const int vflip);
52 void raw6270_2BGR24(uint8_t *raw, uint8_t *rgb, int width,
53 int height, const int hflip,
54 const int vflip);
56 void microdia_getraw(uint8_t *, uint8_t *, int);
58 void microdia_raw2i420(uint8_t *, uint8_t *, int,
59 int, const int, const int);
61 void microdia_raw2bgr24(uint8_t *, uint8_t *, int,
62 int, const int, const int);
63 /**
64 * @brief Decompress a frame
66 * This function permits to decompress a frame from the video stream.
68 * @param dev Device structure
69 * @param buffer Image data
71 * @returns 0 if all is OK
73 int microdia_decompress(struct usb_microdia *dev, struct v4l2_buffer *buffer)
75 int factor;
76 int vflip;
77 int hflip;
78 int width, height;
79 int ret = 0;
81 void *data;
82 void *image;
84 if (dev == NULL) {
85 ret = -EFAULT;
86 goto done;
89 if (dev->flip_detect)
90 dev->flip_detect(dev);
92 if (dev->set_hvflip) {
93 hflip = 0;
94 vflip = 0;
95 } else {
96 hflip = dev->vsettings.hflip;
97 vflip = dev->vsettings.vflip;
100 image = dev->queue.scratch;
102 data = dev->queue.mem + buffer->m.offset;
103 memcpy(image, data, MICRODIA_FRAME_SIZE);
105 factor = 1;
107 width = dev->vsettings.format.width;
108 height = dev->vsettings.format.height;
110 switch (dev->vsettings.format.pixelformat) {
111 case V4L2_PIX_FMT_RGB24:
112 if (dev->webcam_model ==
113 CAMERA_MODEL(USB_0C45_VID, USB_6270_PID) ||
114 dev->webcam_model ==
115 CAMERA_MODEL(USB_0C45_VID, USB_627B_PID) ||
116 dev->webcam_model ==
117 CAMERA_MODEL(USB_0C45_VID, USB_6288_PID) ||
118 dev->webcam_model ==
119 CAMERA_MODEL(USB_0C45_VID, USB_62B3_PID) ||
120 dev->webcam_model ==
121 CAMERA_MODEL(USB_0C45_VID, USB_62BB_PID) ||
122 dev->webcam_model ==
123 CAMERA_MODEL(USB_145F_VID, USB_013D_PID)) {
124 raw6270_2RGB24(image, data, width,
125 height, hflip, vflip);
127 break;
128 case V4L2_PIX_FMT_BGR24:
129 if (dev->webcam_model ==
130 CAMERA_MODEL(USB_0C45_VID, USB_6270_PID) ||
131 dev->webcam_model ==
132 CAMERA_MODEL(USB_0C45_VID, USB_627B_PID) ||
133 dev->webcam_model ==
134 CAMERA_MODEL(USB_0C45_VID, USB_6288_PID) ||
135 dev->webcam_model ==
136 CAMERA_MODEL(USB_0C45_VID, USB_62B3_PID) ||
137 dev->webcam_model ==
138 CAMERA_MODEL(USB_0C45_VID, USB_62BB_PID) ||
139 dev->webcam_model ==
140 CAMERA_MODEL(USB_145F_VID, USB_013D_PID)) {
141 raw6270_2BGR24(image, data, width,
142 height, hflip, vflip);
143 } else {
144 microdia_raw2bgr24(image, data, width,
145 height, hflip, vflip);
147 break;
148 case V4L2_PIX_FMT_YUV420:
149 if (dev->webcam_model ==
150 CAMERA_MODEL(USB_0C45_VID, USB_6270_PID) ||
151 dev->webcam_model ==
152 CAMERA_MODEL(USB_0C45_VID, USB_627B_PID) ||
153 dev->webcam_model ==
154 CAMERA_MODEL(USB_0C45_VID, USB_6288_PID) ||
155 dev->webcam_model ==
156 CAMERA_MODEL(USB_0C45_VID, USB_62B3_PID) ||
157 dev->webcam_model ==
158 CAMERA_MODEL(USB_0C45_VID, USB_62BB_PID) ||
159 dev->webcam_model ==
160 CAMERA_MODEL(USB_145F_VID, USB_013D_PID)) {
161 raw6270_2i420(image, data, width,
162 height, hflip, vflip);
163 } else {
164 microdia_raw2i420(image, data, width,
165 height, hflip, vflip);
167 break;
168 case V4L2_PIX_FMT_YUYV:
169 default:
170 break;
173 buffer->bytesused = dev->vsettings.format.sizeimage;
174 done:
175 return ret;
179 * @brief This function permits to get the raw data. (without treatments)
181 * @param bayer Buffer with the bayer data
182 * @param size Length of bayer buffer
184 * @retval raw Buffer with the data from video sensor
186 void microdia_getraw(uint8_t *bayer, uint8_t *raw,
187 int size) {
188 memcpy(raw, bayer, size);
191 /* Table to translate Y offset to UV offset */
192 static int UVTranslate[32] = {
193 0, 1, 2, 3,
194 8, 9, 10, 11,
195 16, 17, 18, 19,
196 24, 25, 26, 27,
197 4, 5, 6, 7,
198 12, 13, 14, 15,
199 20, 21, 22, 23,
200 28, 29, 30, 31
203 static int Y_coords_624x[128][2] = {
204 { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 0}, { 5, 0}, { 6, 0}, { 7, 0},
205 { 0, 1}, { 1, 1}, { 2, 1}, { 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7, 1},
206 { 0, 2}, { 1, 2}, { 2, 2}, { 3, 2}, { 4, 2}, { 5, 2}, { 6, 2}, { 7, 2},
207 { 0, 3}, { 1, 3}, { 2, 3}, { 3, 3}, { 4, 3}, { 5, 3}, { 6, 3}, { 7, 3},
209 { 0, 4}, { 1, 4}, { 2, 4}, { 3, 4}, { 4, 4}, { 5, 4}, { 6, 4}, { 7, 4},
210 { 0, 5}, { 1, 5}, { 2, 5}, { 3, 5}, { 4, 5}, { 5, 5}, { 6, 5}, { 7, 5},
211 { 0, 6}, { 1, 6}, { 2, 6}, { 3, 6}, { 4, 6}, { 5, 6}, { 6, 6}, { 7, 6},
212 { 0, 7}, { 1, 7}, { 2, 7}, { 3, 7}, { 4, 7}, { 5, 7}, { 6, 7}, { 7, 7},
214 { 8, 0}, { 9, 0}, {10, 0}, {11, 0}, {12, 0}, {13, 0}, {14, 0}, {15, 0},
215 { 8, 1}, { 9, 1}, {10, 1}, {11, 1}, {12, 1}, {13, 1}, {14, 1}, {15, 1},
216 { 8, 2}, { 9, 2}, {10, 2}, {11, 2}, {12, 2}, {13, 2}, {14, 2}, {15, 2},
217 { 8, 3}, { 9, 3}, {10, 3}, {11, 3}, {12, 3}, {13, 3}, {14, 3}, {15, 3},
219 { 8, 4}, { 9, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15, 4},
220 { 8, 5}, { 9, 5}, {10, 5}, {11, 5}, {12, 5}, {13, 5}, {14, 5}, {15, 5},
221 { 8, 6}, { 9, 6}, {10, 6}, {11, 6}, {12, 6}, {13, 6}, {14, 6}, {15, 6},
222 { 8, 7}, { 9, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15, 7}
227 * @brief This function permits to convert an image from 624x raw format to bgr24
228 * @param raw Buffer with the raw data
229 * @param width Width of image
230 * @param height Height of image
231 * @param hflip Horizontal flip
232 * @param vflip Vertical flip
234 * @retval rgb Buffer with the rgb data
236 void microdia_raw2bgr24(uint8_t *raw, uint8_t *rgb,
237 int width, int height, const int hflip,
238 const int vflip)
240 int i = 0, x = 0, y = 0;
241 unsigned char *buf = raw;
242 unsigned char *buf3 = rgb;
244 while (i < (width * height + (width * height) / 2)) {
245 int tile = 0;
246 for (tile = 0; tile < 4; tile++) {
247 int subX = 0;
248 int subY = 0;
249 for (subY = 0; subY < 4; subY++) {
250 for (subX = 0; subX < 8; subX++) {
251 int subI = i + tile * 32 + 8 * subY + subX;
252 int subU = i + 128 + UVTranslate[tile * 8 + 4 * (subY >> 1) + (subX >> 1)];
253 int subV = subU + 32;
255 int relX = x + (((tile == 0) || (tile == 1)) ? 0 : 8) + subX; /* tile 0, 1 to into left column*/
256 int relY = y + (((tile == 0) || (tile == 2)) ? 0 : 4) + subY; /* tile 0, 2 go into top row */
258 if (hflip)
259 relX = width - relX;
260 if (vflip)
261 relY = height - relY;
263 if ((relX < width) && (relY < height)) {
264 unsigned char *ptr;
265 int c, d, e;
266 c = buf[subI] - 16;
267 d = buf[subU] - 128;
268 e = buf[subV] - 128;
270 ptr = buf3 + relY * width * 3 + relX * 3;
271 *ptr = CLIP((298 * c + 516 * d + 128) >> 8, 0, 255);
272 ptr++;
273 *ptr = CLIP((298 * c - 100 * d - 208 * e + 128) >> 8, 0, 255);
274 ptr++;
275 *ptr = CLIP((298 * c + 409 * e + 128) >> 8, 0, 255);
281 i += 192;
282 x += 16;
283 if (x >= width) {
284 x = 0;
285 y += 8;
292 * @brief This function permits to convert an image from 624x raw format to i420
293 * @param raw Buffer with the raw data
294 * @param width Width of image
295 * @param height Height of image
296 * @param hflip Horizontal flip
297 * @param vflip Vertical flip
299 * @retval i420 Buffer with the i420 data
301 void microdia_raw2i420(uint8_t *raw, uint8_t *i420,
302 int width, int height, const int hflip,
303 const int vflip)
305 int i = 0, x = 0, y = 0, j, relX, relY, x_div2, y_div2;
306 unsigned char *buf = raw, *ptr;
307 unsigned char *buf3 = i420;
308 int view_size = width * height;
309 int view_size_div4 = view_size >> 2;
310 int image_x_div2 = width >> 1;
311 int image_y_div2 = height >> 1;
312 int view_x_div2 = width >> 1;
314 while (i < (width * height + (width * height) / 2)) {
315 for (j = 0; j < 128; j++) {
316 relX = x + Y_coords_624x[j][0];
317 relY = y + Y_coords_624x[j][1];
318 if (hflip)
319 relX = width - relX - 1;
320 if (vflip)
321 relY = height - relY - 1;
323 if ((relX < width) && (relY < height)) {
324 ptr = buf3 + relY * width + relX;
325 *ptr = buf[i + j];
329 x_div2 = x >> 1;
330 y_div2 = y >> 1;
331 for (j = 0; j < 32; j++) {
332 relX = (x_div2) + (j & 0x07);
333 relY = (y_div2) + (j >> 3);
334 if (hflip)
335 relX = image_x_div2 - relX - 1;
336 if (vflip)
337 relY = image_y_div2 - relY - 1;
339 if ((relX < width) && (relY < height)) {
340 ptr = buf3 + view_size +
341 relY * (view_x_div2) + relX;
342 *ptr = buf[i + 128 + j];
343 ptr += view_size_div4;
344 *ptr = buf[i + 160 + j];
349 i += 192;
350 x += 16;
351 if (x >= width) {
352 x = 0;
353 y += 8;
360 * @brief This function permits to convert an image from 6270 raw format to i420
361 * @param raw Buffer with the bayer data
362 * @param width Width of image
363 * @param height Height of image
364 * @param hflip Horizontal flip - not implemented
365 * @param vflip Vertical flip - not implemented
367 * @retval i420 Buffer with the i420 data
368 * Format of stream is uvyy,uvyy - repeated 320 times for 640x480
369 * y - repeated 640 times for 640x480
370 * First 1280 bytes is maybe dummy ***FIXME***
372 void raw6270_2i420(uint8_t *raw, uint8_t *i420, int width,
373 int height, const int hflip,
374 const int vflip)
376 int i, j, YIndex = 0, UVIndex = 0;
377 unsigned char *y, *u, *v;
378 uint8_t *buf;
379 /* For fast calculations */
380 int x_div_2, y_div_2;
381 /* Skip first 1280 bytes strange dummy bytes */
382 raw += width * 2;
384 x_div_2 = width / 2; /* for fast calculation if x=640 x_div_2=320 */
385 y_div_2 = height / 2; /* for fast calculation if y=480 y_div_4=240 */
386 buf = raw;
387 y = i420;
388 u = i420 + width * height;
389 v = i420 + width * height + (width >> 1) * (height >> 1);
391 YIndex = 0;
392 UVIndex = 0;
393 /* we skipped 1280 bytes, it's almost two lines */
394 for (i = 0; i < y_div_2 - 1; i++) {
395 for (j = 0; j < x_div_2; j++) {
396 u[UVIndex] = *buf;
397 buf++;
398 v[UVIndex] = *buf;
399 buf++;
400 y[YIndex] = *buf;
401 buf++;
402 YIndex += 1;
403 y[YIndex] = *buf;
404 buf++;
405 YIndex += 1;
406 UVIndex += 1;
408 YIndex -= width;
409 YIndex += width;
411 for (j = 0; j < width; j++) {
412 y[YIndex] = *buf;
413 buf++;
414 YIndex += 1;
416 YIndex -= width;
417 YIndex += width;
419 UVIndex -= x_div_2;
420 UVIndex += (width >> 1);
426 * @brief This function permits to convert an image from 6270 rawformat to BGR24
427 * @param raw Buffer with the bayer data
428 * @param width Width of image
429 * @param height Height of image
430 * @param hflip Horizontal flip - not implemented yet
431 * @param vflip Vertical flip - not implemented yet
433 * @retval rgb Buffer with the rgb data
434 * Format of stream is uvyy,uvyy - repeated 320 times for 640x480
435 * y - repeated 640 times for 640x480
436 * First 1280 bytes is maybe dumy ***FIXME***
438 void raw6270_2BGR24(uint8_t *raw, uint8_t *rgb, int width,
439 int height, const int hflip,
440 const int vflip)
442 int i, j, incX;
443 /* Maybe is not necesery to use long variables but I not sure in this moment */
444 long y11, y12, y21, y22, u, v, y, C, D, E;
445 long ScaleIncX, ScaleIncY;
446 long pointerIncX, pointerIncY;
447 uint8_t *bufUVYY;
448 uint8_t *bufY;
449 uint8_t *out_row1;
450 uint8_t *out_row2;
452 /* For fast calculations*/
453 int x_div_2, y_div_2;
454 /* Skip first 1280 bytes strange dummy bytes */
455 raw += width * 2;
457 x_div_2 = width / 2; /* for fast calculation if x=640 x_div_2=320 */
458 y_div_2 = height / 2; /* for fast calculation if y=480 y_div_4=240 */
459 incX = 3 * width; /* Incrementation koeficient for next row*/
460 bufUVYY = raw;
461 bufY = raw + 2 * width;
464 // Because I can't use float ratio is multiply by 1000
465 // then 1000 is equal of increment image (X or Y) with 1
467 ScaleIncX = (1000 * width) / width;
468 ScaleIncY = (1000 * height) / height;
470 out_row1 = rgb;
471 out_row2 = out_row1 + incX;
472 /* we skipped 1280 bytes, it's almost two lines*/
473 pointerIncY = 1000;
474 for (i = 0; i < y_div_2-1; i++) {
475 pointerIncX = 1000;
476 for (j = 0; j < x_div_2; j++) {
477 pointerIncX += ScaleIncX;
479 u = (unsigned char)(*bufUVYY);
480 bufUVYY++;
482 v = (unsigned char)(*bufUVYY);
483 bufUVYY++;
485 y11 = (unsigned char)(*bufUVYY);
486 bufUVYY++;
488 y12 = (unsigned char)(*bufUVYY);
489 bufUVYY++;
491 y21 = (unsigned char)(*bufY);
492 bufY++;
494 y22 = (unsigned char)(*bufY);
495 bufY++;
497 if ((pointerIncX > 999) && (pointerIncY > 499)) {
498 pointerIncX -= 1001;
499 y = y11;
500 C = y - 16;
501 D = u - 128;
502 E = v - 128;
504 *out_row1 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
505 out_row1++;
506 *out_row1 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
507 out_row1++;
508 *out_row1 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
509 out_row1++;
511 y = y12;
513 C = y - 16;
514 D = u - 128;
515 E = v - 128;
518 *out_row1 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
519 out_row1++;
520 *out_row1 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
521 out_row1++;
522 *out_row1 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
523 out_row1++;
526 // Second row of stream is displayed only
527 // if image is greath than half
529 if (ScaleIncY > 501) {
530 y = y21;
532 C = y - 16;
533 D = u - 128;
534 E = v - 128;
536 *out_row2 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
537 out_row2++;
538 *out_row2 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
539 out_row2++;
540 *out_row2 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
541 out_row2++;
543 y = y22;
545 C = y - 16;
546 D = u - 128;
547 E = v - 128;
549 *out_row2 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
550 out_row2++;
551 *out_row2 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
552 out_row2++;
553 *out_row2 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
554 out_row2++;
559 // this comparation can be optimized and moved in
560 // if((pointerIncX>999)&&(pointerIncY>499))
562 if (pointerIncY > 499)
563 pointerIncY -= 500;
565 // Use 2 rows only if
566 // vertical ratio > 0.5 (increment is ratio*1000)
568 if (ScaleIncY > 501) {
569 out_row1 = out_row1 + incX;
570 out_row2 = out_row2 + incX;
573 pointerIncY += ScaleIncY;
574 bufUVYY = bufUVYY + width;
575 bufY = bufY + 2 * width;
581 * @brief This function permits to convert an image from 6270 rawformat to RGB24
582 * @brief The same function as convert to BGR24 but only B and R is change order
583 * @param raw Buffer with the bayer data
584 * @param width Width of image
585 * @param height Height of image
586 * @param hflip Horizontal flip
587 * @param vflip Vertical flip
589 * @retval rgb Buffer with the rgb data
590 * Format of stream is uvyy,uvyy - repeated 320 times for 640x480
591 * y - repeated 640 times for 640x480
592 * First 1280 bytes is maybe dumy ***FIXME***
594 void raw6270_2RGB24(uint8_t *raw, uint8_t *rgb, int width,
595 int height, const int hflip,
596 const int vflip)
598 int i, j, incX;
599 /* Maybe is not necesery to use long variables but I not sure in this moment */
600 long y11, y12, y21, y22, u, v, y, C, D, E;
601 long ScaleIncX, ScaleIncY;
602 long pointerIncX, pointerIncY;
603 uint8_t *bufUVYY;
604 uint8_t *bufY;
605 uint8_t *out_row1;
606 uint8_t *out_row2;
608 /* For fast calculations */
609 int x_div_2, y_div_2;
610 /* Skip first 1280 bytes strange dummy bytes */
611 raw += 1280;
613 x_div_2 = width / 2; /* for fast calculation if x=640 x_div_2=320 */
614 y_div_2 = height / 2; /* for fast calculation if y=480 y_div_4=240 */
615 incX = 3 * width;
616 bufUVYY = raw;
617 bufY = raw + 2 * width;
620 // Because I can't use float ratio is multiply by 1000 then
621 // 1000 is equal of increment image (X or Y) with 1
623 ScaleIncX = (1000 * width) / width;
624 ScaleIncY = (1000 * height) / height;
626 out_row1 = rgb;
627 out_row2 = out_row1 + incX;
628 /* we skipped 1280 bytes, it's almost two lines */
629 pointerIncY = 1000;
630 for (i = 0; i < y_div_2-1; i++) {
631 pointerIncX = 1000;
632 for (j = 0; j < x_div_2; j++) {
633 pointerIncX += ScaleIncX;
635 u = (unsigned char)(*bufUVYY);
636 bufUVYY++;
638 v = (unsigned char)(*bufUVYY);
639 bufUVYY++;
641 y11 = (unsigned char)(*bufUVYY);
642 bufUVYY++;
644 y12 = (unsigned char)(*bufUVYY);
645 bufUVYY++;
647 y21 = (unsigned char)(*bufY);
648 bufY++;
650 y22 = (unsigned char)(*bufY);
651 bufY++;
653 if ((pointerIncX > 999) && (pointerIncY > 499)) {
654 pointerIncX -= 1001;
655 y = y11;
656 C = y - 16;
657 D = u - 128;
658 E = v - 128;
660 *out_row1 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
661 out_row1++;
662 *out_row1 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
663 out_row1++;
664 *out_row1 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
665 out_row1++;
667 y = y12;
669 C = y - 16;
670 D = u - 128;
671 E = v - 128;
673 *out_row1 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
674 out_row1++;
675 *out_row1 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
676 out_row1++;
677 *out_row1 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
678 out_row1++;
681 // Second row of stream is displayed only
682 // if image is greath than half
684 if (ScaleIncY > 501) {
685 y = y21;
687 C = y - 16;
688 D = u - 128;
689 E = v - 128;
691 *out_row2 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
692 out_row2++;
693 *out_row2 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
694 out_row2++;
695 *out_row2 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
696 out_row2++;
698 y = y22;
700 C = y - 16;
701 D = u - 128;
702 E = v - 128;
704 *out_row2 = CLIP((298 * C + 409 * E + 128) >> 8, 0, 255);
705 out_row2++;
706 *out_row2 = CLIP((298 * C - 100 * D - 208 * E + 128) >> 8, 0, 255);
707 out_row2++;
708 *out_row2 = CLIP((298 * C + 516 * D + 128) >> 8, 0, 255);
709 out_row2++;
714 // this comparation can be optimized and moved in
715 // if((pointerIncX>999)&&(pointerIncY>499))
717 if (pointerIncY > 499)
718 pointerIncY -= 500;
719 /* Use 2 rows only if vertical ratio > 0.5 (increment is ratio*1000) */
720 if (ScaleIncY > 501) {
721 out_row1 = out_row1 + incX;
722 out_row2 = out_row2 + incX;
725 pointerIncY += ScaleIncY;
726 bufUVYY = bufUVYY + width;
727 bufY = bufY + 2 * width;