asset drag/drop to viewers, bluebanana bug, listbox fontlist highlight
[goodguy/history.git] / cinelerra-5.1 / cinelerra / file.C
index ddc1a459c0d51db2d63a9ed871bea77806b34d42..8179d0d3977f68a9c4c20921bb5ed377ff1055ce 100644 (file)
@@ -177,6 +177,7 @@ int File::get_options(FormatTools *format,
                                audio_options,
                                video_options);
                        break;
+#ifdef HAVE_DV
                case FILE_RAWDV:
                        FileDV::get_parameters(parent_window,
                                asset,
@@ -184,6 +185,7 @@ int File::get_options(FormatTools *format,
                                audio_options,
                                video_options);
                        break;
+#endif
                case FILE_PCM:
                case FILE_WAV:
                case FILE_AU:
@@ -417,12 +419,14 @@ int File::open_file(Preferences *preferences,
                                file = new FileScene(this->asset, this);
                                break;
                        }
+#ifdef HAVE_DV
                        if(FileDV::check_sig(this->asset)) {
 // libdv
                                fclose(stream);
                                file = new FileDV(this->asset, this);
                                break;
                        }
+#endif
                        if(FileSndFile::check_sig(this->asset)) {
 // libsndfile
                                fclose(stream);
@@ -592,11 +596,11 @@ int File::open_file(Preferences *preferences,
                case FILE_VORBIS:
                        file = new FileVorbis(this->asset, this);
                        break;
-
+#ifdef HAVE_DV
                case FILE_RAWDV:
                        file = new FileDV(this->asset, this);
                        break;
-
+#endif
 // try plugins
                default:
                        return 1;
@@ -618,10 +622,13 @@ int File::open_file(Preferences *preferences,
        }
 
        if( rd ) {
-// one frame image file, no specific length
-               if( !this->asset->audio_data && this->asset->video_data &&
-                   this->asset->video_length <= 1 )
+// one frame image file, not brender, no specific length
+               if( !this->asset->audio_data && this->asset->use_header &&
+                   this->asset->video_data && !this->asset->single_frame &&
+                   this->asset->video_length >= 0 && this->asset->video_length <= 1 ) {
+                       this->asset->single_frame = 1;
                        this->asset->video_length = -1;
+               }
        }
 
 // Synchronize header parameters
@@ -1120,7 +1127,7 @@ VFrame*** File::get_video_buffer()
 int File::read_samples(Samples *samples, int64_t len)
 {
 // Never try to read more samples than exist in the file
-       if (current_sample + len > asset->audio_length) {
+       if (asset->audio_length >= 0 && current_sample + len > asset->audio_length) {
                len = asset->audio_length - current_sample;
        }
        if(len <= 0) return 0;
@@ -1167,10 +1174,11 @@ int File::read_frame(VFrame *frame, int is_thread)
        if(debug) PRINT_TRACE
        if( !file ) return 1;
        if(debug) PRINT_TRACE
+       int result = 0;
        int supported_colormodel = colormodel_supported(frame->get_color_model());
        int advance_position = 1;
-       int cache_active = use_cache || asset->video_length < 0 ? 1 : 0;
-       int64_t cache_position = asset->video_length >= 0 ? current_frame : -1;
+       int cache_active = use_cache || asset->single_frame ? 1 : 0;
+       int64_t cache_position = !asset->single_frame ? current_frame : -1;
 // Test cache
        if( cache_active && frame_cache->get_frame(frame, cache_position,
                        current_layer, asset->frame_rate) )
@@ -1210,37 +1218,26 @@ int File::read_frame(VFrame *frame, int is_thread)
 
 //                     printf("File::read_frame %d\n", __LINE__);
                temp_frame->copy_stacks(frame);
-               int result = file->read_frame(temp_frame);
-               if( result && frame->get_status() > 0 )
+               result = file->read_frame(temp_frame);
+               if( !result )
+                       frame->transfer_from(temp_frame);
+               else if( result && frame->get_status() > 0 )
                        frame->set_status(-1);
-//for(int i = 0; i < 1000 * 1000; i++) ((float*)temp_frame->get_rows()[0])[i] = 1.0;
-// printf("File::read_frame %d %d %d %d %d %d\n",
-// temp_frame->get_color_model(),
-// temp_frame->get_w(),
-// temp_frame->get_h(),
-// frame->get_color_model(),
-// frame->get_w(),
-// frame->get_h());
-               BC_CModels::transfer(frame->get_rows(), temp_frame->get_rows(),
-                       frame->get_y(), frame->get_u(), frame->get_v(),
-                       temp_frame->get_y(), temp_frame->get_u(), temp_frame->get_v(),
-                       0, 0, temp_frame->get_w(), temp_frame->get_h(),
-                       0, 0, frame->get_w(), frame->get_h(),
-                       temp_frame->get_color_model(),
-                       frame->get_color_model(), 0, temp_frame->get_w(),
-                       frame->get_w());
-//                     printf("File::read_frame %d\n", __LINE__);
+//printf("File::read_frame %d\n", __LINE__);
        }
        else
        {
 // Can't advance position here because it needs to be added to cache
 //printf("File::read_frame %d\n", __LINE__);
-               int result = file->read_frame(frame);
+               result = file->read_frame(frame);
                if( result && frame->get_status() > 0 )
                        frame->set_status(-1);
 //for(int i = 0; i < 100 * 1000; i++) ((float*)frame->get_rows()[0])[i] = 1.0;
        }
 
+       if( result && !current_frame )
+               frame->clear_frame();
+
        if( cache_active && advance_position && frame->get_status() > 0 )
                frame_cache->put_frame(frame, cache_position,
                        current_layer, asset->frame_rate, 1, 0);
@@ -1420,7 +1417,9 @@ int File::get_best_colormodel(Asset *asset, int driver)
 {
        switch(asset->format)
        {
+#ifdef HAVE_FIREWIRE
                case FILE_RAWDV:        return FileDV::get_best_colormodel(asset, driver);
+#endif
                case FILE_MPEG:         return FileMPEG::get_best_colormodel(asset, driver);
                case FILE_JPEG:
                case FILE_JPEG_LIST:    return FileJPEG::get_best_colormodel(asset, driver);
@@ -1526,6 +1525,7 @@ int File::supports_audio(int format)
                case FILE_AIFF:
                case FILE_SND:
                case FILE_FFMPEG:
+               case FILE_RAWDV:
                        return 1;
        }
        return 0;
@@ -1623,16 +1623,88 @@ int File::record_fd()
 }
 
 
-void get_exe_path(char *result)
+void File::get_exe_path(char *result, char *bnp)
 {
-// Get executable path
+// Get executable path, basename
        int len = readlink("/proc/self/exe", result, BCTEXTLEN-1);
        if( len >= 0 ) {
                result[len] = 0;
                char *ptr = strrchr(result, '/');
-               if( ptr ) *ptr = 0;
+               if( ptr ) *ptr++ = 0; else ptr = result;
+               if( bnp ) strncpy(bnp, ptr, BCTEXTLEN);
+       }
+       else {
+               *result = 0;
+               if( bnp ) *bnp = 0;
        }
-       else
-               result[0] = 0;
 }
 
+void File::getenv_path(char *result, const char *path)
+{
+       char *rp = result, *ep = rp + BCTEXTLEN-1;
+       const char *cp = path;
+// any env var can be used here to expand a path as:
+//   "path...$id...": and id is a word as alpha,alnum...
+//   expands as "path...getenv(id)..."
+// CIN_PATH, CIN_LIB are set in main.C,
+       for( int ch=*cp++; ch && rp < ep; ch=*cp++ ) {
+               if( ch == '$' && isalpha(*cp) ) { // scan alpha,alnum...
+                       const char *bp = cp;  char *p = rp;
+                       while( p < ep && *bp && (isalnum(*bp) || *bp == '_') ) *p++ = *bp++;
+                       *p = 0;
+                       const char *envp = getenv(rp); // read env value
+                       if( !envp ) continue;
+                       while( *envp && rp < ep ) *rp++ = *envp++;
+                       cp = bp;                 // subst id=value
+                       continue;
+               }
+               *rp++ = ch;
+       }
+       *rp = 0;
+}
+
+char File::cinexe_path[BCTEXTLEN];
+char File::cinpkg_path[BCTEXTLEN];
+char File::cindat_path[BCTEXTLEN];
+char File::cinlib_path[BCTEXTLEN];
+char File::cincfg_path[BCTEXTLEN];
+char File::cinplg_path[BCTEXTLEN];
+char File::cinlad_path[BCTEXTLEN];
+char File::cinlcl_path[BCTEXTLEN];
+
+void File::init_cin_path()
+{
+       char env_path[BCTEXTLEN], env_pkg[BCTEXTLEN];
+// these values are advertised for forks/shell scripts
+       get_exe_path(env_path, env_pkg);
+       snprintf(cinexe_path, sizeof(cinexe_path), "CIN_PATH=%s", env_path);
+       putenv(cinexe_path);
+       snprintf(cinpkg_path, sizeof(cinpkg_path), "CIN_PKG=%s", env_pkg);
+       putenv(cinpkg_path);
+
+       getenv_path(env_path, CINDAT_DIR);
+       snprintf(cindat_path, sizeof(cindat_path), "CIN_DAT=%s", env_path);
+       putenv(cindat_path);
+
+       getenv_path(env_path, CINLIB_DIR);
+       snprintf(cinlib_path, sizeof(cinlib_path), "CIN_LIB=%s", env_path);
+       putenv(cinlib_path);
+
+       getenv_path(env_path, CONFIG_DIR);
+       snprintf(cincfg_path, sizeof(cincfg_path), "CIN_CONFIG=%s", env_path);
+       putenv(cincfg_path);
+
+       getenv_path(env_path, PLUGIN_DIR);
+       snprintf(cinplg_path, sizeof(cinplg_path), "CIN_PLUGIN=%s", env_path);
+       putenv(cinplg_path);
+
+       getenv_path(env_path, LADSPA_DIR);
+       snprintf(cinlad_path, sizeof(cinlad_path), "CIN_LADSPA=%s", env_path);
+       putenv(cinlad_path);
+
+       getenv_path(env_path, LOCALE_DIR);
+       snprintf(cinlcl_path, sizeof(cinlcl_path), "CIN_LOCALE=%s", env_path);
+       putenv(cinlcl_path);
+}
+
+