summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuergen Keil <jkeil@users.sourceforge.net>2001-10-09 09:50:22 +0000
committerJuergen Keil <jkeil@users.sourceforge.net>2001-10-09 09:50:22 +0000
commit641d2f4ba232ebfc9d7d7b2ba70eb34e951bd51b (patch)
treea9d0dd817f0d5de56a687454f62a6bdd612d7ae8
parentc4ef31142425708cd43d8d02709fc2536b889277 (diff)
downloadxine-lib-641d2f4ba232ebfc9d7d7b2ba70eb34e951bd51b.tar.gz
xine-lib-641d2f4ba232ebfc9d7d7b2ba70eb34e951bd51b.tar.bz2
blend_rgb* with rle-image scaling. Used by the XShm video_out driver.
This fixes the position and size for button hilights using the dvdnav plugin and position and size of subtitles. CVS patchset: 773 CVS date: 2001/10/09 09:50:22
-rw-r--r--src/video_out/alphablend.c139
-rw-r--r--src/video_out/alphablend.h20
-rw-r--r--src/video_out/video_out_xshm.c14
3 files changed, 123 insertions, 50 deletions
diff --git a/src/video_out/alphablend.c b/src/video_out/alphablend.c
index b7add0e31..8a484070c 100644
--- a/src/video_out/alphablend.c
+++ b/src/video_out/alphablend.c
@@ -77,9 +77,28 @@ static void mem_blend32(uint8_t *mem, uint8_t r, uint8_t g, uint8_t b,
}
}
+
+/*
+ * Some macros for fixed point arithmetic.
+ *
+ * The blend_rgb* routines perform rle image scaling using
+ * scale factors that are expressed as integers scaled with
+ * a factor of 2**16.
+ *
+ * INT_TO_SCALED()/SCALED_TO_INT() converts from integer
+ * to scaled fixed point and back.
+ */
+#define SCALE_SHIFT 16
+#define SCALE_FACTOR (1<<SCALE_SHIFT)
+#define INT_TO_SCALED(i) ((i) << SCALE_SHIFT)
+#define SCALED_TO_INT(sc) ((sc) >> SCALE_SHIFT)
+
+
/* TODO: RGB color clut, only b/w now */
-void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
- int dst_height)
+/* TODO: RGB image shrinking (dy_step > 1.0) */
+void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl,
+ int img_width, int img_height,
+ int dst_width, int dst_height)
{
uint8_t *my_trans;
uint16_t my_clut[4];
@@ -89,13 +108,16 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
int src_height = img_overl->height;
rle_elem_t *rle = img_overl->rle;
rle_elem_t *rle_limit = rle + img_overl->num_rle;
- int x_off = img_overl->x;
- int y_off = img_overl->y;
- int mask;
- int x, y;
+ int x, y, x1_scaled, x2_scaled;
+ int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */
+ uint16_t *img_pix;
+
+ dy_step = INT_TO_SCALED(dst_height) / img_height;
+ x_scale = INT_TO_SCALED(img_width) / dst_width;
- uint16_t *dst_pix = (uint16_t *) img;
- dst_pix += dst_width * y_off + x_off;
+ img_pix = (uint16_t *) img
+ + (img_overl->y * img_height / dst_height) * img_width
+ + (img_overl->x * img_width / dst_width);
for (x = 0; x < 4; x++) {
uint16_t clr = clut[x].y >> 2;
@@ -103,10 +125,11 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
}
my_trans = img_overl->trans;
- for (y = 0; y < src_height; y++) {
- mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y);
+ for (y = dy = 0; y < src_height;) {
+ int mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y);
+ rle_elem_t *rle_start = rle;
- for (x = 0; x < src_width;) {
+ for (x = x1_scaled = 0; x < src_width;) {
uint8_t clr;
uint16_t o;
@@ -117,22 +140,34 @@ void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
img_overl->clip_right < x)
o = 0;
+ x2_scaled = SCALED_TO_INT((x + rle->len) * x_scale);
if (o && mask) {
- mem_blend16(dst_pix+x, my_clut[clr], o, rle->len);
+ mem_blend16(img_pix+x1_scaled, my_clut[clr], o, x2_scaled-x1_scaled);
}
+ x1_scaled = x2_scaled;
x += rle->len;
rle++;
if (rle >= rle_limit) break;
}
if (rle >= rle_limit) break;
- dst_pix += dst_width;
+
+ img_pix += img_width;
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
}
}
/* TODO: RGB color clut, only b/w now */
-void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
- int dst_height)
+/* TODO: RGB image shrinking (dy_step > 1.0) */
+void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl,
+ int img_width, int img_height,
+ int dst_width, int dst_height)
{
clut_t *my_clut;
uint8_t *my_trans;
@@ -140,20 +175,24 @@ void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
int src_height = img_overl->height;
rle_elem_t *rle = img_overl->rle;
rle_elem_t *rle_limit = rle + img_overl->num_rle;
- int x_off = img_overl->x;
- int y_off = img_overl->y;
- int mask;
- int x, y;
+ int x, y, x1_scaled, x2_scaled;
+ int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */
+ uint8_t *img_pix;
+
+ dy_step = INT_TO_SCALED(dst_height) / img_height;
+ x_scale = INT_TO_SCALED(img_width) / dst_width;
- uint8_t *dst_pix = img + (dst_width * y_off + x_off) * 3;
+ img_pix = img + 3 * ( (img_overl->y * img_height / dst_height) * img_width
+ + (img_overl->x * img_width / dst_width));
my_clut = (clut_t*) img_overl->color;
my_trans = img_overl->trans;
- for (y = 0; y < src_height; y++) {
- mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y);
+ for (dy = y = 0; y < src_height; ) {
+ int mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y);
+ rle_elem_t *rle_start = rle;
- for (x = 0; x < src_width;) {
+ for (x = x1_scaled = 0; x < src_width;) {
uint8_t clr;
uint16_t o;
@@ -164,23 +203,35 @@ void blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
img_overl->clip_right < x)
o = 0;
+ x2_scaled = SCALED_TO_INT((x + rle->len) * x_scale);
if (o && mask) {
uint8_t v = my_clut[clr].y;
- mem_blend24(dst_pix + x*3, v, v, v, o, rle->len);
+ mem_blend24(img_pix + x1_scaled*3, v, v, v, o, x2_scaled-x1_scaled);
}
+ x1_scaled = x2_scaled;
x += rle->len;
rle++;
if (rle >= rle_limit) break;
}
if (rle >= rle_limit) break;
- dst_pix += dst_width * 3;
+
+ img_pix += img_width * 3;
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
}
}
/* TODO: RGB color clut, only b/w now */
-void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
- int dst_height)
+/* TODO: RGB image shrinking (dy_step > 1.0) */
+void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl,
+ int img_width, int img_height,
+ int dst_width, int dst_height)
{
clut_t *my_clut;
uint8_t *my_trans;
@@ -188,20 +239,24 @@ void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
int src_height = img_overl->height;
rle_elem_t *rle = img_overl->rle;
rle_elem_t *rle_limit = rle + img_overl->num_rle;
- int x_off = img_overl->x;
- int y_off = img_overl->y;
- int mask;
- int x, y;
+ int x, y, x1_scaled, x2_scaled;
+ int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */
+ uint8_t *img_pix;
- uint8_t *dst_pix = img + (dst_width * y_off + x_off) * 4;
+ dy_step = INT_TO_SCALED(dst_height) / img_height;
+ x_scale = INT_TO_SCALED(img_width) / dst_width;
+
+ img_pix = img + 4 * ( (img_overl->y * img_height / dst_height) * img_width
+ + (img_overl->x * img_width / dst_width));
my_clut = (clut_t*) img_overl->color;
my_trans = img_overl->trans;
- for (y = 0; y < src_height; y++) {
- mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y);
+ for (y = dy = 0; y < src_height; ) {
+ int mask = !(img_overl->clip_top > y || img_overl->clip_bottom < y);
+ rle_elem_t *rle_start = rle;
- for (x = 0; x < src_width;) {
+ for (x = x1_scaled = 0; x < src_width;) {
uint8_t clr;
uint16_t o;
@@ -212,17 +267,27 @@ void blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int dst_width,
img_overl->clip_right < x)
o = 0;
+ x2_scaled = SCALED_TO_INT((x + rle->len) * x_scale);
if (o && mask) {
uint8_t v = my_clut[clr].y;
- mem_blend32(dst_pix + x*4, v, v, v, o, rle->len);
+ mem_blend32(img_pix + x1_scaled*4, v, v, v, o, x2_scaled-x1_scaled);
}
+ x1_scaled = x2_scaled;
x += rle->len;
rle++;
if (rle >= rle_limit) break;
}
if (rle >= rle_limit) break;
- dst_pix += dst_width * 4;
+
+ img_pix += img_width * 4;
+ dy += dy_step;
+ if (dy >= INT_TO_SCALED(1)) {
+ dy -= INT_TO_SCALED(1);
+ ++y;
+ } else {
+ rle = rle_start; /* y-scaling, reuse the last rle encoded line */
+ }
}
}
diff --git a/src/video_out/alphablend.h b/src/video_out/alphablend.h
index 66f4e512b..c973c59ed 100644
--- a/src/video_out/alphablend.h
+++ b/src/video_out/alphablend.h
@@ -35,15 +35,17 @@ typedef struct { /* CLUT == Color LookUp Table */
uint8_t foo : 8;
} __attribute__ ((packed)) clut_t;
-void blend_rgb16 (uint8_t * img, vo_overlay_t * overlay, int width,
- int height);
-void blend_rgb24 (uint8_t * img, vo_overlay_t * overlay, int width,
- int height);
-void blend_rgb32 (uint8_t * img, vo_overlay_t * overlay, int width,
- int height);
-void blend_yuv (uint8_t * img, vo_overlay_t * overlay, int width,
-
- int height);
+void blend_rgb16 (uint8_t * img, vo_overlay_t * overlay,
+ int img_width, int img_height,
+ int delivered_width, int delivered_height);
+void blend_rgb24 (uint8_t * img, vo_overlay_t * overlay,
+ int img_width, int img_height,
+ int delivered_iwdth, int delivered_height);
+void blend_rgb32 (uint8_t * img, vo_overlay_t * overlay,
+ int img_width, int img_height,
+ int delivered_iwdth, int delivered_height);
+void blend_yuv (uint8_t * img, vo_overlay_t * overlay,
+ int width, int height);
void crop_overlay (vo_overlay_t * overlay);
#endif
diff --git a/src/video_out/video_out_xshm.c b/src/video_out/video_out_xshm.c
index 4bc337406..56aa1c4a0 100644
--- a/src/video_out/video_out_xshm.c
+++ b/src/video_out/video_out_xshm.c
@@ -17,7 +17,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: video_out_xshm.c,v 1.41 2001/10/03 15:14:03 jkeil Exp $
+ * $Id: video_out_xshm.c,v 1.42 2001/10/09 09:50:22 jkeil Exp $
*
* video_out_xshm.c, X11 shared memory extension interface for xine
*
@@ -717,13 +717,19 @@ static void xshm_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo
if (overlay->rle) {
switch(this->bpp) {
case 16:
- blend_rgb16( (uint8_t *)frame->image->data, overlay, frame->rgb_width, frame->rgb_height);
+ blend_rgb16( (uint8_t *)frame->image->data, overlay,
+ frame->rgb_width, frame->rgb_height,
+ this->delivered_width, this->delivered_height);
break;
case 24:
- blend_rgb24( (uint8_t *)frame->image->data, overlay, frame->rgb_width, frame->rgb_height);
+ blend_rgb24( (uint8_t *)frame->image->data, overlay,
+ frame->rgb_width, frame->rgb_height,
+ this->delivered_width, this->delivered_height);
break;
case 32:
- blend_rgb32( (uint8_t *)frame->image->data, overlay, frame->rgb_width, frame->rgb_height);
+ blend_rgb32( (uint8_t *)frame->image->data, overlay,
+ frame->rgb_width, frame->rgb_height,
+ this->delivered_width, this->delivered_height);
break;
default:
/* It should never get here */