Source Code Cross Referenced for CompositeOpImage.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: CompositeOpImage.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/12/08 00:58:33 $
0010:         * $State: Exp $
0011:         */
0012:        package com.sun.media.jai.opimage;
0013:
0014:        import java.awt.Rectangle;
0015:        import java.awt.image.ColorModel;
0016:        import java.awt.image.IndexColorModel;
0017:        import java.awt.image.DataBuffer;
0018:        import java.awt.image.Raster;
0019:        import java.awt.image.RenderedImage;
0020:        import java.awt.image.SampleModel;
0021:        import java.awt.image.WritableRaster;
0022:        import java.util.Map;
0023:        import javax.media.jai.ImageLayout;
0024:        import javax.media.jai.OpImage;
0025:        import javax.media.jai.PointOpImage;
0026:        import javax.media.jai.RasterAccessor;
0027:        import javax.media.jai.RasterFormatTag;
0028:        import javax.media.jai.RasterFactory;
0029:        import com.sun.media.jai.util.ImageUtil;
0030:        import com.sun.media.jai.util.JDKWorkarounds;
0031:
0032:        // import com.sun.media.jai.test.OpImageTester;
0033:
0034:        /**
0035:         * An <code>OpImage</code> implementing the "Composite" operation as
0036:         * described in <code>javax.media.jai.operator.CompositeDescriptor</code>.
0037:         *
0038:         * <p>For two source images <code>src1</code> and <code>src2</code>,
0039:         * this <code>OpImage</code> places the foreground <code>src1</code>
0040:         * in front of the background <code>src2</code>. This is what commonly
0041:         * known as the "over" composite.
0042:         *
0043:         * <p>The destination image contains both the alpha channel and the
0044:         * color channels. The alpha channel index is determined by the parameter
0045:         * <code>alphaFirst</code>: if true, alpha is the first channel; if false,
0046:         * alpha is the last channel. The formulas used to calculate destination
0047:         * alpha and color values are:
0048:         * <pre>
0049:         * dstAlpha = src1Alpha + src2Alpha * (1 - src1Alpha)
0050:         * dstColor = src1Color + src2Color * (1 - src1Alpha)
0051:         * </pre>
0052:         * where alpha values are in fraction format, and color values are alpha
0053:         * pre-multiplied.
0054:         *
0055:         * <p>The following assumptions are made:
0056:         * <li>The source images, their alpha images, and the destination image all
0057:         * have the same data type.</li>
0058:         * <li>The two source images have the same number of bands and should only
0059:         * contain the color channels.</li>
0060:         * <li>The alpha images are of the same dimension as their cooresponding source
0061:         * image and should be single-banded. If a multi-banded image is supplied, the
0062:         * default band (band 0) is used.</li>
0063:         * <li>If <code>alphaPremultiplied</code> is true, both the source and
0064:         * destination images have alpha pre-multiplied, and vice versa.</li>
0065:         * <li>The destination image must have at least one extra band than the two
0066:         * sources, which represents the alpha channel. It may be user-specified
0067:         * to be the first or the last band of the pixel data.</li>
0068:         *
0069:         * @see javax.media.jai.operator.CompositeDescriptor
0070:         * @see CompositeCRIF
0071:         *
0072:         */
0073:        final class CompositeOpImage extends PointOpImage {
0074:
0075:            /** The alpha image that overrides the alpha for source1. */
0076:            protected RenderedImage source1Alpha;
0077:
0078:            /** The alpha image that overrides the alpha for source2. */
0079:            protected RenderedImage source2Alpha;
0080:
0081:            /** Indicates whether alpha has been premultiplied. */
0082:            protected boolean alphaPremultiplied;
0083:
0084:            /** The alpha and color band offset. */
0085:            private int aOffset; // alpha channel offset
0086:            private int cOffset; // color channels offset
0087:
0088:            /** Maximum Value supported by the data type if it's integral types. */
0089:            private byte maxValueByte;
0090:            private short maxValueShort;
0091:            private int maxValue;
0092:            private float invMaxValue; // 1 / maxValue
0093:
0094:            /**
0095:             * Constructs an <code>CompositeOpImage</code>.
0096:             *
0097:             * @param source1             The foreground source image.
0098:             * @param source2             The background source image.
0099:             * @param layout              The destination image layout.
0100:             * @param source1Alpha        The alpha image that overrides the
0101:             *                            alpha for source1; may not be null.
0102:             * @param source2Alpha        The alpha image that overrides the alpha for
0103:             *                            source2; may be null, in which case source2
0104:             *                            is considered completely opaque.
0105:             * @param alphaPremultiplied  Indicates whether alpha has been
0106:             *                            premultiplied to both sources.
0107:             * @param alphaFirst          If true, alpha is the first band (band 0) in
0108:             *                            destination image; if false, alpha is the
0109:             *                            last band.
0110:             */
0111:            public CompositeOpImage(RenderedImage source1,
0112:                    RenderedImage source2, Map config, ImageLayout layout,
0113:                    RenderedImage source1Alpha, RenderedImage source2Alpha,
0114:                    boolean alphaPremultiplied, boolean alphaFirst) {
0115:                super (source1, source2, layout, config, true);
0116:
0117:                this .source1Alpha = source1Alpha;
0118:                this .source2Alpha = source2Alpha;
0119:                this .alphaPremultiplied = alphaPremultiplied;
0120:
0121:                SampleModel sm = source1.getSampleModel();
0122:                ColorModel cm = source1.getColorModel();
0123:                int dtype = sm.getTransferType();
0124:                int bands;
0125:                if (cm instanceof  IndexColorModel) {
0126:                    bands = cm.getNumComponents();
0127:                } else {
0128:                    bands = sm.getNumBands();
0129:                }
0130:                bands += 1; // one additional alpha channel
0131:
0132:                if (sampleModel.getTransferType() != dtype
0133:                        || sampleModel.getNumBands() != bands) {
0134:                    /*
0135:                     * The current destination sampleModel is not suitable for the
0136:                     * two sources and their alpha images.
0137:                     * Create a suitable sampleModel for the destination image.
0138:                     */
0139:                    sampleModel = RasterFactory.createComponentSampleModel(
0140:                            sampleModel, dtype, tileWidth, tileHeight, bands);
0141:
0142:                    if (colorModel != null
0143:                            && !JDKWorkarounds.areCompatibleDataModels(
0144:                                    sampleModel, colorModel)) {
0145:                        colorModel = ImageUtil.getCompatibleColorModel(
0146:                                sampleModel, config);
0147:                    }
0148:                }
0149:
0150:                aOffset = alphaFirst ? 0 : bands - 1;
0151:                cOffset = alphaFirst ? 1 : 0;
0152:
0153:                switch (dtype) {
0154:                case DataBuffer.TYPE_BYTE:
0155:                    maxValue = 0xFF; // byte is unsigned
0156:                    maxValueByte = (byte) 0xFF;
0157:                    break;
0158:                case DataBuffer.TYPE_USHORT:
0159:                    maxValue = 0xFFFF;
0160:                    maxValueShort = (short) 0xFFFF;
0161:                    break;
0162:                case DataBuffer.TYPE_SHORT:
0163:                    maxValue = Short.MAX_VALUE;
0164:                    maxValueShort = Short.MAX_VALUE;
0165:                    break;
0166:                case DataBuffer.TYPE_INT:
0167:                    maxValue = Integer.MAX_VALUE;
0168:                    break;
0169:                default:
0170:                }
0171:                invMaxValue = 1.0F / maxValue;
0172:            }
0173:
0174:            /**
0175:             * Composites two images within a specified rectangle.
0176:             *
0177:             * @param sources   Cobbled source, guaranteed to provide all the
0178:             *                  source data necessary for computing the rectangle.
0179:             * @param dest      The tile containing the rectangle to be computed.
0180:             * @param destRect  The rectangle within the tile to be computed.
0181:             */
0182:            protected void computeRect(Raster[] sources, WritableRaster dest,
0183:                    Rectangle destRect) {
0184:                /* For PointOpImage, srcRect = destRect. */
0185:                RenderedImage[] renderedSources = source2Alpha == null ? new RenderedImage[3]
0186:                        : new RenderedImage[4];
0187:                renderedSources[0] = getSourceImage(0);
0188:                renderedSources[1] = getSourceImage(1);
0189:                renderedSources[2] = source1Alpha;
0190:                Raster source1AlphaRaster = source1Alpha.getData(destRect);
0191:                Raster source2AlphaRaster = null;
0192:                if (source2Alpha != null) {
0193:                    renderedSources[3] = source2Alpha;
0194:                    source2AlphaRaster = source2Alpha.getData(destRect);
0195:                }
0196:
0197:                RasterFormatTag tags[] = RasterAccessor.findCompatibleTags(
0198:                        renderedSources, this );
0199:                RasterAccessor s1 = new RasterAccessor(sources[0], destRect,
0200:                        tags[0], getSourceImage(0).getColorModel());
0201:                RasterAccessor s2 = new RasterAccessor(sources[1], destRect,
0202:                        tags[1], getSourceImage(1).getColorModel());
0203:                RasterAccessor a1 = new RasterAccessor(source1AlphaRaster,
0204:                        destRect, tags[2], source1Alpha.getColorModel());
0205:                RasterAccessor a2 = null, d = null;
0206:
0207:                if (source2Alpha != null) {
0208:                    a2 = new RasterAccessor(source2AlphaRaster, destRect,
0209:                            tags[3], source2Alpha.getColorModel());
0210:                    d = new RasterAccessor(dest, destRect, tags[4], this 
0211:                            .getColorModel());
0212:                } else {
0213:                    a2 = null;
0214:                    d = new RasterAccessor(dest, destRect, tags[3], this 
0215:                            .getColorModel());
0216:                }
0217:
0218:                switch (d.getDataType()) {
0219:                case DataBuffer.TYPE_BYTE:
0220:                    byteLoop(s1, s2, a1, a2, d);
0221:                    break;
0222:                case DataBuffer.TYPE_USHORT:
0223:                    ushortLoop(s1, s2, a1, a2, d);
0224:                    break;
0225:                case DataBuffer.TYPE_SHORT:
0226:                    shortLoop(s1, s2, a1, a2, d);
0227:                    break;
0228:                case DataBuffer.TYPE_INT:
0229:                    intLoop(s1, s2, a1, a2, d);
0230:                    break;
0231:                case DataBuffer.TYPE_FLOAT:
0232:                    floatLoop(s1, s2, a1, a2, d);
0233:                    break;
0234:                case DataBuffer.TYPE_DOUBLE:
0235:                    doubleLoop(s1, s2, a1, a2, d);
0236:                    break;
0237:                }
0238:                d.copyDataToRaster();
0239:            }
0240:
0241:            /*
0242:             * Formulas for integral data types:
0243:             *
0244:             * d[alpha] = dstAlpha * maxValue
0245:             *          = (src1Alpha + src2Alpha * (1 - src1Alpha)) * maxValue
0246:             * if (source2 is opaque (src2Alpha = 1)) {
0247:             *     d[alpha] = (src1Alpha + 1 * (1 - src1Alpha)) * maxValue
0248:             *              = maxValue
0249:             * } else {
0250:             *     d[alpha] = (a1/maxValue + a2/maxValue * (1 - a1/maxValue)) * maxValue
0251:             *              = a1 + a2 * (1 - a1/maxValue)
0252:             * }
0253:             *
0254:             * if (alpha pre-multiplied to sources and destination) {
0255:             *     d[color] = dstColor
0256:             *              = src1Color + src2Color * (1 - src1Alpha)
0257:             *              = s1 + s2 * (1 - a1/maxValue)
0258:             * } else {
0259:             *     if (source2 is opaque (src2Alpha = 1 & dstAlpha = 1)) {
0260:             *         d[color] = dstColor / dstAlpha
0261:             *                  = (src1Color + src2Color * (1 - src1Alpha))
0262:             *                  = s1 * a1/maxValue + s2 * (1 - a1/maxValue)
0263:             *     } else {
0264:             *         d[color] = dstColor / dstAlpha
0265:             *                  = (src1Color + src2Color * (1 - src1Alpha)) / dstAlpha
0266:             *                  = (s1 * a1/maxValue + s2 * a2/maxValue *
0267:             *                    (1 - a1/maxValue)) / (d[alpha]/maxValue)
0268:             *                  = (s1 * a1 + s2 * a2 * (1 - a1/maxValue)) / d[alpha]
0269:             *     }
0270:             * }
0271:             */
0272:
0273:            private void byteLoop(RasterAccessor src1, RasterAccessor src2,
0274:                    RasterAccessor afa1, RasterAccessor afa2, RasterAccessor dst) {
0275:                int dwidth = dst.getWidth();
0276:                int dheight = dst.getHeight();
0277:                int numBands = src1.getNumBands();
0278:
0279:                /* First source color channels. */
0280:                byte[][] s1 = src1.getByteDataArrays();
0281:                int s1ss = src1.getScanlineStride(); // scanline stride
0282:                int s1ps = src1.getPixelStride(); // pixel stride
0283:                int[] s1bo = src1.getBandOffsets(); // band offsets
0284:
0285:                /* Second source color channels. */
0286:                byte[][] s2 = src2.getByteDataArrays();
0287:                int s2ss = src2.getScanlineStride(); // scanline stride
0288:                int s2ps = src2.getPixelStride(); // pixel stride
0289:                int[] s2bo = src2.getBandOffsets(); // band offsets
0290:
0291:                /* First source alpha channel. */
0292:                byte[] a1 = afa1.getByteDataArray(0); // use band 0
0293:                int a1ss = afa1.getScanlineStride(); // scanline stride
0294:                int a1ps = afa1.getPixelStride(); // pixel stride
0295:                int a1bo = afa1.getBandOffset(0); // band 0 offsets
0296:
0297:                /* Second source alpha channel (if any). */
0298:                byte[] a2 = null;
0299:                int a2ss = 0;
0300:                int a2ps = 0;
0301:                int a2bo = 0;
0302:                if (afa2 != null) {
0303:                    a2 = afa2.getByteDataArray(0); // use band 0
0304:                    a2ss = afa2.getScanlineStride(); // scanline stride
0305:                    a2ps = afa2.getPixelStride(); // pixel stride
0306:                    a2bo = afa2.getBandOffset(0); // band 0 offset
0307:                }
0308:
0309:                /* Destination color and alpha channels. */
0310:                byte[][] d = dst.getByteDataArrays();
0311:                int dss = dst.getScanlineStride(); // scanline stride
0312:                int dps = dst.getPixelStride(); // pixel stride
0313:                int[] dbo = dst.getBandOffsets(); // band offsets
0314:
0315:                int s1so = 0, s2so = 0, a1so = 0, a2so = 0, dso = 0;
0316:                int s1po, s2po, a1po, a2po, dpo; // po = pixel offset
0317:                if (alphaPremultiplied) {
0318:                    if (afa2 == null) {
0319:                        for (int h = 0; h < dheight; h++) {
0320:                            s1po = s1so;
0321:                            s2po = s2so;
0322:                            a1po = a1so;
0323:                            dpo = dso;
0324:
0325:                            for (int w = 0; w < dwidth; w++) {
0326:                                float t = 1.0F - (a1[a1po + a1bo] & 0xFF)
0327:                                        * invMaxValue;
0328:
0329:                                /* Destination alpha channel. */
0330:                                d[aOffset][dpo + dbo[aOffset]] = maxValueByte;
0331:
0332:                                /* Destination color channels. */
0333:                                for (int b = 0; b < numBands; b++) {
0334:                                    int i = b + cOffset;
0335:                                    d[i][dpo + dbo[i]] = (byte) ((s1[b][s1po
0336:                                            + s1bo[b]] & 0xFF) + (s2[b][s2po
0337:                                            + s2bo[b]] & 0xFF)
0338:                                            * t);
0339:                                }
0340:
0341:                                s1po += s1ps;
0342:                                s2po += s2ps;
0343:                                a1po += a1ps;
0344:                                dpo += dps;
0345:                            }
0346:
0347:                            s1so += s1ss;
0348:                            s2so += s2ss;
0349:                            a1so += a1ss;
0350:                            dso += dss;
0351:                        }
0352:                    } else {
0353:                        for (int h = 0; h < dheight; h++) {
0354:                            s1po = s1so;
0355:                            s2po = s2so;
0356:                            a1po = a1so;
0357:                            a2po = a2so;
0358:                            dpo = dso;
0359:
0360:                            for (int w = 0; w < dwidth; w++) {
0361:                                int t1 = a1[a1po + a1bo] & 0xFF; // a1
0362:                                float t2 = 1.0F - t1 * invMaxValue; // 1-a1/maxValue
0363:
0364:                                /* Destination alpha channel. */
0365:                                d[aOffset][dpo + dbo[aOffset]] = (byte) (t1 + (a2[a2po
0366:                                        + a2bo] & 0xFF)
0367:                                        * t2);
0368:
0369:                                /* Destination color channels. */
0370:                                for (int b = 0; b < numBands; b++) {
0371:                                    int i = b + cOffset;
0372:                                    d[i][dpo + dbo[i]] = (byte) ((s1[b][s1po
0373:                                            + s1bo[b]] & 0xFF) + (s2[b][s2po
0374:                                            + s2bo[b]] & 0xFF)
0375:                                            * t2);
0376:                                }
0377:
0378:                                s1po += s1ps;
0379:                                s2po += s2ps;
0380:                                a1po += a1ps;
0381:                                a2po += a2ps;
0382:                                dpo += dps;
0383:                            }
0384:
0385:                            s1so += s1ss;
0386:                            s2so += s2ss;
0387:                            a1so += a1ss;
0388:                            a2so += a2ss;
0389:                            dso += dss;
0390:                        }
0391:                    }
0392:                } else {
0393:                    if (afa2 == null) {
0394:                        for (int h = 0; h < dheight; h++) {
0395:                            s1po = s1so;
0396:                            s2po = s2so;
0397:                            a1po = a1so;
0398:                            dpo = dso;
0399:
0400:                            for (int w = 0; w < dwidth; w++) {
0401:                                float t1 = (a1[a1po + a1bo] & 0xFF)
0402:                                        * invMaxValue;
0403:                                float t2 = 1.0F - t1; // 1-a1/maxValue
0404:
0405:                                /* Destination alpha channel. */
0406:                                d[aOffset][dpo + dbo[aOffset]] = maxValueByte;
0407:
0408:                                /* Destination color channels. */
0409:                                for (int b = 0; b < numBands; b++) {
0410:                                    int i = b + cOffset;
0411:                                    d[i][dpo + dbo[i]] = (byte) ((s1[b][s1po
0412:                                            + s1bo[b]] & 0xFF)
0413:                                            * t1 + (s2[b][s2po + s2bo[b]] & 0xFF)
0414:                                            * t2);
0415:                                }
0416:
0417:                                s1po += s1ps;
0418:                                s2po += s2ps;
0419:                                a1po += a1ps;
0420:                                dpo += dps;
0421:                            }
0422:
0423:                            s1so += s1ss;
0424:                            s2so += s2ss;
0425:                            a1so += a1ss;
0426:                            dso += dss;
0427:                        }
0428:                    } else {
0429:                        for (int h = 0; h < dheight; h++) {
0430:                            s1po = s1so;
0431:                            s2po = s2so;
0432:                            a1po = a1so;
0433:                            a2po = a2so;
0434:                            dpo = dso;
0435:
0436:                            for (int w = 0; w < dwidth; w++) {
0437:                                int t1 = a1[a1po + a1bo] & 0xFF; // a1
0438:                                float t2 = (1.0F - t1 * invMaxValue)
0439:                                        * (a2[a2po + a2bo] & 0xFF); // a2*(1-a1/maxValue)
0440:                                float t3 = t1 + t2; // d[alpha]
0441:                                float t4, t5;
0442:                                if (t3 == 0.0F) {
0443:                                    t4 = 0.0F;
0444:                                    t5 = 0.0F;
0445:                                } else {
0446:                                    t4 = t1 / t3;
0447:                                    t5 = t2 / t3;
0448:                                }
0449:
0450:                                /* Destination alpha channel. */
0451:                                d[aOffset][dpo + dbo[aOffset]] = (byte) t3;
0452:
0453:                                /* Destination color channels. */
0454:                                for (int b = 0; b < numBands; b++) {
0455:                                    int i = b + cOffset;
0456:                                    d[i][dpo + dbo[i]] = (byte) ((s1[b][s1po
0457:                                            + s1bo[b]] & 0xFF)
0458:                                            * t4 + (s2[b][s2po + s2bo[b]] & 0xFF)
0459:                                            * t5);
0460:                                }
0461:
0462:                                s1po += s1ps;
0463:                                s2po += s2ps;
0464:                                a1po += a1ps;
0465:                                a2po += a2ps;
0466:                                dpo += dps;
0467:                            }
0468:
0469:                            s1so += s1ss;
0470:                            s2so += s2ss;
0471:                            a1so += a1ss;
0472:                            a2so += a2ss;
0473:                            dso += dss;
0474:                        }
0475:                    }
0476:                }
0477:            }
0478:
0479:            private void ushortLoop(RasterAccessor src1, RasterAccessor src2,
0480:                    RasterAccessor afa1, RasterAccessor afa2, RasterAccessor dst) {
0481:                int dwidth = dst.getWidth();
0482:                int dheight = dst.getHeight();
0483:                int numBands = src1.getNumBands();
0484:
0485:                /* First source color channels. */
0486:                short[][] s1 = src1.getShortDataArrays();
0487:                int s1ss = src1.getScanlineStride(); // scanline stride
0488:                int s1ps = src1.getPixelStride(); // pixel stride
0489:                int[] s1bo = src1.getBandOffsets(); // band offsets
0490:
0491:                /* Second source color channels. */
0492:                short[][] s2 = src2.getShortDataArrays();
0493:                int s2ss = src2.getScanlineStride(); // scanline stride
0494:                int s2ps = src2.getPixelStride(); // pixel stride
0495:                int[] s2bo = src2.getBandOffsets(); // band offsets
0496:
0497:                /* First source alpha channel. */
0498:                short[] a1 = afa1.getShortDataArray(0); // use band 0
0499:                int a1ss = afa1.getScanlineStride(); // scanline stride
0500:                int a1ps = afa1.getPixelStride(); // pixel stride
0501:                int a1bo = afa1.getBandOffset(0); // band 0 offsets
0502:
0503:                /* Second source alpha channel (if any). */
0504:                short[] a2 = null;
0505:                int a2ss = 0;
0506:                int a2ps = 0;
0507:                int a2bo = 0;
0508:                if (afa2 != null) {
0509:                    a2 = afa2.getShortDataArray(0); // use band 0
0510:                    a2ss = afa2.getScanlineStride(); // scanline stride
0511:                    a2ps = afa2.getPixelStride(); // pixel stride
0512:                    a2bo = afa2.getBandOffset(0); // band 0 offset
0513:                }
0514:
0515:                /* Destination color and alpha channels. */
0516:                short[][] d = dst.getShortDataArrays();
0517:                int dss = dst.getScanlineStride(); // scanline stride
0518:                int dps = dst.getPixelStride(); // pixel stride
0519:                int[] dbo = dst.getBandOffsets(); // band offsets
0520:
0521:                int s1so = 0, s2so = 0, a1so = 0, a2so = 0, dso = 0;
0522:                int s1po, s2po, a1po, a2po, dpo; // po = pixel offset
0523:                if (alphaPremultiplied) {
0524:                    if (afa2 == null) {
0525:                        for (int h = 0; h < dheight; h++) {
0526:                            s1po = s1so;
0527:                            s2po = s2so;
0528:                            a1po = a1so;
0529:                            dpo = dso;
0530:
0531:                            for (int w = 0; w < dwidth; w++) {
0532:                                float t = 1.0F - (a1[a1po + a1bo] & 0xFFFF)
0533:                                        * invMaxValue;
0534:
0535:                                /* Destination alpha channel. */
0536:                                d[aOffset][dpo + dbo[aOffset]] = maxValueShort;
0537:
0538:                                /* Destination color channels. */
0539:                                for (int b = 0; b < numBands; b++) {
0540:                                    int i = b + cOffset;
0541:                                    d[i][dpo + dbo[i]] = (short) ((s1[b][s1po
0542:                                            + s1bo[b]] & 0xFFFF) + (s2[b][s2po
0543:                                            + s2bo[b]] & 0xFFFF)
0544:                                            * t);
0545:                                }
0546:
0547:                                s1po += s1ps;
0548:                                s2po += s2ps;
0549:                                a1po += a1ps;
0550:                                dpo += dps;
0551:                            }
0552:
0553:                            s1so += s1ss;
0554:                            s2so += s2ss;
0555:                            a1so += a1ss;
0556:                            dso += dss;
0557:                        }
0558:                    } else {
0559:                        for (int h = 0; h < dheight; h++) {
0560:                            s1po = s1so;
0561:                            s2po = s2so;
0562:                            a1po = a1so;
0563:                            a2po = a2so;
0564:                            dpo = dso;
0565:
0566:                            for (int w = 0; w < dwidth; w++) {
0567:                                int t1 = a1[a1po + a1bo] & 0xFFFF; // a1
0568:                                float t2 = 1.0F - t1 * invMaxValue; // 1-a1/maxValue
0569:
0570:                                /* Destination alpha channel. */
0571:                                d[aOffset][dpo + dbo[aOffset]] = (short) (t1 + (a2[a2po
0572:                                        + a2bo] & 0xFFFF)
0573:                                        * t2);
0574:
0575:                                /* Destination color channels. */
0576:                                for (int b = 0; b < numBands; b++) {
0577:                                    int i = b + cOffset;
0578:                                    d[i][dpo + dbo[i]] = (short) ((s1[b][s1po
0579:                                            + s1bo[b]] & 0xFFFF) + (s2[b][s2po
0580:                                            + s2bo[b]] & 0xFFFF)
0581:                                            * t2);
0582:                                }
0583:
0584:                                s1po += s1ps;
0585:                                s2po += s2ps;
0586:                                a1po += a1ps;
0587:                                a2po += a2ps;
0588:                                dpo += dps;
0589:                            }
0590:
0591:                            s1so += s1ss;
0592:                            s2so += s2ss;
0593:                            a1so += a1ss;
0594:                            a2so += a2ss;
0595:                            dso += dss;
0596:                        }
0597:                    }
0598:                } else {
0599:                    if (afa2 == null) {
0600:                        for (int h = 0; h < dheight; h++) {
0601:                            s1po = s1so;
0602:                            s2po = s2so;
0603:                            a1po = a1so;
0604:                            dpo = dso;
0605:
0606:                            for (int w = 0; w < dwidth; w++) {
0607:                                float t1 = (a1[a1po + a1bo] & 0xFFFF)
0608:                                        * invMaxValue;
0609:                                float t2 = 1.0F - t1; // 1-a1/maxValue
0610:
0611:                                /* Destination alpha channel. */
0612:                                d[aOffset][dpo + dbo[aOffset]] = maxValueShort;
0613:
0614:                                /* Destination color channels. */
0615:                                for (int b = 0; b < numBands; b++) {
0616:                                    int i = b + cOffset;
0617:                                    d[i][dpo + dbo[i]] = (short) ((s1[b][s1po
0618:                                            + s1bo[b]] & 0xFFFF)
0619:                                            * t1 + (s2[b][s2po + s2bo[b]] & 0xFFFF)
0620:                                            * t2);
0621:                                }
0622:
0623:                                s1po += s1ps;
0624:                                s2po += s2ps;
0625:                                a1po += a1ps;
0626:                                dpo += dps;
0627:                            }
0628:
0629:                            s1so += s1ss;
0630:                            s2so += s2ss;
0631:                            a1so += a1ss;
0632:                            dso += dss;
0633:                        }
0634:                    } else {
0635:                        for (int h = 0; h < dheight; h++) {
0636:                            s1po = s1so;
0637:                            s2po = s2so;
0638:                            a1po = a1so;
0639:                            a2po = a2so;
0640:                            dpo = dso;
0641:
0642:                            for (int w = 0; w < dwidth; w++) {
0643:                                int t1 = a1[a1po + a1bo] & 0xFFFF; // a1
0644:                                float t2 = (1.0F - t1 * invMaxValue)
0645:                                        * (a2[a2po + a2bo] & 0xFFFF); // a2*(1-a1/maxValue)
0646:                                float t3 = t1 + t2; // d[alpha]
0647:                                float t4, t5;
0648:                                if (t3 == 0.0F) {
0649:                                    t4 = 0.0F;
0650:                                    t5 = 0.0F;
0651:                                } else {
0652:                                    t4 = t1 / t3;
0653:                                    t5 = t2 / t3;
0654:                                }
0655:
0656:                                /* Destination alpha channel. */
0657:                                d[aOffset][dpo + dbo[aOffset]] = (short) t3;
0658:
0659:                                /* Destination color channels. */
0660:                                for (int b = 0; b < numBands; b++) {
0661:                                    int i = b + cOffset;
0662:                                    d[i][dpo + dbo[i]] = (short) ((s1[b][s1po
0663:                                            + s1bo[b]] & 0xFFFF)
0664:                                            * t4 + (s2[b][s2po + s2bo[b]] & 0xFFFF)
0665:                                            * t5);
0666:                                }
0667:
0668:                                s1po += s1ps;
0669:                                s2po += s2ps;
0670:                                a1po += a1ps;
0671:                                a2po += a2ps;
0672:                                dpo += dps;
0673:                            }
0674:
0675:                            s1so += s1ss;
0676:                            s2so += s2ss;
0677:                            a1so += a1ss;
0678:                            a2so += a2ss;
0679:                            dso += dss;
0680:                        }
0681:                    }
0682:                }
0683:            }
0684:
0685:            private void shortLoop(RasterAccessor src1, RasterAccessor src2,
0686:                    RasterAccessor afa1, RasterAccessor afa2, RasterAccessor dst) {
0687:                int dwidth = dst.getWidth();
0688:                int dheight = dst.getHeight();
0689:                int numBands = src1.getNumBands();
0690:
0691:                /* First source color channels. */
0692:                short[][] s1 = src1.getShortDataArrays();
0693:                int s1ss = src1.getScanlineStride(); // scanline stride
0694:                int s1ps = src1.getPixelStride(); // pixel stride
0695:                int[] s1bo = src1.getBandOffsets(); // band offsets
0696:
0697:                /* Second source color channels. */
0698:                short[][] s2 = src2.getShortDataArrays();
0699:                int s2ss = src2.getScanlineStride(); // scanline stride
0700:                int s2ps = src2.getPixelStride(); // pixel stride
0701:                int[] s2bo = src2.getBandOffsets(); // band offsets
0702:
0703:                /* First source alpha channel. */
0704:                short[] a1 = afa1.getShortDataArray(0); // use band 0
0705:                int a1ss = afa1.getScanlineStride(); // scanline stride
0706:                int a1ps = afa1.getPixelStride(); // pixel stride
0707:                int a1bo = afa1.getBandOffset(0); // band 0 offsets
0708:
0709:                /* Second source alpha channel (if any). */
0710:                short[] a2 = null;
0711:                int a2ss = 0;
0712:                int a2ps = 0;
0713:                int a2bo = 0;
0714:                if (afa2 != null) {
0715:                    a2 = afa2.getShortDataArray(0); // use band 0
0716:                    a2ss = afa2.getScanlineStride(); // scanline stride
0717:                    a2ps = afa2.getPixelStride(); // pixel stride
0718:                    a2bo = afa2.getBandOffset(0); // band 0 offset
0719:                }
0720:
0721:                /* Destination color and alpha channels. */
0722:                short[][] d = dst.getShortDataArrays();
0723:                int dss = dst.getScanlineStride(); // scanline stride
0724:                int dps = dst.getPixelStride(); // pixel stride
0725:                int[] dbo = dst.getBandOffsets(); // band offsets
0726:
0727:                int s1so = 0, s2so = 0, a1so = 0, a2so = 0, dso = 0;
0728:                int s1po, s2po, a1po, a2po, dpo; // po = pixel offset
0729:                if (alphaPremultiplied) {
0730:                    if (afa2 == null) {
0731:                        for (int h = 0; h < dheight; h++) {
0732:                            s1po = s1so;
0733:                            s2po = s2so;
0734:                            a1po = a1so;
0735:                            dpo = dso;
0736:
0737:                            for (int w = 0; w < dwidth; w++) {
0738:                                float t = 1.0F - a1[a1po + a1bo] * invMaxValue;
0739:
0740:                                /* Destination alpha channel. */
0741:                                d[aOffset][dpo + dbo[aOffset]] = maxValueShort;
0742:
0743:                                /* Destination color channels. */
0744:                                for (int b = 0; b < numBands; b++) {
0745:                                    int i = b + cOffset;
0746:                                    d[i][dpo + dbo[i]] = (short) (s1[b][s1po
0747:                                            + s1bo[b]] + s2[b][s2po + s2bo[b]]
0748:                                            * t);
0749:                                }
0750:
0751:                                s1po += s1ps;
0752:                                s2po += s2ps;
0753:                                a1po += a1ps;
0754:                                dpo += dps;
0755:                            }
0756:
0757:                            s1so += s1ss;
0758:                            s2so += s2ss;
0759:                            a1so += a1ss;
0760:                            dso += dss;
0761:                        }
0762:                    } else {
0763:                        for (int h = 0; h < dheight; h++) {
0764:                            s1po = s1so;
0765:                            s2po = s2so;
0766:                            a1po = a1so;
0767:                            a2po = a2so;
0768:                            dpo = dso;
0769:
0770:                            for (int w = 0; w < dwidth; w++) {
0771:                                int t1 = a1[a1po + a1bo]; // a1
0772:                                float t2 = 1.0F - t1 * invMaxValue; // 1-a1/maxValue
0773:
0774:                                /* Destination alpha channel. */
0775:                                d[aOffset][dpo + dbo[aOffset]] = (short) (t1 + a2[a2po
0776:                                        + a2bo]
0777:                                        * t2);
0778:
0779:                                /* Destination color channels. */
0780:                                for (int b = 0; b < numBands; b++) {
0781:                                    int i = b + cOffset;
0782:                                    d[i][dpo + dbo[i]] = (short) (s1[b][s1po
0783:                                            + s1bo[b]] + s2[b][s2po + s2bo[b]]
0784:                                            * t2);
0785:                                }
0786:
0787:                                s1po += s1ps;
0788:                                s2po += s2ps;
0789:                                a1po += a1ps;
0790:                                a2po += a2ps;
0791:                                dpo += dps;
0792:                            }
0793:
0794:                            s1so += s1ss;
0795:                            s2so += s2ss;
0796:                            a1so += a1ss;
0797:                            a2so += a2ss;
0798:                            dso += dss;
0799:                        }
0800:                    }
0801:                } else {
0802:                    if (afa2 == null) {
0803:                        for (int h = 0; h < dheight; h++) {
0804:                            s1po = s1so;
0805:                            s2po = s2so;
0806:                            a1po = a1so;
0807:                            dpo = dso;
0808:
0809:                            for (int w = 0; w < dwidth; w++) {
0810:                                float t1 = a1[a1po + a1bo] * invMaxValue;
0811:                                float t2 = 1.0F - t1; // 1-a1/maxValue
0812:
0813:                                /* Destination alpha channel. */
0814:                                d[aOffset][dpo + dbo[aOffset]] = maxValueShort;
0815:
0816:                                /* Destination color channels. */
0817:                                for (int b = 0; b < numBands; b++) {
0818:                                    int i = b + cOffset;
0819:                                    d[i][dpo + dbo[i]] = (short) (s1[b][s1po
0820:                                            + s1bo[b]]
0821:                                            * t1 + s2[b][s2po + s2bo[b]] * t2);
0822:                                }
0823:
0824:                                s1po += s1ps;
0825:                                s2po += s2ps;
0826:                                a1po += a1ps;
0827:                                dpo += dps;
0828:                            }
0829:
0830:                            s1so += s1ss;
0831:                            s2so += s2ss;
0832:                            a1so += a1ss;
0833:                            dso += dss;
0834:                        }
0835:                    } else {
0836:                        for (int h = 0; h < dheight; h++) {
0837:                            s1po = s1so;
0838:                            s2po = s2so;
0839:                            a1po = a1so;
0840:                            a2po = a2so;
0841:                            dpo = dso;
0842:
0843:                            for (int w = 0; w < dwidth; w++) {
0844:                                int t1 = a1[a1po + a1bo]; // a1
0845:                                float t2 = (1.0F - t1 * invMaxValue)
0846:                                        * a2[a2po + a2bo]; // a2*(1-a1/maxValue)
0847:                                float t3 = t1 + t2; // d[alpha]
0848:                                float t4, t5;
0849:                                if (t3 == 0.0F) {
0850:                                    t4 = 0.0F;
0851:                                    t5 = 0.0F;
0852:                                } else {
0853:                                    t4 = t1 / t3;
0854:                                    t5 = t2 / t3;
0855:                                }
0856:
0857:                                /* Destination alpha channel. */
0858:                                d[aOffset][dpo + dbo[aOffset]] = (short) t3;
0859:
0860:                                /* Destination color channels. */
0861:                                for (int b = 0; b < numBands; b++) {
0862:                                    int i = b + cOffset;
0863:                                    d[i][dpo + dbo[i]] = (short) (s1[b][s1po
0864:                                            + s1bo[b]]
0865:                                            * t4 + s2[b][s2po + s2bo[b]] * t5);
0866:                                }
0867:
0868:                                s1po += s1ps;
0869:                                s2po += s2ps;
0870:                                a1po += a1ps;
0871:                                a2po += a2ps;
0872:                                dpo += dps;
0873:                            }
0874:
0875:                            s1so += s1ss;
0876:                            s2so += s2ss;
0877:                            a1so += a1ss;
0878:                            a2so += a2ss;
0879:                            dso += dss;
0880:                        }
0881:                    }
0882:                }
0883:            }
0884:
0885:            private void intLoop(RasterAccessor src1, RasterAccessor src2,
0886:                    RasterAccessor afa1, RasterAccessor afa2, RasterAccessor dst) {
0887:                int dwidth = dst.getWidth();
0888:                int dheight = dst.getHeight();
0889:                int numBands = src1.getNumBands();
0890:
0891:                /* First source color channels. */
0892:                int[][] s1 = src1.getIntDataArrays();
0893:                int s1ss = src1.getScanlineStride(); // scanline stride
0894:                int s1ps = src1.getPixelStride(); // pixel stride
0895:                int[] s1bo = src1.getBandOffsets(); // band offsets
0896:
0897:                /* Second source color channels. */
0898:                int[][] s2 = src2.getIntDataArrays();
0899:                int s2ss = src2.getScanlineStride(); // scanline stride
0900:                int s2ps = src2.getPixelStride(); // pixel stride
0901:                int[] s2bo = src2.getBandOffsets(); // band offsets
0902:
0903:                /* First source alpha channel. */
0904:                int[] a1 = afa1.getIntDataArray(0); // use band 0
0905:                int a1ss = afa1.getScanlineStride(); // scanline stride
0906:                int a1ps = afa1.getPixelStride(); // pixel stride
0907:                int a1bo = afa1.getBandOffset(0); // band 0 offsets
0908:
0909:                /* Second source alpha channel (if any). */
0910:                int[] a2 = null;
0911:                int a2ss = 0;
0912:                int a2ps = 0;
0913:                int a2bo = 0;
0914:                if (afa2 != null) {
0915:                    a2 = afa2.getIntDataArray(0); // use band 0
0916:                    a2ss = afa2.getScanlineStride(); // scanline stride
0917:                    a2ps = afa2.getPixelStride(); // pixel stride
0918:                    a2bo = afa2.getBandOffset(0); // band 0 offset
0919:                }
0920:
0921:                /* Destination color and alpha channels. */
0922:                int[][] d = dst.getIntDataArrays();
0923:                int dss = dst.getScanlineStride(); // scanline stride
0924:                int dps = dst.getPixelStride(); // pixel stride
0925:                int[] dbo = dst.getBandOffsets(); // band offsets
0926:
0927:                int s1so = 0, s2so = 0, a1so = 0, a2so = 0, dso = 0;
0928:                int s1po, s2po, a1po, a2po, dpo; // po = pixel offset
0929:                if (alphaPremultiplied) {
0930:                    if (afa2 == null) {
0931:                        for (int h = 0; h < dheight; h++) {
0932:                            s1po = s1so;
0933:                            s2po = s2so;
0934:                            a1po = a1so;
0935:                            dpo = dso;
0936:
0937:                            for (int w = 0; w < dwidth; w++) {
0938:                                float t = 1.0F - a1[a1po + a1bo] * invMaxValue;
0939:
0940:                                /* Destination alpha channel. */
0941:                                d[aOffset][dpo + dbo[aOffset]] = maxValue;
0942:
0943:                                /* Destination color channels. */
0944:                                for (int b = 0; b < numBands; b++) {
0945:                                    int i = b + cOffset;
0946:                                    d[i][dpo + dbo[i]] = (int) (s1[b][s1po
0947:                                            + s1bo[b]] + s2[b][s2po + s2bo[b]]
0948:                                            * t);
0949:                                }
0950:
0951:                                s1po += s1ps;
0952:                                s2po += s2ps;
0953:                                a1po += a1ps;
0954:                                dpo += dps;
0955:                            }
0956:
0957:                            s1so += s1ss;
0958:                            s2so += s2ss;
0959:                            a1so += a1ss;
0960:                            dso += dss;
0961:                        }
0962:                    } else {
0963:                        for (int h = 0; h < dheight; h++) {
0964:                            s1po = s1so;
0965:                            s2po = s2so;
0966:                            a1po = a1so;
0967:                            a2po = a2so;
0968:                            dpo = dso;
0969:
0970:                            for (int w = 0; w < dwidth; w++) {
0971:                                int t1 = a1[a1po + a1bo]; // a1
0972:                                float t2 = 1.0F - t1 * invMaxValue; // 1-a1/maxValue
0973:
0974:                                /* Destination alpha channel. */
0975:                                d[aOffset][dpo + dbo[aOffset]] = (int) (t1 + a2[a2po
0976:                                        + a2bo]
0977:                                        * t2);
0978:
0979:                                /* Destination color channels. */
0980:                                for (int b = 0; b < numBands; b++) {
0981:                                    int i = b + cOffset;
0982:                                    d[i][dpo + dbo[i]] = (int) (s1[b][s1po
0983:                                            + s1bo[b]] + s2[b][s2po + s2bo[b]]
0984:                                            * t2);
0985:                                }
0986:
0987:                                s1po += s1ps;
0988:                                s2po += s2ps;
0989:                                a1po += a1ps;
0990:                                a2po += a2ps;
0991:                                dpo += dps;
0992:                            }
0993:
0994:                            s1so += s1ss;
0995:                            s2so += s2ss;
0996:                            a1so += a1ss;
0997:                            a2so += a2ss;
0998:                            dso += dss;
0999:                        }
1000:                    }
1001:                } else {
1002:                    if (afa2 == null) {
1003:                        for (int h = 0; h < dheight; h++) {
1004:                            s1po = s1so;
1005:                            s2po = s2so;
1006:                            a1po = a1so;
1007:                            dpo = dso;
1008:
1009:                            for (int w = 0; w < dwidth; w++) {
1010:                                float t1 = a1[a1po + a1bo] * invMaxValue; // a1/maxValue
1011:                                float t2 = 1.0F - t1; // 1-a1/maxValue
1012:
1013:                                /* Destination alpha channel. */
1014:                                d[aOffset][dpo + dbo[aOffset]] = maxValue;
1015:
1016:                                /* Destination color channels. */
1017:                                for (int b = 0; b < numBands; b++) {
1018:                                    int i = b + cOffset;
1019:                                    d[i][dpo + dbo[i]] = (int) (s1[b][s1po
1020:                                            + s1bo[b]]
1021:                                            * t1 + s2[b][s2po + s2bo[b]] * t2);
1022:                                }
1023:
1024:                                s1po += s1ps;
1025:                                s2po += s2ps;
1026:                                a1po += a1ps;
1027:                                dpo += dps;
1028:                            }
1029:
1030:                            s1so += s1ss;
1031:                            s2so += s2ss;
1032:                            a1so += a1ss;
1033:                            dso += dss;
1034:                        }
1035:                    } else {
1036:                        for (int h = 0; h < dheight; h++) {
1037:                            s1po = s1so;
1038:                            s2po = s2so;
1039:                            a1po = a1so;
1040:                            a2po = a2so;
1041:                            dpo = dso;
1042:
1043:                            for (int w = 0; w < dwidth; w++) {
1044:                                int t1 = a1[a1po + a1bo]; // a1
1045:                                float t2 = (1.0F - t1 * invMaxValue)
1046:                                        * a2[a2po + a2bo];
1047:                                // a2*(1-a1/maxValue)
1048:                                float t3 = t1 + t2; // d[alpha]
1049:                                float t4, t5;
1050:                                if (t3 == 0.0F) {
1051:                                    t4 = 0.0F;
1052:                                    t5 = 0.0F;
1053:                                } else {
1054:                                    t4 = t1 / t3;
1055:                                    t5 = t2 / t3;
1056:                                }
1057:
1058:                                /* Destination alpha channel. */
1059:                                d[aOffset][dpo + dbo[aOffset]] = (int) t3;
1060:
1061:                                /* Destination color channels. */
1062:                                for (int b = 0; b < numBands; b++) {
1063:                                    int i = b + cOffset;
1064:                                    d[i][dpo + dbo[i]] = (int) (s1[b][s1po
1065:                                            + s1bo[b]]
1066:                                            * t4 + s2[b][s2po + s2bo[b]] * t5);
1067:                                }
1068:
1069:                                s1po += s1ps;
1070:                                s2po += s2ps;
1071:                                a1po += a1ps;
1072:                                a2po += a2ps;
1073:                                dpo += dps;
1074:                            }
1075:
1076:                            s1so += s1ss;
1077:                            s2so += s2ss;
1078:                            a1so += a1ss;
1079:                            a2so += a2ss;
1080:                            dso += dss;
1081:                        }
1082:                    }
1083:                }
1084:            }
1085:
1086:            private void floatLoop(RasterAccessor src1, RasterAccessor src2,
1087:                    RasterAccessor afa1, RasterAccessor afa2, RasterAccessor dst) {
1088:                int dwidth = dst.getWidth();
1089:                int dheight = dst.getHeight();
1090:                int numBands = src1.getNumBands();
1091:
1092:                /* First source color channels. */
1093:                float[][] s1 = src1.getFloatDataArrays();
1094:                int s1ss = src1.getScanlineStride(); // scanline stride
1095:                int s1ps = src1.getPixelStride(); // pixel stride
1096:                int[] s1bo = src1.getBandOffsets(); // band offsets
1097:
1098:                /* Second source color channels. */
1099:                float[][] s2 = src2.getFloatDataArrays();
1100:                int s2ss = src2.getScanlineStride(); // scanline stride
1101:                int s2ps = src2.getPixelStride(); // pixel stride
1102:                int[] s2bo = src2.getBandOffsets(); // band offsets
1103:
1104:                /* First source alpha channel. */
1105:                float[] a1 = afa1.getFloatDataArray(0); // use band 0
1106:                int a1ss = afa1.getScanlineStride(); // scanline stride
1107:                int a1ps = afa1.getPixelStride(); // pixel stride
1108:                int a1bo = afa1.getBandOffset(0); // band 0 offsets
1109:
1110:                /* Second source alpha channel (if any). */
1111:                float[] a2 = null;
1112:                int a2ss = 0;
1113:                int a2ps = 0;
1114:                int a2bo = 0;
1115:                if (afa2 != null) {
1116:                    a2 = afa2.getFloatDataArray(0); // use band 0
1117:                    a2ss = afa2.getScanlineStride(); // scanline stride
1118:                    a2ps = afa2.getPixelStride(); // pixel stride
1119:                    a2bo = afa2.getBandOffset(0); // band 0 offset
1120:                }
1121:
1122:                /* Destination color and alpha channels. */
1123:                float[][] d = dst.getFloatDataArrays();
1124:                int dss = dst.getScanlineStride(); // scanline stride
1125:                int dps = dst.getPixelStride(); // pixel stride
1126:                int[] dbo = dst.getBandOffsets(); // band offsets
1127:
1128:                int s1so = 0, s2so = 0, a1so = 0, a2so = 0, dso = 0;
1129:                int s1po, s2po, a1po, a2po, dpo; // po = pixel offset
1130:                float invMaxValue = 1.0F / Float.MAX_VALUE;
1131:                if (alphaPremultiplied) {
1132:                    if (afa2 == null) {
1133:                        for (int h = 0; h < dheight; h++) {
1134:                            s1po = s1so;
1135:                            s2po = s2so;
1136:                            a1po = a1so;
1137:                            dpo = dso;
1138:
1139:                            for (int w = 0; w < dwidth; w++) {
1140:                                float t = 1.0F - a1[a1po + a1bo] * invMaxValue;
1141:
1142:                                /* Destination alpha channel. */
1143:                                d[aOffset][dpo + dbo[aOffset]] = Float.MAX_VALUE;
1144:
1145:                                /* Destination color channels. */
1146:                                for (int b = 0; b < numBands; b++) {
1147:                                    int i = b + cOffset;
1148:                                    d[i][dpo + dbo[i]] = s1[b][s1po + s1bo[b]]
1149:                                            + s2[b][s2po + s2bo[b]] * t;
1150:                                }
1151:
1152:                                s1po += s1ps;
1153:                                s2po += s2ps;
1154:                                a1po += a1ps;
1155:                                dpo += dps;
1156:                            }
1157:
1158:                            s1so += s1ss;
1159:                            s2so += s2ss;
1160:                            a1so += a1ss;
1161:                            dso += dss;
1162:                        }
1163:                    } else {
1164:                        for (int h = 0; h < dheight; h++) {
1165:                            s1po = s1so;
1166:                            s2po = s2so;
1167:                            a1po = a1so;
1168:                            a2po = a2so;
1169:                            dpo = dso;
1170:
1171:                            for (int w = 0; w < dwidth; w++) {
1172:                                float t1 = a1[a1po + a1bo]; // a1
1173:                                float t2 = 1.0F - t1 * invMaxValue; // 1-a1/maxValue
1174:
1175:                                /* Destination alpha channel. */
1176:                                d[aOffset][dpo + dbo[aOffset]] = t1
1177:                                        + a2[a2po + a2bo] * t2;
1178:
1179:                                /* Destination color channels. */
1180:                                for (int b = 0; b < numBands; b++) {
1181:                                    int i = b + cOffset;
1182:                                    d[i][dpo + dbo[i]] = s1[b][s1po + s1bo[b]]
1183:                                            + s2[b][s2po + s2bo[b]] * t2;
1184:                                }
1185:
1186:                                s1po += s1ps;
1187:                                s2po += s2ps;
1188:                                a1po += a1ps;
1189:                                a2po += a2ps;
1190:                                dpo += dps;
1191:                            }
1192:
1193:                            s1so += s1ss;
1194:                            s2so += s2ss;
1195:                            a1so += a1ss;
1196:                            a2so += a2ss;
1197:                            dso += dss;
1198:                        }
1199:                    }
1200:                } else {
1201:                    if (afa2 == null) {
1202:                        for (int h = 0; h < dheight; h++) {
1203:                            s1po = s1so;
1204:                            s2po = s2so;
1205:                            a1po = a1so;
1206:                            dpo = dso;
1207:
1208:                            for (int w = 0; w < dwidth; w++) {
1209:                                float t1 = a1[a1po + a1bo] * invMaxValue; // a1/maxValue
1210:                                float t2 = 1.0F - t1; // 1-a1/maxValue
1211:
1212:                                /* Destination alpha channel. */
1213:                                d[aOffset][dpo + dbo[aOffset]] = Float.MAX_VALUE;
1214:
1215:                                /* Destination color channels. */
1216:                                for (int b = 0; b < numBands; b++) {
1217:                                    int i = b + cOffset;
1218:                                    d[i][dpo + dbo[i]] = s1[b][s1po + s1bo[b]]
1219:                                            * t1 + s2[b][s2po + s2bo[b]] * t2;
1220:                                }
1221:
1222:                                s1po += s1ps;
1223:                                s2po += s2ps;
1224:                                a1po += a1ps;
1225:                                dpo += dps;
1226:                            }
1227:
1228:                            s1so += s1ss;
1229:                            s2so += s2ss;
1230:                            a1so += a1ss;
1231:                            dso += dss;
1232:                        }
1233:                    } else {
1234:                        for (int h = 0; h < dheight; h++) {
1235:                            s1po = s1so;
1236:                            s2po = s2so;
1237:                            a1po = a1so;
1238:                            a2po = a2so;
1239:                            dpo = dso;
1240:
1241:                            for (int w = 0; w < dwidth; w++) {
1242:                                float t1 = a1[a1po + a1bo]; // a1
1243:                                float t2 = (1.0F - t1 * invMaxValue)
1244:                                        * a2[a2po + a2bo];
1245:                                // a2*(1-a1/maxValue)
1246:                                float t3 = t1 + t2; // d[alpha]
1247:                                float t4, t5;
1248:                                if (t3 == 0.0F) {
1249:                                    t4 = 0.0F;
1250:                                    t5 = 0.0F;
1251:                                } else {
1252:                                    t4 = t1 / t3;
1253:                                    t5 = t2 / t3;
1254:                                }
1255:
1256:                                /* Destination alpha channel. */
1257:                                d[aOffset][dpo + dbo[aOffset]] = t3;
1258:
1259:                                /* Destination color channels. */
1260:                                for (int b = 0; b < numBands; b++) {
1261:                                    int i = b + cOffset;
1262:                                    d[i][dpo + dbo[i]] = s1[b][s1po + s1bo[b]]
1263:                                            * t4 + s2[b][s2po + s2bo[b]] * t5;
1264:                                }
1265:
1266:                                s1po += s1ps;
1267:                                s2po += s2ps;
1268:                                a1po += a1ps;
1269:                                a2po += a2ps;
1270:                                dpo += dps;
1271:                            }
1272:
1273:                            s1so += s1ss;
1274:                            s2so += s2ss;
1275:                            a1so += a1ss;
1276:                            a2so += a2ss;
1277:                            dso += dss;
1278:                        }
1279:                    }
1280:                }
1281:            }
1282:
1283:            private void doubleLoop(RasterAccessor src1, RasterAccessor src2,
1284:                    RasterAccessor afa1, RasterAccessor afa2, RasterAccessor dst) {
1285:                int dwidth = dst.getWidth();
1286:                int dheight = dst.getHeight();
1287:                int numBands = src1.getNumBands();
1288:
1289:                /* First source color channels. */
1290:                double[][] s1 = src1.getDoubleDataArrays();
1291:                int s1ss = src1.getScanlineStride(); // scanline stride
1292:                int s1ps = src1.getPixelStride(); // pixel stride
1293:                int[] s1bo = src1.getBandOffsets(); // band offsets
1294:
1295:                /* Second source color channels. */
1296:                double[][] s2 = src2.getDoubleDataArrays();
1297:                int s2ss = src2.getScanlineStride(); // scanline stride
1298:                int s2ps = src2.getPixelStride(); // pixel stride
1299:                int[] s2bo = src2.getBandOffsets(); // band offsets
1300:
1301:                /* First source alpha channel. */
1302:                double[] a1 = afa1.getDoubleDataArray(0); // use band 0
1303:                int a1ss = afa1.getScanlineStride(); // scanline stride
1304:                int a1ps = afa1.getPixelStride(); // pixel stride
1305:                int a1bo = afa1.getBandOffset(0); // band 0 offsets
1306:
1307:                /* Second source alpha channel (if any). */
1308:                double[] a2 = null;
1309:                int a2ss = 0;
1310:                int a2ps = 0;
1311:                int a2bo = 0;
1312:                if (afa2 != null) {
1313:                    a2 = afa2.getDoubleDataArray(0); // use band 0
1314:                    a2ss = afa2.getScanlineStride(); // scanline stride
1315:                    a2ps = afa2.getPixelStride(); // pixel stride
1316:                    a2bo = afa2.getBandOffset(0); // band 0 offset
1317:                }
1318:
1319:                /* Destination color and alpha channels. */
1320:                double[][] d = dst.getDoubleDataArrays();
1321:                int dss = dst.getScanlineStride(); // scanline stride
1322:                int dps = dst.getPixelStride(); // pixel stride
1323:                int[] dbo = dst.getBandOffsets(); // band offsets
1324:
1325:                int s1so = 0, s2so = 0, a1so = 0, a2so = 0, dso = 0;
1326:                int s1po, s2po, a1po, a2po, dpo; // po = pixel offset
1327:                double invMaxValue = 1.0D / Double.MAX_VALUE;
1328:                if (alphaPremultiplied) {
1329:                    if (afa2 == null) {
1330:                        for (int h = 0; h < dheight; h++) {
1331:                            s1po = s1so;
1332:                            s2po = s2so;
1333:                            a1po = a1so;
1334:                            dpo = dso;
1335:
1336:                            for (int w = 0; w < dwidth; w++) {
1337:                                double t = 1.0D - a1[a1po + a1bo] * invMaxValue;
1338:
1339:                                /* Destination alpha channel. */
1340:                                d[aOffset][dpo + dbo[aOffset]] = Double.MAX_VALUE;
1341:
1342:                                /* Destination color channels. */
1343:                                for (int b = 0; b < numBands; b++) {
1344:                                    int i = b + cOffset;
1345:                                    d[i][dpo + dbo[i]] = s1[b][s1po + s1bo[b]]
1346:                                            + s2[b][s2po + s2bo[b]] * t;
1347:                                }
1348:
1349:                                s1po += s1ps;
1350:                                s2po += s2ps;
1351:                                a1po += a1ps;
1352:                                dpo += dps;
1353:                            }
1354:
1355:                            s1so += s1ss;
1356:                            s2so += s2ss;
1357:                            a1so += a1ss;
1358:                            dso += dss;
1359:                        }
1360:                    } else {
1361:                        for (int h = 0; h < dheight; h++) {
1362:                            s1po = s1so;
1363:                            s2po = s2so;
1364:                            a1po = a1so;
1365:                            a2po = a2so;
1366:                            dpo = dso;
1367:
1368:                            for (int w = 0; w < dwidth; w++) {
1369:                                double t1 = a1[a1po + a1bo]; // a1
1370:                                double t2 = 1.0D - t1 * invMaxValue; // 1-a1/maxValue
1371:
1372:                                /* Destination alpha channel. */
1373:                                d[aOffset][dpo + dbo[aOffset]] = t1
1374:                                        + a2[a2po + a2bo] * t2;
1375:
1376:                                /* Destination color channels. */
1377:                                for (int b = 0; b < numBands; b++) {
1378:                                    int i = b + cOffset;
1379:                                    d[i][dpo + dbo[i]] = s1[b][s1po + s1bo[b]]
1380:                                            + s2[b][s2po + s2bo[b]] * t2;
1381:                                }
1382:
1383:                                s1po += s1ps;
1384:                                s2po += s2ps;
1385:                                a1po += a1ps;
1386:                                a2po += a2ps;
1387:                                dpo += dps;
1388:                            }
1389:
1390:                            s1so += s1ss;
1391:                            s2so += s2ss;
1392:                            a1so += a1ss;
1393:                            a2so += a2ss;
1394:                            dso += dss;
1395:                        }
1396:                    }
1397:                } else {
1398:                    if (afa2 == null) {
1399:                        for (int h = 0; h < dheight; h++) {
1400:                            s1po = s1so;
1401:                            s2po = s2so;
1402:                            a1po = a1so;
1403:                            dpo = dso;
1404:
1405:                            for (int w = 0; w < dwidth; w++) {
1406:                                double t1 = a1[a1po + a1bo] * invMaxValue; // a1/maxValue
1407:                                double t2 = 1.0D - t1; // 1-a1/maxValue
1408:
1409:                                /* Destination alpha channel. */
1410:                                d[aOffset][dpo + dbo[aOffset]] = Double.MAX_VALUE;
1411:
1412:                                /* Destination color channels. */
1413:                                for (int b = 0; b < numBands; b++) {
1414:                                    int i = b + cOffset;
1415:                                    d[i][dpo + dbo[i]] = s1[b][s1po + s1bo[b]]
1416:                                            * t1 + s2[b][s2po + s2bo[b]] * t2;
1417:                                }
1418:
1419:                                s1po += s1ps;
1420:                                s2po += s2ps;
1421:                                a1po += a1ps;
1422:                                dpo += dps;
1423:                            }
1424:
1425:                            s1so += s1ss;
1426:                            s2so += s2ss;
1427:                            a1so += a1ss;
1428:                            dso += dss;
1429:                        }
1430:                    } else {
1431:                        for (int h = 0; h < dheight; h++) {
1432:                            s1po = s1so;
1433:                            s2po = s2so;
1434:                            a1po = a1so;
1435:                            a2po = a2so;
1436:                            dpo = dso;
1437:
1438:                            for (int w = 0; w < dwidth; w++) {
1439:                                double t1 = a1[a1po + a1bo]; // a1
1440:                                double t2 = (1.0D - t1 * invMaxValue)
1441:                                        * a2[a2po + a2bo];
1442:                                // a2*(1-a1/maxValue)
1443:                                double t3 = t1 + t2; // d[alpha]
1444:                                double t4, t5;
1445:                                if (t3 == 0.0D) {
1446:                                    t4 = 0.0D;
1447:                                    t5 = 0.0D;
1448:                                } else {
1449:                                    t4 = t1 / t3;
1450:                                    t5 = t2 / t3;
1451:                                }
1452:
1453:                                /* Destination alpha channel. */
1454:                                d[aOffset][dpo + dbo[aOffset]] = t3;
1455:
1456:                                /* Destination color channels. */
1457:                                for (int b = 0; b < numBands; b++) {
1458:                                    int i = b + cOffset;
1459:                                    d[i][dpo + dbo[i]] = s1[b][s1po + s1bo[b]]
1460:                                            * t4 + s2[b][s2po + s2bo[b]] * t5;
1461:                                }
1462:
1463:                                s1po += s1ps;
1464:                                s2po += s2ps;
1465:                                a1po += a1ps;
1466:                                a2po += a2ps;
1467:                                dpo += dps;
1468:                            }
1469:
1470:                            s1so += s1ss;
1471:                            s2so += s2ss;
1472:                            a1so += a1ss;
1473:                            a2so += a2ss;
1474:                            dso += dss;
1475:                        }
1476:                    }
1477:                }
1478:            }
1479:
1480:            //     public static void main(String args[]) {
1481:            //         System.out.println("AddOpImage Test");
1482:            //         ImageLayout layoutSrc, layoutAlpha;
1483:            //         OpImage src1, src2, afa1, afa2, dst;
1484:            //         Rectangle rect = new Rectangle(0, 0, 10, 5);
1485:
1486:            //         layoutAlpha = OpImageTester.createImageLayout(
1487:            //             0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 1, false);
1488:            //         afa1 = OpImageTester.createRandomOpImage(layoutAlpha);
1489:            //         afa2 = OpImageTester.createRandomOpImage(layoutAlpha);
1490:            //         OpImageTester.printPixels("Alpha 1", afa1, rect);
1491:            //         OpImageTester.printPixels("Alpha 2", afa2, rect);
1492:
1493:            //         System.out.println("1. PixelInterleaved byte 3-band");
1494:
1495:            //         layoutSrc = OpImageTester.createImageLayout(
1496:            //             0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 3, false);
1497:            //         src1 = OpImageTester.createRandomOpImage(layoutSrc);
1498:            //         src2 = OpImageTester.createRandomOpImage(layoutSrc);
1499:
1500:            //         System.out.println("1a. Alpha premultiplied, source2 opaque");
1501:            //         dst = new CompositeOpImage(src1, src2, null, null,
1502:            //                                    afa1, null, true, true);
1503:            //         OpImageTester.testOpImage(dst, rect);
1504:            //         OpImageTester.timeOpImage(dst, 10);
1505:
1506:            //         System.out.println("1b. Alpha premultiplied, source2 not opaque");
1507:            //         dst = new CompositeOpImage(src1, src2, null, null,
1508:            //                                    afa1, afa2, true, true);
1509:            //         OpImageTester.testOpImage(dst, rect);
1510:            //         OpImageTester.timeOpImage(dst, 10);
1511:
1512:            //         System.out.println("1c. Alpha not premultiplied, source2 opaque");
1513:            //         dst = new CompositeOpImage(src1, src2, null, null,
1514:            //                                    afa1, null, false, true);
1515:            //         OpImageTester.testOpImage(dst, rect);
1516:            //         OpImageTester.timeOpImage(dst, 10);
1517:
1518:            //         System.out.println("1d. Alpha not premultiplied, source2 not opaque");
1519:            //         dst = new CompositeOpImage(src1, src2, null, null,
1520:            //                                    afa1, afa2, false, true);
1521:            //         OpImageTester.testOpImage(dst, rect);
1522:            //         OpImageTester.timeOpImage(dst, 10);
1523:
1524:            //         System.out.println("2. Banded byte 3-band");
1525:
1526:            //         layoutSrc = OpImageTester.createImageLayout(
1527:            //             0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 3, true);
1528:            //         src1 = OpImageTester.createRandomOpImage(layoutSrc);
1529:            //         src2 = OpImageTester.createRandomOpImage(layoutSrc);
1530:
1531:            //         System.out.println("2b. Alpha premultiplied, source2 not opaque");
1532:            //         dst = new CompositeOpImage(src1, src2, null, null,
1533:            //                                    afa1, afa2, true, false);
1534:            //         OpImageTester.testOpImage(dst, rect);
1535:            //         OpImageTester.timeOpImage(dst, 10);
1536:
1537:            //         System.out.println("2d. Alpha not premultiplied, source2 not opaque");
1538:            //         dst = new CompositeOpImage(src1, src2, null, null,
1539:            //                                    afa1, afa2, false, true);
1540:            //         OpImageTester.testOpImage(dst, rect);
1541:            //         OpImageTester.timeOpImage(dst, 10);
1542:
1543:            //         layoutAlpha = OpImageTester.createImageLayout(
1544:            //             0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_USHORT, 1, true);
1545:            //         afa1 = OpImageTester.createRandomOpImage(layoutAlpha);
1546:            //         afa2 = OpImageTester.createRandomOpImage(layoutAlpha);
1547:            //         OpImageTester.printPixels("Alpha 1", afa1, rect);
1548:            //         OpImageTester.printPixels("Alpha 2", afa2, rect);
1549:
1550:            //         System.out.println("3. PixelInterleaved ushort 3-band");
1551:
1552:            //         layoutSrc = OpImageTester.createImageLayout(
1553:            //             0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_USHORT, 3, false);
1554:            //         src1 = OpImageTester.createRandomOpImage(layoutSrc);
1555:            //         src2 = OpImageTester.createRandomOpImage(layoutSrc);
1556:
1557:            //         System.out.println("3a. Alpha premultiplied, source2 opaque");
1558:            //         dst = new CompositeOpImage(src1, src2, null, null,
1559:            //                                    afa1, null, true, false);
1560:            //         OpImageTester.testOpImage(dst, rect);
1561:            //         OpImageTester.timeOpImage(dst, 10);
1562:
1563:            //         System.out.println("3d. Alpha not premultiplied, source2 not opaque");
1564:            //         dst = new CompositeOpImage(src1, src2, null, null,
1565:            //                                    afa1, afa2, false, false);
1566:            //         OpImageTester.testOpImage(dst, rect);
1567:            //         OpImageTester.timeOpImage(dst, 10);
1568:            //     }
1569:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.