Пример #1
0
  public WritableRaster copyData(WritableRaster wr) {
    // Get my source.
    CachableRed srcRed = (CachableRed) getSources().get(0);
    CachableRed alphaRed = (CachableRed) getSources().get(1);

    if (is_INT_PACK_BYTE_COMP(srcRed.getSampleModel(), alphaRed.getSampleModel()))
      return INT_PACK_BYTE_COMP_Impl(wr);

    ColorModel cm = srcRed.getColorModel();
    if (cm.hasAlpha()) {
      // Already has alpha channel so we use it.
      srcRed.copyData(wr);

      Rectangle rgn = wr.getBounds();
      if (rgn.intersects(alphaRed.getBounds())) rgn = rgn.intersection(alphaRed.getBounds());
      else return wr;

      int[] wrData = null;
      int[] alphaData = null;

      Raster r = alphaRed.getData(rgn);
      int w = rgn.width;

      final int bands = wr.getSampleModel().getNumBands();

      if (cm.isAlphaPremultiplied()) {
        for (int y = rgn.y; y < rgn.y + rgn.height; y++) {
          wrData = wr.getPixels(rgn.x, y, w, 1, wrData);
          alphaData = r.getSamples(rgn.x, y, w, 1, 0, alphaData);
          int i = 0, a, b;
          // 4 is the most common case.
          // 2 is probably next most common...
          switch (bands) {
            case 2:
              for (int x = 0; x < alphaData.length; x++) {
                a = alphaData[x] & 0xFF;
                wrData[i] = ((wrData[i] & 0xFF) * a) >> 8;
                ++i;
                wrData[i] = ((wrData[i] & 0xFF) * a) >> 8;
                ++i;
              }
              break;
            case 4:
              for (int x = 0; x < alphaData.length; x++) {
                a = alphaData[x] & 0xFF;
                wrData[i] = ((wrData[i] & 0xFF) * a) >> 8;
                ++i;
                wrData[i] = ((wrData[i] & 0xFF) * a) >> 8;
                ++i;
                wrData[i] = ((wrData[i] & 0xFF) * a) >> 8;
                ++i;
                wrData[i] = ((wrData[i] & 0xFF) * a) >> 8;
                ++i;
              }
              break;
            default:
              for (int x = 0; x < alphaData.length; x++) {
                a = alphaData[x] & 0xFF;
                for (b = 0; b < bands; b++) {
                  wrData[i] = ((wrData[i] & 0xFF) * a) >> 8;
                  ++i;
                }
              }
          }
          wr.setPixels(rgn.x, y, w, 1, wrData);
        }
      } else {
        int b = srcRed.getSampleModel().getNumBands() - 1;
        for (int y = rgn.y; y < rgn.y + rgn.height; y++) {
          wrData = wr.getSamples(rgn.x, y, w, 1, b, wrData);
          alphaData = r.getSamples(rgn.x, y, w, 1, 0, alphaData);
          for (int i = 0; i < wrData.length; i++) {
            wrData[i] = ((wrData[i] & 0xFF) * (alphaData[i] & 0xFF)) >> 8;
          }
          wr.setSamples(rgn.x, y, w, 1, b, wrData);
        }
      }

      return wr;
    }

    // No alpha in source, so we hide the alpha channel in wr and
    // have our source fill wr with color info...
    int[] bands = new int[wr.getNumBands() - 1];
    for (int i = 0; i < bands.length; i++) bands[i] = i;

    WritableRaster subWr;
    subWr =
        wr.createWritableChild(
            wr.getMinX(),
            wr.getMinY(),
            wr.getWidth(),
            wr.getHeight(),
            wr.getMinX(),
            wr.getMinY(),
            bands);

    srcRed.copyData(subWr);

    Rectangle rgn = wr.getBounds();
    rgn = rgn.intersection(alphaRed.getBounds());

    bands = new int[] {wr.getNumBands() - 1};
    subWr = wr.createWritableChild(rgn.x, rgn.y, rgn.width, rgn.height, rgn.x, rgn.y, bands);
    alphaRed.copyData(subWr);

    return wr;
  }