comparison vobsub.c @ 25361:f95cd1391ea0

Support using unrar executable to access rar-compressed vobsub files.
author ulion
date Fri, 14 Dec 2007 08:16:39 +0000
parents 078bdfd44751
children 40bda123d2e7
comparison
equal deleted inserted replaced
25360:574ff7687644 25361:f95cd1391ea0
18 #include "version.h" 18 #include "version.h"
19 19
20 #include "vobsub.h" 20 #include "vobsub.h"
21 #include "spudec.h" 21 #include "spudec.h"
22 #include "mp_msg.h" 22 #include "mp_msg.h"
23 #ifdef USE_UNRARLIB 23 #ifdef USE_UNRAR_EXEC
24 #include "unrar_exec.h"
25 #elif defined(USE_UNRARLIB)
24 #include "unrarlib.h" 26 #include "unrarlib.h"
25 #endif 27 #endif
26 #include "libavutil/common.h" 28 #include "libavutil/common.h"
27 29
28 extern int vobsub_id; 30 extern int vobsub_id;
33 /********************************************************************** 35 /**********************************************************************
34 * RAR stream handling 36 * RAR stream handling
35 * The RAR file must have the same basename as the file to open 37 * The RAR file must have the same basename as the file to open
36 * See <URL:http://www.unrarlib.org/> 38 * See <URL:http://www.unrarlib.org/>
37 **********************************************************************/ 39 **********************************************************************/
38 #ifdef USE_UNRARLIB 40 #if defined(USE_UNRARLIB) || defined(USE_UNRAR_EXEC)
39 typedef struct { 41 typedef struct {
40 FILE *file; 42 FILE *file;
41 unsigned char *data; 43 unsigned char *data;
42 unsigned long size; 44 unsigned long size;
43 unsigned long pos; 45 unsigned long pos;
57 /* first try normal access */ 59 /* first try normal access */
58 stream->file = fopen(filename, mode); 60 stream->file = fopen(filename, mode);
59 if (stream->file == NULL) { 61 if (stream->file == NULL) {
60 char *rar_filename; 62 char *rar_filename;
61 const char *p; 63 const char *p;
62 int rc; 64 int rc = 0;
63 /* Guess the RAR archive filename */ 65 /* Guess the RAR archive filename */
64 rar_filename = NULL; 66 rar_filename = NULL;
65 p = strrchr(filename, '.'); 67 p = strrchr(filename, '.');
66 if (p) { 68 if (p) {
67 ptrdiff_t l = p - filename; 69 ptrdiff_t l = p - filename;
86 if ((p = strrchr(filename, '/')) == NULL) { 88 if ((p = strrchr(filename, '/')) == NULL) {
87 p = filename; 89 p = filename;
88 } else { 90 } else {
89 p++; 91 p++;
90 } 92 }
93 #ifdef USE_UNRAR_EXEC
94 rc = unrar_exec_get(&stream->data, &stream->size, p, rar_filename);
95 #endif
96 #ifdef USE_UNRARLIB
97 if (!rc)
91 rc = urarlib_get(&stream->data, &stream->size, (char*) p, rar_filename, ""); 98 rc = urarlib_get(&stream->data, &stream->size, (char*) p, rar_filename, "");
99 #endif
92 if (!rc) { 100 if (!rc) {
93 /* There is no matching filename in the archive. However, sometimes 101 /* There is no matching filename in the archive. However, sometimes
94 * the files we are looking for have been given arbitrary names in the archive. 102 * the files we are looking for have been given arbitrary names in the archive.
95 * Let's look for a file with an exact match in the extension only. */ 103 * Let's look for a file with an exact match in the extension only. */
96 int i, num_files, name_len; 104 int i, num_files = -1, name_len;
97 ArchiveList_struct *list, *lp; 105 ArchiveList_struct *list, *lp;
106 #ifdef USE_UNRARLIB
98 /* the cast in the next line is a hack to overcome a design flaw (IMHO) in unrarlib */ 107 /* the cast in the next line is a hack to overcome a design flaw (IMHO) in unrarlib */
99 num_files = urarlib_list (rar_filename, (ArchiveList_struct *)&list); 108 num_files = urarlib_list (rar_filename, (ArchiveList_struct *)&list);
109 #endif
110 #ifdef USE_UNRAR_EXEC
111 if (num_files <= 0)
112 num_files = unrar_exec_list(rar_filename, &list);
113 #endif
100 if (num_files > 0) { 114 if (num_files > 0) {
101 char *demanded_ext; 115 char *demanded_ext;
102 demanded_ext = strrchr (p, '.'); 116 demanded_ext = strrchr (p, '.');
103 if (demanded_ext) { 117 if (demanded_ext) {
104 int demanded_ext_len = strlen (demanded_ext); 118 int demanded_ext_len = strlen (demanded_ext);
105 for (i=0, lp=list; i<num_files; i++, lp=lp->next) { 119 for (i=0, lp=list; i<num_files; i++, lp=lp->next) {
106 name_len = strlen (lp->item.Name); 120 name_len = strlen (lp->item.Name);
107 if (name_len >= demanded_ext_len && !strcasecmp (lp->item.Name + name_len - demanded_ext_len, demanded_ext)) { 121 if (name_len >= demanded_ext_len && !strcasecmp (lp->item.Name + name_len - demanded_ext_len, demanded_ext)) {
108 if ((rc = urarlib_get(&stream->data, &stream->size, lp->item.Name, rar_filename, ""))) { 122 #ifdef USE_UNRAR_EXEC
109 break; 123 rc = unrar_exec_get(&stream->data, &stream->size,
110 } 124 lp->item.Name, rar_filename);
125 if (rc) break;
126 #endif
127 #ifdef USE_UNRARLIB
128 rc = urarlib_get(&stream->data, &stream->size,
129 lp->item.Name, rar_filename, "");
130 if (rc) break;
131 #endif
111 } 132 }
112 } 133 }
113 } 134 }
135 #ifdef USE_UNRARLIB
114 urarlib_freelist (list); 136 urarlib_freelist (list);
137 #else
138 unrar_exec_freelist(list);
139 #endif
115 } 140 }
116 if (!rc) { 141 if (!rc) {
117 free(rar_filename); 142 free(rar_filename);
118 free(stream); 143 free(stream);
119 return NULL; 144 return NULL;