summaryrefslogtreecommitdiffstats
path: root/libhb/render.c
diff options
context:
space:
mode:
authoreddyg <[email protected]>2007-08-20 23:16:07 +0000
committereddyg <[email protected]>2007-08-20 23:16:07 +0000
commita779f4bd446925e0d1b272de5f30d771c0401424 (patch)
tree92a5f8c6d18d1d9b9626168446f94273b27e1701 /libhb/render.c
parent9de34b8f91c322f99c00014ba18dc005a33b7a0e (diff)
Add colour/chroma to subtitles where they are not transparent.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@842 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/render.c')
-rw-r--r--libhb/render.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/libhb/render.c b/libhb/render.c
index a49bdfada..a8abd0e75 100644
--- a/libhb/render.c
+++ b/libhb/render.c
@@ -34,13 +34,33 @@ hb_work_object_t hb_render =
renderClose
};
+/*
+ * getU() & getV()
+ *
+ * Utility function that finds where the U is in the YUV sub-picture
+ *
+ * The Y data is at the top, followed by U and V, but the U and V
+ * are half the width of the Y, i.e. each chroma element covers 2x2
+ * of the Y's.
+ */
+static uint8_t *getU(uint8_t *data, int width, int height, int x, int y)
+{
+ return(&data[(((y/2) * (width/2)) + (x/2)) + (width*height)]);
+}
+
+static uint8_t *getV(uint8_t *data, int width, int height, int x, int y)
+{
+ return(&data[(((y/2) * (width/2)) + (x/2)) + (width*height) +
+ (width*height)/4]);
+}
+
static void ApplySub( hb_job_t * job, hb_buffer_t * buf,
hb_buffer_t ** _sub )
{
hb_buffer_t * sub = *_sub;
hb_title_t * title = job->title;
int i, j, offset_top, offset_left;
- uint8_t * lum, * alpha, * out;
+ uint8_t * lum, * alpha, * out, * sub_chromaU, * sub_chromaV;
if( !sub )
{
@@ -73,6 +93,9 @@ static void ApplySub( hb_job_t * job, hb_buffer_t * buf,
lum = sub->data;
alpha = lum + sub->width * sub->height;
+ sub_chromaU = alpha + sub->width * sub->height;
+ sub_chromaV = sub_chromaU + sub->width * sub->height;
+
out = buf->data + offset_top * title->width + offset_left;
for( i = 0; i < sub->height; i++ )
@@ -83,14 +106,40 @@ static void ApplySub( hb_job_t * job, hb_buffer_t * buf,
{
if( offset_left + j >= 0 && offset_left + j < title->width )
{
+ uint8_t *chromaU, *chromaV;
+
+ /*
+ * Merge the luminance and alpha with the picture
+ */
out[j] = ( (uint16_t) out[j] * ( 16 - (uint16_t) alpha[j] ) +
(uint16_t) lum[j] * (uint16_t) alpha[j] ) >> 4;
+ /*
+ * Set the chroma (colour) based on whether there is
+ * any alpha at all. Don't try to blend with the picture.
+ */
+ chromaU = getU(buf->data, title->width, title->height,
+ offset_left+j, offset_top+i);
+
+ chromaV = getV(buf->data, title->width, title->height,
+ offset_left+j, offset_top+i);
+
+ if( alpha[j] > 0 )
+ {
+ /*
+ * Add the chroma from the sub-picture, as this is
+ * not a transparent element.
+ */
+ *chromaU = sub_chromaU[j];
+ *chromaV = sub_chromaV[j];
+ }
}
}
}
lum += sub->width;
alpha += sub->width;
+ sub_chromaU += sub->width;
+ sub_chromaV += sub->width;
out += title->width;
}