* src/misc/image.c: implemented ImageConvert().
authorGildas Bazin <gbazin@videolan.org>
Tue, 21 Dec 2004 14:45:51 +0000 (14:45 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 21 Dec 2004 14:45:51 +0000 (14:45 +0000)
include/vlc_image.h
src/misc/image.c

index 9180781..63f5964 100644 (file)
@@ -36,11 +36,14 @@ struct image_handler_t
                              video_format_t *, video_format_t * );
     picture_t * (*pf_read_url) ( image_handler_t *, const char *,
                                  video_format_t *, video_format_t * );
-    block_t* (*pf_write) ( image_handler_t *, picture_t *,
-                           video_format_t *, video_format_t * );
+    block_t * (*pf_write) ( image_handler_t *, picture_t *,
+                            video_format_t *, video_format_t * );
     int (*pf_write_url) ( image_handler_t *, picture_t *,
                           video_format_t *, video_format_t *, const char * );
 
+    picture_t * (*pf_convert) ( image_handler_t *, picture_t *,
+                                video_format_t *, video_format_t * );
+
     /* Private properties */
     vlc_object_t *p_parent;
     decoder_t *p_dec;
@@ -56,6 +59,7 @@ VLC_EXPORT( void, image_HandlerDelete, ( image_handler_t * ) );
 #define image_ReadUrl( a, b, c, d ) a->pf_read_url( a, b, c, d )
 #define image_Write( a, b, c, d ) a->pf_write( a, b, c, d )
 #define image_WriteUrl( a, b, c, d, e ) a->pf_write_url( a, b, c, d, e )
+#define image_Convert( a, b, c, d ) a->pf_convert( a, b, c, d )
 
 # ifdef __cplusplus
 }
index 287285e..37511e6 100644 (file)
@@ -44,6 +44,9 @@ static block_t *ImageWrite( image_handler_t *, picture_t *,
 static int ImageWriteUrl( image_handler_t *, picture_t *,
                           video_format_t *, video_format_t *, const char * );
 
+static picture_t *ImageConvert( image_handler_t *, picture_t *,
+                                video_format_t *, video_format_t * );
+
 static decoder_t *CreateDecoder( vlc_object_t *, video_format_t * );
 static void DeleteDecoder( decoder_t * );
 static encoder_t *CreateEncoder( vlc_object_t *, video_format_t *,
@@ -71,6 +74,7 @@ image_handler_t *__image_HandlerCreate( vlc_object_t *p_this )
     p_image->pf_read_url = ImageReadUrl;
     p_image->pf_write = ImageWrite;
     p_image->pf_write_url = ImageWriteUrl;
+    p_image->pf_convert = ImageConvert;
 
     return p_image;
 }
@@ -341,6 +345,70 @@ static int ImageWriteUrl( image_handler_t *p_image, picture_t *p_pic,
 }
 
 /**
+ * Convert an image to a different format
+ *
+ */
+
+static picture_t *ImageConvert( image_handler_t *p_image, picture_t *p_pic,
+                                video_format_t *p_fmt_in,
+                                video_format_t *p_fmt_out )
+{
+    void (*pf_release)( picture_t * );
+    picture_t *p_pif;
+
+    if( !p_fmt_out->i_chroma ) p_fmt_out->i_chroma = p_fmt_in->i_chroma;
+    if( !p_fmt_out->i_width ) p_fmt_out->i_width = p_fmt_in->i_width;
+    if( !p_fmt_out->i_height ) p_fmt_out->i_height = p_fmt_in->i_height;
+
+    if( p_image->p_filter )
+    if( p_image->p_filter->fmt_in.video.i_chroma != p_fmt_in->i_chroma ||
+        p_image->p_filter->fmt_out.video.i_chroma != p_fmt_out->i_chroma )
+    {
+        /* We need to restart a new filter */
+        DeleteFilter( p_image->p_filter );
+        p_image->p_filter = 0;
+    }
+
+    /* Start a filter */
+    if( !p_image->p_filter )
+    {
+        es_format_t fmt_in;
+        es_format_Init( &fmt_in, VIDEO_ES, p_fmt_in->i_chroma );
+        fmt_in.video = *p_fmt_in;
+
+        p_image->p_filter =
+            CreateFilter( p_image->p_parent, &fmt_in, p_fmt_out );
+
+        if( !p_image->p_filter )
+        {
+            return NULL;
+        }
+    }
+    else
+    {
+        /* Filters should handle on-the-fly size changes */
+        p_image->p_filter->fmt_in.video = *p_fmt_in;
+        p_image->p_filter->fmt_out.video = *p_fmt_out;
+    }
+
+    pf_release = p_pic->pf_release;
+    p_pic->pf_release = PicRelease; /* Small hack */
+    p_pif = p_image->p_filter->pf_video_filter( p_image->p_filter, p_pic );
+    p_pic->pf_release = pf_release;
+
+    if( p_fmt_in->i_chroma == p_fmt_out->i_chroma &&
+        p_fmt_in->i_width == p_fmt_out->i_width &&
+        p_fmt_in->i_height == p_fmt_out->i_height )
+    {
+        /* Duplicate image */
+        p_pif = p_image->p_filter->pf_vout_buffer_new( p_image->p_filter );
+        if( p_pif ) vout_CopyPicture( p_image->p_parent, p_pif, p_pic );
+    }
+
+    return p_pif;
+}
+
+/**
  * Misc functions
  *
  */