+static void cubic_interpolate_line( uint8_t *dst,
+ uint8_t *cur,
+ int plane,
+ int y,
+ hb_filter_private_t * pv )
+{
+ int w = pv->width[plane];
+ int refs = pv->ref_stride[plane];
+ int x;
+
+ for( x = 0; x < w; x++)
+ {
+ int a, b, c, d;
+ a = b = c = d = 0;
+
+ if( y >= 3 )
+ {
+ /* Normal top*/
+ a = cur[-3*refs];
+ b = cur[-refs];
+ }
+ else if( y == 2 || y == 1 )
+ {
+ /* There's only one sample above this pixel, use it twice. */
+ a = cur[-refs];
+ b = cur[-refs];
+ }
+ else if( y == 0 )
+ {
+ /* No samples above, triple up on the one below. */
+ a = cur[+refs];
+ b = cur[+refs];
+ }
+
+ if( y <= ( pv->height[plane] - 4 ) )
+ {
+ /* Normal bottom*/
+ c = cur[+refs];
+ d = cur[3*refs];
+ }
+ else if( y == ( pv->height[plane] - 3 ) || y == ( pv->height[plane] - 2 ) )
+ {
+ /* There's only one sample below, use it twice. */
+ c = cur[+refs];
+ d = cur[+refs];
+ }
+ else if( y == pv->height[plane] - 1)
+ {
+ /* No samples below, triple up on the one above. */
+ c = cur[-refs];
+ d = cur[-refs];
+ }
+
+ dst[0] = cubic_interpolate_pixel( a, b, c, d );
+
+ dst++;
+ cur++;
+ }
+}
+
+void apply_mask_line( uint8_t * srcp,
+ uint8_t * mskp,
+ int width )
+{
+ int x;
+
+ for( x = 0; x < width; x++ )
+ {
+ if( mskp[x] == 255 )
+ {
+ srcp[x] = 255;
+ }
+ }
+}
+
+void apply_mask( hb_filter_private_t * pv )
+{
+ int plane, height;
+
+ for( plane = 0; plane < 3; plane++ )
+ {
+ uint8_t * srcp = ( pv->mode & MODE_MCDEINT ) ? pv->pic_in.data[plane] : pv->pic_out.data[plane];
+ uint8_t * mskp = pv->mask[plane];
+
+ for( height = 0; height < pv->height[plane]; height++ )
+ {
+ if( pv->mode == MODE_MASK && plane == 0 )
+ {
+ memcpy( srcp, mskp, pv->width[plane] );
+ }
+ else if( pv->mode == MODE_MASK )
+ {
+ memset( srcp, 128, pv->width[plane] );
+ }
+ else if( plane == 0 )
+ {
+ apply_mask_line( srcp, mskp, pv->width[plane] );
+ }
+
+ srcp += pv->pic_out.linesize[plane];
+ mskp += pv->ref_stride[plane];
+ }
+ }
+}
+