static public void ProcessImage(Element image)
        {
            bool image_mask  = image.IsImageMask();
            bool interpolate = image.IsImageInterpolate();
            int  width       = image.GetImageWidth();
            int  height      = image.GetImageHeight();
            int  out_data_sz = width * height * 3;

            Console.WriteLine("Image: width=\"{0:d}\" height=\"{1:d}\"", width, height);

            // Matrix2D mtx = image.GetCTM(); // image matrix (page positioning info)

//          ++image_counter;
//          System.Drawing.Bitmap bmp = image.GetBitmap();
//          bmp.Save(output_path + "reader_img_extract_" + image_counter.ToString() + ".png", System.Drawing.Imaging.ImageFormat.Png);
//
            // Alternatively you can use GetImageData to read the raw (decoded) image data
            // image.GetBitsPerComponent();
            // image.GetImageData();	// get raw image data
            // another approach is to use Image2RGB filter that converts every image to
            // RGB format. This could save you time since you don't need to deal with color
            // conversions, image up-sampling, decoding etc.
            // ----------------
            Image2RGB    img_conv = new Image2RGB(image);       // Extract and convert image to RGB 8-bpc format
            FilterReader reader   = new FilterReader(img_conv); //

            byte[] image_data_out = new byte[out_data_sz];      // A buffer used to keep image data.
            reader.Read(image_data_out);                        // image_data_out contains RGB image data.
            // ----------------
            // Note that you don't need to read a whole image at a time. Alternatively
            // you can read a chuck at a time by repeatedly calling reader.Read(buf, buf_sz)
            // until the function returns 0.
        }
        static byte[] FlipImage(Element element)
        {
            Image2RGB    image2rgb   = new Image2RGB(element);
            int          width       = element.GetImageWidth();
            int          height      = element.GetImageHeight();
            int          out_data_sz = width * height * 3;
            int          stride      = width * 3;
            FilterReader reader      = new FilterReader(image2rgb);

            byte[] image_data   = new byte[out_data_sz];
            byte[] flipped_data = new byte[out_data_sz];
            reader.Read(image_data);
            for (int row = 0; row < height; ++row)
            {
                Buffer.BlockCopy(image_data, row * stride, flipped_data, out_data_sz - (stride * (row + 1)), stride);
            }
            return(flipped_data);
        }
        static void ImageExtract(PDFDoc doc, ElementReader reader)
        {
            Element element;

            while ((element = reader.Next()) != null)
            {
                switch (element.GetType())
                {
                case Element.Type.e_image:
                case Element.Type.e_inline_image:
                {
                    Console.WriteLine("--> Image: {0}", ++image_counter);
                    Console.WriteLine("    Width: {0}", element.GetImageWidth());
                    Console.WriteLine("    Height: {0}", element.GetImageHeight());
                    Console.WriteLine("    BPC: {0}", element.GetBitsPerComponent());

                    Matrix2D ctm = element.GetCTM();
                    double   x2 = 1, y2 = 1, y1 = ctm.m_v;
                    ctm.Mult(ref x2, ref y2);
                    // Write the coords to 3 decimal places.
                    Console.WriteLine("    Coords: x1={0:N2}, y1={1:N2}, x2={2:N2}, y2={3:N2}", ctm.m_h, ctm.m_v, x2, y2);
                    pdftron.PDF.Image image = null;
                    if (element.GetType() == Element.Type.e_image)
                    {
                        image = new pdftron.PDF.Image(element.GetXObject());
                        // Convert PDF bitmap to GDI+ Bitmap...
                        //Bitmap bmp = element.GetBitmap();
                        //bmp.Save(fname, ImageFormat.Png);
                        //bmp.Dispose();

                        // Instead of converting PDF images to a Bitmap, you can also extract
                        // uncompressed/compressed image data directly using element.GetImageData()
                        // as illustrated in ElementReaderAdv sample project.
                    }
                    else                             // inline image
                    {
                        if (y1 > y2)
                        {
                            byte[] flipped_image = FlipImage(element);
                            image = pdftron.PDF.Image.Create(doc, flipped_image, element.GetImageWidth(), element.GetImageHeight(), 8, ColorSpace.CreateDeviceRGB());
                        }
                        else
                        {
                            Image2RGB    image2rgb    = new Image2RGB(element);
                            FilterReader image_reader = new FilterReader(image2rgb);
                            image = pdftron.PDF.Image.Create(doc, image_reader, element.GetImageWidth(), element.GetImageHeight(), 8, ColorSpace.CreateDeviceRGB());
                        }
                    }
                    string fname = output_path + "image_extract1_" + image_counter.ToString();
                    image.Export(fname);                              // or ExporAsPng() or ExporAsTiff() ...
                    break;
                }

                case Element.Type.e_form:                         // Process form XObjects
                {
                    reader.FormBegin();
                    ImageExtract(doc, reader);
                    reader.End();
                    break;
                }
                }
            }
        }