18e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
28e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener// Copyright 2006-2008 Adobe Systems Incorporated
38e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener// All Rights Reserved.
48e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener//
58e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener// NOTICE:  Adobe permits you to use, modify, and distribute this file in
68e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener// accordance with the terms of the Adobe license agreement accompanying it.
78e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
88e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
98e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_iptc.cpp#1 $ */
108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/* $DateTime: 2012/05/30 13:28:51 $ */
118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/* $Change: 832332 $ */
128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/* $Author: tknoll $ */
138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_iptc.h"
178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_assertions.h"
198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_auto_ptr.h"
208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_memory_stream.h"
218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_stream.h"
228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener#include "dng_utils.h"
238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
268e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerdng_iptc::dng_iptc ()
278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	:	fTitle ()
298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fUrgency (-1)
318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fCategory ()
338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fSupplementalCategories ()
358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fKeywords ()
378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fInstructions ()
398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fDateTimeCreated ()
418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fDigitalCreationDateTime ()
438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fAuthors         ()
458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fAuthorsPosition ()
468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fCity        ()
488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fState       ()
498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fCountry     ()
508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fCountryCode ()
518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fLocation ()
538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fTransmissionReference ()
558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fHeadline ()
578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fCredit ()
598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fSource ()
618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fCopyrightNotice ()
638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fDescription       ()
658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	,	fDescriptionWriter ()
668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
738e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerdng_iptc::~dng_iptc ()
748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
808e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerbool dng_iptc::IsEmpty () const
818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fTitle.NotEmpty ())
848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fUrgency >= 0)
898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fCategory.NotEmpty ())
948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fSupplementalCategories.Count () > 0)
998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fKeywords.Count () > 0)
1048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fInstructions.NotEmpty ())
1098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fDateTimeCreated.IsValid ())
1148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fDigitalCreationDateTime.IsValid ())
1198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fAuthors.Count () != 0 ||
1248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fAuthorsPosition.NotEmpty ())
1258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fCity   .NotEmpty () ||
1308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fState  .NotEmpty () ||
1318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fCountry.NotEmpty ())
1328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fCountryCode.NotEmpty ())
1378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fLocation.NotEmpty ())
1428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fTransmissionReference.NotEmpty ())
1478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fHeadline.NotEmpty ())
1528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fCredit.NotEmpty ())
1578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fSource.NotEmpty ())
1628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fCopyrightNotice.NotEmpty ())
1678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fDescription      .NotEmpty () ||
1728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		fDescriptionWriter.NotEmpty ())
1738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
1748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return false;
1758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
1768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	return true;
1788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
1808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
1828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1838e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienervoid dng_iptc::ParseString (dng_stream &stream,
1848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						    dng_string &s,
1858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						    CharSet charSet)
1868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
1878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint32 length = stream.Get_uint16 ();
1898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_memory_data buffer (length + 1);
1918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	char *c = buffer.Buffer_char ();
1938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Get (c, length);
1958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	c [length] = 0;
1978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
1988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	switch (charSet)
1998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
2008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		case kCharSetUTF8:
2028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
2038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			s.Set_UTF8 (c);
2048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			break;
2058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
2068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		default:
2088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
2098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			s.Set_SystemEncoding (c);
2108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
2118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
2138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	s.SetLineEndingsToNewLines ();
2158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	s.StripLowASCII ();
2178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	s.TrimTrailingBlanks ();
2198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
2218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
2238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2248e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienervoid dng_iptc::Parse (const void *blockData,
2258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					  uint32 blockSize,
2268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					  uint64 offsetInOriginalFile)
2278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
2288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_stream stream (blockData,
2308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					   blockSize,
2318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					   offsetInOriginalFile);
2328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.SetBigEndian ();
2348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	// Make a first pass though the data, trying to figure out the
2368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	// character set.
2378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	CharSet charSet = kCharSetUnknown;
2398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	bool isValidUTF8 = true;
2418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	bool hasEncodingMarker = false;
2438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint64 firstOffset = stream.Position ();
2458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint64 nextOffset = firstOffset;
2478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	while (nextOffset + 5 < stream.Length ())
2498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
2508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.SetReadPosition (nextOffset);
2528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint8 firstByte = stream.Get_uint8 ();
2548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (firstByte != 0x1C) break;
2568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint8  record   = stream.Get_uint8  ();
2588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint8  dataSet  = stream.Get_uint8  ();
2598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 dataSize = stream.Get_uint16 ();
2608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		nextOffset = stream.Position () + dataSize;
2628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (record == 1)
2648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
2658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			switch (dataSet)
2678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				{
2688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case 90:
2708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
2718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					hasEncodingMarker = true;
2738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (dataSize == 3)
2758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
2768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						uint32 byte1 = stream.Get_uint8 ();
2788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						uint32 byte2 = stream.Get_uint8 ();
2798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						uint32 byte3 = stream.Get_uint8 ();
2808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						if (byte1 == 27 /* Escape */ &&
2828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							byte2 == 0x25 &&
2838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							byte3 == 0x47)
2848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							{
2858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							charSet = kCharSetUTF8;
2878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							}
2898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
2918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
2938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
2958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				default:
2978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
2988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
2998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				}
3008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
3028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		else if (record == 2)
3048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
3058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			dng_memory_data buffer (dataSize + 1);
3078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			char *s = buffer.Buffer_char ();
3098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Get (s, dataSize);
3118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			s [dataSize] = 0;
3138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			isValidUTF8 = isValidUTF8 && dng_string::IsUTF8 (s);
3158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
3178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
3198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	// If we don't have an encoding marker, and the data is valid
3218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	// UTF-8, then assume that it is UTF-8 (rather than system encoding).
3228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (!hasEncodingMarker && isValidUTF8)
3248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
3258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		charSet = kCharSetUTF8;
3278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
3298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	// Make a second pass though the data, actually reading the data.
3318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	nextOffset = firstOffset;
3338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	while (nextOffset + 5 < stream.Length ())
3358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
3368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.SetReadPosition (nextOffset);
3388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint8 firstByte = stream.Get_uint8 ();
3408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (firstByte != 0x1C) break;
3428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint8  record   = stream.Get_uint8  ();
3448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint8  dataSet  = stream.Get_uint8  ();
3458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 dataSize = stream.Get_uint16 ();
3468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		nextOffset = stream.Position () + dataSize;
3488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (record == 2)
3508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
3518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.SetReadPosition (stream.Position () - 2);
3538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			switch ((DataSet) dataSet)
3558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				{
3568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kObjectNameSet:
3588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
3598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fTitle, charSet);
3608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
3618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
3628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kUrgencySet:
3648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
3658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					int32 size = stream.Get_uint16 ();
3678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (size == 1)
3698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
3708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						char c = stream.Get_int8 ();
3728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						if (c >= '0' && c <= '9')
3748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							{
3758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							fUrgency = c - '0';
3768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							}
3778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
3798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
3818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
3838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kCategorySet:
3858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
3868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fCategory, charSet);
3878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
3888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
3898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kSupplementalCategoriesSet:
3918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
3928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					dng_string category;
3948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, category, charSet);
3968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
3978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (category.NotEmpty ())
3988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
3998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fSupplementalCategories.Append (category);
4008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
4018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
4038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
4058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kKeywordsSet:
4078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
4088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					dng_string keyword;
4108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, keyword, charSet);
4128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (keyword.NotEmpty ())
4148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
4158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fKeywords.Append (keyword);
4168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
4178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
4198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
4218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kSpecialInstructionsSet:
4238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
4248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fInstructions, charSet);
4258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
4268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
4278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kDateCreatedSet:
4298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
4308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					uint32 length = stream.Get_uint16 ();
4328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (length == 8)
4348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
4358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						char date [9];
4378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						stream.Get (date, 8);
4398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						date [8] = 0;
4418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fDateTimeCreated.Decode_IPTC_Date (date);
4438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
4458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
4478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
4498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kTimeCreatedSet:
4518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
4528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					uint32 length = stream.Get_uint16 ();
4548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (length >= 4 && length <= 11)
4568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
4578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						char time [12];
4598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						stream.Get (time, length);
4618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						time [length] = 0;
4638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fDateTimeCreated.Decode_IPTC_Time (time);
4658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
4678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
4698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
4718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kDigitalCreationDateSet:
4738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
4748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					uint32 length = stream.Get_uint16 ();
4768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (length == 8)
4788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
4798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						char date [9];
4818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						stream.Get (date, 8);
4838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						date [8] = 0;
4858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fDigitalCreationDateTime.Decode_IPTC_Date (date);
4878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
4898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
4918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
4938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kDigitalCreationTimeSet:
4958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
4968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					uint32 length = stream.Get_uint16 ();
4988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
4998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (length >= 4 && length <= 11)
5008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
5018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						char time [12];
5038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						stream.Get (time, length);
5058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						time [length] = 0;
5078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fDigitalCreationDateTime.Decode_IPTC_Time (time);
5098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
5118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kBylineSet:
5178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					dng_string author;
5208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, author, charSet);
5228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					if (author.NotEmpty ())
5248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						{
5258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						fAuthors.Append (author);
5268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener						}
5278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kBylineTitleSet:
5338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fAuthorsPosition, charSet);
5358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kCitySet:
5398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fCity, charSet);
5418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kProvinceStateSet:
5458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fState, charSet);
5478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kCountryNameSet:
5518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fCountry, charSet);
5538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kCountryCodeSet:
5578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fCountryCode, charSet);
5598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kSublocationSet:
5638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fLocation, charSet);
5658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kOriginalTransmissionReferenceSet:
5698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fTransmissionReference, charSet);
5718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kHeadlineSet:
5758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fHeadline, charSet);
5778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kCreditSet:
5818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fCredit, charSet);
5838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kSourceSet:
5878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fSource, charSet);
5898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kCopyrightNoticeSet:
5938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
5948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fCopyrightNotice, charSet);
5958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
5968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
5978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
5988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kCaptionSet:
5998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
6008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fDescription, charSet);
6018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
6028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
6038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				case kCaptionWriterSet:
6058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
6068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					ParseString (stream, fDescriptionWriter, charSet);
6078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
6088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
6098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				// All other IPTC records are not part of the IPTC core
6118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				// and/or are not kept in sync with XMP tags, so we ignore
6128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				// them.
6138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				default:
6158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					break;
6168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				}
6188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
6208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
6228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
6248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
6268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6278e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienervoid dng_iptc::SpoolString (dng_stream &stream,
6288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							const dng_string &s,
6298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							uint8 dataSet,
6308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							uint32 maxChars,
6318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener							CharSet charSet)
6328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
6338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (s.IsEmpty ())
6358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
6368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		return;
6378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
6388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint16 (0x1C02);
6408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint8  (dataSet);
6418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_string ss (s);
6438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	ss.SetLineEndingsToReturns ();
6458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (charSet == kCharSetUTF8)
6478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
6488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		// UTF-8 encoding.
6508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (ss.Length () > maxChars)
6528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
6538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			ss.Truncate (maxChars);
6548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
6558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 len = ss.Length ();
6578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint16 ((uint16) len);
6598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put (ss.Get (), len);
6618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
6638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	else
6658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
6668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		// System character set encoding.
6688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		dng_memory_data buffer;
6708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		uint32 len = ss.Get_SystemEncoding (buffer);
6728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (len > maxChars)
6748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
6758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			uint32 lower = 0;
6778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			uint32 upper = ss.Length () - 1;
6788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			while (upper > lower)
6808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				{
6818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				uint32 middle = (upper + lower + 1) >> 1;
6838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				dng_string sss (ss);
6858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				sss.Truncate (middle);
6878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				len = sss.Get_SystemEncoding (buffer);
6898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				if (len <= maxChars)
6918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
6928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					lower = middle;
6948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
6968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
6978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				else
6988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					{
6998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					upper = middle - 1;
7018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					}
7038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				}
7058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			ss.Truncate (lower);
7078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			len = ss.Get_SystemEncoding (buffer);
7098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
7118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint16 ((uint16) len);
7138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put (buffer.Buffer_char (), len);
7158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
7178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
7198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
7208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7218e8939fc10ad63576a2785ba1333a23726b7e164Florian Krienerdng_memory_block * dng_iptc::Spool (dng_memory_allocator &allocator,
7228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener									bool padForTIFF)
7238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	{
7248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	uint32 j;
7268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	char s [64];
7288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	dng_memory_stream stream (allocator, NULL, 2048);
7308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.SetBigEndian ();
7328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	// Medata working group - now we just always write UTF-8.
7348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	CharSet charSet = kCharSetUTF8;
7368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	// UTF-8 encoding marker.
7388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (charSet == kCharSetUTF8)
7408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
7418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint16 (0x1C01);
7438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint8  (90);
7448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint16 (3);
7458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint8  (27);
7468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint8  (0x25);
7478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint8  (0x47);
7488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
7508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint16 (0x1C02);
7528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint8  (kRecordVersionSet);
7538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint16 (2);
7548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Put_uint16 (4);
7558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
7578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fTitle,
7588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kObjectNameSet,
7598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 64,
7608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
7618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fUrgency >= 0)
7638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
7648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		sprintf (s, "%1u", (unsigned) fUrgency);
7668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint16 (0x1C02);
7688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint8  (kUrgencySet);
7698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put_uint16 (1);
7718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		stream.Put (s, 1);
7738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
7758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
7778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fCategory,
7788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kCategorySet,
7798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 3,
7808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
7818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	for (j = 0; j < fSupplementalCategories.Count (); j++)
7838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
7848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		SpoolString (stream,
7868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 	 fSupplementalCategories [j],
7878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				     kSupplementalCategoriesSet,
7888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				     32,
7898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					 charSet);
7908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
7928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	for (j = 0; j < fKeywords.Count (); j++)
7948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
7958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
7968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		SpoolString (stream,
7978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 	 fKeywords [j],
7988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				     kKeywordsSet,
7998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				     64,
8008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					 charSet);
8018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
8038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
8058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fInstructions,
8068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kSpecialInstructionsSet,
8078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 255,
8088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
8098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fDateTimeCreated.IsValid ())
8118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
8128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		dng_string dateString = fDateTimeCreated.Encode_IPTC_Date ();
8148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (dateString.NotEmpty ())
8168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
8178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			DNG_ASSERT (dateString.Length () == 8, "Wrong length IPTC date");
8198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint16 (0x1C02);
8218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint8  (kDateCreatedSet);
8228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint16 (8);
8248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put (dateString.Get (), 8);
8268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
8288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		dng_string timeString = fDateTimeCreated.Encode_IPTC_Time ();
8308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (timeString.NotEmpty ())
8328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
8338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint16 (0x1C02);
8358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint8  (kTimeCreatedSet);
8368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint16 ((uint16)timeString.Length ());
8388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put (timeString.Get (), timeString.Length ());
8408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
8428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
8448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (fDigitalCreationDateTime.IsValid ())
8468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
8478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		dng_string dateString = fDigitalCreationDateTime.Encode_IPTC_Date ();
8498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (dateString.NotEmpty ())
8518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
8528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			DNG_ASSERT (dateString.Length () == 8, "Wrong length IPTC date");
8548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint16 (0x1C02);
8568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint8  (kDigitalCreationDateSet);
8578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint16 (8);
8598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put (dateString.Get (), 8);
8618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
8638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		dng_string timeString = fDigitalCreationDateTime.Encode_IPTC_Time ();
8658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		if (timeString.NotEmpty ())
8678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
8688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint16 (0x1C02);
8708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint8  (kDigitalCreationTimeSet);
8718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint16 ((uint16)timeString.Length ());
8738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put (timeString.Get (), timeString.Length ());
8758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
8778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
8798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	for (j = 0; j < fAuthors.Count (); j++)
8818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
8828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		SpoolString (stream,
8848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					 fAuthors [j],
8858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					 kBylineSet,
8868e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					 32,
8878e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener					 charSet);
8888e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8898e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
8908e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8918e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
8928e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fAuthorsPosition,
8938e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kBylineTitleSet,
8948e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 32,
8958e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
8968e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
8978e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
8988e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fCity,
8998e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kCitySet,
9008e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 32,
9018e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9028e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9038e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9048e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fLocation,
9058e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kSublocationSet,
9068e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 32,
9078e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9088e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9098e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9108e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fState,
9118e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kProvinceStateSet,
9128e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 32,
9138e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9148e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9158e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9168e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fCountryCode,
9178e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kCountryCodeSet,
9188e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 3,
9198e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9208e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9218e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9228e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fCountry,
9238e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kCountryNameSet,
9248e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 64,
9258e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9268e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9278e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9288e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fTransmissionReference,
9298e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kOriginalTransmissionReferenceSet,
9308e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 32,
9318e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9328e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9338e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9348e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fHeadline,
9358e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kHeadlineSet,
9368e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 255,
9378e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9388e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9398e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9408e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fCredit,
9418e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kCreditSet,
9428e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 32,
9438e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9448e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9458e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9468e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fSource,
9478e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kSourceSet,
9488e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 32,
9498e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9508e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9518e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9528e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fCopyrightNotice,
9538e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kCopyrightNoticeSet,
9548e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 128,
9558e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9568e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9578e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9588e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fDescription,
9598e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kCaptionSet,
9608e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 2000,
9618e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9628e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9638e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	SpoolString (stream,
9648e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 fDescriptionWriter,
9658e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 kCaptionWriterSet,
9668e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 32,
9678e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener				 charSet);
9688e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9698e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	if (padForTIFF)
9708e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		{
9718e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9728e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		while (stream.Length () & 3)
9738e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			{
9748e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			stream.Put_uint8 (0);
9758e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener			}
9768e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9778e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener		}
9788e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9798e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	stream.Flush ();
9808e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9818e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	return stream.AsMemoryBlock (allocator);
9828e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9838e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener	}
9848e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener
9858e8939fc10ad63576a2785ba1333a23726b7e164Florian Kriener/*****************************************************************************/
986