0001: /*
0002: * $RCSfile: AffineBicubic2OpImage.java,v $
0003: *
0004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * Use is subject to license terms.
0007: *
0008: * $Revision: 1.1 $
0009: * $Date: 2005/02/11 04:56:12 $
0010: * $State: Exp $
0011: */
0012: package com.sun.media.jai.opimage;
0013:
0014: import java.awt.Rectangle;
0015: import java.awt.geom.Point2D;
0016: import java.awt.geom.AffineTransform;
0017: import java.awt.image.DataBuffer;
0018: import java.awt.image.Raster;
0019: import java.awt.image.RenderedImage;
0020: import java.awt.image.WritableRaster;
0021: import java.awt.image.renderable.ParameterBlock;
0022: import javax.media.jai.BorderExtender;
0023: import javax.media.jai.ImageLayout;
0024: import javax.media.jai.Interpolation;
0025: import javax.media.jai.OpImage;
0026: import javax.media.jai.RasterAccessor;
0027: import javax.media.jai.RasterFormatTag;
0028: import java.util.Map;
0029:
0030: /**
0031: * An OpImage subclass that performs bicubic2 Affine mapping
0032: */
0033: final class AffineBicubic2OpImage extends AffineOpImage {
0034:
0035: /* The number of subsampleBits */
0036: private int subsampleBits;
0037: private int shiftvalue;
0038:
0039: /**
0040: * Constructs an AffineBicubic2OpImage from a RenderedImage source,
0041: *
0042: * @param source a RenderedImage.
0043: * @param extender a BorderExtender, or null.
0044: * @param layout an ImageLayout optionally containing the tile grid layout,
0045: * SampleModel, and ColorModel, or null.
0046: * @param interp an Interpolation object to use for resampling
0047: * @param transform the desired AffineTransform.
0048: */
0049: public AffineBicubic2OpImage(RenderedImage source,
0050: BorderExtender extender, Map config, ImageLayout layout,
0051: AffineTransform transform, Interpolation interp,
0052: double[] backgroundValues) {
0053: super (source, extender, config, layout, transform, interp,
0054: backgroundValues);
0055:
0056: subsampleBits = interp.getSubsampleBitsH();
0057: shiftvalue = 1 << subsampleBits;
0058: }
0059:
0060: /**
0061: * Performs an affine transform on a specified rectangle. The sources are
0062: * cobbled.
0063: *
0064: * @param sources an array of source Rasters, guaranteed to provide all
0065: * necessary source data for computing the output.
0066: * @param dest a WritableRaster tile containing the area to be computed.
0067: * @param destRect the rectangle within dest to be processed.
0068: */
0069: protected void computeRect(Raster[] sources, WritableRaster dest,
0070: Rectangle destRect) {
0071: // Retrieve format tags.
0072: RasterFormatTag[] formatTags = getFormatTags();
0073:
0074: Raster source = sources[0];
0075:
0076: Rectangle srcRect = source.getBounds();
0077:
0078: int srcRectX = srcRect.x;
0079: int srcRectY = srcRect.y;
0080:
0081: //
0082: // Get data for the source rectangle & the destination rectangle
0083: // In the first version source Rectangle is the whole source
0084: // image always.
0085: //
0086: // See if we can cache the source to avoid multiple rasteraccesors
0087: //
0088: RasterAccessor srcAccessor = new RasterAccessor(source,
0089: srcRect, formatTags[0], getSourceImage(0)
0090: .getColorModel());
0091: RasterAccessor dstAccessor = new RasterAccessor(dest, destRect,
0092: formatTags[1], getColorModel());
0093:
0094: switch (dstAccessor.getDataType()) {
0095: case DataBuffer.TYPE_BYTE:
0096: byteLoop(srcAccessor, destRect, srcRectX, srcRectY,
0097: dstAccessor);
0098: break;
0099:
0100: case DataBuffer.TYPE_INT:
0101: intLoop(srcAccessor, destRect, srcRectX, srcRectY,
0102: dstAccessor);
0103: break;
0104:
0105: case DataBuffer.TYPE_SHORT:
0106: shortLoop(srcAccessor, destRect, srcRectX, srcRectY,
0107: dstAccessor);
0108: break;
0109:
0110: case DataBuffer.TYPE_USHORT:
0111: ushortLoop(srcAccessor, destRect, srcRectX, srcRectY,
0112: dstAccessor);
0113: break;
0114:
0115: case DataBuffer.TYPE_FLOAT:
0116: floatLoop(srcAccessor, destRect, srcRectX, srcRectY,
0117: dstAccessor);
0118: break;
0119:
0120: case DataBuffer.TYPE_DOUBLE:
0121: doubleLoop(srcAccessor, destRect, srcRectX, srcRectY,
0122: dstAccessor);
0123: break;
0124: }
0125:
0126: // If the RasterAccessor object set up a temporary buffer for the
0127: // op to write to, tell the RasterAccessor to write that data
0128: // to the raster, that we're done with it.
0129: if (dstAccessor.isDataCopy()) {
0130: dstAccessor.clampDataArrays();
0131: dstAccessor.copyDataToRaster();
0132: }
0133: }
0134:
0135: private void byteLoop(RasterAccessor src, Rectangle destRect,
0136: int srcRectX, int srcRectY, RasterAccessor dst) {
0137:
0138: float src_rect_x1 = src.getX();
0139: float src_rect_y1 = src.getY();
0140: float src_rect_x2 = src_rect_x1 + src.getWidth();
0141: float src_rect_y2 = src_rect_y1 + src.getHeight();
0142:
0143: float s_x, s_y;
0144:
0145: float fracx, fracy;
0146: float float_fracx, float_fracy;
0147: float frac_xx, frac_yy;
0148:
0149: int s_ix, s_iy;
0150: int p_x, p_y;
0151:
0152: int p__, p0_, p1_, p2_;
0153: int p_0, p00, p01, p02;
0154: int p_1, p10, p11, p12;
0155: int p_2, p20, p21, p22;
0156:
0157: int s__, s0_, s1_, s2_;
0158: int s_0, s00, s01, s02;
0159: int s_1, s10, s11, s12;
0160: int s_2, s20, s21, s22;
0161:
0162: float s0, s1, s_, s2;
0163: float q_, q0, q1, q2;
0164: float s, q;
0165: int result;
0166:
0167: int xfrac, yfrac;
0168:
0169: int dstPixelOffset;
0170: int dstOffset = 0;
0171:
0172: Point2D dst_pt = new Point2D.Float();
0173: Point2D src_pt = new Point2D.Float();
0174:
0175: byte dstDataArrays[][] = dst.getByteDataArrays();
0176: int dstBandOffsets[] = dst.getBandOffsets();
0177: int dstPixelStride = dst.getPixelStride();
0178: int dstScanlineStride = dst.getScanlineStride();
0179:
0180: byte srcDataArrays[][] = src.getByteDataArrays();
0181: int bandOffsets[] = src.getBandOffsets();
0182: int srcPixelStride = src.getPixelStride();
0183: int srcScanlineStride = src.getScanlineStride();
0184:
0185: int dst_num_bands = dst.getNumBands();
0186:
0187: int dst_min_x = destRect.x;
0188: int dst_min_y = destRect.y;
0189: int dst_max_x = destRect.x + destRect.width;
0190: int dst_max_y = destRect.y + destRect.height;
0191:
0192: byte[] backgroundByte = new byte[dst_num_bands];
0193: for (int i = 0; i < dst_num_bands; i++)
0194: backgroundByte[i] = (byte) backgroundValues[i];
0195:
0196: for (int y = dst_min_y; y < dst_max_y; y++) {
0197: dstPixelOffset = dstOffset;
0198:
0199: // Backward map the first point in the line
0200: // The energy is at the (pt_x + 0.5, pt_y + 0.5)
0201: dst_pt.setLocation((double) dst_min_x + 0.5,
0202: (double) y + 0.5);
0203: mapDestPoint(dst_pt, src_pt);
0204:
0205: // Get the mapped source coordinates
0206: s_x = (float) src_pt.getX();
0207: s_y = (float) src_pt.getY();
0208:
0209: // As per definition of bicubic interpolation
0210: s_x -= 0.5;
0211: s_y -= 0.5;
0212:
0213: // Floor to get the integral coordinate
0214: s_ix = (int) Math.floor(s_x);
0215: s_iy = (int) Math.floor(s_y);
0216:
0217: fracx = s_x - (float) s_ix;
0218: fracy = s_y - (float) s_iy;
0219:
0220: // Translate to/from SampleModel space & Raster space
0221: p_x = (s_ix - srcRectX) * srcPixelStride;
0222: p_y = (s_iy - srcRectY) * srcScanlineStride;
0223:
0224: //
0225: // Get the 16 neighbouring positions of the
0226: // coordinate in question (p00).
0227: //
0228: // p__ p0_ p1_ p2_
0229: // p_0 p00 p10 p20
0230: // p_1 p01 p11 p21
0231: // p_2 p02 p12 p22
0232: //
0233: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
0234: p0_ = p__ + srcPixelStride;
0235: p1_ = p0_ + srcPixelStride;
0236: p2_ = p1_ + srcPixelStride;
0237: p_0 = p__ + srcScanlineStride;
0238: p00 = p_0 + srcPixelStride;
0239: p10 = p00 + srcPixelStride;
0240: p20 = p10 + srcPixelStride;
0241: p_1 = p_0 + srcScanlineStride;
0242: p01 = p_1 + srcPixelStride;
0243: p11 = p01 + srcPixelStride;
0244: p21 = p11 + srcPixelStride;
0245: p_2 = p_1 + srcScanlineStride;
0246: p02 = p_2 + srcPixelStride;
0247: p12 = p02 + srcPixelStride;
0248: p22 = p12 + srcPixelStride;
0249:
0250: for (int x = dst_min_x; x < dst_max_x; x++) {
0251: //
0252: // Check against the source rectangle
0253: //
0254:
0255: if ((s_ix >= src_rect_x1 + 1)
0256: && (s_ix < (src_rect_x2 - 2))
0257: && (s_iy >= (src_rect_y1 + 1))
0258: && (s_iy < (src_rect_y2 - 2))) {
0259: for (int k2 = 0; k2 < dst_num_bands; k2++) {
0260: //
0261: // Get the pixels
0262: //
0263: byte tmp_row[];
0264: int tmp_col;
0265:
0266: tmp_row = srcDataArrays[k2];
0267: tmp_col = bandOffsets[k2];
0268:
0269: s__ = tmp_row[p__ + tmp_col] & 0xff;
0270: s0_ = tmp_row[p0_ + tmp_col] & 0xff;
0271: s1_ = tmp_row[p1_ + tmp_col] & 0xff;
0272: s2_ = tmp_row[p2_ + tmp_col] & 0xff;
0273: s_0 = tmp_row[p_0 + tmp_col] & 0xff;
0274: s00 = tmp_row[p00 + tmp_col] & 0xff;
0275: s10 = tmp_row[p10 + tmp_col] & 0xff;
0276: s20 = tmp_row[p20 + tmp_col] & 0xff;
0277: s_1 = tmp_row[p_1 + tmp_col] & 0xff;
0278: s01 = tmp_row[p01 + tmp_col] & 0xff;
0279: s11 = tmp_row[p11 + tmp_col] & 0xff;
0280: s21 = tmp_row[p21 + tmp_col] & 0xff;
0281: s_2 = tmp_row[p_2 + tmp_col] & 0xff;
0282: s02 = tmp_row[p02 + tmp_col] & 0xff;
0283: s12 = tmp_row[p12 + tmp_col] & 0xff;
0284: s22 = tmp_row[p22 + tmp_col] & 0xff;
0285:
0286: // Get the new frac values
0287: xfrac = (int) (fracx * shiftvalue);
0288: yfrac = (int) (fracy * shiftvalue);
0289:
0290: // Note that the notations are different from
0291: // what's mentioned in the interpolation class
0292: // For example s0_ here is actually s_0 in the
0293: // Interpolation class
0294:
0295: s = interp.interpolate(s__, s0_, s1_, s2_, s_0,
0296: s00, s10, s20, s_1, s01, s11, s21, s_2,
0297: s02, s12, s22, xfrac, yfrac);
0298:
0299: // Round
0300: if (s < 0.5F) {
0301: result = 0;
0302: } else if (s > 254.5F) {
0303: result = 255;
0304: } else {
0305: result = (int) (s + 0.5F);
0306: }
0307:
0308: // write the result
0309: dstDataArrays[k2][dstPixelOffset
0310: + dstBandOffsets[k2]] = (byte) (result & 0xff);
0311: }
0312: } else if (setBackground) {
0313: for (int k = 0; k < dst_num_bands; k++)
0314: dstDataArrays[k][dstPixelOffset
0315: + dstBandOffsets[k]] = backgroundByte[k];
0316: }
0317:
0318: // walk
0319: if (fracx < fracdx1) {
0320: s_ix += incx;
0321: fracx += fracdx;
0322: if (fracx == 1.0F) {
0323: // To avoid overflow in the interpolation table
0324: fracx = 0.999999F;
0325: }
0326: } else {
0327: s_ix += incx1;
0328: fracx -= fracdx1;
0329: }
0330:
0331: if (fracy < fracdy1) {
0332: s_iy += incy;
0333: fracy += fracdy;
0334: if (fracy == 1.0F) {
0335: // To avoid overflow in the interpolation table
0336: fracy = 0.999999F;
0337: }
0338: } else {
0339: s_iy += incy1;
0340: fracy -= fracdy1;
0341: }
0342:
0343: // Translate to/from SampleModel space & Raster space
0344: p_x = (s_ix - srcRectX) * srcPixelStride;
0345: p_y = (s_iy - srcRectY) * srcScanlineStride;
0346:
0347: //
0348: // Get the 16 neighbouring positions of the
0349: // coordinate in question (p00).
0350: //
0351: // p__ p0_ p1_ p2_
0352: // p_0 p00 p10 p20
0353: // p_1 p01 p11 p21
0354: // p_2 p02 p12 p22
0355: //
0356: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
0357: p0_ = p__ + srcPixelStride;
0358: p1_ = p0_ + srcPixelStride;
0359: p2_ = p1_ + srcPixelStride;
0360: p_0 = p__ + srcScanlineStride;
0361: p00 = p_0 + srcPixelStride;
0362: p10 = p00 + srcPixelStride;
0363: p20 = p10 + srcPixelStride;
0364: p_1 = p_0 + srcScanlineStride;
0365: p01 = p_1 + srcPixelStride;
0366: p11 = p01 + srcPixelStride;
0367: p21 = p11 + srcPixelStride;
0368: p_2 = p_1 + srcScanlineStride;
0369: p02 = p_2 + srcPixelStride;
0370: p12 = p02 + srcPixelStride;
0371: p22 = p12 + srcPixelStride;
0372:
0373: dstPixelOffset += dstPixelStride;
0374: }
0375:
0376: dstOffset += dstScanlineStride;
0377: }
0378:
0379: }
0380:
0381: private void intLoop(RasterAccessor src, Rectangle destRect,
0382: int srcRectX, int srcRectY, RasterAccessor dst) {
0383:
0384: float src_rect_x1 = src.getX();
0385: float src_rect_y1 = src.getY();
0386: float src_rect_x2 = src_rect_x1 + src.getWidth();
0387: float src_rect_y2 = src_rect_y1 + src.getHeight();
0388:
0389: float s_x, s_y;
0390:
0391: float fracx, fracy;
0392: float float_fracx, float_fracy;
0393: float frac_xx, frac_yy;
0394:
0395: int s_ix, s_iy;
0396: int p_x, p_y;
0397:
0398: int p__, p0_, p1_, p2_;
0399: int p_0, p00, p01, p02;
0400: int p_1, p10, p11, p12;
0401: int p_2, p20, p21, p22;
0402:
0403: int s__, s0_, s1_, s2_;
0404: int s_0, s00, s01, s02;
0405: int s_1, s10, s11, s12;
0406: int s_2, s20, s21, s22;
0407:
0408: float s0, s1, s_, s2;
0409: float q_, q0, q1, q2;
0410: float s, q;
0411: int result;
0412:
0413: int dstPixelOffset;
0414: int dstOffset = 0;
0415:
0416: int xfrac, yfrac;
0417:
0418: Point2D dst_pt = new Point2D.Float();
0419: Point2D src_pt = new Point2D.Float();
0420:
0421: int dstDataArrays[][] = dst.getIntDataArrays();
0422: int dstBandOffsets[] = dst.getBandOffsets();
0423: int dstPixelStride = dst.getPixelStride();
0424: int dstScanlineStride = dst.getScanlineStride();
0425:
0426: int srcDataArrays[][] = src.getIntDataArrays();
0427: int bandOffsets[] = src.getBandOffsets();
0428: int srcPixelStride = src.getPixelStride();
0429: int srcScanlineStride = src.getScanlineStride();
0430:
0431: int dst_num_bands = dst.getNumBands();
0432:
0433: int dst_min_x = destRect.x;
0434: int dst_min_y = destRect.y;
0435: int dst_max_x = destRect.x + destRect.width;
0436: int dst_max_y = destRect.y + destRect.height;
0437:
0438: int[] backgroundInt = new int[dst_num_bands];
0439: for (int i = 0; i < dst_num_bands; i++)
0440: backgroundInt[i] = (int) backgroundValues[i];
0441:
0442: for (int y = dst_min_y; y < dst_max_y; y++) {
0443: dstPixelOffset = dstOffset;
0444:
0445: // Backward map the first point in the line
0446: // The energy is at the (pt_x + 0.5, pt_y + 0.5)
0447: dst_pt.setLocation((double) dst_min_x + 0.5,
0448: (double) y + 0.5);
0449: mapDestPoint(dst_pt, src_pt);
0450:
0451: // Get the mapped source coordinates
0452: s_x = (float) src_pt.getX();
0453: s_y = (float) src_pt.getY();
0454:
0455: // As per definition of bicubic interpolation
0456: s_x -= 0.5;
0457: s_y -= 0.5;
0458:
0459: // Floor to get the integral coordinate
0460: s_ix = (int) Math.floor(s_x);
0461: s_iy = (int) Math.floor(s_y);
0462:
0463: fracx = s_x - (float) s_ix;
0464: fracy = s_y - (float) s_iy;
0465:
0466: // Translate to/from SampleModel space & Raster space
0467: p_x = (s_ix - srcRectX) * srcPixelStride;
0468: p_y = (s_iy - srcRectY) * srcScanlineStride;
0469:
0470: //
0471: // Get the 16 neighbouring positions of the
0472: // coordinate in question (p00).
0473: //
0474: // p__ p0_ p1_ p2_
0475: // p_0 p00 p10 p20
0476: // p_1 p01 p11 p21
0477: // p_2 p02 p12 p22
0478: //
0479: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
0480: p0_ = p__ + srcPixelStride;
0481: p1_ = p0_ + srcPixelStride;
0482: p2_ = p1_ + srcPixelStride;
0483: p_0 = p__ + srcScanlineStride;
0484: p00 = p_0 + srcPixelStride;
0485: p10 = p00 + srcPixelStride;
0486: p20 = p10 + srcPixelStride;
0487: p_1 = p_0 + srcScanlineStride;
0488: p01 = p_1 + srcPixelStride;
0489: p11 = p01 + srcPixelStride;
0490: p21 = p11 + srcPixelStride;
0491: p_2 = p_1 + srcScanlineStride;
0492: p02 = p_2 + srcPixelStride;
0493: p12 = p02 + srcPixelStride;
0494: p22 = p12 + srcPixelStride;
0495:
0496: for (int x = dst_min_x; x < dst_max_x; x++) {
0497: //
0498: // Check against the source rectangle
0499: //
0500: if ((s_ix >= (src_rect_x1 + 1))
0501: && (s_ix < (src_rect_x2 - 2))
0502: && (s_iy >= (src_rect_y1 + 1))
0503: && (s_iy < (src_rect_y2 - 2))) {
0504: for (int k2 = 0; k2 < dst_num_bands; k2++) {
0505: //
0506: // Get the pixels
0507: //
0508: int tmp_row[];
0509: int tmp_col;
0510:
0511: tmp_row = srcDataArrays[k2];
0512: tmp_col = bandOffsets[k2];
0513:
0514: s__ = tmp_row[p__ + tmp_col];
0515: s0_ = tmp_row[p0_ + tmp_col];
0516: s1_ = tmp_row[p1_ + tmp_col];
0517: s2_ = tmp_row[p2_ + tmp_col];
0518: s_0 = tmp_row[p_0 + tmp_col];
0519: s00 = tmp_row[p00 + tmp_col];
0520: s10 = tmp_row[p10 + tmp_col];
0521: s20 = tmp_row[p20 + tmp_col];
0522: s_1 = tmp_row[p_1 + tmp_col];
0523: s01 = tmp_row[p01 + tmp_col];
0524: s11 = tmp_row[p11 + tmp_col];
0525: s21 = tmp_row[p21 + tmp_col];
0526: s_2 = tmp_row[p_2 + tmp_col];
0527: s02 = tmp_row[p02 + tmp_col];
0528: s12 = tmp_row[p12 + tmp_col];
0529: s22 = tmp_row[p22 + tmp_col];
0530:
0531: // Get the new frac values
0532: xfrac = (int) (fracx * shiftvalue);
0533: yfrac = (int) (fracy * shiftvalue);
0534:
0535: // Note that the notations are different from
0536: // what's mentioned in the interpolation class
0537: // For example s0_ here is actually s_0 in the
0538: // Interpolation class
0539:
0540: s = interp.interpolate(s__, s0_, s1_, s2_, s_0,
0541: s00, s10, s20, s_1, s01, s11, s21, s_2,
0542: s02, s12, s22, xfrac, yfrac);
0543:
0544: // Round the result
0545: if (s < (float) (Integer.MIN_VALUE)) {
0546: result = Integer.MIN_VALUE;
0547: } else if (s > (float) (Integer.MAX_VALUE)) {
0548: result = Integer.MAX_VALUE;
0549: } else if (s > 0.0) {
0550: result = (int) (s + 0.5F);
0551: } else {
0552: result = (int) (s - 0.5F);
0553: }
0554:
0555: // write the result
0556: dstDataArrays[k2][dstPixelOffset
0557: + dstBandOffsets[k2]] = result;
0558: }
0559: } else if (setBackground) {
0560: for (int k = 0; k < dst_num_bands; k++)
0561: dstDataArrays[k][dstPixelOffset
0562: + dstBandOffsets[k]] = backgroundInt[k];
0563: }
0564:
0565: // walk
0566: if (fracx < fracdx1) {
0567: s_ix += incx;
0568: fracx += fracdx;
0569: if (fracx == 1.0F) {
0570: // To avoid overflow in the interpolation table
0571: fracx = 0.999999F;
0572: }
0573: } else {
0574: s_ix += incx1;
0575: fracx -= fracdx1;
0576: }
0577:
0578: if (fracy < fracdy1) {
0579: s_iy += incy;
0580: fracy += fracdy;
0581: if (fracy == 1.0F) {
0582: // To avoid overflow in the interpolation table
0583: fracy = 0.999999F;
0584: }
0585: } else {
0586: s_iy += incy1;
0587: fracy -= fracdy1;
0588: }
0589:
0590: // Translate to/from SampleModel space & Raster space
0591: p_x = (s_ix - srcRectX) * srcPixelStride;
0592: p_y = (s_iy - srcRectY) * srcScanlineStride;
0593:
0594: //
0595: // Get the 16 neighbouring positions of the
0596: // coordinate in question (p00).
0597: //
0598: // p__ p0_ p1_ p2_
0599: // p_0 p00 p10 p20
0600: // p_1 p01 p11 p21
0601: // p_2 p02 p12 p22
0602: //
0603: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
0604: p0_ = p__ + srcPixelStride;
0605: p1_ = p0_ + srcPixelStride;
0606: p2_ = p1_ + srcPixelStride;
0607: p_0 = p__ + srcScanlineStride;
0608: p00 = p_0 + srcPixelStride;
0609: p10 = p00 + srcPixelStride;
0610: p20 = p10 + srcPixelStride;
0611: p_1 = p_0 + srcScanlineStride;
0612: p01 = p_1 + srcPixelStride;
0613: p11 = p01 + srcPixelStride;
0614: p21 = p11 + srcPixelStride;
0615: p_2 = p_1 + srcScanlineStride;
0616: p02 = p_2 + srcPixelStride;
0617: p12 = p02 + srcPixelStride;
0618: p22 = p12 + srcPixelStride;
0619:
0620: dstPixelOffset += dstPixelStride;
0621: }
0622:
0623: dstOffset += dstScanlineStride;
0624: }
0625: }
0626:
0627: private void shortLoop(RasterAccessor src, Rectangle destRect,
0628: int srcRectX, int srcRectY, RasterAccessor dst) {
0629:
0630: float src_rect_x1 = src.getX();
0631: float src_rect_y1 = src.getY();
0632: float src_rect_x2 = src_rect_x1 + src.getWidth();
0633: float src_rect_y2 = src_rect_y1 + src.getHeight();
0634:
0635: float s_x, s_y;
0636:
0637: float fracx, fracy;
0638: float float_fracx, float_fracy;
0639: float frac_xx, frac_yy;
0640:
0641: int s_ix, s_iy;
0642: int p_x, p_y;
0643:
0644: int p__, p0_, p1_, p2_;
0645: int p_0, p00, p01, p02;
0646: int p_1, p10, p11, p12;
0647: int p_2, p20, p21, p22;
0648:
0649: short s__, s0_, s1_, s2_;
0650: short s_0, s00, s01, s02;
0651: short s_1, s10, s11, s12;
0652: short s_2, s20, s21, s22;
0653:
0654: float s0, s1, s_, s2;
0655: float q_, q0, q1, q2;
0656: float s, q;
0657:
0658: int xfrac, yfrac;
0659:
0660: short result;
0661:
0662: int dstPixelOffset;
0663: int dstOffset = 0;
0664:
0665: Point2D dst_pt = new Point2D.Float();
0666: Point2D src_pt = new Point2D.Float();
0667:
0668: short dstDataArrays[][] = dst.getShortDataArrays();
0669: int dstBandOffsets[] = dst.getBandOffsets();
0670: int dstPixelStride = dst.getPixelStride();
0671: int dstScanlineStride = dst.getScanlineStride();
0672:
0673: short srcDataArrays[][] = src.getShortDataArrays();
0674: int bandOffsets[] = src.getBandOffsets();
0675: int srcPixelStride = src.getPixelStride();
0676: int srcScanlineStride = src.getScanlineStride();
0677:
0678: int dst_num_bands = dst.getNumBands();
0679:
0680: int dst_min_x = destRect.x;
0681: int dst_min_y = destRect.y;
0682: int dst_max_x = destRect.x + destRect.width;
0683: int dst_max_y = destRect.y + destRect.height;
0684:
0685: short[] backgroundShort = new short[dst_num_bands];
0686: for (int i = 0; i < dst_num_bands; i++)
0687: backgroundShort[i] = (short) backgroundValues[i];
0688:
0689: for (int y = dst_min_y; y < dst_max_y; y++) {
0690:
0691: dstPixelOffset = dstOffset;
0692:
0693: // Backward map the first point in the line
0694: // The energy is at the (pt_x + 0.5, pt_y + 0.5)
0695: dst_pt.setLocation((double) dst_min_x + 0.5,
0696: (double) y + 0.5);
0697: mapDestPoint(dst_pt, src_pt);
0698:
0699: // Get the mapped source coordinates
0700: s_x = (float) src_pt.getX();
0701: s_y = (float) src_pt.getY();
0702:
0703: // As per definition of bicubic interpolation
0704: s_x -= 0.5;
0705: s_y -= 0.5;
0706:
0707: // Floor to get the integral coordinate
0708: s_ix = (int) Math.floor(s_x);
0709: s_iy = (int) Math.floor(s_y);
0710:
0711: fracx = s_x - (float) s_ix;
0712: fracy = s_y - (float) s_iy;
0713:
0714: // Translate to/from SampleModel space & Raster space
0715: p_x = (s_ix - srcRectX) * srcPixelStride;
0716: p_y = (s_iy - srcRectY) * srcScanlineStride;
0717:
0718: //
0719: // Get the 16 neighbouring positions of the
0720: // coordinate in question (p00).
0721: //
0722: // p__ p0_ p1_ p2_
0723: // p_0 p00 p10 p20
0724: // p_1 p01 p11 p21
0725: // p_2 p02 p12 p22
0726: //
0727: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
0728: p0_ = p__ + srcPixelStride;
0729: p1_ = p0_ + srcPixelStride;
0730: p2_ = p1_ + srcPixelStride;
0731: p_0 = p__ + srcScanlineStride;
0732: p00 = p_0 + srcPixelStride;
0733: p10 = p00 + srcPixelStride;
0734: p20 = p10 + srcPixelStride;
0735: p_1 = p_0 + srcScanlineStride;
0736: p01 = p_1 + srcPixelStride;
0737: p11 = p01 + srcPixelStride;
0738: p21 = p11 + srcPixelStride;
0739: p_2 = p_1 + srcScanlineStride;
0740: p02 = p_2 + srcPixelStride;
0741: p12 = p02 + srcPixelStride;
0742: p22 = p12 + srcPixelStride;
0743:
0744: for (int x = dst_min_x; x < dst_max_x; x++) {
0745: //
0746: // Check against the source rectangle
0747: //
0748: if ((s_ix >= (src_rect_x1 + 1))
0749: && (s_ix < (src_rect_x2 - 2))
0750: && (s_iy >= (src_rect_y1 + 1))
0751: && (s_iy < (src_rect_y2 - 2))) {
0752: for (int k2 = 0; k2 < dst_num_bands; k2++) {
0753: //
0754: // Get the pixels
0755: //
0756: short tmp_row[];
0757: int tmp_col;
0758:
0759: tmp_row = srcDataArrays[k2];
0760: tmp_col = bandOffsets[k2];
0761:
0762: s__ = tmp_row[p__ + tmp_col];
0763: s0_ = tmp_row[p0_ + tmp_col];
0764: s1_ = tmp_row[p1_ + tmp_col];
0765: s2_ = tmp_row[p2_ + tmp_col];
0766: s_0 = tmp_row[p_0 + tmp_col];
0767: s00 = tmp_row[p00 + tmp_col];
0768: s10 = tmp_row[p10 + tmp_col];
0769: s20 = tmp_row[p20 + tmp_col];
0770: s_1 = tmp_row[p_1 + tmp_col];
0771: s01 = tmp_row[p01 + tmp_col];
0772: s11 = tmp_row[p11 + tmp_col];
0773: s21 = tmp_row[p21 + tmp_col];
0774: s_2 = tmp_row[p_2 + tmp_col];
0775: s02 = tmp_row[p02 + tmp_col];
0776: s12 = tmp_row[p12 + tmp_col];
0777: s22 = tmp_row[p22 + tmp_col];
0778:
0779: // Get the new frac values
0780: xfrac = (int) (fracx * shiftvalue);
0781: yfrac = (int) (fracy * shiftvalue);
0782:
0783: // Note that the notations are different from
0784: // what's mentioned in the interpolation class
0785: // For example s0_ here is actually s_0 in the
0786: // Interpolation class
0787:
0788: s = interp.interpolate(s__, s0_, s1_, s2_, s_0,
0789: s00, s10, s20, s_1, s01, s11, s21, s_2,
0790: s02, s12, s22, xfrac, yfrac);
0791:
0792: // Round the result
0793: if (s < (float) Short.MIN_VALUE) {
0794: result = Short.MIN_VALUE;
0795: } else if (s > (float) Short.MAX_VALUE) {
0796: result = Short.MAX_VALUE;
0797: } else if (s > 0.0) {
0798: result = (short) (s + 0.5F);
0799: } else {
0800: result = (short) (s - 0.5F);
0801: }
0802:
0803: // write the result
0804: dstDataArrays[k2][dstPixelOffset
0805: + dstBandOffsets[k2]] = result;
0806: }
0807: } else if (setBackground) {
0808: for (int k = 0; k < dst_num_bands; k++)
0809: dstDataArrays[k][dstPixelOffset
0810: + dstBandOffsets[k]] = backgroundShort[k];
0811: }
0812:
0813: // walk
0814: if (fracx < fracdx1) {
0815: s_ix += incx;
0816: fracx += fracdx;
0817: if (fracx == 1.0F) {
0818: // To avoid overflow in the interpolation table
0819: fracx = 0.999999F;
0820: }
0821: } else {
0822: s_ix += incx1;
0823: fracx -= fracdx1;
0824: }
0825:
0826: if (fracy < fracdy1) {
0827: s_iy += incy;
0828: fracy += fracdy;
0829: if (fracy == 1.0F) {
0830: // To avoid overflow in the interpolation table
0831: fracy = 0.999999F;
0832: }
0833: } else {
0834: s_iy += incy1;
0835: fracy -= fracdy1;
0836: }
0837:
0838: // Translate to/from SampleModel space & Raster space
0839: p_x = (s_ix - srcRectX) * srcPixelStride;
0840: p_y = (s_iy - srcRectY) * srcScanlineStride;
0841:
0842: //
0843: // Get the 16 neighbouring positions of the
0844: // coordinate in question (p00).
0845: //
0846: // p__ p0_ p1_ p2_
0847: // p_0 p00 p10 p20
0848: // p_1 p01 p11 p21
0849: // p_2 p02 p12 p22
0850: //
0851: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
0852: p0_ = p__ + srcPixelStride;
0853: p1_ = p0_ + srcPixelStride;
0854: p2_ = p1_ + srcPixelStride;
0855: p_0 = p__ + srcScanlineStride;
0856: p00 = p_0 + srcPixelStride;
0857: p10 = p00 + srcPixelStride;
0858: p20 = p10 + srcPixelStride;
0859: p_1 = p_0 + srcScanlineStride;
0860: p01 = p_1 + srcPixelStride;
0861: p11 = p01 + srcPixelStride;
0862: p21 = p11 + srcPixelStride;
0863: p_2 = p_1 + srcScanlineStride;
0864: p02 = p_2 + srcPixelStride;
0865: p12 = p02 + srcPixelStride;
0866: p22 = p12 + srcPixelStride;
0867:
0868: dstPixelOffset += dstPixelStride;
0869: }
0870:
0871: dstOffset += dstScanlineStride;
0872: }
0873: }
0874:
0875: private void ushortLoop(RasterAccessor src, Rectangle destRect,
0876: int srcRectX, int srcRectY, RasterAccessor dst) {
0877:
0878: float src_rect_x1 = src.getX();
0879: float src_rect_y1 = src.getY();
0880: float src_rect_x2 = src_rect_x1 + src.getWidth();
0881: float src_rect_y2 = src_rect_y1 + src.getHeight();
0882:
0883: float s_x, s_y;
0884:
0885: float fracx, fracy;
0886: float float_fracx, float_fracy;
0887: float frac_xx, frac_yy;
0888:
0889: int s_ix, s_iy;
0890: int p_x, p_y;
0891:
0892: int p__, p0_, p1_, p2_;
0893: int p_0, p00, p01, p02;
0894: int p_1, p10, p11, p12;
0895: int p_2, p20, p21, p22;
0896:
0897: int s__, s0_, s1_, s2_;
0898: int s_0, s00, s01, s02;
0899: int s_1, s10, s11, s12;
0900: int s_2, s20, s21, s22;
0901:
0902: float s0, s1, s_, s2;
0903: float q_, q0, q1, q2;
0904: float s, q;
0905:
0906: int xfrac, yfrac;
0907:
0908: int result;
0909:
0910: int dstPixelOffset;
0911: int dstOffset = 0;
0912:
0913: Point2D dst_pt = new Point2D.Float();
0914: Point2D src_pt = new Point2D.Float();
0915:
0916: short dstDataArrays[][] = dst.getShortDataArrays();
0917: int dstBandOffsets[] = dst.getBandOffsets();
0918: int dstPixelStride = dst.getPixelStride();
0919: int dstScanlineStride = dst.getScanlineStride();
0920:
0921: short srcDataArrays[][] = src.getShortDataArrays();
0922: int bandOffsets[] = src.getBandOffsets();
0923: int srcPixelStride = src.getPixelStride();
0924: int srcScanlineStride = src.getScanlineStride();
0925:
0926: int dst_num_bands = dst.getNumBands();
0927:
0928: int dst_min_x = destRect.x;
0929: int dst_min_y = destRect.y;
0930: int dst_max_x = destRect.x + destRect.width;
0931: int dst_max_y = destRect.y + destRect.height;
0932:
0933: short[] backgroundUShort = new short[dst_num_bands];
0934: for (int i = 0; i < dst_num_bands; i++)
0935: backgroundUShort[i] = (short) backgroundValues[i];
0936:
0937: for (int y = dst_min_y; y < dst_max_y; y++) {
0938: dstPixelOffset = dstOffset;
0939:
0940: // Backward map the first point in the line
0941: // The energy is at the (pt_x + 0.5, pt_y + 0.5)
0942: dst_pt.setLocation((double) dst_min_x + 0.5,
0943: (double) y + 0.5);
0944: mapDestPoint(dst_pt, src_pt);
0945:
0946: // Get the mapped source coordinates
0947: s_x = (float) src_pt.getX();
0948: s_y = (float) src_pt.getY();
0949:
0950: // As per definition of bicubic interpolation
0951: s_x -= 0.5;
0952: s_y -= 0.5;
0953:
0954: // Floor to get the integral coordinate
0955: s_ix = (int) Math.floor(s_x);
0956: s_iy = (int) Math.floor(s_y);
0957:
0958: fracx = s_x - (float) s_ix;
0959: fracy = s_y - (float) s_iy;
0960:
0961: // Translate to/from SampleModel space & Raster space
0962: p_x = (s_ix - srcRectX) * srcPixelStride;
0963: p_y = (s_iy - srcRectY) * srcScanlineStride;
0964:
0965: //
0966: // Get the 16 neighbouring positions of the
0967: // coordinate in question (p00).
0968: //
0969: // p__ p0_ p1_ p2_
0970: // p_0 p00 p10 p20
0971: // p_1 p01 p11 p21
0972: // p_2 p02 p12 p22
0973: //
0974: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
0975: p0_ = p__ + srcPixelStride;
0976: p1_ = p0_ + srcPixelStride;
0977: p2_ = p1_ + srcPixelStride;
0978: p_0 = p__ + srcScanlineStride;
0979: p00 = p_0 + srcPixelStride;
0980: p10 = p00 + srcPixelStride;
0981: p20 = p10 + srcPixelStride;
0982: p_1 = p_0 + srcScanlineStride;
0983: p01 = p_1 + srcPixelStride;
0984: p11 = p01 + srcPixelStride;
0985: p21 = p11 + srcPixelStride;
0986: p_2 = p_1 + srcScanlineStride;
0987: p02 = p_2 + srcPixelStride;
0988: p12 = p02 + srcPixelStride;
0989: p22 = p12 + srcPixelStride;
0990:
0991: for (int x = dst_min_x; x < dst_max_x; x++) {
0992: //
0993: // Check against the source rectangle
0994: //
0995: if ((s_ix >= (src_rect_x1 + 1))
0996: && (s_ix < (src_rect_x2 - 2))
0997: && (s_iy >= (src_rect_y1 + 1))
0998: && (s_iy < (src_rect_y2 - 2))) {
0999: for (int k2 = 0; k2 < dst_num_bands; k2++) {
1000: //
1001: // Get the pixels
1002: //
1003: short tmp_row[];
1004: int tmp_col;
1005:
1006: tmp_row = srcDataArrays[k2];
1007: tmp_col = bandOffsets[k2];
1008:
1009: s__ = tmp_row[p__ + tmp_col] & 0xffff;
1010: s0_ = tmp_row[p0_ + tmp_col] & 0xffff;
1011: s1_ = tmp_row[p1_ + tmp_col] & 0xffff;
1012: s2_ = tmp_row[p2_ + tmp_col] & 0xffff;
1013: s_0 = tmp_row[p_0 + tmp_col] & 0xffff;
1014: s00 = tmp_row[p00 + tmp_col] & 0xffff;
1015: s10 = tmp_row[p10 + tmp_col] & 0xffff;
1016: s20 = tmp_row[p20 + tmp_col] & 0xffff;
1017: s_1 = tmp_row[p_1 + tmp_col] & 0xffff;
1018: s01 = tmp_row[p01 + tmp_col] & 0xffff;
1019: s11 = tmp_row[p11 + tmp_col] & 0xffff;
1020: s21 = tmp_row[p21 + tmp_col] & 0xffff;
1021: s_2 = tmp_row[p_2 + tmp_col] & 0xffff;
1022: s02 = tmp_row[p02 + tmp_col] & 0xffff;
1023: s12 = tmp_row[p12 + tmp_col] & 0xffff;
1024: s22 = tmp_row[p22 + tmp_col] & 0xffff;
1025:
1026: // Get the new frac values
1027: // Get the new frac values
1028: xfrac = (int) (fracx * shiftvalue);
1029: yfrac = (int) (fracy * shiftvalue);
1030:
1031: // Note that the notations are different from
1032: // what's mentioned in the interpolation class
1033: // For example s0_ here is actually s_0 in the
1034: // Interpolation class
1035:
1036: s = interp.interpolate(s__, s0_, s1_, s2_, s_0,
1037: s00, s10, s20, s_1, s01, s11, s21, s_2,
1038: s02, s12, s22, xfrac, yfrac);
1039:
1040: // Round
1041: if (s < 0.0) {
1042: result = 0;
1043: } else if (s > (float) USHORT_MAX) {
1044: result = USHORT_MAX;
1045: } else {
1046: result = (int) (s + 0.5F);
1047: }
1048:
1049: // write the result
1050: dstDataArrays[k2][dstPixelOffset
1051: + dstBandOffsets[k2]] = (short) (result & 0xFFFF);
1052: }
1053: } else if (setBackground) {
1054: for (int k = 0; k < dst_num_bands; k++)
1055: dstDataArrays[k][dstPixelOffset
1056: + dstBandOffsets[k]] = backgroundUShort[k];
1057: }
1058:
1059: // walk
1060: if (fracx < fracdx1) {
1061: s_ix += incx;
1062: fracx += fracdx;
1063: if (fracx == 1.0F) {
1064: // To avoid overflow in the interpolation table
1065: fracx = 0.999999F;
1066: }
1067: } else {
1068: s_ix += incx1;
1069: fracx -= fracdx1;
1070: }
1071:
1072: if (fracy < fracdy1) {
1073: s_iy += incy;
1074: fracy += fracdy;
1075: if (fracy == 1.0F) {
1076: // To avoid overflow in the interpolation table
1077: fracy = 0.999999F;
1078: }
1079: } else {
1080: s_iy += incy1;
1081: fracy -= fracdy1;
1082: }
1083:
1084: // Translate to/from SampleModel space & Raster space
1085: p_x = (s_ix - srcRectX) * srcPixelStride;
1086: p_y = (s_iy - srcRectY) * srcScanlineStride;
1087:
1088: //
1089: // Get the 16 neighbouring positions of the
1090: // coordinate in question (p00).
1091: //
1092: // p__ p0_ p1_ p2_
1093: // p_0 p00 p10 p20
1094: // p_1 p01 p11 p21
1095: // p_2 p02 p12 p22
1096: //
1097: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
1098: p0_ = p__ + srcPixelStride;
1099: p1_ = p0_ + srcPixelStride;
1100: p2_ = p1_ + srcPixelStride;
1101: p_0 = p__ + srcScanlineStride;
1102: p00 = p_0 + srcPixelStride;
1103: p10 = p00 + srcPixelStride;
1104: p20 = p10 + srcPixelStride;
1105: p_1 = p_0 + srcScanlineStride;
1106: p01 = p_1 + srcPixelStride;
1107: p11 = p01 + srcPixelStride;
1108: p21 = p11 + srcPixelStride;
1109: p_2 = p_1 + srcScanlineStride;
1110: p02 = p_2 + srcPixelStride;
1111: p12 = p02 + srcPixelStride;
1112: p22 = p12 + srcPixelStride;
1113:
1114: dstPixelOffset += dstPixelStride;
1115: }
1116:
1117: dstOffset += dstScanlineStride;
1118: }
1119: }
1120:
1121: private void floatLoop(RasterAccessor src, Rectangle destRect,
1122: int srcRectX, int srcRectY, RasterAccessor dst) {
1123:
1124: float src_rect_x1 = src.getX();
1125: float src_rect_y1 = src.getY();
1126: float src_rect_x2 = src_rect_x1 + src.getWidth();
1127: float src_rect_y2 = src_rect_y1 + src.getHeight();
1128:
1129: float s_x, s_y;
1130:
1131: float fracx, fracy;
1132: float float_fracx, float_fracy;
1133: float frac_xx, frac_yy;
1134:
1135: int s_ix, s_iy;
1136: int p_x, p_y;
1137:
1138: int p__, p0_, p1_, p2_;
1139: int p_0, p00, p01, p02;
1140: int p_1, p10, p11, p12;
1141: int p_2, p20, p21, p22;
1142:
1143: float s__, s0_, s1_, s2_;
1144: float s_0, s00, s01, s02;
1145: float s_1, s10, s11, s12;
1146: float s_2, s20, s21, s22;
1147:
1148: float s0, s1, s_, s2;
1149: float q_, q0, q1, q2;
1150: float s, q;
1151:
1152: int dstPixelOffset;
1153: int dstOffset = 0;
1154:
1155: Point2D dst_pt = new Point2D.Float();
1156: Point2D src_pt = new Point2D.Float();
1157:
1158: float dstDataArrays[][] = dst.getFloatDataArrays();
1159: int dstBandOffsets[] = dst.getBandOffsets();
1160: int dstPixelStride = dst.getPixelStride();
1161: int dstScanlineStride = dst.getScanlineStride();
1162:
1163: float srcDataArrays[][] = src.getFloatDataArrays();
1164: int bandOffsets[] = src.getBandOffsets();
1165: int srcPixelStride = src.getPixelStride();
1166: int srcScanlineStride = src.getScanlineStride();
1167:
1168: int dst_num_bands = dst.getNumBands();
1169:
1170: int dst_min_x = destRect.x;
1171: int dst_min_y = destRect.y;
1172: int dst_max_x = destRect.x + destRect.width;
1173: int dst_max_y = destRect.y + destRect.height;
1174:
1175: float[] backgroundFloat = new float[dst_num_bands];
1176: for (int i = 0; i < dst_num_bands; i++)
1177: backgroundFloat[i] = (float) backgroundValues[i];
1178:
1179: for (int y = dst_min_y; y < dst_max_y; y++) {
1180:
1181: dstPixelOffset = dstOffset;
1182:
1183: // Backward map the first point in the line
1184: // The energy is at the (pt_x + 0.5, pt_y + 0.5)
1185: dst_pt.setLocation((double) dst_min_x + 0.5,
1186: (double) y + 0.5);
1187: mapDestPoint(dst_pt, src_pt);
1188:
1189: // Get the mapped source coordinates
1190: s_x = (float) src_pt.getX();
1191: s_y = (float) src_pt.getY();
1192:
1193: // As per definition of bicubic interpolation
1194: s_x -= 0.5;
1195: s_y -= 0.5;
1196:
1197: // Floor to get the integral coordinate
1198: s_ix = (int) Math.floor(s_x);
1199: s_iy = (int) Math.floor(s_y);
1200:
1201: fracx = s_x - (float) s_ix;
1202: fracy = s_y - (float) s_iy;
1203:
1204: // Translate to/from SampleModel space & Raster space
1205: p_x = (s_ix - srcRectX) * srcPixelStride;
1206: p_y = (s_iy - srcRectY) * srcScanlineStride;
1207:
1208: //
1209: // Get the 16 neighbouring positions of the
1210: // coordinate in question (p00).
1211: //
1212: // p__ p0_ p1_ p2_
1213: // p_0 p00 p10 p20
1214: // p_1 p01 p11 p21
1215: // p_2 p02 p12 p22
1216: //
1217: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
1218: p0_ = p__ + srcPixelStride;
1219: p1_ = p0_ + srcPixelStride;
1220: p2_ = p1_ + srcPixelStride;
1221: p_0 = p__ + srcScanlineStride;
1222: p00 = p_0 + srcPixelStride;
1223: p10 = p00 + srcPixelStride;
1224: p20 = p10 + srcPixelStride;
1225: p_1 = p_0 + srcScanlineStride;
1226: p01 = p_1 + srcPixelStride;
1227: p11 = p01 + srcPixelStride;
1228: p21 = p11 + srcPixelStride;
1229: p_2 = p_1 + srcScanlineStride;
1230: p02 = p_2 + srcPixelStride;
1231: p12 = p02 + srcPixelStride;
1232: p22 = p12 + srcPixelStride;
1233:
1234: for (int x = dst_min_x; x < dst_max_x; x++) {
1235: //
1236: // Check against the source rectangle
1237: //
1238: if ((s_ix >= (src_rect_x1 + 1))
1239: && (s_ix < (src_rect_x2 - 2))
1240: && (s_iy >= (src_rect_y1 + 1))
1241: && (s_iy < (src_rect_y2 - 2))) {
1242: for (int k2 = 0; k2 < dst_num_bands; k2++) {
1243: //
1244: // Get the pixels
1245: //
1246: float tmp_row[];
1247: int tmp_col;
1248:
1249: tmp_row = srcDataArrays[k2];
1250: tmp_col = bandOffsets[k2];
1251:
1252: s__ = tmp_row[p__ + tmp_col];
1253: s0_ = tmp_row[p0_ + tmp_col];
1254: s1_ = tmp_row[p1_ + tmp_col];
1255: s2_ = tmp_row[p2_ + tmp_col];
1256: s_0 = tmp_row[p_0 + tmp_col];
1257: s00 = tmp_row[p00 + tmp_col];
1258: s10 = tmp_row[p10 + tmp_col];
1259: s20 = tmp_row[p20 + tmp_col];
1260: s_1 = tmp_row[p_1 + tmp_col];
1261: s01 = tmp_row[p01 + tmp_col];
1262: s11 = tmp_row[p11 + tmp_col];
1263: s21 = tmp_row[p21 + tmp_col];
1264: s_2 = tmp_row[p_2 + tmp_col];
1265: s02 = tmp_row[p02 + tmp_col];
1266: s12 = tmp_row[p12 + tmp_col];
1267: s22 = tmp_row[p22 + tmp_col];
1268:
1269: // Note that the notations are different from
1270: // what's mentioned in the interpolation class
1271: // For example s0_ here is actually s_0 in the
1272: // Interpolation class
1273: s = interp.interpolate(s__, s0_, s1_, s2_, s_0,
1274: s00, s10, s20, s_1, s01, s11, s21, s_2,
1275: s02, s12, s22, fracx, fracy);
1276:
1277: // write the result
1278: dstDataArrays[k2][dstPixelOffset
1279: + dstBandOffsets[k2]] = s;
1280: }
1281: } else if (setBackground) {
1282: for (int k = 0; k < dst_num_bands; k++)
1283: dstDataArrays[k][dstPixelOffset
1284: + dstBandOffsets[k]] = backgroundFloat[k];
1285: }
1286:
1287: // walk
1288: if (fracx < fracdx1) {
1289: s_ix += incx;
1290: fracx += fracdx;
1291: if (fracx == 1.0F) {
1292: // To avoid overflow in the interpolation table
1293: fracx = 0.999999F;
1294: }
1295: } else {
1296: s_ix += incx1;
1297: fracx -= fracdx1;
1298: }
1299:
1300: if (fracy < fracdy1) {
1301: s_iy += incy;
1302: fracy += fracdy;
1303: if (fracy == 1.0F) {
1304: // To avoid overflow in the interpolation table
1305: fracy = 0.999999F;
1306: }
1307: } else {
1308: s_iy += incy1;
1309: fracy -= fracdy1;
1310: }
1311:
1312: // Translate to/from SampleModel space & Raster space
1313: p_x = (s_ix - srcRectX) * srcPixelStride;
1314: p_y = (s_iy - srcRectY) * srcScanlineStride;
1315:
1316: //
1317: // Get the 16 neighbouring positions of the
1318: // coordinate in question (p00).
1319: //
1320: // p__ p0_ p1_ p2_
1321: // p_0 p00 p10 p20
1322: // p_1 p01 p11 p21
1323: // p_2 p02 p12 p22
1324: //
1325: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
1326: p0_ = p__ + srcPixelStride;
1327: p1_ = p0_ + srcPixelStride;
1328: p2_ = p1_ + srcPixelStride;
1329: p_0 = p__ + srcScanlineStride;
1330: p00 = p_0 + srcPixelStride;
1331: p10 = p00 + srcPixelStride;
1332: p20 = p10 + srcPixelStride;
1333: p_1 = p_0 + srcScanlineStride;
1334: p01 = p_1 + srcPixelStride;
1335: p11 = p01 + srcPixelStride;
1336: p21 = p11 + srcPixelStride;
1337: p_2 = p_1 + srcScanlineStride;
1338: p02 = p_2 + srcPixelStride;
1339: p12 = p02 + srcPixelStride;
1340: p22 = p12 + srcPixelStride;
1341:
1342: dstPixelOffset += dstPixelStride;
1343: }
1344:
1345: dstOffset += dstScanlineStride;
1346: }
1347: }
1348:
1349: private void doubleLoop(RasterAccessor src, Rectangle destRect,
1350: int srcRectX, int srcRectY, RasterAccessor dst) {
1351:
1352: float src_rect_x1 = src.getX();
1353: float src_rect_y1 = src.getY();
1354: float src_rect_x2 = src_rect_x1 + src.getWidth();
1355: float src_rect_y2 = src_rect_y1 + src.getHeight();
1356:
1357: double s_x, s_y;
1358:
1359: double fracx, fracy;
1360: double float_fracx, float_fracy;
1361: double frac_xx, frac_yy;
1362:
1363: int s_ix, s_iy;
1364: int p_x, p_y;
1365:
1366: int p__, p0_, p1_, p2_;
1367: int p_0, p00, p01, p02;
1368: int p_1, p10, p11, p12;
1369: int p_2, p20, p21, p22;
1370:
1371: double s__, s0_, s1_, s2_;
1372: double s_0, s00, s01, s02;
1373: double s_1, s10, s11, s12;
1374: double s_2, s20, s21, s22;
1375:
1376: double s0, s1, s_, s2;
1377: double q_, q0, q1, q2;
1378: double s, q;
1379:
1380: int dstPixelOffset;
1381: int dstOffset = 0;
1382:
1383: Point2D dst_pt = new Point2D.Float();
1384: Point2D src_pt = new Point2D.Float();
1385:
1386: double dstDataArrays[][] = dst.getDoubleDataArrays();
1387: int dstBandOffsets[] = dst.getBandOffsets();
1388: int dstPixelStride = dst.getPixelStride();
1389: int dstScanlineStride = dst.getScanlineStride();
1390:
1391: double srcDataArrays[][] = src.getDoubleDataArrays();
1392: int bandOffsets[] = src.getBandOffsets();
1393: int srcPixelStride = src.getPixelStride();
1394: int srcScanlineStride = src.getScanlineStride();
1395:
1396: int dst_num_bands = dst.getNumBands();
1397:
1398: int dst_min_x = destRect.x;
1399: int dst_min_y = destRect.y;
1400: int dst_max_x = destRect.x + destRect.width;
1401: int dst_max_y = destRect.y + destRect.height;
1402:
1403: for (int y = dst_min_y; y < dst_max_y; y++) {
1404:
1405: dstPixelOffset = dstOffset;
1406:
1407: // Backward map the first point in the line
1408: // The energy is at the (pt_x + 0.5, pt_y + 0.5)
1409: dst_pt.setLocation((double) dst_min_x + 0.5,
1410: (double) y + 0.5);
1411: mapDestPoint(dst_pt, src_pt);
1412:
1413: // Get the mapped source coordinates
1414: s_x = (double) src_pt.getX();
1415: s_y = (double) src_pt.getY();
1416:
1417: // As per definition of bicubic interpolation
1418: s_x -= 0.5;
1419: s_y -= 0.5;
1420:
1421: // Floor to get the integral coordinate
1422: s_ix = (int) Math.floor(s_x);
1423: s_iy = (int) Math.floor(s_y);
1424:
1425: fracx = s_x - (double) s_ix;
1426: fracy = s_y - (double) s_iy;
1427:
1428: // Translate to/from SampleModel space & Raster space
1429: p_x = (s_ix - srcRectX) * srcPixelStride;
1430: p_y = (s_iy - srcRectY) * srcScanlineStride;
1431:
1432: //
1433: // Get the 16 neighbouring positions of the
1434: // coordinate in question (p00).
1435: //
1436: // p__ p0_ p1_ p2_
1437: // p_0 p00 p10 p20
1438: // p_1 p01 p11 p21
1439: // p_2 p02 p12 p22
1440: //
1441: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
1442: p0_ = p__ + srcPixelStride;
1443: p1_ = p0_ + srcPixelStride;
1444: p2_ = p1_ + srcPixelStride;
1445: p_0 = p__ + srcScanlineStride;
1446: p00 = p_0 + srcPixelStride;
1447: p10 = p00 + srcPixelStride;
1448: p20 = p10 + srcPixelStride;
1449: p_1 = p_0 + srcScanlineStride;
1450: p01 = p_1 + srcPixelStride;
1451: p11 = p01 + srcPixelStride;
1452: p21 = p11 + srcPixelStride;
1453: p_2 = p_1 + srcScanlineStride;
1454: p02 = p_2 + srcPixelStride;
1455: p12 = p02 + srcPixelStride;
1456: p22 = p12 + srcPixelStride;
1457:
1458: for (int x = dst_min_x; x < dst_max_x; x++) {
1459: //
1460: // Check against the source rectangle
1461: //
1462: if ((s_ix >= (src_rect_x1 + 1))
1463: && (s_ix < (src_rect_x2 - 2))
1464: && (s_iy >= (src_rect_y1 + 1))
1465: && (s_iy < (src_rect_y2 - 2))) {
1466: for (int k2 = 0; k2 < dst_num_bands; k2++) {
1467: //
1468: // Get the pixels
1469: //
1470: double tmp_row[];
1471: int tmp_col;
1472:
1473: tmp_row = srcDataArrays[k2];
1474: tmp_col = bandOffsets[k2];
1475:
1476: s__ = tmp_row[p__ + tmp_col];
1477: s0_ = tmp_row[p0_ + tmp_col];
1478: s1_ = tmp_row[p1_ + tmp_col];
1479: s2_ = tmp_row[p2_ + tmp_col];
1480: s_0 = tmp_row[p_0 + tmp_col];
1481: s00 = tmp_row[p00 + tmp_col];
1482: s10 = tmp_row[p10 + tmp_col];
1483: s20 = tmp_row[p20 + tmp_col];
1484: s_1 = tmp_row[p_1 + tmp_col];
1485: s01 = tmp_row[p01 + tmp_col];
1486: s11 = tmp_row[p11 + tmp_col];
1487: s21 = tmp_row[p21 + tmp_col];
1488: s_2 = tmp_row[p_2 + tmp_col];
1489: s02 = tmp_row[p02 + tmp_col];
1490: s12 = tmp_row[p12 + tmp_col];
1491: s22 = tmp_row[p22 + tmp_col];
1492:
1493: // Note that the notations are different from
1494: // what's mentioned in the interpolation class
1495: // For example s0_ here is actually s_0 in the
1496: // Interpolation class
1497:
1498: s = interp.interpolate(s__, s0_, s1_, s2_, s_0,
1499: s00, s10, s20, s_1, s01, s11, s21, s_2,
1500: s02, s12, s22, (float) fracx,
1501: (float) fracy);
1502:
1503: // write the result
1504: dstDataArrays[k2][dstPixelOffset
1505: + dstBandOffsets[k2]] = s;
1506: }
1507: } else if (setBackground) {
1508: for (int k = 0; k < dst_num_bands; k++)
1509: dstDataArrays[k][dstPixelOffset
1510: + dstBandOffsets[k]] = backgroundValues[k];
1511: }
1512:
1513: // walk
1514: if (fracx < fracdx1) {
1515: s_ix += incx;
1516: fracx += fracdx;
1517: if (fracx == 1.0) {
1518: // To avoid overflow in the interpolation table
1519: fracx = 0.999999;
1520: }
1521: } else {
1522: s_ix += incx1;
1523: fracx -= fracdx1;
1524: }
1525:
1526: if (fracy < fracdy1) {
1527: s_iy += incy;
1528: fracy += fracdy;
1529: if (fracy == 1.0) {
1530: // To avoid overflow in the interpolation table
1531: fracy = 0.999999;
1532: }
1533: } else {
1534: s_iy += incy1;
1535: fracy -= fracdy1;
1536: }
1537:
1538: // Translate to/from SampleModel space & Raster space
1539: p_x = (s_ix - srcRectX) * srcPixelStride;
1540: p_y = (s_iy - srcRectY) * srcScanlineStride;
1541:
1542: //
1543: // Get the 16 neighbouring positions of the
1544: // coordinate in question (p00).
1545: //
1546: // p__ p0_ p1_ p2_
1547: // p_0 p00 p10 p20
1548: // p_1 p01 p11 p21
1549: // p_2 p02 p12 p22
1550: //
1551: p__ = p_x + p_y - srcScanlineStride - srcPixelStride;
1552: p0_ = p__ + srcPixelStride;
1553: p1_ = p0_ + srcPixelStride;
1554: p2_ = p1_ + srcPixelStride;
1555: p_0 = p__ + srcScanlineStride;
1556: p00 = p_0 + srcPixelStride;
1557: p10 = p00 + srcPixelStride;
1558: p20 = p10 + srcPixelStride;
1559: p_1 = p_0 + srcScanlineStride;
1560: p01 = p_1 + srcPixelStride;
1561: p11 = p01 + srcPixelStride;
1562: p21 = p11 + srcPixelStride;
1563: p_2 = p_1 + srcScanlineStride;
1564: p02 = p_2 + srcPixelStride;
1565: p12 = p02 + srcPixelStride;
1566: p22 = p12 + srcPixelStride;
1567:
1568: dstPixelOffset += dstPixelStride;
1569: }
1570:
1571: dstOffset += dstScanlineStride;
1572: }
1573: }
1574: }
|