summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libtiff/libtiff/tif_print.c
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@digia.com>2013-03-04 10:22:52 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-05 11:07:49 +0200
commit8b2b1b0f63d258ec5ea753cd44531731c0bdece8 (patch)
tree2c651bf7ba4d34ff8314d180eec11c7a7c3bbd52 /src/3rdparty/libtiff/libtiff/tif_print.c
parent7a10649ea7b8963d66c14a0391b7356fc7d9ce9d (diff)
Upgrading libtiff: Adding clean copy of libtiff 4.0.3
This commit removes the previous version of the bundled libtiff (3.9.2), as well as all local modifications to it. It adds an unmodified copy of the official libtiff source distribution, except that various extraneous files have been removed, as usual. The patches required to build it in Qt will follow in separate commit(s). Task-number: QTBUG-25409 Change-Id: If47e02c25ce1a2b3b47eff94a875e2abea0c7e1c Reviewed-by: aavit <eirik.aavitsland@digia.com>
Diffstat (limited to 'src/3rdparty/libtiff/libtiff/tif_print.c')
-rw-r--r--src/3rdparty/libtiff/libtiff/tif_print.c377
1 files changed, 227 insertions, 150 deletions
diff --git a/src/3rdparty/libtiff/libtiff/tif_print.c b/src/3rdparty/libtiff/libtiff/tif_print.c
index 871fffd..402666d 100644
--- a/src/3rdparty/libtiff/libtiff/tif_print.c
+++ b/src/3rdparty/libtiff/libtiff/tif_print.c
@@ -1,4 +1,4 @@
-/* $Id: tif_print.c,v 1.36.2.2 2009-09-17 18:00:28 bfriesen Exp $ */
+/* $Id: tif_print.c,v 1.60 2012-08-19 16:56:35 bfriesen Exp $ */
/*
* Copyright (c) 1988-1997 Sam Leffler
@@ -31,9 +31,12 @@
*/
#include "tiffiop.h"
#include <stdio.h>
-#include <string.h>
+
#include <ctype.h>
+static void
+_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars);
+
static const char *photoNames[] = {
"min-is-white", /* PHOTOMETRIC_MINISWHITE */
"min-is-black", /* PHOTOMETRIC_MINISBLACK */
@@ -44,6 +47,8 @@ static const char *photoNames[] = {
"YCbCr", /* PHOTOMETRIC_YCBCR */
"7 (0x7)",
"CIE L*a*b*", /* PHOTOMETRIC_CIELAB */
+ "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */
+ "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */
};
#define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0]))
@@ -61,7 +66,7 @@ static const char *orientNames[] = {
#define NORIENTNAMES (sizeof (orientNames) / sizeof (orientNames[0]))
static void
-_TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip,
+_TIFFPrintField(FILE* fd, const TIFFField *fip,
uint32 value_count, void *raw_data)
{
uint32 j;
@@ -73,7 +78,7 @@ _TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip,
fprintf(fd, "%u", ((uint8 *) raw_data)[j]);
else if(fip->field_type == TIFF_UNDEFINED)
fprintf(fd, "0x%x",
- (unsigned int) ((unsigned char *) raw_data)[j]);
+ (unsigned int) ((unsigned char *) raw_data)[j]);
else if(fip->field_type == TIFF_SBYTE)
fprintf(fd, "%d", ((int8 *) raw_data)[j]);
else if(fip->field_type == TIFF_SHORT)
@@ -82,23 +87,46 @@ _TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip,
fprintf(fd, "%d", ((int16 *) raw_data)[j]);
else if(fip->field_type == TIFF_LONG)
fprintf(fd, "%lu",
- (unsigned long)((uint32 *) raw_data)[j]);
+ (unsigned long)((uint32 *) raw_data)[j]);
else if(fip->field_type == TIFF_SLONG)
fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_IFD)
+ fprintf(fd, "0x%lx",
+ (unsigned long)((uint32 *) raw_data)[j]);
else if(fip->field_type == TIFF_RATIONAL
|| fip->field_type == TIFF_SRATIONAL
|| fip->field_type == TIFF_FLOAT)
fprintf(fd, "%f", ((float *) raw_data)[j]);
- else if(fip->field_type == TIFF_IFD)
- fprintf(fd, "0x%ulx", ((uint32 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_LONG8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, "%I64u",
+ (unsigned __int64)((uint64 *) raw_data)[j]);
+#else
+ fprintf(fd, "%llu",
+ (unsigned long long)((uint64 *) raw_data)[j]);
+#endif
+ else if(fip->field_type == TIFF_SLONG8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]);
+#else
+ fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]);
+#endif
+ else if(fip->field_type == TIFF_IFD8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, "0x%I64x",
+ (unsigned __int64)((uint64 *) raw_data)[j]);
+#else
+ fprintf(fd, "0x%llx",
+ (unsigned long long)((uint64 *) raw_data)[j]);
+#endif
+ else if(fip->field_type == TIFF_FLOAT)
+ fprintf(fd, "%f", ((float *)raw_data)[j]);
+ else if(fip->field_type == TIFF_DOUBLE)
+ fprintf(fd, "%f", ((double *) raw_data)[j]);
else if(fip->field_type == TIFF_ASCII) {
fprintf(fd, "%s", (char *) raw_data);
break;
}
- else if(fip->field_type == TIFF_DOUBLE)
- fprintf(fd, "%f", ((double *) raw_data)[j]);
- else if(fip->field_type == TIFF_FLOAT)
- fprintf(fd, "%f", ((float *)raw_data)[j]);
else {
fprintf(fd, "<unsupported data type in TIFFPrint>");
break;
@@ -112,16 +140,22 @@ _TIFFPrintField(FILE* fd, const TIFFFieldInfo *fip,
}
static int
-_TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
+_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag,
uint32 value_count, void *raw_data)
{
- TIFFDirectory *td = &tif->tif_dir;
+ (void) tif;
+ /* do not try to pretty print auto-defined fields */
+ if (strncmp(fip->field_name,"Tag ", 4) == 0) {
+ return 0;
+ }
+
switch (tag)
{
case TIFFTAG_INKSET:
- fprintf(fd, " Ink Set: ");
- switch (*((uint16*)raw_data)) {
+ if (value_count == 2 && fip->field_type == TIFF_SHORT) {
+ fprintf(fd, " Ink Set: ");
+ switch (*((uint16*)raw_data)) {
case INKSET_CMYK:
fprintf(fd, "CMYK\n");
break;
@@ -130,30 +164,31 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
*((uint16*)raw_data),
*((uint16*)raw_data));
break;
+ }
+ return 1;
}
- return 1;
+ return 0;
+
case TIFFTAG_DOTRANGE:
- fprintf(fd, " Dot Range: %u-%u\n",
- ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
- return 1;
+ if (value_count == 2 && fip->field_type == TIFF_SHORT) {
+ fprintf(fd, " Dot Range: %u-%u\n",
+ ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
+ return 1;
+ }
+ return 0;
+
case TIFFTAG_WHITEPOINT:
- fprintf(fd, " White Point: %g-%g\n",
- ((float *)raw_data)[0], ((float *)raw_data)[1]); return 1;
- case TIFFTAG_REFERENCEBLACKWHITE:
- {
- uint16 i;
+ if (value_count == 2 && fip->field_type == TIFF_RATIONAL) {
+ fprintf(fd, " White Point: %g-%g\n",
+ ((float *)raw_data)[0], ((float *)raw_data)[1]);
+ return 1;
+ }
+ return 0;
- fprintf(fd, " Reference Black/White:\n");
- for (i = 0; i < td->td_samplesperpixel; i++)
- fprintf(fd, " %2d: %5g %5g\n", i,
- ((float *)raw_data)[2*i+0],
- ((float *)raw_data)[2*i+1]);
- return 1;
- }
case TIFFTAG_XMLPACKET:
{
uint32 i;
-
+
fprintf(fd, " XMLPacket (XMP Metadata):\n" );
for(i = 0; i < value_count; i++)
fputc(((char *)raw_data)[i], fd);
@@ -166,23 +201,29 @@ _TIFFPrettyPrintField(TIFF* tif, FILE* fd, ttag_t tag,
* defined as array of LONG values.
*/
fprintf(fd,
- " RichTIFFIPTC Data: <present>, %lu bytes\n",
- (unsigned long) value_count * 4);
+ " RichTIFFIPTC Data: <present>, %lu bytes\n",
+ (unsigned long) value_count * 4);
return 1;
+
case TIFFTAG_PHOTOSHOP:
fprintf(fd, " Photoshop Data: <present>, %lu bytes\n",
- (unsigned long) value_count);
+ (unsigned long) value_count);
return 1;
+
case TIFFTAG_ICCPROFILE:
fprintf(fd, " ICC Profile: <present>, %lu bytes\n",
- (unsigned long) value_count);
+ (unsigned long) value_count);
return 1;
+
case TIFFTAG_STONITS:
- fprintf(fd,
- " Sample to Nits conversion factor: %.4e\n",
- *((double*)raw_data));
- return 1;
- }
+ if (value_count == 1 && fip->field_type == TIFF_DOUBLE) {
+ fprintf(fd,
+ " Sample to Nits conversion factor: %.4e\n",
+ *((double*)raw_data));
+ return 1;
+ }
+ return 0;
+ }
return 0;
}
@@ -199,8 +240,15 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
uint16 i;
long l, n;
- fprintf(fd, "TIFF Directory at offset 0x%lx (%lu)\n",
- (unsigned long)tif->tif_diroff, (unsigned long)tif->tif_diroff);
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n",
+ (unsigned __int64) tif->tif_diroff,
+ (unsigned __int64) tif->tif_diroff);
+#else
+ fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n",
+ (unsigned long long) tif->tif_diroff,
+ (unsigned long long) tif->tif_diroff);
+#endif
if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
fprintf(fd, " Subfile Type:");
sep = " ";
@@ -344,9 +392,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, " Ink Names: ");
i = td->td_samplesperpixel;
sep = "";
- for (cp = td->td_inknames; i > 0; cp = strchr(cp,'\0')+1, i--) {
+ for (cp = td->td_inknames;
+ i > 0 && cp < td->td_inknames + td->td_inknameslen;
+ cp = strchr(cp,'\0')+1, i--) {
+ int max_chars =
+ td->td_inknameslen - (cp - td->td_inknames);
fputs(sep, fd);
- _TIFFprintAscii(fd, cp);
+ _TIFFprintAsciiBounded(fd, cp, max_chars);
sep = ", ";
}
fputs("\n", fd);
@@ -386,18 +438,9 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
}
if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
{
- /*
- * For hacky reasons (see tif_jpeg.c - JPEGFixupTestSubsampling),
- * we need to fetch this rather than trust what is in our
- * structures.
- */
- uint16 subsampling[2];
-
- TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING,
- subsampling + 0, subsampling + 1 );
fprintf(fd, " YCbCr Subsampling: %u, %u\n",
- subsampling[0], subsampling[1] );
- }
+ td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] );
+ }
if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
fprintf(fd, " YCbCr Positioning: ");
switch (td->td_ycbcrpositioning) {
@@ -437,12 +480,20 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
fprintf(fd, " Min Sample Value: %u\n", td->td_minsamplevalue);
if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue);
- if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
- fprintf(fd, " SMin Sample Value: %g\n",
- td->td_sminsamplevalue);
- if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
- fprintf(fd, " SMax Sample Value: %g\n",
- td->td_smaxsamplevalue);
+ if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
+ int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
+ fprintf(fd, " SMin Sample Value:");
+ for (i = 0; i < count; ++i)
+ fprintf(fd, " %g", td->td_sminsamplevalue[i]);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
+ int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
+ fprintf(fd, " SMax Sample Value:");
+ for (i = 0; i < count; ++i)
+ fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
+ fprintf(fd, "\n");
+ }
if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
fprintf(fd, " Planar Configuration: ");
switch (td->td_planarconfig) {
@@ -475,6 +526,13 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
} else
fprintf(fd, "(present)\n");
}
+ if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
+ fprintf(fd, " Reference Black/White:\n");
+ for (i = 0; i < 3; i++)
+ fprintf(fd, " %2d: %5g %5g\n", i,
+ td->td_refblackwhite[2*i+0],
+ td->td_refblackwhite[2*i+1]);
+ }
if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
fprintf(fd, " Transfer Function: ");
if (flags & TIFFPRINT_CURVES) {
@@ -494,124 +552,136 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
fprintf(fd, " SubIFD Offsets:");
for (i = 0; i < td->td_nsubifd; i++)
- fprintf(fd, " %5lu", (long) td->td_subifd[i]);
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, " %5I64u",
+ (unsigned __int64) td->td_subifd[i]);
+#else
+ fprintf(fd, " %5llu",
+ (unsigned long long) td->td_subifd[i]);
+#endif
fputc('\n', fd);
}
- /*
- ** Custom tag support.
- */
- {
- int i;
- short count;
-
- count = (short) TIFFGetTagListCount(tif);
- for(i = 0; i < count; i++) {
- ttag_t tag = TIFFGetTagListEntry(tif, i);
- const TIFFFieldInfo *fip;
- uint32 value_count;
- int mem_alloc = 0;
- void *raw_data;
-
- fip = TIFFFieldWithTag(tif, tag);
- if(fip == NULL)
- continue;
+ /*
+ ** Custom tag support.
+ */
+ {
+ int i;
+ short count;
- if(fip->field_passcount) {
- if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
+ count = (short) TIFFGetTagListCount(tif);
+ for(i = 0; i < count; i++) {
+ uint32 tag = TIFFGetTagListEntry(tif, i);
+ const TIFFField *fip;
+ uint32 value_count;
+ int mem_alloc = 0;
+ void *raw_data;
+
+ fip = TIFFFieldWithTag(tif, tag);
+ if(fip == NULL)
continue;
- } else {
- if (fip->field_readcount == TIFF_VARIABLE
- || fip->field_readcount == TIFF_VARIABLE2)
- value_count = 1;
- else if (fip->field_readcount == TIFF_SPP)
- value_count = td->td_samplesperpixel;
- else
- value_count = fip->field_readcount;
- if ((fip->field_type == TIFF_ASCII
- || fip->field_readcount == TIFF_VARIABLE
- || fip->field_readcount == TIFF_VARIABLE2
- || fip->field_readcount == TIFF_SPP
- || value_count > 1)
- && fip->field_tag != TIFFTAG_PAGENUMBER
- && fip->field_tag != TIFFTAG_HALFTONEHINTS
- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
- && fip->field_tag != TIFFTAG_DOTRANGE) {
- if(TIFFGetField(tif, tag, &raw_data) != 1)
- continue;
- } else if (fip->field_tag != TIFFTAG_PAGENUMBER
- && fip->field_tag != TIFFTAG_HALFTONEHINTS
- && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
- && fip->field_tag != TIFFTAG_DOTRANGE) {
- raw_data = _TIFFmalloc(
- _TIFFDataSize(fip->field_type)
- * value_count);
- mem_alloc = 1;
- if(TIFFGetField(tif, tag, raw_data) != 1) {
- _TIFFfree(raw_data);
+
+ if(fip->field_passcount) {
+ if (fip->field_readcount == TIFF_VARIABLE ) {
+ if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
+ continue;
+ } else if (fip->field_readcount == TIFF_VARIABLE2 ) {
+ uint16 small_value_count;
+ if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
+ continue;
+ value_count = small_value_count;
+ } else {
+ assert (fip->field_readcount == TIFF_VARIABLE
+ || fip->field_readcount == TIFF_VARIABLE2);
continue;
- }
+ }
} else {
- /*
- * XXX: Should be fixed and removed, see the
- * notes related to TIFFTAG_PAGENUMBER,
- * TIFFTAG_HALFTONEHINTS,
- * TIFFTAG_YCBCRSUBSAMPLING and
- * TIFFTAG_DOTRANGE tags in tif_dir.c. */
- char *tmp;
- raw_data = _TIFFmalloc(
- _TIFFDataSize(fip->field_type)
- * value_count);
- tmp = raw_data;
- mem_alloc = 1;
- if(TIFFGetField(tif, tag, tmp,
- tmp + _TIFFDataSize(fip->field_type)) != 1) {
- _TIFFfree(raw_data);
- continue;
+ if (fip->field_readcount == TIFF_VARIABLE
+ || fip->field_readcount == TIFF_VARIABLE2)
+ value_count = 1;
+ else if (fip->field_readcount == TIFF_SPP)
+ value_count = td->td_samplesperpixel;
+ else
+ value_count = fip->field_readcount;
+ if (fip->field_tag == TIFFTAG_DOTRANGE
+ && strcmp(fip->field_name,"DotRange") == 0) {
+ /* TODO: This is an evil exception and should not have been
+ handled this way ... likely best if we move it into
+ the directory structure with an explicit field in
+ libtiff 4.1 and assign it a FIELD_ value */
+ static uint16 dotrange[2];
+ raw_data = dotrange;
+ TIFFGetField(tif, tag, dotrange+0, dotrange+1);
+ } else if (fip->field_type == TIFF_ASCII
+ || fip->field_readcount == TIFF_VARIABLE
+ || fip->field_readcount == TIFF_VARIABLE2
+ || fip->field_readcount == TIFF_SPP
+ || value_count > 1) {
+ if(TIFFGetField(tif, tag, &raw_data) != 1)
+ continue;
+ } else {
+ raw_data = _TIFFmalloc(
+ _TIFFDataSize(fip->field_type)
+ * value_count);
+ mem_alloc = 1;
+ if(TIFFGetField(tif, tag, raw_data) != 1) {
+ _TIFFfree(raw_data);
+ continue;
+ }
}
}
- }
- /*
- * Catch the tags which needs to be specially handled and
- * pretty print them. If tag not handled in
- * _TIFFPrettyPrintField() fall down and print it as any other
- * tag.
- */
- if (_TIFFPrettyPrintField(tif, fd, tag, value_count, raw_data)) {
+ /*
+ * Catch the tags which needs to be specially handled
+ * and pretty print them. If tag not handled in
+ * _TIFFPrettyPrintField() fall down and print it as
+ * any other tag.
+ */
+ if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data))
+ _TIFFPrintField(fd, fip, value_count, raw_data);
+
if(mem_alloc)
_TIFFfree(raw_data);
- continue;
}
- else
- _TIFFPrintField(fd, fip, value_count, raw_data);
-
- if(mem_alloc)
- _TIFFfree(raw_data);
- }
- }
+ }
if (tif->tif_tagmethods.printdir)
(*tif->tif_tagmethods.printdir)(tif, fd, flags);
+
+ _TIFFFillStriles( tif );
+
if ((flags & TIFFPRINT_STRIPS) &&
TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
- tstrip_t s;
+ uint32 s;
fprintf(fd, " %lu %s:\n",
(long) td->td_nstrips,
isTiled(tif) ? "Tiles" : "Strips");
for (s = 0; s < td->td_nstrips; s++)
- fprintf(fd, " %3lu: [%8lu, %8lu]\n",
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, " %3lu: [%8I64u, %8I64u]\n",
+ (unsigned long) s,
+ (unsigned __int64) td->td_stripoffset[s],
+ (unsigned __int64) td->td_stripbytecount[s]);
+#else
+ fprintf(fd, " %3lu: [%8llu, %8llu]\n",
(unsigned long) s,
- (unsigned long) td->td_stripoffset[s],
- (unsigned long) td->td_stripbytecount[s]);
+ (unsigned long long) td->td_stripoffset[s],
+ (unsigned long long) td->td_stripbytecount[s]);
+#endif
}
}
void
_TIFFprintAscii(FILE* fd, const char* cp)
{
- for (; *cp != '\0'; cp++) {
+ _TIFFprintAsciiBounded( fd, cp, strlen(cp));
+}
+
+static void
+_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars)
+{
+ for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
const char* tp;
if (isprint((int)*cp)) {
@@ -637,3 +707,10 @@ _TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
}
/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */