Source Code Cross Referenced for CompositeNoDestAlphaOpImage.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: CompositeNoDestAlphaOpImage.java,v $
0003:         *
0004:         * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * Use is subject to license terms.
0007:         *
0008:         * $Revision: 1.1 $
0009:         * $Date: 2005/02/11 04:56:18 $
0010:         * $State: Exp $
0011:         */
0012:        package com.sun.media.jai.opimage;
0013:
0014:        import java.awt.Rectangle;
0015:        import java.awt.image.DataBuffer;
0016:        import java.awt.image.Raster;
0017:        import java.awt.image.RenderedImage;
0018:        import java.awt.image.SampleModel;
0019:        import java.awt.image.WritableRaster;
0020:        import javax.media.jai.ImageLayout;
0021:        import javax.media.jai.PointOpImage;
0022:        import javax.media.jai.RasterAccessor;
0023:        import javax.media.jai.RasterFormatTag;
0024:        import javax.media.jai.RasterFactory;
0025:        import java.util.Map;
0026:
0027:        /**
0028:         * An <code>OpImage</code> implementing the "Composite" operation as
0029:         * described in <code>javax.media.jai.operator.CompositeDescriptor</code>.
0030:         * This implementation handles the case where the destination image does
0031:         * not include its result alpha channel.
0032:         *
0033:         * <p> For two source images <code>source1</code> and <code>source2</code>,
0034:         * this <code>OpImage</code> places the foreground <code>source1</code>
0035:         * in front of the background <code>source2</code>. This is what commonly
0036:         * known as the "over" composite.  The destination color values are
0037:         * calculated using the following formula:
0038:         * <pre>
0039:         * dest = source1 * alpha1 + source2 * alpha2 * (1 - alpha1)
0040:         * </pre>
0041:         * where <code>source1</code> and <code>source2</code> are the color values
0042:         * of the two source images, without their alpha multiplied to them, and
0043:         * <code>alpha1</code> and <code>alpha2</code> are the two sources's alpha
0044:         * values in fraction.
0045:         *
0046:         * @see javax.media.jai.operator.CompositeDescriptor
0047:         * @see CompositeCRIF
0048:         *
0049:         */
0050:        final class CompositeNoDestAlphaOpImage extends PointOpImage {
0051:
0052:            /** The alpha image for the first source. */
0053:            private RenderedImage alpha1;
0054:
0055:            /** The alpha image for the second source. */
0056:            private RenderedImage alpha2;
0057:
0058:            /** Indicates whether alpha has been premultiplied. */
0059:            private boolean premultiplied;
0060:
0061:            /** The RasterAccessor format tags. */
0062:            private RasterFormatTag[] tags;
0063:
0064:            /**
0065:             * Constructor.
0066:             *
0067:             * @param source1  The foreground source image.
0068:             * @param source2  The background source image.
0069:
0070:             * @param layout  The destination image layout.
0071:             * @param alpha1  The alpha image for the first source.
0072:             * @param alpha2  The alpha image for the second source. If
0073:             *        <code>null</code>, the second source is assumed to be opaque.
0074:             * @param premultiplied  Indicates whether both sources and destination
0075:             *        have their alpha premultiplied.
0076:             */
0077:            public CompositeNoDestAlphaOpImage(RenderedImage source1,
0078:                    RenderedImage source2, Map config, ImageLayout layout,
0079:                    RenderedImage alpha1, RenderedImage alpha2,
0080:                    boolean premultiplied) {
0081:                super (source1, source2, layout, config, true);
0082:
0083:                this .alpha1 = alpha1;
0084:                this .alpha2 = alpha2;
0085:                this .premultiplied = premultiplied;
0086:
0087:                tags = getFormatTags();
0088:            }
0089:
0090:            /**
0091:             * Composites two images within a specified rectangle.
0092:             *
0093:             * @param sources  Cobbled sources, guaranteed to provide all the
0094:             *        source data necessary for computing the rectangle.
0095:             * @param dest  The tile containing the rectangle to be computed.
0096:             * @param destRect  The rectangle within the tile to be computed.
0097:             */
0098:            protected void computeRect(Raster[] sources, WritableRaster dest,
0099:                    Rectangle destRect) {
0100:                /* For PointOpImage, srcRect = destRect. */
0101:                RasterAccessor s1 = new RasterAccessor(sources[0], destRect,
0102:                        tags[0], getSourceImage(0).getColorModel());
0103:
0104:                RasterAccessor s2 = new RasterAccessor(sources[1], destRect,
0105:                        tags[1], getSourceImage(1).getColorModel());
0106:
0107:                RasterAccessor a1 = new RasterAccessor(
0108:                        alpha1.getData(destRect), destRect, tags[2], alpha1
0109:                                .getColorModel());
0110:
0111:                RasterAccessor a2 = null, d;
0112:                if (alpha2 == null) {
0113:                    d = new RasterAccessor(dest, destRect, tags[3],
0114:                            getColorModel());
0115:                } else {
0116:                    a2 = new RasterAccessor(alpha2.getData(destRect), destRect,
0117:                            tags[3], alpha2.getColorModel());
0118:                    d = new RasterAccessor(dest, destRect, tags[4],
0119:                            getColorModel());
0120:                }
0121:
0122:                switch (d.getDataType()) {
0123:                case DataBuffer.TYPE_BYTE:
0124:                    byteLoop(s1, s2, a1, a2, d);
0125:                    break;
0126:                case DataBuffer.TYPE_USHORT:
0127:                    ushortLoop(s1, s2, a1, a2, d);
0128:                    break;
0129:                case DataBuffer.TYPE_SHORT:
0130:                    shortLoop(s1, s2, a1, a2, d);
0131:                    break;
0132:                case DataBuffer.TYPE_INT:
0133:                    intLoop(s1, s2, a1, a2, d);
0134:                    break;
0135:                case DataBuffer.TYPE_FLOAT:
0136:                    floatLoop(s1, s2, a1, a2, d);
0137:                    break;
0138:                case DataBuffer.TYPE_DOUBLE:
0139:                    doubleLoop(s1, s2, a1, a2, d);
0140:                    break;
0141:                }
0142:
0143:                if (d.isDataCopy()) {
0144:                    d.clampDataArrays();
0145:                    d.copyDataToRaster();
0146:                }
0147:            }
0148:
0149:            /*
0150:             * Formulas for integral data types:
0151:             *
0152:             * if (premultiplied) {
0153:             *     dest = source1 + source2 * (1 - alpha1/maxValue)
0154:             * } else {
0155:             *     if (alpha2 == null) {
0156:             *         dest = source1 * alpha1/maxValue +
0157:             *                source2 * (1 - alpha1/maxValue)
0158:             *     } else {
0159:             *         dest = (source1 * alpha1 +
0160:             *                 source2 * alpha2 * (1 - alpha1/maxValue)) /
0161:             *                (alpha1 + alpha2 * (1 - alpha1/maxValue))
0162:             *     }
0163:             * }
0164:             */
0165:
0166:            private void byteLoop(RasterAccessor s1, RasterAccessor s2,
0167:                    RasterAccessor a1, RasterAccessor a2, RasterAccessor d) {
0168:                /* First source color channels. */
0169:                int s1LineStride = s1.getScanlineStride();
0170:                int s1PixelStride = s1.getPixelStride();
0171:                int[] s1BandOffsets = s1.getBandOffsets();
0172:                byte[][] s1Data = s1.getByteDataArrays();
0173:
0174:                /* Second source color channels. */
0175:                int s2LineStride = s2.getScanlineStride();
0176:                int s2PixelStride = s2.getPixelStride();
0177:                int[] s2BandOffsets = s2.getBandOffsets();
0178:                byte[][] s2Data = s2.getByteDataArrays();
0179:
0180:                /* First source alpha channel. */
0181:                int a1LineStride = a1.getScanlineStride();
0182:                int a1PixelStride = a1.getPixelStride();
0183:                int a1BandOffset = a1.getBandOffset(0);
0184:                byte[] a1Data = a1.getByteDataArray(0);
0185:
0186:                /* Second source alpha channel (if any). */
0187:                int a2LineStride = 0;
0188:                int a2PixelStride = 0;
0189:                int a2BandOffset = 0;
0190:                byte[] a2Data = null;
0191:                if (alpha2 != null) {
0192:                    a2LineStride = a2.getScanlineStride();
0193:                    a2PixelStride = a2.getPixelStride();
0194:                    a2BandOffset = a2.getBandOffset(0);
0195:                    a2Data = a2.getByteDataArray(0);
0196:                }
0197:
0198:                /* Destination color channels. */
0199:                int dLineStride = d.getScanlineStride();
0200:                int dPixelStride = d.getPixelStride();
0201:                int[] dBandOffsets = d.getBandOffsets();
0202:                byte[][] dData = d.getByteDataArrays();
0203:
0204:                int dwidth = d.getWidth();
0205:                int dheight = d.getHeight();
0206:                int dbands = d.getNumBands();
0207:
0208:                float invMax = 1.0F / 0xFF;
0209:
0210:                int s1LineOffset = 0, s2LineOffset = 0, a1LineOffset = 0, a2LineOffset = 0, dLineOffset = 0, s1PixelOffset, s2PixelOffset, a1PixelOffset, a2PixelOffset, dPixelOffset;
0211:
0212:                if (premultiplied) {
0213:                    /* dest = source1 + source2 * (1 - alpha1/max) */
0214:
0215:                    for (int h = 0; h < dheight; h++) {
0216:                        s1PixelOffset = s1LineOffset;
0217:                        s2PixelOffset = s2LineOffset;
0218:                        a1PixelOffset = a1LineOffset + a1BandOffset;
0219:                        dPixelOffset = dLineOffset;
0220:
0221:                        s1LineOffset += s1LineStride;
0222:                        s2LineOffset += s2LineStride;
0223:                        a1LineOffset += a1LineStride;
0224:                        dLineOffset += dLineStride;
0225:
0226:                        for (int w = 0; w < dwidth; w++) {
0227:                            float t = 1.0F - (a1Data[a1PixelOffset] & 0xFF)
0228:                                    * invMax;
0229:
0230:                            /* Destination color channels. */
0231:                            for (int b = 0; b < dbands; b++) {
0232:                                dData[b][dPixelOffset + dBandOffsets[b]] = (byte) ((s1Data[b][s1PixelOffset
0233:                                        + s1BandOffsets[b]] & 0xFF) + (s2Data[b][s2PixelOffset
0234:                                        + s2BandOffsets[b]] & 0xFF)
0235:                                        * t);
0236:                            }
0237:
0238:                            s1PixelOffset += s1PixelStride;
0239:                            s2PixelOffset += s2PixelStride;
0240:                            a1PixelOffset += a1PixelStride;
0241:                            dPixelOffset += dPixelStride;
0242:                        }
0243:                    }
0244:
0245:                } else {
0246:                    if (alpha2 == null) {
0247:                        /* dest = source1 * alpha1/max + source2 * (1 - alpha1/max) */
0248:
0249:                        for (int h = 0; h < dheight; h++) {
0250:                            s1PixelOffset = s1LineOffset;
0251:                            s2PixelOffset = s2LineOffset;
0252:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0253:                            dPixelOffset = dLineOffset;
0254:
0255:                            s1LineOffset += s1LineStride;
0256:                            s2LineOffset += s2LineStride;
0257:                            a1LineOffset += a1LineStride;
0258:                            dLineOffset += dLineStride;
0259:
0260:                            for (int w = 0; w < dwidth; w++) {
0261:                                float t1 = (a1Data[a1PixelOffset] & 0xFF)
0262:                                        * invMax;
0263:                                float t2 = 1.0F - t1;
0264:
0265:                                /* Destination color channels. */
0266:                                for (int b = 0; b < dbands; b++) {
0267:                                    dData[b][dPixelOffset + dBandOffsets[b]] = (byte) ((s1Data[b][s1PixelOffset
0268:                                            + s1BandOffsets[b]] & 0xFF)
0269:                                            * t1 + (s2Data[b][s2PixelOffset
0270:                                            + s2BandOffsets[b]] & 0xFF)
0271:                                            * t2);
0272:                                }
0273:
0274:                                s1PixelOffset += s1PixelStride;
0275:                                s2PixelOffset += s2PixelStride;
0276:                                a1PixelOffset += a1PixelStride;
0277:                                dPixelOffset += dPixelStride;
0278:                            }
0279:                        }
0280:                    } else {
0281:                        /*
0282:                         * dest = (source1 * alpha1 +
0283:                         *         source2 * alpha2 * (1 - alpha1/maxValue)) /
0284:                         *        (alpha1 + alpha2 * (1 - alpha1/maxValue))
0285:                         */
0286:
0287:                        for (int h = 0; h < dheight; h++) {
0288:                            s1PixelOffset = s1LineOffset;
0289:                            s2PixelOffset = s2LineOffset;
0290:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0291:                            a2PixelOffset = a2LineOffset + a2BandOffset;
0292:                            dPixelOffset = dLineOffset;
0293:
0294:                            s1LineOffset += s1LineStride;
0295:                            s2LineOffset += s2LineStride;
0296:                            a1LineOffset += a1LineStride;
0297:                            a2LineOffset += a2LineStride;
0298:                            dLineOffset += dLineStride;
0299:
0300:                            for (int w = 0; w < dwidth; w++) {
0301:                                int t1 = a1Data[a1PixelOffset] & 0xFF;
0302:                                float t2 = (a2Data[a2PixelOffset] & 0xFF)
0303:                                        * (1.0F - t1 * invMax);
0304:                                float t3 = t1 + t2;
0305:                                float t4, t5;
0306:                                if (t3 == 0.0F) {
0307:                                    t4 = 0.0F;
0308:                                    t5 = 0.0F;
0309:                                } else {
0310:                                    t4 = t1 / t3;
0311:                                    t5 = t2 / t3;
0312:                                }
0313:
0314:                                /* Destination color channels. */
0315:                                for (int b = 0; b < dbands; b++) {
0316:                                    dData[b][dPixelOffset + dBandOffsets[b]] = (byte) ((s1Data[b][s1PixelOffset
0317:                                            + s1BandOffsets[b]] & 0xFF)
0318:                                            * t4 + (s2Data[b][s2PixelOffset
0319:                                            + s2BandOffsets[b]] & 0xFF)
0320:                                            * t5);
0321:                                }
0322:
0323:                                s1PixelOffset += s1PixelStride;
0324:                                s2PixelOffset += s2PixelStride;
0325:                                a1PixelOffset += a1PixelStride;
0326:                                a2PixelOffset += a2PixelStride;
0327:                                dPixelOffset += dPixelStride;
0328:                            }
0329:                        }
0330:                    }
0331:                }
0332:            }
0333:
0334:            private void ushortLoop(RasterAccessor s1, RasterAccessor s2,
0335:                    RasterAccessor a1, RasterAccessor a2, RasterAccessor d) {
0336:                /* First source color channels. */
0337:                int s1LineStride = s1.getScanlineStride();
0338:                int s1PixelStride = s1.getPixelStride();
0339:                int[] s1BandOffsets = s1.getBandOffsets();
0340:                short[][] s1Data = s1.getShortDataArrays();
0341:
0342:                /* Second source color channels. */
0343:                int s2LineStride = s2.getScanlineStride();
0344:                int s2PixelStride = s2.getPixelStride();
0345:                int[] s2BandOffsets = s2.getBandOffsets();
0346:                short[][] s2Data = s2.getShortDataArrays();
0347:
0348:                /* First source alpha channel. */
0349:                int a1LineStride = a1.getScanlineStride();
0350:                int a1PixelStride = a1.getPixelStride();
0351:                int a1BandOffset = a1.getBandOffset(0);
0352:                short[] a1Data = a1.getShortDataArray(0);
0353:
0354:                /* Second source alpha channel (if any). */
0355:                int a2LineStride = 0;
0356:                int a2PixelStride = 0;
0357:                int a2BandOffset = 0;
0358:                short[] a2Data = null;
0359:                if (alpha2 != null) {
0360:                    a2LineStride = a2.getScanlineStride();
0361:                    a2PixelStride = a2.getPixelStride();
0362:                    a2BandOffset = a2.getBandOffset(0);
0363:                    a2Data = a2.getShortDataArray(0);
0364:                }
0365:
0366:                /* Destination color channels. */
0367:                int dLineStride = d.getScanlineStride();
0368:                int dPixelStride = d.getPixelStride();
0369:                int[] dBandOffsets = d.getBandOffsets();
0370:                short[][] dData = d.getShortDataArrays();
0371:
0372:                int dwidth = d.getWidth();
0373:                int dheight = d.getHeight();
0374:                int dbands = d.getNumBands();
0375:
0376:                float invMax = 1.0F / 0xFFFF;
0377:
0378:                int s1LineOffset = 0, s2LineOffset = 0, a1LineOffset = 0, a2LineOffset = 0, dLineOffset = 0, s1PixelOffset, s2PixelOffset, a1PixelOffset, a2PixelOffset, dPixelOffset;
0379:
0380:                if (premultiplied) {
0381:                    /* dest = source1 + source2 * (1 - alpha1/max) */
0382:
0383:                    for (int h = 0; h < dheight; h++) {
0384:                        s1PixelOffset = s1LineOffset;
0385:                        s2PixelOffset = s2LineOffset;
0386:                        a1PixelOffset = a1LineOffset + a1BandOffset;
0387:                        dPixelOffset = dLineOffset;
0388:
0389:                        s1LineOffset += s1LineStride;
0390:                        s2LineOffset += s2LineStride;
0391:                        a1LineOffset += a1LineStride;
0392:                        dLineOffset += dLineStride;
0393:
0394:                        for (int w = 0; w < dwidth; w++) {
0395:                            float t = 1.0F - (a1Data[a1PixelOffset] & 0xFFFF)
0396:                                    * invMax;
0397:
0398:                            /* Destination color channels. */
0399:                            for (int b = 0; b < dbands; b++) {
0400:                                dData[b][dPixelOffset + dBandOffsets[b]] = (short) ((s1Data[b][s1PixelOffset
0401:                                        + s1BandOffsets[b]] & 0xFFFF) + (s2Data[b][s2PixelOffset
0402:                                        + s2BandOffsets[b]] & 0xFFFF)
0403:                                        * t);
0404:                            }
0405:
0406:                            s1PixelOffset += s1PixelStride;
0407:                            s2PixelOffset += s2PixelStride;
0408:                            a1PixelOffset += a1PixelStride;
0409:                            dPixelOffset += dPixelStride;
0410:                        }
0411:                    }
0412:
0413:                } else {
0414:                    if (alpha2 == null) {
0415:                        /* dest = source1 * alpha1/max + source2 * (1 - alpha1/max) */
0416:
0417:                        for (int h = 0; h < dheight; h++) {
0418:                            s1PixelOffset = s1LineOffset;
0419:                            s2PixelOffset = s2LineOffset;
0420:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0421:                            dPixelOffset = dLineOffset;
0422:
0423:                            s1LineOffset += s1LineStride;
0424:                            s2LineOffset += s2LineStride;
0425:                            a1LineOffset += a1LineStride;
0426:                            dLineOffset += dLineStride;
0427:
0428:                            for (int w = 0; w < dwidth; w++) {
0429:                                float t1 = (a1Data[a1PixelOffset] & 0xFFFF)
0430:                                        * invMax;
0431:                                float t2 = 1.0F - t1;
0432:
0433:                                /* Destination color channels. */
0434:                                for (int b = 0; b < dbands; b++) {
0435:                                    dData[b][dPixelOffset + dBandOffsets[b]] = (short) ((s1Data[b][s1PixelOffset
0436:                                            + s1BandOffsets[b]] & 0xFFFF)
0437:                                            * t1 + (s2Data[b][s2PixelOffset
0438:                                            + s2BandOffsets[b]] & 0xFFFF)
0439:                                            * t2);
0440:                                }
0441:
0442:                                s1PixelOffset += s1PixelStride;
0443:                                s2PixelOffset += s2PixelStride;
0444:                                a1PixelOffset += a1PixelStride;
0445:                                dPixelOffset += dPixelStride;
0446:                            }
0447:                        }
0448:                    } else {
0449:                        /*
0450:                         * dest = (source1 * alpha1 +
0451:                         *         source2 * alpha2 * (1 - alpha1/maxValue)) /
0452:                         *        (alpha1 + alpha2 * (1 - alpha1/maxValue))
0453:                         */
0454:
0455:                        for (int h = 0; h < dheight; h++) {
0456:                            s1PixelOffset = s1LineOffset;
0457:                            s2PixelOffset = s2LineOffset;
0458:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0459:                            a2PixelOffset = a2LineOffset + a2BandOffset;
0460:                            dPixelOffset = dLineOffset;
0461:
0462:                            s1LineOffset += s1LineStride;
0463:                            s2LineOffset += s2LineStride;
0464:                            a1LineOffset += a1LineStride;
0465:                            a2LineOffset += a2LineStride;
0466:                            dLineOffset += dLineStride;
0467:
0468:                            for (int w = 0; w < dwidth; w++) {
0469:                                int t1 = a1Data[a1PixelOffset] & 0xFFFF;
0470:                                float t2 = (a2Data[a2PixelOffset] & 0xFFFF)
0471:                                        * (1.0F - t1 * invMax);
0472:                                float t3 = t1 + t2;
0473:                                float t4, t5;
0474:                                if (t3 == 0.0F) {
0475:                                    t4 = 0.0F;
0476:                                    t5 = 0.0F;
0477:                                } else {
0478:                                    t4 = t1 / t3;
0479:                                    t5 = t2 / t3;
0480:                                }
0481:
0482:                                /* Destination color channels. */
0483:                                for (int b = 0; b < dbands; b++) {
0484:                                    dData[b][dPixelOffset + dBandOffsets[b]] = (short) ((s1Data[b][s1PixelOffset
0485:                                            + s1BandOffsets[b]] & 0xFFFF)
0486:                                            * t4 + (s2Data[b][s2PixelOffset
0487:                                            + s2BandOffsets[b]] & 0xFFFF)
0488:                                            * t5);
0489:                                }
0490:
0491:                                s1PixelOffset += s1PixelStride;
0492:                                s2PixelOffset += s2PixelStride;
0493:                                a1PixelOffset += a1PixelStride;
0494:                                a2PixelOffset += a2PixelStride;
0495:                                dPixelOffset += dPixelStride;
0496:                            }
0497:                        }
0498:                    }
0499:                }
0500:            }
0501:
0502:            private void shortLoop(RasterAccessor s1, RasterAccessor s2,
0503:                    RasterAccessor a1, RasterAccessor a2, RasterAccessor d) {
0504:                /* First source color channels. */
0505:                int s1LineStride = s1.getScanlineStride();
0506:                int s1PixelStride = s1.getPixelStride();
0507:                int[] s1BandOffsets = s1.getBandOffsets();
0508:                short[][] s1Data = s1.getShortDataArrays();
0509:
0510:                /* Second source color channels. */
0511:                int s2LineStride = s2.getScanlineStride();
0512:                int s2PixelStride = s2.getPixelStride();
0513:                int[] s2BandOffsets = s2.getBandOffsets();
0514:                short[][] s2Data = s2.getShortDataArrays();
0515:
0516:                /* First source alpha channel. */
0517:                int a1LineStride = a1.getScanlineStride();
0518:                int a1PixelStride = a1.getPixelStride();
0519:                int a1BandOffset = a1.getBandOffset(0);
0520:                short[] a1Data = a1.getShortDataArray(0);
0521:
0522:                /* Second source alpha channel (if any). */
0523:                int a2LineStride = 0;
0524:                int a2PixelStride = 0;
0525:                int a2BandOffset = 0;
0526:                short[] a2Data = null;
0527:                if (alpha2 != null) {
0528:                    a2LineStride = a2.getScanlineStride();
0529:                    a2PixelStride = a2.getPixelStride();
0530:                    a2BandOffset = a2.getBandOffset(0);
0531:                    a2Data = a2.getShortDataArray(0);
0532:                }
0533:
0534:                /* Destination color channels. */
0535:                int dLineStride = d.getScanlineStride();
0536:                int dPixelStride = d.getPixelStride();
0537:                int[] dBandOffsets = d.getBandOffsets();
0538:                short[][] dData = d.getShortDataArrays();
0539:
0540:                int dwidth = d.getWidth();
0541:                int dheight = d.getHeight();
0542:                int dbands = d.getNumBands();
0543:
0544:                float invMax = 1.0F / Short.MAX_VALUE;
0545:
0546:                int s1LineOffset = 0, s2LineOffset = 0, a1LineOffset = 0, a2LineOffset = 0, dLineOffset = 0, s1PixelOffset, s2PixelOffset, a1PixelOffset, a2PixelOffset, dPixelOffset;
0547:
0548:                if (premultiplied) {
0549:                    /* dest = source1 + source2 * (1 - alpha1/max) */
0550:
0551:                    for (int h = 0; h < dheight; h++) {
0552:                        s1PixelOffset = s1LineOffset;
0553:                        s2PixelOffset = s2LineOffset;
0554:                        a1PixelOffset = a1LineOffset + a1BandOffset;
0555:                        dPixelOffset = dLineOffset;
0556:
0557:                        s1LineOffset += s1LineStride;
0558:                        s2LineOffset += s2LineStride;
0559:                        a1LineOffset += a1LineStride;
0560:                        dLineOffset += dLineStride;
0561:
0562:                        for (int w = 0; w < dwidth; w++) {
0563:                            float t = 1.0F - a1Data[a1PixelOffset] * invMax;
0564:
0565:                            /* Destination color channels. */
0566:                            for (int b = 0; b < dbands; b++) {
0567:                                dData[b][dPixelOffset + dBandOffsets[b]] = (short) (s1Data[b][s1PixelOffset
0568:                                        + s1BandOffsets[b]] + s2Data[b][s2PixelOffset
0569:                                        + s2BandOffsets[b]]
0570:                                        * t);
0571:                            }
0572:
0573:                            s1PixelOffset += s1PixelStride;
0574:                            s2PixelOffset += s2PixelStride;
0575:                            a1PixelOffset += a1PixelStride;
0576:                            dPixelOffset += dPixelStride;
0577:                        }
0578:                    }
0579:
0580:                } else {
0581:                    if (alpha2 == null) {
0582:                        /* dest = source1 * alpha1/max + source2 * (1 - alpha1/max) */
0583:
0584:                        for (int h = 0; h < dheight; h++) {
0585:                            s1PixelOffset = s1LineOffset;
0586:                            s2PixelOffset = s2LineOffset;
0587:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0588:                            dPixelOffset = dLineOffset;
0589:
0590:                            s1LineOffset += s1LineStride;
0591:                            s2LineOffset += s2LineStride;
0592:                            a1LineOffset += a1LineStride;
0593:                            dLineOffset += dLineStride;
0594:
0595:                            for (int w = 0; w < dwidth; w++) {
0596:                                float t1 = a1Data[a1PixelOffset] * invMax;
0597:                                float t2 = 1.0F - t1;
0598:
0599:                                /* Destination color channels. */
0600:                                for (int b = 0; b < dbands; b++) {
0601:                                    dData[b][dPixelOffset + dBandOffsets[b]] = (short) (s1Data[b][s1PixelOffset
0602:                                            + s1BandOffsets[b]]
0603:                                            * t1 + s2Data[b][s2PixelOffset
0604:                                            + s2BandOffsets[b]]
0605:                                            * t2);
0606:                                }
0607:
0608:                                s1PixelOffset += s1PixelStride;
0609:                                s2PixelOffset += s2PixelStride;
0610:                                a1PixelOffset += a1PixelStride;
0611:                                dPixelOffset += dPixelStride;
0612:                            }
0613:                        }
0614:                    } else {
0615:                        /*
0616:                         * dest = (source1 * alpha1 +
0617:                         *         source2 * alpha2 * (1 - alpha1/maxValue)) /
0618:                         *        (alpha1 + alpha2 * (1 - alpha1/maxValue))
0619:                         */
0620:
0621:                        for (int h = 0; h < dheight; h++) {
0622:                            s1PixelOffset = s1LineOffset;
0623:                            s2PixelOffset = s2LineOffset;
0624:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0625:                            a2PixelOffset = a2LineOffset + a2BandOffset;
0626:                            dPixelOffset = dLineOffset;
0627:
0628:                            s1LineOffset += s1LineStride;
0629:                            s2LineOffset += s2LineStride;
0630:                            a1LineOffset += a1LineStride;
0631:                            a2LineOffset += a2LineStride;
0632:                            dLineOffset += dLineStride;
0633:
0634:                            for (int w = 0; w < dwidth; w++) {
0635:                                int t1 = a1Data[a1PixelOffset];
0636:                                float t2 = a2Data[a2PixelOffset]
0637:                                        * (1.0F - t1 * invMax);
0638:                                float t3 = t1 + t2;
0639:                                float t4, t5;
0640:                                if (t3 == 0.0F) {
0641:                                    t4 = 0.0F;
0642:                                    t5 = 0.0F;
0643:                                } else {
0644:                                    t4 = t1 / t3;
0645:                                    t5 = t2 / t3;
0646:                                }
0647:
0648:                                /* Destination color channels. */
0649:                                for (int b = 0; b < dbands; b++) {
0650:                                    dData[b][dPixelOffset + dBandOffsets[b]] = (short) (s1Data[b][s1PixelOffset
0651:                                            + s1BandOffsets[b]]
0652:                                            * t4 + s2Data[b][s2PixelOffset
0653:                                            + s2BandOffsets[b]]
0654:                                            * t5);
0655:                                }
0656:
0657:                                s1PixelOffset += s1PixelStride;
0658:                                s2PixelOffset += s2PixelStride;
0659:                                a1PixelOffset += a1PixelStride;
0660:                                a2PixelOffset += a2PixelStride;
0661:                                dPixelOffset += dPixelStride;
0662:                            }
0663:                        }
0664:                    }
0665:                }
0666:            }
0667:
0668:            private void intLoop(RasterAccessor s1, RasterAccessor s2,
0669:                    RasterAccessor a1, RasterAccessor a2, RasterAccessor d) {
0670:                /* First source color channels. */
0671:                int s1LineStride = s1.getScanlineStride();
0672:                int s1PixelStride = s1.getPixelStride();
0673:                int[] s1BandOffsets = s1.getBandOffsets();
0674:                int[][] s1Data = s1.getIntDataArrays();
0675:
0676:                /* Second source color channels. */
0677:                int s2LineStride = s2.getScanlineStride();
0678:                int s2PixelStride = s2.getPixelStride();
0679:                int[] s2BandOffsets = s2.getBandOffsets();
0680:                int[][] s2Data = s2.getIntDataArrays();
0681:
0682:                /* First source alpha channel. */
0683:                int a1LineStride = a1.getScanlineStride();
0684:                int a1PixelStride = a1.getPixelStride();
0685:                int a1BandOffset = a1.getBandOffset(0);
0686:                int[] a1Data = a1.getIntDataArray(0);
0687:
0688:                /* Second source alpha channel (if any). */
0689:                int a2LineStride = 0;
0690:                int a2PixelStride = 0;
0691:                int a2BandOffset = 0;
0692:                int[] a2Data = null;
0693:                if (alpha2 != null) {
0694:                    a2LineStride = a2.getScanlineStride();
0695:                    a2PixelStride = a2.getPixelStride();
0696:                    a2BandOffset = a2.getBandOffset(0);
0697:                    a2Data = a2.getIntDataArray(0);
0698:                }
0699:
0700:                /* Destination color channels. */
0701:                int dLineStride = d.getScanlineStride();
0702:                int dPixelStride = d.getPixelStride();
0703:                int[] dBandOffsets = d.getBandOffsets();
0704:                int[][] dData = d.getIntDataArrays();
0705:
0706:                int dwidth = d.getWidth();
0707:                int dheight = d.getHeight();
0708:                int dbands = d.getNumBands();
0709:
0710:                float invMax = 1.0F / Integer.MAX_VALUE;
0711:
0712:                int s1LineOffset = 0, s2LineOffset = 0, a1LineOffset = 0, a2LineOffset = 0, dLineOffset = 0, s1PixelOffset, s2PixelOffset, a1PixelOffset, a2PixelOffset, dPixelOffset;
0713:
0714:                if (premultiplied) {
0715:                    /* dest = source1 + source2 * (1 - alpha1/max) */
0716:
0717:                    for (int h = 0; h < dheight; h++) {
0718:                        s1PixelOffset = s1LineOffset;
0719:                        s2PixelOffset = s2LineOffset;
0720:                        a1PixelOffset = a1LineOffset + a1BandOffset;
0721:                        dPixelOffset = dLineOffset;
0722:
0723:                        s1LineOffset += s1LineStride;
0724:                        s2LineOffset += s2LineStride;
0725:                        a1LineOffset += a1LineStride;
0726:                        dLineOffset += dLineStride;
0727:
0728:                        for (int w = 0; w < dwidth; w++) {
0729:                            float t = 1.0F - a1Data[a1PixelOffset] * invMax;
0730:
0731:                            /* Destination color channels. */
0732:                            for (int b = 0; b < dbands; b++) {
0733:                                dData[b][dPixelOffset + dBandOffsets[b]] = (int) (s1Data[b][s1PixelOffset
0734:                                        + s1BandOffsets[b]] + s2Data[b][s2PixelOffset
0735:                                        + s2BandOffsets[b]]
0736:                                        * t);
0737:                            }
0738:
0739:                            s1PixelOffset += s1PixelStride;
0740:                            s2PixelOffset += s2PixelStride;
0741:                            a1PixelOffset += a1PixelStride;
0742:                            dPixelOffset += dPixelStride;
0743:                        }
0744:                    }
0745:
0746:                } else {
0747:                    if (alpha2 == null) {
0748:                        /* dest = source1 * alpha1/max + source2 * (1 - alpha1/max) */
0749:
0750:                        for (int h = 0; h < dheight; h++) {
0751:                            s1PixelOffset = s1LineOffset;
0752:                            s2PixelOffset = s2LineOffset;
0753:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0754:                            dPixelOffset = dLineOffset;
0755:
0756:                            s1LineOffset += s1LineStride;
0757:                            s2LineOffset += s2LineStride;
0758:                            a1LineOffset += a1LineStride;
0759:                            dLineOffset += dLineStride;
0760:
0761:                            for (int w = 0; w < dwidth; w++) {
0762:                                float t1 = a1Data[a1PixelOffset] * invMax;
0763:                                float t2 = 1.0F - t1;
0764:
0765:                                /* Destination color channels. */
0766:                                for (int b = 0; b < dbands; b++) {
0767:                                    dData[b][dPixelOffset + dBandOffsets[b]] = (int) (s1Data[b][s1PixelOffset
0768:                                            + s1BandOffsets[b]]
0769:                                            * t1 + s2Data[b][s2PixelOffset
0770:                                            + s2BandOffsets[b]]
0771:                                            * t2);
0772:                                }
0773:
0774:                                s1PixelOffset += s1PixelStride;
0775:                                s2PixelOffset += s2PixelStride;
0776:                                a1PixelOffset += a1PixelStride;
0777:                                dPixelOffset += dPixelStride;
0778:                            }
0779:                        }
0780:                    } else {
0781:                        /*
0782:                         * dest = (source1 * alpha1 +
0783:                         *         source2 * alpha2 * (1 - alpha1/maxValue)) /
0784:                         *        (alpha1 + alpha2 * (1 - alpha1/maxValue))
0785:                         */
0786:
0787:                        for (int h = 0; h < dheight; h++) {
0788:                            s1PixelOffset = s1LineOffset;
0789:                            s2PixelOffset = s2LineOffset;
0790:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0791:                            a2PixelOffset = a2LineOffset + a2BandOffset;
0792:                            dPixelOffset = dLineOffset;
0793:
0794:                            s1LineOffset += s1LineStride;
0795:                            s2LineOffset += s2LineStride;
0796:                            a1LineOffset += a1LineStride;
0797:                            a2LineOffset += a2LineStride;
0798:                            dLineOffset += dLineStride;
0799:
0800:                            for (int w = 0; w < dwidth; w++) {
0801:                                int t1 = a1Data[a1PixelOffset];
0802:                                float t2 = a2Data[a2PixelOffset]
0803:                                        * (1.0F - t1 * invMax);
0804:                                float t3 = t1 + t2;
0805:                                float t4, t5;
0806:                                if (t3 == 0.0F) {
0807:                                    t4 = 0.0F;
0808:                                    t5 = 0.0F;
0809:                                } else {
0810:                                    t4 = t1 / t3;
0811:                                    t5 = t2 / t3;
0812:                                }
0813:
0814:                                /* Destination color channels. */
0815:                                for (int b = 0; b < dbands; b++) {
0816:                                    dData[b][dPixelOffset + dBandOffsets[b]] = (int) (s1Data[b][s1PixelOffset
0817:                                            + s1BandOffsets[b]]
0818:                                            * t4 + s2Data[b][s2PixelOffset
0819:                                            + s2BandOffsets[b]]
0820:                                            * t5);
0821:                                }
0822:
0823:                                s1PixelOffset += s1PixelStride;
0824:                                s2PixelOffset += s2PixelStride;
0825:                                a1PixelOffset += a1PixelStride;
0826:                                a2PixelOffset += a2PixelStride;
0827:                                dPixelOffset += dPixelStride;
0828:                            }
0829:                        }
0830:                    }
0831:                }
0832:            }
0833:
0834:            private void floatLoop(RasterAccessor s1, RasterAccessor s2,
0835:                    RasterAccessor a1, RasterAccessor a2, RasterAccessor d) {
0836:                /* First source color channels. */
0837:                int s1LineStride = s1.getScanlineStride();
0838:                int s1PixelStride = s1.getPixelStride();
0839:                int[] s1BandOffsets = s1.getBandOffsets();
0840:                float[][] s1Data = s1.getFloatDataArrays();
0841:
0842:                /* Second source color channels. */
0843:                int s2LineStride = s2.getScanlineStride();
0844:                int s2PixelStride = s2.getPixelStride();
0845:                int[] s2BandOffsets = s2.getBandOffsets();
0846:                float[][] s2Data = s2.getFloatDataArrays();
0847:
0848:                /* First source alpha channel. */
0849:                int a1LineStride = a1.getScanlineStride();
0850:                int a1PixelStride = a1.getPixelStride();
0851:                int a1BandOffset = a1.getBandOffset(0);
0852:                float[] a1Data = a1.getFloatDataArray(0);
0853:
0854:                /* Second source alpha channel (if any). */
0855:                int a2LineStride = 0;
0856:                int a2PixelStride = 0;
0857:                int a2BandOffset = 0;
0858:                float[] a2Data = null;
0859:                if (alpha2 != null) {
0860:                    a2LineStride = a2.getScanlineStride();
0861:                    a2PixelStride = a2.getPixelStride();
0862:                    a2BandOffset = a2.getBandOffset(0);
0863:                    a2Data = a2.getFloatDataArray(0);
0864:                }
0865:
0866:                /* Destination color channels. */
0867:                int dLineStride = d.getScanlineStride();
0868:                int dPixelStride = d.getPixelStride();
0869:                int[] dBandOffsets = d.getBandOffsets();
0870:                float[][] dData = d.getFloatDataArrays();
0871:
0872:                int dwidth = d.getWidth();
0873:                int dheight = d.getHeight();
0874:                int dbands = d.getNumBands();
0875:
0876:                int s1LineOffset = 0, s2LineOffset = 0, a1LineOffset = 0, a2LineOffset = 0, dLineOffset = 0, s1PixelOffset, s2PixelOffset, a1PixelOffset, a2PixelOffset, dPixelOffset;
0877:
0878:                if (premultiplied) {
0879:                    /* dest = source1 + source2 * (1 - alpha1) */
0880:
0881:                    for (int h = 0; h < dheight; h++) {
0882:                        s1PixelOffset = s1LineOffset;
0883:                        s2PixelOffset = s2LineOffset;
0884:                        a1PixelOffset = a1LineOffset + a1BandOffset;
0885:                        dPixelOffset = dLineOffset;
0886:
0887:                        s1LineOffset += s1LineStride;
0888:                        s2LineOffset += s2LineStride;
0889:                        a1LineOffset += a1LineStride;
0890:                        dLineOffset += dLineStride;
0891:
0892:                        for (int w = 0; w < dwidth; w++) {
0893:                            float t = 1.0F - a1Data[a1PixelOffset];
0894:
0895:                            /* Destination color channels. */
0896:                            for (int b = 0; b < dbands; b++) {
0897:                                dData[b][dPixelOffset + dBandOffsets[b]] = s1Data[b][s1PixelOffset
0898:                                        + s1BandOffsets[b]]
0899:                                        + s2Data[b][s2PixelOffset
0900:                                                + s2BandOffsets[b]] * t;
0901:                            }
0902:
0903:                            s1PixelOffset += s1PixelStride;
0904:                            s2PixelOffset += s2PixelStride;
0905:                            a1PixelOffset += a1PixelStride;
0906:                            dPixelOffset += dPixelStride;
0907:                        }
0908:                    }
0909:
0910:                } else {
0911:                    if (alpha2 == null) {
0912:                        /* dest = source1 * alpha1 + source2 * (1 - alpha1) */
0913:
0914:                        for (int h = 0; h < dheight; h++) {
0915:                            s1PixelOffset = s1LineOffset;
0916:                            s2PixelOffset = s2LineOffset;
0917:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0918:                            dPixelOffset = dLineOffset;
0919:
0920:                            s1LineOffset += s1LineStride;
0921:                            s2LineOffset += s2LineStride;
0922:                            a1LineOffset += a1LineStride;
0923:                            dLineOffset += dLineStride;
0924:
0925:                            for (int w = 0; w < dwidth; w++) {
0926:                                float t1 = a1Data[a1PixelOffset];
0927:                                float t2 = 1.0F - t1;
0928:
0929:                                /* Destination color channels. */
0930:                                for (int b = 0; b < dbands; b++) {
0931:                                    dData[b][dPixelOffset + dBandOffsets[b]] = s1Data[b][s1PixelOffset
0932:                                            + s1BandOffsets[b]]
0933:                                            * t1
0934:                                            + s2Data[b][s2PixelOffset
0935:                                                    + s2BandOffsets[b]] * t2;
0936:                                }
0937:
0938:                                s1PixelOffset += s1PixelStride;
0939:                                s2PixelOffset += s2PixelStride;
0940:                                a1PixelOffset += a1PixelStride;
0941:                                dPixelOffset += dPixelStride;
0942:                            }
0943:                        }
0944:                    } else {
0945:                        /*
0946:                         * dest = (source1 * alpha1 + source2 * alpha2 * (1 - alpha1)) /
0947:                         *        (alpha1 + alpha2 * (1 - alpha1))
0948:                         */
0949:
0950:                        for (int h = 0; h < dheight; h++) {
0951:                            s1PixelOffset = s1LineOffset;
0952:                            s2PixelOffset = s2LineOffset;
0953:                            a1PixelOffset = a1LineOffset + a1BandOffset;
0954:                            a2PixelOffset = a2LineOffset + a2BandOffset;
0955:                            dPixelOffset = dLineOffset;
0956:
0957:                            s1LineOffset += s1LineStride;
0958:                            s2LineOffset += s2LineStride;
0959:                            a1LineOffset += a1LineStride;
0960:                            a2LineOffset += a2LineStride;
0961:                            dLineOffset += dLineStride;
0962:
0963:                            for (int w = 0; w < dwidth; w++) {
0964:                                float t1 = a1Data[a1PixelOffset];
0965:                                float t2 = a2Data[a2PixelOffset] * (1.0F - t1);
0966:                                float t3 = t1 + t2;
0967:                                float t4, t5;
0968:                                if (t3 == 0.0F) {
0969:                                    t4 = 0.0F;
0970:                                    t5 = 0.0F;
0971:                                } else {
0972:                                    t4 = t1 / t3;
0973:                                    t5 = t2 / t3;
0974:                                }
0975:
0976:                                /* Destination color channels. */
0977:                                for (int b = 0; b < dbands; b++) {
0978:                                    dData[b][dPixelOffset + dBandOffsets[b]] = s1Data[b][s1PixelOffset
0979:                                            + s1BandOffsets[b]]
0980:                                            * t4
0981:                                            + s2Data[b][s2PixelOffset
0982:                                                    + s2BandOffsets[b]] * t5;
0983:                                }
0984:
0985:                                s1PixelOffset += s1PixelStride;
0986:                                s2PixelOffset += s2PixelStride;
0987:                                a1PixelOffset += a1PixelStride;
0988:                                a2PixelOffset += a2PixelStride;
0989:                                dPixelOffset += dPixelStride;
0990:                            }
0991:                        }
0992:                    }
0993:                }
0994:            }
0995:
0996:            private void doubleLoop(RasterAccessor s1, RasterAccessor s2,
0997:                    RasterAccessor a1, RasterAccessor a2, RasterAccessor d) {
0998:                /* First source color channels. */
0999:                int s1LineStride = s1.getScanlineStride();
1000:                int s1PixelStride = s1.getPixelStride();
1001:                int[] s1BandOffsets = s1.getBandOffsets();
1002:                double[][] s1Data = s1.getDoubleDataArrays();
1003:
1004:                /* Second source color channels. */
1005:                int s2LineStride = s2.getScanlineStride();
1006:                int s2PixelStride = s2.getPixelStride();
1007:                int[] s2BandOffsets = s2.getBandOffsets();
1008:                double[][] s2Data = s2.getDoubleDataArrays();
1009:
1010:                /* First source alpha channel. */
1011:                int a1LineStride = a1.getScanlineStride();
1012:                int a1PixelStride = a1.getPixelStride();
1013:                int a1BandOffset = a1.getBandOffset(0);
1014:                double[] a1Data = a1.getDoubleDataArray(0);
1015:
1016:                /* Second source alpha channel (if any). */
1017:                int a2LineStride = 0;
1018:                int a2PixelStride = 0;
1019:                int a2BandOffset = 0;
1020:                double[] a2Data = null;
1021:                if (alpha2 != null) {
1022:                    a2LineStride = a2.getScanlineStride();
1023:                    a2PixelStride = a2.getPixelStride();
1024:                    a2BandOffset = a2.getBandOffset(0);
1025:                    a2Data = a2.getDoubleDataArray(0);
1026:                }
1027:
1028:                /* Destination color channels. */
1029:                int dLineStride = d.getScanlineStride();
1030:                int dPixelStride = d.getPixelStride();
1031:                int[] dBandOffsets = d.getBandOffsets();
1032:                double[][] dData = d.getDoubleDataArrays();
1033:
1034:                int dwidth = d.getWidth();
1035:                int dheight = d.getHeight();
1036:                int dbands = d.getNumBands();
1037:
1038:                int s1LineOffset = 0, s2LineOffset = 0, a1LineOffset = 0, a2LineOffset = 0, dLineOffset = 0, s1PixelOffset, s2PixelOffset, a1PixelOffset, a2PixelOffset, dPixelOffset;
1039:
1040:                if (premultiplied) {
1041:                    /* dest = source1 + source2 * (1 - alpha1) */
1042:
1043:                    for (int h = 0; h < dheight; h++) {
1044:                        s1PixelOffset = s1LineOffset;
1045:                        s2PixelOffset = s2LineOffset;
1046:                        a1PixelOffset = a1LineOffset + a1BandOffset;
1047:                        dPixelOffset = dLineOffset;
1048:
1049:                        s1LineOffset += s1LineStride;
1050:                        s2LineOffset += s2LineStride;
1051:                        a1LineOffset += a1LineStride;
1052:                        dLineOffset += dLineStride;
1053:
1054:                        for (int w = 0; w < dwidth; w++) {
1055:                            double t = 1.0 - a1Data[a1PixelOffset];
1056:
1057:                            /* Destination color channels. */
1058:                            for (int b = 0; b < dbands; b++) {
1059:                                dData[b][dPixelOffset + dBandOffsets[b]] = s1Data[b][s1PixelOffset
1060:                                        + s1BandOffsets[b]]
1061:                                        + s2Data[b][s2PixelOffset
1062:                                                + s2BandOffsets[b]] * t;
1063:                            }
1064:
1065:                            s1PixelOffset += s1PixelStride;
1066:                            s2PixelOffset += s2PixelStride;
1067:                            a1PixelOffset += a1PixelStride;
1068:                            dPixelOffset += dPixelStride;
1069:                        }
1070:                    }
1071:
1072:                } else {
1073:                    if (alpha2 == null) {
1074:                        /* dest = source1 * alpha1 + source2 * (1 - alpha1) */
1075:
1076:                        for (int h = 0; h < dheight; h++) {
1077:                            s1PixelOffset = s1LineOffset;
1078:                            s2PixelOffset = s2LineOffset;
1079:                            a1PixelOffset = a1LineOffset + a1BandOffset;
1080:                            dPixelOffset = dLineOffset;
1081:
1082:                            s1LineOffset += s1LineStride;
1083:                            s2LineOffset += s2LineStride;
1084:                            a1LineOffset += a1LineStride;
1085:                            dLineOffset += dLineStride;
1086:
1087:                            for (int w = 0; w < dwidth; w++) {
1088:                                double t1 = a1Data[a1PixelOffset];
1089:                                double t2 = 1.0 - t1;
1090:
1091:                                /* Destination color channels. */
1092:                                for (int b = 0; b < dbands; b++) {
1093:                                    dData[b][dPixelOffset + dBandOffsets[b]] = s1Data[b][s1PixelOffset
1094:                                            + s1BandOffsets[b]]
1095:                                            * t1
1096:                                            + s2Data[b][s2PixelOffset
1097:                                                    + s2BandOffsets[b]] * t2;
1098:                                }
1099:
1100:                                s1PixelOffset += s1PixelStride;
1101:                                s2PixelOffset += s2PixelStride;
1102:                                a1PixelOffset += a1PixelStride;
1103:                                dPixelOffset += dPixelStride;
1104:                            }
1105:                        }
1106:                    } else {
1107:                        /*
1108:                         * dest = (source1 * alpha1 + source2 * alpha2 * (1 - alpha1)) /
1109:                         *        (alpha1 + alpha2 * (1 - alpha1))
1110:                         */
1111:
1112:                        for (int h = 0; h < dheight; h++) {
1113:                            s1PixelOffset = s1LineOffset;
1114:                            s2PixelOffset = s2LineOffset;
1115:                            a1PixelOffset = a1LineOffset + a1BandOffset;
1116:                            a2PixelOffset = a2LineOffset + a2BandOffset;
1117:                            dPixelOffset = dLineOffset;
1118:
1119:                            s1LineOffset += s1LineStride;
1120:                            s2LineOffset += s2LineStride;
1121:                            a1LineOffset += a1LineStride;
1122:                            a2LineOffset += a2LineStride;
1123:                            dLineOffset += dLineStride;
1124:
1125:                            for (int w = 0; w < dwidth; w++) {
1126:                                double t1 = a1Data[a1PixelOffset];
1127:                                double t2 = a2Data[a2PixelOffset] * (1.0 - t1);
1128:                                double t3 = t1 + t2;
1129:                                double t4, t5;
1130:                                if (t3 == 0.0) {
1131:                                    t4 = 0.0;
1132:                                    t5 = 0.0;
1133:                                } else {
1134:                                    t4 = t1 / t3;
1135:                                    t5 = t2 / t3;
1136:                                }
1137:
1138:                                /* Destination color channels. */
1139:                                for (int b = 0; b < dbands; b++) {
1140:                                    dData[b][dPixelOffset + dBandOffsets[b]] = s1Data[b][s1PixelOffset
1141:                                            + s1BandOffsets[b]]
1142:                                            * t4
1143:                                            + s2Data[b][s2PixelOffset
1144:                                                    + s2BandOffsets[b]] * t5;
1145:                                }
1146:
1147:                                s1PixelOffset += s1PixelStride;
1148:                                s2PixelOffset += s2PixelStride;
1149:                                a1PixelOffset += a1PixelStride;
1150:                                a2PixelOffset += a2PixelStride;
1151:                                dPixelOffset += dPixelStride;
1152:                            }
1153:                        }
1154:                    }
1155:                }
1156:            }
1157:
1158:            /** Returns the format tags to be used with <code>RasterAccessor</code>. */
1159:            protected synchronized RasterFormatTag[] getFormatTags() {
1160:                RenderedImage[] ri;
1161:                if (alpha2 == null) {
1162:                    ri = new RenderedImage[3];
1163:                } else {
1164:                    ri = new RenderedImage[4];
1165:                    ri[3] = alpha2;
1166:                }
1167:                ri[0] = getSourceImage(0);
1168:                ri[1] = getSourceImage(1);
1169:                ri[2] = alpha1;
1170:
1171:                return RasterAccessor.findCompatibleTags(ri, this);
1172:            }
1173:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.