private static BufferedImage alterRasterCMYK2BGRA(WritableRaster wr,
                                                      BufferedImage smaskImage,
                                                      BufferedImage maskImage) {

        int width = wr.getWidth();
        int height = wr.getHeight();

        Raster smaskRaster = null;
        int smaskWidth = 0;
        int smaskHeight = 0;
        if (smaskImage != null) {
            smaskRaster = smaskImage.getRaster();
            smaskWidth = smaskRaster.getWidth();
            smaskHeight = smaskRaster.getHeight();
            // If smask is larger then the image, and needs to be scaled to match the image.
            if (width < smaskWidth || height < smaskHeight) {
                // calculate scale factors.
                double scaleX = width / (double) smaskWidth;
                double scaleY = height / (double) smaskHeight;
                // scale the mask to match the base image.
                AffineTransform tx = new AffineTransform();
                tx.scale(scaleX, scaleY);
                AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
                BufferedImage sbim = op.filter(smaskImage, null);
                smaskImage.flush();
                smaskImage = sbim;
            }
            // update the new deminsions.
            smaskRaster = smaskImage.getRaster();
            smaskWidth = smaskRaster.getWidth();
            smaskHeight = smaskRaster.getHeight();
        }

        Raster maskRaster = null;
        int maskWidth = 0;
        int maskHeight = 0;
        if (maskImage != null) {
            maskRaster = maskImage.getRaster();
            maskWidth = maskRaster.getWidth();
            maskHeight = maskRaster.getHeight();
        }

        // this convoluted cymk->rgba method is from DeviceCMYK class.
        float inCyan, inMagenta, inYellow, inBlack;
        float lastCyan = -1, lastMagenta = -1, lastYellow = -1, lastBlack = -1;
        double c, m, y2, aw, ac, am, ay, ar, ag, ab;
        float outRed, outGreen, outBlue;
        int rValue = 0, gValue = 0, bValue = 0, alpha = 0;
        int[] values = new int[4];

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                wr.getPixel(x, y, values);

                inCyan = values[0] / 255.0f;
                inMagenta = values[1] / 255.0f;
                inYellow = values[2] / 255.0f;
                // lessen the amount of black, standard 255 fraction is too dark
                // increasing the denominator has the same affect of lighting up
                // the image.
                inBlack = (values[3] / 768.0f);

                if (!(inCyan == lastCyan && inMagenta == lastMagenta &&
                        inYellow == lastYellow && inBlack == lastBlack)){

                    c = clip(0, 1, inCyan + inBlack);
                    m = clip(0, 1, inMagenta + inBlack);
                    y2 = clip(0, 1, inYellow + inBlack);
                    aw = (1 - c) * (1 - m) * (1 - y2);
                    ac = c * (1 - m) * (1 - y2);
                    am = (1 - c) * m * (1 - y2);
                    ay = (1 - c) * (1 - m) * y2;
                    ar = (1 - c) * m * y2;
                    ag = c * (1 - m) * y2;
                    ab = c * m * (1 - y2);

                    outRed = (float)clip(0, 1, aw + 0.9137 * am + 0.9961 * ay + 0.9882 * ar);
                    outGreen = (float)clip(0, 1, aw + 0.6196 * ac + ay + 0.5176 * ag);
                    outBlue = (float)clip(0, 1, aw + 0.7804 * ac + 0.5412 * am + 0.0667 * ar + 0.2118 * ag + 0.4863 * ab);
                    rValue = (int) (outRed * 255);
                    gValue = (int) (outGreen * 255);
                    bValue = (int) (outBlue * 255);
                    alpha = 0xFF;
                }
                lastCyan = inCyan;
                lastMagenta  = inMagenta;
                lastYellow = inYellow;
                lastBlack =  inBlack;

                // this fits into the larger why are we doing this on a case by case basis.
                if (y < smaskHeight && x < smaskWidth && smaskRaster != null){
                    alpha = (smaskRaster.getSample(x, y, 0) & 0xFF);
                }else if (y < maskHeight && x < maskWidth && maskRaster != null) {
                    // When making an ImageMask, the alpha channel is setup so that
                    //  it both works correctly for the ImageMask being painted,
                    //  and also for when it's used here, to determine the alpha
                    //  of an image that it's masking
                    alpha = (maskImage.getRGB(x, y) >>> 24) & 0xFF; // Extract Alpha from ARGB
                }
                values[redIndex] = rValue;
                values[1] = gValue;
                values[blueIndex] = bValue;
                values[3] = alpha;
                wr.setPixel(x, y, values);
            }
        }
        // apply the soft mask, but first we need an rgba image,
        // this is pretty expensive, would like to find quicker method.
        BufferedImage tmpImage = makeRGBABufferedImage(wr);
        if (smaskImage != null) {
            BufferedImage argbImage = new BufferedImage(width,
                    height, BufferedImage.TYPE_INT_ARGB);
            int[] srcBand = new int[width];
            int[] sMaskBand = new int[width];
            // iterate over each band to apply the mask
            for (int i = 0; i < height; i++) {
                tmpImage.getRGB(0, i, width, 1, srcBand, 0, width);
                smaskImage.getRGB(0, i, width, 1, sMaskBand, 0, width);
                // apply the soft mask blending
                for (int j = 0; j < width; j++) {
                    sMaskBand[j] = ((sMaskBand[j] & 0xff) << 24)
                            | (srcBand[j] & ~0xff000000);
                }
                argbImage.setRGB(0, i, width, 1, sMaskBand, 0, width);
            }
            tmpImage.flush();
            tmpImage = argbImage;
        }
        return tmpImage;
    }