Source Code Cross Referenced for MosaicOpImage.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » com » sun » media » jai » opimage » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » com.sun.media.jai.opimage 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: MosaicOpImage.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.2 $
0009:         * $Date: 2005/02/23 21:02:26 $
0010:         * $State: Exp $
0011:         */package com.sun.media.jai.opimage;
0012:
0013:        import java.awt.Point;
0014:        import java.awt.Rectangle;
0015:        import java.awt.image.ColorModel;
0016:        import java.awt.image.DataBuffer;
0017:        import java.awt.image.Raster;
0018:        import java.awt.image.RenderedImage;
0019:        import java.awt.image.SampleModel;
0020:        import java.awt.image.WritableRaster;
0021:        import java.util.ArrayList;
0022:        import java.util.Arrays;
0023:        import java.util.Map;
0024:        import java.util.Vector;
0025:        import javax.media.jai.BorderExtender;
0026:        import javax.media.jai.BorderExtenderConstant;
0027:        import javax.media.jai.ImageLayout;
0028:        import javax.media.jai.JAI;
0029:        import javax.media.jai.OpImage;
0030:        import javax.media.jai.PlanarImage;
0031:        import javax.media.jai.RasterAccessor;
0032:        import javax.media.jai.RasterFormatTag;
0033:        import javax.media.jai.ROI;
0034:        import javax.media.jai.operator.MosaicType;
0035:        import javax.media.jai.operator.MosaicDescriptor;
0036:        import com.sun.media.jai.util.ImageUtil;
0037:
0038:        public class MosaicOpImage extends OpImage {
0039:            private static final int WEIGHT_TYPE_ALPHA = 1;
0040:            private static final int WEIGHT_TYPE_ROI = 2;
0041:            private static final int WEIGHT_TYPE_THRESHOLD = 3;
0042:
0043:            protected MosaicType mosaicType;
0044:            protected PlanarImage[] sourceAlpha;
0045:            protected ROI[] sourceROI;
0046:            protected double[][] sourceThreshold;
0047:            protected double[] backgroundValues;
0048:
0049:            protected int numBands;
0050:
0051:            /** Integral background value. */
0052:            protected int[] background;
0053:
0054:            /** Integral thresholds. */
0055:            protected int[][] threshold;
0056:
0057:            protected boolean isAlphaBitmask = false;
0058:
0059:            private BorderExtender sourceExtender;
0060:            private BorderExtender zeroExtender;
0061:            private PlanarImage[] roiImage;
0062:
0063:            private static final ImageLayout getLayout(Vector sources,
0064:                    ImageLayout layout) {
0065:
0066:                // Contingent variables.
0067:                RenderedImage source0 = null;
0068:                SampleModel targetSM = null;
0069:                ColorModel targetCM = null;
0070:
0071:                // Get source count (might be zero).
0072:                int numSources = sources.size();
0073:
0074:                if (numSources > 0) {
0075:                    // Get SampleModel and ColorModel from first source.
0076:                    source0 = (RenderedImage) sources.get(0);
0077:                    targetSM = source0.getSampleModel();
0078:                    targetCM = source0.getColorModel();
0079:                } else if (layout != null
0080:                        && layout.isValid(ImageLayout.WIDTH_MASK
0081:                                | ImageLayout.HEIGHT_MASK
0082:                                | ImageLayout.SAMPLE_MODEL_MASK)) {
0083:                    // Get SampleModel and ColorModel from layout.
0084:                    targetSM = layout.getSampleModel(null);
0085:                    if (targetSM == null) {
0086:                        throw new IllegalArgumentException(JaiI18N
0087:                                .getString("MosaicOpImage7"));
0088:                    }
0089:                } else {
0090:                    throw new IllegalArgumentException(JaiI18N
0091:                            .getString("MosaicOpImage8"));
0092:                }
0093:
0094:                // Get data type, band count, and sample depth.
0095:                int dataType = targetSM.getDataType();
0096:                int numBands = targetSM.getNumBands();
0097:                int sampleSize = targetSM.getSampleSize(0);
0098:
0099:                // Sample size must equal that of first band.
0100:                for (int i = 1; i < numBands; i++) {
0101:                    if (targetSM.getSampleSize(i) != sampleSize) {
0102:                        throw new IllegalArgumentException(JaiI18N
0103:                                .getString("MosaicOpImage1"));
0104:                    }
0105:                }
0106:
0107:                // Return a clone of ImageLayout passed in if no sources.
0108:                // The input ImageLayout was checked for null above.
0109:                if (numSources < 1) {
0110:                    return (ImageLayout) layout.clone();
0111:                }
0112:
0113:                // Check the other sources against the first.
0114:                for (int i = 1; i < numSources; i++) {
0115:                    RenderedImage source = (RenderedImage) sources.get(i);
0116:                    SampleModel sourceSM = source.getSampleModel();
0117:
0118:                    // Data type and band count must be equal.
0119:                    if (sourceSM.getDataType() != dataType) {
0120:                        throw new IllegalArgumentException(JaiI18N
0121:                                .getString("MosaicOpImage2"));
0122:                    } else if (sourceSM.getNumBands() != numBands) {
0123:                        throw new IllegalArgumentException(JaiI18N
0124:                                .getString("MosaicOpImage3"));
0125:                    }
0126:
0127:                    // Sample size must be equal.
0128:                    for (int j = 0; j < numBands; j++) {
0129:                        if (sourceSM.getSampleSize(j) != sampleSize) {
0130:                            throw new IllegalArgumentException(JaiI18N
0131:                                    .getString("MosaicOpImage1"));
0132:                        }
0133:                    }
0134:                }
0135:
0136:                // Create a new layout or clone the one passed in.
0137:                ImageLayout mosaicLayout = layout == null ? new ImageLayout()
0138:                        : (ImageLayout) layout.clone();
0139:
0140:                // Determine the mosaic bounds.
0141:                Rectangle mosaicBounds = new Rectangle();
0142:                if (mosaicLayout.isValid(ImageLayout.MIN_X_MASK
0143:                        | ImageLayout.MIN_Y_MASK | ImageLayout.WIDTH_MASK
0144:                        | ImageLayout.HEIGHT_MASK)) {
0145:                    // Set the mosaic bounds to the value given in the layout.
0146:                    mosaicBounds.setBounds(mosaicLayout.getMinX(null),
0147:                            mosaicLayout.getMinY(null), mosaicLayout
0148:                                    .getWidth(null), mosaicLayout
0149:                                    .getHeight(null));
0150:                } else if (numSources > 0) {
0151:                    // Set the mosaic bounds to the union of source bounds.
0152:                    mosaicBounds.setBounds(source0.getMinX(),
0153:                            source0.getMinY(), source0.getWidth(), source0
0154:                                    .getHeight());
0155:                    for (int i = 1; i < numSources; i++) {
0156:                        RenderedImage source = (RenderedImage) sources.get(i);
0157:                        Rectangle sourceBounds = new Rectangle(
0158:                                source.getMinX(), source.getMinY(), source
0159:                                        .getWidth(), source.getHeight());
0160:                        mosaicBounds = mosaicBounds.union(sourceBounds);
0161:                    }
0162:                }
0163:
0164:                // Set the mosaic bounds in the layout.
0165:                mosaicLayout.setMinX(mosaicBounds.x);
0166:                mosaicLayout.setMinY(mosaicBounds.y);
0167:                mosaicLayout.setWidth(mosaicBounds.width);
0168:                mosaicLayout.setHeight(mosaicBounds.height);
0169:
0170:                // Check the SampleModel if defined.
0171:                if (mosaicLayout.isValid(ImageLayout.SAMPLE_MODEL_MASK)) {
0172:                    // Get the SampleModel.
0173:                    SampleModel destSM = mosaicLayout.getSampleModel(null);
0174:
0175:                    // Unset SampleModel if differing band count or data type.
0176:                    boolean unsetSampleModel = destSM.getNumBands() != numBands
0177:                            || destSM.getDataType() != dataType;
0178:
0179:                    // Unset SampleModel if differing sample size.
0180:                    for (int i = 0; !unsetSampleModel && i < numBands; i++) {
0181:                        if (destSM.getSampleSize(i) != sampleSize) {
0182:                            unsetSampleModel = true;
0183:                        }
0184:                    }
0185:
0186:                    // Unset SampleModel if needed.
0187:                    if (unsetSampleModel) {
0188:                        mosaicLayout.unsetValid(ImageLayout.SAMPLE_MODEL_MASK);
0189:                    }
0190:                }
0191:
0192:                return mosaicLayout;
0193:            }
0194:
0195:            public MosaicOpImage(Vector sources, ImageLayout layout,
0196:                    Map config, MosaicType mosaicType,
0197:                    PlanarImage[] sourceAlpha, ROI[] sourceROI,
0198:                    double[][] sourceThreshold, double[] backgroundValues) {
0199:                super (sources, getLayout(sources, layout), config, true);
0200:
0201:                // Set the band count.
0202:                this .numBands = sampleModel.getNumBands();
0203:
0204:                // Set the source count.
0205:                int numSources = getNumSources();
0206:
0207:                // Set the mosaic type.
0208:                this .mosaicType = mosaicType;
0209:
0210:                // Save the alpha array.
0211:                this .sourceAlpha = null;
0212:                if (sourceAlpha != null) {
0213:                    // Check alpha images.
0214:                    for (int i = 0; i < sourceAlpha.length; i++) {
0215:                        if (sourceAlpha[i] != null) {
0216:                            SampleModel alphaSM = sourceAlpha[i]
0217:                                    .getSampleModel();
0218:
0219:                            if (alphaSM.getNumBands() != 1) {
0220:                                throw new IllegalArgumentException(JaiI18N
0221:                                        .getString("MosaicOpImage4"));
0222:                            } else if (alphaSM.getDataType() != sampleModel
0223:                                    .getDataType()) {
0224:                                throw new IllegalArgumentException(JaiI18N
0225:                                        .getString("MosaicOpImage5"));
0226:                            } else if (alphaSM.getSampleSize(0) != sampleModel
0227:                                    .getSampleSize(0)) {
0228:                                throw new IllegalArgumentException(JaiI18N
0229:                                        .getString("MosaicOpImage6"));
0230:                            }
0231:                        }
0232:                    }
0233:
0234:                    this .sourceAlpha = new PlanarImage[numSources];
0235:                    System.arraycopy(sourceAlpha, 0, this .sourceAlpha, 0, Math
0236:                            .min(sourceAlpha.length, numSources));
0237:                }
0238:
0239:                // Save the ROI array.
0240:                this .sourceROI = null;
0241:                if (sourceROI != null) {
0242:                    this .sourceROI = new ROI[numSources];
0243:                    System.arraycopy(sourceROI, 0, this .sourceROI, 0, Math.min(
0244:                            sourceROI.length, numSources));
0245:                }
0246:
0247:                // isAlphaBitmask is true if and only if type is blend and an
0248:                // alpha image is supplied for each source.
0249:                this .isAlphaBitmask = !(mosaicType == MosaicDescriptor.MOSAIC_TYPE_BLEND
0250:                        && sourceAlpha != null && !(sourceAlpha.length < numSources));
0251:                if (!this .isAlphaBitmask) {
0252:                    for (int i = 0; i < numSources; i++) {
0253:                        if (sourceAlpha[i] == null) {
0254:                            this .isAlphaBitmask = true;
0255:                            break;
0256:                        }
0257:                    }
0258:                }
0259:
0260:                // Copy the threshold values according to the specification.
0261:                this .sourceThreshold = new double[numSources][numBands];
0262:
0263:                // Ensure the parameter is non-null and has one value.
0264:                if (sourceThreshold == null) {
0265:                    sourceThreshold = new double[][] { { 1.0 } };
0266:                }
0267:                for (int i = 0; i < numSources; i++) {
0268:                    // If there's an array for this source, use it.
0269:                    if (i < sourceThreshold.length
0270:                            && sourceThreshold[i] != null) {
0271:                        if (sourceThreshold[i].length < numBands) {
0272:                            // If the array is less than numBands, fill with element 0.
0273:                            Arrays.fill(this .sourceThreshold[i],
0274:                                    sourceThreshold[i][0]);
0275:                        } else {
0276:                            // Copy the whole array.
0277:                            System.arraycopy(sourceThreshold[i], 0,
0278:                                    this .sourceThreshold[i], 0, numBands);
0279:                        }
0280:                    } else {
0281:                        // Beyond the array or a null element: use the zeroth array.
0282:                        this .sourceThreshold[i] = this .sourceThreshold[0];
0283:                    }
0284:                }
0285:
0286:                // Initialize the integral thresholds.
0287:                this .threshold = new int[numSources][numBands];
0288:                for (int i = 0; i < numSources; i++) {
0289:                    for (int j = 0; j < numBands; j++) {
0290:                        // Truncate as the specified comparison is ">=".
0291:                        this .threshold[i][j] = (int) this .sourceThreshold[i][j];
0292:                    }
0293:                }
0294:
0295:                // Copy the background values per the specification.
0296:                this .backgroundValues = new double[numBands];
0297:                if (backgroundValues == null) {
0298:                    backgroundValues = new double[] { 0.0 };
0299:                }
0300:                if (backgroundValues.length < numBands) {
0301:                    Arrays.fill(this .backgroundValues, backgroundValues[0]);
0302:                } else {
0303:                    System.arraycopy(backgroundValues, 0,
0304:                            this .backgroundValues, 0, numBands);
0305:                }
0306:
0307:                // Clamp the floating point values for the integral cases.
0308:                this .background = new int[this .backgroundValues.length];
0309:                int dataType = sampleModel.getDataType();
0310:                for (int i = 0; i < this .background.length; i++) {
0311:                    switch (dataType) {
0312:                    case DataBuffer.TYPE_BYTE:
0313:                        this .background[i] = ImageUtil
0314:                                .clampRoundByte(this .backgroundValues[i]);
0315:                        break;
0316:                    case DataBuffer.TYPE_USHORT:
0317:                        this .background[i] = ImageUtil
0318:                                .clampRoundUShort(this .backgroundValues[i]);
0319:                        break;
0320:                    case DataBuffer.TYPE_SHORT:
0321:                        this .background[i] = ImageUtil
0322:                                .clampRoundShort(this .backgroundValues[i]);
0323:                        break;
0324:                    case DataBuffer.TYPE_INT:
0325:                        this .background[i] = ImageUtil
0326:                                .clampRoundInt(this .backgroundValues[i]);
0327:                        break;
0328:                    default:
0329:                    }
0330:                }
0331:
0332:                // Determine constant value for source border extension.
0333:                double sourceExtensionConstant;
0334:                switch (dataType) {
0335:                case DataBuffer.TYPE_BYTE:
0336:                    sourceExtensionConstant = 0.0;
0337:                    break;
0338:                case DataBuffer.TYPE_USHORT:
0339:                    sourceExtensionConstant = 0.0;
0340:                    break;
0341:                case DataBuffer.TYPE_SHORT:
0342:                    sourceExtensionConstant = Short.MIN_VALUE;
0343:                    break;
0344:                case DataBuffer.TYPE_INT:
0345:                    sourceExtensionConstant = Integer.MIN_VALUE;
0346:                    break;
0347:                case DataBuffer.TYPE_FLOAT:
0348:                    sourceExtensionConstant = -Float.MAX_VALUE;
0349:                    break;
0350:                case DataBuffer.TYPE_DOUBLE:
0351:                default:
0352:                    sourceExtensionConstant = -Double.MAX_VALUE;
0353:                }
0354:
0355:                // Extend the sources filling with the minimum possible value
0356:                // on account of the threshold technique.
0357:                this .sourceExtender = sourceExtensionConstant == 0.0 ? BorderExtender
0358:                        .createInstance(BorderExtender.BORDER_ZERO)
0359:                        : new BorderExtenderConstant(
0360:                                new double[] { sourceExtensionConstant });
0361:
0362:                // Extends alpha or ROI data with zeros.
0363:                if (sourceAlpha != null || sourceROI != null) {
0364:                    this .zeroExtender = BorderExtender
0365:                            .createInstance(BorderExtender.BORDER_ZERO);
0366:                }
0367:
0368:                // Get the ROI images.
0369:                if (sourceROI != null) {
0370:                    roiImage = new PlanarImage[numSources];
0371:                    for (int i = 0; i < sourceROI.length; i++) {
0372:                        if (sourceROI[i] != null) {
0373:                            roiImage[i] = sourceROI[i].getAsImage();
0374:                        }
0375:                    }
0376:                }
0377:            }
0378:
0379:            public Rectangle mapDestRect(Rectangle destRect, int sourceIndex) {
0380:                if (destRect == null) {
0381:                    throw new IllegalArgumentException(JaiI18N
0382:                            .getString("Generic0"));
0383:                }
0384:
0385:                if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
0386:                    throw new IllegalArgumentException(JaiI18N
0387:                            .getString("Generic1"));
0388:                }
0389:
0390:                return destRect.intersection(getSourceImage(sourceIndex)
0391:                        .getBounds());
0392:            }
0393:
0394:            public Rectangle mapSourceRect(Rectangle sourceRect, int sourceIndex) {
0395:                if (sourceRect == null) {
0396:                    throw new IllegalArgumentException(JaiI18N
0397:                            .getString("Generic0"));
0398:                }
0399:
0400:                if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
0401:                    throw new IllegalArgumentException(JaiI18N
0402:                            .getString("Generic1"));
0403:                }
0404:
0405:                return sourceRect.intersection(getBounds());
0406:            }
0407:
0408:            public Raster computeTile(int tileX, int tileY) {
0409:                // Create a new Raster.
0410:                WritableRaster dest = createWritableRaster(sampleModel,
0411:                        new Point(tileXToX(tileX), tileYToY(tileY)));
0412:
0413:                // Determine the active area; tile intersects with image's bounds.
0414:                Rectangle destRect = getTileRect(tileX, tileY);
0415:
0416:                int numSources = getNumSources();
0417:
0418:                Raster[] rasterSources = new Raster[numSources];
0419:                Raster[] alpha = sourceAlpha != null ? new Raster[numSources]
0420:                        : null;
0421:                Raster[] roi = sourceROI != null ? new Raster[numSources]
0422:                        : null;
0423:
0424:                // Cobble areas
0425:                for (int i = 0; i < numSources; i++) {
0426:                    PlanarImage source = getSourceImage(i);
0427:                    Rectangle srcRect = mapDestRect(destRect, i);
0428:
0429:                    // If srcRect is empty, set the Raster for this source to
0430:                    // null; otherwise pass srcRect to getData(). If srcRect
0431:                    // is null, getData() will return a Raster containing the
0432:                    // data of the entire source image.
0433:                    rasterSources[i] = srcRect != null && srcRect.isEmpty() ? null
0434:                            : source.getExtendedData(destRect, sourceExtender);
0435:
0436:                    if (rasterSources[i] != null) {
0437:                        if (sourceAlpha != null && sourceAlpha[i] != null) {
0438:                            alpha[i] = sourceAlpha[i].getExtendedData(destRect,
0439:                                    zeroExtender);
0440:                        }
0441:
0442:                        if (sourceROI != null && sourceROI[i] != null) {
0443:                            roi[i] = roiImage[i].getExtendedData(destRect,
0444:                                    zeroExtender);
0445:                        }
0446:                    }
0447:                }
0448:
0449:                computeRect(rasterSources, dest, destRect, alpha, roi);
0450:
0451:                for (int i = 0; i < numSources; i++) {
0452:                    Raster sourceData = rasterSources[i];
0453:                    if (sourceData != null) {
0454:                        PlanarImage source = getSourceImage(i);
0455:
0456:                        // Recycle the source tile
0457:                        if (source
0458:                                .overlapsMultipleTiles(sourceData.getBounds())) {
0459:                            recycleTile(sourceData);
0460:                        }
0461:                    }
0462:                }
0463:
0464:                return dest;
0465:            }
0466:
0467:            protected void computeRect(Raster[] sources, WritableRaster dest,
0468:                    Rectangle destRect) {
0469:                computeRect(sources, dest, destRect, null, null);
0470:            }
0471:
0472:            protected void computeRect(Raster[] sources, WritableRaster dest,
0473:                    Rectangle destRect, Raster[] alphaRaster, Raster[] roiRaster) {
0474:                // Save the source count.
0475:                int numSources = sources.length;
0476:
0477:                // Put all non-null sources in a list.
0478:                ArrayList sourceList = new ArrayList(numSources);
0479:                for (int i = 0; i < numSources; i++) {
0480:                    if (sources[i] != null) {
0481:                        sourceList.add(sources[i]);
0482:                    }
0483:                }
0484:
0485:                // Clear the background and return if no sources.
0486:                int numNonNullSources = sourceList.size();
0487:                if (numNonNullSources == 0) {
0488:                    ImageUtil.fillBackground(dest, destRect, backgroundValues);
0489:                    return;
0490:                }
0491:
0492:                // Determine the format tag id.
0493:                SampleModel[] sourceSM = new SampleModel[numNonNullSources];
0494:                for (int i = 0; i < numNonNullSources; i++) {
0495:                    sourceSM[i] = ((Raster) sourceList.get(i)).getSampleModel();
0496:                }
0497:                int formatTagID = RasterAccessor.findCompatibleTag(sourceSM,
0498:                        dest.getSampleModel());
0499:
0500:                // Create source accessors.
0501:                RasterAccessor[] s = new RasterAccessor[numSources];
0502:                for (int i = 0; i < numSources; i++) {
0503:                    if (sources[i] != null) {
0504:                        RasterFormatTag formatTag = new RasterFormatTag(
0505:                                sources[i].getSampleModel(), formatTagID);
0506:                        s[i] = new RasterAccessor(sources[i], destRect,
0507:                                formatTag, null);
0508:                    }
0509:                }
0510:
0511:                // Create dest accessor.
0512:                RasterAccessor d = new RasterAccessor(
0513:                        dest,
0514:                        destRect,
0515:                        new RasterFormatTag(dest.getSampleModel(), formatTagID),
0516:                        null);
0517:
0518:                // Create the alpha accessors.
0519:                RasterAccessor[] a = new RasterAccessor[numSources];
0520:                if (alphaRaster != null) {
0521:                    for (int i = 0; i < numSources; i++) {
0522:                        if (alphaRaster[i] != null) {
0523:                            SampleModel alphaSM = alphaRaster[i]
0524:                                    .getSampleModel();
0525:                            int alphaFormatTagID = RasterAccessor
0526:                                    .findCompatibleTag(null, alphaSM);
0527:                            RasterFormatTag alphaFormatTag = new RasterFormatTag(
0528:                                    alphaSM, alphaFormatTagID);
0529:                            a[i] = new RasterAccessor(alphaRaster[i], destRect,
0530:                                    alphaFormatTag, sourceAlpha[i]
0531:                                            .getColorModel());
0532:                        }
0533:                    }
0534:                }
0535:
0536:                // Branch to data type-specific method.
0537:                switch (d.getDataType()) {
0538:                case DataBuffer.TYPE_BYTE:
0539:                    computeRectByte(s, d, a, roiRaster);
0540:                    break;
0541:                case DataBuffer.TYPE_USHORT:
0542:                    computeRectUShort(s, d, a, roiRaster);
0543:                    break;
0544:                case DataBuffer.TYPE_SHORT:
0545:                    computeRectShort(s, d, a, roiRaster);
0546:                    break;
0547:                case DataBuffer.TYPE_INT:
0548:                    computeRectInt(s, d, a, roiRaster);
0549:                    break;
0550:                case DataBuffer.TYPE_FLOAT:
0551:                    computeRectFloat(s, d, a, roiRaster);
0552:                    break;
0553:                case DataBuffer.TYPE_DOUBLE:
0554:                    computeRectDouble(s, d, a, roiRaster);
0555:                    break;
0556:                }
0557:
0558:                d.copyDataToRaster();
0559:            }
0560:
0561:            private void computeRectByte(RasterAccessor[] src,
0562:                    RasterAccessor dst, RasterAccessor[] alfa, Raster[] roi) {
0563:                // Save the source count.
0564:                int numSources = src.length;
0565:
0566:                // Allocate stride, offset, and data arrays for sources.
0567:                int[] srcLineStride = new int[numSources];
0568:                int[] srcPixelStride = new int[numSources];
0569:                int[][] srcBandOffsets = new int[numSources][];
0570:                byte[][][] srcData = new byte[numSources][][];
0571:
0572:                // Initialize stride, offset, and data arrays for sources.
0573:                for (int i = 0; i < numSources; i++) {
0574:                    if (src[i] != null) {
0575:                        srcLineStride[i] = src[i].getScanlineStride();
0576:                        srcPixelStride[i] = src[i].getPixelStride();
0577:                        srcBandOffsets[i] = src[i].getBandOffsets();
0578:                        srcData[i] = src[i].getByteDataArrays();
0579:                    }
0580:                }
0581:
0582:                // Initialize destination variables.
0583:                int dstMinX = dst.getX();
0584:                int dstMinY = dst.getY();
0585:                int dstWidth = dst.getWidth();
0586:                int dstHeight = dst.getHeight();
0587:                int dstMaxX = dstMinX + dstWidth; // x max exclusive
0588:                int dstMaxY = dstMinY + dstHeight; // y max exclusive
0589:                int dstBands = dst.getNumBands();
0590:                int dstLineStride = dst.getScanlineStride();
0591:                int dstPixelStride = dst.getPixelStride();
0592:                int[] dstBandOffsets = dst.getBandOffsets();
0593:                byte[][] dstData = dst.getByteDataArrays();
0594:
0595:                // Check for alpha.
0596:                boolean hasAlpha = false;
0597:                for (int i = 0; i < numSources; i++) {
0598:                    if (alfa[i] != null) {
0599:                        hasAlpha = true;
0600:                        break;
0601:                    }
0602:                }
0603:
0604:                // Declare alpha channel arrays.
0605:                int[] alfaLineStride = null;
0606:                int[] alfaPixelStride = null;
0607:                int[][] alfaBandOffsets = null;
0608:                byte[][][] alfaData = null;
0609:
0610:                if (hasAlpha) {
0611:                    // Allocate stride, offset, and data arrays for alpha channels.
0612:                    alfaLineStride = new int[numSources];
0613:                    alfaPixelStride = new int[numSources];
0614:                    alfaBandOffsets = new int[numSources][];
0615:                    alfaData = new byte[numSources][][];
0616:
0617:                    // Initialize stride, offset, and data arrays for alpha channels.
0618:                    for (int i = 0; i < numSources; i++) {
0619:                        if (alfa[i] != null) {
0620:                            alfaLineStride[i] = alfa[i].getScanlineStride();
0621:                            alfaPixelStride[i] = alfa[i].getPixelStride();
0622:                            alfaBandOffsets[i] = alfa[i].getBandOffsets();
0623:                            alfaData[i] = alfa[i].getByteDataArrays();
0624:                        }
0625:                    }
0626:                }
0627:
0628:                // Initialize weight type arrays.
0629:                int[] weightTypes = new int[numSources];
0630:                for (int i = 0; i < numSources; i++) {
0631:                    weightTypes[i] = WEIGHT_TYPE_THRESHOLD;
0632:                    if (alfa[i] != null) {
0633:                        weightTypes[i] = WEIGHT_TYPE_ALPHA;
0634:                    } else if (sourceROI != null && sourceROI[i] != null) {
0635:                        weightTypes[i] = WEIGHT_TYPE_ROI;
0636:                    }
0637:                }
0638:
0639:                // Set up source offset and data variabls.
0640:                int[] sLineOffsets = new int[numSources];
0641:                int[] sPixelOffsets = new int[numSources];
0642:                byte[][] sBandData = new byte[numSources][];
0643:
0644:                // Set up alpha offset and data variabls.
0645:                int[] aLineOffsets = null;
0646:                int[] aPixelOffsets = null;
0647:                byte[][] aBandData = null;
0648:                if (hasAlpha) {
0649:                    aLineOffsets = new int[numSources];
0650:                    aPixelOffsets = new int[numSources];
0651:                    aBandData = new byte[numSources][];
0652:                }
0653:
0654:                for (int b = 0; b < dstBands; b++) {
0655:                    // Initialize source and alpha band array and line offsets.
0656:                    for (int s = 0; s < numSources; s++) {
0657:                        if (src[s] != null) {
0658:                            sBandData[s] = srcData[s][b];
0659:                            sLineOffsets[s] = srcBandOffsets[s][b];
0660:                        }
0661:                        if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
0662:                            aBandData[s] = alfaData[s][0];
0663:                            aLineOffsets[s] = alfaBandOffsets[s][0];
0664:                        }
0665:                    }
0666:
0667:                    // Initialize destination band array and line offsets.
0668:                    byte[] dBandData = dstData[b];
0669:                    int dLineOffset = dstBandOffsets[b];
0670:
0671:                    if (mosaicType == MosaicDescriptor.MOSAIC_TYPE_OVERLAY) {
0672:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
0673:                            // Initialize source and alpha pixel offsets and
0674:                            // update line offsets.
0675:                            for (int s = 0; s < numSources; s++) {
0676:                                if (src[s] != null) {
0677:                                    sPixelOffsets[s] = sLineOffsets[s];
0678:                                    sLineOffsets[s] += srcLineStride[s];
0679:                                }
0680:                                if (alfa[s] != null) {
0681:                                    aPixelOffsets[s] = aLineOffsets[s];
0682:                                    aLineOffsets[s] += alfaLineStride[s];
0683:                                }
0684:                            }
0685:
0686:                            // Initialize destination pixel offset and update
0687:                            // line offset.
0688:                            int dPixelOffset = dLineOffset;
0689:                            dLineOffset += dstLineStride;
0690:
0691:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
0692:
0693:                                // Unset destination update flag.
0694:                                boolean setDestValue = false;
0695:
0696:                                // Loop over source until a non-zero weight is
0697:                                // encountered.
0698:                                for (int s = 0; s < numSources; s++) {
0699:                                    if (src[s] == null)
0700:                                        continue;
0701:
0702:                                    byte sourceValue = sBandData[s][sPixelOffsets[s]];
0703:                                    sPixelOffsets[s] += srcPixelStride[s];
0704:
0705:                                    switch (weightTypes[s]) {
0706:                                    case WEIGHT_TYPE_ALPHA:
0707:                                        setDestValue = aBandData[s][aPixelOffsets[s]] != 0;
0708:                                        aPixelOffsets[s] += alfaPixelStride[s];
0709:                                        break;
0710:                                    case WEIGHT_TYPE_ROI:
0711:                                        setDestValue = roi[s].getSample(dstX,
0712:                                                dstY, 0) > 0;
0713:                                        break;
0714:                                    default: // WEIGHT_TYPE_THRESHOLD
0715:                                        setDestValue = (sourceValue & 0xff) >= sourceThreshold[s][b];
0716:                                    }
0717:
0718:                                    // Set the destination value if a non-zero
0719:                                    // weight was found.
0720:                                    if (setDestValue) {
0721:                                        dBandData[dPixelOffset] = sourceValue;
0722:
0723:                                        // Increment offset of subsequent sources.
0724:                                        for (int k = s + 1; k < numSources; k++) {
0725:                                            if (src[k] != null) {
0726:                                                sPixelOffsets[k] += srcPixelStride[k];
0727:                                            }
0728:                                            if (alfa[k] != null) {
0729:                                                aPixelOffsets[k] += alfaPixelStride[k];
0730:                                            }
0731:                                        }
0732:                                        break;
0733:                                    }
0734:                                }
0735:
0736:                                // Set the destination value to the background if
0737:                                // no value was set.
0738:                                if (!setDestValue) {
0739:                                    dBandData[dPixelOffset] = (byte) background[b];
0740:                                }
0741:
0742:                                dPixelOffset += dstPixelStride;
0743:                            }
0744:                        }
0745:                    } else { // mosaicType == MosaicDescriptor.MOSAIC_TYPE_BLEND
0746:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
0747:                            // Initialize source and alpha pixel offsets and
0748:                            // update line offsets.
0749:                            for (int s = 0; s < numSources; s++) {
0750:                                if (src[s] != null) {
0751:                                    sPixelOffsets[s] = sLineOffsets[s];
0752:                                    sLineOffsets[s] += srcLineStride[s];
0753:                                }
0754:                                if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
0755:                                    aPixelOffsets[s] = aLineOffsets[s];
0756:                                    aLineOffsets[s] += alfaLineStride[s];
0757:                                }
0758:                            }
0759:
0760:                            // Initialize destination pixel offset and update
0761:                            // line offset.
0762:                            int dPixelOffset = dLineOffset;
0763:                            dLineOffset += dstLineStride;
0764:
0765:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
0766:
0767:                                // Clear values for blending ratio.
0768:                                float numerator = 0.0F;
0769:                                float denominator = 0.0F;
0770:
0771:                                // Accumulate into numerator and denominator.
0772:                                for (int s = 0; s < numSources; s++) {
0773:                                    if (src[s] == null)
0774:                                        continue;
0775:
0776:                                    byte sourceValue = sBandData[s][sPixelOffsets[s]];
0777:                                    sPixelOffsets[s] += srcPixelStride[s];
0778:
0779:                                    float weight = 0.0F;
0780:                                    switch (weightTypes[s]) {
0781:                                    case WEIGHT_TYPE_ALPHA:
0782:                                        weight = (aBandData[s][aPixelOffsets[s]] & 0xff);
0783:                                        if (weight > 0.0F && isAlphaBitmask) {
0784:                                            weight = 1.0F;
0785:                                        } else {
0786:                                            weight /= 255.0F;
0787:                                        }
0788:                                        aPixelOffsets[s] += alfaPixelStride[s];
0789:                                        break;
0790:                                    case WEIGHT_TYPE_ROI:
0791:                                        weight = roi[s]
0792:                                                .getSample(dstX, dstY, 0) > 0 ? 1.0F
0793:                                                : 0.0F;
0794:                                        break;
0795:                                    default: // WEIGHT_TYPE_THRESHOLD
0796:                                        weight = (sourceValue & 0xff) >= sourceThreshold[s][b] ? 1.0F
0797:                                                : 0.0F;
0798:                                    }
0799:
0800:                                    // Update numerator and denominator.
0801:                                    numerator += (weight * (sourceValue & 0xff));
0802:                                    denominator += weight;
0803:                                }
0804:
0805:                                // Clear the background if all weights were zero,
0806:                                // otherwise blend the values.
0807:                                if (denominator == 0.0) {
0808:                                    dBandData[dPixelOffset] = (byte) background[b];
0809:                                } else {
0810:                                    dBandData[dPixelOffset] = ImageUtil
0811:                                            .clampRoundByte(numerator
0812:                                                    / denominator);
0813:                                }
0814:
0815:                                dPixelOffset += dstPixelStride;
0816:                            }
0817:                        }
0818:                    }
0819:                }
0820:            }
0821:
0822:            private void computeRectUShort(RasterAccessor[] src,
0823:                    RasterAccessor dst, RasterAccessor[] alfa, Raster[] roi) {
0824:                // Save the source count.
0825:                int numSources = src.length;
0826:
0827:                // Allocate stride, offset, and data arrays for sources.
0828:                int[] srcLineStride = new int[numSources];
0829:                int[] srcPixelStride = new int[numSources];
0830:                int[][] srcBandOffsets = new int[numSources][];
0831:                short[][][] srcData = new short[numSources][][];
0832:
0833:                // Initialize stride, offset, and data arrays for sources.
0834:                for (int i = 0; i < numSources; i++) {
0835:                    if (src[i] != null) {
0836:                        srcLineStride[i] = src[i].getScanlineStride();
0837:                        srcPixelStride[i] = src[i].getPixelStride();
0838:                        srcBandOffsets[i] = src[i].getBandOffsets();
0839:                        srcData[i] = src[i].getShortDataArrays();
0840:                    }
0841:                }
0842:
0843:                // Initialize destination variables.
0844:                int dstMinX = dst.getX();
0845:                int dstMinY = dst.getY();
0846:                int dstWidth = dst.getWidth();
0847:                int dstHeight = dst.getHeight();
0848:                int dstMaxX = dstMinX + dstWidth; // x max exclusive
0849:                int dstMaxY = dstMinY + dstHeight; // y max exclusive
0850:                int dstBands = dst.getNumBands();
0851:                int dstLineStride = dst.getScanlineStride();
0852:                int dstPixelStride = dst.getPixelStride();
0853:                int[] dstBandOffsets = dst.getBandOffsets();
0854:                short[][] dstData = dst.getShortDataArrays();
0855:
0856:                // Check for alpha.
0857:                boolean hasAlpha = false;
0858:                for (int i = 0; i < numSources; i++) {
0859:                    if (alfa[i] != null) {
0860:                        hasAlpha = true;
0861:                        break;
0862:                    }
0863:                }
0864:
0865:                // Declare alpha channel arrays.
0866:                int[] alfaLineStride = null;
0867:                int[] alfaPixelStride = null;
0868:                int[][] alfaBandOffsets = null;
0869:                short[][][] alfaData = null;
0870:
0871:                if (hasAlpha) {
0872:                    // Allocate stride, offset, and data arrays for alpha channels.
0873:                    alfaLineStride = new int[numSources];
0874:                    alfaPixelStride = new int[numSources];
0875:                    alfaBandOffsets = new int[numSources][];
0876:                    alfaData = new short[numSources][][];
0877:
0878:                    // Initialize stride, offset, and data arrays for alpha channels.
0879:                    for (int i = 0; i < numSources; i++) {
0880:                        if (alfa[i] != null) {
0881:                            alfaLineStride[i] = alfa[i].getScanlineStride();
0882:                            alfaPixelStride[i] = alfa[i].getPixelStride();
0883:                            alfaBandOffsets[i] = alfa[i].getBandOffsets();
0884:                            alfaData[i] = alfa[i].getShortDataArrays();
0885:                        }
0886:                    }
0887:                }
0888:
0889:                // Initialize weight type arrays.
0890:                int[] weightTypes = new int[numSources];
0891:                for (int i = 0; i < numSources; i++) {
0892:                    weightTypes[i] = WEIGHT_TYPE_THRESHOLD;
0893:                    if (alfa[i] != null) {
0894:                        weightTypes[i] = WEIGHT_TYPE_ALPHA;
0895:                    } else if (sourceROI != null && sourceROI[i] != null) {
0896:                        weightTypes[i] = WEIGHT_TYPE_ROI;
0897:                    }
0898:                }
0899:
0900:                // Set up source offset and data variabls.
0901:                int[] sLineOffsets = new int[numSources];
0902:                int[] sPixelOffsets = new int[numSources];
0903:                short[][] sBandData = new short[numSources][];
0904:
0905:                // Set up alpha offset and data variabls.
0906:                int[] aLineOffsets = null;
0907:                int[] aPixelOffsets = null;
0908:                short[][] aBandData = null;
0909:                if (hasAlpha) {
0910:                    aLineOffsets = new int[numSources];
0911:                    aPixelOffsets = new int[numSources];
0912:                    aBandData = new short[numSources][];
0913:                }
0914:
0915:                for (int b = 0; b < dstBands; b++) {
0916:                    // Initialize source and alpha band array and line offsets.
0917:                    for (int s = 0; s < numSources; s++) {
0918:                        if (src[s] != null) {
0919:                            sBandData[s] = srcData[s][b];
0920:                            sLineOffsets[s] = srcBandOffsets[s][b];
0921:                        }
0922:                        if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
0923:                            aBandData[s] = alfaData[s][0];
0924:                            aLineOffsets[s] = alfaBandOffsets[s][0];
0925:                        }
0926:                    }
0927:
0928:                    // Initialize destination band array and line offsets.
0929:                    short[] dBandData = dstData[b];
0930:                    int dLineOffset = dstBandOffsets[b];
0931:
0932:                    if (mosaicType == MosaicDescriptor.MOSAIC_TYPE_OVERLAY) {
0933:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
0934:                            // Initialize source and alpha pixel offsets and
0935:                            // update line offsets.
0936:                            for (int s = 0; s < numSources; s++) {
0937:                                if (src[s] != null) {
0938:                                    sPixelOffsets[s] = sLineOffsets[s];
0939:                                    sLineOffsets[s] += srcLineStride[s];
0940:                                }
0941:                                if (alfa[s] != null) {
0942:                                    aPixelOffsets[s] = aLineOffsets[s];
0943:                                    aLineOffsets[s] += alfaLineStride[s];
0944:                                }
0945:                            }
0946:
0947:                            // Initialize destination pixel offset and update
0948:                            // line offset.
0949:                            int dPixelOffset = dLineOffset;
0950:                            dLineOffset += dstLineStride;
0951:
0952:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
0953:
0954:                                // Unset destination update flag.
0955:                                boolean setDestValue = false;
0956:
0957:                                // Loop over source until a non-zero weight is
0958:                                // encountered.
0959:                                for (int s = 0; s < numSources; s++) {
0960:                                    if (src[s] == null)
0961:                                        continue;
0962:
0963:                                    short sourceValue = sBandData[s][sPixelOffsets[s]];
0964:                                    sPixelOffsets[s] += srcPixelStride[s];
0965:
0966:                                    switch (weightTypes[s]) {
0967:                                    case WEIGHT_TYPE_ALPHA:
0968:                                        setDestValue = aBandData[s][aPixelOffsets[s]] != 0;
0969:                                        aPixelOffsets[s] += alfaPixelStride[s];
0970:                                        break;
0971:                                    case WEIGHT_TYPE_ROI:
0972:                                        setDestValue = roi[s].getSample(dstX,
0973:                                                dstY, 0) > 0;
0974:                                        break;
0975:                                    default: // WEIGHT_TYPE_THRESHOLD
0976:                                        setDestValue = (sourceValue & 0xffff) >= sourceThreshold[s][b];
0977:                                    }
0978:
0979:                                    // Set the destination value if a non-zero
0980:                                    // weight was found.
0981:                                    if (setDestValue) {
0982:                                        dBandData[dPixelOffset] = sourceValue;
0983:
0984:                                        // Increment offset of subsequent sources.
0985:                                        for (int k = s + 1; k < numSources; k++) {
0986:                                            if (src[k] != null) {
0987:                                                sPixelOffsets[k] += srcPixelStride[k];
0988:                                            }
0989:                                            if (alfa[k] != null) {
0990:                                                aPixelOffsets[k] += alfaPixelStride[k];
0991:                                            }
0992:                                        }
0993:                                        break;
0994:                                    }
0995:                                }
0996:
0997:                                // Set the destination value to the background if
0998:                                // no value was set.
0999:                                if (!setDestValue) {
1000:                                    dBandData[dPixelOffset] = (short) background[b];
1001:                                }
1002:
1003:                                dPixelOffset += dstPixelStride;
1004:                            }
1005:                        }
1006:                    } else { // mosaicType == MosaicDescriptor.MOSAIC_TYPE_BLEND
1007:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
1008:                            // Initialize source and alpha pixel offsets and
1009:                            // update line offsets.
1010:                            for (int s = 0; s < numSources; s++) {
1011:                                if (src[s] != null) {
1012:                                    sPixelOffsets[s] = sLineOffsets[s];
1013:                                    sLineOffsets[s] += srcLineStride[s];
1014:                                }
1015:                                if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
1016:                                    aPixelOffsets[s] = aLineOffsets[s];
1017:                                    aLineOffsets[s] += alfaLineStride[s];
1018:                                }
1019:                            }
1020:
1021:                            // Initialize destination pixel offset and update
1022:                            // line offset.
1023:                            int dPixelOffset = dLineOffset;
1024:                            dLineOffset += dstLineStride;
1025:
1026:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
1027:
1028:                                // Clear values for blending ratio.
1029:                                float numerator = 0.0F;
1030:                                float denominator = 0.0F;
1031:
1032:                                // Accumulate into numerator and denominator.
1033:                                for (int s = 0; s < numSources; s++) {
1034:                                    if (src[s] == null)
1035:                                        continue;
1036:
1037:                                    short sourceValue = sBandData[s][sPixelOffsets[s]];
1038:                                    sPixelOffsets[s] += srcPixelStride[s];
1039:
1040:                                    float weight = 0.0F;
1041:                                    switch (weightTypes[s]) {
1042:                                    case WEIGHT_TYPE_ALPHA:
1043:                                        weight = (aBandData[s][aPixelOffsets[s]] & 0xffff);
1044:                                        if (weight > 0.0F && isAlphaBitmask) {
1045:                                            weight = 1.0F;
1046:                                        } else {
1047:                                            weight /= 65535.0F;
1048:                                        }
1049:                                        aPixelOffsets[s] += alfaPixelStride[s];
1050:                                        break;
1051:                                    case WEIGHT_TYPE_ROI:
1052:                                        weight = roi[s]
1053:                                                .getSample(dstX, dstY, 0) > 0 ? 1.0F
1054:                                                : 0.0F;
1055:                                        break;
1056:                                    default: // WEIGHT_TYPE_THRESHOLD
1057:                                        weight = (sourceValue & 0xffff) >= sourceThreshold[s][b] ? 1.0F
1058:                                                : 0.0F;
1059:                                    }
1060:
1061:                                    // Update numerator and denominator.
1062:                                    numerator += (weight * (sourceValue & 0xffff));
1063:                                    denominator += weight;
1064:                                }
1065:
1066:                                // Clear the background if all weights were zero,
1067:                                // otherwise blend the values.
1068:                                if (denominator == 0.0) {
1069:                                    dBandData[dPixelOffset] = (short) background[b];
1070:                                } else {
1071:                                    dBandData[dPixelOffset] = ImageUtil
1072:                                            .clampRoundUShort(numerator
1073:                                                    / denominator);
1074:                                }
1075:
1076:                                dPixelOffset += dstPixelStride;
1077:                            }
1078:                        }
1079:                    }
1080:                }
1081:            }
1082:
1083:            private void computeRectShort(RasterAccessor[] src,
1084:                    RasterAccessor dst, RasterAccessor[] alfa, Raster[] roi) {
1085:                // Save the source count.
1086:                int numSources = src.length;
1087:
1088:                // Allocate stride, offset, and data arrays for sources.
1089:                int[] srcLineStride = new int[numSources];
1090:                int[] srcPixelStride = new int[numSources];
1091:                int[][] srcBandOffsets = new int[numSources][];
1092:                short[][][] srcData = new short[numSources][][];
1093:
1094:                // Initialize stride, offset, and data arrays for sources.
1095:                for (int i = 0; i < numSources; i++) {
1096:                    if (src[i] != null) {
1097:                        srcLineStride[i] = src[i].getScanlineStride();
1098:                        srcPixelStride[i] = src[i].getPixelStride();
1099:                        srcBandOffsets[i] = src[i].getBandOffsets();
1100:                        srcData[i] = src[i].getShortDataArrays();
1101:                    }
1102:                }
1103:
1104:                // Initialize destination variables.
1105:                int dstMinX = dst.getX();
1106:                int dstMinY = dst.getY();
1107:                int dstWidth = dst.getWidth();
1108:                int dstHeight = dst.getHeight();
1109:                int dstMaxX = dstMinX + dstWidth; // x max exclusive
1110:                int dstMaxY = dstMinY + dstHeight; // y max exclusive
1111:                int dstBands = dst.getNumBands();
1112:                int dstLineStride = dst.getScanlineStride();
1113:                int dstPixelStride = dst.getPixelStride();
1114:                int[] dstBandOffsets = dst.getBandOffsets();
1115:                short[][] dstData = dst.getShortDataArrays();
1116:
1117:                // Check for alpha.
1118:                boolean hasAlpha = false;
1119:                for (int i = 0; i < numSources; i++) {
1120:                    if (alfa[i] != null) {
1121:                        hasAlpha = true;
1122:                        break;
1123:                    }
1124:                }
1125:
1126:                // Declare alpha channel arrays.
1127:                int[] alfaLineStride = null;
1128:                int[] alfaPixelStride = null;
1129:                int[][] alfaBandOffsets = null;
1130:                short[][][] alfaData = null;
1131:
1132:                if (hasAlpha) {
1133:                    // Allocate stride, offset, and data arrays for alpha channels.
1134:                    alfaLineStride = new int[numSources];
1135:                    alfaPixelStride = new int[numSources];
1136:                    alfaBandOffsets = new int[numSources][];
1137:                    alfaData = new short[numSources][][];
1138:
1139:                    // Initialize stride, offset, and data arrays for alpha channels.
1140:                    for (int i = 0; i < numSources; i++) {
1141:                        if (alfa[i] != null) {
1142:                            alfaLineStride[i] = alfa[i].getScanlineStride();
1143:                            alfaPixelStride[i] = alfa[i].getPixelStride();
1144:                            alfaBandOffsets[i] = alfa[i].getBandOffsets();
1145:                            alfaData[i] = alfa[i].getShortDataArrays();
1146:                        }
1147:                    }
1148:                }
1149:
1150:                // Initialize weight type arrays.
1151:                int[] weightTypes = new int[numSources];
1152:                for (int i = 0; i < numSources; i++) {
1153:                    weightTypes[i] = WEIGHT_TYPE_THRESHOLD;
1154:                    if (alfa[i] != null) {
1155:                        weightTypes[i] = WEIGHT_TYPE_ALPHA;
1156:                    } else if (sourceROI != null && sourceROI[i] != null) {
1157:                        weightTypes[i] = WEIGHT_TYPE_ROI;
1158:                    }
1159:                }
1160:
1161:                // Set up source offset and data variabls.
1162:                int[] sLineOffsets = new int[numSources];
1163:                int[] sPixelOffsets = new int[numSources];
1164:                short[][] sBandData = new short[numSources][];
1165:
1166:                // Set up alpha offset and data variabls.
1167:                int[] aLineOffsets = null;
1168:                int[] aPixelOffsets = null;
1169:                short[][] aBandData = null;
1170:                if (hasAlpha) {
1171:                    aLineOffsets = new int[numSources];
1172:                    aPixelOffsets = new int[numSources];
1173:                    aBandData = new short[numSources][];
1174:                }
1175:
1176:                for (int b = 0; b < dstBands; b++) {
1177:                    // Initialize source and alpha band array and line offsets.
1178:                    for (int s = 0; s < numSources; s++) {
1179:                        if (src[s] != null) {
1180:                            sBandData[s] = srcData[s][b];
1181:                            sLineOffsets[s] = srcBandOffsets[s][b];
1182:                        }
1183:                        if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
1184:                            aBandData[s] = alfaData[s][0];
1185:                            aLineOffsets[s] = alfaBandOffsets[s][0];
1186:                        }
1187:                    }
1188:
1189:                    // Initialize destination band array and line offsets.
1190:                    short[] dBandData = dstData[b];
1191:                    int dLineOffset = dstBandOffsets[b];
1192:
1193:                    if (mosaicType == MosaicDescriptor.MOSAIC_TYPE_OVERLAY) {
1194:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
1195:                            // Initialize source and alpha pixel offsets and
1196:                            // update line offsets.
1197:                            for (int s = 0; s < numSources; s++) {
1198:                                if (src[s] != null) {
1199:                                    sPixelOffsets[s] = sLineOffsets[s];
1200:                                    sLineOffsets[s] += srcLineStride[s];
1201:                                }
1202:                                if (alfa[s] != null) {
1203:                                    aPixelOffsets[s] = aLineOffsets[s];
1204:                                    aLineOffsets[s] += alfaLineStride[s];
1205:                                }
1206:                            }
1207:
1208:                            // Initialize destination pixel offset and update
1209:                            // line offset.
1210:                            int dPixelOffset = dLineOffset;
1211:                            dLineOffset += dstLineStride;
1212:
1213:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
1214:
1215:                                // Unset destination update flag.
1216:                                boolean setDestValue = false;
1217:
1218:                                // Loop over source until a non-zero weight is
1219:                                // encountered.
1220:                                for (int s = 0; s < numSources; s++) {
1221:                                    if (src[s] == null)
1222:                                        continue;
1223:
1224:                                    short sourceValue = sBandData[s][sPixelOffsets[s]];
1225:                                    sPixelOffsets[s] += srcPixelStride[s];
1226:
1227:                                    switch (weightTypes[s]) {
1228:                                    case WEIGHT_TYPE_ALPHA:
1229:                                        setDestValue = aBandData[s][aPixelOffsets[s]] != 0;
1230:                                        aPixelOffsets[s] += alfaPixelStride[s];
1231:                                        break;
1232:                                    case WEIGHT_TYPE_ROI:
1233:                                        setDestValue = roi[s].getSample(dstX,
1234:                                                dstY, 0) > 0;
1235:                                        break;
1236:                                    default: // WEIGHT_TYPE_THRESHOLD
1237:                                        setDestValue = sourceValue >= sourceThreshold[s][b];
1238:                                    }
1239:
1240:                                    // Set the destination value if a non-zero
1241:                                    // weight was found.
1242:                                    if (setDestValue) {
1243:                                        dBandData[dPixelOffset] = sourceValue;
1244:
1245:                                        // Increment offset of subsequent sources.
1246:                                        for (int k = s + 1; k < numSources; k++) {
1247:                                            if (src[k] != null) {
1248:                                                sPixelOffsets[k] += srcPixelStride[k];
1249:                                            }
1250:                                            if (alfa[k] != null) {
1251:                                                aPixelOffsets[k] += alfaPixelStride[k];
1252:                                            }
1253:                                        }
1254:                                        break;
1255:                                    }
1256:                                }
1257:
1258:                                // Set the destination value to the background if
1259:                                // no value was set.
1260:                                if (!setDestValue) {
1261:                                    dBandData[dPixelOffset] = (short) background[b];
1262:                                }
1263:
1264:                                dPixelOffset += dstPixelStride;
1265:                            }
1266:                        }
1267:                    } else { // mosaicType == MosaicDescriptor.MOSAIC_TYPE_BLEND
1268:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
1269:                            // Initialize source and alpha pixel offsets and
1270:                            // update line offsets.
1271:                            for (int s = 0; s < numSources; s++) {
1272:                                if (src[s] != null) {
1273:                                    sPixelOffsets[s] = sLineOffsets[s];
1274:                                    sLineOffsets[s] += srcLineStride[s];
1275:                                }
1276:                                if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
1277:                                    aPixelOffsets[s] = aLineOffsets[s];
1278:                                    aLineOffsets[s] += alfaLineStride[s];
1279:                                }
1280:                            }
1281:
1282:                            // Initialize destination pixel offset and update
1283:                            // line offset.
1284:                            int dPixelOffset = dLineOffset;
1285:                            dLineOffset += dstLineStride;
1286:
1287:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
1288:
1289:                                // Clear values for blending ratio.
1290:                                float numerator = 0.0F;
1291:                                float denominator = 0.0F;
1292:
1293:                                // Accumulate into numerator and denominator.
1294:                                for (int s = 0; s < numSources; s++) {
1295:                                    if (src[s] == null)
1296:                                        continue;
1297:
1298:                                    short sourceValue = sBandData[s][sPixelOffsets[s]];
1299:                                    sPixelOffsets[s] += srcPixelStride[s];
1300:
1301:                                    float weight = 0.0F;
1302:                                    switch (weightTypes[s]) {
1303:                                    case WEIGHT_TYPE_ALPHA:
1304:                                        weight = aBandData[s][aPixelOffsets[s]];
1305:                                        if (weight > 0.0F && isAlphaBitmask) {
1306:                                            weight = 1.0F;
1307:                                        } else {
1308:                                            weight /= (float) Short.MAX_VALUE;
1309:                                        }
1310:                                        aPixelOffsets[s] += alfaPixelStride[s];
1311:                                        break;
1312:                                    case WEIGHT_TYPE_ROI:
1313:                                        weight = roi[s]
1314:                                                .getSample(dstX, dstY, 0) > 0 ? 1.0F
1315:                                                : 0.0F;
1316:                                        break;
1317:                                    default: // WEIGHT_TYPE_THRESHOLD
1318:                                        weight = sourceValue >= sourceThreshold[s][b] ? 1.0F
1319:                                                : 0.0F;
1320:                                    }
1321:
1322:                                    // Update numerator and denominator.
1323:                                    numerator += weight * sourceValue;
1324:                                    denominator += weight;
1325:                                }
1326:
1327:                                // Clear the background if all weights were zero,
1328:                                // otherwise blend the values.
1329:                                if (denominator == 0.0) {
1330:                                    dBandData[dPixelOffset] = (short) background[b];
1331:                                } else {
1332:                                    dBandData[dPixelOffset] = ImageUtil
1333:                                            .clampRoundShort(numerator
1334:                                                    / denominator);
1335:                                }
1336:
1337:                                dPixelOffset += dstPixelStride;
1338:                            }
1339:                        }
1340:                    }
1341:                }
1342:            }
1343:
1344:            private void computeRectInt(RasterAccessor[] src,
1345:                    RasterAccessor dst, RasterAccessor[] alfa, Raster[] roi) {
1346:                // Save the source count.
1347:                int numSources = src.length;
1348:
1349:                // Allocate stride, offset, and data arrays for sources.
1350:                int[] srcLineStride = new int[numSources];
1351:                int[] srcPixelStride = new int[numSources];
1352:                int[][] srcBandOffsets = new int[numSources][];
1353:                int[][][] srcData = new int[numSources][][];
1354:
1355:                // Initialize stride, offset, and data arrays for sources.
1356:                for (int i = 0; i < numSources; i++) {
1357:                    if (src[i] != null) {
1358:                        srcLineStride[i] = src[i].getScanlineStride();
1359:                        srcPixelStride[i] = src[i].getPixelStride();
1360:                        srcBandOffsets[i] = src[i].getBandOffsets();
1361:                        srcData[i] = src[i].getIntDataArrays();
1362:                    }
1363:                }
1364:
1365:                // Initialize destination variables.
1366:                int dstMinX = dst.getX();
1367:                int dstMinY = dst.getY();
1368:                int dstWidth = dst.getWidth();
1369:                int dstHeight = dst.getHeight();
1370:                int dstMaxX = dstMinX + dstWidth; // x max exclusive
1371:                int dstMaxY = dstMinY + dstHeight; // y max exclusive
1372:                int dstBands = dst.getNumBands();
1373:                int dstLineStride = dst.getScanlineStride();
1374:                int dstPixelStride = dst.getPixelStride();
1375:                int[] dstBandOffsets = dst.getBandOffsets();
1376:                int[][] dstData = dst.getIntDataArrays();
1377:
1378:                // Check for alpha.
1379:                boolean hasAlpha = false;
1380:                for (int i = 0; i < numSources; i++) {
1381:                    if (alfa[i] != null) {
1382:                        hasAlpha = true;
1383:                        break;
1384:                    }
1385:                }
1386:
1387:                // Declare alpha channel arrays.
1388:                int[] alfaLineStride = null;
1389:                int[] alfaPixelStride = null;
1390:                int[][] alfaBandOffsets = null;
1391:                int[][][] alfaData = null;
1392:
1393:                if (hasAlpha) {
1394:                    // Allocate stride, offset, and data arrays for alpha channels.
1395:                    alfaLineStride = new int[numSources];
1396:                    alfaPixelStride = new int[numSources];
1397:                    alfaBandOffsets = new int[numSources][];
1398:                    alfaData = new int[numSources][][];
1399:
1400:                    // Initialize stride, offset, and data arrays for alpha channels.
1401:                    for (int i = 0; i < numSources; i++) {
1402:                        if (alfa[i] != null) {
1403:                            alfaLineStride[i] = alfa[i].getScanlineStride();
1404:                            alfaPixelStride[i] = alfa[i].getPixelStride();
1405:                            alfaBandOffsets[i] = alfa[i].getBandOffsets();
1406:                            alfaData[i] = alfa[i].getIntDataArrays();
1407:                        }
1408:                    }
1409:                }
1410:
1411:                // Initialize weight type arrays.
1412:                int[] weightTypes = new int[numSources];
1413:                for (int i = 0; i < numSources; i++) {
1414:                    weightTypes[i] = WEIGHT_TYPE_THRESHOLD;
1415:                    if (alfa[i] != null) {
1416:                        weightTypes[i] = WEIGHT_TYPE_ALPHA;
1417:                    } else if (sourceROI != null && sourceROI[i] != null) {
1418:                        weightTypes[i] = WEIGHT_TYPE_ROI;
1419:                    }
1420:                }
1421:
1422:                // Set up source offset and data variabls.
1423:                int[] sLineOffsets = new int[numSources];
1424:                int[] sPixelOffsets = new int[numSources];
1425:                int[][] sBandData = new int[numSources][];
1426:
1427:                // Set up alpha offset and data variabls.
1428:                int[] aLineOffsets = null;
1429:                int[] aPixelOffsets = null;
1430:                int[][] aBandData = null;
1431:                if (hasAlpha) {
1432:                    aLineOffsets = new int[numSources];
1433:                    aPixelOffsets = new int[numSources];
1434:                    aBandData = new int[numSources][];
1435:                }
1436:
1437:                for (int b = 0; b < dstBands; b++) {
1438:                    // Initialize source and alpha band array and line offsets.
1439:                    for (int s = 0; s < numSources; s++) {
1440:                        if (src[s] != null) {
1441:                            sBandData[s] = srcData[s][b];
1442:                            sLineOffsets[s] = srcBandOffsets[s][b];
1443:                        }
1444:                        if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
1445:                            aBandData[s] = alfaData[s][0];
1446:                            aLineOffsets[s] = alfaBandOffsets[s][0];
1447:                        }
1448:                    }
1449:
1450:                    // Initialize destination band array and line offsets.
1451:                    int[] dBandData = dstData[b];
1452:                    int dLineOffset = dstBandOffsets[b];
1453:
1454:                    if (mosaicType == MosaicDescriptor.MOSAIC_TYPE_OVERLAY) {
1455:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
1456:                            // Initialize source and alpha pixel offsets and
1457:                            // update line offsets.
1458:                            for (int s = 0; s < numSources; s++) {
1459:                                if (src[s] != null) {
1460:                                    sPixelOffsets[s] = sLineOffsets[s];
1461:                                    sLineOffsets[s] += srcLineStride[s];
1462:                                }
1463:                                if (alfa[s] != null) {
1464:                                    aPixelOffsets[s] = aLineOffsets[s];
1465:                                    aLineOffsets[s] += alfaLineStride[s];
1466:                                }
1467:                            }
1468:
1469:                            // Initialize destination pixel offset and update
1470:                            // line offset.
1471:                            int dPixelOffset = dLineOffset;
1472:                            dLineOffset += dstLineStride;
1473:
1474:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
1475:
1476:                                // Unset destination update flag.
1477:                                boolean setDestValue = false;
1478:
1479:                                // Loop over source until a non-zero weight is
1480:                                // encountered.
1481:                                for (int s = 0; s < numSources; s++) {
1482:                                    if (src[s] == null)
1483:                                        continue;
1484:
1485:                                    int sourceValue = sBandData[s][sPixelOffsets[s]];
1486:                                    sPixelOffsets[s] += srcPixelStride[s];
1487:
1488:                                    switch (weightTypes[s]) {
1489:                                    case WEIGHT_TYPE_ALPHA:
1490:                                        setDestValue = aBandData[s][aPixelOffsets[s]] != 0;
1491:                                        aPixelOffsets[s] += alfaPixelStride[s];
1492:                                        break;
1493:                                    case WEIGHT_TYPE_ROI:
1494:                                        setDestValue = roi[s].getSample(dstX,
1495:                                                dstY, 0) > 0;
1496:                                        break;
1497:                                    default: // WEIGHT_TYPE_THRESHOLD
1498:                                        setDestValue = sourceValue >= sourceThreshold[s][b];
1499:                                    }
1500:
1501:                                    // Set the destination value if a non-zero
1502:                                    // weight was found.
1503:                                    if (setDestValue) {
1504:                                        dBandData[dPixelOffset] = sourceValue;
1505:
1506:                                        // Increment offset of subsequent sources.
1507:                                        for (int k = s + 1; k < numSources; k++) {
1508:                                            if (src[k] != null) {
1509:                                                sPixelOffsets[k] += srcPixelStride[k];
1510:                                            }
1511:                                            if (alfa[k] != null) {
1512:                                                aPixelOffsets[k] += alfaPixelStride[k];
1513:                                            }
1514:                                        }
1515:                                        break;
1516:                                    }
1517:                                }
1518:
1519:                                // Set the destination value to the background if
1520:                                // no value was set.
1521:                                if (!setDestValue) {
1522:                                    dBandData[dPixelOffset] = (int) background[b];
1523:                                }
1524:
1525:                                dPixelOffset += dstPixelStride;
1526:                            }
1527:                        }
1528:                    } else { // mosaicType == MosaicDescriptor.MOSAIC_TYPE_BLEND
1529:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
1530:                            // Initialize source and alpha pixel offsets and
1531:                            // update line offsets.
1532:                            for (int s = 0; s < numSources; s++) {
1533:                                if (src[s] != null) {
1534:                                    sPixelOffsets[s] = sLineOffsets[s];
1535:                                    sLineOffsets[s] += srcLineStride[s];
1536:                                }
1537:                                if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
1538:                                    aPixelOffsets[s] = aLineOffsets[s];
1539:                                    aLineOffsets[s] += alfaLineStride[s];
1540:                                }
1541:                            }
1542:
1543:                            // Initialize destination pixel offset and update
1544:                            // line offset.
1545:                            int dPixelOffset = dLineOffset;
1546:                            dLineOffset += dstLineStride;
1547:
1548:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
1549:
1550:                                // Clear values for blending ratio.
1551:                                double numerator = 0.0;
1552:                                double denominator = 0.0;
1553:
1554:                                // Accumulate into numerator and denominator.
1555:                                for (int s = 0; s < numSources; s++) {
1556:                                    if (src[s] == null)
1557:                                        continue;
1558:
1559:                                    int sourceValue = sBandData[s][sPixelOffsets[s]];
1560:                                    sPixelOffsets[s] += srcPixelStride[s];
1561:
1562:                                    double weight = 0.0;
1563:                                    switch (weightTypes[s]) {
1564:                                    case WEIGHT_TYPE_ALPHA:
1565:                                        weight = aBandData[s][aPixelOffsets[s]];
1566:                                        if (weight > 0.0F && isAlphaBitmask) {
1567:                                            weight = 1.0F;
1568:                                        } else {
1569:                                            weight /= Integer.MAX_VALUE;
1570:                                        }
1571:                                        aPixelOffsets[s] += alfaPixelStride[s];
1572:                                        break;
1573:                                    case WEIGHT_TYPE_ROI:
1574:                                        weight = roi[s]
1575:                                                .getSample(dstX, dstY, 0) > 0 ? 1.0F
1576:                                                : 0.0F;
1577:                                        break;
1578:                                    default: // WEIGHT_TYPE_THRESHOLD
1579:                                        weight = sourceValue >= sourceThreshold[s][b] ? 1.0F
1580:                                                : 0.0F;
1581:                                    }
1582:
1583:                                    // Update numerator and denominator.
1584:                                    numerator += weight * sourceValue;
1585:                                    denominator += weight;
1586:                                }
1587:
1588:                                // Clear the background if all weights were zero,
1589:                                // otherwise blend the values.
1590:                                if (denominator == 0.0) {
1591:                                    dBandData[dPixelOffset] = (int) background[b];
1592:                                } else {
1593:                                    dBandData[dPixelOffset] = ImageUtil
1594:                                            .clampRoundInt(numerator
1595:                                                    / denominator);
1596:                                }
1597:
1598:                                dPixelOffset += dstPixelStride;
1599:                            }
1600:                        }
1601:                    }
1602:                }
1603:            }
1604:
1605:            private void computeRectFloat(RasterAccessor[] src,
1606:                    RasterAccessor dst, RasterAccessor[] alfa, Raster[] roi) {
1607:                // Save the source count.
1608:                int numSources = src.length;
1609:
1610:                // Allocate stride, offset, and data arrays for sources.
1611:                int[] srcLineStride = new int[numSources];
1612:                int[] srcPixelStride = new int[numSources];
1613:                int[][] srcBandOffsets = new int[numSources][];
1614:                float[][][] srcData = new float[numSources][][];
1615:
1616:                // Initialize stride, offset, and data arrays for sources.
1617:                for (int i = 0; i < numSources; i++) {
1618:                    if (src[i] != null) {
1619:                        srcLineStride[i] = src[i].getScanlineStride();
1620:                        srcPixelStride[i] = src[i].getPixelStride();
1621:                        srcBandOffsets[i] = src[i].getBandOffsets();
1622:                        srcData[i] = src[i].getFloatDataArrays();
1623:                    }
1624:                }
1625:
1626:                // Initialize destination variables.
1627:                int dstMinX = dst.getX();
1628:                int dstMinY = dst.getY();
1629:                int dstWidth = dst.getWidth();
1630:                int dstHeight = dst.getHeight();
1631:                int dstMaxX = dstMinX + dstWidth; // x max exclusive
1632:                int dstMaxY = dstMinY + dstHeight; // y max exclusive
1633:                int dstBands = dst.getNumBands();
1634:                int dstLineStride = dst.getScanlineStride();
1635:                int dstPixelStride = dst.getPixelStride();
1636:                int[] dstBandOffsets = dst.getBandOffsets();
1637:                float[][] dstData = dst.getFloatDataArrays();
1638:
1639:                // Check for alpha.
1640:                boolean hasAlpha = false;
1641:                for (int i = 0; i < numSources; i++) {
1642:                    if (alfa[i] != null) {
1643:                        hasAlpha = true;
1644:                        break;
1645:                    }
1646:                }
1647:
1648:                // Declare alpha channel arrays.
1649:                int[] alfaLineStride = null;
1650:                int[] alfaPixelStride = null;
1651:                int[][] alfaBandOffsets = null;
1652:                float[][][] alfaData = null;
1653:
1654:                if (hasAlpha) {
1655:                    // Allocate stride, offset, and data arrays for alpha channels.
1656:                    alfaLineStride = new int[numSources];
1657:                    alfaPixelStride = new int[numSources];
1658:                    alfaBandOffsets = new int[numSources][];
1659:                    alfaData = new float[numSources][][];
1660:
1661:                    // Initialize stride, offset, and data arrays for alpha channels.
1662:                    for (int i = 0; i < numSources; i++) {
1663:                        if (alfa[i] != null) {
1664:                            alfaLineStride[i] = alfa[i].getScanlineStride();
1665:                            alfaPixelStride[i] = alfa[i].getPixelStride();
1666:                            alfaBandOffsets[i] = alfa[i].getBandOffsets();
1667:                            alfaData[i] = alfa[i].getFloatDataArrays();
1668:                        }
1669:                    }
1670:                }
1671:
1672:                // Initialize weight type arrays.
1673:                int[] weightTypes = new int[numSources];
1674:                for (int i = 0; i < numSources; i++) {
1675:                    weightTypes[i] = WEIGHT_TYPE_THRESHOLD;
1676:                    if (alfa[i] != null) {
1677:                        weightTypes[i] = WEIGHT_TYPE_ALPHA;
1678:                    } else if (sourceROI != null && sourceROI[i] != null) {
1679:                        weightTypes[i] = WEIGHT_TYPE_ROI;
1680:                    }
1681:                }
1682:
1683:                // Set up source offset and data variabls.
1684:                int[] sLineOffsets = new int[numSources];
1685:                int[] sPixelOffsets = new int[numSources];
1686:                float[][] sBandData = new float[numSources][];
1687:
1688:                // Set up alpha offset and data variabls.
1689:                int[] aLineOffsets = null;
1690:                int[] aPixelOffsets = null;
1691:                float[][] aBandData = null;
1692:                if (hasAlpha) {
1693:                    aLineOffsets = new int[numSources];
1694:                    aPixelOffsets = new int[numSources];
1695:                    aBandData = new float[numSources][];
1696:                }
1697:
1698:                for (int b = 0; b < dstBands; b++) {
1699:                    // Initialize source and alpha band array and line offsets.
1700:                    for (int s = 0; s < numSources; s++) {
1701:                        if (src[s] != null) {
1702:                            sBandData[s] = srcData[s][b];
1703:                            sLineOffsets[s] = srcBandOffsets[s][b];
1704:                        }
1705:                        if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
1706:                            aBandData[s] = alfaData[s][0];
1707:                            aLineOffsets[s] = alfaBandOffsets[s][0];
1708:                        }
1709:                    }
1710:
1711:                    // Initialize destination band array and line offsets.
1712:                    float[] dBandData = dstData[b];
1713:                    int dLineOffset = dstBandOffsets[b];
1714:
1715:                    if (mosaicType == MosaicDescriptor.MOSAIC_TYPE_OVERLAY) {
1716:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
1717:                            // Initialize source and alpha pixel offsets and
1718:                            // update line offsets.
1719:                            for (int s = 0; s < numSources; s++) {
1720:                                if (src[s] != null) {
1721:                                    sPixelOffsets[s] = sLineOffsets[s];
1722:                                    sLineOffsets[s] += srcLineStride[s];
1723:                                }
1724:                                if (alfa[s] != null) {
1725:                                    aPixelOffsets[s] = aLineOffsets[s];
1726:                                    aLineOffsets[s] += alfaLineStride[s];
1727:                                }
1728:                            }
1729:
1730:                            // Initialize destination pixel offset and update
1731:                            // line offset.
1732:                            int dPixelOffset = dLineOffset;
1733:                            dLineOffset += dstLineStride;
1734:
1735:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
1736:
1737:                                // Unset destination update flag.
1738:                                boolean setDestValue = false;
1739:
1740:                                // Loop over source until a non-zero weight is
1741:                                // encountered.
1742:                                for (int s = 0; s < numSources; s++) {
1743:                                    if (src[s] == null)
1744:                                        continue;
1745:
1746:                                    float sourceValue = sBandData[s][sPixelOffsets[s]];
1747:                                    sPixelOffsets[s] += srcPixelStride[s];
1748:
1749:                                    switch (weightTypes[s]) {
1750:                                    case WEIGHT_TYPE_ALPHA:
1751:                                        setDestValue = aBandData[s][aPixelOffsets[s]] != 0;
1752:                                        aPixelOffsets[s] += alfaPixelStride[s];
1753:                                        break;
1754:                                    case WEIGHT_TYPE_ROI:
1755:                                        setDestValue = roi[s].getSample(dstX,
1756:                                                dstY, 0) > 0;
1757:                                        break;
1758:                                    default: // WEIGHT_TYPE_THRESHOLD
1759:                                        setDestValue = sourceValue >= sourceThreshold[s][b];
1760:                                    }
1761:
1762:                                    // Set the destination value if a non-zero
1763:                                    // weight was found.
1764:                                    if (setDestValue) {
1765:                                        dBandData[dPixelOffset] = sourceValue;
1766:
1767:                                        // Increment offset of subsequent sources.
1768:                                        for (int k = s + 1; k < numSources; k++) {
1769:                                            if (src[k] != null) {
1770:                                                sPixelOffsets[k] += srcPixelStride[k];
1771:                                            }
1772:                                            if (alfa[k] != null) {
1773:                                                aPixelOffsets[k] += alfaPixelStride[k];
1774:                                            }
1775:                                        }
1776:                                        break;
1777:                                    }
1778:                                }
1779:
1780:                                // Set the destination value to the background if
1781:                                // no value was set.
1782:                                if (!setDestValue) {
1783:                                    dBandData[dPixelOffset] = (float) backgroundValues[b];
1784:                                }
1785:
1786:                                dPixelOffset += dstPixelStride;
1787:                            }
1788:                        }
1789:                    } else { // mosaicType == MosaicDescriptor.MOSAIC_TYPE_BLEND
1790:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
1791:                            // Initialize source and alpha pixel offsets and
1792:                            // update line offsets.
1793:                            for (int s = 0; s < numSources; s++) {
1794:                                if (src[s] != null) {
1795:                                    sPixelOffsets[s] = sLineOffsets[s];
1796:                                    sLineOffsets[s] += srcLineStride[s];
1797:                                }
1798:                                if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
1799:                                    aPixelOffsets[s] = aLineOffsets[s];
1800:                                    aLineOffsets[s] += alfaLineStride[s];
1801:                                }
1802:                            }
1803:
1804:                            // Initialize destination pixel offset and update
1805:                            // line offset.
1806:                            int dPixelOffset = dLineOffset;
1807:                            dLineOffset += dstLineStride;
1808:
1809:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
1810:
1811:                                // Clear values for blending ratio.
1812:                                float numerator = 0.0F;
1813:                                float denominator = 0.0F;
1814:
1815:                                // Accumulate into numerator and denominator.
1816:                                for (int s = 0; s < numSources; s++) {
1817:                                    if (src[s] == null)
1818:                                        continue;
1819:
1820:                                    float sourceValue = sBandData[s][sPixelOffsets[s]];
1821:                                    sPixelOffsets[s] += srcPixelStride[s];
1822:
1823:                                    float weight = 0.0F;
1824:                                    switch (weightTypes[s]) {
1825:                                    case WEIGHT_TYPE_ALPHA:
1826:                                        weight = aBandData[s][aPixelOffsets[s]];
1827:                                        if (weight > 0.0F && isAlphaBitmask) {
1828:                                            weight = 1.0F;
1829:                                        }
1830:                                        aPixelOffsets[s] += alfaPixelStride[s];
1831:                                        break;
1832:                                    case WEIGHT_TYPE_ROI:
1833:                                        weight = roi[s]
1834:                                                .getSample(dstX, dstY, 0) > 0 ? 1.0F
1835:                                                : 0.0F;
1836:                                        break;
1837:                                    default: // WEIGHT_TYPE_THRESHOLD
1838:                                        weight = sourceValue >= sourceThreshold[s][b] ? 1.0F
1839:                                                : 0.0F;
1840:                                    }
1841:
1842:                                    // Update numerator and denominator.
1843:                                    numerator += weight * sourceValue;
1844:                                    denominator += weight;
1845:                                }
1846:
1847:                                // Clear the background if all weights were zero,
1848:                                // otherwise blend the values.
1849:                                if (denominator == 0.0) {
1850:                                    dBandData[dPixelOffset] = (float) backgroundValues[b];
1851:                                } else {
1852:                                    dBandData[dPixelOffset] = numerator
1853:                                            / denominator;
1854:                                }
1855:
1856:                                dPixelOffset += dstPixelStride;
1857:                            }
1858:                        }
1859:                    }
1860:                }
1861:            }
1862:
1863:            private void computeRectDouble(RasterAccessor[] src,
1864:                    RasterAccessor dst, RasterAccessor[] alfa, Raster[] roi) {
1865:                // Save the source count.
1866:                int numSources = src.length;
1867:
1868:                // Allocate stride, offset, and data arrays for sources.
1869:                int[] srcLineStride = new int[numSources];
1870:                int[] srcPixelStride = new int[numSources];
1871:                int[][] srcBandOffsets = new int[numSources][];
1872:                double[][][] srcData = new double[numSources][][];
1873:
1874:                // Initialize stride, offset, and data arrays for sources.
1875:                for (int i = 0; i < numSources; i++) {
1876:                    if (src[i] != null) {
1877:                        srcLineStride[i] = src[i].getScanlineStride();
1878:                        srcPixelStride[i] = src[i].getPixelStride();
1879:                        srcBandOffsets[i] = src[i].getBandOffsets();
1880:                        srcData[i] = src[i].getDoubleDataArrays();
1881:                    }
1882:                }
1883:
1884:                // Initialize destination variables.
1885:                int dstMinX = dst.getX();
1886:                int dstMinY = dst.getY();
1887:                int dstWidth = dst.getWidth();
1888:                int dstHeight = dst.getHeight();
1889:                int dstMaxX = dstMinX + dstWidth; // x max exclusive
1890:                int dstMaxY = dstMinY + dstHeight; // y max exclusive
1891:                int dstBands = dst.getNumBands();
1892:                int dstLineStride = dst.getScanlineStride();
1893:                int dstPixelStride = dst.getPixelStride();
1894:                int[] dstBandOffsets = dst.getBandOffsets();
1895:                double[][] dstData = dst.getDoubleDataArrays();
1896:
1897:                // Check for alpha.
1898:                boolean hasAlpha = false;
1899:                for (int i = 0; i < numSources; i++) {
1900:                    if (alfa[i] != null) {
1901:                        hasAlpha = true;
1902:                        break;
1903:                    }
1904:                }
1905:
1906:                // Declare alpha channel arrays.
1907:                int[] alfaLineStride = null;
1908:                int[] alfaPixelStride = null;
1909:                int[][] alfaBandOffsets = null;
1910:                double[][][] alfaData = null;
1911:
1912:                if (hasAlpha) {
1913:                    // Allocate stride, offset, and data arrays for alpha channels.
1914:                    alfaLineStride = new int[numSources];
1915:                    alfaPixelStride = new int[numSources];
1916:                    alfaBandOffsets = new int[numSources][];
1917:                    alfaData = new double[numSources][][];
1918:
1919:                    // Initialize stride, offset, and data arrays for alpha channels.
1920:                    for (int i = 0; i < numSources; i++) {
1921:                        if (alfa[i] != null) {
1922:                            alfaLineStride[i] = alfa[i].getScanlineStride();
1923:                            alfaPixelStride[i] = alfa[i].getPixelStride();
1924:                            alfaBandOffsets[i] = alfa[i].getBandOffsets();
1925:                            alfaData[i] = alfa[i].getDoubleDataArrays();
1926:                        }
1927:                    }
1928:                }
1929:
1930:                // Initialize weight type arrays.
1931:                int[] weightTypes = new int[numSources];
1932:                for (int i = 0; i < numSources; i++) {
1933:                    weightTypes[i] = WEIGHT_TYPE_THRESHOLD;
1934:                    if (alfa[i] != null) {
1935:                        weightTypes[i] = WEIGHT_TYPE_ALPHA;
1936:                    } else if (sourceROI != null && sourceROI[i] != null) {
1937:                        weightTypes[i] = WEIGHT_TYPE_ROI;
1938:                    }
1939:                }
1940:
1941:                // Set up source offset and data variabls.
1942:                int[] sLineOffsets = new int[numSources];
1943:                int[] sPixelOffsets = new int[numSources];
1944:                double[][] sBandData = new double[numSources][];
1945:
1946:                // Set up alpha offset and data variabls.
1947:                int[] aLineOffsets = null;
1948:                int[] aPixelOffsets = null;
1949:                double[][] aBandData = null;
1950:                if (hasAlpha) {
1951:                    aLineOffsets = new int[numSources];
1952:                    aPixelOffsets = new int[numSources];
1953:                    aBandData = new double[numSources][];
1954:                }
1955:
1956:                for (int b = 0; b < dstBands; b++) {
1957:                    // Initialize source and alpha band array and line offsets.
1958:                    for (int s = 0; s < numSources; s++) {
1959:                        if (src[s] != null) {
1960:                            sBandData[s] = srcData[s][b];
1961:                            sLineOffsets[s] = srcBandOffsets[s][b];
1962:                        }
1963:                        if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
1964:                            aBandData[s] = alfaData[s][0];
1965:                            aLineOffsets[s] = alfaBandOffsets[s][0];
1966:                        }
1967:                    }
1968:
1969:                    // Initialize destination band array and line offsets.
1970:                    double[] dBandData = dstData[b];
1971:                    int dLineOffset = dstBandOffsets[b];
1972:
1973:                    if (mosaicType == MosaicDescriptor.MOSAIC_TYPE_OVERLAY) {
1974:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
1975:                            // Initialize source and alpha pixel offsets and
1976:                            // update line offsets.
1977:                            for (int s = 0; s < numSources; s++) {
1978:                                if (src[s] != null) {
1979:                                    sPixelOffsets[s] = sLineOffsets[s];
1980:                                    sLineOffsets[s] += srcLineStride[s];
1981:                                }
1982:                                if (alfa[s] != null) {
1983:                                    aPixelOffsets[s] = aLineOffsets[s];
1984:                                    aLineOffsets[s] += alfaLineStride[s];
1985:                                }
1986:                            }
1987:
1988:                            // Initialize destination pixel offset and update
1989:                            // line offset.
1990:                            int dPixelOffset = dLineOffset;
1991:                            dLineOffset += dstLineStride;
1992:
1993:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
1994:
1995:                                // Unset destination update flag.
1996:                                boolean setDestValue = false;
1997:
1998:                                // Loop over source until a non-zero weight is
1999:                                // encountered.
2000:                                for (int s = 0; s < numSources; s++) {
2001:                                    if (src[s] == null)
2002:                                        continue;
2003:
2004:                                    double sourceValue = sBandData[s][sPixelOffsets[s]];
2005:                                    sPixelOffsets[s] += srcPixelStride[s];
2006:
2007:                                    switch (weightTypes[s]) {
2008:                                    case WEIGHT_TYPE_ALPHA:
2009:                                        setDestValue = aBandData[s][aPixelOffsets[s]] != 0;
2010:                                        aPixelOffsets[s] += alfaPixelStride[s];
2011:                                        break;
2012:                                    case WEIGHT_TYPE_ROI:
2013:                                        setDestValue = roi[s].getSample(dstX,
2014:                                                dstY, 0) > 0;
2015:                                        break;
2016:                                    default: // WEIGHT_TYPE_THRESHOLD
2017:                                        setDestValue = sourceValue >= sourceThreshold[s][b];
2018:                                    }
2019:
2020:                                    // Set the destination value if a non-zero
2021:                                    // weight was found.
2022:                                    if (setDestValue) {
2023:                                        dBandData[dPixelOffset] = sourceValue;
2024:
2025:                                        // Increment offset of subsequent sources.
2026:                                        for (int k = s + 1; k < numSources; k++) {
2027:                                            if (src[k] != null) {
2028:                                                sPixelOffsets[k] += srcPixelStride[k];
2029:                                            }
2030:                                            if (alfa[k] != null) {
2031:                                                aPixelOffsets[k] += alfaPixelStride[k];
2032:                                            }
2033:                                        }
2034:                                        break;
2035:                                    }
2036:                                }
2037:
2038:                                // Set the destination value to the background if
2039:                                // no value was set.
2040:                                if (!setDestValue) {
2041:                                    dBandData[dPixelOffset] = backgroundValues[b];
2042:                                }
2043:
2044:                                dPixelOffset += dstPixelStride;
2045:                            }
2046:                        }
2047:                    } else { // mosaicType == MosaicDescriptor.MOSAIC_TYPE_BLEND
2048:                        for (int dstY = dstMinY; dstY < dstMaxY; dstY++) {
2049:                            // Initialize source and alpha pixel offsets and
2050:                            // update line offsets.
2051:                            for (int s = 0; s < numSources; s++) {
2052:                                if (src[s] != null) {
2053:                                    sPixelOffsets[s] = sLineOffsets[s];
2054:                                    sLineOffsets[s] += srcLineStride[s];
2055:                                }
2056:                                if (weightTypes[s] == WEIGHT_TYPE_ALPHA) {
2057:                                    aPixelOffsets[s] = aLineOffsets[s];
2058:                                    aLineOffsets[s] += alfaLineStride[s];
2059:                                }
2060:                            }
2061:
2062:                            // Initialize destination pixel offset and update
2063:                            // line offset.
2064:                            int dPixelOffset = dLineOffset;
2065:                            dLineOffset += dstLineStride;
2066:
2067:                            for (int dstX = dstMinX; dstX < dstMaxX; dstX++) {
2068:
2069:                                // Clear values for blending ratio.
2070:                                double numerator = 0.0F;
2071:                                double denominator = 0.0F;
2072:
2073:                                // Accumulate into numerator and denominator.
2074:                                for (int s = 0; s < numSources; s++) {
2075:                                    if (src[s] == null)
2076:                                        continue;
2077:
2078:                                    double sourceValue = sBandData[s][sPixelOffsets[s]];
2079:                                    sPixelOffsets[s] += srcPixelStride[s];
2080:
2081:                                    double weight = 0.0F;
2082:                                    switch (weightTypes[s]) {
2083:                                    case WEIGHT_TYPE_ALPHA:
2084:                                        weight = aBandData[s][aPixelOffsets[s]];
2085:                                        if (weight > 0.0F && isAlphaBitmask) {
2086:                                            weight = 1.0F;
2087:                                        }
2088:                                        aPixelOffsets[s] += alfaPixelStride[s];
2089:                                        break;
2090:                                    case WEIGHT_TYPE_ROI:
2091:                                        weight = roi[s]
2092:                                                .getSample(dstX, dstY, 0) > 0 ? 1.0F
2093:                                                : 0.0F;
2094:                                        break;
2095:                                    default: // WEIGHT_TYPE_THRESHOLD
2096:                                        weight = sourceValue >= sourceThreshold[s][b] ? 1.0F
2097:                                                : 0.0F;
2098:                                    }
2099:
2100:                                    // Update numerator and denominator.
2101:                                    numerator += weight * sourceValue;
2102:                                    denominator += weight;
2103:                                }
2104:
2105:                                // Clear the background if all weights were zero,
2106:                                // otherwise blend the values.
2107:                                if (denominator == 0.0) {
2108:                                    dBandData[dPixelOffset] = backgroundValues[b];
2109:                                } else {
2110:                                    dBandData[dPixelOffset] = numerator
2111:                                            / denominator;
2112:                                }
2113:
2114:                                dPixelOffset += dstPixelStride;
2115:                            }
2116:                        }
2117:                    }
2118:                }
2119:            }
2120:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.