gifload does unicode on win

sigh again
This commit is contained in:
John Cupitt 2016-08-17 14:37:15 +01:00
parent 030921efc6
commit 578764b582
4 changed files with 41 additions and 19 deletions

2
TODO
View File

@ -1,5 +1,7 @@
- done: jpeg, tiff, csv, vips
cfitsio: no unicode support on Windows, as far as I can see
- add unicode filename test
- add APPROX convsep test?

View File

@ -7,6 +7,8 @@
* 26/7/16
* - transparency was wrong if there was no EXTENSION_RECORD
* - write 1, 2, 3, or 4 bands depending on file contents
* 17/8/16
* - support unicode on win
*/
/*
@ -61,7 +63,7 @@
#include <gif_lib.h>
/* giflib 5 is rather different :-( functions have error returns and there's
* not LastError function.
* no LastError().
*
* GIFLIB_MAJOR was introduced in 4.1.6. Use it to test for giflib 5.x.
*/
@ -216,19 +218,32 @@ vips_foreign_load_gif_close( VipsForeignLoadGif *gif )
static int
vips_foreign_load_gif_open( VipsForeignLoadGif *gif, const char *filename )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gif );
int fd;
g_assert( !gif->file );
if( !(fd = vips__open_read( filename )) ) {
vips_error_system( errno, class->nickname,
_( "unable to open \"%s\"" ), filename );
return( -1 );
}
#ifdef HAVE_GIFLIB_5
{
int error;
if( !(gif->file = DGifOpenFileName( filename, &error )) ) {
if( !(gif->file = DGifOpenFileHandle( fd, &error )) ) {
/* DGifOpenFileHandle() closes fd for us on error.
*/
vips_foreign_load_gif_error_vips( gif, error );
return( -1 );
}
}
#else
if( !(gif->file = DGifOpenFileName( filename )) ) {
if( !(gif->file = DGifOpenFileHandle( fd )) ) {
/* DGifOpenFileHandle() closes fd for us on error.
*/
vips_foreign_load_gif_error_vips( gif, GifLastError() );
return( -1 );
}

View File

@ -223,6 +223,7 @@ gint64 vips_file_length( int fd );
int vips__write( int fd, const void *buf, size_t count );
int vips__open( const char *filename, int flags, ... );
int vips__open_read( const char *filename );
FILE *vips__fopen( const char *filename, const char *mode );
FILE *vips__file_open_read( const char *filename,

View File

@ -55,8 +55,12 @@
#endif /*OS_WIN32*/
#include <vips/vips.h>
#include <vips/internal.h>
#include <vips/debug.h>
#include <vips/internal.h>
/* Temp buffer for snprintf() layer on old systems.
*/
#define MAX_BUF (100000)
/* Try to make an O_BINARY ... sometimes need the leading '_'.
*/
@ -88,10 +92,6 @@
*/
#define MODE_READONLY BINARYIZE (O_RDONLY)
/* Temp buffer for snprintf() layer on old systems.
*/
#define MAX_BUF (100000)
/* Test two lists for eqality.
*/
gboolean
@ -543,7 +543,7 @@ vips__write( int fd, const void *buf, size_t count )
return( 0 );
}
/* open() with a utf8 filename.
/* open() with a utf8 filename, setting errno.
*/
int
vips__open( const char *filename, int flags, ... )
@ -558,12 +558,11 @@ vips__open( const char *filename, int flags, ... )
#ifdef OS_WIN32
{
GError *error = NULL;
wchar_t *path16;
if( !(path16 = (wchar_t *)
g_utf8_to_utf16( filename, -1, NULL, NULL, &error )) ) {
vips_g_error( &error );
g_utf8_to_utf16( filename, -1, NULL, NULL, NULL )) ) {
errno = EACCES;
return( -1 );
}
@ -578,7 +577,13 @@ vips__open( const char *filename, int flags, ... )
return( fd );
}
/* fopen() with utf8 filename and mode.
int
vips__open_read( const char *filename )
{
return( vips__open( filename, MODE_READONLY ) );
}
/* fopen() with utf8 filename and mode, setting errno.
*/
FILE *
vips__fopen( const char *filename, const char *mode )
@ -586,19 +591,18 @@ vips__fopen( const char *filename, const char *mode )
FILE *fp;
#ifdef OS_WIN32
GError *error = NULL;
wchar_t *path16, *mode16;
if( !(path16 = (wchar_t *)
g_utf8_to_utf16( filename, -1, NULL, NULL, &error )) ) {
vips_g_error( &error );
g_utf8_to_utf16( filename, -1, NULL, NULL, NULL )) ) {
errno = EACCES;
return( NULL );
}
if( !(mode16 = (wchar_t *)
g_utf8_to_utf16( mode, -1, NULL, NULL, &error )) ) {
g_utf8_to_utf16( mode, -1, NULL, NULL, NULL )) ) {
g_free( path16 );
vips_g_error( &error );
errno = EACCES;
return( NULL );
}
@ -831,7 +835,7 @@ vips__get_bytes( const char *filename, unsigned char buf[], int len )
* so no hasty messages. And the file might be truncated, so no error
* on read either.
*/
if( (fd = vips__open( name, MODE_READONLY )) == -1 )
if( (fd = vips__open_read( name )) == -1 )
return( 0 );
if( read( fd, buf, len ) != len ) {
close( fd );