/amplayer/player/player_sub.c
C | 1893 lines | 1566 code | 227 blank | 100 comment | 588 complexity | a63399465d200142c4affc0aa021c982 MD5 | raw file
Possible License(s): LGPL-3.0, CC-BY-SA-3.0, GPL-2.0, GPL-3.0, LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- /*******************************************************************
- *
- * Copyright C 2005 by Amlogic, Inc. All Rights Reserved.
- *
- * Description:
- *
- * Author: Amlogic Software
- * Created: 12/22/2005 9:13PM
- *
- *******************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <sys/stat.h>
- #include "list.h"
- #include "player_sub.h"
- #include "player_priv.h"
- #define DUMP_SUB
- static float mpsub_position = 0;
- static int sub_slacktime = 20000; //20 sec
- static int sub_no_text_pp = 0; // 1 => do not apply text post-processing
- // like {\...} elimination in SSA format.
- /* read one line of string from data source */
- static char *subfile_buffer = NULL;
- static int buffer_size;
- static unsigned subfile_read;
- static char *internal_subf_gets(char *s, int fd)
- {
- int offset = subfile_read;
- int copied;
- if (!subfile_buffer) {
- subfile_buffer = (char *)MALLOC(LINE_LEN);
- if (subfile_buffer) {
- subfile_read = 0;
- offset = 0;
- buffer_size = read(fd, subfile_buffer, LINE_LEN);
- if (buffer_size <= 0) {
- return NULL;
- }
- } else {
- log_error("no enough memory!\n");
- return NULL;
- }
- }
- while ((offset < buffer_size) && (subfile_buffer[offset] != '\n')) {
- offset++;
- }
- if (offset < buffer_size) {
- MEMCPY(s, subfile_buffer + subfile_read, offset - subfile_read);
- s[offset - subfile_read ] = '\0';
- subfile_read = offset + 1;
- if (subfile_read == LINE_LEN) {
- subfile_read = 0;
- buffer_size = read(fd, subfile_buffer, LINE_LEN);
- }
- } else {
- if (buffer_size < LINE_LEN) {
- /* end of file w/o terminator "\n" */
- return NULL;
- }
- copied = LINE_LEN - subfile_read;
- MEMCPY(s, subfile_buffer + subfile_read, copied);
- if (buffer_size == LINE_LEN) {
- /* refill */
- buffer_size = read(fd, subfile_buffer, LINE_LEN);
- if (buffer_size < 0) {
- return NULL;
- }
- }
- offset = 0;
- while ((offset < MIN(LINE_LEN - copied, buffer_size)) && (subfile_buffer[offset] != '\n')) {
- offset++;
- }
- if (subfile_buffer[offset] == '\n') {
- subfile_read = offset + 1;
- if (offset) {
- memcpy(s + copied, subfile_buffer, offset);
- }
- s[copied + offset + 1] = '\0';
- } else if (buffer_size < LINE_LEN) {
- /* end of file w/o terminator "\n" */
- return NULL;
- } else {
- s[LINE_LEN + 1] = '\0';
- }
- }
- return s;
- }
- /* internal string manipulation functions */
- static int internal_eol(char p)
- {
- return (p == '\r' || p == '\n' || p == '\0');
- }
- static void internal_trail_space(char *s)
- {
- int i = 0;
- while (isspace(s[i])) {
- ++i;
- }
- if (i) {
- strcpy(s, s + i);
- }
- i = strlen(s) - 1;
- while (i > 0 && isspace(s[i])) {
- s[i--] = '\0';
- }
- }
- static char *internal_stristr(const char *haystack, const char *needle)
- {
- int len = 0;
- const char *p = haystack;
- if (!(haystack && needle)) {
- return NULL;
- }
- len = strlen(needle);
- while (*p != '\0') {
- if (strncasecmp(p, needle, len) == 0) {
- return (char*)p;
- }
- p++;
- }
- return NULL;
- }
- static char *internal_sub_readtext(char *source, char **dest)
- {
- int len = 0;
- char *p = source;
- while (!internal_eol(*p) && *p != '|') {
- p++, len++;
- }
- if (*dest == NULL) {
- *dest = (char *)MALLOC(len + 1);
- }
- if (*dest) {
- return ERR;
- }
- strncpy(*dest, source, len);
- (*dest)[len] = 0;
- while (*p == '\r' || *p == '\n' || *p == '|') {
- p++;
- }
- if (*p) {
- /* not-last text field */
- return p;
- } else {
- /* last text field */
- return NULL;
- }
- }
- static char *internal_sub_strdup(char *src)
- {
- char *ret;
- int len;
- len = strlen(src);
- ret = (char *)MALLOC(len + 1);
- if (ret) {
- strcpy(ret, src);
- }
- return ret;
- }
- /* subtitle file read line functions */
- static subtitle_t *internal_sub_read_line_sami(int fd, subtitle_t *current)
- {
- static char line[LINE_LEN + 1];
- static char *s = NULL, *slacktime_s;
- char text[LINE_LEN + 1], *p = NULL, *q;
- int state;
- current->text.lines = current->start = current->end = 0;
- current->text.alignment = SUB_ALIGNMENT_BOTTOMCENTER;
- state = 0;
- /* read the first line */
- if (!s) {
- s = internal_subf_gets(line, fd);
- if (!s) {
- return 0;
- }
- }
- do {
- switch (state) {
- case 0: /* find "START=" or "Slacktime:" */
- slacktime_s = internal_stristr(s, "Slacktime:");
- if (slacktime_s) {
- sub_slacktime = strtol(slacktime_s + 10, NULL, 0) / 10;
- }
- s = internal_stristr(s, "Start=");
- if (s) {
- current->start = strtol(s + 6, &s, 0) / 10;
- /* eat '>' */
- for (; *s != '>' && *s != '\0'; s++) {
- ;
- }
- s++;
- state = 1;
- continue;
- }
- break;
- case 1: /* find (optionnal) "<P", skip other TAGs */
- for (; *s == ' ' || *s == '\t'; s++) {
- ; /* strip blanks, if any */
- }
- if (*s == '\0') {
- break;
- }
- if (*s != '<') {
- state = 3;
- p = text;
- continue;
- } /* not a TAG */
- s++;
- if (*s == 'P' || *s == 'p') {
- s++;
- state = 2;
- continue;
- } /* found '<P' */
- for (; *s != '>' && *s != '\0'; s++) {
- ; /* skip remains of non-<P> TAG */
- }
- if (s == '\0') {
- break;
- }
- s++;
- continue;
- case 2: /* find ">" */
- s = strchr(s, '>');
- if (s) {
- s++;
- state = 3;
- p = text;
- continue;
- }
- break;
- case 3: /* get all text until '<' appears */
- if (*s == '\0') {
- break;
- } else if (!strncasecmp(s, "<br>", 4)) {
- *p = '\0';
- p = text;
- internal_trail_space(text);
- if (text[0] != '\0') {
- current->text.text[current->text.lines++] = internal_sub_strdup(text);
- }
- s += 4;
- } else if ((*s == '{') && !sub_no_text_pp) {
- state = 5;
- ++s;
- continue;
- } else if (*s == '<') {
- state = 4;
- } else if (!strncasecmp(s, " ", 6)) {
- *p++ = ' ';
- s += 6;
- } else if (*s == '\t') {
- *p++ = ' ';
- s++;
- } else if (*s == '\r' || *s == '\n') {
- s++;
- } else {
- *p++ = *s++;
- }
- /* skip duplicated space */
- if (p > text + 2) if (*(p - 1) == ' ' && *(p - 2) == ' ') {
- p--;
- }
- continue;
- case 4: /* get current->end or skip <TAG> */
- q = internal_stristr(s, "Start=");
- if (q) {
- current->end = strtol(q + 6, &q, 0) / 10 - 1;
- *p = '\0';
- internal_trail_space(text);
- if (text[0] != '\0') {
- current->text.text[current->text.lines++] = internal_sub_strdup(text);
- }
- if (current->text.lines > 0) {
- state = 99;
- break;
- }
- state = 0;
- continue;
- }
- s = strchr(s, '>');
- if (s) {
- s++;
- state = 3;
- continue;
- }
- break;
- case 5: /* get rid of {...} text, but read the alignment code */
- if ((*s == '\\') && (*(s + 1) == 'a') && !sub_no_text_pp) {
- if (internal_stristr(s, "\\a1") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_BOTTOMLEFT;
- s = s + 3;
- }
- if (internal_stristr(s, "\\a2") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_BOTTOMCENTER;
- s = s + 3;
- } else if (internal_stristr(s, "\\a3") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_BOTTOMRIGHT;
- s = s + 3;
- } else if ((internal_stristr(s, "\\a4") != NULL) || (internal_stristr(s, "\\a5") != NULL) || (internal_stristr(s, "\\a8") != NULL)) {
- current->text.alignment = SUB_ALIGNMENT_TOPLEFT;
- s = s + 3;
- } else if (internal_stristr(s, "\\a6") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_TOPCENTER;
- s = s + 3;
- } else if (internal_stristr(s, "\\a7") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_TOPRIGHT;
- s = s + 3;
- } else if (internal_stristr(s, "\\a9") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_MIDDLELEFT;
- s = s + 3;
- } else if (internal_stristr(s, "\\a10") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_MIDDLECENTER;
- s = s + 4;
- } else if (internal_stristr(s, "\\a11") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_MIDDLERIGHT;
- s = s + 4;
- }
- }
- if (*s == '}') {
- state = 3;
- }
- ++s;
- continue;
- }
- /* read next line */
- s = internal_subf_gets(line, fd);
- if (state != 99 && !s) {
- if (current->start > 0) {
- break; // if it is the last subtitle
- } else {
- return 0;
- }
- }
- } while (state != 99);
- /* For the last subtitle */
- if (current->end <= 0) {
- current->end = current->start + sub_slacktime;
- *p = '\0';
- internal_trail_space(text);
- if (text[0] != '\0') {
- current->text.text[current->text.lines++] = internal_sub_strdup(text);
- }
- }
- return current;
- }
- subtitle_t *internal_sub_read_line_microdvd(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- char line2[LINE_LEN + 1];
- char *p, *next;
- int i;
- float ptsrate = (float)current->end / 960;
- current->end = 0;
- do {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- } while ((sscanf(line, "{%ld}{}%[^\r\n]", &(current->start), line2) < 2) &&
- (sscanf(line, "{%ld}{%ld}%[^\r\n]", &(current->start), &(current->end), line2) < 3));
- p = line2;
- next = p, i = 0;
- while (1) {
- next = internal_sub_readtext(next, &(current->text.text[i]));
- if (!next) {
- break;
- }
- if (current->text.text[i] == ERR) {
- return ERR;
- }
- i++;
- if (i >= SUB_MAX_TEXT) {
- log_print(("Too many lines in a subtitle\n"));
- current->text.lines = i;
- return current;
- }
- }
- current->text.lines = ++i;
- current->start = current->start * ptsrate;
- current->end = current->end * ptsrate;
- return current;
- }
- subtitle_t *internal_sub_read_line_mpl2(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- char line2[LINE_LEN + 1];
- char *p, *next;
- int i;
- do {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- } while ((sscanf(line, "[%ld][%ld]%[^\r\n]", &(current->start), &(current->end), line2) < 3));
- current->start *= 10;
- current->end *= 10;
- p = line2;
- next = p, i = 0;
- while (1) {
- next = internal_sub_readtext(next, &(current->text.text[i]));
- if (!next) {
- break;
- }
- if (current->text.text[i] == ERR) {
- return ERR;
- }
- i++;
- if (i >= SUB_MAX_TEXT) {
- log_print(("Too many lines in a subtitle\n"));
- current->text.lines = i;
- return current;
- }
- }
- current->text.lines = ++i;
- return current;
- }
- subtitle_t *internal_sub_read_line_subrip(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- int a1, a2, a3, a4, b1, b2, b3, b4;
- char *p = NULL, *q = NULL;
- int len;
- while (1) {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- if (sscanf(line, "%d:%d:%d.%d,%d:%d:%d.%d",
- &a1, &a2, &a3, &a4, &b1, &b2, &b3, &b4) < 8) {
- continue;
- }
- current->start = a1 * 360000 + a2 * 6000 + a3 * 100 + a4;
- current->end = b1 * 360000 + b2 * 6000 + b3 * 100 + b4;
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- p = q = line;
- for (current->text.lines = 1; current->text.lines < SUB_MAX_TEXT; current->text.lines++) {
- for (q = p, len = 0; *p && *p != '\r' && *p != '\n' && *p != '|' && strncmp(p, "[br]", 4); p++, len++) {
- ;
- }
- current->text.text[current->text.lines - 1] = (char *)MALLOC(len + 1);
- if (!current->text.text[current->text.lines - 1]) {
- return ERR;
- }
- strncpy(current->text.text[current->text.lines - 1], q, len);
- current->text.text[current->text.lines - 1][len] = '\0';
- if (!*p || *p == '\r' || *p == '\n') {
- break;
- }
- if (*p == '|') {
- p++;
- } else {
- while (*p++ != ']') {
- ;
- }
- }
- }
- break;
- }
- return current;
- }
- subtitle_t *internal_sub_read_line_subviewer(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- int a1, a2, a3, a4, b1, b2, b3, b4;
- char *p = NULL;
- int i, len;
- while (!current->text.text[0]) {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- if ((len = sscanf(line,
- "%d:%d:%d%[,.:]%d --> %d:%d:%d%[,.:]%d",
- &a1, &a2, &a3, (char *)&i, &a4, &b1, &b2, &b3,
- (char *)&i, &b4)) < 10) {
- continue;
- }
- current->start = a1 * 360000 + a2 * 6000 + a3 * 100 + a4 / 10;
- current->end = b1 * 360000 + b2 * 6000 + b3 * 100 + b4 / 10;
- for (i = 0; i < SUB_MAX_TEXT;) {
- if (!internal_subf_gets(line, fd)) {
- break;
- }
- len = 0;
- for (p = line; *p != '\n' && *p != '\r' && *p; p++, len++) {
- ;
- }
- if (len) {
- int j = 0, skip = 0;
- char *curptr = current->text.text[i] = (char *)MALLOC(len + 1);
- if (!current->text.text[i]) {
- return ERR;
- }
- for (; j < len; j++) {
- /* let's filter html tags ::atmos */
- if (line[j] == '>') {
- skip = 0;
- continue;
- }
- if (line[j] == '<') {
- skip = 1;
- continue;
- }
- if (skip) {
- continue;
- }
- *curptr = line[j];
- curptr++;
- }
- *curptr = '\0';
- i++;
- } else {
- break;
- }
- }
- current->text.lines = i;
- }
- return current;
- }
- subtitle_t *internal_sub_read_line_subviewer2(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- int a1, a2, a3, a4;
- char *p = NULL;
- int i, len;
- while (!current->text.text[0]) {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- if (line[0] != '{') {
- continue;
- }
- if ((len = sscanf(line, "{T %d:%d:%d:%d", &a1, &a2, &a3, &a4)) < 4) {
- continue;
- }
- current->start = a1 * 360000 + a2 * 6000 + a3 * 100 + a4 / 10;
- for (i = 0; i < SUB_MAX_TEXT;) {
- if (!internal_subf_gets(line, fd)) {
- break;
- }
- if (line[0] == '}') {
- break;
- }
- len = 0;
- for (p = line; *p != '\n' && *p != '\r' && *p; ++p, ++len) {
- ;
- }
- if (len) {
- current->text.text[i] = (char *)MALLOC(len + 1);
- if (!current->text.text[i]) {
- return ERR;
- }
- strncpy(current->text.text[i], line, len);
- current->text.text[i][len] = '\0';
- ++i;
- } else {
- break;
- }
- }
- current->text.lines = i;
- }
- return current;
- }
- subtitle_t *internal_sub_read_line_vplayer(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- int a1, a2, a3;
- char *p = NULL, *next, separator;
- int i, len, plen;
- while (!current->text.text[0]) {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- if ((len = sscanf(line, "%d:%d:%d%c%n", &a1, &a2, &a3, &separator, &plen)) < 4) {
- continue;
- }
- current->start = a1 * 360000 + a2 * 6000 + a3 * 100;
- if (!current->start) {
- continue;
- }
- p = &line[plen];
- //log_print("plen %d, p %s\n", plen, p);
- i = 0;
- if (*p != '|') {
- next = p;
- while (1) {
- next = internal_sub_readtext(next, &(current->text.text[i]));
- if (!next) {
- break;
- }
- if (current->text.text[i] == ERR) {
- return ERR;
- }
- i++;
- if (i >= SUB_MAX_TEXT) {
- log_print(("Too many lines in a subtitle\n"));
- current->text.lines = i;
- while (1) {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- if ((len = sscanf(line, "%d:%d:%d%c%n", &a1, &a2, &a3, &separator, &plen)) < 4) {
- continue;
- } else {
- current->end = a1 * 360000 + a2 * 6000 + a3 * 100;
- return current;
- }
- }
- return current;
- }
- }
- current->text.lines = i;
- }
- }
- while (1) {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- if ((len = sscanf(line, "%d:%d:%d%c%n", &a1, &a2, &a3, &separator, &plen)) < 4) {
- continue;
- } else {
- current->end = a1 * 360000 + a2 * 6000 + a3 * 100;
- return current;
- }
- }
- return current;
- }
- subtitle_t *internal_sub_read_line_rt(int fd, subtitle_t *current)
- {
- //TODO: This format uses quite rich (sub/super)set of xhtml
- // I couldn't check it since DTD is not included.
- // WARNING: full XML parses can be required for proper parsing
- char line[LINE_LEN + 1];
- int a1, a2, a3, a4, b1, b2, b3, b4;
- char *p = NULL, *next = NULL;
- int i, len, plen;
- while (!current->text.text[0]) {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- //TODO: it seems that format of time is not easily determined, it may be 1:12, 1:12.0 or 0:1:12.0
- //to describe the same moment in time. Maybe there are even more formats in use.
- //if ((len=sscanf (line, "<Time Begin=\"%d:%d:%d.%d\" End=\"%d:%d:%d.%d\"",&a1,&a2,&a3,&a4,&b1,&b2,&b3,&b4)) < 8)
- plen = a1 = a2 = a3 = a4 = b1 = b2 = b3 = b4 = 0;
- if (
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d.%d\" %*[Ee]nd=\"%d.%d\"%*[^<]<clear/>%n", &a3, &a4, &b3, &b4, &plen)) < 4) &&
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d.%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n", &a3, &a4, &b2, &b3, &b4, &plen)) < 5) &&
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n", &a2, &a3, &b2, &b3, &plen)) < 4) &&
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d:%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n", &a2, &a3, &b2, &b3, &b4, &plen)) < 5) &&
- // ((len=sscanf (line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d\"%*[^<]<clear/>%n",&a2,&a3,&a4,&b2,&b3,&plen)) < 5) &&
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\" %*[Ee]nd=\"%d:%d.%d\"%*[^<]<clear/>%n", &a2, &a3, &a4, &b2, &b3, &b4, &plen)) < 6) &&
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d:%d:%d.%d\" %*[Ee]nd=\"%d:%d:%d.%d\"%*[^<]<clear/>%n", &a1, &a2, &a3, &a4, &b1, &b2, &b3, &b4, &plen)) < 8) &&
- //now try it without end time
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d.%d\"%*[^<]<clear/>%n", &a3, &a4, &plen)) < 2) &&
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d:%d\"%*[^<]<clear/>%n", &a2, &a3, &plen)) < 2) &&
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d:%d.%d\"%*[^<]<clear/>%n", &a2, &a3, &a4, &plen)) < 3) &&
- ((len = sscanf(line, "<%*[tT]ime %*[bB]egin=\"%d:%d:%d.%d\"%*[^<]<clear/>%n", &a1, &a2, &a3, &a4, &plen)) < 4)
- ) {
- continue;
- }
- current->start = a1 * 360000 + a2 * 6000 + a3 * 100 + a4 / 10;
- current->end = b1 * 360000 + b2 * 6000 + b3 * 100 + b4 / 10;
- if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0) {
- current->end = current->start + 200;
- }
- p = line;
- p += plen;
- i = 0;
- // TODO: I don't know what kind of convention is here for marking multiline subs, maybe <br/> like in xml?
- next = strstr(line, "<clear/>");
- if (next && strlen(next) > 8) {
- next += 8;
- i = 0;
- while (1) {
- next = internal_sub_readtext(next, &(current->text.text[i]));
- if (!next) {
- break;
- }
- if (current->text.text[i] == ERR) {
- return ERR;
- }
- i++;
- if (i >= SUB_MAX_TEXT) {
- log_print(("Too many lines in a subtitle\n"));
- current->text.lines = i;
- return current;
- }
- }
- }
- current->text.lines = i + 1;
- }
- return current;
- }
- subtitle_t *internal_sub_read_line_ssa(int fd, subtitle_t *current)
- {
- /*
- * Sub Station Alpha v4 (and v2?) scripts have 9 commas before subtitle
- * other Sub Station Alpha scripts have only 8 commas before subtitle
- * Reading the "ScriptType:" field is not reliable since many scripts appear
- * w/o it
- *
- * http://www.scriptclub.org is a good place to find more examples
- * http://www.eswat.demon.co.uk is where the SSA specs can be found
- */
- int comma;
- static int max_comma = 32;/* let's use 32 for the case that the */
- /* amount of commas increase with newer SSA versions */
- int hour1, min1, sec1, hunsec1,
- hour2, min2, sec2, hunsec2, nothing;
- int num;
- char line[LINE_LEN + 1], line3[LINE_LEN + 1], *line2;
- char *tmp;
- do {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- } while ((sscanf(line, "Dialogue: Marked=%d,%d:%d:%d.%d,%d:%d:%d.%d,"
- "%[^\n\r]", ¬hing,
- &hour1, &min1, &sec1, &hunsec1,
- &hour2, &min2, &sec2, &hunsec2,
- line3) < 9) &&
- (sscanf(line, "Dialogue: %d,%d:%d:%d.%d,%d:%d:%d.%d,"
- "%[^\n\r]", ¬hing,
- &hour1, &min1, &sec1, &hunsec1,
- &hour2, &min2, &sec2, &hunsec2,
- line3) < 9));
- line2 = strchr(line3, ',');
- for (comma = 4; comma < max_comma; comma ++) {
- tmp = strchr(line2 + 1, ',');
- if (!tmp) {
- break;
- }
- if (*(++tmp) == ' ') {
- break;
- }
- /* a space after a comma means we're already in a sentence */
- line2 = tmp;
- }
- if (comma < max_comma) {
- max_comma = comma;
- }
- /* eliminate the trailing comma */
- if (*line2 == ',') {
- line2++;
- }
- current->text.lines = 0;
- num = 0;
- current->start = 360000 * hour1 + 6000 * min1 + 100 * sec1 + hunsec1;
- current->end = 360000 * hour2 + 6000 * min2 + 100 * sec2 + hunsec2;
- while (((tmp = strstr(line2, "\\n")) != NULL) || ((tmp = strstr(line2, "\\N")) != NULL)) {
- current->text.text[num] = (char *)MALLOC(tmp - line2 + 1);
- strncpy(current->text.text[num], line2, tmp - line2);
- current->text.text[num][tmp - line2] = '\0';
- line2 = tmp + 2;
- num++;
- current->text.lines++;
- if (current->text.lines >= SUB_MAX_TEXT) {
- return current;
- }
- }
- current->text.text[num] = internal_sub_strdup(line2);
- current->text.lines++;
- return current;
- }
- static void internal_sub_pp_ssa(subtitle_t *sub)
- {
- int l = sub->text.lines;
- char *so, *de, *start;
- while (l) {
- /* eliminate any text enclosed with {}, they are font and color settings */
- so = de = sub->text.text[--l];
- while (*so) {
- if (*so == '{' && so[1] == '\\') {
- for (start = so; *so && *so != '}'; so++) {
- ;
- }
- if (*so) {
- so++;
- } else {
- so = start;
- }
- }
- if (*so) {
- *de = *so;
- so++;
- de++;
- }
- }
- *de = *so;
- }
- }
- /*
- * PJS subtitles reader.
- * That's the "Phoenix Japanimation Society" format.
- * I found some of them in http://www.scriptsclub.org/ (used for anime).
- * The time is in tenths of second.
- */
- subtitle_t *internal_sub_read_line_pjs(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- char text[LINE_LEN + 1], *s, *d;
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- /* skip spaces */
- for (s = line; *s && isspace(*s); s++) {
- ;
- }
- /* allow empty lines at the end of the file */
- if (*s == 0) {
- return NULL;
- }
- /* get the time */
- if (sscanf(s, "%ld,%ld,", &(current->start), &(current->end)) < 2) {
- return ERR;
- }
- /* the files I have are in tenths of second */
- current->start *= 10;
- current->end *= 10;
- /* walk to the beggining of the string */
- for (; *s; s++) {
- if (*s == ',') {
- break;
- }
- }
- if (*s) {
- for (s++; *s; s++) if (*s == ',') {
- break;
- }
- if (*s) {
- s++;
- }
- }
- if (*s != '"') {
- return ERR;
- }
- /* copy the string to the text buffer */
- for (s++, d = text; *s && *s != '"'; s++, d++) {
- *d = *s;
- }
- *d = 0;
- current->text.text[0] = internal_sub_strdup(text);
- current->text.lines = 1;
- return current;
- }
- subtitle_t *internal_sub_read_line_mpsub(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- float a, b;
- int num = 0;
- char *p, *q;
- do {
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- } while (sscanf(line, "%f %f", &a, &b) != 2);
- mpsub_position += a * 100;
- current->start = (int) mpsub_position;
- mpsub_position += b * 100;
- current->end = (int) mpsub_position;
- while (num < SUB_MAX_TEXT) {
- if (!internal_subf_gets(line, fd)) {
- return (num == 0) ? NULL : current;
- }
- p = line;
- while (isspace(*p)) {
- p++;
- }
- if (internal_eol(*p) && num > 0) {
- return current;
- }
- if (internal_eol(*p)) {
- return NULL;
- }
- for (q = p; !internal_eol(*q); q++) {
- ;
- }
- *q = '\0';
- if (strlen(p)) {
- current->text.text[num] = internal_sub_strdup(p);
- current->text.lines = ++num;
- } else {
- return (num == 0) ? NULL : current;
- }
- }
- return NULL; /* we should have returned before if it's OK */
- }
- #define str2ms(s) (((s[1]-0x30)*3600*10+(s[2]-0x30)*3600+(s[4]-0x30)*60*10+(s[5]-0x30)*60+(s[7]-0x30)*10+(s[8]-0x30))*1000+(s[10]-0x30)*100+(s[11]-0x30)*10+(s[12]-0x30))
- SUBAPI subtitle_t *internal_divx_sub_add(subdata_t *subdata, unsigned char *data)
- {
- unsigned char *s;
- subtitle_t *sub = (subtitle_t *)calloc(1, sizeof(subtitle_t));
- if (!sub) {
- return NULL;
- }
- s = &data[0];
- sub->start = str2ms(s) * 90;
- s = &data[13];
- sub->end = str2ms(s) * 90;
- sub->subdata = data;
- //AVSchedLock();
- list_add_tail(&sub->list, &subdata->list);
- subdata->sub_num++;
- //AVSchedUnlock();
- return sub;
- }
- SUBAPI void internal_divx_sub_delete(subdata_t *subdata, int pts)
- {
- list_t *entry;
- entry = subdata->list.next;
- while (entry != &subdata->list) {
- subtitle_t *subp = list_entry(entry, subtitle_t, list);
- if (subp->start < pts) {
- if (subp->subdata) {
- FREE(subp->subdata);
- }
- //AVSchedLock();
- list_del(&subp->list);
- subdata->sub_num--;
- //AVSchedUnlock();
- entry = entry->next;
- FREE(subp);
- } else {
- break;
- }
- }
- }
- SUBAPI void internal_divx_sub_flush(subdata_t *subdata)
- {
- list_t *entry;
- if (subdata->sub_format != SUB_DIVX) {
- return;
- }
- entry = subdata->list.next;
- while (entry != &subdata->list) {
- subtitle_t *subp = list_entry(entry, subtitle_t, list);
- if (subp->subdata) {
- FREE(subp->subdata);
- }
- list_del(&subp->list);
- entry = entry->next;
- FREE(subp);
- }
- subdata->sub_num = 0;
- }
- static subtitle_t *previous_aqt_sub;
- subtitle_t *internal_sub_read_line_aqt(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- char *next;
- int i;
- while (1) {
- // try to locate next subtitle
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- if (!(sscanf(line, "-->> %ld", &(current->start)) < 1)) {
- break;
- }
- }
- if (previous_aqt_sub != NULL) {
- previous_aqt_sub->end = current->start - 1;
- }
- previous_aqt_sub = current;
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- internal_sub_readtext((char *)&line, ¤t->text.text[0]);
- current->text.lines = 1;
- current->end = current->start; // will be corrected by next subtitle
- if (!internal_subf_gets(line, fd)) {
- return current;
- }
- next = line, i = 1;
- while (1) {
- next = internal_sub_readtext(next, &(current->text.text[i]));
- if (!next) {
- break;
- }
- if (current->text.text[i] == ERR) {
- return ERR;
- }
- i++;
- if (i >= SUB_MAX_TEXT) {
- log_print(("Too many lines in a subtitle\n"));
- current->text.lines = i;
- return current;
- }
- }
- current->text.lines = i + 1;
- if ((current->text.text[0] == '\0') && (current->text.text[1] == '\0')) {
- // void subtitle -> end of previous marked and exit
- previous_aqt_sub = NULL;
- return NULL;
- }
- return current;
- }
- subtitle_t *internal_previous_subrip09_sub = NULL;
- subtitle_t *internal_sub_read_line_subrip09(int fd, subtitle_t *current)
- {
- char line[LINE_LEN + 1];
- int a1, a2, a3;
- char * next = NULL;
- int i, len;
- while (1) {
- // try to locate next subtitle
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- if (!((len = sscanf(line, "[%d:%d:%d]", &a1, &a2, &a3)) < 3)) {
- break;
- }
- }
- current->start = a1 * 360000 + a2 * 6000 + a3 * 100;
- if (internal_previous_subrip09_sub != NULL) {
- internal_previous_subrip09_sub->end = current->start - 1;
- }
- internal_previous_subrip09_sub = current;
- if (!internal_subf_gets(line, fd)) {
- return NULL;
- }
- next = line, i = 0;
- current->text.text[0] = '\0'; // just to be sure that string is clear
- while (1) {
- next = internal_sub_readtext(next, &(current->text.text[i]));
- if (!next) {
- break;
- }
- if (current->text.text[i] == ERR) {
- return ERR;
- }
- i++;
- if (i >= SUB_MAX_TEXT) {
- log_print(("Too many lines in a subtitle\n"));
- current->text.lines = i;
- return current;
- }
- }
- current->text.lines = i + 1;
- if ((current->text.text[0] == '\0') && (i == 0)) {
- // void subtitle -> end of previous marked and exit
- internal_previous_subrip09_sub = NULL;
- return NULL;
- }
- return current;
- }
- subtitle_t *internal_sub_read_line_jacosub(int fd, subtitle_t * current)
- {
- char line1[LINE_LEN], line2[LINE_LEN], directive[LINE_LEN], *p, *q;
- unsigned a1, a2, a3, a4, b1, b2, b3, b4, comment = 0;
- static unsigned jacoTimeres = 30;
- static int jacoShift = 0;
- memset(current, 0, sizeof(subtitle_t));
- memset(line1, 0, LINE_LEN);
- memset(line2, 0, LINE_LEN);
- memset(directive, 0, LINE_LEN);
- while (!current->text.text[0]) {
- if (!internal_subf_gets(line1, fd)) {
- return NULL;
- }
- if (sscanf(line1, "%u:%u:%u.%u %u:%u:%u.%u %[^\n\r]",
- &a1, &a2, &a3, &a4,
- &b1, &b2, &b3, &b4, line2) < 9) {
- if (sscanf(line1, "@%u @%u %[^\n\r]", &a4, &b4, line2) < 3) {
- if (line1[0] == '#') {
- int hours = 0, minutes = 0, seconds, delta, inverter = 1;
- unsigned units = jacoShift;
- switch (toupper(line1[1])) {
- case 'S':
- if (isalpha(line1[2])) {
- delta = 6;
- } else {
- delta = 2;
- }
- if (sscanf(&line1[delta], "%d", &hours)) {
- if (hours < 0) {
- hours *= -1;
- inverter = -1;
- }
- if (sscanf(&line1[delta], "%*d:%d", &minutes)) {
- if (sscanf(&line1[delta], "%*d:%*d:%d", &seconds)) {
- sscanf(&line1[delta], "%*d:%*d:%*d.%d", &units);
- } else {
- hours = 0;
- sscanf(&line1[delta], "%d:%d.%d", &minutes, &seconds, &units);
- minutes *= inverter;
- }
- } else {
- hours = minutes = 0;
- sscanf(&line1[delta], "%d.%d", &seconds, &units);
- seconds *= inverter;
- }
- jacoShift = ((hours * 3600 + minutes * 60 + seconds) * jacoTimeres + units)
- * inverter;
- }
- break;
- case 'T':
- if (isalpha(line1[2])) {
- delta = 8;
- } else {
- delta = 2;
- }
- sscanf(&line1[delta], "%u", &jacoTimeres);
- break;
- }
- }
- continue;
- } else {
- current->start = (unsigned long)((a4 + jacoShift) * 100.0 / jacoTimeres);
- current->end = (unsigned long)((b4 + jacoShift) * 100.0 / jacoTimeres);
- }
- } else {
- current->start = (unsigned long)(((a1 * 3600 + a2 * 60 + a3) * jacoTimeres + a4 +
- jacoShift) * 100.0 / jacoTimeres);
- current->end = (unsigned long)(((b1 * 3600 + b2 * 60 + b3) * jacoTimeres + b4 +
- jacoShift) * 100.0 / jacoTimeres);
- }
- current->text.lines = 0;
- p = line2;
- while ((*p == ' ') || (*p == '\t')) {
- ++p;
- }
- if (isalpha(*p) || *p == '[') {
- int cont, jLength;
- if (sscanf(p, "%s %[^\n\r]", directive, line1) < 2) {
- return (subtitle_t *) ERR;
- }
- jLength = strlen(directive);
- for (cont = 0; cont < jLength; ++cont) {
- if (isalpha(*(directive + cont))) {
- *(directive + cont) = toupper(*(directive + cont));
- }
- }
- if ((strstr(directive, "RDB") != NULL)
- || (strstr(directive, "RDC") != NULL)
- || (strstr(directive, "RLB") != NULL)
- || (strstr(directive, "RLG") != NULL)) {
- continue;
- }
- if (strstr(directive, "JL") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_BOTTOMLEFT;
- } else if (strstr(directive, "JR") != NULL) {
- current->text.alignment = SUB_ALIGNMENT_BOTTOMRIGHT;
- } else {
- current->text.alignment = SUB_ALIGNMENT_BOTTOMCENTER;
- }
- strcpy(line2, line1);
- p = line2;
- }
- for (q = line1; (!internal_eol(*p)) && (current->text.lines < SUB_MAX_TEXT); ++p) {
- switch (*p) {
- case '{':
- comment++;
- break;
- case '}':
- if (comment) {
- --comment;
- //the next line to get rid of a blank after the comment
- if ((*(p + 1)) == ' ') {
- p++;
- }
- }
- break;
- case '~':
- if (!comment) {
- *q = ' ';
- ++q;
- }
- break;
- case ' ':
- case '\t':
- if ((*(p + 1) == ' ') || (*(p + 1) == '\t')) {
- break;
- }
- if (!comment) {
- *q = ' ';
- ++q;
- }
- break;
- case '\\':
- if (*(p + 1) == 'n') {
- *q = '\0';
- q = line1;
- current->text.text[current->text.lines++] = internal_sub_strdup(line1);
- ++p;
- break;
- }
- if ((toupper(*(p + 1)) == 'C')
- || (toupper(*(p + 1)) == 'F')) {
- ++p, ++p;
- break;
- }
- if ((*(p + 1) == 'B') || (*(p + 1) == 'b') || (*(p + 1) == 'D') || //actually this means "insert current date here"
- (*(p + 1) == 'I') || (*(p + 1) == 'i') || (*(p + 1) == 'N') || (*(p + 1) == 'T') || //actually this means "insert current time here"
- (*(p + 1) == 'U') || (*(p + 1) == 'u')) {
- ++p;
- break;
- }
- if ((*(p + 1) == '\\') ||
- (*(p + 1) == '~') || (*(p + 1) == '{')) {
- ++p;
- } else if (internal_eol(*(p + 1))) {
- if (!internal_subf_gets(directive, fd)) {
- return NULL;
- }
- internal_trail_space(directive);
- strncat(line2, directive,
- (LINE_LEN > 511) ? LINE_LEN : 511);
- break;
- }
- default:
- if (!comment) {
- *q = *p;
- ++q;
- }
- break;
- } //-- switch
- } //-- for
- *q = '\0';
- current->text.text[current->text.lines] = internal_sub_strdup(line1);
- } //-- while
- current->text.lines++;
- return current;
- }
- static int internal_sub_autodetect(int fd)
- {
- char line[LINE_LEN + 1];
- int i, j = 0;
- char p;
- j = sscanf("00:02:21,606 --> 00:02:23,073",
- "%d:%d:%d%[,.:]%d --> %d:%d:%d%[,.:]%d",
- &i, &i, &i, (char *)&i, &i, &i, &i, &i, (char *)&i, &i);
- j = sscanf("abc",
- "[aef]bc",
- (char *)&i);
- while (j < 100) {
- j++;
- if (!internal_subf_gets(line, fd)) {
- return SUB_INVALID;
- }
- if (sscanf(line, "{%d}{%d}", &i, &i) == 2) {
- return SUB_MICRODVD;
- }
- if (sscanf(line, "{%d}{}", &i) == 1) {
- return SUB_MICRODVD;
- }
- if (sscanf(line, "[%d][%d]", &i, &i) == 2) {
- return SUB_MPL2;
- }
- if (sscanf(line, "%d:%d:%d.%d,%d:%d:%d.%d", &i, &i, &i, &i, &i, &i, &i, &i) == 8) {
- return SUB_SUBRIP;
- }
- if (sscanf(line, "%d:%d:%d%[,.:]%d --> %d:%d:%d%[,.:]%d", &i, &i, &i, (char *)&i, &i, &i, &i, &i, (char *)&i, &i) == 10) {
- return SUB_SUBVIEWER;
- }
- if (sscanf(line, "{T %d:%d:%d:%d", &i, &i, &i, &i) == 4) {
- return SUB_SUBVIEWER2;
- }
- if (strstr(line, "<SAMI>")) {
- return SUB_SAMI;
- }
- if (sscanf(line, "%d:%d:%d.%d %d:%d:%d.%d", &i, &i, &i, &i, &i, &i, &i, &i) == 8) {
- return SUB_JACOSUB;
- }
- if (sscanf(line, "@%d @%d", &i, &i) == 2) {
- return SUB_JACOSUB;
- }
- if (sscanf(line, "%d:%d:%d:", &i, &i, &i) == 3) {
- return SUB_VPLAYER;
- }
- if (sscanf(line, "%d:%d:%d ", &i, &i, &i) == 3) {
- return SUB_VPLAYER;
- }
- //TODO: just checking if first line of sub starts with "<" is WAY
- // too weak test for RT
- // Please someone who knows the format of RT... FIX IT!!!
- // It may conflict with other sub formats in the future (actually it doesn't)
- if (*line == '<') {
- return SUB_RT;
- }
- if (!memcmp(line, "Dialogue: Marked", 16)) {
- return SUB_SSA;
- }
- if (!memcmp(line, "Dialogue: ", 10)) {
- return SUB_SSA;
- }
- if (sscanf(line, "%d,%d,\"%c", &i, &i, (char *) &i) == 3) {
- return SUB_PJS;
- }
- if (sscanf(line, "FORMAT=%d", &i) == 1) {
- return SUB_MPSUB;
- }
- if (sscanf(line, "FORMAT=TIM%c", &p) == 1 && p == 'E') {
- return SUB_MPSUB;
- }
- if (strstr(line, "-->>")) {
- return SUB_AQTITLE;
- }
- if (sscanf(line, "[%d:%d:%d]", &i, &i, &i) == 3) {
- return SUB_SUBRIP09;
- }
- }
- return SUB_INVALID; // too many bad lines
- }
- SUBAPI void internal_sub_close(subdata_t *subdata)
- {
- int i;
- list_t *entry;
- entry = subdata->list.next;
- while (entry != &subdata->list) {
- subtitle_t *subt = list_entry(entry, subtitle_t, list);
- if (subdata->sub_format == SUB_DIVX) {
- if (subt->subdata) {
- FREE(subt->subdata);
- }
- } else {
- for (i = 0; i < subt->text.lines; i++) {
- FREE(subt->text.text[i]);
- }
- }
- entry = entry->next;
- FREE(subt);
- }
- FREE(subdata);
- }
- SUBAPI subdata_t *internal_sub_open(char *filename, unsigned int rate)
- {
- int fd = 0;
- subtitle_t *sub, *sub_read;
- subdata_t *subdata;
- int sub_format = SUB_INVALID;
- subreader_t sr[] = {
- { internal_sub_read_line_microdvd, NULL, "microdvd" },
- { internal_sub_read_line_subrip, NULL, "subrip" },
- { internal_sub_read_line_subviewer, NULL, "subviewer" },
- { internal_sub_read_line_sami, NULL, "sami" },
- { internal_sub_read_line_vplayer, NULL, "vplayer" },
- { internal_sub_read_line_rt, NULL, "rt" },
- { internal_sub_read_line_ssa, internal_sub_pp_ssa, "ssa" },
- { internal_sub_read_line_pjs, NULL, "pjs" },
- { internal_sub_read_line_mpsub, NULL, "mpsub" },
- { internal_sub_read_line_aqt, NULL, "aqt" },
- { internal_sub_read_line_subviewer2, NULL, "subviewer 2.0" },
- { internal_sub_read_line_subrip09, NULL, "subrip 0.9" },
- { internal_sub_read_line_jacosub, NULL, "jacosub" },
- { internal_sub_read_line_mpl2, NULL, "mpl2" }
- };
- subreader_t *srp;
- if (filename == NULL) {
- return NULL;
- } else if (0 == strcmp(filename, "subdivx")) {
- sub_format = SUB_DIVX;
- } else {
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- return NULL;
- }
- }
- subdata = (subdata_t *)MALLOC(sizeof(subdata_t));
- if (!subdata) {
- close(fd);
- return NULL;
- }
- memset(subdata, 0, sizeof(subdata_t));
- INIT_LIST_HEAD(&subdata->list);
- if (sub_format == SUB_DIVX) {
- subdata->sub_format = sub_format;
- subdata->sub_num = 0;
- return subdata;
- } else {
- subdata->sub_format = internal_sub_autodetect(fd);
- }
- if (subdata->sub_format == SUB_INVALID) {
- log_print(("SUB: Could not determine file format\n"));
- internal_sub_close(subdata);
- close(fd);
- return NULL;
- }
- srp = sr + subdata->sub_format;
- //log_print(("SUB: Detected subtitle file format: %s\n", srp->name));
- lseek(fd, 0, SEEK_SET);
- if (subfile_buffer) {
- FREE(subfile_buffer);
- subfile_buffer = NULL;
- }
- while (1) {
- sub = (subtitle_t *)MALLOC(sizeof(subtitle_t));
- if (!sub) {
- break;
- }
- memset(sub, 0, sizeof(subtitle_t));
- sub->end = rate;
- sub_read = srp->read(fd, sub);
- if (!sub_read) {
- FREE(sub);
- break; // EOF
- }
- if (sub_read == ERR) {
- FREE(sub);
- subdata->sub_error++;
- } else {
- // Apply any post processing that needs recoding first
- if (!sub_no_text_pp && srp->post) {
- srp->post(sub_read);
- }
- /* 10ms to pts conversion */
- sub->start = sub_ms2pts(sub->start);
- sub->end = sub_ms2pts(sub->end);
- //log_print("return: %s\n", sub->text.text[0]);
- list_add_tail(&sub->list, &subdata->list);
- subdata->sub_num++;
- }
- }
- if (subfile_buffer) {
- FREE(subfile_buffer);
- subfile_buffer = NULL;
- }
- close(fd);
- if (subdata->sub_num <= 0) {
- internal_sub_close(subdata);
- return NULL;
- }
- log_print("SUB: Read %d subtitles", subdata->sub_num);
- if (subdata->sub_error) {
- log_print(", %d bad line(s).\n", subdata->sub_error);
- } else {
- log_print((".\n"));
- }
- return subdata;
- }
- SUBAPI char *internal_sub_filenames(char *filename, unsigned perfect_match)
- {
- char *dir;
- char *sub_exts[] = {"utf", "sub", "srt", "smi",
- "rt", "txt", "ssa", "aqt", "jss", "js", "ass", NULL
- };
- char *p = NULL, *p2 = NULL;
- char *ext, *fn, *long_fn;
- DIR *pDir;
- int i, looking;
- struct dirent *pDirEntry;
- char *subname = NULL;
- unsigned videofile_lnamlen = 0;
- /* get directory name first */
- fn = p;
- p = strrchr(filename, '/');
- p2 = strrchr(filename, '\\');
- if (p2 > p) {
- p = p2;
- }
- if (p) {
- dir = (char *)MALLOC(p - filename + 2);
- if (!dir) {
- return NULL;
- }
- memcpy(dir, filename, p - filename + 1); /* including final '/' or '\\' */
- dir[p - filename + 1] = '\0';
- fn = p + 1;
- } else {
- dir = (char *)MALLOC(3);
- if (!dir) {
- return NULL;
- }
- strcpy(dir, "./");
- }
- /* get long file name of input file */
- pDir = opendir(dir);
- if (!pDir) {
- FREE(dir);
- return NULL;
- }
- looking = 1;
- while (looking) {
- pDirEntry = readdir(pDir);
- if (!pDirEntry) {
- break;
- }
- if (pDirEntry->d_type & S_IFDIR) {
- continue;
- }
- /*
- if(pDirEntry->d_reclen){
- if(strncasecmp(fn,pDirEntry->d_name,pDirEntry->d_reclen) == 0){
- looking = 0;
- }
- }
- else{
- if(strncasecmp(fn, pDirEntry->d_name, pDirEntry->d_namlen) == 0){
- looking = 0;
- }
- }*/
- if (strncasecmp(fn, pDirEntry->d_name, pDirEntry->d_reclen) == 0) {
- looking = 0;
- }
- }
- if (looking == 1) {
- closedir(pDir);
- FREE(dir);
- return NULL;
- } else {
- /* sometimes long file name is not available, just use short name */
- #if 0
- if (p…
Large files files are truncated, but you can click here to view the full file