Commit 0172640e authored by ivo's avatar ivo

Bump version number to 1.3.0. The following are patches by (the amazing) Peter Harris:

 * oggenc: --utf8 command similar to vorbiscomment's --raw
 * oggenc: fixed the encoding of extended characters in Windows
 * oggenc: validate raw UTF-8 sent to oggenc
 * vorbiscomment: validate raw UTF-8 sent to vorbiscomment
More info is available in ticket #268.

svn path=/trunk/vorbis-tools/; revision=15316
parent 8b4b8b5b
vorbis-tools 1.2.1 -- Unreleased
vorbis-tools 1.3.0 -- Unreleased
* Fixed an error in configure.ac; --with-speex/flac work again (#1319)
* Corrected problems in the Visual Studio project files
* Updated po files from the Translation Project
* Added new en_GB.po, sk.po and vi.po translation files
* Added new en_GB.po, eo.po, sk.po and vi.po translation files
* Added AC_USE_SYSTEM_EXTENSIONS to configure.ac; no more autogen.sh warnings
* Corrected SUBLANG values in intl/localename.c (#1415)
* Modify -v to -V on oggenc and oggdec for consistency (#1112)
* Fix for utf8_decode in Windows; improves behavior in vorbiscomment (#268)
* ogg123: backported fix from libfishsound to patch the Speex decoder (#1347)
* ogg123: fixed CPU issue when outputting to a closed pipe (#1357)
* ogg123: return value to stop decoding after buffer is shut down (#1357)
......@@ -18,9 +19,13 @@ vorbis-tools 1.2.1 -- Unreleased
* oggenc: support for 32 bit Wave files (#1326)
* oggenc: --ignorelength; support for Wave files > 4 GB (#1326)
* oggenc: split help text into manageable chunks to help translators (#1385)
* oggenc: --utf8 command similar to vorbiscomment's --raw (#268)
* oggenc: fixed the encoding of extended characters in Windows (#268)
* oggenc: validate raw UTF-8 sent to oggenc (#268)
* ogginfo: support for information in Kate streams (#1360)
* vcut: 64 bit fixes (#1366)
* vorbiscomment: correct memory allocation (#472)
* vorbiscomment: validate raw UTF-8 sent to vorbiscomment (#268)
vorbis-tools 1.2.0 -- 2008-02-21
......
......@@ -11,7 +11,7 @@ AC_CANONICAL_TARGET
AC_PREREQ(2.53)
AM_INIT_AUTOMAKE([vorbis-tools],[1.2.1])
AM_INIT_AUTOMAKE([vorbis-tools],[1.3.0])
AM_MAINTAINER_MODE
AM_CONFIG_HEADER([config.h])
......@@ -30,7 +30,7 @@ CFLAGS="$cflags_save"
AC_PROG_LIBTOOL
ALL_LINGUAS="be cs da en_GB es fr hr hu nl ro ru sk sv uk vi"
ALL_LINGUAS="be cs da en_GB eo es fr hr hu nl ro ru sk sv uk vi"
AM_GNU_GETTEXT
dnl --------------------------------------------------
......
......@@ -28,6 +28,7 @@ void convert_set_charset(const char *charset);
int utf8_encode(const char *from, char **to);
int utf8_decode(const char *from, char **to);
int utf8_validate(const char *from);
#ifdef __cplusplus
}
......
......@@ -18,7 +18,7 @@ typedef void (*error_func)(char *errormessage);
void *timer_start(void);
double timer_time(void *);
void timer_clear(void *);
int create_directories(char *);
int create_directories(char *, int);
void update_statistics_full(char *fn, long total, long done, double time);
void update_statistics_notime(char *fn, long total, long done, double time);
......@@ -90,6 +90,8 @@ typedef struct
unsigned int skeleton_serial;
int fixedserial;
int ignorelength;
int isutf8;
} oe_options;
typedef struct
......
......@@ -62,6 +62,7 @@ struct option long_options[] = {
{"scale", 1, 0, 0},
{"advanced-encode-option", 1, 0, 0},
{"discard-comments", 0, 0, 0},
{"utf8", 0,0,0},
{"ignorelength", 0, 0, 0},
{NULL,0,0,0}
};
......@@ -81,7 +82,7 @@ int main(int argc, char **argv)
oe_options opt = {NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL,
0, NULL, 0, NULL, 0, NULL, 0, 1, 0, 0, 0,16,44100,2, 0, NULL,
DEFAULT_NAMEFMT_REMOVE, DEFAULT_NAMEFMT_REPLACE,
NULL, 0, -1,-1,-1,.3,-1,0, 0,0.f, 0, 0, 0};
NULL, 0, -1,-1,-1,.3,-1,0, 0,0.f, 0, 0, 0, 0};
int i;
......@@ -89,6 +90,8 @@ int main(int argc, char **argv)
int numfiles;
int errors=0;
get_args_from_ucs16(&argc, &argv);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
......@@ -176,7 +179,7 @@ int main(int argc, char **argv)
}
else
{
in = fopen(infiles[i], "rb");
in = oggenc_fopen(infiles[i], "rb", opt.isutf8);
if(in == NULL)
{
......@@ -279,7 +282,7 @@ int main(int argc, char **argv)
}
/* Create any missing subdirectories, if possible */
if(create_directories(out_fn)) {
if(create_directories(out_fn, opt.isutf8)) {
if(closein)
fclose(in);
fprintf(stderr, _("ERROR: Could not create required subdirectories for output filename \"%s\"\n"), out_fn);
......@@ -295,7 +298,7 @@ int main(int argc, char **argv)
continue;
}
out = fopen(out_fn, "wb");
out = oggenc_fopen(out_fn, "wb", opt.isutf8);
if(out == NULL)
{
if(closein)
......@@ -311,8 +314,20 @@ int main(int argc, char **argv)
/* Now, set the rest of the options */
enc_opts.out = out;
enc_opts.comments = &vc;
#ifdef _WIN32
if (opt.isutf8) {
enc_opts.filename = NULL;
enc_opts.infilename = NULL;
utf8_decode(out_fn, &enc_opts.filename);
utf8_decode(infiles[i], &enc_opts.infilename);
} else {
enc_opts.filename = strdup(out_fn);
enc_opts.infilename = strdup(infiles[i]);
}
#else
enc_opts.filename = out_fn;
enc_opts.infilename = infiles[i];
#endif
enc_opts.managed = opt.managed;
enc_opts.bitrate = opt.nominal_bitrate;
enc_opts.min_bitrate = opt.min_bitrate;
......@@ -377,6 +392,10 @@ clear_all:
if(out_fn) free(out_fn);
if(opt.outfile) free(opt.outfile);
#ifdef _WIN32
if(enc_opts.filename) free(enc_opts.filename);
if(enc_opts.infilename) free(enc_opts.infilename);
#endif
vorbis_comment_clear(&vc);
format->close_func(enc_opts.readdata);
......@@ -471,6 +490,9 @@ static void usage(void)
" Default settings for the above two arguments are platform\n"
" specific.\n"));
fprintf(stdout, _(
" --utf8 Tells oggenc that the command line parameters date, title,\n"
" album, artist, genre, and comment are already in UTF-8.\n"
" On Windows, this switch applies to file names too.\n"
" -c, --comment=c Add the given string as an extra comment. This may be\n"
" used multiple times. The argument should be in the\n"
" format \"tag=value\".\n"
......@@ -666,6 +688,9 @@ static void parse_options(int argc, char **argv, oe_options *opt)
optarg);
}
}
else if(!strcmp(long_options[option_index].name, "utf8")) {
opt->isutf8 = 1;
}
else if(!strcmp(long_options[option_index].name, "advanced-encode-option")) {
char *arg = strdup(optarg);
char *val;
......@@ -887,7 +912,18 @@ static void parse_options(int argc, char **argv, oe_options *opt)
static void add_tag(vorbis_comment *vc, oe_options *opt,char *name, char *value)
{
char *utf8;
if(utf8_encode(value, &utf8) >= 0)
if (opt->isutf8)
{
if (!utf8_validate(value)) {
fprintf(stderr, _("'%s' is not valid UTF-8, cannot add\n"), name?name:"comment");
} else {
if(name == NULL)
vorbis_comment_add(vc, value);
else
vorbis_comment_add_tag(vc, name, value);
}
}
else if(utf8_encode(value, &utf8) >= 0)
{
if(name == NULL)
vorbis_comment_add(vc, utf8);
......
......@@ -21,11 +21,16 @@
#include <stdlib.h>
#include <ctype.h>
#if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
#include <getopt.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#endif
#ifdef _WIN32
#include <windows.h>
#endif
#if defined(_WIN32) && defined(_MSC_VER)
void setbinmode(FILE *f)
......@@ -127,11 +132,14 @@ void timer_clear(void *timer)
#endif
int create_directories(char *fn)
int create_directories(char *fn, int isutf8)
{
char *end, *start;
struct stat statbuf;
char *segment = malloc(strlen(fn)+1);
#ifdef _WIN32
wchar_t seg[MAX_PATH+1];
#endif
start = fn;
#ifdef _WIN32
......@@ -141,12 +149,26 @@ int create_directories(char *fn)
while((end = strpbrk(start+1, PATH_SEPS)) != NULL)
{
int rv;
memcpy(segment, fn, end-fn);
segment[end-fn] = 0;
if(stat(segment,&statbuf)) {
#ifdef _WIN32
if (isutf8) {
MultiByteToWideChar(CP_UTF8, 0, segment, -1, seg, MAX_PATH+1);
rv = _wstat(seg,&statbuf);
} else
#endif
rv = stat(segment,&statbuf);
if(rv) {
if(errno == ENOENT) {
if(mkdir(segment, 0777)) {
#ifdef _WIN32
if (isutf8)
rv = _wmkdir(seg);
else
#endif
rv = mkdir(segment, 0777);
if(rv) {
fprintf(stderr, _("Couldn't create directory \"%s\": %s\n"),
segment, strerror(errno));
free(segment);
......@@ -181,5 +203,129 @@ int create_directories(char *fn)
}
#ifdef _WIN32
FILE *oggenc_fopen(char *fn, char *mode, int isutf8)
{
if (isutf8) {
wchar_t wfn[MAX_PATH+1];
wchar_t wmode[32];
MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, MAX_PATH+1);
MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, 32);
return _wfopen(wfn, wmode);
} else
return fopen(fn, mode);
}
static int
parse_for_utf8(int argc, char **argv)
{
extern struct option long_options[];
int ret;
int option_index = 1;
while((ret = getopt_long(argc, argv, "A:a:b:B:c:C:d:G:hkl:m:M:n:N:o:P:q:QrR:s:t:vX:",
long_options, &option_index)) != -1)
{
switch(ret)
{
case 0:
if(!strcmp(long_options[option_index].name, "utf8")) {
return 1;
}
break;
default:
break;
}
}
return 0;
}
typedef WINSHELLAPI LPWSTR * (APIENTRY *tCommandLineToArgvW)(LPCWSTR lpCmdLine, int*pNumArgs);
void get_args_from_ucs16(int *argc, char ***argv)
{
OSVERSIONINFO vi;
int utf8;
utf8 = parse_for_utf8(*argc, *argv);
optind = 1; /* Reset getopt_long */
/* If command line is already UTF-8, don't convert */
if (utf8)
return;
vi.dwOSVersionInfoSize = sizeof(vi);
GetVersionEx(&vi);
/* We only do NT4 and more recent.*/
/* It would be relatively easy to add NT3.5 support. Is anyone still using NT3? */
/* It would be relatively hard to add 9x support. Fortunately, 9x is
a lost cause for unicode support anyway. */
if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT && vi.dwMajorVersion >= 4) {
const char utf8flag[] = "--utf8";
int newargc;
int sizeofargs = 0;
int a, count;
char *argptr;
char **newargv = NULL;
LPWSTR *ucs16argv = NULL;
tCommandLineToArgvW pCommandLineToArgvW = NULL;
HMODULE hLib = NULL;
hLib = LoadLibrary("shell32.dll");
if (!hLib)
goto bail;
pCommandLineToArgvW = (tCommandLineToArgvW)GetProcAddress(hLib, "CommandLineToArgvW");
if (!pCommandLineToArgvW)
goto bail;
ucs16argv = pCommandLineToArgvW(GetCommandLineW(), &newargc);
if (!ucs16argv)
goto bail;
for (a=0; a<newargc; a++) {
count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
NULL, 0, NULL, NULL);
if (count == 0)
goto bail;
sizeofargs += count;
}
sizeofargs += strlen(utf8flag) + 1;
newargv = malloc(((newargc + 2) * sizeof(char *)) + sizeofargs);
argptr = (char *)(&newargv[newargc+2]);
for (a=0; a<newargc; a++) {
count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
argptr, sizeofargs, NULL, NULL);
if (count == 0)
goto bail;
newargv[a] = argptr;
argptr += count;
sizeofargs -= count;
}
count = strlen(utf8flag) + 1;
strcpy(argptr, utf8flag);
newargv[a] = argptr;
argptr += count;
sizeofargs -= count;
newargv[a+1] = NULL;
*argc = newargc + 1;
*argv = newargv;
bail:
if (hLib != NULL)
FreeLibrary(hLib);
if (ucs16argv != NULL)
GlobalFree(ucs16argv);
}
}
#endif
......@@ -29,5 +29,16 @@ void setbinmode(FILE *);
#endif
#endif /* __PLATFORM_H */
#ifdef _WIN32
extern FILE *oggenc_fopen(char *fn, char *mode, int isutf8);
extern void get_args_from_ucs16(int *argc, char ***argv);
#else
#define oggenc_fopen(x,y,z) fopen(x,y)
#define get_args_from_ucs16(x,y) { }
#endif
#endif /* __PLATFORM_H */
This diff is collapsed.
......@@ -322,3 +322,66 @@ int utf8_decode(const char *from, char **to)
}
#endif
/* Quick and dirty UTF-8 validation: */
/* check the first "count" bytes of "s" to make
sure they are all valid UTF-8 "continuation" bytes */
static int checknext(const char *s, int count)
{
int i;
for (i = 0; i < count; i++) {
if ((s[i] & 0xc0) != 0x80)
return 0;
}
return 1;
}
static struct {
char mask;
char value;
unsigned after;
} test[] = {
{ 0x80, 0, 0 }, /* 7-bit ASCII - One byte sequence */
{ 0xe0, 0xc0, 1 }, /* Two byte sequence */
{ 0xf0, 0xe0, 2 }, /* Three byte sequence */
{ 0xf8, 0xf0, 3 }, /* Four byte sequence */
{ 0xfc, 0xf8, 4 }, /* Five byte sequence */
{ 0xfe, 0xfc, 5 }, /* Six byte sequence */
/* All other values are not valid UTF-8 */
};
#define NUM_TESTS (sizeof(test)/sizeof(test[0]))
/* Returns true if the C-string is a valid UTF-8 sequence
Returns false otherwise */
int utf8_validate(const char *s)
{
size_t len = strlen(s);
while (len) {
int i;
for (i = 0; i < NUM_TESTS; i++) {
if ((s[0] & test[i].mask) == test[i].value) {
unsigned after = test[i].after;
if (len < after + 1)
return 0;
if (!checknext(s+1, after))
return 0;
s += after + 1;
len -= after + 1;
goto next;
}
}
/* If none of the tests match, invalid UTF-8 */
return 0;
next: ;
}
/* Zero bytes left, and all test pass. Valid UTF-8. */
return 1;
}
Name: vorbis-tools
Version: 1.2.1
Version: 1.3.0
Release: 1
Summary: Several Ogg Vorbis Tools
......
......@@ -340,7 +340,10 @@ int add_comment(char *line, vorbis_comment *vc, int raw)
value++;
if(raw) {
vorbis_comment_add_tag(vc, line, value);
if (!utf8_validate(value))
fprintf(stderr, _("'%s' is not valid UTF-8, cannot add\n"), line);
else
vorbis_comment_add_tag(vc, line, value);
return 0;
}
/* convert the value from the native charset to UTF-8 */
......
......@@ -2,6 +2,6 @@
#define CONFIG_H 1
#define PACKAGE "vorbis-tools"
#define VERSION "1.2.1"
#define VERSION "1.3.0"
#endif /* CONFIG_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment