[vlc-devel] [PATCH 1/2] Sepia video filter

Laurent Aimar fenrir at elivagar.org
Sun Nov 28 13:55:35 CET 2010


Hi,

On Sat, Nov 27, 2010 at 07:07:31PM +0100, Branko Kokanovic wrote:
> here is updated version (just first patch). It's my fault I didn't know
> about blend.c. I mostly changed everything Laurent said, except
> iteration through frames.
 Could you move the code you reused from blend.c to a common header?
(in a independant patch). Duplicating code is not a good thing.

> >From c2335cfadd41aadcf4fbe96c4f759470fff3e431 Mon Sep 17 00:00:00 2001
> From: Branko Kokanovic <branko.kokanovic at gmail.com>
> Date: Mon, 15 Nov 2010 20:20:14 +0100
> Subject: [PATCH 1/2] Sepia video filter
> 
> diff --git a/modules/video_filter/sepia.c b/modules/video_filter/sepia.c
> new file mode 100644
> index 0000000..7067023
> --- /dev/null
> +++ b/modules/video_filter/sepia.c
> @@ -0,0 +1,554 @@
> +#ifdef HAVE_CONFIG_H
> +# include "config.h"
> +#endif
> +
> +#include <vlc_common.h>
> +#include <vlc_plugin.h>
> +
> +#include <assert.h>
> +#include <vlc_filter.h>
> +#include "filter_picture.h"
> +
> +/*****************************************************************************
> + * Local prototypes
> + *****************************************************************************/
> +static int  Create      ( vlc_object_t * );
> +static void Destroy     ( vlc_object_t * );
> +
> +static void vlc_rgb_index( int *, int *, int *, const video_format_t * );
> +static void RVSepia( picture_t *, picture_t *, int );
> +static void PlanarI420Sepia( picture_t *, picture_t *, int);
> +static void PackedYUVSepia( picture_t *, picture_t *, int);
> +static void YuvSepia( uint8_t *, uint8_t *, uint8_t *, uint8_t *,
> +                    uint8_t, uint8_t, uint8_t, uint8_t, int );
> +static void Sepia( int *, int *, int *, int );
> +static picture_t *Filter( filter_t *, picture_t * );
> +
> +static const char *const ppsz_filter_options[] = {
> +    "intensity", NULL
> +};
> +
> +/*****************************************************************************
> + * Module descriptor
> + *****************************************************************************/
> +#define SEPIA_INTENSITY_TEXT N_("Sepia intensity")
> +#define SEPIA_INTENSITY_LONGTEXT N_("Intensity of sepia effect" )
> +
> +#define CFG_PREFIX "sepia-"
> +
> +vlc_module_begin ()
> +    set_description( N_("Sepia video filter") )
> +    set_shortname( N_("Sepia" ) )
> +    set_help( N_("Gives video a warmer tone by applying sepia effect") )
> +    set_category( CAT_VIDEO )
> +    set_subcategory( SUBCAT_VIDEO_VFILTER )
> +    set_capability( "video filter2", 0 )
> +    add_integer_with_range( CFG_PREFIX "intensity", 30, 0, 255, NULL,
> +                           SEPIA_INTENSITY_TEXT, SEPIA_INTENSITY_LONGTEXT,
> +                           false )
> +    set_callbacks( Create, Destroy )
> +vlc_module_end ()
> +
> +/*****************************************************************************
> + * callback prototypes
> + *****************************************************************************/
> +static int FilterCallback( vlc_object_t *, char const *,
> +                           vlc_value_t, vlc_value_t, void * );
> +
> +/*****************************************************************************
> + * filter_sys_t: adjust filter method descriptor
> + *****************************************************************************/
> +struct filter_sys_t
> +{
> +    int i_sepia_cfg;
 Storing directly SepiaFunction will simplify a bit the code.
> +    int i_intensity;
> +    vlc_spinlock_t lock;
> +};
> +
> +typedef void (*SepiaFunction)( picture_t *, picture_t *, int );
> +
> +static const struct
> +{
> +    vlc_fourcc_t i_chroma;
> +    SepiaFunction pf_sepia;
> +} p_sepia_cfg[] = {
> +    { VLC_CODEC_I420, PlanarI420Sepia },
> +    { VLC_CODEC_RGB24, RVSepia },
> +    { VLC_CODEC_RGB32, RVSepia },
> +    { VLC_CODEC_UYVY, PackedYUVSepia },
> +    { VLC_CODEC_CYUV, PackedYUVSepia },
 Are you sure it is CYUV and not VLC_CODEC_VYUY? 
> +    { VLC_CODEC_YUYV, PackedYUVSepia },
> +    { VLC_CODEC_YVYU, PackedYUVSepia },
> +    { 0, NULL }
> +};

> +/*****************************************************************************
> + * Create: allocates Sepia video thread output method
> + *****************************************************************************
> + * This function allocates and initializes a Sepia vout method.
> + *****************************************************************************/
> +static int Create( vlc_object_t *p_this )
> +{
> +    filter_t *p_filter = (filter_t *)p_this;
> +    filter_sys_t *p_sys;
> +
> +    /* Allocate structure */
> +    p_sys = p_filter->p_sys = malloc( sizeof( filter_sys_t ) );
> +    if( p_filter->p_sys == NULL )
> +        return VLC_ENOMEM;
> +
> +    p_sys->i_sepia_cfg = -1;
> +
> +    for( int i = 0; p_sepia_cfg[i].i_chroma != 0; i++ )
> +    {
> +        if( p_sepia_cfg[i].i_chroma != p_filter->fmt_in.video.i_chroma )
> +            continue;
> +        p_sys->i_sepia_cfg = i;
> +    }
> +
> +    if( p_sys->i_sepia_cfg == -1 )
> +    {
> +        msg_Err( p_filter, "Unsupported input chroma (%4.4s)",
> +                (char*)&(p_filter->fmt_in.video.i_chroma) );
> +        free( p_sys );
> +        return VLC_EGENERIC;
> +    }
> +
> +    if( p_filter->fmt_in.video.i_chroma != p_filter->fmt_out.video.i_chroma )
 As you have a priority of 0, this test is not needed.
> +    {
> +        msg_Err( p_filter, "Input and output chromas don't match" );
> +        return VLC_EGENERIC;
> +    }
> +
> +    config_ChainParse( p_filter, CFG_PREFIX, ppsz_filter_options,
> +                       p_filter->p_cfg );
> +    p_sys->i_intensity= var_CreateGetIntegerCommand( p_filter,
> +                       CFG_PREFIX "intensity" );
> +
> +    vlc_spin_init( &p_sys->lock );
> +
> +    var_AddCallback( p_filter, CFG_PREFIX "intensity", FilterCallback, NULL );
> +
> +    p_filter->pf_video_filter = Filter;
> +
> +    return VLC_SUCCESS;
> +}
> +
> +/*****************************************************************************
> + * Destroy: destroy sepia video thread output method
> + *****************************************************************************
> + * Terminate an output method
> + *****************************************************************************/
> +static void Destroy( vlc_object_t *p_this )
> +{
> +    filter_t *p_filter = (filter_t *)p_this;
> +
> +    var_DelCallback( p_filter, CFG_PREFIX "intensity", FilterCallback, NULL );
> +
> +    vlc_spin_destroy( &p_filter->p_sys->lock );
> +    free( p_filter->p_sys );
> +}
> +
> +/*****************************************************************************
> + * Render: displays previously rendered output
> + *****************************************************************************
> + * This function send the currently rendered image to sepia image, waits
> + * until it is displayed and switch the two rendering buffers, preparing next
> + * frame.
> + *****************************************************************************/
> +static picture_t *Filter( filter_t *p_filter, picture_t *p_pic )
> +{
> +    picture_t *p_outpic;
> +    int intensity;
> +
> +    if( !p_pic ) return NULL;
> +
> +    filter_sys_t *p_sys = p_filter->p_sys;
> +    vlc_spin_lock( &p_sys->lock );
> +    intensity = p_sys->i_intensity;
> +    vlc_spin_unlock( &p_sys->lock );
> +
> +    p_outpic = filter_NewPicture( p_filter );
> +    if( !p_outpic )
> +    {
> +        msg_Warn( p_filter, "can't get output picture" );
> +        picture_Release( p_pic );
> +        return NULL;
> +    }
> +
> +    p_sepia_cfg[p_sys->i_sepia_cfg].pf_sepia( p_pic, p_outpic, intensity );
> +
> +    return CopyInfoAndRelease( p_outpic, p_pic );
> +}
> +
> +/***********************************************************************
> + * Utils
> + ***********************************************************************/
> +static inline uint8_t vlc_uint8( int v )
> +{
> +    if( v > 255 )
> +        return 255;
> +    else if( v < 0 )
> +        return 0;
> +    return v;
> +}
> +
> +static inline void yuv_to_rgb( int *r, int *g, int *b,
> +                               uint8_t y1, uint8_t u1, uint8_t v1 )
> +{
> +    /* macros used for YUV pixel conversions */
> +#   define SCALEBITS 10
> +#   define ONE_HALF  (1 << (SCALEBITS - 1))
> +#   define FIX(x)    ((int) ((x) * (1<<SCALEBITS) + 0.5))
> +
> +    int y, cb, cr, r_add, g_add, b_add;
> +
> +    cb = u1 - 128;
> +    cr = v1 - 128;
> +    r_add = FIX(1.40200*255.0/224.0) * cr + ONE_HALF;
> +    g_add = - FIX(0.34414*255.0/224.0) * cb
> +            - FIX(0.71414*255.0/224.0) * cr + ONE_HALF;
> +    b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;
> +    y = (y1 - 16) * FIX(255.0/219.0);
> +    *r = vlc_uint8( (y + r_add) >> SCALEBITS );
> +    *g = vlc_uint8( (y + g_add) >> SCALEBITS );
> +    *b = vlc_uint8( (y + b_add) >> SCALEBITS );
> +#undef FIX
> +#undef ONE_HALF
> +#undef SCALEBITS
> +}
> +
> +static void vlc_rgb_index( int *pi_rindex, int *pi_gindex, int *pi_bindex,
> +                           const video_format_t *p_fmt )
> +{
> +    if( p_fmt->i_chroma != VLC_CODEC_RGB24 && p_fmt->i_chroma != VLC_CODEC_RGB32 )
> +        return;
> +
> +    /* XXX it will works only if mask are 8 bits aligned */
> +#ifdef WORDS_BIGENDIAN
> +    const int i_mask_bits = p_fmt->i_chroma == VLC_CODEC_RGB24 ? 24 : 32;
> +    *pi_rindex = ( i_mask_bits - p_fmt->i_lrshift ) / 8;
> +    *pi_gindex = ( i_mask_bits - p_fmt->i_lgshift ) / 8;
> +    *pi_bindex = ( i_mask_bits - p_fmt->i_lbshift ) / 8;
> +#else
> +    *pi_rindex = p_fmt->i_lrshift / 8;
> +    *pi_gindex = p_fmt->i_lgshift / 8;
> +    *pi_bindex = p_fmt->i_lbshift / 8;
> +#endif
> +}
> +
> +/*****************************************************************************
> + * PlanarI420Sepia: Applies sepia to one frame of the planar I420 video
> + *****************************************************************************
> + * This function applies sepia effect to one frame of the video by iterating
> + * through video lines. In every pass, start of Y, U and V planes is calculated
> + * and for every pixel we calculate new values of YUV values.
> + *****************************************************************************/
> +static void PlanarI420Sepia( picture_t *p_pic, picture_t *p_outpic,
> +                               int i_intensity )
> +{
> +    uint8_t *p_in_y, *p_in_u, *p_in_v, *p_in_end_y, *p_line_end_y, *p_out_y,
> +            *p_out_u, *p_out_v;
> +    int i_current_line = 0;
> +
> +    p_in_y = p_pic->p[Y_PLANE].p_pixels;
> +    p_in_end_y = p_in_y + p_pic->p[Y_PLANE].i_visible_lines
> +        * p_pic->p[Y_PLANE].i_pitch;
> +    p_out_y = p_outpic->p[Y_PLANE].p_pixels;
> +
> +    /* iterate for every visible line in the frame */
> +    while( p_in_y < p_in_end_y )
> +    {
> +        p_line_end_y = p_in_y + p_pic->p[Y_PLANE].i_visible_pitch;
> +        /* calculate start of U plane line */
> +        p_in_u = p_pic->p[U_PLANE].p_pixels
> +            + p_pic->p[U_PLANE].i_pitch * ( i_current_line / 2 );
> +        p_out_u = p_outpic->p[U_PLANE].p_pixels
> +            + p_outpic->p[U_PLANE].i_pitch * ( i_current_line / 2 );
> +        /* calculate start of V plane line */
> +        p_in_v = p_pic->p[V_PLANE].p_pixels
> +            + p_pic->p[V_PLANE].i_pitch * ( i_current_line / 2 );
> +        p_out_v = p_outpic->p[V_PLANE].p_pixels
> +            + p_outpic->p[V_PLANE].i_pitch * ( i_current_line / 2 );
> +        /* iterate for every two pixels in line */
> +        while( p_in_y < p_line_end_y )
> +        {
> +            uint8_t y1, y2, u, v;
> +            uint8_t sepia_y1, sepia_y2, sepia_u, sepia_v;
> +            /* retrieve original YUV values */
> +            y1 = *p_in_y++;
> +            y2 = *p_in_y++;
> +            u = *p_in_u++;
> +            v = *p_in_v++;
> +            /* calculate new, sepia values */
> +            YuvSepia( &sepia_y1, &sepia_y2, &sepia_u, &sepia_v,
> +                     y1, y2, u, v, i_intensity );
> +            /* put new values */
> +            *p_out_y++ = sepia_y1;
> +            *p_out_y++ = sepia_y2;
> +            *p_out_u++ = sepia_u;
> +            *p_out_v++ = sepia_v;
> +        }
> +        p_in_y += p_pic->p[Y_PLANE].i_pitch
> +            - p_pic->p[Y_PLANE].i_visible_pitch;
> +        p_out_y += p_outpic->p[Y_PLANE].i_pitch
> +            - p_outpic->p[Y_PLANE].i_visible_pitch;
> +        i_current_line++;
> +    }
 You still work on the chroma twice (but do not correctly sum it). You need to read
2x2 Y pixels for 1 U and 1 V (well if you accept aliased chroma, otherwise you would
need to interpolate U and V for each Y). Something like should work:

for( int y = 0; y < p_pic->p[Y_PLANE].i_visible_lines - 1; y += 2)
{
	for( int x = 0; x < p_pic->p[Y_PLANE].i_visible_pitch - 1; x += 2)
	{
		const int su = p_pic->p[U_PLANE].p_pixels[(y/2) * p_pic->p[U_PLANE].i_pitch + (x/2)];
		const int sv = p_pic->p[V_PLANE].p_pixels[(y/2) * p_pic->p[V_PLANE].i_pitch + (x/2)];
		int du = 0, dv = 0;
		for( int dy = 0; dy < 2; dy++ )
		{
			/* Compute each (y1, y2) and save them, accumate u and v into du/dv */
		}
		p_outpic->p[U_PLANE].p_pixels[(y/2) * p_outpic->p[U_PLANE].i_pitch + (x/2)] = (du + 1 ) >> 1;
		p_outpic->p[V_PLANE].p_pixels[(y/2) * p_outpic->p[V_PLANE].i_pitch + (x/2)] = (dv + 1 ) >> 1;
	}
}

> +/*****************************************************************************
> + * PackedYUVSepia: Applies sepia to one frame of the packed YUV video
> + *****************************************************************************
> + * This function applies sepia effext to one frame of the video by iterating
> + * through video lines. In every pass, we calculate new values for pixels
> + * (UYVY, VYUY, YUYV and YVYU formats are supported)
> + *****************************************************************************/
> +static void PackedYUVSepia( picture_t *p_pic, picture_t *p_outpic,
> +                           int i_intensity )
> +{
> +    uint8_t *p_in, *p_in_end, *p_line_start, *p_line_end, *p_out;
> +    uint8_t y1 = 16, y2 = 16, u = 128, v = 128;
> +
> +    p_in = p_pic->p[0].p_pixels;
> +    p_in_end = p_in + p_pic->p[0].i_visible_lines
> +        * p_pic->p[0].i_pitch;
> +    p_out = p_outpic->p[0].p_pixels;
> +
> +    while( p_in < p_in_end )
> +    {
> +        p_line_start = p_in;
> +        p_line_end = p_in + p_pic->p[0].i_visible_pitch;
> +        while( p_in < p_line_end )
> +        {
> +            uint8_t sepia_y1, sepia_y2, sepia_u, sepia_v;
> +            /* extract proper pixel values */
> +            switch( p_pic->format.i_chroma )
> +            {
> +                case VLC_CODEC_UYVY:
> +                    u = *p_in++;
> +                    y1 = *p_in++;
> +                    v = *p_in++;
> +                    y2 = *p_in++;
> +                    break;
> +                case VLC_CODEC_VYUY:
> +                    v = *p_in++;
> +                    y1 = *p_in++;
> +                    u = *p_in++;
> +                    y2 = *p_in++;
> +                    break;
> +                case VLC_CODEC_YUYV:
> +                    y1 = *p_in++;
> +                    u = *p_in++;
> +                    y2 = *p_in++;
> +                    v = *p_in++;
> +                    break;
> +                case VLC_CODEC_YVYU:
> +                    y1 = *p_in++;
> +                    v = *p_in++;
> +                    y2 = *p_in++;
> +                    u = *p_in++;
> +                    break;
> +                default:
> +                    assert( false );
> +            }
 Calling vlc_yuv_packed_index() at the start of the function and then using
the provided index will simplify the code:

vlc_yuv_packed_index(&i_idx_y, &i_idx_u, &i_idx_v);

YuvSepia(&p_out[i_idx_y+0], &p_out[i_idx_y+2], &p_out[i_idx_u], &p_out[i_idx_v],
	 &p_in[i_idx_y+0], &p_in[i_idx_y+2], &p_in[i_idx_u], &p_in[i_idx_v]);
p_out += 4;
p_in  += 4;

> +            /* calculate new, sepia values */
> +            YuvSepia( &sepia_y1, &sepia_y2, &sepia_u, &sepia_v,
> +                     y1, y2, u, v, i_intensity );
> +            /* put new values in proper place */
> +            switch( p_pic->format.i_chroma )
> +            {
> +                case VLC_CODEC_UYVY:
> +                    *p_out++ = sepia_u;
> +                    *p_out++ = sepia_y1;
> +                    *p_out++ = sepia_v;
> +                    *p_out++ = sepia_y2;
> +                    break;
> +                case VLC_CODEC_VYUY:
> +                    *p_out++ = sepia_v;
> +                    *p_out++ = sepia_y1;
> +                    *p_out++ = sepia_u;
> +                    *p_out++ = sepia_y2;
> +                    break;
> +                case VLC_CODEC_YUYV:
> +                    *p_out++ = sepia_y1;
> +                    *p_out++ = sepia_u;
> +                    *p_out++ = sepia_y2;
> +                    *p_out++ = sepia_v;
> +                    break;
> +                case VLC_CODEC_YVYU:
> +                    *p_out++ = sepia_y1;
> +                    *p_out++ = sepia_v;
> +                    *p_out++ = sepia_y2;
> +                    *p_out++ = sepia_u;
> +                    break;
> +                default:
> +                    assert( false );
> +            }
> +        }
> +        p_in += p_pic->p[0].i_pitch - p_pic->p[0].i_visible_pitch;
> +        p_out += p_outpic->p[0].i_pitch
> +            - p_outpic->p[0].i_visible_pitch;
> +    }
> +}

> +
> +/*****************************************************************************
> + * RVSepia: Applies sepia to one frame of the RV24/RV32 video
> + *****************************************************************************
> + * This function applies sepia effect to one frame of the video by iterating
> + * through video lines and calculating new values for every byte in chunks of
> + * 3 (RV24) or 4 (RV32) bytes.
> + *****************************************************************************/
> +static void RVSepia( picture_t *p_pic, picture_t *p_outpic, int i_intensity )
> +{
> +    uint8_t *p_in, *p_in_end, *p_line_start, *p_line_end, *p_out;
> +    int i_r, i_g, i_b;
> +    bool b_isRV32 = p_pic->format.i_chroma == VLC_CODEC_RGB32;
> +    int i_rindex = 0, i_gindex = 1, i_bindex = 2;
> +
> +    vlc_rgb_index( &i_rindex, &i_gindex, &i_bindex, &p_outpic->format );
> +
> +    p_in = p_pic->p[0].p_pixels;
> +    p_in_end = p_in + p_pic->p[0].i_visible_lines
> +        * p_pic->p[0].i_pitch;
> +    p_out = p_outpic->p[0].p_pixels;
> +
> +    while( p_in < p_in_end )
> +    {
> +        p_line_start = p_in;
> +        p_line_end = p_in + p_pic->p[0].i_visible_pitch;
> +        while( p_in < p_line_end )
> +        {
> +            /* extract r,g,b values */
> +            i_r = p_in[i_rindex];
> +            i_g = p_in[i_gindex];
> +            i_b = p_in[i_bindex];
> +            p_in += 3;
> +            /* do sepia */
> +            Sepia( &i_r, &i_g, &i_b, i_intensity );
> +            /* put new r,g,b values */
> +            p_out[i_rindex] = i_r;
> +            p_out[i_gindex] = i_g;
> +            p_out[i_bindex] = i_b;
> +            p_out += 3;
> +            /* for rv32 we take 4 chunks at the time */
> +            if ( b_isRV32 )
> +            {
> +                /* alpha channel stays the same */
> +                *p_out++ = *p_in++;
> +            }
> +        }
> +        p_in += p_pic->p[0].i_pitch - p_pic->p[0].i_visible_pitch;
> +        p_out += p_outpic->p[0].i_pitch
> +            - p_outpic->p[0].i_visible_pitch;
> +    }
> +}
> +
> +/*****************************************************************************
> + * YuvSepia: Calculates sepia to YUV values
> + *****************************************************************************
> + * This function calculates sepia values of YUV color space for a given sepia
> + * intensity. It converts YUV color values to theirs RGB equivalents,
> + * calculates sepia values and then converts RGB values to YUV values again.
> + *****************************************************************************/
> +static void YuvSepia( uint8_t* sepia_y1, uint8_t* sepia_y2,
> +                             uint8_t* sepia_u, uint8_t* sepia_v,
> +                             uint8_t y1, uint8_t y2, uint8_t u, uint8_t v,
> +                             int i_intensity )
> +{
> +    int r1, g1, b1; /* for y1 new value */
> +    int r2, b2, g2; /* for y2 new value */
> +    int r3, g3, b3; /* for new values of u and v */
> +    /* fist convert YUV -> RGB */
> +    yuv_to_rgb( &r1, &g1, &b1, y1, u, v );
> +    yuv_to_rgb( &r2, &g2, &b2, y2, u, v );
> +    yuv_to_rgb( &r3, &g3, &b3, ( y1 + y2 ) / 2, u, v );
> +    /* calculates new values for r, g and b components */
> +    Sepia( &r1, &g1, &b1, i_intensity );
> +    Sepia( &r2, &g2, &b2, i_intensity );
> +    Sepia( &r3, &g3, &b3, i_intensity );
> +    /* convert from calculated RGB -> YUV */
> +    *sepia_y1 = ( ( 66 * r1 + 129 * g1 +  25 * b1 + 128 ) >> 8 ) +  16;
> +    *sepia_y2 = ( ( 66 * r2 + 129 * g2 +  25 * b2 + 128 ) >> 8 ) +  16;
> +    *sepia_u = ( ( -38 * r3 -  74 * g3 + 112 * b3 + 128 ) >> 8 ) + 128;
> +    *sepia_v = ( ( 112 * r3 -  94 * g3 -  18 * b3 + 128 ) >> 8 ) + 128;
 I think (but unsure) that you can avoid computing r/g/b3, and simply
average r/g/b12 (It is true if Sepia() is linear).

> +/*****************************************************************************
> + * Sepia: Calculates sepia of RGB values
> + *****************************************************************************
> + * This function calculates sepia values of RGB color space for a given sepia
> + * intensity. Sepia algorithm is taken from here:
> + * http://groups.google.com/group/comp.lang.java.programmer/browse_thread/
> + *   thread/9d20a72c40b119d0/18f12770ec6d9dd6
> + *****************************************************************************/
> +static void Sepia( int *p_r, int *p_g, int *p_b, int i_intensity )
> +{
> +    int16_t i_sepia_r, i_sepia_g, i_sepia_b, i_round;
> +    int i_sepia_depth = 20;
> +    i_round = ( *p_r + *p_g + *p_b ) / 3;
> +    i_sepia_r = i_round + ( i_sepia_depth * 2 );
> +    if ( i_sepia_r > 255 )
> +    {
> +        i_sepia_r = 255;
> +    }
> +    i_sepia_g = i_round + i_sepia_depth;
> +    if ( i_sepia_g > 255 )
> +    {
> +        i_sepia_g = 255;
> +    }
> +    i_sepia_b = i_round - i_intensity;
> +    if ( i_sepia_b < 0 )
> +    {
> +        i_sepia_b = 0;
> +    }
> +    else if ( i_sepia_b > 255 )
> +    {
> +        i_sepia_b = 255;
> +    }
 You can reuse vlc_uint8().
> +    *p_r = i_sepia_r;
> +    *p_g = i_sepia_g;
> +    *p_b = i_sepia_b;
> +}

Regards,

-- 
fenrir



More information about the vlc-devel mailing list