improvements to tiff/png load in vips7
same as we did for jpg some work on pyramid save as well
This commit is contained in:
parent
2aa24fce03
commit
501fabccbe
31
TODO
31
TODO
@ -1,3 +1,34 @@
|
|||||||
|
- try
|
||||||
|
|
||||||
|
vips copy big8.v x.tif[pyramid,bigtiff,tile,tile-width=256,tile-height=256] --vips-progress
|
||||||
|
|
||||||
|
where big8.v is >4gb
|
||||||
|
|
||||||
|
get:
|
||||||
|
|
||||||
|
TIFFFetchDirectory: /tmp/vips-1-0RA3GW.tif: Can not read TIFF directory count
|
||||||
|
TIFFReadDirectory: /tmp/vips-1-0RA3GW.tif: Failed to read directory at offset 0
|
||||||
|
vips2tiff: unable to open "/tmp/vips-1-0RA3GW.tif" for input
|
||||||
|
|
||||||
|
where /tmp/vips-1-0RA3GW.tif is the largest pyramid layer
|
||||||
|
|
||||||
|
perhaps a flushing problem? predictor?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- load an image in nip2
|
||||||
|
|
||||||
|
enter
|
||||||
|
|
||||||
|
insert 100 0 A1 A1
|
||||||
|
|
||||||
|
save as vips .. leak!
|
||||||
|
|
||||||
|
save as jpg, no leak
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- try
|
- try
|
||||||
|
|
||||||
vips im_extract_bands /tmp/input.tiff /tmp/out.tif 0 3
|
vips im_extract_bands /tmp/input.tiff /tmp/out.tif 0 3
|
||||||
|
@ -350,7 +350,9 @@ vips_insert_class_init( VipsInsertClass *class )
|
|||||||
vobject_class->description = _( "insert an image" );
|
vobject_class->description = _( "insert an image" );
|
||||||
vobject_class->build = vips_insert_build;
|
vobject_class->build = vips_insert_build;
|
||||||
|
|
||||||
operation_class->flags = VIPS_OPERATION_SEQUENTIAL;
|
/* Not sequential, since the image being inserted may be clipped and
|
||||||
|
* we may need to skip the top or bottom.
|
||||||
|
*/
|
||||||
|
|
||||||
VIPS_ARG_IMAGE( class, "main", -1,
|
VIPS_ARG_IMAGE( class, "main", -1,
|
||||||
_( "Main" ),
|
_( "Main" ),
|
||||||
|
@ -46,8 +46,8 @@
|
|||||||
|
|
||||||
#include "../foreign/vipspng.h"
|
#include "../foreign/vipspng.h"
|
||||||
|
|
||||||
int
|
static int
|
||||||
im_png2vips( const char *name, IMAGE *out )
|
png2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||||
{
|
{
|
||||||
char filename[FILENAME_MAX];
|
char filename[FILENAME_MAX];
|
||||||
char mode[FILENAME_MAX];
|
char mode[FILENAME_MAX];
|
||||||
@ -66,19 +66,43 @@ im_png2vips( const char *name, IMAGE *out )
|
|||||||
* used writeline.
|
* used writeline.
|
||||||
*
|
*
|
||||||
* If we're writing the image to a "p", switch it to a "t".
|
* If we're writing the image to a "p", switch it to a "t".
|
||||||
|
*
|
||||||
|
* Don't do this for header read, since we don't want to force a
|
||||||
|
* malloc if all we are doing is looking at fields.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( out->dtype == VIPS_IMAGE_PARTIAL ) {
|
if( !header_only &&
|
||||||
|
out->dtype == VIPS_IMAGE_PARTIAL ) {
|
||||||
if( vips__image_wio_output( out ) )
|
if( vips__image_wio_output( out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( header_only ) {
|
||||||
if( vips__png_read( filename, out ) )
|
if( vips__png_read( filename, out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( vips__png_header( filename, out ) )
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_png2vips( const char *name, IMAGE *out )
|
||||||
|
{
|
||||||
|
return( png2vips( name, out, FALSE ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* By having a separate header func, we get lazy.c to open via disc/mem.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
im_png2vips_header( const char *name, IMAGE *out )
|
||||||
|
{
|
||||||
|
return( png2vips( name, out, TRUE ) );
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ispng( const char *filename )
|
ispng( const char *filename )
|
||||||
{
|
{
|
||||||
@ -100,6 +124,7 @@ vips_format_png_class_init( VipsFormatPngClass *class )
|
|||||||
object_class->description = _( "PNG" );
|
object_class->description = _( "PNG" );
|
||||||
|
|
||||||
format_class->is_a = ispng;
|
format_class->is_a = ispng;
|
||||||
|
format_class->header = im_png2vips_header;
|
||||||
format_class->load = im_png2vips;
|
format_class->load = im_png2vips;
|
||||||
format_class->save = im_vips2png;
|
format_class->save = im_vips2png;
|
||||||
format_class->suffs = png_suffs;
|
format_class->suffs = png_suffs;
|
||||||
|
@ -50,8 +50,8 @@
|
|||||||
|
|
||||||
#include "../foreign/tiff.h"
|
#include "../foreign/tiff.h"
|
||||||
|
|
||||||
int
|
static int
|
||||||
im_tiff2vips( const char *name, IMAGE *out )
|
tiff2vips( const char *name, IMAGE *out, gboolean header_only )
|
||||||
{
|
{
|
||||||
char filename[FILENAME_MAX];
|
char filename[FILENAME_MAX];
|
||||||
char mode[FILENAME_MAX];
|
char mode[FILENAME_MAX];
|
||||||
@ -76,20 +76,44 @@ im_tiff2vips( const char *name, IMAGE *out )
|
|||||||
*
|
*
|
||||||
* If we're writing the image to a "p", switch it to a "t". And only
|
* If we're writing the image to a "p", switch it to a "t". And only
|
||||||
* for non-tiled (strip) images which we write with writeline.
|
* for non-tiled (strip) images which we write with writeline.
|
||||||
|
*
|
||||||
|
* Don't do this for header read, since we don't want to force a
|
||||||
|
* malloc if all we are doing is looking at fields.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( !vips__istifftiled( filename ) &&
|
if( !header_only &&
|
||||||
|
!vips__istifftiled( filename ) &&
|
||||||
out->dtype == VIPS_IMAGE_PARTIAL ) {
|
out->dtype == VIPS_IMAGE_PARTIAL ) {
|
||||||
if( vips__image_wio_output( out ) )
|
if( vips__image_wio_output( out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( header_only ) {
|
||||||
|
if( vips__tiff_read_header( filename, out, page ) )
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
else {
|
||||||
if( vips__tiff_read( filename, out, page ) )
|
if( vips__tiff_read( filename, out, page ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
im_tiff2vips( const char *name, IMAGE *out )
|
||||||
|
{
|
||||||
|
return( tiff2vips( name, out, FALSE ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* By having a separate header func, we get lazy.c to open via disc/mem.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
im_tiff2vips_header( const char *name, IMAGE *out )
|
||||||
|
{
|
||||||
|
return( tiff2vips( name, out, TRUE ) );
|
||||||
|
}
|
||||||
|
|
||||||
static VipsFormatFlags
|
static VipsFormatFlags
|
||||||
tiff_flags( const char *name )
|
tiff_flags( const char *name )
|
||||||
{
|
{
|
||||||
@ -127,6 +151,7 @@ vips_format_tiff_class_init( VipsFormatTiffClass *class )
|
|||||||
object_class->description = _( "TIFF" );
|
object_class->description = _( "TIFF" );
|
||||||
|
|
||||||
format_class->is_a = istiff;
|
format_class->is_a = istiff;
|
||||||
|
format_class->header = im_tiff2vips_header;
|
||||||
format_class->load = im_tiff2vips;
|
format_class->load = im_tiff2vips;
|
||||||
format_class->save = im_vips2tiff;
|
format_class->save = im_vips2tiff;
|
||||||
format_class->get_flags = tiff_flags;
|
format_class->get_flags = tiff_flags;
|
||||||
|
@ -160,8 +160,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define DEBUG
|
#define DEBUG_VERBOSE
|
||||||
*/
|
*/
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -916,11 +917,11 @@ save_tile( TiffWrite *tw,
|
|||||||
*/
|
*/
|
||||||
pack2tiff( tw, reg, tbuf, area );
|
pack2tiff( tw, reg, tbuf, area );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG_VERBOSE
|
||||||
printf( "Writing %dx%d pixels at position %dx%d to image %s\n",
|
printf( "Writing %dx%d pixels at position %dx%d to image %s\n",
|
||||||
tw->tilew, tw->tileh, area->left, area->top,
|
tw->tilew, tw->tileh, area->left, area->top,
|
||||||
TIFFFileName( tif ) );
|
TIFFFileName( tif ) );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG_VERBOSE*/
|
||||||
|
|
||||||
/* Write to TIFF! easy.
|
/* Write to TIFF! easy.
|
||||||
*/
|
*/
|
||||||
@ -1141,13 +1142,23 @@ delete_files( TiffWrite *tw )
|
|||||||
PyramidLayer *layer = tw->layer;
|
PyramidLayer *layer = tw->layer;
|
||||||
|
|
||||||
if( tw->bname ) {
|
if( tw->bname ) {
|
||||||
|
#ifndef DEBUG
|
||||||
unlink( tw->bname );
|
unlink( tw->bname );
|
||||||
|
#else
|
||||||
|
printf( "delete_files: leaving %s\n", tw->bname );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
tw->bname = NULL;
|
tw->bname = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( layer = tw->layer; layer; layer = layer->below )
|
for( layer = tw->layer; layer; layer = layer->below )
|
||||||
if( layer->lname ) {
|
if( layer->lname ) {
|
||||||
|
#ifndef DEBUG
|
||||||
unlink( layer->lname );
|
unlink( layer->lname );
|
||||||
|
#else
|
||||||
|
printf( "delete_files: leaving %s\n", layer->lname );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
layer->lname = NULL;
|
layer->lname = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1157,9 +1168,7 @@ delete_files( TiffWrite *tw )
|
|||||||
static void
|
static void
|
||||||
free_tiff_write( TiffWrite *tw )
|
free_tiff_write( TiffWrite *tw )
|
||||||
{
|
{
|
||||||
#ifndef DEBUG
|
|
||||||
delete_files( tw );
|
delete_files( tw );
|
||||||
#endif /*DEBUG*/
|
|
||||||
|
|
||||||
VIPS_FREEF( TIFFClose, tw->tif );
|
VIPS_FREEF( TIFFClose, tw->tif );
|
||||||
VIPS_FREEF( vips_free, tw->tbuf );
|
VIPS_FREEF( vips_free, tw->tbuf );
|
||||||
@ -1340,7 +1349,7 @@ tiff_copy( TiffWrite *tw, TIFF *out, TIFF *in )
|
|||||||
CopyField( TIFFTAG_ROWSPERSTRIP, i32 );
|
CopyField( TIFFTAG_ROWSPERSTRIP, i32 );
|
||||||
CopyField( TIFFTAG_SUBFILETYPE, i32 );
|
CopyField( TIFFTAG_SUBFILETYPE, i32 );
|
||||||
|
|
||||||
if( tw->predictor != -1 )
|
if( tw->predictor != 1 )
|
||||||
TIFFSetField( out, TIFFTAG_PREDICTOR, tw->predictor );
|
TIFFSetField( out, TIFFTAG_PREDICTOR, tw->predictor );
|
||||||
|
|
||||||
/* TIFFTAG_JPEGQUALITY is a pesudo-tag, so we can't copy it.
|
/* TIFFTAG_JPEGQUALITY is a pesudo-tag, so we can't copy it.
|
||||||
|
@ -346,7 +346,7 @@ typedef enum {
|
|||||||
/**
|
/**
|
||||||
* VipsForeignTiffPredictor:
|
* VipsForeignTiffPredictor:
|
||||||
* @VIPS_FOREIGN_TIFF_PREDICTOR_NONE: no prediction
|
* @VIPS_FOREIGN_TIFF_PREDICTOR_NONE: no prediction
|
||||||
* @VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL: horizontal differenceing
|
* @VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL: horizontal differencing
|
||||||
* @VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT: float predictor
|
* @VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT: float predictor
|
||||||
*
|
*
|
||||||
* The predictor can help deflate and lzw compression. The values are fixed by
|
* The predictor can help deflate and lzw compression. The values are fixed by
|
||||||
|
@ -92,8 +92,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Define for debug output.
|
/* Define for debug output.
|
||||||
*/
|
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user