Return-Path: <awaresystems.be+caf_=filtered=awaresystems.be@gmail.com>
Delivered-To: filtered@awaresystems.be
Received: from mx-g.one.com (mx-g.one.com [91.198.169.54])
	by mail6.local (Postfix) with ESMTP id 14DF53001C1261
	for <filtered@awaresystems.be>; Mon,  9 Jun 2014 11:40:31 +0000 (UTC)
X-Virus-Scanned: by one.com
Received-SPF: pass (mx-g: domain of awaresystems.be+caf_=filtered=awaresystems.be@gmail.com designates 209.85.215.42 as permitted sender)
X-Greylist: whitelisted by SQLgrey-1.8.0-rc2
Received: from mail-la0-f42.google.com (mail-la0-f42.google.com [209.85.215.42])
	by mx-g.one.com (Postfix) with ESMTP id C2CCF3EC938
	for <filtered@awaresystems.be>; Mon,  9 Jun 2014 11:40:30 +0000 (UTC)
Received: by mail-la0-f42.google.com with SMTP id el20so3017782lab.1
        for <filtered@awaresystems.be>; Mon, 09 Jun 2014 04:40:30 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-original-authentication-results:delivered-to:delivered-to:from:to
         :thread-topic:thread-index:date:message-id:references:in-reply-to
         :accept-language:content-language:content-id:mime-version:subject
         :precedence:list-id:list-unsubscribe:list-archive:list-post
         :list-help:list-subscribe:content-type:content-transfer-encoding
         :sender:errors-to;
        bh=4sVBE+qSR34/weqRby++gWb0Q3WlS8EZHHs1cY+ePhc=;
        b=jQxmWbelVUOZD+OhBOhYHoQwCe9YlxDYoPJ6hGxp74KNep4PWtxgMKawEMoeHV3Ylk
         QPoGvQNg3D5Y5vJU/5wnMQmSGmnJIs3EwIGtDzg+56PDd1okZ+xnWj3r83yaunMDk6e7
         qbHkdZofyq/dNvu0nIwm8OBHJv6Ayce8jBC5//lJU8QU+BBCplXLbXcMVzFDC53aBn49
         w2bwamzEZ+EBoRymzw9r9Cl9/T1fcREMjWd/5iHiWiM5kD9eH3DacReWXZqQJqvPltoy
         9pwus1zAi9cdYDqfAiKweG5DUZxAmMkDvo+cHaJXdM7sOPQyLlMUtG+RHlTUo2bMwNVA
         1wyw==
X-Original-Authentication-Results: mx.google.com;       spf=neutral (google.com: tiff-bounces@lists.maptools.org does not designate permitted sender hosts) smtp.mail=tiff-bounces@lists.maptools.org
X-Received: by 10.112.198.102 with SMTP id jb6mr16303011lbc.18.1402314030331;
        Mon, 09 Jun 2014 04:40:30 -0700 (PDT)
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.114.18.137 with SMTP id w9csp14035ldd;
        Mon, 9 Jun 2014 04:40:29 -0700 (PDT)
X-Received: by 10.152.10.168 with SMTP id j8mr17373661lab.37.1402314029590;
        Mon, 09 Jun 2014 04:40:29 -0700 (PDT)
Authentication-Results: mx.google.com;
       spf=neutral (google.com: tiff-bounces@lists.maptools.org does not designate permitted sender hosts) smtp.mail=tiff-bounces@lists.maptools.org
Received-SPF: none (google.com: tiff-bounces@lists.maptools.org does not designate permitted sender hosts) client-ip=91.198.169.51;
Received: by 10.112.18.7 with POP3 id s7mf2570747lbd.9;
        Mon, 09 Jun 2014 04:40:29 -0700 (PDT)
X-Gmail-Fetch-Info: info@awaresystems.be 1 pop.awaresystems.be 110 info@awaresystems.be
Delivered-To: info@awaresystems.be
Received: from mx-d.one.com (mx-d.one.com [91.198.169.51])
	by mail6.local (Postfix) with ESMTP id 8A857300199241
	for <info@awaresystems.be>; Mon,  9 Jun 2014 11:36:30 +0000 (UTC)
X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0-rc2
Received: from lists.maptools.org (ks365428.kimsufi.com [94.23.4.142])
	by mx-d.one.com (Postfix) with ESMTP id 483C5808A42
	for <info@awaresystems.be>; Mon,  9 Jun 2014 11:36:30 +0000 (UTC)
Received: from [10.1.0.241] (localhost.localdomain [127.0.0.1])
	by lists.maptools.org (Postfix) with ESMTP id ECFF935C048;
	Mon,  9 Jun 2014 06:35:21 -0500 (EST)
Received: from emea01-db3-obe.outbound.protection.outlook.com
	(mail-db3lp0080.outbound.protection.outlook.com [213.199.154.80])
	by lists.maptools.org (Postfix) with ESMTPS id CD06C35C048
	for <tiff@lists.maptools.org>; Mon,  9 Jun 2014 06:32:56 -0500 (EST)
Received: from DB3PR06MB092.eurprd06.prod.outlook.com (10.141.1.27) by
	DB3PR06MB091.eurprd06.prod.outlook.com (10.141.1.24) with Microsoft
	SMTP Server (TLS) id 15.0.959.24; Mon, 9 Jun 2014 11:32:56 +0000
Received: from DB3PR06MB092.eurprd06.prod.outlook.com ([169.254.4.25]) by
	DB3PR06MB092.eurprd06.prod.outlook.com ([169.254.4.25]) with mapi id
	15.00.0954.000; Mon, 9 Jun 2014 11:32:56 +0000
From: Stephen Morris <s-morris@n-eos.com>
To: "tiff@lists.maptools.org" <tiff@lists.maptools.org>
Thread-Topic: [Tiff] What's wrong with my code for adding custom tags to a file
Thread-Index: AQHPgLG4n3B3tVLDTkqfNRJXO5POWptiqg4AgAFVbwCAAS76AIACUYqAgAEic4CAABoGgA==
Date: Mon, 9 Jun 2014 11:32:55 +0000
Message-ID: <CFBB5640.1A690%s-morris@n-eos.com>
References: <CFB6138E.1A4BC%stephen@morris.net>
	<413F4632-74AC-4FB4-AEA7-D1A82DA31FB7@cs.cmu.edu>
	<CFB75D41.1A522%s-morris@n-eos.com>
	<18E06A74-F857-4627-9DF8-1872721A92EC@cs.cmu.edu>
	<1DAE1065-1AC7-48C3-95FA-4C371573E26F@cs.cmu.edu>
	<CFBB41F5.1A652%s-morris@n-eos.com>
In-Reply-To: <CFBB41F5.1A652%s-morris@n-eos.com>
Accept-Language: en-GB, en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
x-originating-ip: [89.168.13.228]
x-microsoft-antispam: BCL:0;PCL:0;RULEID:
x-forefront-prvs: 02379661A3
x-forefront-antispam-report: SFV:NSPM;
	SFS:(6009001)(428001)(199002)(189002)(243025005)(2656002)(86362001)(77982001)(101416001)(19580395003)(83322001)(54356999)(92726001)(50986999)(15975445006)(20776003)(64706001)(76176999)(92566001)(87936001)(93886002)(81342001)(79102001)(81542001)(36756003)(15202345003)(21056001)(66066001)(83072002)(74662001)(99396002)(85852003)(46102001)(4396001)(31966008);
	DIR:OUT; SFP:; SCL:1; SRVR:DB3PR06MB091;
	H:DB3PR06MB092.eurprd06.prod.outlook.com; FPR:; MLV:sfv;
	PTR:InfoNoRecords; A:1; MX:1; LANG:en; 
received-spf: None (: n-eos.com does not designate permitted sender hosts)
authentication-results: spf=none (sender IP is )
	smtp.mailfrom=s-morris@n-eos.com; 
Content-ID: <534F5F989A7B3048B33F417E79AADFF6@eurprd06.prod.outlook.com>
MIME-Version: 1.0
X-OriginatorOrg: n-eos.com
Subject: Re: [Tiff] What's wrong with my code for adding custom tags to a
	file
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: text/plain; charset="windows-1252"
Content-Transfer-Encoding: quoted-printable
Sender: tiff-bounces@lists.maptools.org
Errors-To: tiff-bounces@lists.maptools.org

Here as promised is my ultimately successful testing code.

It turned out that there were two keys to getting it to work:
(1)	Defining the TIFFFieldInfo fields correctly as Paul Heckbert pointed
out, which is different from the example given in the documentation.
(2)	Using the =B3extender=B2 pattern for encapsulating the call to
TIFFMergeFieldInfo, but doing this *before* opening the file. If I left
the call until after opening the file, then when reading a file with
custom tags the =B3Warning, unknown field=B2 messages would be issued
immediately on opening the file.

Here is the code. As in my original posting, this is a complete listing
apart from my separate =8CPGM=B9 module which just reads in an image from a
.pgm file. My test code then proceeds to re-save this file as a TIFF
containing various custom tags; and then to clear the tag values and
re-read the file, verifying that the tag values stored in the file can
also be correctly read back from it:

=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B=8B

#include "stdafx.h"
#include "PGM.h"
#include "tiffio.h"

// There are a number of TIFF-related definitions we need to make in order
to support the custom tags
// that we want to include in our files. The form of these definitions and
subroutines comes straight
// out of the libtiff documentation, and the values of the custom tags
themselves come from the
// range (65000-75535) defined in the TIFF specification as "reusable" and
suitable for private use
// within organisations. See
http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
#define N(a) (sizeof(a) / sizeof (a[0]))
#define TIFFTAG_INCIDENTPOWER     65000
#define TIFFTAG_REFLECTEDPOWER    65001
#define TIFFTAG_T1                65002
#define TIFFTAG_T2                65003
#define TIFFTAG_HUMIDITY          65004
#define TIFFTAG_EXPOSURE          65005

static const TIFFFieldInfo xtiffFieldInfo[] =3D {
    { TIFFTAG_INCIDENTPOWER,  1, 1, TIFF_LONG,  FIELD_CUSTOM, 0, 0,
const_cast<char*>("LaserIncidentPower") },
    { TIFFTAG_REFLECTEDPOWER, 1, 1, TIFF_LONG,  FIELD_CUSTOM, 0, 0,
const_cast<char*>("LaserReflectedPower") },
    { TIFFTAG_T1,             1, 1, TIFF_FLOAT, FIELD_CUSTOM, 0, 0,
const_cast<char*>("Temperature_1") },
    { TIFFTAG_T2,             1, 1, TIFF_FLOAT, FIELD_CUSTOM, 0, 0,
const_cast<char*>("Temperature_2") },
    { TIFFTAG_HUMIDITY,       1, 1, TIFF_FLOAT, FIELD_CUSTOM, 0, 0,
const_cast<char*>("Humidity") },
    { TIFFTAG_EXPOSURE,       1, 1, TIFF_FLOAT, FIELD_CUSTOM, 0, 0,
const_cast<char*>("ExposureTime(ms)") }
};                                                                  // The
casts are necessary because the
                                                                    //
string literals are inherently const,
                                                                    // but
the definition of TIFFFieldInfo
                                                                    //
requires a non-const string pointer.
                                                                    // The
Intel and Microsoft compilers
                                                                    //
tolerate this, but gcc doesn't.

static TIFFExtendProc parent_extender =3D NULL;  // In case we want a chain
of extensions

static void registerCustomTIFFTags(TIFF *tif)
{
    /* Install the extended Tag field info */
    int error =3D TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo)=
);

    if (parent_extender)
        (*parent_extender)(tif);
}

static void augment_libtiff_with_custom_tags() {
    Static bool first_time =3D true;
    if (!first_time) return;
    first_time =3D false;
    parent_extender =3D TIFFSetTagExtender(registerCustomTIFFTags);
}

void saveAsTiff(int nx, int ny, unsigned short *image, const char*
filename,
                int Power1, int Power2, float T1, float T2, float
Humidity, float Exposure)
{
    // Create the TIFF directory object:
    augment_libtiff_with_custom_tags();
    TIFF* tif =3D TIFFOpen(filename, "w");

    // Set the tags: first the standard ones...
    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, nx);
    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ny);
    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
    TIFFSetField(tif, TIFFTAG_ZIPQUALITY, 6); // Takes maximum advantage
of Intel ZLIB enhancements
    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
    TIFFSetField(tif, TIFFTAG_ORIENTATION,
static_cast<int>(ORIENTATION_TOPLEFT));
    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, ny);
    // Saving the whole image in a single block makes heavy
    // demands on memory but should enable optimum compression
    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

    // ... and now our own custom ones:
    TIFFSetField(tif, TIFFTAG_INCIDENTPOWER, Power1);
    TIFFSetField(tif, TIFFTAG_REFLECTEDPOWER, Power2);
    TIFFSetField(tif, TIFFTAG_T1, T1);
    TIFFSetField(tif, TIFFTAG_T2, T2);
    TIFFSetField(tif, TIFFTAG_HUMIDITY, Humidity);
    TIFFSetField(tif, TIFFTAG_EXPOSURE, Exposure);

    TIFFWriteEncodedStrip(tif, 0, static_cast<void *>(image), nx * ny *
2); =

                                                              // The '* 2'
is present because each pixel
                                                              // has 16
bits, hence two bytes
     // Write the directory to a file, and close it:
     TIFFWriteDirectory(tif);
     TIFFClose(tif);
}

void readFromTiff(int *nx, int *ny, unsigned short **image, const char*
filename,
                  int *Power1, int *Power2, float *T1, float *T2, float
*Humidity, float *Exposure)
{
    // Create the TIFF directory object:
    augment_libtiff_with_custom_tags();
    TIFF* tif =3D TIFFOpen(filename, "r");
    if (NULL =3D=3D tif)
    {
        *nx =3D -1;
        *ny =3D -1;
        return;
    }

    // Read in the image size and metadata:
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, nx);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, ny);
    TIFFGetField(tif, TIFFTAG_INCIDENTPOWER, Power1);
    TIFFGetField(tif, TIFFTAG_REFLECTEDPOWER, Power2);
    TIFFGetField(tif, TIFFTAG_T1, T1);
    TIFFGetField(tif, TIFFTAG_T2, T2);
    TIFFGetField(tif, TIFFTAG_HUMIDITY, Humidity);
    TIFFGetField(tif, TIFFTAG_EXPOSURE, Exposure);

    // Dimension the buffer, and read in the image data itself:
    *image =3D new unsigned short[(*nx) * (*ny)];
    TIFFReadEncodedStrip(tif, static_cast<tstrip_t>(0), static_cast<void
*>(*image), static_cast<tsize_t>(-1));
    TIFFClose(tif);
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Variables to hold the image
    int nx, ny;
    unsigned short *image =3D nullptr;

    // Information we'd like to put into our custom tags:
    int Power1 =3D 1000000;
    int Power2 =3D 8;
    float T1 =3D 23.5f;
    float T2 =3D -18.7f;
    float Humidity =3D 0.98f;
    float Exposure =3D 0.001f;

    // Read the test image in from a PGM file:
    readFromPGM(&nx, &ny, &image, "TestImage.pgm");

    // Save the image as a TIF file:
    saveAsTiff(nx, ny, image, "TestImage.tif", Power1, Power2, T1, T2,
Humidity, Exposure);
   =

    // Prepare to read back in: first clear the various fields
    Power1 =3D 0;
    Power2 =3D 0;
    T1 =3D 0.0f;
    T2 =3D 0.0f;
    Humidity =3D 0.0f;
    Exposure =3D 0.0f;
    nx =3D 0;
    ny =3D 0;
    delete [] image;

    // Now read the image back in from the file:
    readFromTiff(&nx, &ny, &image, "TestImage.tif", &Power1, &Power2, &T1,
&T2, &Humidity, &Exposure);

    // Verify the tag values:
    printf("Image size =3D %d, %d\r\n", ny, ny);
    printf("Power1 =3D %d\r\n", Power1);
    printf("Power2 =3D %d\r\n", Power2);
    printf("T1 =3D %6.3f\r\n", T1);
    printf("T2 =3D %6.3f\r\n", T2);
    printf("Humidity =3D %6.3f\r\n", Humidity);
    printf("Exposure =3D %6.3f\r\n", Exposure);
    return 0;
}

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