Return-Path: <tiff-bounces@lists.maptools.org>
X-Original-To: info@awaresystems.be
Delivered-To: info@awaresystems.be
Received: from mx-i.b-one.net (mx-i.one.com [91.198.169.56])
	by mail9.b-one.net (Postfix) with ESMTP id BEB9F400220
	for <info@awaresystems.be>; Mon, 24 Nov 2008 20:44:40 +0100 (CET)
X-Virus-Scanned: by one.com
X-Spam-Score: 0
X-Spam-Level: 
X-Spam-Status: No, score=0 tagged_above=0 required=6 tests=[none]
X-Greylist: domain auto-whitelisted by SQLgrey-1.7.4
Received: from duke.maptools.org (r153.dmsolutions.ca [209.217.116.153])
	by mx-i.b-one.net (Postfix) with ESMTP id 8553A8E00
	for <info@awaresystems.be>; Mon, 24 Nov 2008 20:44:39 +0100 (CET)
Received: from duke.maptools.org (duke.maptools.org [127.0.0.1])
	by duke.maptools.org (8.12.11/8.12.10) with ESMTP id mAOJemlZ008173;
	Mon, 24 Nov 2008 14:42:34 -0500
Received: from mail-svr1.cs.utah.edu (mail-svr1.cs.utah.edu [155.98.64.241])
	by duke.maptools.org (8.12.11/8.12.10) with ESMTP id mAOJejF0008169
	for <tiff@lists.maptools.org>; Mon, 24 Nov 2008 14:40:45 -0500
Received: from localhost (localhost [127.0.0.1])
	by mail-svr1.cs.utah.edu (Postfix) with ESMTP id 8755D6500B7
	for <tiff@lists.maptools.org>; Mon, 24 Nov 2008 12:40:43 -0700 (MST)
Received: from mail-svr1.cs.utah.edu ([127.0.0.1])
	by localhost (mail-svr1.cs.utah.edu [127.0.0.1]) (amavisd-new,
	port 10024) with ESMTP id bdkkJPMTuYQF for <tiff@lists.maptools.org>;
	Mon, 24 Nov 2008 12:40:43 -0700 (MST)
Received: from [192.168.1.101] (c-67-166-125-84.hsd1.ut.comcast.net
	[67.166.125.84])
	by smtps.cs.utah.edu (Postfix) with ESMTPSA id C4EA96500AF
	for <tiff@lists.maptools.org>; Mon, 24 Nov 2008 12:40:42 -0700 (MST)
Message-ID: <492B0339.5080704@cs.utah.edu>
Date: Mon, 24 Nov 2008 12:40:41 -0700
From: William B Thompson <thompson@cs.utah.edu>
User-Agent: Thunderbird 2.0.0.17 (X11/20080922)
MIME-Version: 1.0
To: tiff@lists.maptools.org
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Subject: [Tiff] TIFFWriteScanline corrupts buffer when compression with
 predication is enabled
X-BeenThere: tiff@lists.maptools.org
X-Mailman-Version: 2.1.4
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>
Sender: tiff-bounces@lists.maptools.org
Errors-To: tiff-bounces@lists.maptools.org

As best as I can tell, TIFFWriteScanline corrupts the input buffer in
the calling program with LZW and deflate (zip) compression when
horizontal prediction is enabled for integer values or floating point
prediction is enable for floating point values.  This occurs with both
libtiff 3.8.2 and 4.0.0beta2.  A test program for the 8 bit integer case
is included at the end of this message.

The declaration of TIFFWriteScanline does not include the "const"
qualifier for the buffer argument, so modifying values in the buffer is
not, strictly speaking, in violation of the specification.  It seems to
me, however, that it is bad practice.  It is certainly bad practice when
not described in the man page for TIFFWriteScanline.

One might argue that it is rare to rewrite or otherwise reuse an output
buffer that has just been written to a file.  I can testify from
personal experience that it might be rare, but it does occur (and is a
pain to track down when it happens).

	- Bill

/*
 * Run with and without -p flag.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <tiffio.h>

#define OUTPUT_NAME     "libtiff-prediction-test.tif"

int
main ( int argc, char *argv[] )
{
    TIFF        *output;
    uint8       *output_buffer;
    int         i;
    int         prediction_flag = 0;

    if ( ( argc == 2 ) && ( strcmp ( argv[1], "-p" ) == 0 ) ) {
        prediction_flag = 1;
    }

    output_buffer = (uint8 *) _TIFFmalloc ( 10 * sizeof ( uint8 ) );
    for ( i = 0; i < 10; i++ ) {
        output_buffer[i] = 10;
    }

    output = TIFFOpen ( OUTPUT_NAME , "w" );
    TIFFSetField ( output, TIFFTAG_IMAGEWIDTH, 10 );
    TIFFSetField ( output, TIFFTAG_IMAGELENGTH, 1 );
    TIFFSetField ( output, TIFFTAG_BITSPERSAMPLE, 8 );
    TIFFSetField ( output, TIFFTAG_SAMPLESPERPIXEL, 1 );
    TIFFSetField ( output, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
    if ( prediction_flag ) {
        printf ( "using horizontal prediction\n" );
        TIFFSetField ( output, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL );
    } else {
        printf ( "not using horizontal prediction\n" );
    }
    TIFFSetField ( output, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
    TIFFSetField ( output, TIFFTAG_ROWSPERSTRIP,
            TIFFDefaultStripSize ( output, 0 ) );
    TIFFSetField ( output, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
    TIFFSetField ( output, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK );

    printf ( "output buffer before call to TIFFWriteScanline:\n" );
    for ( i = 0; i < 10; i++ ) {
        printf ( "%4d", output_buffer[i] );
    }
    printf ( "\n" );

    TIFFWriteScanline ( output, output_buffer, 0, 0 );

    printf ( "output buffer after call to TIFFWriteScanline:\n" );
    for ( i = 0; i < 10; i++ ) {
        printf ( "%4d", output_buffer[i] );
    }
    printf ( "\n" );

    TIFFClose ( output );

    return ( EXIT_SUCCESS );    /* normal exit */
}
_______________________________________________
Tiff mailing list: Tiff@lists.maptools.org
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
