Package: libnifti1
Version: 1.1.0-3.1~debug.1
Severity: normal
Tags: patch
Hi Michael,
I've been cooking it for a bit and unfortunately still dumping it here not
fully cooked.
As you saw, we have got an issue with python-nifti not being able to handle
.nii.gz with large dimensionality [1].
Major issue (bug with casting if fprintf's I will report separately for
clarity): nifticlib's API does support large data blocks, they rely on size_t
type for len and nmemb in znz(read|write). But then two sides of the problem:
* zlib's gz(read|write) take len of type 'unsigned', so it cannot handle larger
data blocks
* well, gcc was complaining about above, so in "COMP: Explicitly
typecast" (commit in 2008 after most recent release 1.1.0 you put into
Debian) gzwrite call got casting done, to make it unsigned for sure. gzread
had casting to (int) since 2005
So, I checked with zlib guys either anything could be done on the zlib side,
but because it would break at least ABI, decision was easy -- keep it as is,
and advise providing helpers at the "user"'s level. Below is the quote for
helpful reply from Mark Adler. He also mentioned separately that "The code
snippet is donated, but also not tested.".
Please forward this report upstream, so they could address it in the best
manner (without me hacking it up).
Thank you in advance.
On Jun 29, 2010, at 7:18 PM, Yaroslav Halchenko wrote:
> I thought woohoo -- but then looked into the code and saw that
> gzread/gzwrite still have "unsigned" ... so it seems that support for
> large files isn't yet there, or am I mistaken?
Yaroslav,
Indeed, there is support for large files, in that large files can be opened and
seeked. The changes were to gzopen, gzseek, and gztell. Without using LFS,
you can't even *open* a large file in Linux.
gzread works just peachy on large files as well, but only a piece at a time
where a piece has to have length that fits in an unsigned int (preferably an
int, since gzread returns an int). All that means is that you need
to call gzread multiple times, which is how gzread is normally used. You can
write a trivial wrapper function to do a single read operation to a large
buffer. Something like:
#define BIG (((unsigned)(-1)>>2)+1)
off_t gzreadbig(gzFile file, void *buf, off_t len)
{
unsigned n;
int got;
off_t tot = 0;
while (len) {
n = len > BIG ? BIG : (unsigned)len;
got = gzread(file, buf, n);
if (got < 0)
return got;
tot += got;
len -= got;
buf += got;
if (got < (int)n)
break;
}
return tot;
}
Mark
[1]
http://lists.alioth.debian.org/pipermail/pkg-exppsy-pymvpa/2010q2/001168.html
-- System Information:
Debian Release: squeeze/sid
APT prefers unstable
APT policy: (901, 'unstable'), (900, 'testing'), (300, 'experimental')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.32-5-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages libnifti1 depends on:
ii libc6 2.11.1-2 Embedded GNU C Library: Shared lib
ii zlib1g 1:1.2.3.5.dfsg-1 compression library - runtime
libnifti1 recommends no packages.
libnifti1 suggests no packages.
-- no debconf information
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]