add im_vips2bufpng
This commit is contained in:
parent
9e41002a08
commit
6b686678ce
@ -17,6 +17,8 @@
|
||||
* - fixed 16-bit save
|
||||
* 12/5/10
|
||||
* - lololo but broke 8-bit save, fixed again
|
||||
* 20/7/10 Tim Elliott
|
||||
* - added im_vips2bufpng()
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -371,4 +373,129 @@ im_vips2png( IMAGE *in, const char *filename )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
typedef struct _PngWriteBuf {
|
||||
char *buf;
|
||||
size_t len;
|
||||
size_t alloc;
|
||||
} PngWriteBuf;
|
||||
|
||||
static void
|
||||
png_write_buf_free( PngWriteBuf *wbuf )
|
||||
{
|
||||
IM_FREE( wbuf );
|
||||
}
|
||||
|
||||
static PngWriteBuf *
|
||||
png_write_buf_new( void )
|
||||
{
|
||||
PngWriteBuf *wbuf;
|
||||
|
||||
if( !(wbuf = IM_NEW( NULL, PngWriteBuf )) )
|
||||
return( NULL );
|
||||
|
||||
wbuf->buf = NULL;
|
||||
wbuf->len = 0;
|
||||
wbuf->alloc = 0;
|
||||
|
||||
return( wbuf );
|
||||
}
|
||||
|
||||
static void
|
||||
png_write_buf_grow( PngWriteBuf *wbuf, size_t grow_len )
|
||||
{
|
||||
size_t new_len = wbuf->len + grow_len;
|
||||
|
||||
if( new_len > wbuf->alloc ) {
|
||||
size_t proposed_alloc = (16 + wbuf->alloc) * 3 / 2;
|
||||
|
||||
wbuf->alloc = IM_MAX( proposed_alloc, new_len );
|
||||
|
||||
/* There's no im_realloc(), so we call g_realloc() directly.
|
||||
* This is safe, since im_malloc() / im_free() are wrappers
|
||||
* over g_malloc() / g_free().
|
||||
*
|
||||
* FIXME: add im_realloc().
|
||||
*/
|
||||
wbuf->buf = g_realloc( wbuf->buf, wbuf->alloc );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
user_write_data( png_structp png_ptr, png_bytep data, png_size_t length )
|
||||
{
|
||||
PngWriteBuf *wbuf = (PngWriteBuf *) png_ptr->io_ptr;
|
||||
char *write_start;
|
||||
|
||||
png_write_buf_grow( wbuf, length );
|
||||
|
||||
write_start = wbuf->buf + wbuf->len;
|
||||
png_memcpy( write_start, data, length );
|
||||
|
||||
wbuf->len += length;
|
||||
|
||||
g_assert( wbuf->len <= wbuf->alloc );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_vips2bufpng:
|
||||
* @in: image to save
|
||||
* @out: allocate output buffer local to this
|
||||
* @compression: Compress with this much effort
|
||||
* @interlace: 0 means don't interlace, 1 selects ADAM7 interlacing
|
||||
* @obuf: return output buffer here
|
||||
* @olen: return output length here
|
||||
*
|
||||
* As im_vips2png(), but save as a memory buffer. The memory is allocated
|
||||
* local to @out (that is, when @out is closed the memory will be released,
|
||||
* pass %NULL to release yourself).
|
||||
*
|
||||
* The address of the buffer is returned in @obuf, the length of the buffer in
|
||||
* @olen.
|
||||
*
|
||||
* See also: #VipsFormat, im_vips2png().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
im_vips2bufpng( IMAGE *in, IMAGE *out,
|
||||
int compression, int interlace, char **obuf, size_t *olen )
|
||||
{
|
||||
PngWriteBuf *wbuf;
|
||||
Write *write;
|
||||
|
||||
if( !(wbuf = png_write_buf_new()) ||
|
||||
!(write = write_new( in )) )
|
||||
return( -1 );
|
||||
|
||||
png_set_write_fn( write->pPng, wbuf, user_write_data, NULL );
|
||||
|
||||
/* Convert it!
|
||||
*/
|
||||
if( write_vips( write, compression, interlace ) ) {
|
||||
write_destroy( write );
|
||||
png_write_buf_free( wbuf );
|
||||
im_error( "im_vips2bufpng",
|
||||
"%s", _( "unable to write to buffer" ) );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
write_destroy( write );
|
||||
|
||||
*obuf = wbuf->buf;
|
||||
*olen = wbuf->len;
|
||||
|
||||
png_write_buf_free( wbuf );
|
||||
|
||||
if( out && im_add_close_callback( out,
|
||||
(im_callback_fn) im_free, *obuf, NULL ) ) {
|
||||
im_free( *obuf );
|
||||
*obuf = NULL;
|
||||
*olen = 0;
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#endif /*HAVE_PNG*/
|
||||
|
Loading…
Reference in New Issue
Block a user