public static void Main(string[] args)
{
Copier c = new Copier();
StringBuilder mode = new StringBuilder();
mode.Append('w');
char imageNumberSeparator = ','; // (default) comma separator character
FillOrder defaultFillOrder = 0;
int defaultTileLength = -1;
int initialDirectoryOffset = 0;
PlanarConfig defaultPlanarConfig = PlanarConfig.UNKNOWN;
int defaultRowsPerStrip = 0;
int defaultTileWidth = -1;
int argn = 0;
for (; argn < args.Length; argn++)
{
string option = args[argn];
if (option[0] == '-')
option = option.Substring(1);
else
break;
string optionArg = null;
if (argn < (args.Length - 1))
optionArg = args[argn + 1];
switch (option[0])
{
case ',':
if (option[1] != '=')
{
usage();
return;
}
imageNumberSeparator = option[2];
break;
case 'b':
// this file is bias image subtracted from others
if (c.m_bias != null)
{
Console.Error.Write("Only 1 bias image may be specified\n");
return;
}
string biasName = args[argn + 1];
c.m_bias = Tiff.Open(biasName, "r");
if (c.m_bias == null)
{
Console.Error.WriteLine("Failed to open '{0}' as input.", biasName);
return;
}
if (c.m_bias.IsTiled())
{
Console.Error.Write("Bias image must be organized in strips\n");
return;
}
FieldValue[] result = c.m_bias.GetField(TiffTag.SAMPLESPERPIXEL);
short samples = result[0].ToShort();
if (samples != 1)
{
Console.Error.Write("Bias image must be monochrome\n");
return;
}
argn++;
break;
case 'a':
// append to output
mode[0] = 'a';
break;
case 'c':
// compression scheme
if (!c.ProcessCompressOptions(optionArg))
{
usage();
return;
}
argn++;
break;
case 'f':
// fill order
if (optionArg == "lsb2msb")
defaultFillOrder = FillOrder.LSB2MSB;
else if (optionArg == "msb2lsb")
defaultFillOrder = FillOrder.MSB2LSB;
else
{
usage();
return;
}
argn++;
break;
case 'i':
// ignore errors
c.m_ignore = true;
break;
case 'l':
// tile length
c.m_outtiled = 1;
defaultTileLength = int.Parse(optionArg, CultureInfo.InvariantCulture);
argn++;
break;
case 'o':
// initial directory offset
initialDirectoryOffset = int.Parse(optionArg, CultureInfo.InvariantCulture);
break;
case 'p':
// planar configuration
if (optionArg == "separate")
defaultPlanarConfig = PlanarConfig.SEPARATE;
else if (optionArg == "contig")
defaultPlanarConfig = PlanarConfig.CONTIG;
else
{
usage();
return;
}
argn++;
break;
case 'r':
// rows/strip
defaultRowsPerStrip = int.Parse(optionArg, CultureInfo.InvariantCulture);
argn++;
break;
case 's':
// generate stripped output
c.m_outtiled = 0;
break;
case 't':
// generate tiled output
c.m_outtiled = 1;
break;
case 'w':
// tile width
c.m_outtiled = 1;
defaultTileWidth = int.Parse(optionArg, CultureInfo.InvariantCulture);
argn++;
break;
case 'B':
mode.Append('b');
break;
case 'L':
mode.Append('l');
break;
case 'M':
mode.Append('m');
break;
case 'C':
mode.Append('c');
break;
case 'x':
c.m_pageInSeq = 1;
break;
case '?':
usage();
return;
}
}
if (args.Length - argn < 2)
{
// there must be at least one input and one output image names after options
usage();
return;
}
using (Tiff outImage = Tiff.Open(args[args.Length - 1], mode.ToString()))
{
if (outImage == null)
{
Console.Error.WriteLine("Failed to open '{0}' as output.", args[args.Length - 1]);
return;
}
if ((args.Length - argn) == 2)
c.m_pageNum = -1;
for (; argn < args.Length - 1; argn++)
{
string[] fileAndPageNums = args[argn].Split(new char[] { imageNumberSeparator });
using (Tiff inImage = Tiff.Open(fileAndPageNums[0], "r"))
{
if (inImage == null)
return;
if (initialDirectoryOffset != 0 && !inImage.SetSubDirectory(initialDirectoryOffset))
{
Tiff.Error(inImage.FileName(), "Error, setting subdirectory at 0x{0:x}", initialDirectoryOffset);
inImage.Dispose();
break;
}
int initialPage = 0;
int pageNumPos = 1;
if (pageNumPos < fileAndPageNums.Length && !string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
initialPage = int.Parse(fileAndPageNums[pageNumPos]);
int totalPages = inImage.NumberOfDirectories();
for (int i = initialPage; i < totalPages; )
{
c.m_config = defaultPlanarConfig;
c.m_compression = c.m_defcompression;
c.m_predictor = c.m_defpredictor;
c.m_fillorder = defaultFillOrder;
c.m_rowsperstrip = defaultRowsPerStrip;
c.m_tilewidth = defaultTileWidth;
c.m_tilelength = defaultTileLength;
c.m_g3opts = c.m_defg3opts;
if (!inImage.SetDirectory((short)i))
{
Console.Error.Write("{0}{1}{2} not found!\n",
inImage.FileName(), imageNumberSeparator, i);
return;
}
if (!c.Copy(inImage, outImage) || !outImage.WriteDirectory())
return;
// if we have at least one page specifier and current specifier is not empty.
// specifier is empty when trailing separator used like this: "file,num,"
if (pageNumPos < fileAndPageNums.Length && !string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
{
// move to next page specifier
pageNumPos++;
if (pageNumPos < fileAndPageNums.Length)
{
// new page specifier position is valid
if (!string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
{
// new page specifier is not empty. use specified page number
i = int.Parse(fileAndPageNums[pageNumPos]);
}
else
{
// new page specifier is empty. just move to the next page
i++;
}
}
else
{
// new page specifier position is invalid. done all pages.
break;
}
}
else
{
// we have no page specifiers or current page specifier is empty
// just move to the next page
i++;
}
}
}
}
}
}