transition icons, ru po, listbox sliderbar fixes, update xlat, xft wide char fixes...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / file.C
index 57b09f0eac0aad61c38787bb2877dc4b55b9c733..7e3493b1bc3b57e656173c7654899e5219d38ac3 100644 (file)
@@ -71,6 +71,7 @@
 #include "packagingengine.h"
 #include "pluginserver.h"
 #include "preferences.h"
+#include "probeprefs.h"
 #include "samples.h"
 #include "vframe.h"
 
@@ -220,6 +221,7 @@ int File::get_options(FormatTools *format,
                                audio_options,
                                video_options);
                        break;
+#ifdef HAVE_OPENEXR
                case FILE_EXR:
                case FILE_EXR_LIST:
                        FileEXR::get_parameters(parent_window,
@@ -228,6 +230,7 @@ int File::get_options(FormatTools *format,
                                audio_options,
                                video_options);
                        break;
+#endif
                case FILE_FLAC:
                        FileFLAC::get_parameters(parent_window,
                                asset,
@@ -359,15 +362,143 @@ int File::delete_oldest()
        return frame_cache->delete_oldest();
 }
 
-
-
-
-
-
-
-
-
-
+// file driver in order of probe precidence
+//  can be reordered in preferences->interface
+const char *File::default_probes[] = { 
+       "FFMPEG_Early",
+       "Scene", 
+       "DB",
+#ifdef HAVE_DV 
+       "DV",   
+#endif 
+       "SndFile",
+       "PNG",
+       "JPEG",
+       "GIF",
+#ifdef HAVE_OPENEXR
+       "EXR",
+#endif
+       "FLAC",
+       "CR2",
+       "TGA",
+       "TIFF",
+       "OGG",
+       "Vorbis",
+       "MPEG",
+       "EDL",
+               "FFMPEG_Late", 
+}; 
+const int File::nb_probes =
+       sizeof(File::default_probes)/sizeof(File::default_probes[0]); 
+
+
+int File::probe()
+{
+       FILE *fp = fopen(this->asset->path, "rb");
+       if( !fp ) return FILE_NOT_FOUND;
+       char data[16];
+       memset(data,0,sizeof(data));
+       int ret = fread(data, 1, 16, fp);
+       fclose(fp);
+       if( !ret ) return FILE_NOT_FOUND;
+
+       for( int i=0; i<preferences->file_probes.size(); ++i ) {
+               ProbePref *pref = preferences->file_probes[i];
+               if( !pref->armed ) continue;
+               if( !strncmp(pref->name,"FFMPEG",6) ) { // FFMPEG Early/Late
+                       if( !FileFFMPEG::check_sig(this->asset) ) continue;
+                       file = new FileFFMPEG(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"DB") ) { // MediaDB
+                       if( !FileDB::check_sig(this->asset) ) continue;
+                       file = new FileDB(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"Scene") ) { // scene file
+                       if( !FileScene::check_sig(this->asset, data)) continue;
+                       file = new FileScene(this->asset, this);
+                       return FILE_OK;
+               }
+#ifdef HAVE_DV
+               if( !strcmp(pref->name,"DV") ) { // libdv
+                       if( !FileDV::check_sig(this->asset) ) continue;
+                       file = new FileDV(this->asset, this);
+                       return FILE_OK;
+               }
+#endif
+               if( !strcmp(pref->name,"SndFile") ) { // libsndfile
+                       if( !FileSndFile::check_sig(this->asset) ) continue;
+                       file = new FileSndFile(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"PNG") ) { // PNG file
+                       if( !FilePNG::check_sig(this->asset) ) continue;
+                       file = new FilePNG(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"JPEG") ) { // JPEG file
+                       if( !FileJPEG::check_sig(this->asset) ) continue;
+                       file = new FileJPEG(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"GIF") ) { // GIF file
+                       if( !FileGIF::check_sig(this->asset)) continue;
+                       file = new FileGIF(this->asset, this);
+                       return FILE_OK;
+               }
+#ifdef HAVE_EXR
+               if( !strcmp(pref->name,"EXR") ) { // EXR file
+                       if( !FileEXR::check_sig(this->asset, data)) continue;
+                       file = new FileEXR(this->asset, this);
+                       return FILE_OK;
+               }
+#endif
+               if( !strcmp(pref->name,"FLAC") ) { // FLAC file
+                       if( !FileFLAC::check_sig(this->asset, data)) continue;
+                       file = new FileFLAC(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"CR2") ) { // CR2 file
+                       if( !FileCR2::check_sig(this->asset)) continue;
+                       file = new FileCR2(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"TGA") ) { // TGA file
+                       if( !FileTGA::check_sig(this->asset) ) continue;
+                       file = new FileTGA(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"TIFF") ) { // TIFF file
+                       if( !FileTIFF::check_sig(this->asset) ) continue;
+                       file = new FileTIFF(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"OGG") ) { // OGG file
+                       if( !FileOGG::check_sig(this->asset) ) continue;
+                       file = new FileOGG(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"Vorbis") ) { // VorbisFile file
+                       if( !FileVorbis::check_sig(this->asset) ) continue;
+                       file = new FileVorbis(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"MPEG") ) { // MPEG file
+                       if( !FileMPEG::check_sig(this->asset) ) continue;
+                       file = new FileMPEG(this->asset, this);
+                       return FILE_OK;
+               }
+               if( !strcmp(pref->name,"EDL") ) { // XML file
+                       if( data[0] != '<' ) continue;
+                       if( !strncmp(&data[1],"EDL>",4) ||
+                           !strncmp(&data[1],"HTAL>",5) ||
+                           !strncmp(&data[1],"?xml",4) )
+                               return FILE_IS_XML;
+               }
+       }
+       return FILE_UNRECOGNIZED_CODEC; // maybe PCM file ?
+}
 
 int File::open_file(Preferences *preferences,
        Asset *asset,
@@ -386,225 +517,101 @@ int File::open_file(Preferences *preferences,
 
        if(debug) printf("File::open_file %p %d\n", this, __LINE__);
 
-       switch(this->asset->format)
-       {
+       switch(this->asset->format) {
 // get the format now
 // If you add another format to case 0, you also need to add another case for the
 // file format #define.
-               case FILE_UNKNOWN:
-                       if(FileDB::check_sig(this->asset)) {
-// MediaDb file
-                               file = new FileDB(this->asset, this);
-                               break;
-                       }
-// if early probe enabled
-                       if( preferences->ffmpeg_early_probe &&
-                           FileFFMPEG::check_sig(this->asset)) {
-                               file = new FileFFMPEG(this->asset, this);
-                               break;
-                       }
-
-                       FILE *stream;
-                       if(!(stream = fopen(this->asset->path, "rb"))) {
-// file not found
-                               return 1;
-                       }
-
-                       char test[16];  memset(test,0,sizeof(test)); // int result =
-                       fread(test, 16, 1, stream);
-
-                       if(FileScene::check_sig(this->asset, test)) {
-// scene file
-                               fclose(stream);
-                               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);
-                               file = new FileSndFile(this->asset, this);
-                               break;
-                       }
-                       if(FilePNG::check_sig(this->asset)) {
-// PNG file
-                               fclose(stream);
-                               file = new FilePNG(this->asset, this);
-                               break;
-                       }
-                       if(FileJPEG::check_sig(this->asset)) {
-// JPEG file
-                               fclose(stream);
-                               file = new FileJPEG(this->asset, this);
-                               break;
-                       }
-                       if(FileGIF::check_sig(this->asset)) {
-// GIF file
-                               fclose(stream);
-                               file = new FileGIF(this->asset, this);
-                               break;
-                       }
-                       if(FileEXR::check_sig(this->asset, test)) {
-// EXR file
-                               fclose(stream);
-                               file = new FileEXR(this->asset, this);
-                               break;
-                       }
-                       if(FileFLAC::check_sig(this->asset, test)) {
-// FLAC file
-                               fclose(stream);
-                               file = new FileFLAC(this->asset, this);
-                               break;
-                       }
-                       if(FileCR2::check_sig(this->asset)) {
-// CR2 file
-                               fclose(stream);
-                               file = new FileCR2(this->asset, this);
-                               break;
-                       }
-                       if(FileTGA::check_sig(this->asset)) {
-// TGA file
-                               fclose(stream);
-                               file = new FileTGA(this->asset, this);
-                               break;
-                       }
-                       if(FileTIFF::check_sig(this->asset)) {
-// TIFF file
-                               fclose(stream);
-                               file = new FileTIFF(this->asset, this);
-                               break;
-                       }
-                       if(FileOGG::check_sig(this->asset)) {
-// OGG file
-                               fclose(stream);
-                               file = new FileOGG(this->asset, this);
-                               break;
-                       }
-                       if(FileVorbis::check_sig(this->asset)) {
-// VorbisFile file
-                               fclose(stream);
-                               file = new FileVorbis(this->asset, this);
-                               break;
-                       }
-                       if(FileMPEG::check_sig(this->asset)) {
-// MPEG file
-                               fclose(stream);
-                               file = new FileMPEG(this->asset, this);
-                               break;
-                       }
-                       if( test[0] == '<' && (
-                               !strncmp(&test[1],"EDL>",4) ||
-                               !strncmp(&test[1],"HTAL>",5) ||
-                               !strncmp(&test[1],"?xml",4) ) ) {
-// XML file
-                               fclose(stream);
-                               return FILE_IS_XML;
-                       }    // can't load project file
-                       if( !preferences->ffmpeg_early_probe &&
-                           FileFFMPEG::check_sig(this->asset) ) {
-                               fclose(stream);
-                               file = new FileFFMPEG(this->asset, this);
-                               break;
-                       }
-// PCM file
-                       fclose(stream);
-                       return FILE_UNRECOGNIZED_CODEC;
-                       break;
-
+       case FILE_UNKNOWN: {
+               int ret = probe();
+               if( ret != FILE_OK ) return ret;
+               break; }
 // format already determined
-               case FILE_AC3:
-                       file = new FileAC3(this->asset, this);
-                       break;
-
-               case FILE_SCENE:
-                       file = new FileScene(this->asset, this);
-                       break;
-
-               case FILE_FFMPEG:
-                       file = new FileFFMPEG(this->asset, this);
-                       break;
-
-               case FILE_PCM:
-               case FILE_WAV:
-               case FILE_AU:
-               case FILE_AIFF:
-               case FILE_SND:
+       case FILE_AC3:
+               file = new FileAC3(this->asset, this);
+               break;
+
+       case FILE_SCENE:
+               file = new FileScene(this->asset, this);
+               break;
+
+       case FILE_FFMPEG:
+               file = new FileFFMPEG(this->asset, this);
+               break;
+
+       case FILE_PCM:
+       case FILE_WAV:
+       case FILE_AU:
+       case FILE_AIFF:
+       case FILE_SND:
 //printf("File::open_file 1\n");
-                       file = new FileSndFile(this->asset, this);
-                       break;
-
-               case FILE_PNG:
-               case FILE_PNG_LIST:
-                       file = new FilePNG(this->asset, this);
-                       break;
-
-               case FILE_JPEG:
-               case FILE_JPEG_LIST:
-                       file = new FileJPEG(this->asset, this);
-                       break;
-
-               case FILE_GIF:
-               case FILE_GIF_LIST:
-                       file = new FileGIF(this->asset, this);
-                       break;
-
-               case FILE_EXR:
-               case FILE_EXR_LIST:
-                       file = new FileEXR(this->asset, this);
-                       break;
-
-               case FILE_FLAC:
-                       file = new FileFLAC(this->asset, this);
-                       break;
-
-               case FILE_CR2:
-               case FILE_CR2_LIST:
-                       file = new FileCR2(this->asset, this);
-                       break;
-
-               case FILE_TGA_LIST:
-               case FILE_TGA:
-                       file = new FileTGA(this->asset, this);
-                       break;
-
-               case FILE_TIFF:
-               case FILE_TIFF_LIST:
-                       file = new FileTIFF(this->asset, this);
-                       break;
-
-               case FILE_DB:
-                       file = new FileDB(this->asset, this);
-                       break;
-
-               case FILE_MPEG:
-               case FILE_AMPEG:
-               case FILE_VMPEG:
-                       file = new FileMPEG(this->asset, this);
-                       break;
-
-               case FILE_OGG:
-                       file = new FileOGG(this->asset, this);
-                       break;
-
-               case FILE_VORBIS:
-                       file = new FileVorbis(this->asset, this);
-                       break;
+               file = new FileSndFile(this->asset, this);
+               break;
+
+       case FILE_PNG:
+       case FILE_PNG_LIST:
+               file = new FilePNG(this->asset, this);
+               break;
+
+       case FILE_JPEG:
+       case FILE_JPEG_LIST:
+               file = new FileJPEG(this->asset, this);
+               break;
+
+       case FILE_GIF:
+       case FILE_GIF_LIST:
+               file = new FileGIF(this->asset, this);
+               break;
+#ifdef HAVE_OPENEXR
+       case FILE_EXR:
+       case FILE_EXR_LIST:
+               file = new FileEXR(this->asset, this);
+               break;
+#endif
+       case FILE_FLAC:
+               file = new FileFLAC(this->asset, this);
+               break;
+
+       case FILE_CR2:
+       case FILE_CR2_LIST:
+               file = new FileCR2(this->asset, this);
+               break;
+
+       case FILE_TGA_LIST:
+       case FILE_TGA:
+               file = new FileTGA(this->asset, this);
+               break;
+
+       case FILE_TIFF:
+       case FILE_TIFF_LIST:
+               file = new FileTIFF(this->asset, this);
+               break;
+
+       case FILE_DB:
+               file = new FileDB(this->asset, this);
+               break;
+
+       case FILE_MPEG:
+       case FILE_AMPEG:
+       case FILE_VMPEG:
+               file = new FileMPEG(this->asset, this);
+               break;
+
+       case FILE_OGG:
+               file = new FileOGG(this->asset, this);
+               break;
+
+       case FILE_VORBIS:
+               file = new FileVorbis(this->asset, this);
+               break;
 #ifdef HAVE_DV
-               case FILE_RAWDV:
-                       file = new FileDV(this->asset, this);
-                       break;
+       case FILE_RAWDV:
+               file = new FileDV(this->asset, this);
+               break;
 #endif
 // try plugins
-               default:
-                       return 1;
-                       break;
+       default:
+               return 1;
+               break;
        }
 
 
@@ -622,10 +629,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
@@ -1124,7 +1134,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;
@@ -1171,10 +1181,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) )
@@ -1214,37 +1225,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);
@@ -1260,16 +1260,12 @@ int File::can_copy_from(Asset *asset,
        int output_w,
        int output_h)
 {
-       if(!asset) return 0;
-
-       if(file)
-       {
+       if( asset && file ) {
                return asset->width == output_w &&
                        asset->height == output_h &&
                        file->can_copy_from(asset, position);
        }
-       else
-               return 0;
+       return 0;
 }
 
 // Fill in queries about formats when adding formats here.
@@ -1322,36 +1318,35 @@ const char* File::formattostr(int format)
 
 const char* File::formattostr(ArrayList<PluginServer*> *plugindb, int format)
 {
-       switch(format)
-       {
-               case FILE_SCENE:        return _(SCENE_NAME);
-               case FILE_AC3:          return _(AC3_NAME);
-               case FILE_WAV:          return _(WAV_NAME);
-               case FILE_PCM:          return _(PCM_NAME);
-               case FILE_AU:           return _(AU_NAME);
-               case FILE_AIFF:         return _(AIFF_NAME);
-               case FILE_SND:          return _(SND_NAME);
-               case FILE_PNG:          return _(PNG_NAME);
-               case FILE_PNG_LIST:     return _(PNG_LIST_NAME);
-               case FILE_JPEG:         return _(JPEG_NAME);
-               case FILE_JPEG_LIST:    return _(JPEG_LIST_NAME);
-               case FILE_CR2:          return _(CR2_NAME);
-               case FILE_CR2_LIST:     return _(CR2_LIST_NAME);
-               case FILE_FLAC:         return _(FLAC_NAME);
-               case FILE_EXR:          return _(EXR_NAME);
-               case FILE_EXR_LIST:     return _(EXR_LIST_NAME);
-               case FILE_MPEG:         return _(MPEG_NAME);
-               case FILE_AMPEG:        return _(AMPEG_NAME);
-               case FILE_VMPEG:        return _(VMPEG_NAME);
-               case FILE_TGA:          return _(TGA_NAME);
-               case FILE_TGA_LIST:     return _(TGA_LIST_NAME);
-               case FILE_TIFF:         return _(TIFF_NAME);
-               case FILE_TIFF_LIST:    return _(TIFF_LIST_NAME);
-               case FILE_OGG:          return _(OGG_NAME);
-               case FILE_VORBIS:       return _(VORBIS_NAME);
-               case FILE_RAWDV:        return _(RAWDV_NAME);
-               case FILE_FFMPEG:       return _(FFMPEG_NAME);
-               case FILE_DB:           return _(DBASE_NAME);
+       switch(format) {
+       case FILE_SCENE:        return _(SCENE_NAME);
+       case FILE_AC3:          return _(AC3_NAME);
+       case FILE_WAV:          return _(WAV_NAME);
+       case FILE_PCM:          return _(PCM_NAME);
+       case FILE_AU:           return _(AU_NAME);
+       case FILE_AIFF:         return _(AIFF_NAME);
+       case FILE_SND:          return _(SND_NAME);
+       case FILE_PNG:          return _(PNG_NAME);
+       case FILE_PNG_LIST:     return _(PNG_LIST_NAME);
+       case FILE_JPEG:         return _(JPEG_NAME);
+       case FILE_JPEG_LIST:    return _(JPEG_LIST_NAME);
+       case FILE_CR2:          return _(CR2_NAME);
+       case FILE_CR2_LIST:     return _(CR2_LIST_NAME);
+       case FILE_FLAC:         return _(FLAC_NAME);
+       case FILE_EXR:          return _(EXR_NAME);
+       case FILE_EXR_LIST:     return _(EXR_LIST_NAME);
+       case FILE_MPEG:         return _(MPEG_NAME);
+       case FILE_AMPEG:        return _(AMPEG_NAME);
+       case FILE_VMPEG:        return _(VMPEG_NAME);
+       case FILE_TGA:          return _(TGA_NAME);
+       case FILE_TGA_LIST:     return _(TGA_LIST_NAME);
+       case FILE_TIFF:         return _(TIFF_NAME);
+       case FILE_TIFF_LIST:    return _(TIFF_LIST_NAME);
+       case FILE_OGG:          return _(OGG_NAME);
+       case FILE_VORBIS:       return _(VORBIS_NAME);
+       case FILE_RAWDV:        return _(RAWDV_NAME);
+       case FILE_FFMPEG:       return _(FFMPEG_NAME);
+       case FILE_DB:           return _(DBASE_NAME);
        }
        return _("Unknown");
 }
@@ -1371,15 +1366,14 @@ int File::strtobits(const char *bits)
 const char* File::bitstostr(int bits)
 {
 //printf("File::bitstostr\n");
-       switch(bits)
-       {
-               case BITSLINEAR8:       return (NAME_8BIT);
-               case BITSLINEAR16:      return (NAME_16BIT);
-               case BITSLINEAR24:      return (NAME_24BIT);
-               case BITSLINEAR32:      return (NAME_32BIT);
-               case BITSULAW:          return (NAME_ULAW);
-               case BITS_ADPCM:        return (NAME_ADPCM);
-               case BITSFLOAT:         return (NAME_FLOAT);
+       switch(bits) {
+       case BITSLINEAR8:       return (NAME_8BIT);
+       case BITSLINEAR16:      return (NAME_16BIT);
+       case BITSLINEAR24:      return (NAME_24BIT);
+       case BITSLINEAR32:      return (NAME_32BIT);
+       case BITSULAW:          return (NAME_ULAW);
+       case BITS_ADPCM:        return (NAME_ADPCM);
+       case BITSFLOAT:         return (NAME_FLOAT);
        }
        return _("Unknown");
 }
@@ -1424,14 +1418,16 @@ int File::get_best_colormodel(Asset *asset, int driver)
 {
        switch(asset->format)
        {
-#ifdef HAVE_FIREWIRE
+#ifdef HAVE_DV
                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);
+#ifdef HAVE_OPENEXR
                case FILE_EXR:
                case FILE_EXR_LIST:     return FileEXR::get_best_colormodel(asset, driver);
+#endif
                case FILE_PNG:
                case FILE_PNG_LIST:     return FilePNG::get_best_colormodel(asset, driver);
                case FILE_TGA:
@@ -1532,6 +1528,7 @@ int File::supports_audio(int format)
                case FILE_AIFF:
                case FILE_SND:
                case FILE_FFMPEG:
+               case FILE_RAWDV:
                        return 1;
        }
        return 0;
@@ -1629,16 +1626,83 @@ 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;
+}
+
+void File::setenv_path(char *result, const char *var, const char *path)
+{
+       char *env = getenv(var);
+       if( env ) return;
+       char env_path[BCTEXTLEN];
+       getenv_path(env_path, path);
+       sprintf(result, "%s=%s", var, env_path);
+       putenv(result);
+}
+
+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];
+char File::cinbwr_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);
+
+       setenv_path(cindat_path, "CIN_DAT", CINDAT_DIR);
+       setenv_path(cinlib_path, "CIN_LIB", CINLIB_DIR);
+       setenv_path(cincfg_path, "CIN_CONFIG", CONFIG_DIR);
+       setenv_path(cinplg_path, "CIN_PLUGIN", PLUGIN_DIR);
+       setenv_path(cinlad_path, "CIN_LADSPA", LADSPA_DIR);
+       setenv_path(cinlcl_path, "CIN_LOCALE", LOCALE_DIR);
+       setenv_path(cinbwr_path, "CIN_BROWSER", CIN_BROWSER);
+}
+
+