217 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
225 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
218 |
226 |
219 yacc += y_increment; |
227 yacc += y_increment; |
220 } |
228 } |
221 } |
229 } |
|
230 #ifdef __SYMBIAN32__ |
|
231 EXPORT_C |
|
232 #endif |
|
233 |
|
234 void |
|
235 vs_scanline_resample_4tap_Y16 (uint8_t * dest, uint8_t * src, |
|
236 int n, int src_width, int *xacc, int increment) |
|
237 { |
|
238 int i; |
|
239 int j; |
|
240 int acc; |
|
241 int x; |
|
242 int y; |
|
243 uint16_t *d = (uint16_t *) dest, *s = (uint16_t *) src; |
|
244 |
|
245 acc = *xacc; |
|
246 for (i = 0; i < n; i++) { |
|
247 j = acc >> 16; |
|
248 x = (acc & 0xff00) >> 8; |
|
249 if (j - 1 >= 0 && j + 2 < src_width) { |
|
250 y = vs_4tap_taps[x][0] * s[MAX (j - 1, 0)]; |
|
251 y += vs_4tap_taps[x][1] * s[j]; |
|
252 y += vs_4tap_taps[x][2] * s[j + 1]; |
|
253 y += vs_4tap_taps[x][3] * s[j + 2]; |
|
254 } else { |
|
255 y = vs_4tap_taps[x][0] * s[CLAMP (j - 1, 0, src_width - 1)]; |
|
256 y += vs_4tap_taps[x][1] * s[CLAMP (j, 0, src_width - 1)]; |
|
257 y += vs_4tap_taps[x][2] * s[CLAMP (j + 1, 0, src_width - 1)]; |
|
258 y += vs_4tap_taps[x][3] * s[CLAMP (j + 2, 0, src_width - 1)]; |
|
259 } |
|
260 y += (1 << (SHIFT - 1)); |
|
261 d[i] = CLAMP (y >> SHIFT, 0, 65535); |
|
262 acc += increment; |
|
263 } |
|
264 *xacc = acc; |
|
265 } |
|
266 #ifdef __SYMBIAN32__ |
|
267 EXPORT_C |
|
268 #endif |
|
269 |
|
270 void |
|
271 vs_scanline_merge_4tap_Y16 (uint8_t * dest, uint8_t * src1, uint8_t * src2, |
|
272 uint8_t * src3, uint8_t * src4, int n, int acc) |
|
273 { |
|
274 int i; |
|
275 int y; |
|
276 int a, b, c, d; |
|
277 uint16_t *de = (uint16_t *) dest, *s1 = (uint16_t *) src1; |
|
278 uint16_t *s2 = (uint16_t *) src2, *s3 = (uint16_t *) src3; |
|
279 uint16_t *s4 = (uint16_t *) src4; |
|
280 |
|
281 acc = (acc >> 8) & 0xff; |
|
282 a = vs_4tap_taps[acc][0]; |
|
283 b = vs_4tap_taps[acc][1]; |
|
284 c = vs_4tap_taps[acc][2]; |
|
285 d = vs_4tap_taps[acc][3]; |
|
286 for (i = 0; i < n; i++) { |
|
287 y = a * s1[i]; |
|
288 y += b * s2[i]; |
|
289 y += c * s3[i]; |
|
290 y += d * s4[i]; |
|
291 y += (1 << (SHIFT - 1)); |
|
292 de[i] = CLAMP (y >> SHIFT, 0, 65535); |
|
293 } |
|
294 } |
|
295 #ifdef __SYMBIAN32__ |
|
296 EXPORT_C |
|
297 #endif |
|
298 |
|
299 |
|
300 void |
|
301 vs_image_scale_4tap_Y16 (const VSImage * dest, const VSImage * src, |
|
302 uint8_t * tmpbuf) |
|
303 { |
|
304 int yacc; |
|
305 int y_increment; |
|
306 int x_increment; |
|
307 int i; |
|
308 int j; |
|
309 int xacc; |
|
310 int k; |
|
311 |
|
312 if (dest->height == 1) |
|
313 y_increment = 0; |
|
314 else |
|
315 y_increment = ((src->height - 1) << 16) / (dest->height - 1); |
|
316 |
|
317 if (dest->width == 1) |
|
318 x_increment = 0; |
|
319 else |
|
320 x_increment = ((src->width - 1) << 16) / (dest->width - 1); |
|
321 |
|
322 k = 0; |
|
323 for (i = 0; i < 4; i++) { |
|
324 xacc = 0; |
|
325 vs_scanline_resample_4tap_Y16 (tmpbuf + i * dest->stride, |
|
326 src->pixels + i * src->stride, dest->width, src->width, |
|
327 &xacc, x_increment); |
|
328 } |
|
329 |
|
330 yacc = 0; |
|
331 for (i = 0; i < dest->height; i++) { |
|
332 uint8_t *t0, *t1, *t2, *t3; |
|
333 |
|
334 j = yacc >> 16; |
|
335 |
|
336 while (j > k) { |
|
337 k++; |
|
338 if (k + 3 < src->height) { |
|
339 xacc = 0; |
|
340 vs_scanline_resample_4tap_Y16 (tmpbuf + ((k + 3) & 3) * dest->stride, |
|
341 src->pixels + (k + 3) * src->stride, |
|
342 dest->width, src->width, &xacc, x_increment); |
|
343 } |
|
344 } |
|
345 |
|
346 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride; |
|
347 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride; |
|
348 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride; |
|
349 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride; |
|
350 vs_scanline_merge_4tap_Y16 (dest->pixels + i * dest->stride, |
|
351 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
|
352 |
|
353 yacc += y_increment; |
|
354 } |
|
355 } |
|
356 #ifdef __SYMBIAN32__ |
|
357 EXPORT_C |
|
358 #endif |
|
359 |
|
360 |
|
361 void |
|
362 vs_scanline_resample_4tap_RGBA (uint8_t * dest, uint8_t * src, |
|
363 int n, int src_width, int *xacc, int increment) |
|
364 { |
|
365 int i; |
|
366 int j; |
|
367 int acc; |
|
368 int x; |
|
369 int y; |
|
370 int off; |
|
371 |
|
372 acc = *xacc; |
|
373 for (i = 0; i < n; i++) { |
|
374 j = acc >> 16; |
|
375 x = (acc & 0xffff) >> 8; |
|
376 |
|
377 for (off = 0; off < 4; off++) { |
|
378 if (j - 1 >= 0 && j + 2 < src_width) { |
|
379 y = vs_4tap_taps[x][0] * src[MAX ((j - 1) * 4 + off, 0)]; |
|
380 y += vs_4tap_taps[x][1] * src[j * 4 + off]; |
|
381 y += vs_4tap_taps[x][2] * src[(j + 1) * 4 + off]; |
|
382 y += vs_4tap_taps[x][3] * src[(j + 2) * 4 + off]; |
|
383 } else { |
|
384 y = vs_4tap_taps[x][0] * src[CLAMP ((j - 1) * 4 + off, 0, |
|
385 4 * (src_width - 1) + off)]; |
|
386 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + off, 0, |
|
387 4 * (src_width - 1) + off)]; |
|
388 y += vs_4tap_taps[x][2] * src[CLAMP ((j + 1) * 4 + off, 0, |
|
389 4 * (src_width - 1) + off)]; |
|
390 y += vs_4tap_taps[x][3] * src[CLAMP ((j + 2) * 4 + off, 0, |
|
391 4 * (src_width - 1) + off)]; |
|
392 } |
|
393 y += (1 << (SHIFT - 1)); |
|
394 dest[i * 4 + off] = CLAMP (y >> SHIFT, 0, 255); |
|
395 } |
|
396 acc += increment; |
|
397 } |
|
398 *xacc = acc; |
|
399 } |
|
400 #ifdef __SYMBIAN32__ |
|
401 EXPORT_C |
|
402 #endif |
|
403 |
|
404 |
|
405 void |
|
406 vs_scanline_merge_4tap_RGBA (uint8_t * dest, uint8_t * src1, uint8_t * src2, |
|
407 uint8_t * src3, uint8_t * src4, int n, int acc) |
|
408 { |
|
409 int i; |
|
410 int y; |
|
411 int off; |
|
412 int a, b, c, d; |
|
413 |
|
414 acc = (acc >> 8) & 0xff; |
|
415 a = vs_4tap_taps[acc][0]; |
|
416 b = vs_4tap_taps[acc][1]; |
|
417 c = vs_4tap_taps[acc][2]; |
|
418 d = vs_4tap_taps[acc][3]; |
|
419 for (i = 0; i < n; i++) { |
|
420 for (off = 0; off < 4; off++) { |
|
421 y = a * src1[i * 4 + off]; |
|
422 y += b * src2[i * 4 + off]; |
|
423 y += c * src3[i * 4 + off]; |
|
424 y += d * src4[i * 4 + off]; |
|
425 y += (1 << (SHIFT - 1)); |
|
426 dest[i * 4 + off] = CLAMP (y >> SHIFT, 0, 255); |
|
427 } |
|
428 } |
|
429 } |
|
430 #ifdef __SYMBIAN32__ |
|
431 EXPORT_C |
|
432 #endif |
|
433 |
|
434 |
|
435 void |
|
436 vs_image_scale_4tap_RGBA (const VSImage * dest, const VSImage * src, |
|
437 uint8_t * tmpbuf) |
|
438 { |
|
439 int yacc; |
|
440 int y_increment; |
|
441 int x_increment; |
|
442 int i; |
|
443 int j; |
|
444 int xacc; |
|
445 int k; |
|
446 |
|
447 if (dest->height == 1) |
|
448 y_increment = 0; |
|
449 else |
|
450 y_increment = ((src->height - 1) << 16) / (dest->height - 1); |
|
451 |
|
452 if (dest->width == 1) |
|
453 x_increment = 0; |
|
454 else |
|
455 x_increment = ((src->width - 1) << 16) / (dest->width - 1); |
|
456 |
|
457 k = 0; |
|
458 for (i = 0; i < 4; i++) { |
|
459 xacc = 0; |
|
460 vs_scanline_resample_4tap_RGBA (tmpbuf + i * dest->stride, |
|
461 src->pixels + i * src->stride, dest->width, src->width, |
|
462 &xacc, x_increment); |
|
463 } |
|
464 |
|
465 yacc = 0; |
|
466 for (i = 0; i < dest->height; i++) { |
|
467 uint8_t *t0, *t1, *t2, *t3; |
|
468 |
|
469 j = yacc >> 16; |
|
470 |
|
471 while (j > k) { |
|
472 k++; |
|
473 if (k + 3 < src->height) { |
|
474 xacc = 0; |
|
475 vs_scanline_resample_4tap_RGBA (tmpbuf + ((k + 3) & 3) * dest->stride, |
|
476 src->pixels + (k + 3) * src->stride, |
|
477 dest->width, src->width, &xacc, x_increment); |
|
478 } |
|
479 } |
|
480 |
|
481 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride; |
|
482 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride; |
|
483 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride; |
|
484 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride; |
|
485 vs_scanline_merge_4tap_RGBA (dest->pixels + i * dest->stride, |
|
486 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
|
487 |
|
488 yacc += y_increment; |
|
489 } |
|
490 } |
|
491 #ifdef __SYMBIAN32__ |
|
492 EXPORT_C |
|
493 #endif |
|
494 |
|
495 |
|
496 void |
|
497 vs_scanline_resample_4tap_RGB (uint8_t * dest, uint8_t * src, |
|
498 int n, int src_width, int *xacc, int increment) |
|
499 { |
|
500 int i; |
|
501 int j; |
|
502 int acc; |
|
503 int x; |
|
504 int y; |
|
505 int off; |
|
506 |
|
507 acc = *xacc; |
|
508 for (i = 0; i < n; i++) { |
|
509 j = acc >> 16; |
|
510 x = (acc & 0xffff) >> 8; |
|
511 |
|
512 for (off = 0; off < 3; off++) { |
|
513 if (j - 1 >= 0 && j + 2 < src_width) { |
|
514 y = vs_4tap_taps[x][0] * src[MAX ((j - 1) * 3 + off, 0)]; |
|
515 y += vs_4tap_taps[x][1] * src[j * 3 + off]; |
|
516 y += vs_4tap_taps[x][2] * src[(j + 1) * 3 + off]; |
|
517 y += vs_4tap_taps[x][3] * src[(j + 2) * 3 + off]; |
|
518 } else { |
|
519 y = vs_4tap_taps[x][0] * src[CLAMP ((j - 1) * 3 + off, 0, |
|
520 3 * (src_width - 1) + off)]; |
|
521 y += vs_4tap_taps[x][1] * src[CLAMP (j * 3 + off, 0, |
|
522 3 * (src_width - 1) + off)]; |
|
523 y += vs_4tap_taps[x][2] * src[CLAMP ((j + 1) * 3 + off, 0, |
|
524 3 * (src_width - 1) + off)]; |
|
525 y += vs_4tap_taps[x][3] * src[CLAMP ((j + 2) * 3 + off, 0, |
|
526 3 * (src_width - 1) + off)]; |
|
527 } |
|
528 y += (1 << (SHIFT - 1)); |
|
529 dest[i * 3 + off] = CLAMP (y >> SHIFT, 0, 255); |
|
530 } |
|
531 acc += increment; |
|
532 } |
|
533 *xacc = acc; |
|
534 } |
|
535 #ifdef __SYMBIAN32__ |
|
536 EXPORT_C |
|
537 #endif |
|
538 |
|
539 |
|
540 void |
|
541 vs_scanline_merge_4tap_RGB (uint8_t * dest, uint8_t * src1, uint8_t * src2, |
|
542 uint8_t * src3, uint8_t * src4, int n, int acc) |
|
543 { |
|
544 int i; |
|
545 int y; |
|
546 int off; |
|
547 int a, b, c, d; |
|
548 |
|
549 acc = (acc >> 8) & 0xff; |
|
550 a = vs_4tap_taps[acc][0]; |
|
551 b = vs_4tap_taps[acc][1]; |
|
552 c = vs_4tap_taps[acc][2]; |
|
553 d = vs_4tap_taps[acc][3]; |
|
554 for (i = 0; i < n; i++) { |
|
555 for (off = 0; off < 3; off++) { |
|
556 y = a * src1[i * 3 + off]; |
|
557 y += b * src2[i * 3 + off]; |
|
558 y += c * src3[i * 3 + off]; |
|
559 y += d * src4[i * 3 + off]; |
|
560 y += (1 << (SHIFT - 1)); |
|
561 dest[i * 3 + off] = CLAMP (y >> SHIFT, 0, 255); |
|
562 } |
|
563 } |
|
564 } |
|
565 #ifdef __SYMBIAN32__ |
|
566 EXPORT_C |
|
567 #endif |
|
568 |
|
569 |
|
570 void |
|
571 vs_image_scale_4tap_RGB (const VSImage * dest, const VSImage * src, |
|
572 uint8_t * tmpbuf) |
|
573 { |
|
574 int yacc; |
|
575 int y_increment; |
|
576 int x_increment; |
|
577 int i; |
|
578 int j; |
|
579 int xacc; |
|
580 int k; |
|
581 |
|
582 if (dest->height == 1) |
|
583 y_increment = 0; |
|
584 else |
|
585 y_increment = ((src->height - 1) << 16) / (dest->height - 1); |
|
586 |
|
587 if (dest->width == 1) |
|
588 x_increment = 0; |
|
589 else |
|
590 x_increment = ((src->width - 1) << 16) / (dest->width - 1); |
|
591 |
|
592 k = 0; |
|
593 for (i = 0; i < 4; i++) { |
|
594 xacc = 0; |
|
595 vs_scanline_resample_4tap_RGB (tmpbuf + i * dest->stride, |
|
596 src->pixels + i * src->stride, dest->width, src->width, |
|
597 &xacc, x_increment); |
|
598 } |
|
599 |
|
600 yacc = 0; |
|
601 for (i = 0; i < dest->height; i++) { |
|
602 uint8_t *t0, *t1, *t2, *t3; |
|
603 |
|
604 j = yacc >> 16; |
|
605 |
|
606 while (j > k) { |
|
607 k++; |
|
608 if (k + 3 < src->height) { |
|
609 xacc = 0; |
|
610 vs_scanline_resample_4tap_RGB (tmpbuf + ((k + 3) & 3) * dest->stride, |
|
611 src->pixels + (k + 3) * src->stride, |
|
612 dest->width, src->width, &xacc, x_increment); |
|
613 } |
|
614 } |
|
615 |
|
616 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride; |
|
617 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride; |
|
618 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride; |
|
619 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride; |
|
620 vs_scanline_merge_4tap_RGB (dest->pixels + i * dest->stride, |
|
621 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
|
622 |
|
623 yacc += y_increment; |
|
624 } |
|
625 } |
|
626 #ifdef __SYMBIAN32__ |
|
627 EXPORT_C |
|
628 #endif |
|
629 |
|
630 |
|
631 void |
|
632 vs_scanline_resample_4tap_YUYV (uint8_t * dest, uint8_t * src, |
|
633 int n, int src_width, int *xacc, int increment) |
|
634 { |
|
635 int i; |
|
636 int j; |
|
637 int acc; |
|
638 int x; |
|
639 int y; |
|
640 int quads = (n + 1) / 2; |
|
641 int last_y = 2 * (src_width - 1); |
|
642 int last_u = |
|
643 MAX ((2 * (src_width - 1) % 4 == |
|
644 0) ? 2 * (src_width - 1) + 1 : 2 * (src_width - 1) - 1, 1); |
|
645 int last_v = |
|
646 MAX ((2 * (src_width - 1) % 4 == |
|
647 2) ? 2 * (src_width - 1) + 1 : 2 * (src_width - 1) - 1, 1); |
|
648 |
|
649 acc = *xacc; |
|
650 for (i = 0; i < quads; i++) { |
|
651 j = acc >> 16; |
|
652 x = (acc & 0xffff) >> 8; |
|
653 |
|
654 if (j - 1 >= 0 && j + 2 < src_width) { |
|
655 y = vs_4tap_taps[x][0] * src[MAX (j * 2 + 0 - 2, 0)]; |
|
656 y += vs_4tap_taps[x][1] * src[j * 2 + 0]; |
|
657 y += vs_4tap_taps[x][2] * src[j * 2 + 0 + 2]; |
|
658 y += vs_4tap_taps[x][3] * src[j * 2 + 0 + 4]; |
|
659 } else { |
|
660 y = vs_4tap_taps[x][0] * src[CLAMP (j * 2 + 0 - 2, 0, last_y)]; |
|
661 y += vs_4tap_taps[x][1] * src[CLAMP (j * 2 + 0, 0, last_y)]; |
|
662 y += vs_4tap_taps[x][2] * src[CLAMP (j * 2 + 0 + 2, 0, last_y)]; |
|
663 y += vs_4tap_taps[x][3] * src[CLAMP (j * 2 + 0 + 4, 0, last_y)]; |
|
664 } |
|
665 y += (1 << (SHIFT - 1)); |
|
666 dest[i * 4 + 0] = CLAMP (y >> SHIFT, 0, 255); |
|
667 |
|
668 j = acc >> 17; |
|
669 x = (acc & 0x1ffff) >> 9; |
|
670 |
|
671 if (2 * (j - 1) >= 0 && 2 * (j + 4) < src_width) { |
|
672 y = vs_4tap_taps[x][0] * src[MAX (j * 4 + 1 - 4, 1)]; |
|
673 y += vs_4tap_taps[x][1] * src[j * 4 + 1]; |
|
674 y += vs_4tap_taps[x][2] * src[j * 4 + 1 + 4]; |
|
675 y += vs_4tap_taps[x][3] * src[j * 4 + 1 + 8]; |
|
676 } else { |
|
677 y = vs_4tap_taps[x][0] * src[CLAMP (j * 4 + 1 - 4, 1, last_u)]; |
|
678 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + 1, 1, last_u)]; |
|
679 y += vs_4tap_taps[x][2] * src[CLAMP (j * 4 + 1 + 4, 1, last_u)]; |
|
680 y += vs_4tap_taps[x][3] * src[CLAMP (j * 4 + 1 + 8, 1, last_u)]; |
|
681 } |
|
682 y += (1 << (SHIFT - 1)); |
|
683 dest[i * 4 + 1] = CLAMP (y >> SHIFT, 0, 255); |
|
684 |
|
685 if (2 * i + 1 < n) { |
|
686 if (2 * (j - 1) >= 0 && 2 * (j + 4) < src_width) { |
|
687 y = vs_4tap_taps[x][0] * src[MAX (j * 4 + 3 - 4, 3)]; |
|
688 y += vs_4tap_taps[x][1] * src[j * 4 + 3]; |
|
689 y += vs_4tap_taps[x][2] * src[j * 4 + 3 + 4]; |
|
690 y += vs_4tap_taps[x][3] * src[j * 4 + 3 + 8]; |
|
691 } else { |
|
692 y = vs_4tap_taps[x][0] * src[CLAMP (j * 4 + 3 - 4, 3, last_v)]; |
|
693 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + 3, 3, last_v)]; |
|
694 y += vs_4tap_taps[x][2] * src[CLAMP (j * 4 + 3 + 4, 3, last_v)]; |
|
695 y += vs_4tap_taps[x][3] * src[CLAMP (j * 4 + 3 + 8, 3, last_v)]; |
|
696 } |
|
697 y += (1 << (SHIFT - 1)); |
|
698 dest[i * 4 + 3] = CLAMP (y >> SHIFT, 0, 255); |
|
699 } |
|
700 |
|
701 acc += increment; |
|
702 j = acc >> 16; |
|
703 x = (acc & 0xffff) >> 8; |
|
704 |
|
705 if (2 * i + 1 < n) { |
|
706 if (j - 1 >= 0 && j + 2 < src_width) { |
|
707 y = vs_4tap_taps[x][0] * src[MAX (j * 2 + 0 - 2, 0)]; |
|
708 y += vs_4tap_taps[x][1] * src[j * 2 + 0]; |
|
709 y += vs_4tap_taps[x][2] * src[j * 2 + 0 + 2]; |
|
710 y += vs_4tap_taps[x][3] * src[j * 2 + 0 + 4]; |
|
711 } else { |
|
712 y = vs_4tap_taps[x][0] * src[CLAMP (j * 2 + 0 - 2, 0, last_y)]; |
|
713 y += vs_4tap_taps[x][1] * src[CLAMP (j * 2 + 0, 0, last_y)]; |
|
714 y += vs_4tap_taps[x][2] * src[CLAMP (j * 2 + 0 + 2, 0, last_y)]; |
|
715 y += vs_4tap_taps[x][3] * src[CLAMP (j * 2 + 0 + 4, 0, last_y)]; |
|
716 } |
|
717 y += (1 << (SHIFT - 1)); |
|
718 dest[i * 4 + 2] = CLAMP (y >> SHIFT, 0, 255); |
|
719 acc += increment; |
|
720 } |
|
721 } |
|
722 *xacc = acc; |
|
723 } |
|
724 #ifdef __SYMBIAN32__ |
|
725 EXPORT_C |
|
726 #endif |
|
727 |
|
728 |
|
729 void |
|
730 vs_scanline_merge_4tap_YUYV (uint8_t * dest, uint8_t * src1, uint8_t * src2, |
|
731 uint8_t * src3, uint8_t * src4, int n, int acc) |
|
732 { |
|
733 int i; |
|
734 int y; |
|
735 int a, b, c, d; |
|
736 int quads = (n + 1) / 2; |
|
737 |
|
738 acc = (acc >> 8) & 0xff; |
|
739 a = vs_4tap_taps[acc][0]; |
|
740 b = vs_4tap_taps[acc][1]; |
|
741 c = vs_4tap_taps[acc][2]; |
|
742 d = vs_4tap_taps[acc][3]; |
|
743 for (i = 0; i < quads; i++) { |
|
744 y = a * src1[i * 4 + 0]; |
|
745 y += b * src2[i * 4 + 0]; |
|
746 y += c * src3[i * 4 + 0]; |
|
747 y += d * src4[i * 4 + 0]; |
|
748 y += (1 << (SHIFT - 1)); |
|
749 dest[i * 4 + 0] = CLAMP (y >> SHIFT, 0, 255); |
|
750 |
|
751 y = a * src1[i * 4 + 1]; |
|
752 y += b * src2[i * 4 + 1]; |
|
753 y += c * src3[i * 4 + 1]; |
|
754 y += d * src4[i * 4 + 1]; |
|
755 y += (1 << (SHIFT - 1)); |
|
756 dest[i * 4 + 1] = CLAMP (y >> SHIFT, 0, 255); |
|
757 |
|
758 if (2 * i + 1 < n) { |
|
759 y = a * src1[i * 4 + 2]; |
|
760 y += b * src2[i * 4 + 2]; |
|
761 y += c * src3[i * 4 + 2]; |
|
762 y += d * src4[i * 4 + 2]; |
|
763 y += (1 << (SHIFT - 1)); |
|
764 dest[i * 4 + 2] = CLAMP (y >> SHIFT, 0, 255); |
|
765 |
|
766 y = a * src1[i * 4 + 3]; |
|
767 y += b * src2[i * 4 + 3]; |
|
768 y += c * src3[i * 4 + 3]; |
|
769 y += d * src4[i * 4 + 3]; |
|
770 y += (1 << (SHIFT - 1)); |
|
771 dest[i * 4 + 3] = CLAMP (y >> SHIFT, 0, 255); |
|
772 } |
|
773 } |
|
774 } |
|
775 #ifdef __SYMBIAN32__ |
|
776 EXPORT_C |
|
777 #endif |
|
778 |
|
779 |
|
780 void |
|
781 vs_image_scale_4tap_YUYV (const VSImage * dest, const VSImage * src, |
|
782 uint8_t * tmpbuf) |
|
783 { |
|
784 int yacc; |
|
785 int y_increment; |
|
786 int x_increment; |
|
787 int i; |
|
788 int j; |
|
789 int xacc; |
|
790 int k; |
|
791 |
|
792 if (dest->height == 1) |
|
793 y_increment = 0; |
|
794 else |
|
795 y_increment = ((src->height - 1) << 16) / (dest->height - 1); |
|
796 |
|
797 if (dest->width == 1) |
|
798 x_increment = 0; |
|
799 else |
|
800 x_increment = ((src->width - 1) << 16) / (dest->width - 1); |
|
801 |
|
802 k = 0; |
|
803 for (i = 0; i < 4; i++) { |
|
804 xacc = 0; |
|
805 vs_scanline_resample_4tap_YUYV (tmpbuf + i * dest->stride, |
|
806 src->pixels + i * src->stride, dest->width, src->width, |
|
807 &xacc, x_increment); |
|
808 } |
|
809 |
|
810 yacc = 0; |
|
811 for (i = 0; i < dest->height; i++) { |
|
812 uint8_t *t0, *t1, *t2, *t3; |
|
813 |
|
814 j = yacc >> 16; |
|
815 |
|
816 while (j > k) { |
|
817 k++; |
|
818 if (k + 3 < src->height) { |
|
819 xacc = 0; |
|
820 vs_scanline_resample_4tap_YUYV (tmpbuf + ((k + 3) & 3) * dest->stride, |
|
821 src->pixels + (k + 3) * src->stride, |
|
822 dest->width, src->width, &xacc, x_increment); |
|
823 } |
|
824 } |
|
825 |
|
826 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride; |
|
827 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride; |
|
828 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride; |
|
829 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride; |
|
830 vs_scanline_merge_4tap_YUYV (dest->pixels + i * dest->stride, |
|
831 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
|
832 |
|
833 yacc += y_increment; |
|
834 } |
|
835 } |
|
836 #ifdef __SYMBIAN32__ |
|
837 EXPORT_C |
|
838 #endif |
|
839 |
|
840 |
|
841 void |
|
842 vs_scanline_resample_4tap_UYVY (uint8_t * dest, uint8_t * src, |
|
843 int n, int src_width, int *xacc, int increment) |
|
844 { |
|
845 int i; |
|
846 int j; |
|
847 int acc; |
|
848 int x; |
|
849 int y; |
|
850 int quads = (n + 1) / 2; |
|
851 int last_y = 2 * (src_width - 1) + 1; |
|
852 int last_u = |
|
853 MAX ((2 * (src_width - 1) % 4 == |
|
854 0) ? 2 * (src_width - 1) : 2 * (src_width - 1) - 2, 0); |
|
855 int last_v = |
|
856 MAX ((2 * (src_width - 1) % 4 == |
|
857 2) ? 2 * (src_width - 1) : 2 * (src_width - 1) - 2, 0); |
|
858 |
|
859 acc = *xacc; |
|
860 for (i = 0; i < quads; i++) { |
|
861 j = acc >> 16; |
|
862 x = (acc & 0xffff) >> 8; |
|
863 |
|
864 if (j - 1 >= 0 && j + 2 < src_width) { |
|
865 y = vs_4tap_taps[x][0] * src[MAX (j * 2 + 1 - 2, 1)]; |
|
866 y += vs_4tap_taps[x][1] * src[j * 2 + 1]; |
|
867 y += vs_4tap_taps[x][2] * src[j * 2 + 1 + 2]; |
|
868 y += vs_4tap_taps[x][3] * src[j * 2 + 1 + 4]; |
|
869 } else { |
|
870 y = vs_4tap_taps[x][0] * src[CLAMP (j * 2 + 1 - 2, 1, last_y)]; |
|
871 y += vs_4tap_taps[x][1] * src[CLAMP (j * 2 + 1, 1, last_y)]; |
|
872 y += vs_4tap_taps[x][2] * src[CLAMP (j * 2 + 1 + 2, 1, last_y)]; |
|
873 y += vs_4tap_taps[x][3] * src[CLAMP (j * 2 + 1 + 4, 1, last_y)]; |
|
874 } |
|
875 y += (1 << (SHIFT - 1)); |
|
876 dest[i * 4 + 1] = CLAMP (y >> SHIFT, 0, 255); |
|
877 |
|
878 j = acc >> 17; |
|
879 x = (acc & 0x1ffff) >> 9; |
|
880 |
|
881 if (2 * (j - 2) >= 0 && 2 * (j + 4) < src_width) { |
|
882 y = vs_4tap_taps[x][0] * src[MAX (j * 4 + 0 - 4, 0)]; |
|
883 y += vs_4tap_taps[x][1] * src[j * 4 + 0]; |
|
884 y += vs_4tap_taps[x][2] * src[j * 4 + 0 + 4]; |
|
885 y += vs_4tap_taps[x][3] * src[j * 4 + 0 + 8]; |
|
886 } else { |
|
887 y = vs_4tap_taps[x][0] * src[CLAMP (j * 4 + 0 - 4, 0, last_u)]; |
|
888 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + 0, 0, last_u)]; |
|
889 y += vs_4tap_taps[x][2] * src[CLAMP (j * 4 + 0 + 4, 0, last_u)]; |
|
890 y += vs_4tap_taps[x][3] * src[CLAMP (j * 4 + 0 + 8, 0, last_u)]; |
|
891 } |
|
892 y += (1 << (SHIFT - 1)); |
|
893 dest[i * 4 + 0] = CLAMP (y >> SHIFT, 0, 255); |
|
894 |
|
895 if (2 * i + 1 < n) { |
|
896 if (2 * (j - 1) >= 0 && 2 * (j + 4) < src_width) { |
|
897 y = vs_4tap_taps[x][0] * src[MAX (j * 4 + 2 - 4, 2)]; |
|
898 y += vs_4tap_taps[x][1] * src[j * 4 + 2]; |
|
899 y += vs_4tap_taps[x][2] * src[j * 4 + 2 + 4]; |
|
900 y += vs_4tap_taps[x][3] * src[j * 4 + 2 + 8]; |
|
901 } else { |
|
902 y = vs_4tap_taps[x][0] * src[CLAMP (j * 4 + 2 - 4, 2, last_v)]; |
|
903 y += vs_4tap_taps[x][1] * src[CLAMP (j * 4 + 2, 2, last_v)]; |
|
904 y += vs_4tap_taps[x][2] * src[CLAMP (j * 4 + 2 + 4, 2, last_v)]; |
|
905 y += vs_4tap_taps[x][3] * src[CLAMP (j * 4 + 2 + 8, 2, last_v)]; |
|
906 } |
|
907 y += (1 << (SHIFT - 1)); |
|
908 dest[i * 4 + 2] = CLAMP (y >> SHIFT, 0, 255); |
|
909 } |
|
910 |
|
911 acc += increment; |
|
912 j = acc >> 16; |
|
913 x = (acc & 0xffff) >> 8; |
|
914 |
|
915 if (2 * i + 1 < n) { |
|
916 if (j - 1 >= 0 && j + 2 < src_width) { |
|
917 y = vs_4tap_taps[x][0] * src[MAX (j * 2 + 1 - 2, 0)]; |
|
918 y += vs_4tap_taps[x][1] * src[j * 2 + 1]; |
|
919 y += vs_4tap_taps[x][2] * src[j * 2 + 1 + 2]; |
|
920 y += vs_4tap_taps[x][3] * src[j * 2 + 1 + 4]; |
|
921 } else { |
|
922 y = vs_4tap_taps[x][0] * src[CLAMP (j * 2 + 1 - 2, 1, last_y)]; |
|
923 y += vs_4tap_taps[x][1] * src[CLAMP (j * 2 + 1, 1, last_y)]; |
|
924 y += vs_4tap_taps[x][2] * src[CLAMP (j * 2 + 1 + 2, 1, last_y)]; |
|
925 y += vs_4tap_taps[x][3] * src[CLAMP (j * 2 + 1 + 4, 1, last_y)]; |
|
926 } |
|
927 y += (1 << (SHIFT - 1)); |
|
928 dest[i * 4 + 3] = CLAMP (y >> SHIFT, 0, 255); |
|
929 acc += increment; |
|
930 } |
|
931 } |
|
932 *xacc = acc; |
|
933 } |
|
934 #ifdef __SYMBIAN32__ |
|
935 EXPORT_C |
|
936 #endif |
|
937 |
|
938 |
|
939 void |
|
940 vs_scanline_merge_4tap_UYVY (uint8_t * dest, uint8_t * src1, uint8_t * src2, |
|
941 uint8_t * src3, uint8_t * src4, int n, int acc) |
|
942 { |
|
943 int i; |
|
944 int y; |
|
945 int a, b, c, d; |
|
946 int quads = (n + 1) / 2; |
|
947 |
|
948 acc = (acc >> 8) & 0xff; |
|
949 a = vs_4tap_taps[acc][0]; |
|
950 b = vs_4tap_taps[acc][1]; |
|
951 c = vs_4tap_taps[acc][2]; |
|
952 d = vs_4tap_taps[acc][3]; |
|
953 for (i = 0; i < quads; i++) { |
|
954 y = a * src1[i * 4 + 0]; |
|
955 y += b * src2[i * 4 + 0]; |
|
956 y += c * src3[i * 4 + 0]; |
|
957 y += d * src4[i * 4 + 0]; |
|
958 y += (1 << (SHIFT - 1)); |
|
959 dest[i * 4 + 0] = CLAMP (y >> SHIFT, 0, 255); |
|
960 |
|
961 y = a * src1[i * 4 + 1]; |
|
962 y += b * src2[i * 4 + 1]; |
|
963 y += c * src3[i * 4 + 1]; |
|
964 y += d * src4[i * 4 + 1]; |
|
965 y += (1 << (SHIFT - 1)); |
|
966 dest[i * 4 + 1] = CLAMP (y >> SHIFT, 0, 255); |
|
967 |
|
968 if (2 * i + 1 < n) { |
|
969 y = a * src1[i * 4 + 2]; |
|
970 y += b * src2[i * 4 + 2]; |
|
971 y += c * src3[i * 4 + 2]; |
|
972 y += d * src4[i * 4 + 2]; |
|
973 y += (1 << (SHIFT - 1)); |
|
974 dest[i * 4 + 2] = CLAMP (y >> SHIFT, 0, 255); |
|
975 |
|
976 y = a * src1[i * 4 + 3]; |
|
977 y += b * src2[i * 4 + 3]; |
|
978 y += c * src3[i * 4 + 3]; |
|
979 y += d * src4[i * 4 + 3]; |
|
980 y += (1 << (SHIFT - 1)); |
|
981 dest[i * 4 + 3] = CLAMP (y >> SHIFT, 0, 255); |
|
982 } |
|
983 } |
|
984 } |
|
985 #ifdef __SYMBIAN32__ |
|
986 EXPORT_C |
|
987 #endif |
|
988 |
|
989 |
|
990 void |
|
991 vs_image_scale_4tap_UYVY (const VSImage * dest, const VSImage * src, |
|
992 uint8_t * tmpbuf) |
|
993 { |
|
994 int yacc; |
|
995 int y_increment; |
|
996 int x_increment; |
|
997 int i; |
|
998 int j; |
|
999 int xacc; |
|
1000 int k; |
|
1001 |
|
1002 if (dest->height == 1) |
|
1003 y_increment = 0; |
|
1004 else |
|
1005 y_increment = ((src->height - 1) << 16) / (dest->height - 1); |
|
1006 |
|
1007 if (dest->width == 1) |
|
1008 x_increment = 0; |
|
1009 else |
|
1010 x_increment = ((src->width - 1) << 16) / (dest->width - 1); |
|
1011 |
|
1012 k = 0; |
|
1013 for (i = 0; i < 4; i++) { |
|
1014 xacc = 0; |
|
1015 vs_scanline_resample_4tap_UYVY (tmpbuf + i * dest->stride, |
|
1016 src->pixels + i * src->stride, dest->width, src->width, |
|
1017 &xacc, x_increment); |
|
1018 } |
|
1019 |
|
1020 yacc = 0; |
|
1021 for (i = 0; i < dest->height; i++) { |
|
1022 uint8_t *t0, *t1, *t2, *t3; |
|
1023 |
|
1024 j = yacc >> 16; |
|
1025 |
|
1026 while (j > k) { |
|
1027 k++; |
|
1028 if (k + 3 < src->height) { |
|
1029 xacc = 0; |
|
1030 vs_scanline_resample_4tap_UYVY (tmpbuf + ((k + 3) & 3) * dest->stride, |
|
1031 src->pixels + (k + 3) * src->stride, |
|
1032 dest->width, src->width, &xacc, x_increment); |
|
1033 } |
|
1034 } |
|
1035 |
|
1036 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride; |
|
1037 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride; |
|
1038 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride; |
|
1039 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride; |
|
1040 vs_scanline_merge_4tap_UYVY (dest->pixels + i * dest->stride, |
|
1041 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
|
1042 |
|
1043 yacc += y_increment; |
|
1044 } |
|
1045 } |
|
1046 |
|
1047 /* note that src and dest are uint16_t, and thus endian dependent */ |
|
1048 |
|
1049 #define RGB565_R(x) (((x)&0xf800)>>8 | ((x)&0xf800)>>13) |
|
1050 #define RGB565_G(x) (((x)&0x07e0)>>3 | ((x)&0x07e0)>>9) |
|
1051 #define RGB565_B(x) (((x)&0x001f)<<3 | ((x)&0x001f)>>2) |
|
1052 |
|
1053 #define RGB565(r,g,b) \ |
|
1054 ((((r)<<8)&0xf800) | (((g)<<3)&0x07e0) | (((b)>>3)&0x001f)) |
|
1055 |
|
1056 #ifdef __SYMBIAN32__ |
|
1057 EXPORT_C |
|
1058 #endif |
|
1059 |
|
1060 void |
|
1061 vs_scanline_resample_4tap_RGB565 (uint8_t * dest_u8, uint8_t * src_u8, |
|
1062 int n, int src_width, int *xacc, int increment) |
|
1063 { |
|
1064 int i; |
|
1065 int j; |
|
1066 int acc; |
|
1067 int x; |
|
1068 int y, y_r, y_b, y_g; |
|
1069 uint16_t *dest = (uint16_t *) dest_u8; |
|
1070 uint16_t *src = (uint16_t *) src_u8; |
|
1071 |
|
1072 acc = *xacc; |
|
1073 for (i = 0; i < n; i++) { |
|
1074 j = acc >> 16; |
|
1075 x = acc & 0xffff >> 8; |
|
1076 |
|
1077 if (j - 1 >= 0 && j + 2 < src_width) { |
|
1078 y = vs_4tap_taps[x][0] * RGB565_R (src[MAX ((j - 1), 0)]); |
|
1079 y += vs_4tap_taps[x][1] * RGB565_R (src[j]); |
|
1080 y += vs_4tap_taps[x][2] * RGB565_R (src[(j + 1)]); |
|
1081 y += vs_4tap_taps[x][3] * RGB565_R (src[(j + 2)]); |
|
1082 } else { |
|
1083 y = vs_4tap_taps[x][0] * RGB565_R (src[CLAMP ((j - 1), 0, |
|
1084 src_width - 1)]); |
|
1085 y += vs_4tap_taps[x][1] * RGB565_R (src[CLAMP (j, 0, src_width - 1)]); |
|
1086 y += vs_4tap_taps[x][2] * RGB565_R (src[CLAMP ((j + 1), 0, |
|
1087 src_width - 1)]); |
|
1088 y += vs_4tap_taps[x][3] * RGB565_R (src[CLAMP ((j + 2), 0, |
|
1089 src_width - 1)]); |
|
1090 } |
|
1091 y += (1 << (SHIFT - 1)); |
|
1092 y_r = CLAMP (y >> SHIFT, 0, 255); |
|
1093 |
|
1094 if (j - 1 >= 0 && j + 2 < src_width) { |
|
1095 y = vs_4tap_taps[x][0] * RGB565_G (src[MAX ((j - 1), 0)]); |
|
1096 y += vs_4tap_taps[x][1] * RGB565_G (src[j]); |
|
1097 y += vs_4tap_taps[x][2] * RGB565_G (src[(j + 1)]); |
|
1098 y += vs_4tap_taps[x][3] * RGB565_G (src[(j + 2)]); |
|
1099 } else { |
|
1100 y = vs_4tap_taps[x][0] * RGB565_G (src[CLAMP ((j - 1), 0, |
|
1101 src_width - 1)]); |
|
1102 y += vs_4tap_taps[x][1] * RGB565_G (src[CLAMP (j, 0, src_width - 1)]); |
|
1103 y += vs_4tap_taps[x][2] * RGB565_G (src[CLAMP ((j + 1), 0, |
|
1104 src_width - 1)]); |
|
1105 y += vs_4tap_taps[x][3] * RGB565_G (src[CLAMP ((j + 2), 0, |
|
1106 src_width - 1)]); |
|
1107 } |
|
1108 y += (1 << (SHIFT - 1)); |
|
1109 y_g = CLAMP (y >> SHIFT, 0, 255); |
|
1110 |
|
1111 if (j - 1 >= 0 && j + 2 < src_width) { |
|
1112 y = vs_4tap_taps[x][0] * RGB565_B (src[MAX ((j - 1), 0)]); |
|
1113 y += vs_4tap_taps[x][1] * RGB565_B (src[j]); |
|
1114 y += vs_4tap_taps[x][2] * RGB565_B (src[(j + 1)]); |
|
1115 y += vs_4tap_taps[x][3] * RGB565_B (src[(j + 2)]); |
|
1116 } else { |
|
1117 y = vs_4tap_taps[x][0] * RGB565_B (src[CLAMP ((j - 1), 0, |
|
1118 src_width - 1)]); |
|
1119 y += vs_4tap_taps[x][1] * RGB565_B (src[CLAMP (j, 0, src_width - 1)]); |
|
1120 y += vs_4tap_taps[x][2] * RGB565_B (src[CLAMP ((j + 1), 0, |
|
1121 src_width - 1)]); |
|
1122 y += vs_4tap_taps[x][3] * RGB565_B (src[CLAMP ((j + 2), 0, |
|
1123 src_width - 1)]); |
|
1124 } |
|
1125 y += (1 << (SHIFT - 1)); |
|
1126 y_b = CLAMP (y >> SHIFT, 0, 255); |
|
1127 |
|
1128 dest[i] = RGB565 (y_r, y_b, y_g); |
|
1129 acc += increment; |
|
1130 } |
|
1131 *xacc = acc; |
|
1132 } |
|
1133 #ifdef __SYMBIAN32__ |
|
1134 EXPORT_C |
|
1135 #endif |
|
1136 |
|
1137 |
|
1138 void |
|
1139 vs_scanline_merge_4tap_RGB565 (uint8_t * dest_u8, uint8_t * src1_u8, |
|
1140 uint8_t * src2_u8, uint8_t * src3_u8, uint8_t * src4_u8, int n, int acc) |
|
1141 { |
|
1142 int i; |
|
1143 int y, y_r, y_b, y_g; |
|
1144 int a, b, c, d; |
|
1145 uint16_t *dest = (uint16_t *) dest_u8; |
|
1146 uint16_t *src1 = (uint16_t *) src1_u8; |
|
1147 uint16_t *src2 = (uint16_t *) src2_u8; |
|
1148 uint16_t *src3 = (uint16_t *) src3_u8; |
|
1149 uint16_t *src4 = (uint16_t *) src4_u8; |
|
1150 |
|
1151 acc = (acc >> 8) & 0xff; |
|
1152 a = vs_4tap_taps[acc][0]; |
|
1153 b = vs_4tap_taps[acc][1]; |
|
1154 c = vs_4tap_taps[acc][2]; |
|
1155 d = vs_4tap_taps[acc][3]; |
|
1156 |
|
1157 for (i = 0; i < n; i++) { |
|
1158 y = a * RGB565_R (src1[i]); |
|
1159 y += b * RGB565_R (src2[i]); |
|
1160 y += c * RGB565_R (src3[i]); |
|
1161 y += d * RGB565_R (src4[i]); |
|
1162 y += (1 << (SHIFT - 1)); |
|
1163 y_r = CLAMP (y >> SHIFT, 0, 255); |
|
1164 |
|
1165 y = a * RGB565_G (src1[i]); |
|
1166 y += b * RGB565_G (src2[i]); |
|
1167 y += c * RGB565_G (src3[i]); |
|
1168 y += d * RGB565_G (src4[i]); |
|
1169 y += (1 << (SHIFT - 1)); |
|
1170 y_g = CLAMP (y >> SHIFT, 0, 255); |
|
1171 |
|
1172 y = a * RGB565_B (src1[i]); |
|
1173 y += b * RGB565_B (src2[i]); |
|
1174 y += c * RGB565_B (src3[i]); |
|
1175 y += d * RGB565_B (src4[i]); |
|
1176 y += (1 << (SHIFT - 1)); |
|
1177 y_b = CLAMP (y >> SHIFT, 0, 255); |
|
1178 |
|
1179 dest[i] = RGB565 (y_r, y_b, y_g); |
|
1180 } |
|
1181 } |
|
1182 #ifdef __SYMBIAN32__ |
|
1183 EXPORT_C |
|
1184 #endif |
|
1185 |
|
1186 |
|
1187 void |
|
1188 vs_image_scale_4tap_RGB565 (const VSImage * dest, const VSImage * src, |
|
1189 uint8_t * tmpbuf) |
|
1190 { |
|
1191 int yacc; |
|
1192 int y_increment; |
|
1193 int x_increment; |
|
1194 int i; |
|
1195 int j; |
|
1196 int xacc; |
|
1197 int k; |
|
1198 |
|
1199 if (dest->height == 1) |
|
1200 y_increment = 0; |
|
1201 else |
|
1202 y_increment = ((src->height - 1) << 16) / (dest->height - 1); |
|
1203 |
|
1204 if (dest->width == 1) |
|
1205 x_increment = 0; |
|
1206 else |
|
1207 x_increment = ((src->width - 1) << 16) / (dest->width - 1); |
|
1208 |
|
1209 k = 0; |
|
1210 for (i = 0; i < 4; i++) { |
|
1211 xacc = 0; |
|
1212 vs_scanline_resample_4tap_RGB565 (tmpbuf + i * dest->stride, |
|
1213 src->pixels + i * src->stride, dest->width, src->width, |
|
1214 &xacc, x_increment); |
|
1215 } |
|
1216 |
|
1217 yacc = 0; |
|
1218 for (i = 0; i < dest->height; i++) { |
|
1219 uint8_t *t0, *t1, *t2, *t3; |
|
1220 |
|
1221 j = yacc >> 16; |
|
1222 |
|
1223 while (j > k) { |
|
1224 k++; |
|
1225 if (k + 3 < src->height) { |
|
1226 xacc = 0; |
|
1227 vs_scanline_resample_4tap_RGB565 (tmpbuf + ((k + 3) & 3) * dest->stride, |
|
1228 src->pixels + (k + 3) * src->stride, |
|
1229 dest->width, src->width, &xacc, x_increment); |
|
1230 } |
|
1231 } |
|
1232 |
|
1233 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride; |
|
1234 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride; |
|
1235 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride; |
|
1236 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride; |
|
1237 vs_scanline_merge_4tap_RGB565 (dest->pixels + i * dest->stride, |
|
1238 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
|
1239 |
|
1240 yacc += y_increment; |
|
1241 } |
|
1242 } |
|
1243 |
|
1244 /* note that src and dest are uint16_t, and thus endian dependent */ |
|
1245 |
|
1246 #define RGB555_R(x) (((x)&0x7c00)>>8 | ((x)&0x7c00)>>13) |
|
1247 #define RGB555_G(x) (((x)&0x03e0)>>3 | ((x)&0x03e0)>>9) |
|
1248 #define RGB555_B(x) (((x)&0x001f)<<3 | ((x)&0x001f)>>2) |
|
1249 |
|
1250 #define RGB555(r,g,b) \ |
|
1251 ((((r)<<7)&0x7c00) | (((g)<<2)&0x03e0) | (((b)>>3)&0x001f)) |
|
1252 |
|
1253 #ifdef __SYMBIAN32__ |
|
1254 EXPORT_C |
|
1255 #endif |
|
1256 |
|
1257 void |
|
1258 vs_scanline_resample_4tap_RGB555 (uint8_t * dest_u8, uint8_t * src_u8, |
|
1259 int n, int src_width, int *xacc, int increment) |
|
1260 { |
|
1261 int i; |
|
1262 int j; |
|
1263 int acc; |
|
1264 int x; |
|
1265 int y, y_r, y_b, y_g; |
|
1266 uint16_t *dest = (uint16_t *) dest_u8; |
|
1267 uint16_t *src = (uint16_t *) src_u8; |
|
1268 |
|
1269 acc = *xacc; |
|
1270 for (i = 0; i < n; i++) { |
|
1271 j = acc >> 16; |
|
1272 x = acc & 0xffff >> 8; |
|
1273 |
|
1274 if (j - 1 >= 0 && j + 2 < src_width) { |
|
1275 y = vs_4tap_taps[x][0] * RGB555_R (src[MAX ((j - 1), 0)]); |
|
1276 y += vs_4tap_taps[x][1] * RGB555_R (src[j]); |
|
1277 y += vs_4tap_taps[x][2] * RGB555_R (src[(j + 1)]); |
|
1278 y += vs_4tap_taps[x][3] * RGB555_R (src[(j + 2)]); |
|
1279 } else { |
|
1280 y = vs_4tap_taps[x][0] * RGB555_R (src[CLAMP ((j - 1), 0, |
|
1281 src_width - 1)]); |
|
1282 y += vs_4tap_taps[x][1] * RGB555_R (src[CLAMP (j, 0, src_width - 1)]); |
|
1283 y += vs_4tap_taps[x][2] * RGB555_R (src[CLAMP ((j + 1), 0, |
|
1284 src_width - 1)]); |
|
1285 y += vs_4tap_taps[x][3] * RGB555_R (src[CLAMP ((j + 2), 0, |
|
1286 src_width - 1)]); |
|
1287 } |
|
1288 y += (1 << (SHIFT - 1)); |
|
1289 y_r = CLAMP (y >> SHIFT, 0, 255); |
|
1290 |
|
1291 if (j - 1 >= 0 && j + 2 < src_width) { |
|
1292 y = vs_4tap_taps[x][0] * RGB555_G (src[MAX ((j - 1), 0)]); |
|
1293 y += vs_4tap_taps[x][1] * RGB555_G (src[j]); |
|
1294 y += vs_4tap_taps[x][2] * RGB555_G (src[(j + 1)]); |
|
1295 y += vs_4tap_taps[x][3] * RGB555_G (src[(j + 2)]); |
|
1296 } else { |
|
1297 y = vs_4tap_taps[x][0] * RGB555_G (src[CLAMP ((j - 1), 0, |
|
1298 src_width - 1)]); |
|
1299 y += vs_4tap_taps[x][1] * RGB555_G (src[CLAMP (j, 0, src_width - 1)]); |
|
1300 y += vs_4tap_taps[x][2] * RGB555_G (src[CLAMP ((j + 1), 0, |
|
1301 src_width - 1)]); |
|
1302 y += vs_4tap_taps[x][3] * RGB555_G (src[CLAMP ((j + 2), 0, |
|
1303 src_width - 1)]); |
|
1304 } |
|
1305 y += (1 << (SHIFT - 1)); |
|
1306 y_g = CLAMP (y >> SHIFT, 0, 255); |
|
1307 |
|
1308 if (j - 1 >= 0 && j + 2 < src_width) { |
|
1309 y = vs_4tap_taps[x][0] * RGB555_B (src[MAX ((j - 1), 0)]); |
|
1310 y += vs_4tap_taps[x][1] * RGB555_B (src[j]); |
|
1311 y += vs_4tap_taps[x][2] * RGB555_B (src[(j + 1)]); |
|
1312 y += vs_4tap_taps[x][3] * RGB555_B (src[(j + 2)]); |
|
1313 } else { |
|
1314 y = vs_4tap_taps[x][0] * RGB555_B (src[CLAMP ((j - 1), 0, |
|
1315 src_width - 1)]); |
|
1316 y += vs_4tap_taps[x][1] * RGB555_B (src[CLAMP (j, 0, src_width - 1)]); |
|
1317 y += vs_4tap_taps[x][2] * RGB555_B (src[CLAMP ((j + 1), 0, |
|
1318 src_width - 1)]); |
|
1319 y += vs_4tap_taps[x][3] * RGB555_B (src[CLAMP ((j + 2), 0, |
|
1320 src_width - 1)]); |
|
1321 } |
|
1322 y += (1 << (SHIFT - 1)); |
|
1323 y_b = CLAMP (y >> SHIFT, 0, 255); |
|
1324 |
|
1325 dest[i] = RGB555 (y_r, y_b, y_g); |
|
1326 acc += increment; |
|
1327 } |
|
1328 *xacc = acc; |
|
1329 } |
|
1330 #ifdef __SYMBIAN32__ |
|
1331 EXPORT_C |
|
1332 #endif |
|
1333 |
|
1334 |
|
1335 void |
|
1336 vs_scanline_merge_4tap_RGB555 (uint8_t * dest_u8, uint8_t * src1_u8, |
|
1337 uint8_t * src2_u8, uint8_t * src3_u8, uint8_t * src4_u8, int n, int acc) |
|
1338 { |
|
1339 int i; |
|
1340 int y, y_r, y_b, y_g; |
|
1341 int a, b, c, d; |
|
1342 uint16_t *dest = (uint16_t *) dest_u8; |
|
1343 uint16_t *src1 = (uint16_t *) src1_u8; |
|
1344 uint16_t *src2 = (uint16_t *) src2_u8; |
|
1345 uint16_t *src3 = (uint16_t *) src3_u8; |
|
1346 uint16_t *src4 = (uint16_t *) src4_u8; |
|
1347 |
|
1348 acc = (acc >> 8) & 0xff; |
|
1349 a = vs_4tap_taps[acc][0]; |
|
1350 b = vs_4tap_taps[acc][1]; |
|
1351 c = vs_4tap_taps[acc][2]; |
|
1352 d = vs_4tap_taps[acc][3]; |
|
1353 |
|
1354 for (i = 0; i < n; i++) { |
|
1355 y = a * RGB555_R (src1[i]); |
|
1356 y += b * RGB555_R (src2[i]); |
|
1357 y += c * RGB555_R (src3[i]); |
|
1358 y += d * RGB555_R (src4[i]); |
|
1359 y += (1 << (SHIFT - 1)); |
|
1360 y_r = CLAMP (y >> SHIFT, 0, 255); |
|
1361 |
|
1362 y = a * RGB555_G (src1[i]); |
|
1363 y += b * RGB555_G (src2[i]); |
|
1364 y += c * RGB555_G (src3[i]); |
|
1365 y += d * RGB555_G (src4[i]); |
|
1366 y += (1 << (SHIFT - 1)); |
|
1367 y_g = CLAMP (y >> SHIFT, 0, 255); |
|
1368 |
|
1369 y = a * RGB555_B (src1[i]); |
|
1370 y += b * RGB555_B (src2[i]); |
|
1371 y += c * RGB555_B (src3[i]); |
|
1372 y += d * RGB555_B (src4[i]); |
|
1373 y += (1 << (SHIFT - 1)); |
|
1374 y_b = CLAMP (y >> SHIFT, 0, 255); |
|
1375 |
|
1376 dest[i] = RGB555 (y_r, y_b, y_g); |
|
1377 } |
|
1378 } |
|
1379 #ifdef __SYMBIAN32__ |
|
1380 EXPORT_C |
|
1381 #endif |
|
1382 |
|
1383 |
|
1384 void |
|
1385 vs_image_scale_4tap_RGB555 (const VSImage * dest, const VSImage * src, |
|
1386 uint8_t * tmpbuf) |
|
1387 { |
|
1388 int yacc; |
|
1389 int y_increment; |
|
1390 int x_increment; |
|
1391 int i; |
|
1392 int j; |
|
1393 int xacc; |
|
1394 int k; |
|
1395 |
|
1396 if (dest->height == 1) |
|
1397 y_increment = 0; |
|
1398 else |
|
1399 y_increment = ((src->height - 1) << 16) / (dest->height - 1); |
|
1400 |
|
1401 if (dest->width == 1) |
|
1402 x_increment = 0; |
|
1403 else |
|
1404 x_increment = ((src->width - 1) << 16) / (dest->width - 1); |
|
1405 |
|
1406 k = 0; |
|
1407 for (i = 0; i < 4; i++) { |
|
1408 xacc = 0; |
|
1409 vs_scanline_resample_4tap_RGB555 (tmpbuf + i * dest->stride, |
|
1410 src->pixels + i * src->stride, dest->width, src->width, |
|
1411 &xacc, x_increment); |
|
1412 } |
|
1413 |
|
1414 yacc = 0; |
|
1415 for (i = 0; i < dest->height; i++) { |
|
1416 uint8_t *t0, *t1, *t2, *t3; |
|
1417 |
|
1418 j = yacc >> 16; |
|
1419 |
|
1420 while (j > k) { |
|
1421 k++; |
|
1422 if (k + 3 < src->height) { |
|
1423 xacc = 0; |
|
1424 vs_scanline_resample_4tap_RGB555 (tmpbuf + ((k + 3) & 3) * dest->stride, |
|
1425 src->pixels + (k + 3) * src->stride, |
|
1426 dest->width, src->width, &xacc, x_increment); |
|
1427 } |
|
1428 } |
|
1429 |
|
1430 t0 = tmpbuf + (CLAMP (j - 1, 0, src->height - 1) & 3) * dest->stride; |
|
1431 t1 = tmpbuf + (CLAMP (j, 0, src->height - 1) & 3) * dest->stride; |
|
1432 t2 = tmpbuf + (CLAMP (j + 1, 0, src->height - 1) & 3) * dest->stride; |
|
1433 t3 = tmpbuf + (CLAMP (j + 2, 0, src->height - 1) & 3) * dest->stride; |
|
1434 vs_scanline_merge_4tap_RGB555 (dest->pixels + i * dest->stride, |
|
1435 t0, t1, t2, t3, dest->width, yacc & 0xffff); |
|
1436 |
|
1437 yacc += y_increment; |
|
1438 } |
|
1439 } |