summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJuergen Keil <jkeil@users.sourceforge.net>2001-09-27 13:09:01 +0000
committerJuergen Keil <jkeil@users.sourceforge.net>2001-09-27 13:09:01 +0000
commitc459ed70ae500a8961c55931936a3157c55d4430 (patch)
treef9af8b9173ca8fcde94c3aec87256893fb3f8939 /src
parentedd9b716884e51270dd474ecc509baf9963570ee (diff)
downloadxine-lib-c459ed70ae500a8961c55931936a3157c55d4430.tar.gz
xine-lib-c459ed70ae500a8961c55931936a3157c55d4430.tar.bz2
Add a few scale_line variants for PAL VCD
CVS patchset: 703 CVS date: 2001/09/27 13:09:01
Diffstat (limited to 'src')
-rw-r--r--src/video_out/yuv2rgb.c251
1 files changed, 196 insertions, 55 deletions
diff --git a/src/video_out/yuv2rgb.c b/src/video_out/yuv2rgb.c
index 12aa0f1ea..a460f290f 100644
--- a/src/video_out/yuv2rgb.c
+++ b/src/video_out/yuv2rgb.c
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: yuv2rgb.c,v 1.19 2001/09/25 18:39:36 jkeil Exp $
+ * $Id: yuv2rgb.c,v 1.20 2001/09/27 13:09:01 jkeil Exp $
*/
#include "config.h"
@@ -182,36 +182,6 @@ static void scale_line_gen (uint8_t *source, uint8_t *dest,
profiler_stop_count(prof_scale_line);
}
-#if 0
-static void scale_line_fast (uint8_t *source, uint8_t *dest,
- int width, int step) {
- /*
- * scales a yuv source row to a dest row, without interpolation
- * (faster then scale_line_gen, but quality suffers especially for
- * large scale factors)
- */
- int dx;
-
- profiler_start_count(prof_scale_line);
-
- dx = 0;
-
- while (--width >= 0) {
-
- *dest++ = *source;
-
- dx += step;
- while (dx > 32768) {
- dx -= 32768;
- source++;
- }
- }
-
- profiler_stop_count(prof_scale_line);
-}
-#endif
-
-
/*
* Interpolates 16 output pixels from 15 source pixels using shifts.
* Useful for scaling a PAL mpeg2 dvd input source to 4:3 format on
@@ -635,6 +605,179 @@ done:
}
+/*
+ * Interpolates 12 output pixels from 11 source pixels using shifts.
+ * Useful for scaling a PAL vcd input source to 4:3 display format.
+ */
+static void scale_line_11_12 (uint8_t *source, uint8_t *dest,
+ int width, int step) {
+
+ int p1, p2;
+
+ profiler_start_count(prof_scale_line);
+
+ while ((width -= 12) >= 0) {
+ p1 = source[0];
+ p2 = source[1];
+ dest[0] = p1;
+ dest[1] = (1*p1 + 7*p2) >> 3;
+ p1 = source[2];
+ dest[2] = (1*p2 + 7*p1) >> 3;
+ p2 = source[3];
+ dest[3] = (1*p1 + 3*p2) >> 2;
+ p1 = source[4];
+ dest[4] = (3*p2 + 5*p1) >> 3;
+ p2 = source[5];
+ dest[5] = (3*p1 + 5*p2) >> 3;
+ p1 = source[6];
+ dest[6] = (1*p2 + 1*p1) >> 1;
+ p2 = source[7];
+ dest[7] = (5*p1 + 3*p2) >> 3;
+ p1 = source[8];
+ dest[8] = (5*p2 + 3*p1) >> 3;
+ p2 = source[9];
+ dest[9] = (3*p1 + 1*p2) >> 2;
+ p1 = source[10];
+ dest[10] = (7*p2 + 1*p1) >> 3;
+ p2 = source[11];
+ dest[11] = (7*p1 + 1*p2) >> 3;
+ source += 11;
+ dest += 12;
+ }
+
+ if ((width += 12) <= 0) goto done;
+ *dest++ = source[0];
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[0] + 7*source[1]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[1] + 7*source[2]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[2] + 3*source[3]) >> 2;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[3] + 5*source[4]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[4] + 5*source[5]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[5] + 1*source[6]) >> 1;
+ if (--width <= 0) goto done;
+ *dest++ = (5*source[6] + 3*source[7]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (5*source[7] + 3*source[8]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[8] + 1*source[9]) >> 2;
+ if (--width <= 0) goto done;
+ *dest++ = (7*source[9] + 1*source[10]) >> 3;
+done:
+
+ profiler_stop_count(prof_scale_line);
+}
+
+
+/*
+ * Interpolates 24 output pixels from 11 source pixels using shifts.
+ * Useful for scaling a PAL vcd input source to 4:3 display format
+ * at 2*zoom.
+ */
+static void scale_line_11_24 (uint8_t *source, uint8_t *dest,
+ int width, int step) {
+
+ int p1, p2;
+
+ profiler_start_count(prof_scale_line);
+
+ while ((width -= 24) >= 0) {
+ p1 = source[0];
+ p2 = source[1];
+ dest[0] = p1;
+ dest[1] = (1*p1 + 1*p2) >> 1;
+ dest[2] = (1*p1 + 7*p2) >> 3;
+ p1 = source[2];
+ dest[3] = (5*p2 + 3*p1) >> 3;
+ dest[4] = (1*p2 + 7*p1) >> 3;
+ p2 = source[3];
+ dest[5] = (3*p1 + 1*p2) >> 2;
+ dest[6] = (1*p1 + 3*p2) >> 2;
+ p1 = source[4];
+ dest[7] = (3*p2 + 1*p1) >> 2;
+ dest[8] = (3*p2 + 5*p1) >> 3;
+ p2 = source[5];
+ dest[9] = (7*p1 + 1*p2) >> 3;
+ dest[10] = (3*p1 + 5*p2) >> 3;
+ p1 = source[6];
+ dest[11] = p2;
+ dest[12] = (1*p2 + 1*p1) >> 1;
+ dest[13] = p1;
+ p2 = source[7];
+ dest[14] = (5*p1 + 3*p2) >> 3;
+ dest[15] = (1*p1 + 7*p2) >> 3;
+ p1 = source[8];
+ dest[16] = (5*p2 + 3*p1) >> 3;
+ dest[17] = (1*p2 + 3*p1) >> 2;
+ p2 = source[9];
+ dest[18] = (3*p1 + 1*p2) >> 2;
+ dest[19] = (1*p1 + 3*p2) >> 2;
+ p1 = source[10];
+ dest[20] = (7*p2 + 1*p1) >> 3;
+ dest[21] = (3*p2 + 5*p1) >> 3;
+ p2 = source[11];
+ dest[22] = (7*p1 + 1*p2) >> 3;
+ dest[23] = (1*p1 + 1*p2) >> 1;
+ source += 11;
+ dest += 24;
+ }
+
+ if ((width += 24) <= 0) goto done;
+ *dest++ = source[0];
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[0] + 1*source[1]) >> 1;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[0] + 7*source[1]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (5*source[1] + 3*source[2]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[1] + 7*source[2]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[2] + 1*source[3]) >> 2;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[2] + 3*source[3]) >> 2;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[3] + 1*source[4]) >> 2;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[3] + 5*source[4]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (7*source[4] + 1*source[5]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[4] + 5*source[5]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = source[5];
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[5] + 1*source[6]) >> 1;
+ if (--width <= 0) goto done;
+ *dest++ = source[6];
+ if (--width <= 0) goto done;
+ *dest++ = (5*source[6] + 3*source[7]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[6] + 7*source[7]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (5*source[7] + 3*source[8]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[7] + 3*source[8]) >> 2;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[8] + 1*source[9]) >> 2;
+ if (--width <= 0) goto done;
+ *dest++ = (1*source[8] + 3*source[9]) >> 2;
+ if (--width <= 0) goto done;
+ *dest++ = (7*source[9] + 1*source[10]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (3*source[9] + 5*source[10]) >> 3;
+ if (--width <= 0) goto done;
+ *dest++ = (7*source[10] + 1*source[11]) >> 3;
+done:
+
+ profiler_stop_count(prof_scale_line);
+}
+
+
/* Interpolate 2 output pixels from one source pixel. */
static void scale_line_1_2 (uint8_t *source, uint8_t *dest,
@@ -677,33 +820,31 @@ static void scale_line_1_1 (uint8_t *source, uint8_t *dest,
static scale_line_func_t find_scale_line_func(int step) {
-#if 1
- if (step == 15*32768/16) {
- printf("yuv2rgb: using dvd 4:3 optimized scale_line\n");
- return scale_line_15_16;
- }
- if (step == 45*32768/64) {
- printf("yuv2rgb: using dvd fullscreen(1024x768) optimized scale_line\n");
- return scale_line_45_64;
- }
- if (step == 9*32768/16) {
- printf("yuv2rgb: using dvd fullscreen(1280x1024) optimized scale_line\n");
- return scale_line_9_16;
- }
- if (step == 1*32768/2) {
- printf("yuv2rgb: using optimized 2*zoom scale_line\n");
- return scale_line_1_2;
- }
- if (step == 1*32768/1) {
- printf("yuv2rgb: using non-scaled scale_line\n");
- return scale_line_1_1;
+ static struct {
+ int src_step;
+ int dest_step;
+ scale_line_func_t func;
+ char *desc;
+ } scale_line[] = {
+ { 15, 16, scale_line_15_16, "dvd(pal) 4:3" },
+ { 45, 64, scale_line_45_64, "dvd fullscreen(1024x768)" },
+ { 9, 16, scale_line_9_16, "dvd fullscreen(1280x1024)" },
+ { 11, 12, scale_line_11_12, "vcd(pal) 4:3" },
+ { 11, 24, scale_line_11_24, "vcd(pal) 4:3 2*zoom" },
+ { 1, 2, scale_line_1_2, "2*zoom" },
+ { 1, 1, scale_line_1_1, "non-scaled" },
+ };
+ int i;
+
+ for (i = 0; i < sizeof(scale_line)/sizeof(scale_line[0]); i++) {
+ if (step == scale_line[i].src_step*32768/scale_line[i].dest_step) {
+ printf("yuv2rgb: using %s optimized scale_line\n", scale_line[i].desc);
+ return scale_line[i].func;
+ }
}
printf("yuv2rgb: using generic scale_line with interpolation\n");
return scale_line_gen;
-#else
- printf("yuv2rgb: using generic scale_line without interpolation\n");
- return scale_line_fast;
-#endif
+
}