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 library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library 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 GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <framework/mlt_producer.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
);
40 SDL_Surface
*converted
= NULL
;
45 *format
= mlt_image_yuv422
;
46 *image
= mlt_pool_alloc( *width
* *height
* 2 );
47 alpha
= mlt_pool_alloc( *width
* *height
);
49 if ( surface
->format
->BitsPerPixel
!= 32 && surface
->format
->BitsPerPixel
!= 24 )
52 fmt
.BitsPerPixel
= 24;
53 fmt
.BytesPerPixel
= 3;
57 fmt
.Rmask
= 0xff << 16;
58 fmt
.Gmask
= 0xff << 8;
60 converted
= SDL_ConvertSurface( surface
, &fmt
, 0 );
63 switch( surface
->format
->BitsPerPixel
)
66 mlt_convert_rgb24a_to_yuv422( surface
->pixels
, *width
, *height
, surface
->pitch
, *image
, alpha
);
69 mlt_convert_rgb24_to_yuv422( surface
->pixels
, *width
, *height
, surface
->pitch
, *image
);
70 memset( alpha
, 255, *width
* *height
);
73 mlt_convert_rgb24_to_yuv422( converted
->pixels
, *width
, *height
, converted
->pitch
, *image
);
74 memset( alpha
, 255, *width
* *height
);
79 SDL_FreeSurface( converted
);
82 mlt_properties_set_data( properties
, "image", *image
, *width
* *height
* 2, mlt_pool_release
, NULL
);
83 mlt_properties_set_data( properties
, "alpha", alpha
, *width
* *height
, mlt_pool_release
, NULL
);
84 mlt_properties_set_int( properties
, "width", *width
);
85 mlt_properties_set_int( properties
, "height", *height
);
90 static int filter_files( const struct dirent
*de
)
92 return de
->d_name
[ 0 ] != '.';
95 static mlt_properties
parse_file_names( char *resource
)
97 mlt_properties properties
= mlt_properties_new( );
99 if ( strstr( resource
, "/.all." ) != NULL
)
101 char *dir_name
= strdup( resource
);
102 char *extension
= strrchr( resource
, '.' );
103 *( strstr( dir_name
, "/.all." ) + 1 ) = '\0';
104 char fullname
[ 1024 ];
105 strcpy( fullname
, dir_name
);
106 struct dirent
**de
= NULL
;
107 int n
= scandir( fullname
, &de
, filter_files
, alphasort
);
111 for (i
= 0; i
< n
; i
++ )
113 snprintf( fullname
, 1023, "%s%s", dir_name
, de
[i
]->d_name
);
114 if ( strstr( fullname
, extension
) && lstat( fullname
, &info
) == 0 &&
115 ( S_ISREG( info
.st_mode
) || info
.st_mode
| S_IXUSR
) )
118 sprintf( temp
, "%d", i
);
119 mlt_properties_set( properties
, temp
, fullname
);
129 mlt_properties_set( properties
, "0", resource
);
135 static SDL_Surface
*load_image( mlt_producer producer
)
137 mlt_properties properties
= MLT_PRODUCER_PROPERTIES( producer
);
138 char *resource
= mlt_properties_get( properties
, "resource" );
139 char *last_resource
= mlt_properties_get( properties
, "_last_resource" );
141 char *this_resource
= NULL
;
142 double ttl
= mlt_properties_get_int( properties
, "ttl" );
143 mlt_position position
= mlt_producer_position( producer
);
144 SDL_Surface
*surface
= mlt_properties_get_data( properties
, "_surface", NULL
);
145 mlt_properties filenames
= mlt_properties_get_data( properties
, "_filenames", NULL
);
147 if ( filenames
== NULL
)
149 filenames
= parse_file_names( resource
);
150 mlt_properties_set_data( properties
, "_surface", surface
, 0, ( mlt_destructor
)SDL_FreeSurface
, 0 );
153 image_idx
= ( int )floor( ( double )position
/ ttl
) % mlt_properties_count( filenames
);
154 this_resource
= mlt_properties_get_value( filenames
, image_idx
);
156 if ( last_resource
== NULL
|| strcmp( last_resource
, this_resource
) )
158 surface
= IMG_Load( this_resource
);
159 if ( surface
!= NULL
)
161 surface
->refcount
++;
162 mlt_properties_set_data( properties
, "_surface", surface
, 0, ( mlt_destructor
)SDL_FreeSurface
, 0 );
163 mlt_properties_set( properties
, "_last_resource", this_resource
);
166 else if ( surface
!= NULL
)
168 surface
->refcount
++;
174 static int producer_get_frame( mlt_producer producer
, mlt_frame_ptr frame
, int index
)
177 *frame
= mlt_frame_init( MLT_PRODUCER_SERVICE( producer
) );
179 if ( *frame
!= NULL
)
181 // Create the surface for the current image
182 SDL_Surface
*surface
= load_image( producer
);
184 if ( surface
!= NULL
)
186 // Obtain properties of frame and producer
187 mlt_properties properties
= MLT_FRAME_PROPERTIES( *frame
);
189 // Obtain properties of producer
190 mlt_properties producer_props
= MLT_PRODUCER_PROPERTIES( producer
);
192 // Update timecode on the frame we're creating
193 mlt_frame_set_position( *frame
, mlt_producer_position( producer
) );
195 // Set producer-specific frame properties
196 mlt_properties_set_int( properties
, "progressive", 1 );
197 mlt_properties_set_double( properties
, "aspect_ratio", mlt_properties_get_double( producer_props
, "aspect_ratio" ) );
198 mlt_properties_set_data( properties
, "surface", surface
, 0, ( mlt_destructor
)SDL_FreeSurface
, NULL
);
199 mlt_properties_set_int( properties
, "real_width", surface
->w
);
200 mlt_properties_set_int( properties
, "real_height", surface
->h
);
202 // Push the get_image method
203 mlt_frame_push_get_image( *frame
, producer_get_image
);
207 // Calculate the next timecode
208 mlt_producer_prepare_next( producer
);
213 static void producer_close( mlt_producer producer
)
215 producer
->close
= NULL
;
216 mlt_producer_close( producer
);
220 mlt_producer
producer_sdl_image_init( mlt_profile profile
, mlt_service_type type
, const char *id
, char *file
)
222 mlt_producer producer
= calloc( 1, sizeof( struct mlt_producer_s
) );
223 if ( producer
!= NULL
&& mlt_producer_init( producer
, NULL
) == 0 )
225 // Get the properties interface
226 mlt_properties properties
= MLT_PRODUCER_PROPERTIES( producer
);
228 // Callback registration
229 producer
->get_frame
= producer_get_frame
;
230 producer
->close
= ( mlt_destructor
)producer_close
;
232 // Set the default properties
233 mlt_properties_set( properties
, "resource", file
);
234 mlt_properties_set( properties
, "_resource", "" );
235 mlt_properties_set_double( properties
, "aspect_ratio", 1 );
236 mlt_properties_set_int( properties
, "ttl", 25 );
237 mlt_properties_set_int( properties
, "progressive", 1 );