private final int ippFilter()

in modules/awt/src/main/java/common/java/awt/image/LookupOp.java [362:552]


    private final int ippFilter(
            Raster src, WritableRaster dst,
            int imageType, boolean skipAlpha
    ) {
        int res;

        int srcStride, dstStride;
        int channels;
        int offsets[] = null;
        int channelsOrder[] = null;

        switch (imageType) {
            case BufferedImage.TYPE_INT_ARGB:
            case BufferedImage.TYPE_INT_ARGB_PRE:
            case BufferedImage.TYPE_INT_RGB: {
                channels = 4;
                srcStride = src.getWidth()*4;
                dstStride = dst.getWidth()*4;
                channelsOrder = new int[] {2, 1, 0, 3};
                break;
            }

            case BufferedImage.TYPE_4BYTE_ABGR:
            case BufferedImage.TYPE_4BYTE_ABGR_PRE:
            case BufferedImage.TYPE_INT_BGR: {
                channels = 4;
                srcStride = src.getWidth()*4;
                dstStride = dst.getWidth()*4;
                break;
            }

            case BufferedImage.TYPE_BYTE_GRAY: {
                channels = 1;
                srcStride = src.getWidth();
                dstStride = dst.getWidth();
                break;
            }

            case BufferedImage.TYPE_3BYTE_BGR: {
                channels = 3;
                srcStride = src.getWidth()*3;
                dstStride = dst.getWidth()*3;
                channelsOrder = new int[] {2, 1, 0};
                break;
            }

            case BufferedImage.TYPE_USHORT_GRAY:
            case BufferedImage.TYPE_USHORT_565_RGB:
            case BufferedImage.TYPE_USHORT_555_RGB:
            case BufferedImage.TYPE_BYTE_BINARY: {
                return slowFilter(src, dst, skipAlpha);
            }

            default: {
                SampleModel srcSM = src.getSampleModel();
                SampleModel dstSM = dst.getSampleModel();

                if (
                        srcSM instanceof PixelInterleavedSampleModel &&
                        dstSM instanceof PixelInterleavedSampleModel
                ) {
                    // Check PixelInterleavedSampleModel
                    if (
                            srcSM.getDataType() != DataBuffer.TYPE_BYTE ||
                            dstSM.getDataType() != DataBuffer.TYPE_BYTE
                    ) {
                        return slowFilter(src, dst, skipAlpha);
                    }

                    // Have IPP functions for 1, 3 and 4 channels
                    channels = srcSM.getNumBands();
                    if (!(channels == 1 || channels == 3 || channels == 4)) {
                        return slowFilter(src, dst, skipAlpha);
                    }

                    srcStride = ((ComponentSampleModel) srcSM).getScanlineStride();
                    dstStride = ((ComponentSampleModel) dstSM).getScanlineStride();

                    channelsOrder = ((ComponentSampleModel) srcSM).getBandOffsets();
                } else if (
                        srcSM instanceof SinglePixelPackedSampleModel &&
                        dstSM instanceof SinglePixelPackedSampleModel
                ) {
                    // Check SinglePixelPackedSampleModel
                    SinglePixelPackedSampleModel sppsm1 =
                            (SinglePixelPackedSampleModel) srcSM;
                    SinglePixelPackedSampleModel sppsm2 =
                            (SinglePixelPackedSampleModel) dstSM;

                    channels = sppsm1.getNumBands();

                     // TYPE_INT_RGB, TYPE_INT_ARGB...
                    if (
                            sppsm1.getDataType() != DataBuffer.TYPE_INT ||
                            sppsm2.getDataType() != DataBuffer.TYPE_INT ||
                            !(channels == 3 || channels == 4)
                    ) {
                        return slowFilter(src, dst, skipAlpha);
                    }

                    // Check compatibility of sample models
                    if (
                            !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) ||
                            !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())
                    ) {
                        return slowFilter(src, dst, skipAlpha);
                    }

                    for (int i=0; i<channels; i++) {
                        if (sppsm1.getSampleSize(i) != 8) {
                            return slowFilter(src, dst, skipAlpha);
                        }
                    }

                    channelsOrder = new int[channels];
                    int bitOffsets[] = sppsm1.getBitOffsets();
                    for (int i=0; i<channels; i++) {
                        channelsOrder[i] = bitOffsets[i] / 8;
                    }

                    if (channels == 3) { // Don't skip channel now, could be optimized
                        channels = 4;
                    }

                    srcStride = sppsm1.getScanlineStride() * 4;
                    dstStride = sppsm2.getScanlineStride() * 4;
                } else {
                    return slowFilter(src, dst, skipAlpha);
                }

                // Fill offsets if there's a child raster
                if (src.getParent() != null || dst.getParent() != null) {
                    if (
                            src.getSampleModelTranslateX() != 0 ||
                            src.getSampleModelTranslateY() != 0 ||
                            dst.getSampleModelTranslateX() != 0 ||
                            dst.getSampleModelTranslateY() != 0
                    ) {
                        offsets = new int[4];
                        offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
                        offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
                        offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
                        offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
                    }
                }
            }
        }

        int levels[] = null, values[] = null;
        int channelMultiplier = skipAlpha ? -1 : 1;
        if (channelMultiplier*channels == validForChannels) { // use existing levels/values
            levels = cachedLevels;
            values = cachedValues;
        } else { // create new levels/values
            if (lut instanceof ByteLookupTable) {
                byte data[][] = ((ByteLookupTable)lut).getTable();
                levels = new int[channels*data[0].length];
                values = new int[channels*data[0].length];
                createByteLevels(channels, skipAlpha, levels, values, channelsOrder);
            } else if (lut instanceof ShortLookupTable) {
                short data[][] = ((ShortLookupTable)lut).getTable();
                levels = new int[channels*data[0].length];
                values = new int[channels*data[0].length];
                createShortLevels(channels, skipAlpha, levels, values, channelsOrder);
            }

            // cache levels/values
            validForChannels = channelMultiplier*channels;
            cachedLevels = levels;
            cachedValues = values;
        }

        Object srcData, dstData;
        AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
        try {
            srcData = dbAccess.getData(src.getDataBuffer());
            dstData = dbAccess.getData(dst.getDataBuffer());
        } catch (IllegalArgumentException e) {
            return -1; // Unknown data buffer type
        }

        res = ippLUT(
            srcData, src.getWidth(), src.getHeight(), srcStride,
            dstData, dst.getWidth(), dst.getHeight(), dstStride,
            levels, values,
            channels, offsets,
            false
        );

        return res;
    }