Return-Path: <awaresystems.be+caf_=filtered=awaresystems.be@gmail.com>
Delivered-To: filtered@awaresystems.be
Received: from mx5.public.one.com ([10.246.18.25])
	by mail6.local.one.com (Dovecot) with LMTP id MiSPAx+JVVh/XwAAsyOMew
	for <filtered@awaresystems.be>; Sat, 17 Dec 2016 18:51:43 +0000
X-HalOne-ID: d9badce6-c489-11e6-991b-b82a72d82f61
Received: from mail-oi0-f51.google.com (unknown [209.85.218.51])
	by mx5.public.one.com (Halon Mail Gateway) with ESMTPS
	for <filtered@awaresystems.be>; Sat, 17 Dec 2016 18:51:41 +0000 (UTC)
Received: by mail-oi0-f51.google.com with SMTP id w63so109625267oiw.0
        for <filtered@awaresystems.be>; Sat, 17 Dec 2016 10:51:41 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-original-authentication-results:x-gm-message-state:delivered-to
         :from:to:date:message-id:references:mime-version:cc:subject
         :precedence:list-id:list-unsubscribe:list-archive:list-post
         :list-help:list-subscribe:mime-version:sender:errors-to;
        bh=jSp2yI3PZrjXC3ImLCsPVm625frWvDMrfUc69Nf+D+c=;
        b=fKrL4yzFdcze9oflvdiWLsGtB6qU7pGFmI3Usr10/zg29axiW0RSLqY1UXBrvBQt4m
         ae9keLtRoK7MybiTFtAZ9ReaUx40i+LogrY4Qh3KQhWnJ//on4gdsAo2ZMW0HiOe4dcR
         B2rVKwrX6sz4TLR9a/12wBfXps2Wd1nuq0vBIfiGxXgw21FA30kRVks8IQYVGKIRAdUp
         LUBZBV18dSbXAPa0KwOAGIjgUFm8nSeifqVcMTwNc7ghSs3+hMFOWKp2sTK6l5vAxtC4
         MD6tf0gIbmPRepWd96wUG7DXSJFwC4TROGmVdnlZYe0GiNadGiXxlCx75YgCTXdhw5UZ
         M1tg==
X-Original-Authentication-Results: mx.google.com;       spf=neutral (google.com: 94.23.4.142 is neither permitted nor denied by best guess record for domain of tiff-bounces@lists.maptools.org) smtp.mailfrom=tiff-bounces@lists.maptools.org;       dmarc=fail (p=NONE dis=NONE) header.from=seznam.cz
X-Gm-Message-State: AKaTC01B4aRohesWj04fNr3yFbBzXFiJ4IFFBaWzRLSJ7tbYbKIchHC4YajDttnOiIjhuaiRw82jLKfwO3xtgZ5Zo4+1Ps8=
X-Received: by 10.157.56.179 with SMTP id p48mr5684292otc.247.1482000700381;
        Sat, 17 Dec 2016 10:51:40 -0800 (PST)
X-Forwarded-To: filtered@awaresystems.be
X-Forwarded-For: awaresystems.be@gmail.com filtered@awaresystems.be
Delivered-To: awaresystems.be@gmail.com
Received: by 10.202.192.135 with SMTP id q129csp755251oif;
        Sat, 17 Dec 2016 10:51:38 -0800 (PST)
X-Received: by 10.194.243.106 with SMTP id wx10mr9106989wjc.191.1482000698730;
        Sat, 17 Dec 2016 10:51:38 -0800 (PST)
Return-Path: <tiff-bounces@lists.maptools.org>
Received: from lists.maptools.org (ks365428.kimsufi.com. [94.23.4.142])
        by mx.google.com with ESMTP id k24si8823700wmi.156.2016.12.17.10.51.38;
        Sat, 17 Dec 2016 10:51:38 -0800 (PST)
Received-SPF: neutral (google.com: 94.23.4.142 is neither permitted nor denied by best guess record for domain of tiff-bounces@lists.maptools.org) client-ip=94.23.4.142;
Authentication-Results: mx.google.com;
       spf=neutral (google.com: 94.23.4.142 is neither permitted nor denied by best guess record for domain of tiff-bounces@lists.maptools.org) smtp.mailfrom=tiff-bounces@lists.maptools.org;
       dmarc=fail (p=NONE dis=NONE) header.from=seznam.cz
Received: from [10.1.0.241] (localhost.localdomain [127.0.0.1])
	by lists.maptools.org (Postfix) with ESMTP id 5AAB635C066;
	Sat, 17 Dec 2016 13:50:41 -0500 (EST)
Received: from mxl2.seznam.cz (mxl2.seznam.cz [77.75.76.44])
	by lists.maptools.org (Postfix) with ESMTPS id 30E7D35C064
	for <tiff@lists.maptools.org>; Sat, 17 Dec 2016 13:46:50 -0500 (EST)
Received: from email.seznam.cz
	by email-smtpc8a.ng.seznam.cz (email-smtpc8a.ng.seznam.cz
	[10.23.10.225]) id 223849dc043bee142229bf32;
	Sat, 17 Dec 2016 19:46:49 +0100 (CET)
Received: from unknown ([::ffff:83.208.231.197])
	by email.seznam.cz (szn-ebox-4.5.190) with HTTP;
	Sat, 17 Dec 2016 19:46:48 +0100 (CET)
From: "Mickey Rose" <mickey.rose@seznam.cz>
To: "Even Rouault" <even.rouault@spatialys.com>
Date: Sat, 17 Dec 2016 19:46:48 +0100 (CET)
Message-Id: <Jx1.4RVY.6a6Eqmuldk{.1OLOWO@seznam.cz>
References: <2061150.pX6JBIZquU@even-i700>
Mime-Version: 1.0 (szn-mime-2.0.12)
X-Mailer: szn-ebox-4.5.190
Cc: tiff@lists.maptools.org
Subject: Re: [Tiff]
	=?utf-8?q?Thoughts_about_a_proposed_patch_to_fix_a_heap-ba?=
	=?utf-8?q?sed_buffer=09overflow_in_putcontig8bitYCbCr44tile_=3F?=
X-BeenThere: tiff@lists.maptools.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: TIFF and libtiff discussion <tiff.lists.maptools.org>
List-Unsubscribe: <http://lists.maptools.org/mailman/listinfo/tiff>,
	<mailto:tiff-request@lists.maptools.org?subject=unsubscribe>
List-Archive: <http://lists.maptools.org/mailman/private/tiff>
List-Post: <mailto:tiff@lists.maptools.org>
List-Help: <mailto:tiff-request@lists.maptools.org?subject=help>
List-Subscribe: <http://lists.maptools.org/mailman/listinfo/tiff>,
	<mailto:tiff-request@lists.maptools.org?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============0769772828=="
Mime-version: 1.0
Sender: tiff-bounces@lists.maptools.org
Errors-To: tiff-bounces@lists.maptools.org

--===============0769772828==
Content-Type: multipart/alternative;
	boundary="=_30e66c122e87d83450f58ced=f609cbef-2ee0-5b05-a754-60df12d9e056_="

--=_30e66c122e87d83450f58ced=f609cbef-2ee0-5b05-a754-60df12d9e056_=
Content-Type: text/plain;
	charset=utf-8
Content-Transfer-Encoding: quoted-printable

=0A=
=0A=
---------- P=C5=AFvodn=C3=AD zpr=C3=A1va ----------=0A=
Od: Even Rouault <even.rouault@spatialys.com>=0A=
Datum: 17. 12. 2016 16:21:33=0A=
=0A=
=0A=
"=0A=
I've spent a couple of hours analyzing the issue raised on =0A=
http://bugzilla.maptools.org/show_bug.cgi?id=3D2637=0A=
=0A=
=C2=A0=0A=
 =0A=
This is a defect in tif_getimage.c when decoding a tiled old-JPEG=0A=
=0A=
with YCbCr 4:4 resampling, and with a unusual tile width of 3.=0A=
=0A=
"=0A=
=0A=
=0A=
=0A=
I wonder how you managed to create tiled YCbCr tiff. Some time ago I wante=
d =0A=
to create some=0A=
=0A=
such images for testing, and couldn't figure out how, as the rgb2ycbcr too=
l =0A=
only creates stripped,=0A=
=0A=
and tiffcp and tiffcrop refuse to copy subsampled non-JPEG images.=0A=
=0A=
=0A=
=0A=
=0A=
=0A=
But I digress. The function `putcontig8bitYCbCr44tile` is used for strippe=
d =0A=
images as well, so you=0A=
=0A=
don't need to create images with weird tile sizes, you can just create =
=0A=
stripped images with weird=0A=
=0A=
=0A=
widths and observe that 4x4 subsampling is a no-go with certain widths.=
=0A=
=0A=
=0A=
=0A=
"=0A=
=0A=
putcontig8bitYCbCr44tile has an optimized case when the useful width and =
=0A=
height are=0A=
=0A=
multiple of 4, and here we are in the general case when they are not. So =
=0A=
apparently=0A=
=0A=
this code is supposed to deal with useful width not multiple of 4. I canno=
t =0A=
really=0A=
=0A=
make sense of the (fromskew * 18) / 4 computation (18=3D4x4+2 and 4 must b=
e =0A=
the horizontal=0A=
=0A=
or vertical resampling factor) and the pp +=3D fromskew (note that=0A=
=0A=
those are also used in the optimized case ). Interestingly in the 2x2 =
=0A=
resampling case,=0A=
=0A=
the formula is (fromskew / 2) * 6, so the division there is made before th=
e =0A=
computation.=0A=
=0A=
So perhaps a fix would be (fromskew / 4) * 18 ?, which would evaluate to 0=
 =0A=
here=0A=
=0A=
and avoid the overflow.=0A=
=0A=
=0A=
=0A=
"=0A=
=0A=
=0A=
=0A=
`fromskew` that is passed to the function is the number of pixels to skip =
=0A=
when advancing to the next row.=0A=
=0A=
This calculation turns it into the number of bytes to skip when advancing =
to=0A=
the next 4-row pack.=0A=
=0A=
=0A=
In 4x4 subsampling case, there are 4x4 Y samples, 1 Cb and 1 Cr sample in =
a =0A=
block, hence the block size is 18.=0A=
=0A=
=0A=
`(fromskew / 4) * 18` might fix that for the tile reading case, but not wh=
en=0A=
you ask TIFFRGBAImageGet=0A=
to give you w=3D19 pixels (with col_offset=3D0 to keep it simple) from a =
=0A=
stripped image whose width=3D21;=0A=
because fromskew=3D2px, but it must skip the 1 right-most block when advan=
cing=0A=
to the next row pack.=0A=
=0A=
In other words, the number of skipped pixels alone isn't enough informatio=
n =0A=
to calculate how many bytes=0A=
need to be skipped.=0A=
=0A=
I've recently re-written a considerable portion of `get_image.c` put* =
=0A=
functions because I needed to extract=0A=
regions with arbitrary `col_offset` and `row_offset` from any kind of imag=
e.=0A=
Although partial support for=0A=
arbitrary `col_offset` was recently added to libtiff, it's still broken fo=
r =0A=
paletted and subsampled images,=0A=
so I had to roll my own. I can turn my modifications into a proper patch, =
=0A=
but that's not a priority for me and=0A=
I'd very much prefer to do that after libtiff will have migrated to git or=
 =0A=
mercurial.=0A=
=0A=
After having implemented and tested arbitrary region extraction from 4x4 =
=0A=
subsampled images, I came to=0A=
the conclusion that it'd be better to remove 4x4 subsampling support from =
=0A=
libtiff and the TIFF specification=0A=
as well. I was planning to propose that in a message of its own, as it sur=
e =0A=
will be contentious, but since you=0A=
mentioned one of the reasons, I think I might just add to that...=0A=
=C2=A0"=0A=
=0A=
But I cannot verify if that doesnt break valid images. Has =0A=
=0A=
someone legit OJPEG tiled 4:4 images... ? I tried to create a regular JPEG=
 =0A=
tiled 4:4, with=0A=
=0A=
tile of dimension 32x32 (otherwise this is rejected), and of image dimensi=
on=0A=
63x63, but this=0A=
=0A=
is kind of fun since by default libjpeg has a C_MAX_BLOCKS_IN_MCU/D_MAX_=
=0A=
BLOCKS_IN_MCU limit=0A=
=0A=
to 10 that prevents that (you need to increase it to 20 for example)=0A=
=0A=
"=0A=
=0A=
=0A=
=0A=
Yes, and there's also a snarly comment in libjpeg source, discouraging fro=
m =0A=
increasing the=0A=
=0A=
compression limit (for decompression you might be *forced* to increase it =
to=0A=
decode an image=0A=
=0A=
you get somewhere).=0A=
=0A=
=0A=
=0A=
=0A=
Therefore it is impossible to create or decode a JPEG-compressed TIFF with=
 4=0A=
x4 subsampling=0A=
=0A=
(which would require 18 blocks in MCU), unless you use a custom-built =
=0A=
libjpeg with higher limits.=0A=
=0A=
IMO not worth it, totally defeats portability.=0A=
=0A=
=0A=
=0A=
=0A=
=0A=
So you have to use a different compression if you want 4x4 subsampling. No=
w,=0A=
I'm no expert=0A=
=0A=
on image compression, but isn't it generally better to subsample less and =
=0A=
lossy-compress more?=0A=
=0A=
I mean, if I had a source (non-subsampled) image and a desired subsampled =
=0A=
file size, it'd expect=0A=
=0A=
4x2-subsampled JPEG to look better than 4x4-subsampled ANOTHER-compression=
, =0A=
simply=0A=
=0A=
because the 4x2 JPEG might preserve some detail (if the size budget allows=
 =0A=
sufficient quality)=0A=
=0A=
that the 4x4 has lost even before compression.=0A=
=0A=
=0A=
=0A=
=0A=
=0A=
The second reason I think 4x4 subsampling is not worth supporting is that =
it=0A=
complicates=0A=
=0A=
implementation. Compare `putcontig8bitYCbCr44tile` with any of the other `=
=0A=
put*` routines.=0A=
=0A=
And it grows larger with correct handling of arbitrary col_offset. Of =
=0A=
course, that's just a few=0A=
=0A=
more lines of code, so not a big deal.=0A=
=0A=
=0A=
=0A=
=0A=
=0A=
But there's a bigger issue. Here's a part of `TIFFScanlineSize64` comment =
=0A=
from `tif_strip.c`=0A=
=0A=
=0A=
=C2=A0* The ScanlineSize in case of YCbCrSubsampling is defined as the=
=0A=
=C2=A0* strip size divided by the strip height, i.e. the size of a pack of=
 =0A=
vertical=0A=
=C2=A0* subsampling lines divided by vertical subsampling. It should thus =
make=0A=
=C2=A0* sense when multiplied by a multiple of vertical subsampling.=0A=
=0A=
In the case of 4x4 subsampling (18-byte blocks), this definition only make=
s =0A=
sense=0A=
when the number of blocks per line is even. When there's an odd number of =
=0A=
them,=0A=
the size of the pack isn't divisible by 4.=0A=
=0A=
If (1 <=3D width % 8=C2=A0 <=3D 4) then ScanlineSize is not a whole number=
.=0A=
=0A=
Hence 4x4 subsampled images would need special treatment wherever =0A=
ScanlineSize=0A=
is used to calculate some offset into the image.=0A=
=0A=
=0A=
--=_30e66c122e87d83450f58ced=f609cbef-2ee0-5b05-a754-60df12d9e056_=
Content-Type: text/html;
	charset=utf-8
Content-Transfer-Encoding: quoted-printable

<html><body><br><p>---------- P=C5=AFvodn=C3=AD zpr=C3=A1va ----------<br>=
Od: Even Rouault &lt;even.rouault@spatialys.com&gt;<br>Datum: 17. 12. 2016=
 16:21:33<br></p><br><blockquote><div style=3D"font-family:'monospace';fon=
t-size:9pt;font-weight:400;font-style:normal">I've spent a couple of hours=
 analyzing the issue raised on=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">http://bugzilla.maptools.org/show_bug.cgi?id=3D2637</=
p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">&nbsp;</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">This is a defect in tif_getimage.c when decoding a ti=
led old-JPEG</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">with YCbCr 4:4 resampling, and with a unusual tile wi=
dth of 3.</p>=0A=
</div></blockquote><p><br></p><p>I wonder how you managed to create tiled =
YCbCr tiff. Some time ago I wanted to create some</p><p>such images for te=
sting, and couldn't figure out how, as the rgb2ycbcr tool only creates str=
ipped,</p><p>and tiffcp and tiffcrop refuse to copy subsampled non-JPEG im=
ages.<br></p><p><br></p><p>But I digress. The function `putcontig8bitYCbCr=
44tile` is used for stripped images as well, so you</p><p>don't need to cr=
eate images with weird tile sizes, you can just create stripped images wit=
h weird<br></p><p>widths and observe that 4x4 subsampling is a no-go with =
certain widths.</p><p><br></p><blockquote><div style=3D"font-family:'monos=
pace';font-size:9pt;font-weight:400;font-style:normal"><p style=3D"margin-=
top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px=
">putcontig8bitYCbCr44tile has an optimized case when the useful width and=
 height are</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">multiple of 4, and here we are in the general case wh=
en they are not. So apparently</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">this code is supposed to deal with useful width not m=
ultiple of 4. I cannot really</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">make sense of the (fromskew * 18) / 4 computation (18=
=3D4x4+2 and 4 must be the horizontal</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">or vertical resampling factor) and the pp +=3D fromsk=
ew (note that</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">those are also used in the optimized case ). Interest=
ingly in the 2x2 resampling case,</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">the formula is (fromskew / 2) * 6, so the division th=
ere is made before the computation.</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">So perhaps a fix would be (fromskew / 4) * 18 ?, whic=
h would evaluate to 0 here</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">and avoid the overflow.</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px"></p></div></blockquote><p><br></p><p>`fromskew` that =
is passed to the function is the number of pixels to skip when advancing t=
o the next row.</p><p>This calculation turns it into the number of bytes t=
o skip when advancing to the next 4-row pack.<br></p><p>In 4x4 subsampling=
 case, there are 4x4 Y samples, 1 Cb and 1 Cr sample in a block, hence the=
 block size is 18.<br></p><br>`(fromskew / 4) * 18` might fix that for the=
 tile reading case, but not when you ask TIFFRGBAImageGet<br>to give you w=
=3D19 pixels (with col_offset=3D0 to keep it simple) from a stripped image=
 whose width=3D21;<br>because fromskew=3D2px, but it must skip the 1 right=
-most block when advancing to the next row pack.<br><br>In other words, th=
e number of skipped pixels alone isn't enough information to calculate how=
 many bytes<br>need to be skipped.<br><br>I've recently re-written a consi=
derable portion of `get_image.c` put* functions because I needed to extrac=
t<br>regions with arbitrary `col_offset` and `row_offset` from any kind of=
 image. Although partial support for<br>arbitrary `col_offset` was recentl=
y added to libtiff, it's still broken for paletted and subsampled images,<=
br>so I had to roll my own. I can turn my modifications into a proper patc=
h, but that's not a priority for me and<br>I'd very much prefer to do that=
 after libtiff will have migrated to git or mercurial.<br><br>After having=
 implemented and tested arbitrary region extraction from 4x4 subsampled im=
ages, I came to<br>the conclusion that it'd be better to remove 4x4 subsam=
pling support from libtiff and the TIFF specification<br>as well. I was pl=
anning to propose that in a message of its own, as it sure will be content=
ious, but since you<br>mentioned one of the reasons, I think I might just =
add to that...<br>&nbsp;<blockquote><div style=3D"font-family:'monospace';=
font-size:9pt;font-weight:400;font-style:normal"><p style=3D"margin-top:0p=
x;margin-bottom:0px;margin-left:0px;margin-right:0px;text-indent:0px">But =
I cannot verify if that doesnt break valid images. Has=0A=
</p><p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-ri=
ght:0px;text-indent:0px">someone legit OJPEG tiled 4:4 images... ? I tried=
 to create a regular JPEG tiled 4:4, with</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">tile of dimension 32x32 (otherwise this is rejected),=
 and of image dimension 63x63, but this</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">is kind of fun since by default libjpeg has a C_MAX_B=
LOCKS_IN_MCU/D_MAX_BLOCKS_IN_MCU limit</p>=0A=
<p style=3D"margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:=
0px;text-indent:0px">to 10 that prevents that (you need to increase it to =
20 for example)</p></div></blockquote><p><br></p><p>Yes, and there's also =
a snarly comment in libjpeg source, discouraging from increasing the</p><p=
>compression limit (for decompression you might be *forced* to increase it=
 to decode an image</p><p>you get somewhere).</p><p><br></p><p>Therefore i=
t is impossible to create or decode a JPEG-compressed TIFF with 4x4 subsam=
pling</p><p>(which would require 18 blocks in MCU), unless you use a custo=
m-built libjpeg with higher limits.</p><p>IMO not worth it, totally defeat=
s portability.<br></p><p><br></p><p>So you have to use a different compres=
sion if you want 4x4 subsampling. Now, I'm no expert</p><p>on image compre=
ssion, but isn't it generally better to subsample less and lossy-compress =
more?</p><p>I mean, if I had a source (non-subsampled) image and a desired=
 subsampled file size, it'd expect</p><p>4x2-subsampled JPEG to look bette=
r than 4x4-subsampled ANOTHER-compression, simply</p><p>because the 4x2 JP=
EG might preserve some detail (if the size budget allows sufficient qualit=
y)</p><p>that the 4x4 has lost even before compression.<br></p><p><br></p>=
<p>The second reason I think 4x4 subsampling is not worth supporting is th=
at it complicates</p><p> implementation. Compare `putcontig8bitYCbCr44tile=
` with any of the other `put*` routines.</p><p>And it grows larger with co=
rrect handling of arbitrary col_offset. Of course, that's just a few</p><p=
>more lines of code, so not a big deal.<br></p><p><br></p><p>But there's a=
 bigger issue. Here's a part of `TIFFScanlineSize64` comment from `tif_str=
ip.c`<br></p><br>&nbsp;* The ScanlineSize in case of YCbCrSubsampling is d=
efined as the<br>&nbsp;* strip size divided by the strip height, i.e. the =
size of a pack of vertical<br>&nbsp;* subsampling lines divided by vertica=
l subsampling. It should thus make<br>&nbsp;* sense when multiplied by a m=
ultiple of vertical subsampling.<br><br>In the case of 4x4 subsampling (18=
-byte blocks), this definition only makes sense<br>when the number of bloc=
ks per line is even. When there's an odd number of them,<br>the size of th=
e pack isn't divisible by 4.<br><br>If (1 &lt;=3D width % 8&nbsp; &lt;=3D =
4) then ScanlineSize is not a whole number.<br><br>Hence 4x4 subsampled im=
ages would need special treatment wherever ScanlineSize<br>is used to calc=
ulate some offset into the image.<br><br><br></body></html>=
--=_30e66c122e87d83450f58ced=f609cbef-2ee0-5b05-a754-60df12d9e056_=--


--===============0769772828==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Tiff mailing list: Tiff@lists.maptools.org
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
--===============0769772828==--
