Пример #1
0
  /**
   * This function 'fixes' the source's color model. Right now it just selects if it should have one
   * or two bands based on if the source had an alpha channel.
   */
  protected static ColorModel fixColorModel(CachableRed src) {
    ColorModel cm = src.getColorModel();
    if (cm != null) {
      if (cm.hasAlpha()) return GraphicsUtil.Linear_sRGB_Unpre;

      return GraphicsUtil.Linear_sRGB;
    } else {
      // No ColorModel so try to make some intelligent
      // decisions based just on the number of bands...
      // 1 bands -> replicated into RGB
      // 2 bands -> Band 0 replicated into RGB & Band 1 -> alpha premult
      // 3 bands -> sRGB (not-linear?)
      // 4 bands -> sRGB premult (not-linear?)
      SampleModel sm = src.getSampleModel();

      switch (sm.getNumBands()) {
        case 1:
          return GraphicsUtil.Linear_sRGB;
        case 2:
          return GraphicsUtil.Linear_sRGB_Unpre;
        case 3:
          return GraphicsUtil.Linear_sRGB;
      }
      return GraphicsUtil.Linear_sRGB_Unpre;
    }
  }
Пример #2
0
  /**
   * This function 'fixes' the source's sample model. Right now it just selects if it should have 3
   * or 4 bands based on if the source had an alpha channel.
   */
  protected static SampleModel fixSampleModel(CachableRed src) {
    SampleModel sm = src.getSampleModel();
    ColorModel cm = src.getColorModel();

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

    boolean alpha = false;

    if (cm != null) alpha = cm.hasAlpha();
    else {
      switch (sm.getNumBands()) {
        case 1:
        case 3:
          alpha = false;
          break;
        default:
          alpha = true;
          break;
      }
    }
    if (alpha)
      return new SinglePixelPackedSampleModel(
          DataBuffer.TYPE_INT,
          sm.getWidth(),
          sm.getHeight(),
          new int[] {0xFF0000, 0xFF00, 0xFF, 0xFF000000});
    else
      return new SinglePixelPackedSampleModel(
          DataBuffer.TYPE_INT, sm.getWidth(), sm.getHeight(), new int[] {0xFF0000, 0xFF00, 0xFF});
  }
Пример #3
0
  public AffineRed(CachableRed src, AffineTransform src2me, RenderingHints hints) {
    super(); // We _must_ call init...

    this.src2me = src2me;
    this.hints = hints;

    try {
      me2src = src2me.createInverse();
    } catch (NoninvertibleTransformException nite) {
      me2src = null;
    }

    // Calculate my bounds by applying the affine transform to
    // my input data..codec/
    Rectangle srcBounds = src.getBounds();
    // srcBounds.grow(-1,-1);
    Rectangle myBounds;
    myBounds = src2me.createTransformedShape(srcBounds).getBounds();

    // If the output buffer is not premultiplied in certain cases it
    // fails to properly divide out the Alpha (it always does
    // the affine on premultiplied data), hence you get ugly
    // back aliasing effects...
    ColorModel cm = fixColorModel(src);

    // fix my sample model so it makes sense given my size.
    SampleModel sm = fixSampleModel(src, cm, myBounds);

    Point2D pt = new Point2D.Float(src.getTileGridXOffset(), src.getTileGridYOffset());
    pt = src2me.transform(pt, null);

    // Finish initializing our base class...
    init(src, myBounds, cm, sm, (int) pt.getX(), (int) pt.getY(), null);
  }
Пример #4
0
  protected static ColorModel fixColorModel(CachableRed src) {
    ColorModel cm = src.getColorModel();

    if (cm.hasAlpha()) {
      if (!cm.isAlphaPremultiplied()) cm = GraphicsUtil.coerceColorModel(cm, true);
      return cm;
    }

    ColorSpace cs = cm.getColorSpace();

    int b = src.getSampleModel().getNumBands() + 1;
    if (b == 4) {
      int[] masks = new int[4];
      for (int i = 0; i < b - 1; i++) masks[i] = 0xFF0000 >> (8 * i);
      masks[3] = 0xFF << (8 * (b - 1));

      return new DirectColorModel(
          cs, 8 * b, masks[0], masks[1], masks[2], masks[3], true, DataBuffer.TYPE_INT);
    }

    int[] bits = new int[b];
    for (int i = 0; i < b; i++) bits[i] = 8;
    return new ComponentColorModel(
        cs, bits, true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_INT);
  }
Пример #5
0
  public WritableRaster copyData(WritableRaster wr) {
    // Get my source.
    CachableRed src = (CachableRed) getSources().get(0);

    Rectangle srcR = src.getBounds();
    Rectangle wrR = wr.getBounds();

    if (wrR.intersects(srcR)) {
      Rectangle r = wrR.intersection(srcR);

      // Limit the raster I send to my source to his rect.
      WritableRaster srcWR;
      srcWR = wr.createWritableChild(r.x, r.y, r.width, r.height, r.x, r.y, null);
      src.copyData(srcWR);
    }

    if (padMode == PadMode.ZERO_PAD) {
      handleZero(wr);
    } else if (padMode == PadMode.REPLICATE) {
      handleReplicate(wr);
    } else if (padMode == PadMode.WRAP) {
      handleWrap(wr);
    }

    return wr;
  }
Пример #6
0
  protected static ColorModel fixColorModel(CachableRed src) {
    ColorModel cm = src.getColorModel();

    int b = src.getSampleModel().getNumBands();
    int[] masks = new int[4];
    switch (b) {
      case 1:
        masks[0] = 0xFF;
        break;
      case 2:
        masks[0] = 0x00FF;
        masks[3] = 0xFF00;
        break;
      case 3:
        masks[0] = 0xFF0000;
        masks[1] = 0x00FF00;
        masks[2] = 0x0000FF;
        break;
      case 4:
        masks[0] = 0x00FF0000;
        masks[1] = 0x0000FF00;
        masks[2] = 0x000000FF;
        masks[3] = 0xFF000000;
        break;
      default:
        throw new IllegalArgumentException(
            "GaussianBlurRed8Bit only supports one to four band images");
    }
    ColorSpace cs = cm.getColorSpace();
    return new DirectColorModel(
        cs, 8 * b, masks[0], masks[1], masks[2], masks[3], true, DataBuffer.TYPE_INT);
  }
Пример #7
0
 /**
  * Multiply the alpha of one image with a mask image. The size of the resultant image is the
  * intersection of the two image bounds. If you want the end image to be the size of one or the
  * other please use the PadRed operator.
  *
  * @param src The image to convert to multiply the alpha of
  * @param alpha The mask image to multiply the alpha channel of src with.
  */
 public MultiplyAlphaRed(CachableRed src, CachableRed alpha) {
   super(
       makeList(src, alpha),
       makeBounds(src, alpha),
       fixColorModel(src),
       fixSampleModel(src),
       src.getTileGridXOffset(),
       src.getTileGridYOffset(),
       null);
 }
Пример #8
0
 /**
  * Construct an instance of TranslateRed
  *
  * @param xloc The new x coordinate of cr.getMinX().
  * @param yloc The new y coordinate of cr.getMinY().
  */
 public TranslateRed(CachableRed cr, int xloc, int yloc) {
   super(
       cr,
       new Rectangle(xloc, yloc, cr.getWidth(), cr.getHeight()),
       cr.getColorModel(),
       cr.getSampleModel(),
       cr.getTileGridXOffset() + xloc - cr.getMinX(),
       cr.getTileGridYOffset() + yloc - cr.getMinY(),
       null);
   deltaX = xloc - cr.getMinX();
   deltaY = yloc - cr.getMinY();
 }
Пример #9
0
  /**
   * Construct a blurred version of <tt>src</tt>, by blurring with a gaussian kernel with standard
   * Deviation of <tt>stdDev</tt> pixels.
   *
   * @param src The source image to blur
   * @param stdDevX The Standard Deviation of the Gaussian kernel in X
   * @param stdDevY The Standard Deviation of the Gaussian kernel in Y
   * @param rh Rendering hints.
   */
  public GaussianBlurRed8Bit(CachableRed src, double stdDevX, double stdDevY, RenderingHints rh) {
    super(); // Remember to call super.init()

    this.stdDevX = stdDevX;
    this.stdDevY = stdDevY;
    this.hints = rh;

    xinset = surroundPixels(stdDevX, rh);
    yinset = surroundPixels(stdDevY, rh);

    Rectangle myBounds = src.getBounds();
    myBounds.x += xinset;
    myBounds.y += yinset;
    myBounds.width -= 2 * xinset;
    myBounds.height -= 2 * yinset;
    if ((myBounds.width <= 0) || (myBounds.height <= 0)) {
      myBounds.width = 0;
      myBounds.height = 0;
    }

    ColorModel cm = fixColorModel(src);
    SampleModel sm = src.getSampleModel();
    int tw = sm.getWidth();
    int th = sm.getHeight();
    if (tw > myBounds.width) tw = myBounds.width;
    if (th > myBounds.height) th = myBounds.height;
    sm = cm.createCompatibleSampleModel(tw, th);

    init(
        src,
        myBounds,
        cm,
        sm,
        src.getTileGridXOffset() + xinset,
        src.getTileGridYOffset() + yinset,
        null);

    boolean highQuality =
        ((hints != null)
            && RenderingHints.VALUE_RENDER_QUALITY.equals(hints.get(RenderingHints.KEY_RENDERING)));

    // System.out.println("StdDev: " + stdDevX + "x" + stdDevY);
    if ((xinset != 0) && ((stdDevX < 2) || highQuality))
      convOp[0] = new ConvolveOp(makeQualityKernelX(xinset * 2 + 1));
    else dX = (int) Math.floor(DSQRT2PI * stdDevX + 0.5f);

    if ((yinset != 0) && ((stdDevY < 2) || highQuality))
      convOp[1] = new ConvolveOp(makeQualityKernelY(yinset * 2 + 1));
    else dY = (int) Math.floor(DSQRT2PI * stdDevY + 0.5f);
  }
Пример #10
0
  public static ColorModel fixColorModel(CachableRed src) {
    ColorModel cm = src.getColorModel();

    if (cm.hasAlpha()) return cm;

    int b = src.getSampleModel().getNumBands() + 1;
    int[] bits = new int[b];
    for (int i = 0; i < b; i++) bits[i] = 8;

    ColorSpace cs = cm.getColorSpace();

    return new ComponentColorModel(
        cs, bits, true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
  }
Пример #11
0
  /**
   * Construct a luminace image from src.
   *
   * @param src The image to convert to a luminance image
   */
  public Any2LsRGBRed(CachableRed src) {
    super(
        src,
        src.getBounds(),
        fixColorModel(src),
        fixSampleModel(src),
        src.getTileGridXOffset(),
        src.getTileGridYOffset(),
        null);

    ColorModel srcCM = src.getColorModel();
    if (srcCM == null) return;
    ColorSpace srcCS = srcCM.getColorSpace();
    if (srcCS == ColorSpace.getInstance(ColorSpace.CS_sRGB)) srcIssRGB = true;
  }
Пример #12
0
  public static SampleModel fixSampleModel(CachableRed src) {
    ColorModel cm = src.getColorModel();
    SampleModel srcSM = src.getSampleModel();

    if (cm.hasAlpha()) return srcSM;

    int w = srcSM.getWidth();
    int h = srcSM.getHeight();
    int b = srcSM.getNumBands() + 1;
    int[] offsets = new int[b];
    for (int i = 0; i < b; i++) offsets[i] = i;

    // Really should check DataType range in srcSM...
    return new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, w, h, b, w * b, offsets);
  }
Пример #13
0
  /**
   * Construct A Rendered Pad operation. If the pad is smaller than the original image size then
   * this devolves to a Crop.
   *
   * @param src The image to pad/crop
   * @param bounds The bounds of the result (same coord system as src).
   * @param padMode The pad mode to use (currently ignored).
   * @param hints The hints to use for drawing 'pad' area.
   */
  public PadRed(CachableRed src, Rectangle bounds, PadMode padMode, RenderingHints hints) {
    super(src, bounds, src.getColorModel(), fixSampleModel(src, bounds), bounds.x, bounds.y, null);

    this.padMode = padMode;

    if (DEBUG) {
      System.out.println(
          "Src: "
              + src
              + " Bounds: "
              + bounds
              + " Off: "
              + src.getTileGridXOffset()
              + ", "
              + src.getTileGridYOffset());
    }
    this.hints = hints;
  }
Пример #14
0
  /**
   * This function 'fixes' the source's sample model. right now it just ensures that the sample
   * model isn't much larger than my width.
   */
  protected static SampleModel fixSampleModel(CachableRed src, Rectangle bounds) {
    int defSz = AbstractTiledRed.getDefaultTileSize();

    SampleModel sm = src.getSampleModel();
    int w = sm.getWidth();
    if (w < defSz) w = defSz;
    if (w > bounds.width) w = bounds.width;
    int h = sm.getHeight();
    if (h < defSz) h = defSz;
    if (h > bounds.height) h = bounds.height;

    // System.out.println("Pad SMSz: " + w + "x" + h);

    return sm.createCompatibleSampleModel(w, h);
  }
Пример #15
0
  /**
   * This function 'fixes' the source's sample model. right now it just ensures that the sample
   * model isn't much larger than my width.
   */
  protected SampleModel fixSampleModel(CachableRed src, ColorModel cm, Rectangle bounds) {
    SampleModel sm = src.getSampleModel();
    int defSz = AbstractTiledRed.getDefaultTileSize();

    int w = sm.getWidth();
    if (w < defSz) w = defSz;
    if (w > bounds.width) w = bounds.width;
    int h = sm.getHeight();
    if (h < defSz) h = defSz;
    if (h > bounds.height) h = bounds.height;

    if ((w <= 0) || (h <= 0)) {
      w = 1;
      h = 1;
    }

    return cm.createCompatibleSampleModel(w, h);
  }
Пример #16
0
  protected void handleReplicate(WritableRaster wr) {
    // Get my source.
    CachableRed src = (CachableRed) getSources().get(0);
    Rectangle srcR = src.getBounds();
    Rectangle wrR = wr.getBounds();

    int x = wrR.x;
    int y = wrR.y;
    int width = wrR.width;
    int height = wrR.height;

    Rectangle r;
    {
      // Calculate an intersection that makes some sense
      // even when the rects don't really intersect
      // (The x and y ranges will be correct if they
      // overlap in one dimension even if they don't
      // intersect in both dimensions).
      int minX = (srcR.x > x) ? srcR.x : x;
      int maxX =
          (((srcR.x + srcR.width - 1) < (x + width - 1))
              ? (srcR.x + srcR.width - 1)
              : (x + width - 1));
      int minY = (srcR.y > y) ? srcR.y : y;
      int maxY =
          (((srcR.y + srcR.height - 1) < (y + height - 1))
              ? (srcR.y + srcR.height - 1)
              : (y + height - 1));

      int x0 = minX;
      int w = maxX - minX + 1;
      int y0 = minY;
      int h = maxY - minY + 1;
      if (w < 0) {
        x0 = 0;
        w = 0;
      }
      if (h < 0) {
        y0 = 0;
        h = 0;
      }
      r = new Rectangle(x0, y0, w, h);
    }

    // We split the edge drawing up into four parts.
    //
    //  +-----------------------------+
    //  | 3    | 1             | 4    |
    //  |      +---------------+      |
    //  /      /               /      /
    //  /      / src           /      /
    //  /      /               /      /
    //  /      /               /      /
    //  |      +---------------+      |
    //  |      | 2             |      |
    //  +-----------------------------+
    //

    // Draw #1
    if (y < srcR.y) {
      int repW = r.width;
      int repX = r.x;
      int wrX = r.x;
      int wrY = y;
      if (x + width - 1 <= srcR.x) {
        // we are off to the left of src. so set repX to the
        // left most pixel...
        repW = 1;
        repX = srcR.x;
        wrX = x + width - 1;
      } else if (x >= srcR.x + srcR.width) {
        // we are off to the right of src, so set repX to
        // the right most pixel
        repW = 1;
        repX = srcR.x + srcR.width - 1;
        wrX = x;
      }

      // This fills the top row of section 1 from src (we
      // go to src instead of getting the data from wr because
      // in some cases wr will be completely off the top of src
      WritableRaster wr1 = wr.createWritableChild(wrX, wrY, repW, 1, repX, srcR.y, null);
      src.copyData(wr1);
      wrY++;

      int endY = srcR.y;
      if (y + height < endY) endY = y + height;

      if (wrY < endY) {
        int[] pixels = wr.getPixels(wrX, wrY - 1, repW, 1, (int[]) null);
        while (wrY < srcR.y) {
          wr.setPixels(wrX, wrY, repW, 1, pixels);
          wrY++;
        }
      }
    }

    // Draw #2
    if ((y + height) > (srcR.y + srcR.height)) {
      int repW = r.width;
      int repX = r.x;
      int repY = srcR.y + srcR.height - 1;

      int wrX = r.x;
      int wrY = srcR.y + srcR.height;
      if (wrY < y) wrY = y;

      if (x + width <= srcR.x) {
        // we are off to the left of src. so set repX to the
        // left most pixel...
        repW = 1;
        repX = srcR.x;
        wrX = x + width - 1;
      } else if (x >= srcR.x + srcR.width) {
        // we are off to the right of src, so set repX to
        // the right most pixel
        repW = 1;
        repX = srcR.x + srcR.width - 1;
        wrX = x;
      }

      if (DEBUG) {
        System.out.println("wr: " + wr.getBounds());
        System.out.println("req: [" + wrX + ", " + wrY + ", " + repW + ", 1]");
      }

      // First we get the top row of pixels from src. (we
      // go to src instead of getting the data from wr because
      // in some cases wr will be completely off the bottom of src).
      WritableRaster wr1 = wr.createWritableChild(wrX, wrY, repW, 1, repX, repY, null);
      // This fills the top row of section 2 from src
      src.copyData(wr1);
      wrY++;

      int endY = y + height;
      if (wrY < endY) {
        // This fills the rest of section 2 from the first line.
        int[] pixels = wr.getPixels(wrX, wrY - 1, repW, 1, (int[]) null);
        while (wrY < endY) {
          wr.setPixels(wrX, wrY, repW, 1, pixels);
          wrY++;
        }
      }
    }

    // Draw #3
    if (x < srcR.x) {
      // We are garunteed that we have a column of pixels down
      // the edge of 1 and src.  We simply replicate this column
      // out to the edges of 2.
      int wrX = srcR.x;
      if (x + width <= srcR.x) {
        wrX = x + width - 1;
      }

      int xLoc = x;
      int[] pixels = wr.getPixels(wrX, y, 1, height, (int[]) null);
      while (xLoc < wrX) {
        wr.setPixels(xLoc, y, 1, height, pixels);
        xLoc++;
      }
    }

    // Draw #4
    if (x + width > srcR.x + srcR.width) {
      // We are garunteed that we have a column of pixels down
      // the edge of 1 and src.  We simply replicate this column
      // out to the edges of 3.
      int wrX = srcR.x + srcR.width - 1;
      if (x >= srcR.x + srcR.width) {
        wrX = x;
      }

      int xLoc = wrX + 1;
      int endX = x + width - 1;
      int[] pixels = wr.getPixels(wrX, y, 1, height, (int[]) null);
      while (xLoc < endX) {
        wr.setPixels(xLoc, y, 1, height, pixels);
        xLoc++;
      }
    }
  }
Пример #17
0
  public void genRect(WritableRaster wr) {
    if (me2src == null) return;

    Rectangle srcR = me2src.createTransformedShape(wr.getBounds()).getBounds();

    // System.out.println("Affine wrR: " + wr.getBounds());
    // System.out.println("Affine srcR: " + srcR);

    // Outset by two pixels so we get context for interpolation...
    srcR.setBounds(srcR.x - 1, srcR.y - 1, srcR.width + 2, srcR.height + 2);

    // Don't try and get data from src that it doesn't have...
    CachableRed src = (CachableRed) getSources().get(0);

    // Raster srcRas = src.getData(srcR);

    if (!srcR.intersects(src.getBounds())) return;
    Raster srcRas = src.getData(srcR.intersection(src.getBounds()));

    if (srcRas == null) return;

    // This works around the problem that the buffered ops
    // completely ignore the coords of the Rasters passed in.
    AffineTransform aff = (AffineTransform) src2me.clone();

    // Translate what is at 0,0 (which will be what our current
    // minX/Y is) to our current minX,minY.
    aff.concatenate(AffineTransform.getTranslateInstance(srcRas.getMinX(), srcRas.getMinY()));

    Point2D srcPt = new Point2D.Float(wr.getMinX(), wr.getMinY());
    srcPt = me2src.transform(srcPt, null);

    Point2D destPt =
        new Point2D.Double(srcPt.getX() - srcRas.getMinX(), srcPt.getY() - srcRas.getMinY());

    destPt = aff.transform(destPt, null);

    // Translate what will be at minX,minY to zero, zero
    // which where java2d will think the real minX,minY is.
    aff.preConcatenate(AffineTransform.getTranslateInstance(-destPt.getX(), -destPt.getY()));

    AffineTransformOp op = new AffineTransformOp(aff, hints);

    BufferedImage srcBI, myBI;
    ColorModel srcCM = src.getColorModel();
    ColorModel myCM = getColorModel();

    WritableRaster srcWR = (WritableRaster) srcRas;
    // If the output buffer is not premultiplied in certain cases
    // it fails to properly divide out the Alpha (it always does
    // the affine on premultiplied data). We help it out by
    // premultiplying for it.
    srcCM = GraphicsUtil.coerceData(srcWR, srcCM, true);
    srcBI =
        new BufferedImage(
            srcCM, srcWR.createWritableTranslatedChild(0, 0), srcCM.isAlphaPremultiplied(), null);

    myBI =
        new BufferedImage(
            myCM, wr.createWritableTranslatedChild(0, 0), myCM.isAlphaPremultiplied(), null);

    op.filter(srcBI, myBI);

    // if ((count % 40) == 0) {
    //     org.apache.batik.ImageDisplay.showImage("Src: " , srcBI);
    //     org.apache.batik.ImageDisplay.showImage("Dst: " , myBI);
    // }
    // count++;
  }
Пример #18
0
 public static Rectangle makeBounds(CachableRed src1, CachableRed src2) {
   Rectangle r1 = src1.getBounds();
   Rectangle r2 = src2.getBounds();
   return r1.intersection(r2);
 }
Пример #19
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;
  }
Пример #20
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;
  }
Пример #21
0
  public WritableRaster copyData(WritableRaster wr) {
    // Get my source.
    CachableRed src = (CachableRed) getSources().get(0);

    Rectangle r = wr.getBounds();
    r.x -= xinset;
    r.y -= yinset;
    r.width += 2 * xinset;
    r.height += 2 * yinset;

    // System.out.println("Gaussian GenR: " + wr);
    // System.out.println("SrcReq: " + r);

    ColorModel srcCM = src.getColorModel();

    WritableRaster tmpR1 = null, tmpR2 = null;

    tmpR1 = srcCM.createCompatibleWritableRaster(r.width, r.height);
    {
      WritableRaster fill;
      fill = tmpR1.createWritableTranslatedChild(r.x, r.y);
      src.copyData(fill);
    }
    if (srcCM.hasAlpha() && !srcCM.isAlphaPremultiplied())
      GraphicsUtil.coerceData(tmpR1, srcCM, true);

    // For the blur box approx we can use dest as our intermediate
    // otherwise we let it default to null which means we create a new
    // one...

    // this lets the Vertical conv know how much is junk, so it
    // doesn't bother to convolve the top and bottom edges
    int skipX;
    // long t1 = System.currentTimeMillis();
    if (xinset == 0) {
      skipX = 0;
    } else if (convOp[0] != null) {
      tmpR2 = getColorModel().createCompatibleWritableRaster(r.width, r.height);
      tmpR2 = convOp[0].filter(tmpR1, tmpR2);
      skipX = convOp[0].getKernel().getXOrigin();

      // Swap them...
      WritableRaster tmp = tmpR1;
      tmpR1 = tmpR2;
      tmpR2 = tmp;
    } else {
      if ((dX & 0x01) == 0) {
        tmpR1 = boxFilterH(tmpR1, tmpR1, 0, 0, dX, dX / 2);
        tmpR1 = boxFilterH(tmpR1, tmpR1, dX / 2, 0, dX, dX / 2 - 1);
        tmpR1 = boxFilterH(tmpR1, tmpR1, dX - 1, 0, dX + 1, dX / 2);
        skipX = dX - 1 + dX / 2;
      } else {
        tmpR1 = boxFilterH(tmpR1, tmpR1, 0, 0, dX, dX / 2);
        tmpR1 = boxFilterH(tmpR1, tmpR1, dX / 2, 0, dX, dX / 2);
        tmpR1 = boxFilterH(tmpR1, tmpR1, dX - 2, 0, dX, dX / 2);
        skipX = dX - 2 + dX / 2;
      }
    }

    if (yinset == 0) {
      tmpR2 = tmpR1;
    } else if (convOp[1] != null) {
      if (tmpR2 == null) {
        tmpR2 = getColorModel().createCompatibleWritableRaster(r.width, r.height);
      }
      tmpR2 = convOp[1].filter(tmpR1, tmpR2);
    } else {
      if ((dY & 0x01) == 0) {
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, 0, dY, dY / 2);
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, dY / 2, dY, dY / 2 - 1);
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, dY - 1, dY + 1, dY / 2);
      } else {
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, 0, dY, dY / 2);
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, dY / 2, dY, dY / 2);
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, dY - 2, dY, dY / 2);
      }
      tmpR2 = tmpR1;
    }
    // long t2 = System.currentTimeMillis();
    // System.out.println("Time: " + (t2-t1) +
    //                       (((convOp[0] != null) || (convOp[1] != null))?
    //                        " ConvOp":""));
    // System.out.println("Rasters  WR :" + wr.getBounds());
    // System.out.println("         tmp:" + tmpR2.getBounds());
    // System.out.println("      bounds:" + getBounds());
    // System.out.println("       skipX:" + skipX +
    //                    " dx:" + dX + " Dy: " + dY);
    tmpR2 = tmpR2.createWritableTranslatedChild(r.x, r.y);
    GraphicsUtil.copyData(tmpR2, wr);

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

    // Already has alpha channel so we use it.
    srcRed.copyData(wr);

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

    Raster r = alphaRed.getData(rgn);

    ComponentSampleModel csm;
    csm = (ComponentSampleModel) r.getSampleModel();
    final int alpScanStride = csm.getScanlineStride();

    DataBufferByte alpDB = (DataBufferByte) r.getDataBuffer();
    final int alpBase =
        (alpDB.getOffset()
            + csm.getOffset(
                rgn.x - r.getSampleModelTranslateX(), rgn.y - r.getSampleModelTranslateY()));

    // Access the pixel data array
    final byte[] alpPixels = alpDB.getBankData()[0];

    SinglePixelPackedSampleModel sppsm;
    sppsm = (SinglePixelPackedSampleModel) wr.getSampleModel();
    final int srcScanStride = sppsm.getScanlineStride();

    DataBufferInt srcDB = (DataBufferInt) wr.getDataBuffer();
    final int srcBase =
        (srcDB.getOffset()
            + sppsm.getOffset(
                rgn.x - wr.getSampleModelTranslateX(), rgn.y - wr.getSampleModelTranslateY()));

    // Access the pixel data array
    final int[] srcPixels = srcDB.getBankData()[0];

    ColorModel cm = srcRed.getColorModel();

    if (cm.isAlphaPremultiplied()) {
      // For alpha premult we need to multiply all comps.
      for (int y = 0; y < rgn.height; y++) {
        int sp = srcBase + y * srcScanStride;
        int ap = alpBase + y * alpScanStride;
        int end = sp + rgn.width;

        while (sp < end) {
          int a = ((int) alpPixels[ap++]) & 0xFF;
          final int pix = srcPixels[sp];
          srcPixels[sp] =
              ((((((pix >>> 24)) * a) & 0xFF00) << 16)
                  | (((((pix >>> 16) & 0xFF) * a) & 0xFF00) << 8)
                  | (((((pix >>> 8) & 0xFF) * a) & 0xFF00))
                  | (((((pix) & 0xFF) * a) & 0xFF00) >> 8));
          sp++;
        }
      }

    } else {
      // For non-alpha premult we only need to multiply alpha.
      for (int y = 0; y < rgn.height; y++) {
        int sp = srcBase + y * srcScanStride;
        int ap = alpBase + y * alpScanStride;
        int end = sp + rgn.width;
        while (sp < end) {
          int a = ((int) alpPixels[ap++]) & 0xFF;
          int sa = srcPixels[sp] >>> 24;
          srcPixels[sp] = ((((sa * a) & 0xFF00) << 16) | srcPixels[sp] & 0x00FFFFFF);
          sp++;
        }
      }
    }

    return wr;
  }
Пример #23
0
  protected void handleZero(WritableRaster wr) {
    // Get my source.
    CachableRed src = (CachableRed) getSources().get(0);
    Rectangle srcR = src.getBounds();
    Rectangle wrR = wr.getBounds();

    ZeroRecter zr = ZeroRecter.getZeroRecter(wr);

    // area rect (covers the area left to handle).
    Rectangle ar = new Rectangle(wrR.x, wrR.y, wrR.width, wrR.height);
    // draw rect (used for calls to zeroRect);
    Rectangle dr = new Rectangle(wrR.x, wrR.y, wrR.width, wrR.height);

    // We split the edge drawing up into four parts.
    //
    //  +-----------------------------+
    //  | 1    | 2                    |
    //  |      +---------------+------|
    //  /      /               /4     /
    //  /      /               /      /
    //  /      /               /      /
    //  /      /               /      /
    //  |      +---------------+------|
    //  |      |  3                   |
    //  +-----------------------------+
    //
    //  We update our x,y, width, height as we go along so
    //  we 'forget' about the parts we have already painted...

    // Draw #1
    if (DEBUG) {
      System.out.println("WrR: " + wrR + " srcR: " + srcR);
      // g2d.setColor(new Color(255,0,0,128));
    }
    if (ar.x < srcR.x) {
      int w = srcR.x - ar.x;
      if (w > ar.width) w = ar.width;
      // g2d.fillRect(x, y, w, height);
      dr.width = w;
      zr.zeroRect(dr);

      ar.x += w;
      ar.width -= w;
    }

    // Draw #2
    if (DEBUG) {
      System.out.println(
          "WrR: [" + ar.x + "," + ar.y + "," + ar.width + "," + ar.height + "] s rcR: " + srcR);
      // g2d.setColor(new Color(0,0,255,128));
    }
    if (ar.y < srcR.y) {
      int h = srcR.y - ar.y;
      if (h > ar.height) h = ar.height;
      // g2d.fillRect(x, y, width, h);
      dr.x = ar.x;
      dr.y = ar.y;
      dr.width = ar.width;
      dr.height = h;
      zr.zeroRect(dr);

      ar.y += h;
      ar.height -= h;
    }

    // Draw #3
    if (DEBUG) {
      System.out.println(
          "WrR: [" + ar.x + "," + ar.y + "," + ar.width + "," + ar.height + "] srcR: " + srcR);
      // g2d.setColor(new Color(0,255,0,128));
    }
    if (ar.y + ar.height > srcR.y + srcR.height) {
      int h = (ar.y + ar.height) - (srcR.y + srcR.height);
      if (h > ar.height) h = ar.height;

      int y0 = ar.y + ar.height - h; // the +/-1 cancel (?)

      // g2d.fillRect(x, y0, width, h);
      dr.x = ar.x;
      dr.y = y0;
      dr.width = ar.width;
      dr.height = h;
      zr.zeroRect(dr);

      ar.height -= h;
    }

    // Draw #4
    if (DEBUG) {
      System.out.println(
          "WrR: [" + ar.x + "," + ar.y + "," + ar.width + "," + ar.height + "] srcR: " + srcR);
      // g2d.setColor(new Color(255,255,0,128));
    }
    if (ar.x + ar.width > srcR.x + srcR.width) {
      int w = (ar.x + ar.width) - (srcR.x + srcR.width);
      if (w > ar.width) w = ar.width;
      int x0 = ar.x + ar.width - w; // the +/-1 cancel (?)

      // g2d.fillRect(x0, y, w, height);
      dr.x = x0;
      dr.y = ar.y;
      dr.width = w;
      dr.height = ar.height;
      zr.zeroRect(dr);

      ar.width -= w;
    }
  }