Permalink
Browse files

Fix openslide_read_region() for layer > 0 && (w > 4096 || h > 4096)

openslide_read_region() was using the wrong coordinate plane for x and y
when breaking up regions larger than 4096 pixels/side, causing it to
return corrupt data.

Closes #86.
  • Loading branch information...
1 parent 2c1ddcc commit b6aaf67678b9beb5ad960bc4b99180724a616ed8 @bgilbert bgilbert committed Feb 13, 2012
Showing with 7 additions and 6 deletions.
  1. +7 −6 src/openslide.c
View
@@ -1,7 +1,7 @@
/*
* OpenSlide, a library for reading whole slide image files
*
- * Copyright (c) 2007-2011 Carnegie Mellon University
+ * Copyright (c) 2007-2012 Carnegie Mellon University
* All rights reserved.
*
* OpenSlide is free software: you can redistribute it and/or modify
@@ -536,21 +536,22 @@ void openslide_read_region(openslide_t *osr,
// 3. We would like to constrain the intermediate surface to a reasonable
// amount of RAM.
const int64_t d = 4096;
+ double ds = openslide_get_layer_downsample(osr, layer);
for (int64_t row = 0; !openslide_get_error(osr) && row < (h + d - 1) / d;
row++) {
for (int64_t col = 0; !openslide_get_error(osr) && col < (w + d - 1) / d;
col++) {
// calculate surface coordinates and size
- int64_t sx = x + col * d;
- int64_t sy = y + row * d;
- int64_t sw = MIN(x + w - sx, d);
- int64_t sh = MIN(y + h - sy, d);
+ int64_t sx = x + col * d * ds; // layer 0 plane
+ int64_t sy = y + row * d * ds; // layer 0 plane
+ int64_t sw = MIN(w - col * d, d); // layer plane
+ int64_t sh = MIN(h - row * d, d); // layer plane
// create the cairo surface for the dest
cairo_surface_t *surface;
if (dest) {
surface = cairo_image_surface_create_for_data(
- (unsigned char *) (dest + w * (sy - y) + (sx - x)),
+ (unsigned char *) (dest + w * row * d + col * d),
CAIRO_FORMAT_ARGB32, sw, sh, w * 4);
} else {
// nil surface

0 comments on commit b6aaf67

Please sign in to comment.