예제 #1
0
  /**
   * Checks if the specified {@code SampleModel} is compatible with this {@code ColorModel}. If
   * {@code sm} is {@code null}, this method returns {@code false}.
   *
   * @param sm the specified {@code SampleModel}, or {@code null}
   * @return {@code true} if the specified {@code SampleModel} is compatible with this {@code
   *     ColorModel}; {@code false} otherwise.
   * @see SampleModel
   */
  public boolean isCompatibleSampleModel(SampleModel sm) {
    if (!(sm instanceof SinglePixelPackedSampleModel)) {
      return false;
    }

    // Must have the same number of components
    if (numComponents != sm.getNumBands()) {
      return false;
    }

    // Transfer type must be the same
    if (sm.getTransferType() != transferType) {
      return false;
    }

    SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sm;
    // Now compare the specific masks
    int[] bitMasks = sppsm.getBitMasks();
    if (bitMasks.length != maskArray.length) {
      return false;
    }

    /* compare 'effective' masks only, i.e. only part of the mask
     * which fits the capacity of the transfer type.
     */
    int maxMask = (int) ((1L << DataBuffer.getDataTypeSize(transferType)) - 1);
    for (int i = 0; i < bitMasks.length; i++) {
      if ((maxMask & bitMasks[i]) != (maxMask & maskArray[i])) {
        return false;
      }
    }

    return true;
  }
예제 #2
0
 /**
  * Returns a width- and height-aligned image representation sharing data w/ {@link #image}.
  *
  * @param width
  * @param height
  * @return
  * @throws IllegalArgumentException if requested size exceeds image size
  */
 public BufferedImage getAlignedImage(int width, int height) throws IllegalArgumentException {
   if (width * height > image.getWidth() * image.getHeight()) {
     throw new IllegalArgumentException(
         "Requested size exceeds image size: "
             + width
             + "x"
             + height
             + " > "
             + image.getWidth()
             + "x"
             + image.getHeight());
   }
   if (width == image.getWidth() && height == image.getHeight()) {
     return image;
   } else {
     final ColorModel cm = image.getColorModel();
     final WritableRaster raster0 = image.getRaster();
     final DataBuffer dataBuffer = raster0.getDataBuffer();
     final SinglePixelPackedSampleModel sppsm0 =
         (SinglePixelPackedSampleModel) raster0.getSampleModel();
     final SinglePixelPackedSampleModel sppsm1 =
         new SinglePixelPackedSampleModel(
             dataBuffer.getDataType(),
             width,
             height,
             width /* scanLineStride */,
             sppsm0.getBitMasks());
     final WritableRaster raster1 = WritableRaster.createWritableRaster(sppsm1, dataBuffer, null);
     return new BufferedImage(cm, raster1, cm.isAlphaPremultiplied(), null);
   }
 }
예제 #3
0
  private void writeSinglePixelPackedSampleModel(DataOutput out, SinglePixelPackedSampleModel model)
      throws IOException {

    int[] masks = model.getBitMasks();
    out.writeInt(masks.length);
    for (int i = 0; i < masks.length; i++) out.writeInt(masks[i]);

    out.writeInt(model.getDataType());
    out.writeInt(model.getWidth());
    out.writeInt(model.getHeight());
    out.writeInt(model.getScanlineStride());
  }
예제 #4
0
  public static boolean is_INT_PACK_Data(SampleModel sm, boolean requireAlpha) {
    // Check ColorModel is of type DirectColorModel
    if (!(sm instanceof SinglePixelPackedSampleModel)) return false;

    // Check transfer type
    if (sm.getDataType() != DataBuffer.TYPE_INT) return false;

    SinglePixelPackedSampleModel sppsm;
    sppsm = (SinglePixelPackedSampleModel) sm;

    int[] masks = sppsm.getBitMasks();
    if (masks.length == 3) {
      if (requireAlpha) return false;
    } else if (masks.length != 4) return false;

    if (masks[0] != 0x00ff0000) return false;
    if (masks[1] != 0x0000ff00) return false;
    if (masks[2] != 0x000000ff) return false;
    return !((masks.length == 4) && (masks[3] != 0xff000000));
  }
  /**
   * Ipp filter.
   *
   * @param src the src.
   * @param dst the dst.
   * @param imageType the image type.
   * @return the int.
   */
  @SuppressWarnings("unused")
  private int ippFilter(Raster src, WritableRaster dst, int imageType) {
    int srcStride, dstStride;
    boolean skipChannel = false;
    int channels;
    int offsets[] = null;

    switch (imageType) {
      case BufferedImage.TYPE_INT_RGB:
      case BufferedImage.TYPE_INT_BGR:
        {
          channels = 4;
          srcStride = src.getWidth() * 4;
          dstStride = dst.getWidth() * 4;
          skipChannel = true;
          break;
        }

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

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

      case BufferedImage.TYPE_3BYTE_BGR:
        {
          channels = 3;
          srcStride = src.getWidth() * 3;
          dstStride = dst.getWidth() * 3;
          break;
        }

      case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in
        // native code?
      case BufferedImage.TYPE_USHORT_565_RGB:
      case BufferedImage.TYPE_USHORT_555_RGB:
      case BufferedImage.TYPE_BYTE_BINARY:
        {
          return slowFilter(src, dst);
        }

      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);
            }

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

            int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8;

            srcStride = ((ComponentSampleModel) srcSM).getScanlineStride() * dataTypeSize;
            dstStride = ((ComponentSampleModel) dstSM).getScanlineStride() * dataTypeSize;
          } else if (srcSM instanceof SinglePixelPackedSampleModel
              && dstSM instanceof SinglePixelPackedSampleModel) {
            // Check SinglePixelPackedSampleModel
            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
            SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;

            // No IPP function for this type
            if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) {
              return slowFilter(src, dst);
            }

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

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

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

            if (channels == 3) {
              channels = 4;
            }

            int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8;

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

          // 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();
            }
          }
        }
    }

    double m00 = at.getScaleX();
    double m01 = at.getShearX();
    double m02 = at.getTranslateX();
    double m10 = at.getShearY();
    double m11 = at.getScaleY();
    double m12 = at.getTranslateY();

    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
    }

    return ippAffineTransform(
        m00,
        m01,
        m02,
        m10,
        m11,
        m12,
        srcData,
        src.getWidth(),
        src.getHeight(),
        srcStride,
        dstData,
        dst.getWidth(),
        dst.getHeight(),
        dstStride,
        iType,
        channels,
        skipChannel,
        offsets);
  }
예제 #6
0
  public WritableRaster copyData(WritableRaster wr) {
    // Get my source.
    CachableRed src = (CachableRed) getSources().get(0);
    ColorModel srcCM = src.getColorModel();
    SampleModel srcSM = src.getSampleModel();

    // Fast case, SRGB source, INT Pack writable raster...
    if (srcIssRGB && Any2sRGBRed.is_INT_PACK_COMP(wr.getSampleModel())) {
      src.copyData(wr);
      if (srcCM.hasAlpha()) GraphicsUtil.coerceData(wr, srcCM, false);
      Any2sRGBRed.applyLut_INT(wr, sRGBToLsRGBLut);
      return wr;
    }

    if (srcCM == null) {
      // We don't really know much about this source, let's
      // guess based on the number of bands...

      float[][] matrix = null;
      switch (srcSM.getNumBands()) {
        case 1:
          matrix = new float[1][3];
          matrix[0][0] = 1; // Red
          matrix[0][1] = 1; // Grn
          matrix[0][2] = 1; // Blu
          break;
        case 2:
          matrix = new float[2][4];
          matrix[0][0] = 1; // Red
          matrix[0][1] = 1; // Grn
          matrix[0][2] = 1; // Blu
          matrix[1][3] = 1; // Alpha
          break;
        case 3:
          matrix = new float[3][3];
          matrix[0][0] = 1; // Red
          matrix[1][1] = 1; // Grn
          matrix[2][2] = 1; // Blu
          break;
        default:
          matrix = new float[srcSM.getNumBands()][4];
          matrix[0][0] = 1; // Red
          matrix[1][1] = 1; // Grn
          matrix[2][2] = 1; // Blu
          matrix[3][3] = 1; // Alpha
          break;
      }

      Raster srcRas = src.getData(wr.getBounds());
      BandCombineOp op = new BandCombineOp(matrix, null);
      op.filter(srcRas, wr);
    } else {
      ColorModel dstCM = getColorModel();
      BufferedImage dstBI;

      if (!dstCM.hasAlpha()) {
        // No alpha ao we don't have to work around the bug
        // in the color convert op.
        dstBI =
            new BufferedImage(
                dstCM, wr.createWritableTranslatedChild(0, 0), dstCM.isAlphaPremultiplied(), null);
      } else {
        // All this nonsense is to work around the fact that
        // the Color convert op doesn't properly copy the
        // Alpha from src to dst.
        SinglePixelPackedSampleModel dstSM;
        dstSM = (SinglePixelPackedSampleModel) wr.getSampleModel();
        int[] masks = dstSM.getBitMasks();
        SampleModel dstSMNoA =
            new SinglePixelPackedSampleModel(
                dstSM.getDataType(),
                dstSM.getWidth(),
                dstSM.getHeight(),
                dstSM.getScanlineStride(),
                new int[] {masks[0], masks[1], masks[2]});
        ColorModel dstCMNoA = GraphicsUtil.Linear_sRGB;

        WritableRaster dstWr;
        dstWr = Raster.createWritableRaster(dstSMNoA, wr.getDataBuffer(), new Point(0, 0));
        dstWr =
            dstWr.createWritableChild(
                wr.getMinX() - wr.getSampleModelTranslateX(),
                wr.getMinY() - wr.getSampleModelTranslateY(),
                wr.getWidth(),
                wr.getHeight(),
                0,
                0,
                null);

        dstBI = new BufferedImage(dstCMNoA, dstWr, false, null);
      }

      // Divide out alpha if we have it.  We need to do this since
      // the color convert may not be a linear operation which may
      // lead to out of range values.
      ColorModel srcBICM = srcCM;
      WritableRaster srcWr;
      if ((srcCM.hasAlpha() == true) && (srcCM.isAlphaPremultiplied() != false)) {
        Rectangle wrR = wr.getBounds();
        SampleModel sm = srcCM.createCompatibleSampleModel(wrR.width, wrR.height);

        srcWr = Raster.createWritableRaster(sm, new Point(wrR.x, wrR.y));
        src.copyData(srcWr);
        srcBICM = GraphicsUtil.coerceData(srcWr, srcCM, false);
      } else {
        Raster srcRas = src.getData(wr.getBounds());
        srcWr = GraphicsUtil.makeRasterWritable(srcRas);
      }

      BufferedImage srcBI;
      srcBI = new BufferedImage(srcBICM, srcWr.createWritableTranslatedChild(0, 0), false, null);

      /*
       * System.out.println("src: " + srcBI.getWidth() + "x" +
       *                    srcBI.getHeight());
       * System.out.println("dst: " + dstBI.getWidth() + "x" +
       *                    dstBI.getHeight());
       */

      ColorConvertOp op = new ColorConvertOp(null);
      op.filter(srcBI, dstBI);

      if (dstCM.hasAlpha())
        copyBand(
            srcWr, srcSM.getNumBands() - 1,
            wr, getSampleModel().getNumBands() - 1);
    }
    return wr;
  }