png img proxy fixes, speed zoom segv fix, colapse ins 1frm silence undo, repair rende...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / filelist.C
index 0422596412183e67a4f2159e028f8a2bedd91a7c..dd78cf5726deeeb9924fb46b968bee5a70f40878 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "asset.h"
 #include "bcsignals.h"
+#include "cstrdup.h"
 #include "file.h"
 #include "filelist.h"
 #include "guicast.h"
@@ -34,6 +35,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
@@ -75,22 +77,27 @@ int FileList::reset_parameters_derived()
 
 int FileList::open_file(int rd, int wr)
 {
-       int result = 0;
+       int result = 1;
 
 // skip header for write
        if(file->wr)
        {
+               int fd = open(asset->path, O_CREAT+O_TRUNC+O_RDWR, 0777);
+               if( fd >= 0 ) {
+                       close(fd);
+                       result = 0;
 // Frame files are created in write_frame and list index is created when
 // file is closed.
 // Look for the starting number in the path but ignore the starting character
 // and total digits since these are used by the header.
-               Render::get_starting_number(asset->path,
-                       first_number,
-                       number_start,
-                       number_digits);
-               path_list.remove_all_objects();
-               writer = new FrameWriter(this,
+                       Render::get_starting_number(asset->path,
+                               first_number, number_start, number_digits);
+                       path_list.remove_all_objects();
+                       writer = new FrameWriter(this,
                        asset->format == list_type ? file->cpus : 1);
+               }
+               else
+                       eprintf(_("Error while opening \"%s\" for writing. \n%m\n"), asset->path);
        }
        else
        if(file->rd)
@@ -125,21 +132,28 @@ int FileList::open_file(int rd, int wr)
 //printf("FileList::open_file 2\n", asset->use_header);
 //printf("FileList::open_file %d\n", __LINE__);
                                        asset->format = frame_type;
+                                       int width = asset->width;
+                                       int height = asset->height;
                                        result = read_frame_header(asset->path);
+                                       asset->actual_width = asset->width;
+                                       if( width ) asset->width = width;
+                                       asset->actual_height = asset->height;
+                                       if( height ) asset->height = height;
                                        asset->layers = 1;
-                                       if(!asset->frame_rate)
+                                       if( !asset->frame_rate )
                                                asset->frame_rate = 1;
                                        asset->video_length = -1;
                                }
+                               result = 0;
                        }
+                       else
+                               eprintf(_("Error while opening \"%s\" for reading. \n%m\n"), asset->path);
                }
                else
                {
                        Render::get_starting_number(asset->path,
-                               first_number,
-                               number_start,
-                               number_digits,
-                               6);
+                               first_number, number_start, number_digits, 6);
+                       result = 0;
                }
        }
 
@@ -171,35 +185,31 @@ int FileList::close_file()
 int FileList::write_list_header()
 {
        FILE *stream = fopen(asset->path, "w");
+       if( !stream ) return 1;
 // Use sprintf instead of fprintf for VFS.
-       char string[BCTEXTLEN];
-       sprintf(string, "%s\n", list_prefix);
-       fwrite(string, strlen(string), 1, stream);
-       sprintf(string, "# First line is always %s\n", list_prefix);
-       fwrite(string, strlen(string), 1, stream);
-       sprintf(string, "# Frame rate:\n");
-       fwrite(string, strlen(string), 1, stream);
-       sprintf(string, "%f\n", asset->frame_rate);
-       fwrite(string, strlen(string), 1, stream);
-       sprintf(string, "# Width:\n");
-       fwrite(string, strlen(string), 1, stream);
-       sprintf(string, "%d\n", asset->width);
-       fwrite(string, strlen(string), 1, stream);
-       sprintf(string, "# Height:\n");
-       fwrite(string, strlen(string), 1, stream);
-       sprintf(string, "%d\n", asset->height);
-       fwrite(string, strlen(string), 1, stream);
-       sprintf(string, "# List of image files follows\n");
-       fwrite(string, strlen(string), 1, stream);
-
-       for(int i = 0; i < path_list.total; i++)
-       {
+       fprintf(stream, "%s\n", list_prefix);
+       fprintf(stream, "# First line is always %s\n", list_prefix);
+       fprintf(stream, "# Frame rate:\n");
+       fprintf(stream, "%f\n", asset->frame_rate);
+       fprintf(stream, "# Width:\n");
+       fprintf(stream, "%d\n", asset->width);
+       fprintf(stream, "# Height:\n");
+       fprintf(stream, "%d\n", asset->height);
+       fprintf(stream, "# List of image files follows\n");
+
+       char *cp = strrchr(asset->path, '/');
+       int dir_len = !cp ? 0 : cp - asset->path;
+
+       for(int i = 0; i < path_list.total; i++) {
+               const char *path = path_list.values[i];
 // Fix path for VFS but leave leading slash
-               if(!strncmp(path_list.values[i], RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
-                       sprintf(string, "%s\n", path_list.values[i] + strlen(RENDERFARM_FS_PREFIX));
-               else
-                       sprintf(string, "%s\n", path_list.values[i]);
-               fwrite(string, strlen(string), 1, stream);
+               if( !strncmp(path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)) )
+                       path += strlen(RENDERFARM_FS_PREFIX);
+// ./path for relative list access
+               else if( dir_len > 0 && !strncmp(path, asset->path, dir_len) ) {
+                       fprintf(stream, ".");  path += dir_len;
+               }
+               fprintf(stream, "%s\n", path);
        }
        fclose(stream);
        return 0;
@@ -207,59 +217,59 @@ int FileList::write_list_header()
 
 int FileList::read_list_header()
 {
-       char string[BCTEXTLEN], *new_entry;
+       char string[BCTEXTLEN];
 
        FILE *stream = fopen(asset->path, "r");
-
-
-       if(stream)
-       {
+       if( !stream ) return 1;
 // Get information about the frames
-               do
-               {
-                       (void)fgets(string, BCTEXTLEN, stream);
-               }while(!feof(stream) && (string[0] == '#' || string[0] == ' ' || isalpha(string[0])));
+       do {
+               if( feof(stream) || !fgets(string, BCTEXTLEN, stream) ) return 1;
+       } while(string[0] == '#' || string[0] == ' ' || isalpha(string[0]));
 
 // Don't want a user configured frame rate to get destroyed
-               if(asset->frame_rate == 0)
-                       asset->frame_rate = atof(string);
-
-               do
-               {
-                       (void)fgets(string, BCTEXTLEN, stream);
-               }while(!feof(stream) && (string[0] == '#' || string[0] == ' '));
-               asset->width = atol(string);
-
-               do
-               {
-                       (void)fgets(string, BCTEXTLEN, stream);
-               }while(!feof(stream) && (string[0] == '#' || string[0] == ' '));
-               asset->height = atol(string);
-
-               asset->interlace_mode = BC_ILACE_MODE_UNDETECTED;  // May be good to store the info in the list?
-               asset->layers = 1;
-               asset->audio_data = 0;
-               asset->video_data = 1;
-
-// Get all the paths
-               while(!feof(stream))
-               {
-                       (void)fgets(string, BCTEXTLEN, stream);
-                       if(strlen(string) && string[0] != '#' && string[0] != ' ' && !feof(stream))
-                       {
-                               string[strlen(string) - 1] = 0;
-                               path_list.append(new_entry = new char[strlen(string) + 1]);
-                               strcpy(new_entry, string);
-                       }
-               }
+       if(asset->frame_rate == 0)
+               asset->frame_rate = atof(string);
+
+       do {
+               if( feof(stream) || !fgets(string, BCTEXTLEN, stream) ) return 1;
+       } while(string[0] == '#' || string[0] == ' ');
+       if( (asset->width = atol(string)) <= 0 ) return 1;
+
+       do {
+               if( feof(stream) || !fgets(string, BCTEXTLEN, stream) ) return 1;
+       } while(string[0] == '#' || string[0] == ' ');
+       if( (asset->height = atol(string)) <= 0 ) return 1;
+
+       asset->interlace_mode = ILACE_MODE_UNDETECTED;
+       asset->layers = 1;
+       asset->audio_data = 0;
+       asset->video_data = 1;
 
-//for(int i = 0; i < path_list.total; i++) printf("%s\n", path_list.values[i]);
-               fclose(stream);
-               asset->video_length = path_list.total;
+       char prefix[BCTEXTLEN], *bp = prefix, *cp = strrchr(asset->path, '/');
+       for( int i=0, n=!cp ? 0 : cp-asset->path; i<n; ++i ) *bp++ = asset->path[i];
+       *bp = 0;
+
+// Get all the paths, expand relative paths
+       int missing = 0;
+       while( !feof(stream) && fgets(string, BCTEXTLEN, stream) ) {
+               int len = strlen(string);
+               if( !len || string[0] == '#' || string[0] == ' ' ) continue;
+               if( string[len-1] == '\n' ) string[len-1] = 0;
+               char path[BCTEXTLEN], *pp = path, *ep = pp + sizeof(path)-1;
+               if( string[0] == '.' && string[1] == '/' && prefix[0] )
+                       pp += snprintf(pp, ep-pp, "%s/", prefix);
+               snprintf(pp, ep-pp, "%s", string);
+               if( access(path, R_OK) && !missing++ )
+                       eprintf(_("%s:no such file"), path);
+               path_list.append(cstrdup(path));
        }
-       else
-               return 1;
 
+//for(int i = 0; i < path_list.total; i++) printf("%s\n", path_list.values[i]);
+       fclose(stream);
+       if( !(asset->video_length = path_list.total) )
+               eprintf(_("%s:\nlist empty"), asset->path);
+       if( missing )
+               eprintf(_("%s:\n%d files not found"), asset->path, missing);
        return 0;
 }
 
@@ -295,7 +305,7 @@ int FileList::read_frame(VFrame *frame)
 
                FILE *in;
 
-// Fix path for VFS
+// Fix path for VFS.  Not used anymore.
                if(!strncmp(asset->path, RENDERFARM_FS_PREFIX, strlen(RENDERFARM_FS_PREFIX)))
                        sprintf(string, "%s%s", RENDERFARM_FS_PREFIX, path);
                else
@@ -339,6 +349,7 @@ int FileList::read_frame(VFrame *frame)
        }
        else
        {
+               asset->single_frame = 1;
 // Allocate and decompress single frame into new temporary
 //printf("FileList::read_frame %d\n", frame->get_color_model());
                if(!temp || temp->get_color_model() != frame->get_color_model())
@@ -366,12 +377,8 @@ int FileList::read_frame(VFrame *frame)
                                                        data->allocate_compressed_data(ostat.st_size);
                                                        data->set_compressed_size(ostat.st_size);
                                                        (void)fread(data->get_data(), ostat.st_size, 1, fd);
-                                                       temp = new VFrame(0,
-                                                               -1,
-                                                               asset->width,
-                                                               asset->height,
-                                                               frame->get_color_model(),
-                                                               -1);
+                                                       temp = new VFrame(asset->actual_width, asset->actual_height,
+                                                                       frame->get_color_model(), 0);
                                                        read_frame(temp, data);
                                                        break;
                                        }
@@ -386,50 +393,17 @@ int FileList::read_frame(VFrame *frame)
                        }
                        else
                        {
-                               temp = new VFrame(0,
-                                       -1,
-                                       asset->width,
-                                       asset->height,
-                                       frame->get_color_model(),
-                                       -1);
+                               temp = new VFrame(asset->actual_width, asset->actual_height,
+                                       frame->get_color_model(), 0);
                                read_frame(temp, asset->path);
                        }
                }
 
                if(!temp) return result;
 
-// printf("FileList::read_frame frame=%d temp=%d\n",
-// frame->get_color_model(),
-// temp->get_color_model());
-               if(frame->get_color_model() == temp->get_color_model())
-               {
-                       frame->copy_from(temp);
-               }
-               else
-               {
-// Never happens
-                       BC_CModels::transfer(frame->get_rows(), /* Leave NULL if non existent */
-                               temp->get_rows(),
-                               frame->get_y(), /* Leave NULL if non existent */
-                               frame->get_u(),
-                               frame->get_v(),
-                               temp->get_y(), /* Leave NULL if non existent */
-                               temp->get_u(),
-                               temp->get_v(),
-                               0,        /* Dimensions to capture from input frame */
-                               0,
-                               asset->width,
-                               asset->height,
-                               0,       /* Dimensions to project on output frame */
-                               0,
-                               asset->width,
-                               asset->height,
-                               temp->get_color_model(),
-                               frame->get_color_model(),
-                               0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
-                               temp->get_w(),       /* For planar use the luma rowspan */
-                               frame->get_w());
-               }
+//printf("FileList::read_frame frame=%d temp=%d\n",
+// frame->get_color_model(), // temp->get_color_model());
+               frame->transfer_from(temp);
        }