Return-Path: <tiff-bounces@lists.osgeo.org>
Received: from mailgate109.isp.belgacom.be ([195.238.20.41])
          by mailfep003.skynet.be
          (InterMail vM.8.04.03.28.4 201-2389-100-182-103-20180124)
          with ESMTP
          id <20201231023900.QFMC7220.mailfep003.skynet.be@mailgate109.isp.belgacom.be>
          for <chris.lindelaan@skynet.be>; Thu, 31 Dec 2020 03:39:00 +0100
Received-SPF: None (mx101.skynet.be: no sender authenticity
  information available from domain of
  tiff-bounces@lists.osgeo.org) identity=pra;
  client-ip=140.211.15.3; receiver=mx101.skynet.be;
  envelope-from="tiff-bounces@lists.osgeo.org";
  x-sender="tiff-bounces@lists.osgeo.org";
  x-conformance=sidf_compatible
Received-SPF: Pass (mx101.skynet.be: domain of
  tiff-bounces@lists.osgeo.org designates 140.211.15.3 as
  permitted sender) identity=mailfrom; client-ip=140.211.15.3;
  receiver=mx101.skynet.be;
  envelope-from="tiff-bounces@lists.osgeo.org";
  x-sender="tiff-bounces@lists.osgeo.org";
  x-conformance=sidf_compatible; x-record-type="v=spf1";
  x-record-text="v=spf1 mx a:mail.osgeo.org a:lists.osgeo.org
  a:mail.osgeo.osuosl.org a:tracsvn.osgeo.osuosl.org -all"
Received-SPF: Pass (mx101.skynet.be: domain of
  postmaster@lists.osgeo.org designates 140.211.15.3 as
  permitted sender) identity=helo; client-ip=140.211.15.3;
  receiver=mx101.skynet.be;
  envelope-from="tiff-bounces@lists.osgeo.org";
  x-sender="postmaster@lists.osgeo.org";
  x-conformance=sidf_compatible; x-record-type="v=spf1";
  x-record-text="v=spf1 mx a:mail.osgeo.org a:lists.osgeo.org
  a:mail.osgeo.osuosl.org a:tracsvn.osgeo.osuosl.org -all"
Authentication-Results: mx101.skynet.be; spf=None smtp.pra=tiff-bounces@lists.osgeo.org; spf=Pass smtp.mailfrom=tiff-bounces@lists.osgeo.org; spf=Pass smtp.helo=postmaster@lists.osgeo.org; dkim=hardfail (body hash did not verify [final]) header.i=@larrygritz.com
X-Ironport-Dmarc-Check-Result: validskip
IronPort-SDR: 12HFlQ0f13VCHx5imJMTlf/jv71QlMxNq+LULt0s4FpAMU0Bj4du8xdd0BzO6J3vyr0qDt8M/r
 qONrefO/zjV2qI+xE1Vj4lbeOuVHcC/rhgHPoeN4xPYbWhNXzH4zbuecEj+z7fu8CoixcnGRxn
 ogCpRYvEW7dkatestP97y+jOmh1aPxiHG1MFpdBUzYOJ4UaSjt8c2ZHXQEw8M+kWRNqPiRj61B
 BxEQTKbuP6TbWhP5PIfN6ZvbinYmXsEZnq2qIOyhVo0gBV7ei4uv0z4ZmVD75GGBcFIHDmC/u6
 bye1qjk4Gblqlo9YlZrY2L8s
IronPort-PHdr: =?us-ascii?q?9a23=3AgvcF4xdEuBoy8lc4iSldpV2KlGMj4u6mDksu8p?=
 =?us-ascii?q?Mizoh2WeGdxc24ZhWN2/xhgRfzUJnB7Loc0qyK6v+mAzZcqsrQ+Fk5M7V0Hy?=
 =?us-ascii?q?cfjssXmwFySOWkMmbcaMDQUiohAc5ZX0Vk9XzoeWJcGcL5ekGA6ibqtW1aFR?=
 =?us-ascii?q?rwLxd6KfroEYDOkcu3y/qy+5rOaAlUmTaxe7x/IAi0oAnLqMUan4RvJqk+xx?=
 =?us-ascii?q?bNv3BFZ/lYyWR0KFyJgh3y/N2w/Jlt8yRRv/Iu6ctNWrjkcqo7ULJVEi0oP3?=
 =?us-ascii?q?g668P3uxbDSxCP5mYHXWUNjhVIGQnF4wrkUZr3ryD3q/By2CiePc3xULA0RT?=
 =?us-ascii?q?Gv5LplRRP0lCsKMSMy/XrJgcJskq1UvBOhpwR+w4HKZoGVKOF+db7Zcd8DWG?=
 =?us-ascii?q?ZNQtpdWylHD4ihbYUAEvABMP5XoIf9pVQAoxiwBQeyCu3o1zFInn37068n3+?=
 =?us-ascii?q?kvDQ3JwBIvH8kVvXTRsNn1Mb0fUeCpwKXWyzjIcvNY2S366IjNah0vp+uDXa?=
 =?us-ascii?q?hqccvR1EIhFhnFjlSMqY3kIjiY0eANs2eA4upkT+2vkXQnqgF+oji1x8cslo?=
 =?us-ascii?q?jIipgJxVDD8CV02YA4LsC3R0Bne9CrCodQtz2EOItsRMMvW3xltDg6x7AJpJ?=
 =?us-ascii?q?O2ficExZYnyhPBdfCKcYuF7w79WOieIzp1hm9pdK6jixux8EWtyPHwW9S03V?=
 =?us-ascii?q?tWoCRJjNfCu24L2hfO5MaHTf598V2g2TaJzw3T8eBEIUUslarfNZEh2b4xlo?=
 =?us-ascii?q?EPsUvdGy/2g1/6jKiMdkUr4uSo5P7nba/+pp+cNo97lhr+MqE0lcywAOQ3Lg?=
 =?us-ascii?q?sOU3Kc+eSm273u+1DyTrZSjvAuj6XUv4zWKd4FqqKkHgNZyJsv5halAzqoyN?=
 =?us-ascii?q?gUgHsKIV1fdB+FlYTlJk/CLfLiAfujhVmnjS1lyOrcPrL7B5XANnjDn6nlfb?=
 =?us-ascii?q?Z680NczAszzctD55JPEL0BJ+nzWkDvu9zfFBM5NBa0w+n/BNV80IMRR36PD7?=
 =?us-ascii?q?eEPK7drVOE/PwjL/SRaIMPpTrwK+Ip6vD2gX88g1AdfK2p3ZUNaHC/G/RrO1?=
 =?us-ascii?q?mZYXvigtcPCGsFpQ0+TPHsiFKeTzFTfG2/X6Y95jEgFIKmFp3PRoe2gLyOwi?=
 =?us-ascii?q?i7GYdaZmdcClCDCXvobZmLW+8QaCKOJc9siiALVbi7S48gzhGirgv6y7thLu?=
 =?us-ascii?q?XJ5CIYsYjs28Jz5+DIjhEy9jx1D8KD3GGRVW17hX0HFHcL2rtiqxl91kubyv?=
 =?us-ascii?q?o/xPhZDsBIofRSXQo9c5nGwKt/AtH2XwvHOdCRVFehRM7hHTA/QIEMxcQTaR?=
 =?us-ascii?q?N4EtSmkheRwyukDfoPmqWWCYco2qbdxGTqYcFmxHvBkq47gA49X8FNOGa607?=
 =?us-ascii?q?N57BXZHIXTkk+UxJusbrkW/CPE+GqZmGqSoFlDAkk3VaTeQWtZYVDZoNO/4V?=
 =?us-ascii?q?nNCLqnCLAiOw0GztaeK6xMcZr1jFtIF8rlI8nUQ2+4l2qqUBOBx7eQa9j2em?=
 =?us-ascii?q?sTmT/QEVUJiBw7+XedKRN4ATyurmWYCyZhQknyaUHh+vUrtXWgU0UvxBuLZU?=
 =?us-ascii?q?Ay673g0BkfzdKGSv4I07QEsScn42F+Eky80snbDfKbpg95eKgabdo55F5ck3?=
 =?us-ascii?q?7J8RFmaM+ONadn03oXaR5m92z01gllQtFEnuAupWkw3QVoKL6KllhGcmXLjt?=
 =?us-ascii?q?jLJrTLJzyqr1iUYKnM1wSbiY7Oo/pdxNcZjhDOogitC0M+8nJhj4QOgWXJv8?=
 =?us-ascii?q?aCBV8ISpu0SUY+rksyrOTAby00947YhjVgZK29qCXT1MgoGPljwRGlLJ9fZc?=
 =?us-ascii?q?bmXAT1FdEXAdTrNP0ylgqsbxcJef5f7rU1OMX0bOaM2qOgILRuhjWj32VBpZ?=
 =?us-ascii?q?pwykadsjZ7GOLBw5tXyPr9vEPVUjrnl16uv4X2ldJeaD8fBGe5wiX/VpJWNe?=
 =?us-ascii?q?VpKIICE32/LNe22sc4jJnoCDZS9AuTNlMhid+qeRvITXzZ0ABqsCZfsWKpnR?=
 =?us-ascii?q?SRkWNNujJ8/eKViR3Sybv/VTBfGEJxeVNui3LyALWE18gQG3miUVgjy0a4yR?=
 =?us-ascii?q?r+1aEY9OdRJDbaEXt2QE2UZzlZQKrpjeajUcxU8rwK7QIUDtyjeHWxFrnakU?=
 =?us-ascii?q?cCyXzMBigOn280Xhel4JfEv00i1HDNBlgohSLgSf5O1Br5+5+5J7YJhBcdan?=
 =?us-ascii?q?VCjiDTGVObJ+WD8faNy7XYlOmkVUmMTZNTTDi60ZHHuRS+tFFBGAeEkM7sqP?=
 =?us-ascii?q?fpPiEU6QTS1Iw5HTWNrQz7ZJHszbj/K+98Y010UV/18cZ0E4B6wcMgwZAK3n?=
 =?us-ascii?q?4CgY+JuHcdi2DpZN9c1bO2bHMWRXYHwtKd5g/5kFNuNHOH1srKWHSby89UNI?=
 =?us-ascii?q?PgMEoLxiIw6dxLA66I7btC2BF4uUe8sRmLOqgvmydEkaJo830LhewV/gAgnW?=
 =?us-ascii?q?2GGr5HO05eMGT3kgiQqcikpfBLZWihNLK3yUx1kMuJCLCZvhoaX232d5BkGj?=
 =?us-ascii?q?V/vY1kKFyZ6HTo8cn/fcXIK9catxmaiRDF2vRUJpx0nP0XgyFqIkr5vGY50K?=
 =?us-ascii?q?g8lhNj2te9pofUY3518veBCwVDfibwe9tV+jzpivNGmd2K2om0Aph7MjEKR4?=
 =?us-ascii?q?fzC/WzHz8V8/P9OFXGHD49ryKbEKDTEwae7A8mpXXDAtirPmqXbHUYwZ1kQw?=
 =?us-ascii?q?XVOkFFgQ4FFAY0n5gwEjXrjMzseUt0/HYQs3b8owFW2+1yNgXtFGzYoV7yOA?=
 =?us-ascii?q?05Q5WeMhdaqzp6yRyMaJ646eR+V2Fd7sT59UqWKX2dahgOB2xbEkqDT0vuOL?=
 =?us-ascii?q?Wj/5HJ7vSYC+yiLvDPfaTry6QWVvGGwoiq25dn+DDEP9uGP31rBfk2kkRZWn?=
 =?us-ascii?q?UxF8PckjQJAysZ8kCFJ9Kaqhn58CpqqMuy69zvWRnz/s2IELRfNpNo4R/3ya?=
 =?us-ascii?q?aPOuiMhTpofC5C38BppzeAw7we0VgOziB2ImDxSfJa7HeLFf+WwfwfFRMQZi?=
 =?us-ascii?q?JtOdEd6rJlhlALIs3KjN7pkLR13ZtXQx9IU0LsnsaxaIkEOWa4YRnbBUiFcb?=
 =?us-ascii?q?6BODvAztrfZaKnVaYWi/5buhr2viyUWRyGXHzLh3zyWhajPPsZxj2aMhIbso?=
 =?us-ascii?q?agdB1gEkDnTcn6cVu8K9B6insx27J+1RaofSYMdDN7dU1KtLiZ6yhV1+5+F2?=
 =?us-ascii?q?J25X1gNeCYmiyd4rCCeKwbuvZqHCl40tlizihnm+lt5TpfDLxwiHKK95h1oE?=
 =?us-ascii?q?Cgn/XJwDc1GBZJrz9KgsqMsyAAce3F95dOHHzD4RQG4H64DxURu8AjDcbgtq?=
 =?us-ascii?q?cWzcLA3K7+MzZN9dvI8NBUXpSMbpjeaTx4bFyyUDfPaWlNBSamL2Tem1BQnL?=
 =?us-ascii?q?mJ+3uZo4J74pnglZwSS6NKAVk8F/cUEENgT5QJJJZ6WC9hkKbO1ZJQoyDn9V?=
 =?us-ascii?q?+IGYMB7fWlHrqIDP7iKSiUl+xBd0JQmPXjLpUVO5G90UExDzsy1InMBUfUWs?=
 =?us-ascii?q?hA5yN7aQph6llM/nY7RGou3UnocSup4WQPDrizhRE7jU15e+tnp1KOqx8nY0?=
 =?us-ascii?q?HHoic9ihx7hdTrj3WbdyP3J6qrdYVXEDbv8U8qPZ78BQFvYkfh+C4sfCeBTL?=
 =?us-ascii?q?VXgbx6cGltgwKJoppDF8lXSqhcaQMRz/WaNL04lE5RoSK9yQpb9PPIXNF8wR?=
 =?us-ascii?q?Ayf8fm/Bcik0pzKcQ4LqvKKO9Vw0hM0+iQ6zSw2Ll5xR9WLhQI+WKWPikTt0?=
 =?us-ascii?q?EPcL48KGKhrOht8hCZ3TxYd2ULEf0wrZcIvgs0aeGJziam1KVMJ0f3MPeCKL?=
 =?us-ascii?q?id/W/amoaBEE8q30gTiU8D+qN53MBldFGJUFsriryLGFxMPM7GY1gPPfBf/3?=
 =?us-ascii?q?XSYyuC9N71784oZ9eFH/vzBa+LpP9M2wS/HxcvEphK5MlTVpWr1UjZK4/gIt?=
 =?us-ascii?q?tngV014x/3IVyeEPlTUBaKiysc5cakw5Jwm45HKXkRDH58PiO++rvM7lZ22L?=
 =?us-ascii?q?zZBY5wOypcBcMNLRdUEIWiljRcvmhcATX/ye8fxAWYrnf9qinWEDjgfo9jaf?=
 =?us-ascii?q?OTNltnDNC7/yl68rDj0AKPtM+HfiejaJI56bqtoasAqp2KCu1ZV+x4ox6Ews?=
 =?us-ascii?q?9DRG2sXnKJG9PmQvq4I4Qqc9HwDW63F1KljDdgBdvwMtjoJK+VhwrlXq5QsZ?=
 =?us-ascii?q?KHx3YkLsCwEXcZARg69IRhrOpsIBYOZZY2e0uirwMlK6m2OxuVyP2qQn2xMn?=
 =?us-ascii?q?1RVPZSyqO9fbMdnE9OJqeqjXAnSJ891ey+90UAEYoLgh/pzvGmf4BCUCL3Fy?=
 =?us-ascii?q?8Va0DVqCE+jWQkKvcqz7J13kbTqVdFeWPuFqQheClesto7H1/XPXhmFj9yWQ?=
 =?us-ascii?q?qHlYSaqgu8l7lA+iJcm5BTyuJItz75pJCXaWCoWbe3stPSqCUtap4huaIUU8?=
 =?us-ascii?q?SrK5mDvZLa2DvEQ5TX9AqeTSmhE7xdgNcYKXBEWvBDgn8jf8sdtodGr00qS8?=
 =?us-ascii?q?AlI/pIEqZk47mubXA9XHwiiBQBXobF5wQsx+K12r/UjBCVKctwNB0frI4Ehc?=
 =?us-ascii?q?ASXikwZTkR9vb6C9fm0lScQ21OGz89qBxW7VtfxItxZfz+po3TQ5JLjTlMrK?=
 =?us-ascii?q?AsC3aZJtxT71L+D1qurx34RfGmyrP72QNJ0Omq1cIUVRk5DlJSlb9b?=
X-IronPort-Anti-Spam-Filtered: true
X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0EsAAB6OO1fhwMP04xiGQEBAQEBAQE?=
 =?us-ascii?q?BAQEBAQEBAQEBARIBAQEBAQEBAQEBAQFAgU+BdgYoGAFkWx0DBzaICoU5iCw?=
 =?us-ascii?q?Dg32YMRQBAQIBAQEBAQkYAQoKAgQBAQEBgQOFMAgfBgEENBMCAQIBAQEDAgU?=
 =?us-ascii?q?BAQEEAQEBAgEBAgMCAgEBAhABAQEBDQsJCCksBmBgBGIGWwSBbAwzDII4BQI?=
 =?us-ascii?q?DHwEGbYEGAQEBAQEBAQEBAQEBAQEBAQEBAQEWAg1UJkIBAQEBAgEBAQEaChk?=
 =?us-ascii?q?GCh4LAQICAQECBgEBCg4KHAYECAMBIwEvBhMFBBKDCwGCZiAFCq5mdIEBM4M?=
 =?us-ascii?q?Me4FRg0KBOQmBOI0pQT4BgQI/gREnHIFYfj6CUgsBAwGFKIIsgWmBC18BKgF?=
 =?us-ascii?q?UByAVRwohGxIULQKPMgGMIQ1Km1GDAIkqhniEQoZ3H4MpkAiPH5FGjVWRHQx?=
 =?us-ascii?q?GRoQXgW2BezMaCBsVOyoBgj4JNQ8BAgECDQIBAgMBAgICAQECAgEBAo4qF4E?=
 =?us-ascii?q?CAQKCSYUUhWVTAjUCBgoBAQMJW4sJgQ5fAQE?=
X-IPAS-Result: =?us-ascii?q?A0EsAAB6OO1fhwMP04xiGQEBAQEBAQEBAQEBAQEBAQEBA?=
 =?us-ascii?q?RIBAQEBAQEBAQEBAQFAgU+BdgYoGAFkWx0DBzaICoU5iCwDg32YMRQBAQIBA?=
 =?us-ascii?q?QEBAQkYAQoKAgQBAQEBgQOFMAgfBgEENBMCAQIBAQEDAgUBAQEEAQEBAgEBA?=
 =?us-ascii?q?gMCAgEBAhABAQEBDQsJCCksBmBgBGIGWwSBbAwzDII4BQIDHwEGbYEGAQEBA?=
 =?us-ascii?q?QEBAQEBAQEBAQEBAQEBAQEWAg1UJkIBAQEBAgEBAQEaChkGCh4LAQICAQECB?=
 =?us-ascii?q?gEBCg4KHAYECAMBIwEvBhMFBBKDCwGCZiAFCq5mdIEBM4MMe4FRg0KBOQmBO?=
 =?us-ascii?q?I0pQT4BgQI/gREnHIFYfj6CUgsBAwGFKIIsgWmBC18BKgFUByAVRwohGxIUL?=
 =?us-ascii?q?QKPMgGMIQ1Km1GDAIkqhniEQoZ3H4MpkAiPH5FGjVWRHQxGRoQXgW2BezMaC?=
 =?us-ascii?q?BsVOyoBgj4JNQ8BAgECDQIBAgMBAgICAQECAgEBAo4qF4ECAQKCSYUUhWVTA?=
 =?us-ascii?q?jUCBgoBAQMJW4sJgQ5fAQE?=
X-MGA-submission: =?us-ascii?q?MDFMWGJTOkP65qIPeEbKdgaDsyZCzwpV1PYwzn?=
 =?us-ascii?q?clT6TzgqosgCNmgNEHm70EK632REnlcRrrRwlvZMZhWi73JliPuTjZNq?=
 =?us-ascii?q?fomkUgv550eelVG6N6skk5fQkERGP+0ccSTfU=3D?=
Received: from osgeo6.osgeo.osuosl.org (HELO lists.osgeo.org) ([140.211.15.3])
  by mx101.skynet.be with ESMTP/TLS/ECDHE-RSA-AES128-GCM-SHA256; 31 Dec 2020 03:38:57 +0100
Received: from osgeo6.osgeo.osuosl.org (localhost [127.0.0.1])
	by lists.osgeo.org (Postfix) with ESMTP id 832086143EB4;
	Wed, 30 Dec 2020 18:38:51 -0800 (PST)
Received: from hedgehog.birch.relay.mailchannels.net
 (hedgehog.birch.relay.mailchannels.net [23.83.209.81])
 by lists.osgeo.org (Postfix) with ESMTPS id 2D3B9614662C
 for <tiff@lists.osgeo.org>; Wed, 30 Dec 2020 18:38:50 -0800 (PST)
X-Sender-Id: dreamhost|x-authsender|lg@larrygritz.com
Received: from relay.mailchannels.net (localhost [127.0.0.1])
 by relay.mailchannels.net (Postfix) with ESMTP id 5A0A7122397;
 Thu, 31 Dec 2020 02:38:49 +0000 (UTC)
Received: from pdx1-sub0-mail-a4.g.dreamhost.com
 (100-96-87-21.trex.outbound.svc.cluster.local [100.96.87.21])
 (Authenticated sender: dreamhost)
 by relay.mailchannels.net (Postfix) with ESMTPA id 836B3121EB6;
 Thu, 31 Dec 2020 02:38:48 +0000 (UTC)
X-Sender-Id: dreamhost|x-authsender|lg@larrygritz.com
Received: from pdx1-sub0-mail-a4.g.dreamhost.com (pop.dreamhost.com
 [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384)
 by 0.0.0.0:2500 (trex/5.18.11); Thu, 31 Dec 2020 02:38:49 +0000
X-MC-Relay: Neutral
X-MailChannels-SenderId: dreamhost|x-authsender|lg@larrygritz.com
X-MailChannels-Auth-Id: dreamhost
X-Shrill-Keen: 64cd1fda3dfb81e6_1609382329159_315813919
X-MC-Loop-Signature: 1609382329159:69992478
X-MC-Ingress-Time: 1609382329159
Received: from pdx1-sub0-mail-a4.g.dreamhost.com (localhost [127.0.0.1])
 by pdx1-sub0-mail-a4.g.dreamhost.com (Postfix) with ESMTP id 35289875B8;
 Wed, 30 Dec 2020 18:38:48 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=larrygritz.com; h=
 content-type:mime-version:subject:from:in-reply-to:date:cc
 :message-id:references:to; s=larrygritz.com; bh=XYhO9xkhi2JHLeeR
 xvflWA67QAk=; b=Ytb7uIB0JDRURdnMvIUX0pb/YbV8b75uD4lza+8+Fc7a8TVW
 0Szi1S4IZjsrGJ4O+6PwqMC4oOZ4pr7Gq+837gANg2jUH904z8BF3A0QXWVyeNw+
 02EsF4RoqlwcOpTBdKq4JsNarjCEsfhUy9tz/eWm9TCqrSgV7ZBfGAFPCAk=
Received: from xboxone.hitronhub.home (S0106f0f249b09b33.vc.shawcable.net
 [174.7.127.0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (No client certificate requested)
 (Authenticated sender: lg@larrygritz.com)
 by pdx1-sub0-mail-a4.g.dreamhost.com (Postfix) with ESMTPSA id A8E8A7E0A4;
 Wed, 30 Dec 2020 18:38:47 -0800 (PST)
Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.4\))
X-DH-BACKEND: pdx1-sub0-mail-a4
From: Larry Gritz <lg@larrygritz.com>
In-Reply-To: <alpine.GSO.2.20.2012301932030.20407@scrappy.simplesystems.org>
Date: Wed, 30 Dec 2020 18:38:46 -0800
Cc: tiff@lists.osgeo.org
X-Mao-Original-Outgoing-Id: 631075126.572901-1af1283692c1c71c03209bb184d38c36
Message-Id: <1701694F-50BA-44E0-86CC-10002DEF0831@larrygritz.com>
References: <mailman.25.1609358402.3913.tiff@lists.osgeo.org>
 <20DAEBC0-D179-4C65-A807-B989425738F9@larrygritz.com>
 <alpine.GSO.2.20.2012301932030.20407@scrappy.simplesystems.org>
To: Bob Friesenhahn <bfriesen@simple.dallas.tx.us>
X-Mailer: Apple Mail (2.3608.120.23.2.4)
Subject: Re: [Tiff] Multithreading support?
X-BeenThere: tiff@lists.osgeo.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: TIFF and libtiff discussion <tiff.lists.osgeo.org>
List-Unsubscribe: <https://lists.osgeo.org/mailman/options/tiff>,
 <mailto:tiff-request@lists.osgeo.org?subject=unsubscribe>
List-Post: <mailto:tiff@lists.osgeo.org>
List-Help: <mailto:tiff-request@lists.osgeo.org?subject=help>
List-Subscribe: <https://lists.osgeo.org/mailman/listinfo/tiff>,
 <mailto:tiff-request@lists.osgeo.org?subject=subscribe>
Content-Type: multipart/mixed; boundary="===============8563241416235669655=="
Errors-To: tiff-bounces@lists.osgeo.org
Sender: "Tiff" <tiff-bounces@lists.osgeo.org>


--===============8563241416235669655==
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_470FCDE8-5DD5-43B6-9156-954CB7A6B16F"


--Apple-Mail=_470FCDE8-5DD5-43B6-9156-954CB7A6B16F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

Yeah, the back compatibility could be tricky, but I think it's possible =
to add a few new API calls that are thread-safe, even while keeping the =
old calls and workflows and documenting them as not threadsafe.

I agree with you about the internal thread pool -- FWIW, that's a bit of =
an albatross around the neck of OpenEXR. A better strategy is to allow =
an interface for specifying how to submit tasks to the application's =
thread pool, somewhat akin for how the application can supply its own =
low-level I/O functions. Or to just punt on any internal threading =
knowledge at all and just have a clean separation between the inherently =
serial and stateful parts of the API and the parts amenable to =
concurrency. The biggest sin currently is that TIFFReadScanline/Tile/etc =
present a stateful serial interface, but most of the internal expense is =
code that doesn't need to be.


> Are you (and others) ready and willing to do most of the work?

Not at all! Unfortunately, my libtiff internals knowledge is thin and =
I'm already the maintainer of two large and widely used open source =
packages (hence, I do fully understand the frustration of somebody just =
laying a call for a major overhaul at your doorstep but being unable to =
send a PR, sorry). I'm afraid that the biggest contribution that I'm =
able to make in practice is just to outline in some detail what the =
downstream packages really need from libtiff in order to get an order of =
magnitude speedup.

I think that the minimal step forward would be to expose a =
stateless/reentrant TIFF{Encode,Decode}{Strip,Tile}, which would be a =
simple way to access libtiff's implementations of the compression codecs =
(e.g. TIFFReadEncodedStrip would be equivalent to TIFFReadRawStrip =
followed immediately by TIFFDecodeStrip) -- that would allow apps to do =
all the thread policy stuff by using libtiff to serially perform the I/O =
and then the app side could make concurrent calls for the decoding. =
That's basically what I'm doing in OIIO now to speed up TIFF I/O, except =
that I only have it working for a few major cases (deflate compression =
only, horizontal or no predictor, uint8 or uint16 types only, contiguous =
planarconfig only). A simple libtiff API call that handled raw =
strips/tiles <--> pixels for all possible cases supported by the library =
would be tremendously helpful. It's possible (I don't know) that these =
entry points already more or less exist internal to the library, and all =
they really need is to be cleaned up and exposed as part of the API?

	-- lg


> On Dec 30, 2020, at 5:48 PM, Bob Friesenhahn =
<bfriesen@simple.dallas.tx.us> wrote:
>=20
> On Wed, 30 Dec 2020, Larry Gritz wrote:
>=20
>> But it would dramatically improve libtiff to have any or all of the =
following:
>>=20
>> * Add API calls for reading/writing a range of scanlines or tiles at =
a time.
>> * Eschew any "statefulness" between calls -- i.e. a single call =
should be able to specify begin/end scanline, and the TIFF directory =
within the file to read from (so there is not hidden state between =
TIFFSetDirectory and TIFFReadScanline that currently requires a lock on =
the application side).
>> * Reentrancy/thread safety of multiple read calls happening =
simultaneously on the same open TIFF handle.
>> * Ideally, using an internal thread pool (or at least the ability to =
optionally use TBB or an external thread pool passed in, etc.) so that =
libtiff could parallelize everything but the raw I/O that has to be =
serialized. Or, alternately, ...
>> * Exposing through the libtiff API a simple thread-safe "decompress =
this raw strip or tile that I already read" and "compress this pixel =
buffer to a raw strip buffer" that implements all of the codecs =
supported, thus allowing apps to split the raw read/write from the =
[de]compression, so they can more easily use their own threading to =
parallelize at least the [de]compression.
>>=20
>> Many applications could see an order of magnitude improvement in the =
I/O performance for TIFF files.
>=20
> This sounds great to me, as long as it can be layered in without =
impacting existing usages.  Existing apps need to continue to compile =
and run and without any background cycles consumed that they did not =
request.  I expect that there would need to be a lot of internal =
changes.
>=20
> Things like an internal thread pool would never be something that =
libtiff would itself decide to instantiate (given that the usage you =
describe is not the norm), but it could provide APIs which allow a using =
app to side-load a thread pool.
>=20
> Others have said that support for async-I/O (offloading several I/O =
requests to the kernel and being notified when data is available) is the =
solution to perceived problems, but async-I/O is not as uniformly =
supported as threads are.  Async-I/O does not provide any assistance for =
compression/decompression requirements.
>=20
> Libtiff is on GitLab now and the common way things work is that =
someone does the work, pushes a branch, and then submits a merge =
request.  Sometimes branches stay open/pending for a long time as =
development proceeds.  Are you (and others) ready and willing to do most =
of the work?
>=20
> Bob
> --=20
> Bob Friesenhahn
> bfriesen@simple.dallas.tx.us, =
http://www.simplesystems.org/users/bfriesen/
> GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/
> Public Key,     =
http://www.simplesystems.org/users/bfriesen/public-key.txt
>=20

--
Larry Gritz
lg@larrygritz.com





--Apple-Mail=_470FCDE8-5DD5-43B6-9156-954CB7A6B16F
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=us-ascii

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dus-ascii"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; line-break: after-white-space;" class=3D"">Yeah,=
 the back compatibility could be tricky, but I think it's possible to =
add a few new API calls that are thread-safe, even while keeping the old =
calls and workflows and documenting them as not threadsafe.<div =
class=3D""><br class=3D""></div><div class=3D"">I agree with you about =
the internal thread pool -- FWIW, that's a bit of an albatross around =
the neck of OpenEXR. A better strategy is to allow an interface for =
specifying how to submit tasks to the application's thread pool, =
somewhat akin for how the application can supply its own low-level I/O =
functions. Or to just punt on any internal threading knowledge at all =
and just have a clean separation between the inherently serial and =
stateful parts of the API and the parts amenable to concurrency. The =
biggest sin currently is that TIFFReadScanline/Tile/etc present a =
stateful serial interface, but most of the internal expense is code that =
doesn't need to be.</div><div class=3D""><br class=3D""><div =
class=3D""><br class=3D""></div><div class=3D""><blockquote type=3D"cite" =
class=3D"">Are you (and others) ready and willing to do most of the =
work?</blockquote><div class=3D""><br class=3D""></div>Not at all! =
Unfortunately, my libtiff internals knowledge is thin and I'm already =
the maintainer of two large and widely used open source packages (hence, =
I do fully understand the frustration of somebody just laying a call for =
a major overhaul at your doorstep but being unable to send a PR, sorry). =
I'm afraid that the biggest contribution that I'm able to make in =
practice is just to outline in some detail what the downstream packages =
really need from libtiff in order to get an order of magnitude =
speedup.</div><div class=3D""><br class=3D""></div><div class=3D"">I =
think that the minimal step forward would be to expose a =
stateless/reentrant TIFF{Encode,Decode}{Strip,Tile}, which would be a =
simple way to access libtiff's implementations of the compression codecs =
(e.g. TIFFReadEncodedStrip would be equivalent to TIFFReadRawStrip =
followed immediately by TIFFDecodeStrip) -- that would allow apps to do =
all the thread policy stuff by using libtiff to serially perform the I/O =
and then the app side could make concurrent calls for the decoding. =
That's basically what I'm doing in OIIO now to speed up TIFF I/O, except =
that I only have it working for a few major cases (deflate compression =
only, horizontal or no predictor, uint8 or uint16 types only, contiguous =
planarconfig only). A simple libtiff API call that handled raw =
strips/tiles &lt;--&gt; pixels for all possible cases supported by the =
library would be tremendously helpful. It's possible (I don't know) that =
these entry points already more or less exist internal to the library, =
and all they really need is to be cleaned up and exposed as part of the =
API?</div><div class=3D""><br class=3D""></div><div class=3D""><span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>-- =
lg</div><div class=3D""><br class=3D""></div><div class=3D""><br =
class=3D""><div><blockquote type=3D"cite" class=3D""><div class=3D"">On =
Dec 30, 2020, at 5:48 PM, Bob Friesenhahn &lt;<a =
href=3D"mailto:bfriesen@simple.dallas.tx.us" =
class=3D"">bfriesen@simple.dallas.tx.us</a>&gt; wrote:</div><br =
class=3D"Apple-interchange-newline"><div class=3D""><div class=3D"">On =
Wed, 30 Dec 2020, Larry Gritz wrote:<br class=3D""><br =
class=3D""><blockquote type=3D"cite" class=3D"">But it would =
dramatically improve libtiff to have any or all of the following:<br =
class=3D""><br class=3D"">* Add API calls for reading/writing a range of =
scanlines or tiles at a time.<br class=3D"">* Eschew any "statefulness" =
between calls -- i.e. a single call should be able to specify begin/end =
scanline, and the TIFF directory within the file to read from (so there =
is not hidden state between TIFFSetDirectory and TIFFReadScanline that =
currently requires a lock on the application side).<br class=3D"">* =
Reentrancy/thread safety of multiple read calls happening simultaneously =
on the same open TIFF handle.<br class=3D"">* Ideally, using an internal =
thread pool (or at least the ability to optionally use TBB or an =
external thread pool passed in, etc.) so that libtiff could parallelize =
everything but the raw I/O that has to be serialized. Or, alternately, =
...<br class=3D"">* Exposing through the libtiff API a simple =
thread-safe "decompress this raw strip or tile that I already read" and =
"compress this pixel buffer to a raw strip buffer" that implements all =
of the codecs supported, thus allowing apps to split the raw read/write =
from the [de]compression, so they can more easily use their own =
threading to parallelize at least the [de]compression.<br class=3D""><br =
class=3D"">Many applications could see an order of magnitude improvement =
in the I/O performance for TIFF files.<br class=3D""></blockquote><br =
class=3D"">This sounds great to me, as long as it can be layered in =
without impacting existing usages. &nbsp;Existing apps need to continue =
to compile and run and without any background cycles consumed that they =
did not request. &nbsp;I expect that there would need to be a lot of =
internal changes.<br class=3D""><br class=3D"">Things like an internal =
thread pool would never be something that libtiff would itself decide to =
instantiate (given that the usage you describe is not the norm), but it =
could provide APIs which allow a using app to side-load a thread =
pool.<br class=3D""><br class=3D"">Others have said that support for =
async-I/O (offloading several I/O requests to the kernel and being =
notified when data is available) is the solution to perceived problems, =
but async-I/O is not as uniformly supported as threads are. =
&nbsp;Async-I/O does not provide any assistance for =
compression/decompression requirements.<br class=3D""><br =
class=3D"">Libtiff is on GitLab now and the common way things work is =
that someone does the work, pushes a branch, and then submits a merge =
request. &nbsp;Sometimes branches stay open/pending for a long time as =
development proceeds. &nbsp;Are you (and others) ready and willing to do =
most of the work?<br class=3D""><br class=3D"">Bob<br class=3D"">-- <br =
class=3D"">Bob Friesenhahn<br class=3D""><a =
href=3D"mailto:bfriesen@simple.dallas.tx.us" =
class=3D"">bfriesen@simple.dallas.tx.us</a>, <a =
href=3D"http://www.simplesystems.org/users/bfriesen/" =
class=3D"">http://www.simplesystems.org/users/bfriesen/</a><br =
class=3D"">GraphicsMagick Maintainer, &nbsp;&nbsp;&nbsp;<a =
href=3D"http://www.GraphicsMagick.org/" =
class=3D"">http://www.GraphicsMagick.org/</a><br class=3D"">Public Key, =
&nbsp;&nbsp;&nbsp;&nbsp;<a =
href=3D"http://www.simplesystems.org/users/bfriesen/public-key.txt" =
class=3D"">http://www.simplesystems.org/users/bfriesen/public-key.txt</a><=
br class=3D""><br class=3D""></div></div></blockquote></div><br =
class=3D""><div class=3D"">
<div dir=3D"auto" style=3D"caret-color: rgb(0, 0, 0); color: rgb(0, 0, =
0); letter-spacing: normal; text-align: start; text-indent: 0px; =
text-transform: none; white-space: normal; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; text-decoration: none; word-wrap: =
break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" =
class=3D""><div>--</div><div>Larry Gritz</div><div><a =
href=3D"mailto:lg@larrygritz.com" =
class=3D"">lg@larrygritz.com</a></div><div class=3D""><br =
class=3D""></div></div><br class=3D"Apple-interchange-newline"><br =
class=3D"Apple-interchange-newline">

</div>
<br class=3D""></div></div></body></html>=

--Apple-Mail=_470FCDE8-5DD5-43B6-9156-954CB7A6B16F--

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

_______________________________________________
Tiff mailing list
Tiff@lists.osgeo.org
https://lists.osgeo.org/mailman/listinfo/tiff

--===============8563241416235669655==--
