public static PDImageXObject createFromImage(PDDocument document, BufferedImage image)
            throws IOException
    {
        if (isGrayImage(image))
        {
            return createFromGrayImage(image, document);
        }

        // We try to encode the image with predictor
        if (USE_PREDICTOR_ENCODER)
        {
            PDImageXObject pdImageXObject = new PredictorEncoder(document, image).encode();
            if (pdImageXObject != null)
            {
                if (pdImageXObject.getColorSpace() == PDDeviceRGB.INSTANCE &&
                    pdImageXObject.getBitsPerComponent() < 16 &&
                    image.getWidth() * image.getHeight() <= 50 * 50)
                {
                    // also create classic compressed image, compare sizes
                    PDImageXObject pdImageXObjectClassic = createFromRGBImage(image, document);
                    if (pdImageXObjectClassic.getCOSObject().getLength() < 
                        pdImageXObject.getCOSObject().getLength())
                    {
                        pdImageXObject.getCOSObject().close();
                        return pdImageXObjectClassic;
                    }
                    else
                    {
                        pdImageXObjectClassic.getCOSObject().close();
                    }
                }
                return pdImageXObject;
            }
        }

        // Fallback: We export the image as 8-bit sRGB and might lose color information
        return createFromRGBImage(image, document);
    }
@Test
    void testCreateLosslessFromImage4BYTE_ABGR() throws IOException
    {
        PDDocument document = new PDDocument();
        BufferedImage image = ImageIO.read(this.getClass().getResourceAsStream("png.png"));

        // create an ARGB image
        int w = image.getWidth();
        int h = image.getHeight();
        BufferedImage argbImage = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics ag = argbImage.getGraphics();
        ag.drawImage(image, 0, 0, null);
        ag.dispose();

        for (int x = 0; x < argbImage.getWidth(); ++x)
        {
            for (int y = 0; y < argbImage.getHeight(); ++y)
            {
                argbImage.setRGB(x, y, (argbImage.getRGB(x, y) & 0xFFFFFF) | ((y / 10 * 10) << 24));
            }
        }

        // extra for PDFBOX-3181: check for exception due to different sizes of 
        // alphaRaster.getSampleModel().getWidth()
        // and
        // alphaRaster.getWidth()
        // happens with image returned by BufferedImage.getSubimage()
        argbImage = argbImage.getSubimage(1, 1, argbImage.getWidth() - 2, argbImage.getHeight() - 2);
        w -= 2;
        h -= 2;

        PDImageXObject ximage = LosslessFactory.createFromImage(document, argbImage);

        validate(ximage, 8, w, h, "png", PDDeviceRGB.INSTANCE.getName());
        checkIdent(argbImage, ximage.getImage());
        checkIdentRGB(argbImage, ximage.getOpaqueImage(null, 1));

        assertNotNull(ximage.getSoftMask());
        validate(ximage.getSoftMask(), 8, w, h, "png", PDDeviceGray.INSTANCE.getName());
        assertTrue(colorCount(ximage.getSoftMask().getImage()) > image.getHeight() / 10);

        doWritePDF(document, ximage, TESTRESULTSDIR, "4babgr.pdf");
    }