public final BufferedImage filter(BufferedImage src, BufferedImage dst) {
    if (src == dst) {
      // awt.252=Source can't be same as the destination
      throw new IllegalArgumentException(Messages.getString("awt.252")); // $NON-NLS-1$
    }

    ColorModel srcCM = src.getColorModel();
    BufferedImage finalDst = null;

    if (srcCM instanceof IndexColorModel
        && (iType != TYPE_NEAREST_NEIGHBOR || srcCM.getPixelSize() % 8 != 0)) {
      src = ((IndexColorModel) srcCM).convertToIntDiscrete(src.getRaster(), true);
      srcCM = src.getColorModel();
    }

    if (dst == null) {
      dst = createCompatibleDestImage(src, srcCM);
    } else {
      if (!srcCM.equals(dst.getColorModel())) {
        // Treat BufferedImage.TYPE_INT_RGB and
        // BufferedImage.TYPE_INT_ARGB as same
        if (!((src.getType() == BufferedImage.TYPE_INT_RGB
                || src.getType() == BufferedImage.TYPE_INT_ARGB)
            && (dst.getType() == BufferedImage.TYPE_INT_RGB
                || dst.getType() == BufferedImage.TYPE_INT_ARGB))) {
          finalDst = dst;
          dst = createCompatibleDestImage(src, srcCM);
        }
      }
    }

    // Skip alpha channel for TYPE_INT_RGB images
    if (slowFilter(src.getRaster(), dst.getRaster()) != 0) {
      // awt.21F=Unable to transform source
      throw new ImagingOpException(Messages.getString("awt.21F")); // $NON-NLS-1$
      // TODO - uncomment
      // if (ippFilter(src.getRaster(), dst.getRaster(), src.getType()) !=
      // 0)
      // throw new ImagingOpException ("Unable to transform source");
    }

    if (finalDst != null) {
      Graphics2D g = finalDst.createGraphics();
      g.setComposite(AlphaComposite.Src);
      g.drawImage(dst, 0, 0, null);
    } else {
      finalDst = dst;
    }

    return finalDst;
  }