add load from buffer
This commit is contained in:
parent
6144aecccb
commit
070c9bd5a7
@ -21,6 +21,7 @@
|
||||
- vips_system() now supports many input images and you can change image
|
||||
argument order
|
||||
- support 16-bit palette TIFFs, plus palette TIFFs can have an alpha
|
||||
- add vips_tiffload_buffer()
|
||||
|
||||
6/3/14 started 7.38.6
|
||||
- grey ramp minimum was wrong
|
||||
|
@ -144,6 +144,8 @@
|
||||
* 11/4/14
|
||||
* - support 16 bits per sample palette images
|
||||
* - palette images can have an alpha
|
||||
* 22/4/14
|
||||
* - add read from buffer
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -208,6 +210,8 @@ typedef struct _ReadTiff {
|
||||
/* Parameters.
|
||||
*/
|
||||
char *filename;
|
||||
void *buf;
|
||||
size_t len;
|
||||
VipsImage *out;
|
||||
int page;
|
||||
gboolean readbehind;
|
||||
@ -225,6 +229,10 @@ typedef struct _ReadTiff {
|
||||
*/
|
||||
gboolean memcpy;
|
||||
|
||||
/* The current 'file pointer' for memory buffers.
|
||||
*/
|
||||
size_t pos;
|
||||
|
||||
/* Geometry.
|
||||
*/
|
||||
uint32 twidth, theight; /* Tile size */
|
||||
@ -1635,15 +1643,16 @@ readtiff_destroy( VipsObject *object, ReadTiff *rtiff )
|
||||
}
|
||||
|
||||
static ReadTiff *
|
||||
readtiff_new( const char *filename, VipsImage *out, int page,
|
||||
gboolean readbehind )
|
||||
readtiff_new( VipsImage *out, int page, gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
|
||||
if( !(rtiff = VIPS_NEW( out, ReadTiff )) )
|
||||
return( NULL );
|
||||
|
||||
rtiff->filename = vips_strdup( VIPS_OBJECT( out ), filename );
|
||||
rtiff->filename = NULL;
|
||||
rtiff->buf = NULL;
|
||||
rtiff->len = 0;
|
||||
rtiff->out = out;
|
||||
rtiff->page = page;
|
||||
rtiff->readbehind = readbehind;
|
||||
@ -1651,6 +1660,7 @@ readtiff_new( const char *filename, VipsImage *out, int page,
|
||||
rtiff->sfn = NULL;
|
||||
rtiff->client = NULL;
|
||||
rtiff->memcpy = FALSE;
|
||||
rtiff->pos = 0;
|
||||
rtiff->twidth = 0;
|
||||
rtiff->theight = 0;
|
||||
rtiff->separate = FALSE;
|
||||
@ -1669,6 +1679,148 @@ readtiff_new( const char *filename, VipsImage *out, int page,
|
||||
return( rtiff );
|
||||
}
|
||||
|
||||
static ReadTiff *
|
||||
readtiff_new_filename( const char *filename, VipsImage *out, int page,
|
||||
gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
int i;
|
||||
|
||||
if( !(rtiff = readtiff_new_filename( out, page, readbehind )) )
|
||||
return( NULL );
|
||||
|
||||
rtiff->filename = vips_strdup( VIPS_OBJECT( out ), filename );
|
||||
|
||||
/* No mmap --- no performance advantage with libtiff, and it burns up
|
||||
* our VM if the tiff file is large.
|
||||
*/
|
||||
if( !(rtiff->tiff = TIFFOpen( filename, "rm" )) ) {
|
||||
vips_error( "tiff2vips", _( "unable to open \"%s\" for input" ),
|
||||
filename );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
for( i = 0; i < page; i++ )
|
||||
if( !TIFFReadDirectory( rtiff->tiff ) ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "TIFF does not contain page %d" ),
|
||||
rtiff->page );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( rtiff );
|
||||
}
|
||||
|
||||
static tsize_t
|
||||
my_tiff_read( thandle_t st, tdata_t buffer, tsize_t size )
|
||||
{
|
||||
ReadTiff *rtiff = (ReadTiff *) st;
|
||||
|
||||
size_t available = rtiff->len - rtiff->pos;
|
||||
size_t copy = VIPS_MIN( size, available );
|
||||
|
||||
memcpy( buffer, rtiff->buf + rtiff->pos, copy );
|
||||
rtiff->pos += copy;
|
||||
|
||||
return( copy );
|
||||
}
|
||||
|
||||
static tsize_t
|
||||
my_tiff_write( thandle_t st, tdata_t buffer, tsize_t size )
|
||||
{
|
||||
ReadTiff *rtiff = (ReadTiff *) st;
|
||||
|
||||
g_assert( 0 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
my_tiff_close( thandle_t )
|
||||
{
|
||||
ReadTiff *rtiff = (ReadTiff *) st;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static toff_t
|
||||
my_tiff_seek( thandle_t st, toff_t pos, int whence )
|
||||
{
|
||||
ReadTiff *rtiff = (ReadTiff *) st;
|
||||
|
||||
if( whence == SEEK_SET )
|
||||
rtiff->pos = pos;
|
||||
else if( whence == SEEK_CUR )
|
||||
rtiff->pos += pos;
|
||||
else if( whence == SEEK_END )
|
||||
rtiff->pos = rtiff->len + pos;
|
||||
else
|
||||
g_assert( 0 );
|
||||
|
||||
return( rtiff->pos );
|
||||
}
|
||||
|
||||
static toff_t
|
||||
my_tiff_size( thandle_t st )
|
||||
{
|
||||
ReadTiff *rtiff = (ReadTiff *) st;
|
||||
|
||||
return( rtiff->len );
|
||||
}
|
||||
|
||||
static int
|
||||
my_tiff_map( thandle_t, tdata_t *, toff_t * )
|
||||
{
|
||||
ReadTiff *rtiff = (ReadTiff *) st;
|
||||
|
||||
g_assert( 0 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
my_tiff_unmap( thandle_t, tdata_t, toff_t )
|
||||
{
|
||||
ReadTiff *rtiff = (ReadTiff *) st;
|
||||
|
||||
g_assert( 0 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static ReadTiff *
|
||||
readtiff_new_buffer( void *buf, size_t len, VipsImage *out, int page,
|
||||
gboolean readbehind )
|
||||
{
|
||||
ReadTiff *rtiff;
|
||||
int i;
|
||||
|
||||
if( !(rtiff = readtiff_new( out, page, readbehind )) )
|
||||
return( NULL );
|
||||
|
||||
rtiff->buf = buf;
|
||||
rtiff->len = len;
|
||||
|
||||
if( !(rtiff->tiff = TIFFClientOpen( "Memory", "w",
|
||||
(thandle_t) rtiff,
|
||||
my_tiff_read, my_tiff_write, my_tiff_seek, my_tiff_close,
|
||||
my_tiff_size, my_tiff_map, my_tiff_unmap )) ) {
|
||||
vips_error( "tiff2vips", "%s",
|
||||
_( "unable to open memory buffer for input" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
for( i = 0; i < page; i++ )
|
||||
if( !TIFFReadDirectory( rtiff->tiff ) ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "TIFF does not contain page %d" ),
|
||||
rtiff->page );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( rtiff );
|
||||
}
|
||||
|
||||
/* Pull out the nth directory from a TIFF file.
|
||||
*/
|
||||
static TIFF *
|
||||
@ -1732,15 +1884,10 @@ vips__tiff_read( const char *filename, VipsImage *out, int page,
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = readtiff_new( filename, out, page, readbehind )) )
|
||||
if( !(rtiff = readtiff_new_filename( filename,
|
||||
out, page, readbehind )) )
|
||||
return( -1 );
|
||||
|
||||
if( !(rtiff->tiff = get_directory( rtiff->filename, rtiff->page )) ) {
|
||||
vips_error( "tiff2vips", _( "TIFF file does not "
|
||||
"contain page %d" ), rtiff->page );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( TIFFIsTiled( rtiff->tiff ) ) {
|
||||
if( read_tilewise( rtiff, out ) )
|
||||
return( -1 );
|
||||
@ -1760,16 +1907,9 @@ vips__tiff_read_header( const char *filename, VipsImage *out, int page )
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
if( !(rtiff = readtiff_new( filename, out, page, FALSE )) )
|
||||
if( !(rtiff = readtiff_new_filename( filename, out, page, FALSE )) )
|
||||
return( -1 );
|
||||
|
||||
if( !(rtiff->tiff = get_directory( rtiff->filename, rtiff->page )) ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "TIFF file does not contain page %d" ),
|
||||
rtiff->page );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( parse_header( rtiff, out ) )
|
||||
return( -1 );
|
||||
|
||||
@ -1814,19 +1954,9 @@ vips__tiff_read_header_buffer( void *buf, size_t len, VipsImage *out, int page )
|
||||
|
||||
vips__tiff_init();
|
||||
|
||||
move the TIFFOpen into readtiff_new
|
||||
|
||||
put the get_dir in there as well
|
||||
|
||||
if( !(rtiff = readtiff_new_buffer( buf, len, out, page, FALSE )) )
|
||||
return( -1 );
|
||||
|
||||
if( !(rtiff->tiff = get_directory( rtiff, rtiff->page )) ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "TIFF does not contain page %d" ), rtiff->page );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( parse_header( rtiff, out ) )
|
||||
return( -1 );
|
||||
|
||||
@ -1849,12 +1979,6 @@ vips__tiff_read_buffer( void *buf, size_t len, VipsImage *out,
|
||||
if( !(rtiff = readtiff_new_buffer( buf, len, out, page, readbehind )) )
|
||||
return( -1 );
|
||||
|
||||
if( !(rtiff->tiff = get_directory( rtiff, rtiff->page )) ) {
|
||||
vips_error( "tiff2vips",
|
||||
_( "TIFF does not contain page %d" ), rtiff->page );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( TIFFIsTiled( rtiff->tiff ) ) {
|
||||
if( read_tilewise( rtiff, out ) )
|
||||
return( -1 );
|
||||
|
Loading…
Reference in New Issue
Block a user