static void saveTheImage(Image saveimage, int imageIndex, DocToImagesOptions options, ImageSaveParams isp)
        {
            string outputfilepath;

            if (options.getoutputdir() != "")
            {
                outputfilepath = options.getoutputdir() + "/" + options.getoutputfile() +
                                 formatdigits(options.getZeroSuffix(), imageIndex);
            }
            else
            {
                outputfilepath = options.getoutputfile() + formatdigits(options.getZeroSuffix(), imageIndex);
            }

            outputfilepath = CreateFileSuffix(outputfilepath, options.getoutputformat());
            try
            {
                saveimage.Save(outputfilepath, options.getoutputformat(), isp);
                saveimage.Dispose();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Cannot write an image to a file: " + ex.Message);
            }
        }
        static void Main(string[] args)
        {
            string docpath;

            Console.WriteLine("PDF Document to Images Sample:");
            if (args.Length < 2)
            {
                Usage();
                Environment.Exit(1);
            }

            DocToImagesOptions options = new DocToImagesOptions();

            if (args[args.Length - 1].StartsWith("-") || args[args.Length - 1].Contains("="))
            {
                Console.WriteLine("The last option must be the path to a PDF file.");
                Usage();
                Environment.Exit(1);
            }

            for (int i = 0; i < args.Length - 1; i++)
            {
                String arg = args[i];
                if (arg.StartsWith("-") && arg.Contains("="))
                {
                    String opt = arg.Substring(arg.IndexOf("=") + 1);
                    if (arg.StartsWith("-format="))
                    {
                        // Process output format option
                        if (opt.Equals("jpg"))
                        {
                            options.setoutputformat(ImageType.JPEG);
                        }
                        else if (opt.Equals("tif"))
                        {
                            options.setoutputformat(ImageType.TIFF);
                        }
                        else if (opt.Equals("bmp"))
                        {
                            options.setoutputformat(ImageType.BMP);
                        }
                        else if (opt.Equals("png"))
                        {
                            options.setoutputformat(ImageType.PNG);
                        }
                        else if (opt.Equals("gif"))
                        {
                            options.setoutputformat(ImageType.GIF);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the format option. Valid values are jpg, tif, bmp, png, gif");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-color="))
                    {
                        // Process output color option
                        if (opt.Equals("gray"))
                        {
                            options.setcolor(ColorSpace.DeviceGray);
                        }
                        else if (opt.Equals("rgb"))
                        {
                            options.setcolor(ColorSpace.DeviceRGB);
                        }
                        else if (opt.Equals("cmyk"))
                        {
                            options.setcolor(ColorSpace.DeviceCMYK);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the color option. Valid values are gray, rgb, cmyk");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-grayhalftone="))
                    {
                        // Process grayscale half tone
                        if (opt.Equals("y"))
                        {
                            options.setgrayhalftone(true);
                        }
                        else if (opt.Equals("n"))
                        {
                            options.setgrayhalftone(false);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the grayhalftone option.  Valid values are n or y");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-first="))
                    {
                        // Process first page only option
                        if (opt.Equals("y"))
                        {
                            options.setfirst(true);
                        }
                        else if (opt.Equals("n"))
                        {
                            options.setfirst(false);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the first option.  Valid values are 'y' and 'n'.");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-quality="))
                    {
                        // Process jpeg quality option
                        int quality = int.Parse(opt);
                        if (quality < 1 || 1 > 100)
                        {
                            Console.WriteLine("Invalid value for the quality option.  Valid values are 1 through 100.");
                            Environment.Exit(1);
                        }
                        options.setquality(quality);
                        continue;
                    }

                    if (arg.Contains("resolution="))
                    {
                        // Process horizontal and/or vertical resolution option
                        if (opt.Contains("x"))
                        {
                            string hopt = opt.Substring(0, opt.IndexOf("x"));
                            String vopt = opt.Substring(opt.IndexOf("x") + 1);
                            options.sethres(double.Parse(hopt));
                            options.setvres(double.Parse(vopt));
                        }
                        else
                        {
                            double res = double.Parse(opt);
                            options.sethres(res);
                            options.setvres(res);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-fontlist="))
                    {
                        // process font search directory list option
                        options.setfontdirs(opt);
                        continue;
                    }

                    if (arg.StartsWith("-pixels="))
                    {
                        // process size in pixels option
                        if (opt.Contains("x"))
                        {
                            string hopt = opt.Substring(0, opt.IndexOf("x"));
                            String vopt = opt.Substring(opt.IndexOf("x") + 1);
                            options.sethpixels(int.Parse(hopt));
                            options.setvpixels(int.Parse(vopt));
                        }
                        else
                        {
                            int pixels = int.Parse(opt);
                            options.sethpixels(pixels);
                            options.setvpixels(pixels);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-compression="))
                    {
                        // process TIFF compression option
                        if (opt.Equals("no"))
                        {
                            options.setcompress(CompressionCode.NONE);
                        }
                        else if (opt.Equals("lzw"))
                        {
                            options.setcompress(CompressionCode.LZW);
                        }
                        else if (opt.Equals("g3"))
                        {
                            options.setcompress(CompressionCode.G3);
                        }
                        else if (opt.Equals("g4"))
                        {
                            options.setcompress(CompressionCode.G4);
                        }
                        else if (opt.Equals("flate"))
                        {
                            options.setcompress(CompressionCode.FLATE);
                        }
                        else if (opt.Equals("dct"))
                        {
                            options.setcompress(CompressionCode.DCT);
                        }
                        else if (opt.Equals("default"))
                        {
                            options.setcompress(CompressionCode.Default);
                        }
                        else if (opt.Equals("none"))
                        {
                            options.setcompress(CompressionCode.NONE);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the compression option.  Valid values are: no|lzw|g3|g4|jpg");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-region="))
                    {
                        // process page output region option
                        if (!(opt.Equals("crop") || opt.Equals("media") || opt.Equals("art") ||
                              opt.Equals("trim") || opt.Equals("bleed") || opt.Equals("bounding")))
                        {
                            Console.WriteLine("Invalid value for the region option.  Value values are: crop|media|art|trim|bleed|bounding");
                            Environment.Exit(1);
                        }
                        options.setpageregion(opt);
                        continue;
                    }

                    if (arg.Contains("pages="))
                    {
                        // process pages to be rasterized list option
                        if (opt.Equals("even"))
                        {
                            options.setevenpages();
                        }
                        else if (opt.Equals("odd"))
                        {
                            options.setoddpages();
                        }
                        else
                        {
                            /*
                             * Get the comma separated page groups and check each
                             * for page ranges.  If page ranges exist then create the
                             * range using the page numbers on either side of the '-' as
                             * the lower and upper bound.
                             */
                            string[] pagegroups = opt.Split(',');
                            for (int ix = 0; ix < pagegroups.Length; ix++)
                            {
                                string pagegroup = pagegroups[ix];
                                if (pagegroup.Contains("-"))
                                {
                                    string[] pagerange = pagegroup.Split('-');
                                    if (pagerange.Length != 2 || pagerange[0].Equals("") || pagerange[1].Equals(""))
                                    {
                                        Console.WriteLine("Misformatted page range: " + pagegroup);
                                        Environment.Exit(1);
                                    }
                                    else
                                    {
                                        for (int z = int.Parse(pagerange[0]); z <= int.Parse(pagerange[1]); z++)
                                        {
                                            options.appendpagelist(z);
                                        }
                                    }
                                }
                                else
                                {
                                    int printpage = int.Parse(pagegroup);
                                    options.appendpagelist(printpage);
                                }
                            }
                        }
                        continue;
                    }

                    if (arg.StartsWith("-output="))
                    {
                        // process output filename option
                        options.setoutputfile(opt);
                        continue;
                    }

                    if (arg.StartsWith("-smoothing="))
                    {
                        // process smoothing option none|text|all
                        if (opt.Equals("none"))
                        {
                            options.setsmooth(SmoothFlags.None);
                        }
                        else if (opt.Equals("text"))
                        {
                            options.setsmooth(SmoothFlags.Text);
                        }
                        else if (opt.Equals("all"))
                        {
                            options.setsmooth(SmoothFlags.Image | SmoothFlags.LineArt | SmoothFlags.Text);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the smoothing option.  Valid values are none|text|all");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-reverse="))
                    {
                        // process gray reverse option
                        if (opt.Equals("y"))
                        {
                            options.setreversegray(true);
                        }
                        else if (opt.Equals("n"))
                        {
                            options.setreversegray(false);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the reverse option.  Valid values are 'y' and 'n'.");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-blackisone="))
                    {
                        // Photometrically reverse Tiff  option
                        if (opt.Equals("y"))
                        {
                            options.setblackisone(true);
                        }
                        else if (opt.Equals("n"))
                        {
                            options.setblackisone(false);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the blackisone option.  Valid values are 'y' and 'n'.");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-multi="))
                    {
                        // process multipage tif option
                        if (opt.Equals("y"))
                        {
                            options.setmultipage(true);
                        }
                        else if (opt.Equals("n"))
                        {
                            options.setmultipage(false);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the multi option.  Valid values are 'y' and 'n'.");
                            Environment.Exit(1);
                        }
                        continue;
                    }

                    if (arg.StartsWith("-digits="))
                    {
                        // process fixed digit suffix length option
                        int numdigits = int.Parse(opt);
                        if (numdigits < 0 || numdigits > 9)
                        {
                            Console.WriteLine("Invalid value for the digits option. Valid values are 0-9.");
                        }
                        options.setZeroSuffix(numdigits);
                        continue;
                    }

                    if (arg.StartsWith("-asprinted="))
                    {
                        // process render only printable annotations option
                        if (opt.Equals("y"))
                        {
                            options.setasprinted(true);
                        }
                        else if (opt.Equals("n"))
                        {
                            options.setasprinted(false);
                        }
                        else
                        {
                            Console.WriteLine("Invalid value for the asprinted option.  Valid values are 'y' and 'n'.");
                            Environment.Exit(1);
                        }
                        continue;
                    }
                    Console.WriteLine("Invalid option: " + arg);
                    Usage();
                    Environment.Exit(1);
                }
                else
                {
                    Console.WriteLine("Invalid option: " + arg);
                    Usage();
                    Environment.Exit(1);
                }
            }

            docpath = args[args.Length - 1];
            // Now crosscheck and verify the combinations of the options we have entered.
            int errorcount = 0;

            if (options.checkformattype() == false)
            {
                Console.WriteLine("format must be set to tif, jpg, bmp, png, or gif");
                errorcount++;
            }

            if (options.checkcolorspacegrayhalftone() == false)
            {
                Console.WriteLine("grayhalftone can only be set to 1 for a value of 'gray' for color");
                errorcount++;
            }

            if (options.checkformatcompressiontiff() == false)
            {
                Console.WriteLine("Compression can only be this value for a format value of 'tif'");
                errorcount++;
            }

            if (options.checkformatcompressionpng() == false)
            {
                Console.WriteLine("Compression can only be this value for a format value of 'png'");
                errorcount++;
            }

            if (options.checkformatcompressionjpg() == false)
            {
                Console.WriteLine("Compression can only be this value for a format value of 'jpg'");
                errorcount++;
            }

            if (options.checkcompressionnone() == false)
            {
                Console.WriteLine("Compression can only be this value for a format value of 'bmp' or 'png' or 'tif'");
                errorcount++;
            }

            if (options.checkreversegray() == false)
            {
                Console.WriteLine("reverse can only be set to 'y' for a value of 'gray' for color");
                errorcount++;
            }

            if (options.checkblackisoneformat() == false)
            {
                Console.WriteLine("blackisone can only be set to 'y' for a format value of 'tif'");
                errorcount++;
            }

            if (options.checktiffcompressgrayhalftone() == false)
            {
                Console.WriteLine("compression can only be set to 'g3' or 'g4' if grayhalftone is set to 'y' and color is set to 'gray'");
                errorcount++;
            }


            if (options.checkgrayhalftoneformat() == false)
            {
                Console.WriteLine("grayhalftone can only be set to 'y' for format set to tif");
                errorcount++;
            }

            if (options.checkqualityimagetype() == false)
            {
                Console.WriteLine("quality can only be set to a value other than 0 for a format value of 'jpg'");
                errorcount++;
            }

            if (options.checkfirstonlypagerange() == false)
            {
                Console.WriteLine("The pages option cannot be specified if firstonly is set to 'y'");
                errorcount++;
            }

            if (options.checkfirstonlyevenodd() == false)
            {
                Console.WriteLine("The pages option cannot be set to 'even' or 'odd' if firstonly is set to 'y'");
                errorcount++;
            }

            if (options.checkmultiformat() == false)
            {
                Console.WriteLine("The multi option can only be set to 'y' if format is set to 'tif'");
                errorcount++;
            }

            if (options.checkfontdirs() != true)
            {
                errorcount++;
            }

            if (errorcount > 0)
            {
                Console.WriteLine("Because of command line option errors, no image processing will be performed.");
                Environment.Exit(1);
            }

            using (Library lib = new Library(options.getfontdirs()))
            {
                Document   pdfdocument = null;
                int        numpages    = 0;
                List <int> pagelist    = new List <int>(0);
                try
                {
                    pdfdocument = new Document(docpath);
                    numpages    = pdfdocument.NumPages;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error opening PDF document " + docpath + ":" + ex.Message);
                    Environment.Exit(1);
                }

                /*
                 * Now that we know we can open the PDF file, use the filename to create what will be the basis
                 * of the output filename and directory name.
                 */

                string outputfilename;
                if (options.getoutputfile() == "")
                {
                    outputfilename = docpath;
                }
                else
                {
                    outputfilename = options.getoutputfile();
                }
                options.setoutputdir(System.IO.Path.GetDirectoryName(outputfilename));
                string[] basefilename = System.IO.Path.GetFileName(outputfilename).Split('.'); // split off the .pdf suffix.
                options.setoutputfile(basefilename[0]);


                if (options.checkpagelist(numpages) == false)
                {
                    Console.WriteLine("The list of pages given in the 'pages' option is outside the number of pages in this PDF document: " + pdfdocument.NumPages);
                    Environment.Exit(1);
                }

                /*
                 * If the list of pages were not populated from the command line options, or if the options have specified
                 * all odd or all even, then populate the list here and then reget the list.
                 */

                pagelist = options.getpagelist();
                if (pagelist.Count == 0)
                {
                    if (options.getfirst() == true) // First page only.
                    {
                        numpages = 1;               // Will modify the operation of the loop below.
                    }
                    for (int i = 0; i < numpages; i++)
                    {
                        // Remember in the Doc object page #'s start with 0, but physically they start with 1.
                        if ((options.onlyodd() == false && options.onlyeven() == false) ||  // all pages
                            (options.onlyodd() == true && (((i + 1) % 2) == 1)) ||          // this is an odd page
                            (options.onlyeven() == true && (((i + 1) % 2) == 0)))           // this is an even page
                        {
                            options.appendpagelist(i);
                        }
                    }
                    pagelist = options.getpagelist();
                }

                PageImageParams pip = new PageImageParams(options.getcolor(), options.getsmooth(), options.gethpixels(),
                                                          options.getvpixels(), options.gethres(), options.getvres(),
                                                          (DrawFlags.UseAnnotFaces | DrawFlags.DoLazyErase));
                if (options.getasprinted() == true)
                {
                    pip.PageDrawFlags |= DrawFlags.IsPrinting;
                }

                ImageCollection Pageimagecollection = new ImageCollection();

                if (options.getoutputformat() == ImageType.TIFF && options.getcompress() == CompressionCode.NONE)
                {
                    options.setcompress(CompressionCode.LZW); // Default for TIF
                }

                ImageSaveParams isp = new ImageSaveParams();
                isp.HalftoneGrayImages = options.getgrayhalftone();
                isp.Compression        = options.getcompress();
                if (options.getoutputformat() == ImageType.JPEG)
                {
                    isp.JPEGQuality = options.getquality();
                }
                isp.ReverseGray    = options.getreversegray();
                isp.TIFFBlackIsOne = options.getblackisone();

                for (int i = 0; i < pagelist.Count; i++) // Get the images of the PDF pages to create an image collection.
                {
                    Page docpage  = pdfdocument.GetPage(pagelist[i]);
                    Rect PageRect = null;
                    if (options.getpageregion().Equals("crop"))
                    {
                        PageRect = docpage.CropBox;
                    }
                    else if (options.getpageregion().Equals("media"))
                    {
                        PageRect = docpage.MediaBox;
                    }
                    else if (options.getpageregion().Equals("art"))
                    {
                        PageRect = docpage.ArtBox;
                    }
                    else if (options.getpageregion().Equals("bounding"))
                    {
                        PageRect = docpage.BBox;
                    }
                    else if (options.getpageregion().Equals("bleed"))
                    {
                        PageRect = docpage.BleedBox;
                    }
                    else if (options.getpageregion().Equals("trim"))
                    {
                        PageRect = docpage.TrimBox;
                    }
                    else
                    {
                        Console.WriteLine("Unknown page region option.");
                        Environment.Exit(1);
                    }
                    try
                    {
                        Image pageimage = docpage.GetImage(PageRect, pip);
                        if (options.getmultipage() == true)
                        {
                            Pageimagecollection.Append(pageimage);
                        }
                        else
                        {
                            int x = i + 1;
                            saveTheImage(pageimage, x, options, isp);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Cannot rasterize page to an image: " + ex.Message);
                        Environment.Exit(1);
                    }
                }

                /*
                 * Pageimagecollection now Contains, as the name states,
                 * a collection of images created from the PDF pages according
                 * to the user's options.  Now to post process them to the image.
                 * type according to the user's options.
                 */
                if (options.getmultipage() == true)
                {
                    string outputfilepath;
                    if (options.getoutputdir() != "")
                    {
                        outputfilepath = options.getoutputdir() + "/" + options.getoutputfile();
                    }
                    else
                    {
                        outputfilepath = options.getoutputfile();
                    }

                    outputfilepath = CreateFileSuffix(outputfilepath, options.getoutputformat());
                    try
                    {
                        Pageimagecollection.Save(outputfilepath, options.getoutputformat(), isp);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Cannot save images to a multi-page TIF file: " + ex.Message);
                    }
                }
            }
        }