Zeiss ZVI file format support development for OpenSlide

Benjamin Gilbert bgilbert at cs.cmu.edu
Thu Jul 19 14:48:00 EDT 2012

On 07/19/2012 02:25 AM, Alexandre Kharlamov wrote:
> How about this: the reported levels_count will stay as it were,
> the raw access to the images will only start beyond that number and
> the total number of images available (not including every tile in a
> mosaic, of course) will only be reported as part of metadata together
> with additional description for each image id. No change to API is needed.

Even if overloading the level argument wasn't problematic from an API 
perspective, it still wouldn't give you what you needed. 
openslide_read_region() is defined to fill the passed buffer with ARGB 
image data.

> Besides, I can't think of any better solution. Creating separate
> function for
> time, focal, and any other possible dimension is pointless. Besides, as I
> understand, ZVI file can store totally unrelated images in one file, just as
> a package. If you have a better idea, please, don't hesitate to propose it.

This needs some more thought, and I haven't yet had a chance to read 
through DICOM supplement 145, but here's my current strawman:

/* Brightfield, or first 3 channels fluorescence */
void openslide_read_region_cursor(openslide_t *osr,
     openslide_cursor_t *cursor, uint32_t *buf, int64_t x, int64_t y,
     int level, int64_t w, int64_t h);

/* Fluorescence, or arbitrary channel brightfield */
void openslide_read_region_channel(openslide_t *osr,
     openslide_cursor_t *cursor, uint8_t *buf, int channel,
     int64_t x, int64_t y, int level, int64_t w, int64_t h);

openslide_cursor_t *openslide_cursor_new(void);
void openslide_cursor_free(openslide_cursor_t *cursor);

Each axis would have slices indexed from 0, just as levels are handled 
now.  For each axis (channel, time, focal plane), e.g.:

int openslide_get_timepoint_count(openslide_t *osr);
double openslide_get_timepoint_time(openslide_t *osr, int timepoint);
int openslide_cursor_get_timepoint(openslide_cursor_t *cursor);
void openslide_cursor_set_timepoint(openslide_cursor_t *cursor,
     int timepoint);

except that channels are not included in the cursor.

This API is unpleasantly verbose.  It does, however, allow us to add 
additional axes, if needed, without breaking the ABI.  It also allows an 
application to ignore any axes it doesn't care about.  Of course, we 
would need to figure out what metadata to expose for each axis.

You had a good point that the level argument is different from the other 
axes because it refers to redundant data, so at the moment I've left it 
as a separate argument to openslide_read_channel_region() rather than 
including it in the cursor.

I'm not sure what to do with the unrelated images you mentioned.  Are 
they mosaic tiles or something else?  Can each of the images have 
multiple timepoints, focal planes, etc?  Can each of the images have 
*different* numbers of those things?

--Benjamin Gilbert

More information about the openslide-users mailing list