+
+/** Get the image associated to the frame.
+ *
+ * You should express the desired format, width, and height as inputs. As long
+ * as the loader producer was used to generate this or the imageconvert filter
+ * was attached, then you will get the image back in the format you desire.
+ * However, you do not always get the width and height you request depending
+ * on properties and filters. You do not need to supply a pre-allocated
+ * buffer, but you should always supply the desired image format.
+ *
+ * \public \memberof mlt_frame_s
+ * \param self a frame
+ * \param[out] buffer an image buffer
+ * \param[in,out] format the image format
+ * \param[in,out] width the horizontal size in pixels
+ * \param[in,out] height the vertical size in pixels
+ * \param writable whether or not you will need to be able to write to the memory returned in \p buffer
+ * \return true if error
+ * \todo Better describe the width and height as inputs.
+ */
+
+int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
+{
+ mlt_properties properties = MLT_FRAME_PROPERTIES( self );
+ mlt_get_image get_image = mlt_frame_pop_get_image( self );
+ mlt_image_format requested_format = *format;
+ int error = 0;
+
+ if ( get_image )
+ {
+ mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 );
+ error = get_image( self, buffer, format, width, height, writable );
+ if ( !error && buffer && *buffer )
+ {
+ mlt_properties_set_int( properties, "width", *width );
+ mlt_properties_set_int( properties, "height", *height );
+ if ( self->convert_image && requested_format != mlt_image_none )
+ self->convert_image( self, buffer, format, requested_format );
+ mlt_properties_set_int( properties, "format", *format );
+ }
+ else
+ {
+ error = generate_test_image( properties, buffer, format, width, height, writable );
+ }
+ }
+ else if ( mlt_properties_get_data( properties, "image", NULL ) && buffer )
+ {
+ *format = mlt_properties_get_int( properties, "format" );
+ *buffer = mlt_properties_get_data( properties, "image", NULL );
+ *width = mlt_properties_get_int( properties, "width" );
+ *height = mlt_properties_get_int( properties, "height" );
+ if ( self->convert_image && *buffer && requested_format != mlt_image_none )
+ {
+ self->convert_image( self, buffer, format, requested_format );
+ mlt_properties_set_int( properties, "format", *format );
+ }
+ }
+ else
+ {
+ error = generate_test_image( properties, buffer, format, width, height, writable );
+ }
+
+ return error;
+}
+
+/** Get the alpha channel associated to the frame.
+ *
+ * \public \memberof mlt_frame_s
+ * \param self a frame
+ * \return the alpha channel
+ */
+
+uint8_t *mlt_frame_get_alpha_mask( mlt_frame self )
+{
+ uint8_t *alpha = NULL;
+ if ( self != NULL )
+ {
+ if ( self->get_alpha_mask != NULL )
+ alpha = self->get_alpha_mask( self );
+ if ( alpha == NULL )
+ alpha = mlt_properties_get_data( &self->parent, "alpha", NULL );
+ if ( alpha == NULL )
+ {
+ int size = mlt_properties_get_int( &self->parent, "width" ) * mlt_properties_get_int( &self->parent, "height" );
+ alpha = mlt_pool_alloc( size );
+ memset( alpha, 255, size );
+ mlt_properties_set_data( &self->parent, "alpha", alpha, size, mlt_pool_release, NULL );
+ }
+ }
+ return alpha;
+}
+
+/** Get the short name for an audio format.
+ *
+ * You do not need to deallocate the returned string.
+ * \public \memberof mlt_frame_s
+ * \param format an audio format enum
+ * \return a string for the name of the image format
+ */
+
+const char * mlt_audio_format_name( mlt_audio_format format )
+{
+ switch ( format )
+ {
+ case mlt_audio_none: return "none";
+ case mlt_audio_s16: return "s16";
+ case mlt_audio_s32: return "s32";
+ case mlt_audio_s32le: return "s32le";
+ case mlt_audio_float: return "float";
+ case mlt_audio_f32le: return "f32le";
+ case mlt_audio_u8: return "u8";
+ }
+ return "invalid";