Added new profiles system: mlt_profile, MLT_PROFILE, and profiles documents.
[melted] / src / framework / mlt_geometry.c
index 7a9944c..67d98ee 100644 (file)
@@ -1,26 +1,27 @@
 /*
- * mlt_geometry.h -- provides the geometry API
+ * mlt_geometry.c -- provides the geometry API
  * Copyright (C) 2004-2005 Ushodaya Enterprises Limited
  * Author: Charles Yates <charles.yates@pandora.be>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
+ * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "mlt_geometry.h"
 #include "mlt_tokeniser.h"
 #include "mlt_factory.h"
+#include "mlt_profile.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -54,12 +55,8 @@ mlt_geometry mlt_geometry_init( )
                if ( this->local != NULL )
                {
                        geometry self = this->local;
-                       char *normalisation = mlt_environment( "MLT_NORMALISATION" );
-                       self->nw = 720;
-                       if ( normalisation == NULL || strcmp( normalisation, "NTSC" ) )
-                               self->nh = 576;
-                       else
-                               self->nh = 480;
+                       self->nw = mlt_profile_get()->width;
+                       self->nh = mlt_profile_get()->height;
                }
                else
                {
@@ -98,9 +95,9 @@ static void mlt_geometry_virtual_refresh( mlt_geometry this )
                                        geometry_item prev = current->prev;
                                        geometry_item next = current->next;
 
-                                       float prev_value = 0;
-                                       float next_value = 0;
-                                       float value = 0;
+                                       double prev_value = 0;
+                                       double next_value = 0;
+                                       double value = 0;
 
                                        while( prev != NULL && !prev->data.f[ i ] ) prev = prev->prev;
                                        while( next != NULL && !next->data.f[ i ] ) next = next->next;
@@ -173,6 +170,11 @@ static int mlt_geometry_drop( mlt_geometry this, geometry_item item )
                        self->item->data.f[4] = 1;
                }
        }
+       else if ( item->next != NULL && item->prev != NULL )
+       {
+               item->prev->next = item->next;
+               item->next->prev = item->prev;
+       }
        else if ( item->next != NULL )
        {
                item->next->prev = item->prev;
@@ -180,7 +182,6 @@ static int mlt_geometry_drop( mlt_geometry this, geometry_item item )
        else if ( item->prev != NULL )
        {
                item->prev->next = item->next;
-               item->next->prev = item->prev;
        }
 
        free( item );
@@ -277,7 +278,7 @@ void mlt_geometry_set_length( mlt_geometry this, int length )
        // Get the local/private structure
        geometry self = this->local;
 
-       // return the length
+       // set the length
        self->length = length;
 }
 
@@ -438,6 +439,7 @@ int mlt_geometry_fetch( mlt_geometry this, mlt_geometry_item item, float positio
        else
        {
                memset( item, 0, sizeof( struct mlt_geometry_item_s ) );
+               item->frame = position;
                item->mix = 100;
        }
 
@@ -520,7 +522,7 @@ int mlt_geometry_remove( mlt_geometry this, int position )
        // Get the first item
        geometry_item place = self->item;
 
-       while( place != NULL && position < place->data.frame )
+       while( place != NULL && position != place->data.frame )
                place = place->next;
 
        if ( place != NULL && position == place->data.frame )
@@ -533,7 +535,7 @@ int mlt_geometry_remove( mlt_geometry this, int position )
 }
 
 // Get the key at the position or the next following
-int mlt_geometry_key( mlt_geometry this, mlt_geometry_item item, int position )
+int mlt_geometry_next_key( mlt_geometry this, mlt_geometry_item item, int position )
 {
        // Get the local/private geometry structure
        geometry self = this->local;
@@ -550,8 +552,27 @@ int mlt_geometry_key( mlt_geometry this, mlt_geometry_item item, int position )
        return place == NULL;
 }
 
+// Get the key at the position or the previous key
+int mlt_geometry_prev_key( mlt_geometry this, mlt_geometry_item item, int position )
+{
+       // Get the local/private geometry structure
+       geometry self = this->local;
+
+       // Get the first item
+       geometry_item place = self->item;
+
+       while( place != NULL && place->next != NULL && position >= place->next->data.frame )
+               place = place->next;
+
+       if ( place != NULL )
+               memcpy( item, &place->data, sizeof( struct mlt_geometry_item_s ) );
+
+       return place == NULL;
+}
+
 char *mlt_geometry_serialise_cut( mlt_geometry this, int in, int out )
 {
+       geometry self = this->local;
        struct mlt_geometry_item_s item;
        char *ret = malloc( 1000 );
        int used = 0;
@@ -580,6 +601,14 @@ char *mlt_geometry_serialise_cut( mlt_geometry this, int in, int out )
                                if ( mlt_geometry_fetch( this, &item, item.frame ) )
                                        break;
 
+                               // If the first key is larger than the current position
+                               // then do nothing here
+                               if ( self->item->data.frame > item.frame )
+                               {
+                                       item.frame ++;
+                                       continue;
+                               }
+
                                // To ensure correct seeding, ensure all values are fixed
                                item.f[0] = 1;
                                item.f[1] = 1;
@@ -590,7 +619,7 @@ char *mlt_geometry_serialise_cut( mlt_geometry this, int in, int out )
                        // Typically, we move from key to key
                        else if ( item.frame < out )
                        {
-                               if ( mlt_geometry_key( this, &item, item.frame ) )
+                               if ( mlt_geometry_next_key( this, &item, item.frame ) )
                                        break;
 
                                // Special case - crop at the out point