Constness changes
[melted] / src / modules / core / transition_composite.c
index 578131b..04a518f 100644 (file)
@@ -201,7 +201,7 @@ static inline double delta_calculate( mlt_transition this, mlt_frame frame, mlt_
        return length * ( y - x ) / 2.0;
 }
 
-static int get_value( mlt_properties properties, char *preferred, char *fallback )
+static int get_value( mlt_properties properties, const char *preferred, const char *fallback )
 {
        int value = mlt_properties_get_int( properties, preferred );
        if ( value == 0 )
@@ -555,13 +555,13 @@ static int composite_yuv( uint8_t *p_dest, int width_dest, int height_dest, uint
        int alpha_b_stride = stride_src / bpp;
        int alpha_a_stride = stride_dest / bpp;
 
-       // Snap to even columns to prevent "chroma swap"
-       p_src += uneven_x_src * 2;
-       width_src -= 2 * uneven_x_src;
-       alpha_b += uneven_x_src;
-       p_dest += uneven_x * 2;
-       width_src -= 2 * uneven_x;
-       alpha_a += uneven_x;
+       // Align chroma of source and destination
+       if ( uneven_x != uneven_x_src )
+       {
+               p_src += 2;
+               width_src -= 2;
+               alpha_b += 1;
+       }
 
        // now do the compositing only to cropped extents
        for ( i = 0; i < height_src; i += step )
@@ -624,7 +624,7 @@ static uint16_t* get_luma( mlt_transition this, mlt_properties properties, int w
                luma_height = height;
        }
 
-       if ( resource != NULL && strchr( resource, '%' ) )
+       if ( resource && resource[0] && strchr( resource, '%' ) )
        {
                // TODO: Clean up quick and dirty compressed/existence check
                FILE *test;
@@ -637,7 +637,28 @@ static uint16_t* get_luma( mlt_transition this, mlt_properties properties, int w
                resource = temp;
        }
 
-       if ( resource != NULL && ( luma_bitmap == NULL || luma_width != width || luma_height != height ) )
+       if ( resource && resource[0] )
+       {
+               char *old_luma = mlt_properties_get( properties, "_luma" );
+               int old_invert = mlt_properties_get_int( properties, "_luma_invert" );
+
+               if ( invert != old_invert || ( old_luma && old_luma[0] && strcmp( resource, old_luma ) ) )
+               {
+                       mlt_properties_set_data( properties, "_luma.orig_bitmap", NULL, 0, NULL, NULL );
+                       luma_bitmap = NULL;
+               }
+       }
+       else {
+               char *old_luma = mlt_properties_get( properties, "_luma" );
+               if ( old_luma && old_luma[0] )
+               {
+                       mlt_properties_set_data( properties, "_luma.orig_bitmap", NULL, 0, NULL, NULL );
+                       luma_bitmap = NULL;
+                       mlt_properties_set( properties, "_luma", NULL);
+               }
+       }
+
+       if ( resource && resource[0] && ( luma_bitmap == NULL || luma_width != width || luma_height != height ) )
        {
                uint16_t *orig_bitmap = mlt_properties_get_data( properties, "_luma.orig_bitmap", NULL );
                luma_width = mlt_properties_get_int( properties, "_luma.orig_width" );
@@ -725,6 +746,8 @@ static uint16_t* get_luma( mlt_transition this, mlt_properties properties, int w
                mlt_properties_set_int( properties, "_luma.width", width );
                mlt_properties_set_int( properties, "_luma.height", height );
                mlt_properties_set_data( properties, "_luma.bitmap", luma_bitmap, width * height * 2, mlt_pool_release, NULL );
+               mlt_properties_set( properties, "_luma", resource );
+               mlt_properties_set_int( properties, "_luma_invert", invert );
        }
        return luma_bitmap;
 }
@@ -840,6 +863,50 @@ static int get_b_frame_image( mlt_transition this, mlt_frame b_frame, uint8_t **
        return ret && image != NULL;
 }
 
+static void crop_calculate( mlt_transition this, mlt_properties properties, struct geometry_s *result, double position )
+{
+       // Initialize panning info
+       result->x_src = 0;
+       result->y_src = 0;
+       if ( mlt_properties_get( properties, "crop" ) )
+       {
+               mlt_geometry crop = mlt_properties_get_data( properties, "crop_geometry", NULL );
+               if ( !crop )
+               {
+                       crop = mlt_geometry_init();
+                       mlt_position in = mlt_transition_get_in( this );
+                       mlt_position out = mlt_transition_get_out( this );
+                       int length = out - in + 1;
+                       double cycle = mlt_properties_get_double( properties, "cycle" );
+
+                       // Allow a geometry repeat cycle
+                       if ( cycle >= 1 )
+                               length = cycle;
+                       else if ( cycle > 0 )
+                               length *= cycle;
+                       mlt_geometry_parse( crop, mlt_properties_get( properties, "crop" ), length, result->sw, result->sh );
+                       mlt_properties_set_data( properties, "crop_geometry", crop, 0, (mlt_destructor)mlt_geometry_close, NULL );
+               }
+
+               // Repeat processing
+               int length = mlt_geometry_get_length( crop );
+               int mirror_off = mlt_properties_get_int( properties, "mirror_off" );
+               int repeat_off = mlt_properties_get_int( properties, "repeat_off" );
+               if ( !repeat_off && position >= length && length != 0 )
+               {
+                       int section = position / length;
+                       position -= section * length;
+                       if ( !mirror_off && section % 2 == 1 )
+                               position = length - position;
+               }
+
+               // Compute the pan
+               struct mlt_geometry_item_s crop_item;
+               mlt_geometry_fetch( crop, &crop_item, position );
+               result->x_src = rint( crop_item.x );
+               result->y_src = rint( crop_item.y );
+       }
+}
 
 static mlt_geometry composite_calculate( mlt_transition this, struct geometry_s *result, mlt_frame a_frame, double position )
 {
@@ -898,25 +965,7 @@ static mlt_geometry composite_calculate( mlt_transition this, struct geometry_s
        result->halign = alignment_parse( mlt_properties_get( properties, "halign" ) );
        result->valign = alignment_parse( mlt_properties_get( properties, "valign" ) );
 
-       result->x_src = 0;
-       result->y_src = 0;
-       if ( mlt_properties_get( properties, "crop" ) )
-       {
-               mlt_geometry crop = mlt_properties_get_data( properties, "crop_geometry", NULL );
-               if ( !crop )
-               {
-                       crop = mlt_geometry_init();
-                       mlt_position in = mlt_transition_get_in( this );
-                       mlt_position out = mlt_transition_get_out( this );
-                       int length = out - in + 1;
-                       mlt_geometry_parse( crop, mlt_properties_get( properties, "crop" ), length, result->sw, result->sh );
-                       mlt_properties_set_data( properties, "crop_geometry", crop, 0, (mlt_destructor)mlt_geometry_close, NULL );
-               }
-               struct mlt_geometry_item_s crop_item;
-               mlt_geometry_fetch( crop, &crop_item, position );
-               result->x_src = crop_item.x;
-               result->y_src = crop_item.y;
-       }
+       crop_calculate( this, properties, result, position );
 
        return start;
 }
@@ -1089,7 +1138,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                uint8_t *alpha_b = NULL;
 
                // Composites always need scaling... defaulting to lowest
-               char *rescale = mlt_properties_get( a_props, "rescale.interp" );
+               const char *rescale = mlt_properties_get( a_props, "rescale.interp" );
                if ( rescale == NULL || !strcmp( rescale, "none" ) )
                        rescale = "nearest";
                mlt_properties_set( a_props, "rescale.interp", rescale );