2 * producer_sdl_image.c -- Image loader which wraps SDL_image
3 * Copyright (C) 2005 Visual Media FX
4 * Author: Charles Yates <charles.yates@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "producer_sdl_image.h"
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_pool.h>
28 #include <sys/types.h>
34 #include <SDL_image.h>
36 static int producer_get_image( mlt_frame frame
, uint8_t **image
, mlt_image_format
*format
, int *width
, int *height
, int writable
)
38 mlt_properties properties
= MLT_FRAME_PROPERTIES( frame
);
39 SDL_Surface
*surface
= mlt_properties_get_data( properties
, "surface", NULL
);
44 *format
= mlt_image_yuv422
;
45 *image
= mlt_pool_alloc( *width
* *height
* 2 );
46 alpha
= mlt_pool_alloc( *width
* *height
);
48 switch( surface
->format
->BitsPerPixel
)
51 mlt_convert_rgb24a_to_yuv422( surface
->pixels
, *width
, *height
, surface
->pitch
, *image
, alpha
);
54 mlt_convert_rgb24_to_yuv422( surface
->pixels
, *width
, *height
, surface
->pitch
, *image
);
55 memset( alpha
, 255, *width
* *height
);
62 mlt_properties_set_data( properties
, "image", *image
, *width
* *height
* 2, mlt_pool_release
, NULL
);
63 mlt_properties_set_data( properties
, "alpha", alpha
, *width
* *height
, mlt_pool_release
, NULL
);
64 mlt_properties_set_int( properties
, "width", *width
);
65 mlt_properties_set_int( properties
, "height", *height
);
70 static int filter_files( const struct dirent
*de
)
72 return de
->d_name
[ 0 ] != '.';
75 static mlt_properties
parse_file_names( char *resource
)
77 mlt_properties properties
= mlt_properties_new( );
79 if ( strstr( resource
, "/.all." ) != NULL
)
81 char *dir_name
= strdup( resource
);
82 char *extension
= strrchr( resource
, '.' );
83 *( strstr( dir_name
, "/.all." ) + 1 ) = '\0';
84 char fullname
[ 1024 ];
85 strcpy( fullname
, dir_name
);
86 struct dirent
**de
= NULL
;
87 int n
= scandir( fullname
, &de
, filter_files
, alphasort
);
91 for (i
= 0; i
< n
; i
++ )
93 snprintf( fullname
, 1023, "%s%s", dir_name
, de
[i
]->d_name
);
94 if ( strstr( fullname
, extension
) && lstat( fullname
, &info
) == 0 &&
95 ( S_ISREG( info
.st_mode
) || info
.st_mode
| S_IXUSR
) )
98 sprintf( temp
, "%d", i
);
99 mlt_properties_set( properties
, temp
, fullname
);
109 mlt_properties_set( properties
, "0", resource
);
115 static SDL_Surface
*load_image( mlt_producer producer
)
117 mlt_properties properties
= MLT_PRODUCER_PROPERTIES( producer
);
118 char *resource
= mlt_properties_get( properties
, "resource" );
119 char *last_resource
= mlt_properties_get( properties
, "_last_resource" );
121 char *this_resource
= NULL
;
122 double ttl
= mlt_properties_get_int( properties
, "ttl" );
123 mlt_position position
= mlt_producer_position( producer
);
124 SDL_Surface
*surface
= mlt_properties_get_data( properties
, "_surface", NULL
);
125 mlt_properties filenames
= mlt_properties_get_data( properties
, "_filenames", NULL
);
127 if ( filenames
== NULL
)
129 filenames
= parse_file_names( resource
);
130 mlt_properties_set_data( properties
, "_surface", surface
, 0, ( mlt_destructor
)SDL_FreeSurface
, 0 );
133 image_idx
= ( int )floor( ( double )position
/ ttl
) % mlt_properties_count( filenames
);
134 this_resource
= mlt_properties_get_value( filenames
, image_idx
);
136 if ( last_resource
== NULL
|| strcmp( last_resource
, this_resource
) )
138 surface
= IMG_Load( this_resource
);
139 if ( surface
!= NULL
)
141 surface
->refcount
++;
142 mlt_properties_set_data( properties
, "_surface", surface
, 0, ( mlt_destructor
)SDL_FreeSurface
, 0 );
143 mlt_properties_set( properties
, "_last_resource", this_resource
);
146 else if ( surface
!= NULL
)
148 surface
->refcount
++;
154 static int producer_get_frame( mlt_producer producer
, mlt_frame_ptr frame
, int index
)
157 *frame
= mlt_frame_init( );
159 if ( *frame
!= NULL
)
161 // Create the surface for the current image
162 SDL_Surface
*surface
= load_image( producer
);
164 if ( surface
!= NULL
)
166 // Obtain properties of frame and producer
167 mlt_properties properties
= MLT_FRAME_PROPERTIES( *frame
);
169 // Obtain properties of producer
170 mlt_properties producer_props
= MLT_PRODUCER_PROPERTIES( producer
);
172 // Update timecode on the frame we're creating
173 mlt_frame_set_position( *frame
, mlt_producer_position( producer
) );
175 // Set producer-specific frame properties
176 mlt_properties_set_int( properties
, "progressive", 1 );
177 mlt_properties_set_double( properties
, "aspect_ratio", mlt_properties_get_double( producer_props
, "aspect_ratio" ) );
178 mlt_properties_set_data( properties
, "surface", surface
, 0, ( mlt_destructor
)SDL_FreeSurface
, NULL
);
179 mlt_properties_set_int( properties
, "real_width", surface
->w
);
180 mlt_properties_set_int( properties
, "real_height", surface
->h
);
182 // Push the get_image method
183 mlt_frame_push_get_image( *frame
, producer_get_image
);
187 // Calculate the next timecode
188 mlt_producer_prepare_next( producer
);
193 static void producer_close( mlt_producer producer
)
195 producer
->close
= NULL
;
196 mlt_producer_close( producer
);
200 mlt_producer
producer_sdl_image_init( char *file
)
202 mlt_producer producer
= calloc( 1, sizeof( struct mlt_producer_s
) );
203 if ( producer
!= NULL
&& mlt_producer_init( producer
, NULL
) == 0 )
205 // Get the properties interface
206 mlt_properties properties
= MLT_PRODUCER_PROPERTIES( producer
);
208 // Callback registration
209 producer
->get_frame
= producer_get_frame
;
210 producer
->close
= ( mlt_destructor
)producer_close
;
212 // Set the default properties
213 mlt_properties_set( properties
, "resource", file
);
214 mlt_properties_set( properties
, "_resource", "" );
215 mlt_properties_set_double( properties
, "aspect_ratio", 1 );
216 mlt_properties_set_int( properties
, "ttl", 25 );
217 mlt_properties_set_int( properties
, "progressive", 1 );