r1051: Resources window: Keep the divider inside the window.
[cinelerra_cv.git] / libmpeg3 / mpeg3io.c
blobc8e77bc507625c3fa232e52c23c9fed9dd6f863a
1 #include "mpeg3private.h"
2 #include "mpeg3protos.h"
4 #include <mntent.h>
5 #include <stdint.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/stat.h>
10 mpeg3_fs_t* mpeg3_new_fs(char *path)
12 mpeg3_fs_t *fs = calloc(1, sizeof(mpeg3_fs_t));
13 fs->buffer = calloc(1, MPEG3_IO_SIZE);
14 // Force initial read
15 fs->buffer_position = -0xffff;
16 fs->css = mpeg3_new_css();
17 strcpy(fs->path, path);
18 return fs;
21 int mpeg3_delete_fs(mpeg3_fs_t *fs)
23 mpeg3_delete_css(fs->css);
24 free(fs->buffer);
25 free(fs);
26 return 0;
29 int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src)
31 strcpy(dst->path, src->path);
32 dst->current_byte = 0;
33 return 0;
36 int64_t mpeg3io_get_total_bytes(mpeg3_fs_t *fs)
38 struct stat64 ostat;
39 stat64(fs->path, &ostat);
40 fs->total_bytes = ostat.st_size;
41 return fs->total_bytes;
44 * fseek(fs->fd, 0, SEEK_END);
45 * fs->total_bytes = ftell(fs->fd);
46 * fseek(fs->fd, 0, SEEK_SET);
47 * return fs->total_bytes;
51 int64_t mpeg3io_path_total_bytes(char *path)
53 struct stat64 st;
54 if(stat64(path, &st) < 0) return 0;
55 return st.st_size;
58 int mpeg3io_open_file(mpeg3_fs_t *fs)
60 /* Need to perform authentication before reading a single byte. */
61 mpeg3_get_keys(fs->css, fs->path);
63 //printf("mpeg3io_open_file 1 %s\n", fs->path);
64 if(!(fs->fd = fopen64(fs->path, "rb")))
66 if (fs->path) fprintf(stderr,"[mpeg3io_open_file] Error opening file '%s': ",fs->path);
67 perror("");
68 return 1;
71 fs->total_bytes = mpeg3io_get_total_bytes(fs);
73 if(!fs->total_bytes)
75 fclose(fs->fd);
76 return 1;
79 fs->current_byte = 0;
80 fs->buffer_position = -0xffff;
81 return 0;
84 int mpeg3io_close_file(mpeg3_fs_t *fs)
86 if(fs->fd) fclose(fs->fd);
87 fs->fd = 0;
88 return 0;
91 int mpeg3io_read_data(unsigned char *buffer, int64_t bytes, mpeg3_fs_t *fs)
93 int result = 0, i, fragment_size;
94 //printf("mpeg3io_read_data 1 %d\n", bytes);
96 for(i = 0; bytes > 0 && !result; )
98 result = mpeg3io_sync_buffer(fs);
99 //printf("mpeg3io_read_data 2\n");
101 fragment_size = MPEG3_IO_SIZE;
103 if(fragment_size > bytes) fragment_size = bytes;
105 if(fs->buffer_offset + fragment_size > fs->buffer_size)
106 fragment_size = fs->buffer_size - fs->buffer_offset;
108 memcpy(buffer + i, fs->buffer + fs->buffer_offset, fragment_size);
110 fs->buffer_offset += fragment_size;
111 fs->current_byte += fragment_size;
112 i += fragment_size;
113 bytes -= fragment_size;
114 //printf("mpeg3io_read_data 10 %d\n", bytes);
117 //printf("mpeg3io_read_data 100 %d\n", bytes);
118 return (result && bytes);
121 int mpeg3io_seek(mpeg3_fs_t *fs, int64_t byte)
123 //printf("mpeg3io_seek 1 %lld\n", byte);
124 fs->current_byte = byte;
125 return (fs->current_byte < 0) || (fs->current_byte > fs->total_bytes);
128 int mpeg3io_seek_relative(mpeg3_fs_t *fs, int64_t bytes)
130 //printf("mpeg3io_seek_relative 1 %lld\n", bytes);
131 fs->current_byte += bytes;
132 return (fs->current_byte < 0) || (fs->current_byte > fs->total_bytes);
136 void mpeg3io_read_buffer(mpeg3_fs_t *fs)
138 // Special case for sequential reverse buffer.
139 // This is only used for searching for previous codes.
140 // Here we move a full half buffer backwards since the search normally
141 // goes backwards and then forwards a little bit.
142 if(fs->current_byte < fs->buffer_position &&
143 fs->current_byte >= fs->buffer_position - MPEG3_IO_SIZE / 2)
145 int64_t new_buffer_position = fs->current_byte - MPEG3_IO_SIZE / 2;
146 int64_t new_buffer_size = MIN(fs->buffer_size + MPEG3_IO_SIZE / 2,
147 MPEG3_IO_SIZE);
148 if(new_buffer_position < 0)
150 new_buffer_size += new_buffer_position;
151 new_buffer_position = 0;
154 // Shift existing buffer forward and calculate amount of new data needed.
155 int remainder = new_buffer_position + new_buffer_size - fs->buffer_position;
156 if(remainder < 0) remainder = 0;
157 int remainder_start = new_buffer_size - remainder;
158 if(remainder)
160 memmove(fs->buffer + remainder_start, fs->buffer, remainder);
165 fseeko64(fs->fd, new_buffer_position, SEEK_SET);
166 fread(fs->buffer, 1, remainder_start, fs->fd);
169 fs->buffer_position = new_buffer_position;
170 fs->buffer_size = new_buffer_size;
171 fs->buffer_offset = fs->current_byte - fs->buffer_position;
173 else
174 // Sequential forward buffer or random seek
176 int result;
177 fs->buffer_position = fs->current_byte;
178 fs->buffer_offset = 0;
180 result = fseeko64(fs->fd, fs->buffer_position, SEEK_SET);
181 //printf("mpeg3io_read_buffer 2 %llx %llx\n", fs->buffer_position, ftell(fs->fd));
182 fs->buffer_size = fread(fs->buffer, 1, MPEG3_IO_SIZE, fs->fd);
187 * printf(__FUNCTION__ " 2 result=%d ftell=%llx buffer_position=%llx %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x\n",
188 * result,
189 * ftello64(fs->fd),
190 * fs->buffer_position,
191 * fs->buffer[0x0],
192 * fs->buffer[0x1],
193 * fs->buffer[0x2],
194 * fs->buffer[0x3],
195 * fs->buffer[0x4],
196 * fs->buffer[0x5],
197 * fs->buffer[0x6],
198 * fs->buffer[0x7],
199 * fs->buffer[0x12],
200 * fs->buffer[0x13]);
205 void mpeg3io_complete_path(char *complete_path, char *path)
207 if(path[0] != '/')
209 char current_dir[MPEG3_STRLEN];
210 getcwd(current_dir, MPEG3_STRLEN);
211 sprintf(complete_path, "%s/%s", current_dir, path);
213 else
214 strcpy(complete_path, path);
217 int mpeg3io_device(char *path, char *device)
219 struct stat64 file_st, device_st;
220 struct mntent *mnt;
221 FILE *fp;
223 if(stat64(path, &file_st) < 0)
225 perror("mpeg3io_device");
226 return 1;
229 fp = setmntent(MOUNTED, "r");
230 while(fp && (mnt = getmntent(fp)))
232 if(stat64(mnt->mnt_fsname, &device_st) < 0) continue;
233 if(device_st.st_rdev == file_st.st_dev)
235 strncpy(device, mnt->mnt_fsname, MPEG3_STRLEN);
236 break;
239 endmntent(fp);
241 return 0;
244 void mpeg3io_get_directory(char *directory, char *path)
246 char *ptr = strrchr(path, '/');
247 if(ptr)
249 int i;
250 for(i = 0; i < ptr - path; i++)
252 directory[i] = path[i];
254 directory[i] = 0;
258 void mpeg3io_get_filename(char *filename, char *path)
260 char *ptr = strrchr(path, '/');
261 if(!ptr)
262 ptr = path;
263 else
264 ptr++;
266 strcpy(filename, ptr);
269 void mpeg3io_joinpath(char *title_path, char *directory, char *new_filename)
271 sprintf(title_path, "%s/%s", directory, new_filename);