/* Make a new buffer. */ VipsBuffer * vips_buffer_new( VipsImage *im, VipsRect *area ) { VipsBuffer *buffer; buffer = g_new( VipsBuffer, 1 ); buffer->ref_count = 1; buffer->im = im; buffer->area = *area; buffer->done = FALSE; buffer->cache = NULL; buffer->bsize = (size_t) VIPS_IMAGE_SIZEOF_PEL( im ) * area->width * area->height; if( !(buffer->buf = vips_tracked_malloc( buffer->bsize )) ) { vips_buffer_unref( buffer ); return( NULL ); } #ifdef DEBUG printf( "** vips_buffer_new: left = %d, top = %d, " "width = %d, height = %d (%p)\n", buffer->area.left, buffer->area.top, buffer->area.width, buffer->area.height, buffer ); #endif /*DEBUG*/ #ifdef DEBUG g_mutex_lock( vips__global_lock ); vips__buffers_all = g_slist_prepend( vips__buffers_all, buffer ); printf( "%d buffers in vips\n", g_slist_length( vips__buffers_all ) ); g_mutex_unlock( vips__global_lock ); #endif /*DEBUG*/ return( buffer ); }
/* Unref old, ref new, in a single operation. Reuse stuff if we can. The * buffer we return might or might not be done. */ VipsBuffer * vips_buffer_unref_ref( VipsBuffer *old_buffer, VipsImage *im, VipsRect *area ) { VipsBuffer *buffer; g_assert( !old_buffer || old_buffer->im == im ); /* Is the current buffer OK? */ if( old_buffer && vips_rect_includesrect( &old_buffer->area, area ) ) return( old_buffer ); /* Does the new area already have a buffer? */ if( (buffer = buffer_find( im, area )) ) { VIPS_FREEF( vips_buffer_unref, old_buffer ); return( buffer ); } /* Is the current buffer unshared? We can just move it. */ if( old_buffer && old_buffer->ref_count == 1 ) { if( buffer_move( old_buffer, area ) ) { vips_buffer_unref( old_buffer ); return( NULL ); } return( old_buffer ); } /* Fallback ... unref the old one, make a new one. */ VIPS_FREEF( vips_buffer_unref, old_buffer ); if( !(buffer = vips_buffer_new( im, area )) ) return( NULL ); return( buffer ); }