add OpenSlide helper to copy a line of pixels

This commit is contained in:
Benjamin Gilbert 2011-11-27 21:50:41 -05:00
parent ef5d72e5af
commit 395d4ef067
1 changed files with 31 additions and 27 deletions

View File

@ -13,6 +13,7 @@
* - consolidate setup into one function * - consolidate setup into one function
* - support reading arbitrary layers * - support reading arbitrary layers
* - use VIPS_ARRAY() * - use VIPS_ARRAY()
* - add helper to copy a line of pixels
*/ */
/* /*
@ -139,6 +140,31 @@ readslide_new( const char *filename, VipsImage *out )
return( rslide ); return( rslide );
} }
static void
copy_line( ReadSlide *rslide, uint32_t *in, int count, PEL *out )
{
uint8_t a;
int i;
for( i = 0; i < count; i++ ) {
/* Convert from ARGB to RGBA and undo premultiplication.
*/
a = in[i] >> 24;
if( a != 0 ) {
out[4 * i + 0] = 255 * ((in[i] >> 16) & 255) / a;
out[4 * i + 1] = 255 * ((in[i] >> 8) & 255) / a;
out[4 * i + 2] = 255 * (in[i] & 255) / a;
} else {
/* Use background color.
*/
out[4 * i + 0] = (rslide->background >> 16) & 255;
out[4 * i + 1] = (rslide->background >> 8) & 255;
out[4 * i + 2] = rslide->background & 255;
}
out[4 * i + 3] = a;
}
}
static int static int
fill_region( VipsRegion *out, void *seq, void *_rslide, void *unused, fill_region( VipsRegion *out, void *seq, void *_rslide, void *unused,
gboolean *stop ) gboolean *stop )
@ -146,10 +172,7 @@ fill_region( VipsRegion *out, void *seq, void *_rslide, void *unused,
ReadSlide *rslide = _rslide; ReadSlide *rslide = _rslide;
uint32_t *buf; uint32_t *buf;
const char *error; const char *error;
PEL *pel; int y;
uint32_t sample;
uint8_t a;
int x, y;
buf = VIPS_ARRAY( NULL, out->valid.width * out->valid.height, buf = VIPS_ARRAY( NULL, out->valid.width * out->valid.height,
uint32_t ); uint32_t );
@ -157,29 +180,10 @@ fill_region( VipsRegion *out, void *seq, void *_rslide, void *unused,
out->valid.left * rslide->downsample, out->valid.left * rslide->downsample,
out->valid.top * rslide->downsample, rslide->layer, out->valid.top * rslide->downsample, rslide->layer,
out->valid.width, out->valid.height ); out->valid.width, out->valid.height );
for( y = 0; y < out->valid.height; y++ ) { for( y = 0; y < out->valid.height; y++ )
for( x = 0; x < out->valid.width; x++ ) { copy_line( rslide, buf + y * out->valid.width,
/* Convert from ARGB to RGBA and undo out->valid.width, VIPS_REGION_ADDR_TOPLEFT( out ) +
* premultiplication. y * VIPS_REGION_LSKIP( out ));
*/
pel = VIPS_REGION_ADDR( out, out->valid.left + x,
out->valid.top + y );
sample = buf[y * out->valid.height + x];
a = sample >> 24;
if( a != 0 ) {
pel[0] = 255 * ((sample >> 16) & 255) / a;
pel[1] = 255 * ((sample >> 8) & 255) / a;
pel[2] = 255 * (sample & 255) / a;
} else {
/* Use background color.
*/
pel[0] = (rslide->background >> 16) & 255;
pel[1] = (rslide->background >> 8) & 255;
pel[2] = rslide->background & 255;
}
pel[3] = a;
}
}
vips_free( buf ); vips_free( buf );
error = openslide_get_error( rslide->osr ); error = openslide_get_error( rslide->osr );