public bool Copy(Tiff inImage, Tiff outImage)
{
int width = 0;
FieldValue[] result = inImage.GetField(TiffTag.IMAGEWIDTH);
if (result != null)
{
width = result[0].ToInt();
outImage.SetField(TiffTag.IMAGEWIDTH, width);
}
int length = 0;
result = inImage.GetField(TiffTag.IMAGELENGTH);
if (result != null)
{
length = result[0].ToInt();
outImage.SetField(TiffTag.IMAGELENGTH, length);
}
short bitspersample = 1;
result = inImage.GetField(TiffTag.BITSPERSAMPLE);
if (result != null)
{
bitspersample = result[0].ToShort();
outImage.SetField(TiffTag.BITSPERSAMPLE, bitspersample);
}
short samplesperpixel = 1;
result = inImage.GetField(TiffTag.SAMPLESPERPIXEL);
if (result != null)
{
samplesperpixel = result[0].ToShort();
outImage.SetField(TiffTag.SAMPLESPERPIXEL, samplesperpixel);
}
if (m_compression != (Compression)(-1))
outImage.SetField(TiffTag.COMPRESSION, m_compression);
else
{
result = inImage.GetField(TiffTag.COMPRESSION);
if (result != null)
{
m_compression = (Compression)result[0].ToInt();
outImage.SetField(TiffTag.COMPRESSION, m_compression);
}
}
result = inImage.GetFieldDefaulted(TiffTag.COMPRESSION);
Compression input_compression = (Compression)result[0].ToInt();
result = inImage.GetFieldDefaulted(TiffTag.PHOTOMETRIC);
Photometric input_photometric = (Photometric)result[0].ToShort();
if (input_compression == Compression.JPEG)
{
/* Force conversion to RGB */
inImage.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RGB);
}
else if (input_photometric == Photometric.YCBCR)
{
/* Otherwise, can't handle subsampled input */
result = inImage.GetFieldDefaulted(TiffTag.YCBCRSUBSAMPLING);
short subsamplinghor = result[0].ToShort();
short subsamplingver = result[1].ToShort();
if (subsamplinghor != 1 || subsamplingver != 1)
{
Console.Error.WriteLine("tiffcp: {0}: Can't copy/convert subsampled image.", inImage.FileName());
return false;
}
}
if (m_compression == Compression.JPEG)
{
if (input_photometric == Photometric.RGB && m_jpegcolormode == JpegColorMode.RGB)
outImage.SetField(TiffTag.PHOTOMETRIC, Photometric.YCBCR);
else
outImage.SetField(TiffTag.PHOTOMETRIC, input_photometric);
}
else if (m_compression == Compression.SGILOG || m_compression == Compression.SGILOG24)
{
outImage.SetField(TiffTag.PHOTOMETRIC, samplesperpixel == 1 ? Photometric.LOGL : Photometric.LOGLUV);
}
else
{
if (input_compression != Compression.JPEG)
copyTag(inImage, outImage, TiffTag.PHOTOMETRIC, 1, TiffType.SHORT);
}
if (m_fillorder != 0)
outImage.SetField(TiffTag.FILLORDER, m_fillorder);
else
copyTag(inImage, outImage, TiffTag.FILLORDER, 1, TiffType.SHORT);
/*
* Will copy `Orientation' tag from input image
*/
result = inImage.GetFieldDefaulted(TiffTag.ORIENTATION);
m_orientation = (Orientation)result[0].ToByte();
switch (m_orientation)
{
case Orientation.BOTRIGHT:
case Orientation.RIGHTBOT:
Tiff.Warning(inImage.FileName(), "using bottom-left orientation");
m_orientation = Orientation.BOTLEFT;
break;
case Orientation.LEFTBOT:
case Orientation.BOTLEFT:
break;
case Orientation.TOPRIGHT:
case Orientation.RIGHTTOP:
default:
Tiff.Warning(inImage.FileName(), "using top-left orientation");
m_orientation = Orientation.TOPLEFT;
break;
case Orientation.LEFTTOP:
case Orientation.TOPLEFT:
break;
}
outImage.SetField(TiffTag.ORIENTATION, m_orientation);
/*
* Choose tiles/strip for the output image according to
* the command line arguments (-tiles, -strips) and the
* structure of the input image.
*/
if (m_outtiled == -1)
{
if (inImage.IsTiled())
m_outtiled = 1;
else
m_outtiled = 0;
}
if (m_outtiled != 0)
{
/*
* Setup output file's tile width&height. If either
* is not specified, use either the value from the
* input image or, if nothing is defined, use the
* library default.
*/
if (m_tilewidth == -1)
{
result = inImage.GetFieldDefaulted(TiffTag.TILEWIDTH);
if (result != null)
m_tilewidth = result[0].ToInt();
}
if (m_tilelength == -1)
{
result = inImage.GetFieldDefaulted(TiffTag.TILELENGTH);
if (result != null)
m_tilelength = result[0].ToInt();
}
outImage.DefaultTileSize(ref m_tilewidth, ref m_tilelength);
outImage.SetField(TiffTag.TILEWIDTH, m_tilewidth);
outImage.SetField(TiffTag.TILELENGTH, m_tilelength);
}
else
{
/*
* RowsPerStrip is left unspecified: use either the
* value from the input image or, if nothing is defined,
* use the library default.
*/
if (m_rowsperstrip == 0)
{
result = inImage.GetField(TiffTag.ROWSPERSTRIP);
if (result == null)
m_rowsperstrip = outImage.DefaultStripSize(m_rowsperstrip);
else
m_rowsperstrip = result[0].ToInt();
if (m_rowsperstrip > length && m_rowsperstrip != -1)
m_rowsperstrip = length;
}
else if (m_rowsperstrip == -1)
m_rowsperstrip = length;
outImage.SetField(TiffTag.ROWSPERSTRIP, m_rowsperstrip);
}
if (m_config != PlanarConfig.UNKNOWN)
outImage.SetField(TiffTag.PLANARCONFIG, m_config);
else
{
result = inImage.GetField(TiffTag.PLANARCONFIG);
if (result != null)
{
m_config = (PlanarConfig)result[0].ToShort();
outImage.SetField(TiffTag.PLANARCONFIG, m_config);
}
}
if (samplesperpixel <= 4)
copyTag(inImage, outImage, TiffTag.TRANSFERFUNCTION, 4, TiffType.SHORT);
copyTag(inImage, outImage, TiffTag.COLORMAP, 4, TiffType.SHORT);
/* SMinSampleValue & SMaxSampleValue */
switch (m_compression)
{
case Compression.JPEG:
outImage.SetField(TiffTag.JPEGQUALITY, m_quality);
outImage.SetField(TiffTag.JPEGCOLORMODE, m_jpegcolormode);
break;
case Compression.LZW:
case Compression.ADOBE_DEFLATE:
case Compression.DEFLATE:
if (m_predictor != -1)
outImage.SetField(TiffTag.PREDICTOR, m_predictor);
else
{
result = inImage.GetField(TiffTag.PREDICTOR);
if (result != null)
{
m_predictor = result[0].ToShort();
outImage.SetField(TiffTag.PREDICTOR, m_predictor);
}
}
break;
case Compression.CCITTFAX3:
case Compression.CCITTFAX4:
if (m_compression == Compression.CCITTFAX3)
{
if (m_g3opts != Group3Opt.UNKNOWN)
outImage.SetField(TiffTag.GROUP3OPTIONS, m_g3opts);
else
{
result = inImage.GetField(TiffTag.GROUP3OPTIONS);
if (result != null)
{
m_g3opts = (Group3Opt)result[0].ToShort();
outImage.SetField(TiffTag.GROUP3OPTIONS, m_g3opts);
}
}
}
else
copyTag(inImage, outImage, TiffTag.GROUP4OPTIONS, 1, TiffType.LONG);
copyTag(inImage, outImage, TiffTag.BADFAXLINES, 1, TiffType.LONG);
copyTag(inImage, outImage, TiffTag.CLEANFAXDATA, 1, TiffType.LONG);
copyTag(inImage, outImage, TiffTag.CONSECUTIVEBADFAXLINES, 1, TiffType.LONG);
copyTag(inImage, outImage, TiffTag.FAXRECVPARAMS, 1, TiffType.LONG);
copyTag(inImage, outImage, TiffTag.FAXRECVTIME, 1, TiffType.LONG);
copyTag(inImage, outImage, TiffTag.FAXSUBADDRESS, 1, TiffType.ASCII);
break;
}
result = inImage.GetField(TiffTag.ICCPROFILE);
if (result != null)
outImage.SetField(TiffTag.ICCPROFILE, result[0], result[1]);
result = inImage.GetField(TiffTag.NUMBEROFINKS);
if (result != null)
{
short ninks = result[0].ToShort();
outImage.SetField(TiffTag.NUMBEROFINKS, ninks);
result = inImage.GetField(TiffTag.INKNAMES);
if (result != null)
{
string inknames = result[0].ToString();
string[] parts = inknames.Split(new char[] { '\0' });
int inknameslen = 0;
foreach (string part in parts)
inknameslen += part.Length + 1;
outImage.SetField(TiffTag.INKNAMES, inknameslen, inknames);
}
}
result = inImage.GetField(TiffTag.PAGENUMBER);
if (m_pageInSeq == 1)
{
if (m_pageNum < 0)
{
/* only one input file */
if (result != null)
outImage.SetField(TiffTag.PAGENUMBER, result[0], result[1]);
}
else
{
outImage.SetField(TiffTag.PAGENUMBER, m_pageNum++, 0);
}
}
else
{
if (result != null)
{
if (m_pageNum < 0)
{
/* only one input file */
outImage.SetField(TiffTag.PAGENUMBER, result[0], result[1]);
}
else
{
outImage.SetField(TiffTag.PAGENUMBER, m_pageNum++, 0);
}
}
}
int NTAGS = g_tags.Length;
for (int i = 0; i < NTAGS; i++)
{
tagToCopy p = g_tags[i];
copyTag(inImage, outImage, p.tag, p.count, p.type);
}
return pickFuncAndCopy(inImage, outImage, bitspersample, samplesperpixel, length, width);
}