Skip to content

Commit f8003bd

Browse files
authored
Add tiffsave target (#2798)
* compiles, but untested * works, but libtiff needs seek for write next: add seek methods to target * add target seek and read seem to work next: disc temps for disc output * add libnsgif COPYING oops, we were missing the COPYING file see #2800 thanks mika-fischer * tiffsave uses a disc temp if it can * revise temp target rules only make a disc temp if we are writing to a filesystem target * add new target methods to targetcustom
1 parent 58b5350 commit f8003bd

File tree

13 files changed

+708
-408
lines changed

13 files changed

+708
-408
lines changed

ChangeLog

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
- add "gap" option to vips_reduce[hv]() and vips_resize() [kleisauke]
2222
- add "ceil" option to vips_shrink() [kleisauke]
2323
- quality improvements for image resizing [kleisauke]
24+
- add vips_source_new_from_target()
25+
- add vips_target_seek(), vips_target_read(), vips_target_new_temp()
26+
- add vips_tiffsave_target()
2427
- add vips_target_end(), deprecate vips_target_finish()
2528

2629
26/11/21 started 8.12.3

libvips/foreign/foreign.c

+2
Original file line numberDiff line numberDiff line change
@@ -2878,6 +2878,7 @@ vips_foreign_operation_init( void )
28782878
extern GType vips_foreign_load_tiff_source_get_type( void );
28792879
extern GType vips_foreign_save_tiff_file_get_type( void );
28802880
extern GType vips_foreign_save_tiff_buffer_get_type( void );
2881+
extern GType vips_foreign_save_tiff_target_get_type( void );
28812882

28822883
extern GType vips_foreign_load_raw_get_type( void );
28832884
extern GType vips_foreign_save_raw_get_type( void );
@@ -3090,6 +3091,7 @@ vips_foreign_operation_init( void )
30903091
vips_foreign_load_tiff_source_get_type();
30913092
vips_foreign_save_tiff_file_get_type();
30923093
vips_foreign_save_tiff_buffer_get_type();
3094+
vips_foreign_save_tiff_target_get_type();
30933095
#endif /*HAVE_TIFF*/
30943096

30953097
#if defined(HAVE_OPENSLIDE) && !defined(OPENSLIDE_MODULE)

libvips/foreign/pforeign.h

+1-22
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extern "C" {
5151

5252
void vips__tiff_init( void );
5353

54-
int vips__tiff_write( VipsImage *in, const char *filename,
54+
int vips__tiff_write_target( VipsImage *in, VipsTarget *target,
5555
VipsForeignTiffCompression compression, int Q,
5656
VipsForeignTiffPredictor predictor,
5757
const char *profile,
@@ -72,27 +72,6 @@ int vips__tiff_write( VipsImage *in, const char *filename,
7272
gboolean premultiply,
7373
int page_height );
7474

75-
int vips__tiff_write_buf( VipsImage *in,
76-
void **obuf, size_t *olen,
77-
VipsForeignTiffCompression compression, int Q,
78-
VipsForeignTiffPredictor predictor,
79-
const char *profile,
80-
gboolean tile, int tile_width, int tile_height,
81-
gboolean pyramid,
82-
int bitdepth,
83-
gboolean miniswhite,
84-
VipsForeignTiffResunit resunit, double xres, double yres,
85-
gboolean bigtiff,
86-
gboolean rgbjpeg,
87-
gboolean properties, gboolean strip,
88-
VipsRegionShrink region_shrink,
89-
int level,
90-
gboolean lossless,
91-
VipsForeignDzDepth depth,
92-
gboolean subifd,
93-
gboolean premultiply,
94-
int page_height );
95-
9675
gboolean vips__istiff_source( VipsSource *source );
9776
gboolean vips__istifftiled_source( VipsSource *source );
9877
int vips__tiff_read_header_source( VipsSource *source, VipsImage *out,

libvips/foreign/tiff.c

+39-135
Original file line numberDiff line numberDiff line change
@@ -90,48 +90,6 @@ vips__tiff_init( void )
9090
TIFFSetWarningHandler( vips__thandler_warning );
9191
}
9292

93-
/* Open TIFF for output.
94-
*/
95-
TIFF *
96-
vips__tiff_openout( const char *path, gboolean bigtiff )
97-
{
98-
TIFF *tif;
99-
const char *mode = bigtiff ? "w8" : "w";
100-
101-
#ifdef DEBUG
102-
printf( "vips__tiff_openout( \"%s\", \"%s\" )\n", path, mode );
103-
#endif /*DEBUG*/
104-
105-
/* Need the utf-16 version on Windows.
106-
*/
107-
#ifdef G_OS_WIN32
108-
{
109-
GError *error = NULL;
110-
wchar_t *path16;
111-
112-
if( !(path16 = (wchar_t *)
113-
g_utf8_to_utf16( path, -1, NULL, NULL, &error )) ) {
114-
vips_g_error( &error );
115-
return( NULL );
116-
}
117-
118-
tif = TIFFOpenW( path16, mode );
119-
120-
g_free( path16 );
121-
}
122-
#else /*!G_OS_WIN32*/
123-
tif = TIFFOpen( path, mode );
124-
#endif /*G_OS_WIN32*/
125-
126-
if( !tif ) {
127-
vips_error( "tiff",
128-
_( "unable to open \"%s\" for output" ), path );
129-
return( NULL );
130-
}
131-
132-
return( tif );
133-
}
134-
13593
/* TIFF input from a vips source.
13694
*/
13795

@@ -152,13 +110,11 @@ openin_source_write( thandle_t st, tdata_t buffer, tsize_t size )
152110
}
153111

154112
static toff_t
155-
openin_source_seek( thandle_t st, toff_t position, int whence )
113+
openin_source_seek( thandle_t st, toff_t offset, int whence )
156114
{
157115
VipsSource *source = VIPS_SOURCE( st );
158116

159-
/* toff_t is usually uint64, with -1 cast to uint64 to indicate error.
160-
*/
161-
return( (toff_t) vips_source_seek( source, position, whence ) );
117+
return( (toff_t) vips_source_seek( source, offset, whence ) );
162118
}
163119

164120
static int
@@ -240,151 +196,99 @@ vips__tiff_openin_source( VipsSource *source )
240196
return( tiff );
241197
}
242198

243-
/* TIFF output to a memory buffer.
199+
/* TIFF output to a target.
244200
*/
245201

246-
typedef struct _VipsTiffOpenoutBuffer {
247-
VipsDbuf dbuf;
248-
249-
/* On close, consolidate and write the output here.
250-
*/
251-
void **out_data;
252-
size_t *out_length;
253-
} VipsTiffOpenoutBuffer;
254-
202+
/* libtiff needs this (!!?!?!) for writing multipage images.
203+
*/
255204
static tsize_t
256-
openout_buffer_read( thandle_t st, tdata_t data, tsize_t size )
205+
openout_target_read( thandle_t st, tdata_t data, tsize_t size )
257206
{
258-
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
259-
260-
#ifdef DEBUG
261-
printf( "openout_buffer_read: %zd bytes\n", size );
262-
#endif /*DEBUG*/
207+
VipsTarget *target = (VipsTarget *) st;
263208

264-
return( vips_dbuf_read( &buffer->dbuf, data, size ) );
209+
return( vips_target_read( target, data, size ) );
265210
}
266211

267212
static tsize_t
268-
openout_buffer_write( thandle_t st, tdata_t data, tsize_t size )
213+
openout_target_write( thandle_t st, tdata_t data, tsize_t size )
269214
{
270-
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
215+
VipsTarget *target = (VipsTarget *) st;
271216

272-
#ifdef DEBUG
273-
printf( "openout_buffer_write: %zd bytes\n", size );
274-
#endif /*DEBUG*/
275-
276-
vips_dbuf_write( &buffer->dbuf, data, size );
217+
if( vips_target_write( target, data, size ) )
218+
return( (tsize_t) -1 );
277219

278220
return( size );
279221
}
280222

281-
static int
282-
openout_buffer_close( thandle_t st )
223+
static toff_t
224+
openout_target_seek( thandle_t st, toff_t offset, int whence )
283225
{
284-
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
285-
286-
*(buffer->out_data) = vips_dbuf_steal( &buffer->dbuf,
287-
buffer->out_length);
226+
VipsTarget *target = (VipsTarget *) st;
288227

289-
return( 0 );
228+
return( vips_target_seek( target, offset, whence ) );
290229
}
291230

292-
static toff_t
293-
openout_buffer_seek( thandle_t st, toff_t position, int whence )
231+
static int
232+
openout_target_close( thandle_t st )
294233
{
295-
VipsTiffOpenoutBuffer *buffer = (VipsTiffOpenoutBuffer *) st;
296-
297-
#ifdef DEBUG
298-
printf( "openout_buffer_seek: position %zd, whence %d ",
299-
position, whence );
300-
switch( whence ) {
301-
case SEEK_SET:
302-
printf( "set" );
303-
break;
304-
305-
case SEEK_END:
306-
printf( "end" );
307-
break;
308-
309-
case SEEK_CUR:
310-
printf( "cur" );
311-
break;
312-
313-
default:
314-
printf( "unknown" );
315-
break;
316-
}
317-
printf( "\n" );
318-
#endif /*DEBUG*/
234+
VipsTarget *target = (VipsTarget *) st;
319235

320-
vips_dbuf_seek( &buffer->dbuf, position, whence );
236+
if( vips_target_end( target ) )
237+
return( -1 );
321238

322-
return( vips_dbuf_tell( &buffer->dbuf ) );
239+
return( 0 );
323240
}
324241

325242
static toff_t
326-
openout_buffer_length( thandle_t st )
243+
openout_target_length( thandle_t st )
327244
{
328245
g_assert_not_reached();
329246

330-
return( 0 );
247+
return( (toff_t) -1 );
331248
}
332249

333250
static int
334-
openout_buffer_map( thandle_t st, tdata_t *start, toff_t *len )
251+
openout_target_map( thandle_t st, tdata_t *start, toff_t *len )
335252
{
336253
g_assert_not_reached();
337254

338-
return( 0 );
255+
return( -1 );
339256
}
340257

341258
static void
342-
openout_buffer_unmap( thandle_t st, tdata_t start, toff_t len )
259+
openout_target_unmap( thandle_t st, tdata_t start, toff_t len )
343260
{
344261
g_assert_not_reached();
345262

346263
return;
347264
}
348265

349-
/* On TIFFClose(), @data and @length are set to point to the output buffer.
350-
*/
351266
TIFF *
352-
vips__tiff_openout_buffer( VipsImage *image,
353-
gboolean bigtiff, void **out_data, size_t *out_length )
267+
vips__tiff_openout_target( VipsTarget *target, gboolean bigtiff )
354268
{
355269
const char *mode = bigtiff ? "w8" : "w";
356270

357-
VipsTiffOpenoutBuffer *buffer;
358271
TIFF *tiff;
359272

360273
#ifdef DEBUG
361274
printf( "vips__tiff_openout_buffer:\n" );
362275
#endif /*DEBUG*/
363276

364-
g_assert( out_data );
365-
g_assert( out_length );
366-
367-
buffer = VIPS_NEW( image, VipsTiffOpenoutBuffer );
368-
vips_dbuf_init( &buffer->dbuf );
369-
buffer->out_data = out_data;
370-
buffer->out_length = out_length;
371-
372-
if( !(tiff = TIFFClientOpen( "memory output", mode,
373-
(thandle_t) buffer,
374-
openout_buffer_read,
375-
openout_buffer_write,
376-
openout_buffer_seek,
377-
openout_buffer_close,
378-
openout_buffer_length,
379-
openout_buffer_map,
380-
openout_buffer_unmap )) ) {
381-
vips_error( "vips__tiff_openout_buffer", "%s",
382-
_( "unable to open memory buffer for output" ) );
277+
if( !(tiff = TIFFClientOpen( "target output", mode,
278+
(thandle_t) target,
279+
openout_target_read,
280+
openout_target_write,
281+
openout_target_seek,
282+
openout_target_close,
283+
openout_target_length,
284+
openout_target_map,
285+
openout_target_unmap )) ) {
286+
vips_error( "vips__tiff_openout_target", "%s",
287+
_( "unable to open target for output" ) );
383288
return( NULL );
384289
}
385290

386291
return( tiff );
387292
}
388293

389294
#endif /*HAVE_TIFF*/
390-

libvips/foreign/tiff.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ extern "C" {
4040
TIFF *vips__tiff_openin_source( VipsSource *source );
4141

4242
TIFF *vips__tiff_openout( const char *path, gboolean bigtiff );
43-
TIFF *vips__tiff_openout_buffer( VipsImage *image,
44-
gboolean bigtiff, void **out_data, size_t *out_length );
43+
TIFF *vips__tiff_openout_target( VipsTarget *target, gboolean bigtiff );
4544

4645
#ifdef __cplusplus
4746
}

0 commit comments

Comments
 (0)