Source Code Cross Referenced for ScaleBilinearOpImage.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) 


001:        /*
002:         * $RCSfile: ScaleBilinearOpImage.java,v $
003:         *
004:         * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * Use is subject to license terms.
007:         *
008:         * $Revision: 1.1 $
009:         * $Date: 2005/02/11 04:56:42 $
010:         * $State: Exp $
011:         */
012:        package com.sun.media.jai.opimage;
013:
014:        import java.awt.Rectangle;
015:        import java.awt.image.DataBuffer;
016:        import java.awt.image.Raster;
017:        import java.awt.image.RenderedImage;
018:        import java.awt.image.WritableRaster;
019:        import java.awt.image.renderable.ParameterBlock;
020:        import javax.media.jai.BorderExtender;
021:        import javax.media.jai.ImageLayout;
022:        import javax.media.jai.Interpolation;
023:        import javax.media.jai.InterpolationBilinear;
024:        import javax.media.jai.OpImage;
025:        import javax.media.jai.PlanarImage;
026:        import javax.media.jai.RasterAccessor;
027:        import javax.media.jai.RasterFormatTag;
028:        import javax.media.jai.ScaleOpImage;
029:        import java.util.Map;
030:        import com.sun.media.jai.util.Rational;
031:
032:        // import com.sun.media.jai.test.OpImageTester;
033:
034:        /**
035:         * An <code>OpImage</code> that performs bilinear interpolation scaling.
036:         *
037:         */
038:        final class ScaleBilinearOpImage extends ScaleOpImage {
039:
040:            /** The number of SubsampleBits */
041:            private int subsampleBits;
042:
043:            /** Subsampling related variables */
044:            int one, shift2, round2;
045:
046:            Rational half = new Rational(1, 2);
047:            long invScaleYInt, invScaleYFrac;
048:            long invScaleXInt, invScaleXFrac;
049:
050:            /**
051:             * Constructs a ScaleBilinearOpImage from a RenderedImage source,
052:             * 
053:             * @param source a RenderedImage.
054:             * @param extender a BorderExtender, or null.
055:             * @param layout an ImageLayout optionally containing the tile grid layout,
056:             *        SampleModel, and ColorModel, or null.
057:             * @param xScale scale factor along x axis.
058:             * @param yScale scale factor along y axis.
059:             * @param xTrans translation factor along x axis.
060:             * @param yTrans translation factor along y axis.
061:             * @param interp a Interpolation object to use for resampling.
062:             */
063:            public ScaleBilinearOpImage(RenderedImage source,
064:                    BorderExtender extender, Map config, ImageLayout layout,
065:                    float xScale, float yScale, float xTrans, float yTrans,
066:                    Interpolation interp) {
067:                super (source, layout, config, true, extender, interp, xScale,
068:                        yScale, xTrans, yTrans);
069:
070:                subsampleBits = interp.getSubsampleBitsH();
071:
072:                // Number of subsampling positions
073:                one = 1 << subsampleBits;
074:
075:                // Subsampling related variables
076:                shift2 = 2 * subsampleBits;
077:                round2 = 1 << (shift2 - 1);
078:
079:                if (invScaleYRational.num > invScaleYRational.denom) {
080:                    invScaleYInt = invScaleYRational.num
081:                            / invScaleYRational.denom;
082:                    invScaleYFrac = invScaleYRational.num
083:                            % invScaleYRational.denom;
084:                } else {
085:                    invScaleYInt = 0;
086:                    invScaleYFrac = invScaleYRational.num;
087:                }
088:
089:                if (invScaleXRational.num > invScaleXRational.denom) {
090:                    invScaleXInt = invScaleXRational.num
091:                            / invScaleXRational.denom;
092:                    invScaleXFrac = invScaleXRational.num
093:                            % invScaleXRational.denom;
094:                } else {
095:                    invScaleXInt = 0;
096:                    invScaleXFrac = invScaleXRational.num;
097:                }
098:            }
099:
100:            /**
101:             * Performs scale operation on a specified rectangle. The sources are
102:             * cobbled.
103:             *
104:             * @param sources an array of source Rasters, guaranteed to provide all
105:             *                necessary source data for computing the output.
106:             * @param dest a WritableRaster tile containing the area to be computed.
107:             * @param destRect the rectangle within dest to be processed.
108:             */
109:            protected void computeRect(Raster[] sources, WritableRaster dest,
110:                    Rectangle destRect) {
111:                // Retrieve format tags.
112:                RasterFormatTag[] formatTags = getFormatTags();
113:
114:                Raster source = sources[0];
115:                // Get the source rectangle
116:                Rectangle srcRect = source.getBounds();
117:
118:                RasterAccessor srcAccessor = new RasterAccessor(source,
119:                        srcRect, formatTags[0], getSource(0).getColorModel());
120:
121:                RasterAccessor dstAccessor = new RasterAccessor(dest, destRect,
122:                        formatTags[1], getColorModel());
123:
124:                int dwidth = destRect.width;
125:                int dheight = destRect.height;
126:                int srcPixelStride = srcAccessor.getPixelStride();
127:                int srcScanlineStride = srcAccessor.getScanlineStride();
128:
129:                int[] ypos = new int[dheight];
130:                int[] xpos = new int[dwidth];
131:
132:                int xfracvalues[] = null, yfracvalues[] = null;
133:                float xfracvaluesFloat[] = null, yfracvaluesFloat[] = null;
134:
135:                switch (dstAccessor.getDataType()) {
136:                case DataBuffer.TYPE_BYTE:
137:                case DataBuffer.TYPE_SHORT:
138:                case DataBuffer.TYPE_USHORT:
139:                case DataBuffer.TYPE_INT:
140:                    yfracvalues = new int[dheight];
141:                    xfracvalues = new int[dwidth];
142:                    preComputePositionsInt(destRect, srcRect.x, srcRect.y,
143:                            srcPixelStride, srcScanlineStride, xpos, ypos,
144:                            xfracvalues, yfracvalues);
145:                    break;
146:
147:                case DataBuffer.TYPE_FLOAT:
148:                case DataBuffer.TYPE_DOUBLE:
149:                    yfracvaluesFloat = new float[dheight];
150:                    xfracvaluesFloat = new float[dwidth];
151:                    preComputePositionsFloat(destRect, srcRect.x, srcRect.y,
152:                            srcPixelStride, srcScanlineStride, xpos, ypos,
153:                            xfracvaluesFloat, yfracvaluesFloat);
154:                    break;
155:
156:                default:
157:                    throw new RuntimeException(JaiI18N
158:                            .getString("OrderedDitherOpImage0"));
159:                }
160:
161:                switch (dstAccessor.getDataType()) {
162:                case DataBuffer.TYPE_BYTE:
163:                    byteLoop(srcAccessor, destRect, dstAccessor, xpos, ypos,
164:                            xfracvalues, yfracvalues);
165:                    break;
166:
167:                case DataBuffer.TYPE_SHORT:
168:                    shortLoop(srcAccessor, destRect, dstAccessor, xpos, ypos,
169:                            xfracvalues, yfracvalues);
170:                    break;
171:
172:                case DataBuffer.TYPE_USHORT:
173:                    ushortLoop(srcAccessor, destRect, dstAccessor, xpos, ypos,
174:                            xfracvalues, yfracvalues);
175:                    break;
176:
177:                case DataBuffer.TYPE_INT:
178:                    intLoop(srcAccessor, destRect, dstAccessor, xpos, ypos,
179:                            xfracvalues, yfracvalues);
180:                    break;
181:
182:                case DataBuffer.TYPE_FLOAT:
183:                    floatLoop(srcAccessor, destRect, dstAccessor, xpos, ypos,
184:                            xfracvaluesFloat, yfracvaluesFloat);
185:                    break;
186:
187:                case DataBuffer.TYPE_DOUBLE:
188:                    doubleLoop(srcAccessor, destRect, dstAccessor, xpos, ypos,
189:                            xfracvaluesFloat, yfracvaluesFloat);
190:                    break;
191:                }
192:
193:                // If the RasterAccessor object set up a temporary buffer for the 
194:                // op to write to, tell the RasterAccessor to write that data
195:                // to the raster no that we're done with it.
196:                if (dstAccessor.isDataCopy()) {
197:                    dstAccessor.clampDataArrays();
198:                    dstAccessor.copyDataToRaster();
199:                }
200:            }
201:
202:            private void preComputePositionsInt(Rectangle destRect,
203:                    int srcRectX, int srcRectY, int srcPixelStride,
204:                    int srcScanlineStride, int xpos[], int ypos[],
205:                    int xfracvalues[], int yfracvalues[]) {
206:
207:                int dwidth = destRect.width;
208:                int dheight = destRect.height;
209:
210:                // Loop variables based on the destination rectangle to be calculated.
211:                int dx = destRect.x;
212:                int dy = destRect.y;
213:
214:                long syNum = dy, syDenom = 1;
215:
216:                // Subtract the X translation factor sy -= transY
217:                syNum = syNum * transYRationalDenom - transYRationalNum
218:                        * syDenom;
219:                syDenom *= transYRationalDenom;
220:
221:                // Add 0.5
222:                syNum = 2 * syNum + syDenom;
223:                syDenom *= 2;
224:
225:                // Multply by invScaleX
226:                syNum *= invScaleYRationalNum;
227:                syDenom *= invScaleYRationalDenom;
228:
229:                // Subtract 0.5
230:                syNum = 2 * syNum - syDenom;
231:                syDenom *= 2;
232:
233:                // Separate the x source coordinate into integer and fractional part
234:                int srcYInt = Rational.floor(syNum, syDenom);
235:                long srcYFrac = syNum % syDenom;
236:                if (srcYInt < 0) {
237:                    srcYFrac = syDenom + srcYFrac;
238:                }
239:
240:                // Normalize - Get a common denominator for the fracs of 
241:                // src and invScaleY
242:                long commonYDenom = syDenom * invScaleYRationalDenom;
243:                srcYFrac *= invScaleYRationalDenom;
244:                long newInvScaleYFrac = invScaleYFrac * syDenom;
245:
246:                // Precalculate the x positions and store them in an array.
247:                long sxNum = dx, sxDenom = 1;
248:
249:                // Subtract the X translation factor sx -= transX
250:                sxNum = sxNum * transXRationalDenom - transXRationalNum
251:                        * sxDenom;
252:                sxDenom *= transXRationalDenom;
253:
254:                // Add 0.5
255:                sxNum = 2 * sxNum + sxDenom;
256:                sxDenom *= 2;
257:
258:                // Multply by invScaleX
259:                sxNum *= invScaleXRationalNum;
260:                sxDenom *= invScaleXRationalDenom;
261:
262:                // Subtract 0.5
263:                sxNum = 2 * sxNum - sxDenom;
264:                sxDenom *= 2;
265:
266:                // Separate the x source coordinate into integer and fractional part
267:                int srcXInt = Rational.floor(sxNum, sxDenom);
268:                long srcXFrac = sxNum % sxDenom;
269:                if (srcXInt < 0) {
270:                    srcXFrac = sxDenom + srcXFrac;
271:                }
272:
273:                // Normalize - Get a common denominator for the fracs of 
274:                // src and invScaleX
275:                long commonXDenom = sxDenom * invScaleXRationalDenom;
276:                srcXFrac *= invScaleXRationalDenom;
277:                long newInvScaleXFrac = invScaleXFrac * sxDenom;
278:
279:                for (int i = 0; i < dwidth; i++) {
280:                    xpos[i] = (srcXInt - srcRectX) * srcPixelStride;
281:                    xfracvalues[i] = (int) (((float) srcXFrac / (float) commonXDenom) * one);
282:
283:                    // Move onto the next source pixel.
284:
285:                    // Add the integral part of invScaleX to the integral part
286:                    // of srcX
287:                    srcXInt += invScaleXInt;
288:
289:                    // Add the fractional part of invScaleX to the fractional part
290:                    // of srcX
291:                    srcXFrac += newInvScaleXFrac;
292:
293:                    // If the fractional part is now greater than equal to the
294:                    // denominator, divide so as to reduce the numerator to be less
295:                    // than the denominator and add the overflow to the integral part.
296:                    if (srcXFrac >= commonXDenom) {
297:                        srcXInt += 1;
298:                        srcXFrac -= commonXDenom;
299:                    }
300:                }
301:
302:                for (int i = 0; i < dheight; i++) {
303:
304:                    // Calculate the source position in the source data array.
305:                    ypos[i] = (srcYInt - srcRectY) * srcScanlineStride;
306:
307:                    // Calculate the yfrac value
308:                    yfracvalues[i] = (int) (((float) srcYFrac / (float) commonYDenom) * one);
309:
310:                    // Move onto the next source pixel.
311:
312:                    // Add the integral part of invScaleY to the integral part
313:                    // of srcY
314:                    srcYInt += invScaleYInt;
315:
316:                    // Add the fractional part of invScaleY to the fractional part
317:                    // of srcY
318:                    srcYFrac += newInvScaleYFrac;
319:
320:                    // If the fractional part is now greater than equal to the
321:                    // denominator, divide so as to reduce the numerator to be less
322:                    // than the denominator and add the overflow to the integral part.
323:                    if (srcYFrac >= commonYDenom) {
324:                        srcYInt += 1;
325:                        srcYFrac -= commonYDenom;
326:                    }
327:                }
328:            }
329:
330:            private void preComputePositionsFloat(Rectangle destRect,
331:                    int srcRectX, int srcRectY, int srcPixelStride,
332:                    int srcScanlineStride, int xpos[], int ypos[],
333:                    float xfracvaluesFloat[], float yfracvaluesFloat[]) {
334:
335:                int dwidth = destRect.width;
336:                int dheight = destRect.height;
337:
338:                // Loop variables based on the destination rectangle to be calculated.
339:                int dx = destRect.x;
340:                int dy = destRect.y;
341:
342:                long syNum = dy, syDenom = 1;
343:
344:                // Subtract the X translation factor sy -= transY
345:                syNum = syNum * transYRationalDenom - transYRationalNum
346:                        * syDenom;
347:                syDenom *= transYRationalDenom;
348:
349:                // Add 0.5
350:                syNum = 2 * syNum + syDenom;
351:                syDenom *= 2;
352:
353:                // Multply by invScaleX
354:                syNum *= invScaleYRationalNum;
355:                syDenom *= invScaleYRationalDenom;
356:
357:                // Subtract 0.5
358:                syNum = 2 * syNum - syDenom;
359:                syDenom *= 2;
360:
361:                // Separate the x source coordinate into integer and fractional part
362:                int srcYInt = Rational.floor(syNum, syDenom);
363:                long srcYFrac = syNum % syDenom;
364:                if (srcYInt < 0) {
365:                    srcYFrac = syDenom + srcYFrac;
366:                }
367:
368:                // Normalize - Get a common denominator for the fracs of 
369:                // src and invScaleY
370:                long commonYDenom = syDenom * invScaleYRationalDenom;
371:                srcYFrac *= invScaleYRationalDenom;
372:                long newInvScaleYFrac = invScaleYFrac * syDenom;
373:
374:                // Precalculate the x positions and store them in an array.
375:                long sxNum = dx, sxDenom = 1;
376:
377:                // Subtract the X translation factor sx -= transX
378:                sxNum = sxNum * transXRationalDenom - transXRationalNum
379:                        * sxDenom;
380:                sxDenom *= transXRationalDenom;
381:
382:                // Add 0.5
383:                sxNum = 2 * sxNum + sxDenom;
384:                sxDenom *= 2;
385:
386:                // Multply by invScaleX
387:                sxNum *= invScaleXRationalNum;
388:                sxDenom *= invScaleXRationalDenom;
389:
390:                // Subtract 0.5
391:                sxNum = 2 * sxNum - sxDenom;
392:                sxDenom *= 2;
393:
394:                // Separate the x source coordinate into integer and fractional part
395:                int srcXInt = Rational.floor(sxNum, sxDenom);
396:                long srcXFrac = sxNum % sxDenom;
397:                if (srcXInt < 0) {
398:                    srcXFrac = sxDenom + srcXFrac;
399:                }
400:
401:                // Normalize - Get a common denominator for the fracs of 
402:                // src and invScaleX
403:                long commonXDenom = sxDenom * invScaleXRationalDenom;
404:                srcXFrac *= invScaleXRationalDenom;
405:                long newInvScaleXFrac = invScaleXFrac * sxDenom;
406:
407:                for (int i = 0; i < dwidth; i++) {
408:
409:                    xpos[i] = (srcXInt - srcRectX) * srcPixelStride;
410:                    xfracvaluesFloat[i] = (float) srcXFrac
411:                            / (float) commonXDenom;
412:
413:                    // Move onto the next source pixel.
414:
415:                    // Add the integral part of invScaleX to the integral part
416:                    // of srcX
417:                    srcXInt += invScaleXInt;
418:
419:                    // Add the fractional part of invScaleX to the fractional part
420:                    // of srcX
421:                    srcXFrac += newInvScaleXFrac;
422:
423:                    // If the fractional part is now greater than equal to the
424:                    // denominator, divide so as to reduce the numerator to be less 
425:                    // than the denominator and add the overflow to the integral part.
426:                    if (srcXFrac >= commonXDenom) {
427:                        srcXInt += 1;
428:                        srcXFrac -= commonXDenom;
429:                    }
430:                }
431:
432:                for (int i = 0; i < dheight; i++) {
433:
434:                    // Calculate the source position in the source data array.
435:                    ypos[i] = (srcYInt - srcRectY) * srcScanlineStride;
436:
437:                    // Calculate the yfrac value
438:                    yfracvaluesFloat[i] = (float) srcYFrac
439:                            / (float) commonYDenom;
440:
441:                    // Move onto the next source pixel.
442:
443:                    // Add the integral part of invScaleY to the integral part
444:                    // of srcY
445:                    srcYInt += invScaleYInt;
446:
447:                    // Add the fractional part of invScaleY to the fractional part
448:                    // of srcY
449:                    srcYFrac += newInvScaleYFrac;
450:
451:                    // If the fractional part is now greater than equal to the
452:                    // denominator, divide so as to reduce the numerator to be less 
453:                    // than the denominator and add the overflow to the integral part.
454:                    if (srcYFrac >= commonYDenom) {
455:                        srcYInt += 1;
456:                        srcYFrac -= commonYDenom;
457:                    }
458:                }
459:
460:            }
461:
462:            private void byteLoop(RasterAccessor src, Rectangle dstRect,
463:                    RasterAccessor dst, int xpos[], int ypos[],
464:                    int xfracvalues[], int yfracvalues[]) {
465:
466:                int srcPixelStride = src.getPixelStride();
467:                int srcScanlineStride = src.getScanlineStride();
468:                int srcLastXDataPos = (src.getWidth() - 1) * srcPixelStride;
469:
470:                int dwidth = dstRect.width;
471:                int dheight = dstRect.height;
472:                int dnumBands = dst.getNumBands();
473:                byte dstDataArrays[][] = dst.getByteDataArrays();
474:                int dstBandOffsets[] = dst.getBandOffsets();
475:                int dstPixelStride = dst.getPixelStride();
476:                int dstScanlineStride = dst.getScanlineStride();
477:
478:                byte srcDataArrays[][] = src.getByteDataArrays();
479:                int bandOffsets[] = src.getBandOffsets();
480:
481:                int dstOffset = 0;
482:
483:                /* Four surrounding pixels are needed for Bilinear interpolation.
484:                 * If the dest pixel to be calculated is at (dx, dy) then the
485:                 * actual source pixel (sx, sy) required is (dx/scaleX, dy/scaleY).
486:                 * The four pixels that surround it are at the positions:
487:                 * s00 = src(sxlow, sylow)
488:                 * s01 = src(sxhigh, sylow)
489:                 * s10 = src(sxlow, syhigh)
490:                 * s11 = src(sxhigh, syhigh)
491:                 * where sxlow = Math.floor(sx), sxhigh = Math.ceil(sx)
492:                 * and   sylow = Math.floor(sy), syhigh = Math.ceil(sy)
493:                 *
494:                 * The value of the destination pixel can now be calculated as:
495:                 * s0 = (s01 - s00)*xfrac + s00;
496:                 * s1 = (s11 - s10)*xfrac + s10;
497:                 * dst(x,y) = (s1 - s0)*yfrac + s0;
498:                 */
499:
500:                int posylow, posyhigh, posxlow, posxhigh;
501:                int s00, s01, s10, s11;
502:
503:                // Precalculate the y positions and store them in an array.
504:                int xfrac, yfrac;
505:                int s, s0, s1;
506:
507:                // Putting band loop outside
508:                for (int k = 0; k < dnumBands; k++) {
509:                    byte dstData[] = dstDataArrays[k];
510:                    byte srcData[] = srcDataArrays[k];
511:                    int dstScanlineOffset = dstBandOffsets[k];
512:                    int bandOffset = bandOffsets[k];
513:                    for (int j = 0; j < dheight; j++) {
514:
515:                        int dstPixelOffset = dstScanlineOffset;
516:                        yfrac = yfracvalues[j];
517:                        posylow = ypos[j] + bandOffset;
518:                        posyhigh = posylow + srcScanlineStride;
519:
520:                        for (int i = 0; i < dwidth; i++) {
521:                            xfrac = xfracvalues[i];
522:                            posxlow = xpos[i];
523:                            posxhigh = posxlow + srcPixelStride;
524:
525:                            // Get the four surrounding pixel values
526:                            s00 = srcData[posxlow + posylow] & 0xff;
527:                            s01 = srcData[posxhigh + posylow] & 0xff;
528:                            s10 = srcData[posxlow + posyhigh] & 0xff;
529:                            s11 = srcData[posxhigh + posyhigh] & 0xff;
530:
531:                            // Perform the bilinear interpolation
532:                            s0 = (s01 - s00) * xfrac + (s00 << subsampleBits);
533:                            s1 = (s11 - s10) * xfrac + (s10 << subsampleBits);
534:                            s = ((s1 - s0) * yfrac + (s0 << subsampleBits) + round2) >> shift2;
535:
536:                            dstData[dstPixelOffset] = (byte) (s & 0xff);
537:                            dstPixelOffset += dstPixelStride;
538:                        }
539:                        dstScanlineOffset += dstScanlineStride;
540:
541:                    }
542:                }
543:            }
544:
545:            private void shortLoop(RasterAccessor src, Rectangle dstRect,
546:                    RasterAccessor dst, int xpos[], int ypos[],
547:                    int xfracvalues[], int yfracvalues[]) {
548:
549:                int srcPixelStride = src.getPixelStride();
550:                int srcScanlineStride = src.getScanlineStride();
551:                int srcLastXDataPos = (src.getWidth() - 1) * srcPixelStride;
552:
553:                int dwidth = dstRect.width;
554:                int dheight = dstRect.height;
555:                int dnumBands = dst.getNumBands();
556:                short dstDataArrays[][] = dst.getShortDataArrays();
557:                int dstBandOffsets[] = dst.getBandOffsets();
558:                int dstPixelStride = dst.getPixelStride();
559:                int dstScanlineStride = dst.getScanlineStride();
560:
561:                short srcDataArrays[][] = src.getShortDataArrays();
562:                int bandOffsets[] = src.getBandOffsets();
563:
564:                int dstOffset = 0;
565:                int posylow, posyhigh, posxlow, posxhigh;
566:                int s00, s01, s10, s11, s0, s1, s;
567:                int xfrac, yfrac;
568:
569:                // Putting band loop outside
570:                for (int k = 0; k < dnumBands; k++) {
571:                    short dstData[] = dstDataArrays[k];
572:                    short srcData[] = srcDataArrays[k];
573:                    int dstScanlineOffset = dstBandOffsets[k];
574:                    int bandOffset = bandOffsets[k];
575:                    for (int j = 0; j < dheight; j++) {
576:                        int dstPixelOffset = dstScanlineOffset;
577:                        yfrac = yfracvalues[j];
578:                        posylow = ypos[j] + bandOffset;
579:                        posyhigh = posylow + srcScanlineStride;
580:
581:                        for (int i = 0; i < dwidth; i++) {
582:                            xfrac = xfracvalues[i];
583:                            posxlow = xpos[i];
584:                            posxhigh = posxlow + srcPixelStride;
585:
586:                            // Get the four surrounding pixel values
587:                            s00 = srcData[posxlow + posylow];
588:                            s01 = srcData[posxhigh + posylow];
589:                            s10 = srcData[posxlow + posyhigh];
590:                            s11 = srcData[posxhigh + posyhigh];
591:
592:                            // Perform the bilinear interpolation
593:                            s0 = (s01 - s00) * xfrac + (s00 << subsampleBits);
594:                            s1 = (s11 - s10) * xfrac + (s10 << subsampleBits);
595:                            s = ((s1 - s0) * yfrac + (s0 << subsampleBits) + round2) >> shift2;
596:
597:                            dstData[dstPixelOffset] = (short) s;
598:                            dstPixelOffset += dstPixelStride;
599:                        }
600:                        dstScanlineOffset += dstScanlineStride;
601:                    }
602:                }
603:            }
604:
605:            private void ushortLoop(RasterAccessor src, Rectangle dstRect,
606:                    RasterAccessor dst, int xpos[], int ypos[],
607:                    int xfracvalues[], int yfracvalues[]) {
608:
609:                int srcPixelStride = src.getPixelStride();
610:                int srcScanlineStride = src.getScanlineStride();
611:                int srcLastXDataPos = (src.getWidth() - 1) * srcPixelStride;
612:
613:                int dwidth = dstRect.width;
614:                int dheight = dstRect.height;
615:                int dnumBands = dst.getNumBands();
616:                short dstDataArrays[][] = dst.getShortDataArrays();
617:                int dstBandOffsets[] = dst.getBandOffsets();
618:                int dstPixelStride = dst.getPixelStride();
619:                int dstScanlineStride = dst.getScanlineStride();
620:
621:                short srcDataArrays[][] = src.getShortDataArrays();
622:                int bandOffsets[] = src.getBandOffsets();
623:
624:                int dstOffset = 0;
625:                int posylow, posyhigh, posxlow, posxhigh;
626:                int s00, s01, s10, s11, s0, s1, s;
627:                int xfrac, yfrac;
628:
629:                // Putting band loop outside
630:                for (int k = 0; k < dnumBands; k++) {
631:                    short dstData[] = dstDataArrays[k];
632:                    short srcData[] = srcDataArrays[k];
633:                    int dstScanlineOffset = dstBandOffsets[k];
634:                    int bandOffset = bandOffsets[k];
635:                    for (int j = 0; j < dheight; j++) {
636:                        int dstPixelOffset = dstScanlineOffset;
637:                        yfrac = yfracvalues[j];
638:                        posylow = ypos[j] + bandOffset;
639:                        posyhigh = posylow + srcScanlineStride;
640:
641:                        for (int i = 0; i < dwidth; i++) {
642:                            xfrac = xfracvalues[i];
643:                            posxlow = xpos[i];
644:                            posxhigh = posxlow + srcPixelStride;
645:
646:                            // Get the four surrounding pixel values
647:                            s00 = srcData[posxlow + posylow] & 0xffff;
648:                            s01 = srcData[posxhigh + posylow] & 0xffff;
649:                            s10 = srcData[posxlow + posyhigh] & 0xffff;
650:                            s11 = srcData[posxhigh + posyhigh] & 0xffff;
651:
652:                            // Perform the bilinear interpolation
653:                            s0 = (s01 - s00) * xfrac + (s00 << subsampleBits);
654:                            s1 = (s11 - s10) * xfrac + (s10 << subsampleBits);
655:                            s = ((s1 - s0) * yfrac + (s0 << subsampleBits) + round2) >> shift2;
656:
657:                            dstData[dstPixelOffset] = (short) (s & 0xffff);
658:                            dstPixelOffset += dstPixelStride;
659:                        }
660:                        dstScanlineOffset += dstScanlineStride;
661:                    }
662:                }
663:            }
664:
665:            // identical to byteLoops, except datatypes have changed.  clumsy,
666:            // but there's no other way in Java
667:            private void intLoop(RasterAccessor src, Rectangle dstRect,
668:                    RasterAccessor dst, int xpos[], int ypos[],
669:                    int xfracvalues[], int yfracvalues[]) {
670:
671:                int srcPixelStride = src.getPixelStride();
672:                int srcScanlineStride = src.getScanlineStride();
673:                int srcLastXDataPos = (src.getWidth() - 1) * srcPixelStride;
674:
675:                int dwidth = dstRect.width;
676:                int dheight = dstRect.height;
677:                int dnumBands = dst.getNumBands();
678:                int dstDataArrays[][] = dst.getIntDataArrays();
679:                int dstBandOffsets[] = dst.getBandOffsets();
680:                int dstPixelStride = dst.getPixelStride();
681:                int dstScanlineStride = dst.getScanlineStride();
682:
683:                int srcDataArrays[][] = src.getIntDataArrays();
684:                int bandOffsets[] = src.getBandOffsets();
685:
686:                int dstOffset = 0;
687:                int posylow, posyhigh, posxlow, posxhigh;
688:                int s00, s10, s01, s11;
689:                long s0, s1;
690:                int xfrac, yfrac;
691:                int shift = 29 - subsampleBits;
692:
693:                // Putting band loop outside
694:                for (int k = 0; k < dnumBands; k++) {
695:                    int dstData[] = dstDataArrays[k];
696:                    int srcData[] = srcDataArrays[k];
697:                    int dstScanlineOffset = dstBandOffsets[k];
698:                    int bandOffset = bandOffsets[k];
699:                    for (int j = 0; j < dheight; j++) {
700:                        int dstPixelOffset = dstScanlineOffset;
701:                        yfrac = yfracvalues[j];
702:                        posylow = ypos[j] + bandOffset;
703:                        posyhigh = posylow + srcScanlineStride;
704:
705:                        for (int i = 0; i < dwidth; i++) {
706:                            xfrac = xfracvalues[i];
707:                            posxlow = xpos[i];
708:                            posxhigh = posxlow + srcPixelStride;
709:
710:                            // Get the four surrounding pixel values
711:                            s00 = srcData[posxlow + posylow];
712:                            s01 = srcData[posxhigh + posylow];
713:                            s10 = srcData[posxlow + posyhigh];
714:                            s11 = srcData[posxhigh + posyhigh];
715:
716:                            // Perform the bilinear interpolation
717:                            if ((s00 | s10) >>> shift == 0) {
718:                                if ((s01 | s11) >>> shift == 0) {
719:                                    s0 = (s01 - s00) * xfrac
720:                                            + (s00 << subsampleBits);
721:                                    s1 = (s11 - s10) * xfrac
722:                                            + (s10 << subsampleBits);
723:                                } else {
724:                                    s0 = ((long) s01 - s00) * xfrac
725:                                            + (s00 << subsampleBits);
726:                                    s1 = ((long) s11 - s10) * xfrac
727:                                            + (s10 << subsampleBits);
728:                                }
729:                            } else {
730:                                s0 = ((long) s01 - s00) * xfrac
731:                                        + ((long) s00 << subsampleBits);
732:                                s1 = ((long) s11 - s10) * xfrac
733:                                        + ((long) s10 << subsampleBits);
734:                            }
735:
736:                            dstData[dstPixelOffset] = (int) (((s1 - s0) * yfrac
737:                                    + (s0 << subsampleBits) + round2) >> shift2);
738:
739:                            dstPixelOffset += dstPixelStride;
740:                        }
741:                        dstScanlineOffset += dstScanlineStride;
742:                    }
743:                }
744:            }
745:
746:            // Interpolation for floating point samples done as specified by the
747:            // following formula:
748:            //        float s0 = (s01 - s00)*xfrac + s00;
749:            //        float s1 = (s11 - s10)*xfrac + s10;
750:            //        return (s1 - s0)*yfrac + s0;
751:            // Note that xfrac, yfrac are in the range [0.0F, 1.0F)
752:
753:            private void floatLoop(RasterAccessor src, Rectangle dstRect,
754:                    RasterAccessor dst, int xpos[], int ypos[],
755:                    float xfracvaluesFloat[], float yfracvaluesFloat[]) {
756:
757:                int srcPixelStride = src.getPixelStride();
758:                int srcScanlineStride = src.getScanlineStride();
759:                int srcLastXDataPos = (src.getWidth() - 1) * srcPixelStride;
760:
761:                int dwidth = dstRect.width;
762:                int dheight = dstRect.height;
763:                int dnumBands = dst.getNumBands();
764:                float dstDataArrays[][] = dst.getFloatDataArrays();
765:                int dstBandOffsets[] = dst.getBandOffsets();
766:                int dstPixelStride = dst.getPixelStride();
767:                int dstScanlineStride = dst.getScanlineStride();
768:
769:                float srcDataArrays[][] = src.getFloatDataArrays();
770:                int bandOffsets[] = src.getBandOffsets();
771:
772:                float s00, s01, s10, s11;
773:                float s0, s1;
774:                float xfrac, yfrac;
775:                int dstOffset = 0;
776:                int posylow, posyhigh, posxlow, posxhigh;
777:
778:                // Putting band loop outside
779:                for (int k = 0; k < dnumBands; k++) {
780:                    float dstData[] = dstDataArrays[k];
781:                    float srcData[] = srcDataArrays[k];
782:                    int dstScanlineOffset = dstBandOffsets[k];
783:                    int bandOffset = bandOffsets[k];
784:                    for (int j = 0; j < dheight; j++) {
785:                        int dstPixelOffset = dstScanlineOffset;
786:                        yfrac = yfracvaluesFloat[j];
787:                        posylow = ypos[j] + bandOffset;
788:                        posyhigh = posylow + srcScanlineStride;
789:
790:                        for (int i = 0; i < dwidth; i++) {
791:                            xfrac = xfracvaluesFloat[i];
792:                            posxlow = xpos[i];
793:                            posxhigh = posxlow + srcPixelStride;
794:
795:                            // Get the four surrounding pixel values
796:                            s00 = srcData[posxlow + posylow];
797:                            s01 = srcData[posxhigh + posylow];
798:                            s10 = srcData[posxlow + posyhigh];
799:                            s11 = srcData[posxhigh + posyhigh];
800:
801:                            // Perform the bilinear interpolation
802:                            s0 = (s01 - s00) * xfrac + s00;
803:                            s1 = (s11 - s10) * xfrac + s10;
804:
805:                            dstData[dstPixelOffset] = (s1 - s0) * yfrac + s0;
806:
807:                            dstPixelOffset += dstPixelStride;
808:                        }
809:                        dstScanlineOffset += dstScanlineStride;
810:                    }
811:                }
812:            }
813:
814:            private void doubleLoop(RasterAccessor src, Rectangle dstRect,
815:                    RasterAccessor dst, int xpos[], int ypos[],
816:                    float xfracvaluesFloat[], float yfracvaluesFloat[]) {
817:
818:                int srcPixelStride = src.getPixelStride();
819:                int srcScanlineStride = src.getScanlineStride();
820:                int srcLastXDataPos = (src.getWidth() - 1) * srcPixelStride;
821:
822:                int dwidth = dstRect.width;
823:                int dheight = dstRect.height;
824:                int dnumBands = dst.getNumBands();
825:                double dstDataArrays[][] = dst.getDoubleDataArrays();
826:                int dstBandOffsets[] = dst.getBandOffsets();
827:                int dstPixelStride = dst.getPixelStride();
828:                int dstScanlineStride = dst.getScanlineStride();
829:
830:                double srcDataArrays[][] = src.getDoubleDataArrays();
831:                int bandOffsets[] = src.getBandOffsets();
832:
833:                double s00, s01, s10, s11;
834:                double s0, s1;
835:                double xfrac, yfrac;
836:                int dstOffset = 0;
837:                int posylow, posyhigh, posxlow, posxhigh;
838:
839:                // Putting band loop outside
840:                for (int k = 0; k < dnumBands; k++) {
841:                    double dstData[] = dstDataArrays[k];
842:                    double srcData[] = srcDataArrays[k];
843:                    int dstScanlineOffset = dstBandOffsets[k];
844:                    int bandOffset = bandOffsets[k];
845:                    for (int j = 0; j < dheight; j++) {
846:                        int dstPixelOffset = dstScanlineOffset;
847:                        yfrac = yfracvaluesFloat[j];
848:                        posylow = ypos[j] + bandOffset;
849:                        posyhigh = posylow + srcScanlineStride;
850:
851:                        for (int i = 0; i < dwidth; i++) {
852:                            xfrac = xfracvaluesFloat[i];
853:                            posxlow = xpos[i];
854:                            posxhigh = posxlow + srcPixelStride;
855:
856:                            // Get the four surrounding pixel values
857:                            s00 = srcData[posxlow + posylow];
858:                            s01 = srcData[posxhigh + posylow];
859:                            s10 = srcData[posxlow + posyhigh];
860:                            s11 = srcData[posxhigh + posyhigh];
861:
862:                            // Perform the bilinear interpolation
863:                            s0 = (s01 - s00) * xfrac + s00;
864:                            s1 = (s11 - s10) * xfrac + s10;
865:
866:                            dstData[dstPixelOffset] = (s1 - s0) * yfrac + s0;
867:
868:                            dstPixelOffset += dstPixelStride;
869:                        }
870:                        dstScanlineOffset += dstScanlineStride;
871:                    }
872:                }
873:            }
874:
875:            //     public static OpImage createTestImage(OpImageTester oit) {
876:            //         Interpolation interp =
877:            //             Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
878:            //         return new ScaleBilinearOpImage(oit.getSource(), null, null,
879:            //                                         new ImageLayout(oit.getSource()),
880:            //                                         2.5F, 2.5F, 0.0F, 0.0F,
881:            //                                         interp);
882:            //     }
883:
884:            //     public static void main(String args[]) {
885:            //         String classname = "com.sun.media.jai.opimage.ScaleBilinearOpImage";
886:            // 	OpImageTester.performDiagnostics(classname,args);
887:            // 	System.exit(1);
888:
889:            //         System.out.println("ScaleOpImage Test");
890:            //         ImageLayout layout;
891:            //         OpImage src, dst;
892:            //         Rectangle rect = new Rectangle(0, 0, 5, 5);
893:
894:            // 	InterpolationBilinear interp = new InterpolationBilinear();
895:
896:            //         System.out.println("1. PixelInterleaved short 3-band");
897:            //         layout = OpImageTester.createImageLayout(
898:            //             0, 0, 200, 200, 0, 0, 64, 64, DataBuffer.TYPE_SHORT, 3, false);
899:            //         src = OpImageTester.createRandomOpImage(layout);
900:            //         dst = new ScaleBilinearOpImage(src, null, null, null,
901:            //                                        2.0F, 2.0F, 0.0F, 0.0F, interp);
902:            //         OpImageTester.testOpImage(dst, rect);
903:            //         OpImageTester.timeOpImage(dst, 10);
904:
905:            //         System.out.println("2. PixelInterleaved ushort 3-band");
906:            //         layout = OpImageTester.createImageLayout(
907:            //             0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_USHORT, 3, false);
908:            //         src = OpImageTester.createRandomOpImage(layout);
909:            //         dst = new ScaleBilinearOpImage(src, null, null, null,
910:            //                                        2.0F, 2.0F, 0.0F, 0.0F, interp);
911:            //         OpImageTester.testOpImage(dst, rect);
912:            //         OpImageTester.timeOpImage(dst, 10);
913:
914:            //         System.out.println("3. PixelInterleaved float 3-band");
915:            //         layout = OpImageTester.createImageLayout(0, 0, 512, 512, 0, 0, 200, 200,
916:            // 						 DataBuffer.TYPE_FLOAT, 3,
917:            // 						 false);
918:            //         src = OpImageTester.createRandomOpImage(layout);
919:            //         dst = new ScaleBilinearOpImage(src, null, null, null,
920:            //                                        2.0F, 2.0F, 0.0F, 0.0F, interp);
921:            //         OpImageTester.testOpImage(dst, rect);
922:            //         OpImageTester.timeOpImage(dst, 10);
923:
924:            //         System.out.println("4. PixelInterleaved double 3-band");
925:            //         layout = OpImageTester.createImageLayout(0, 0, 512, 512,
926:            //                                                  0, 0, 200, 200,
927:            // 						 DataBuffer.TYPE_DOUBLE, 3,
928:            // 						 false);
929:            //         src = OpImageTester.createRandomOpImage(layout);
930:            //         dst = new ScaleBilinearOpImage(src, null, null, null,
931:            //                                        2.0F, 2.0F, 0.0F, 0.0F, interp);
932:            //         OpImageTester.testOpImage(dst, rect);
933:            //         OpImageTester.timeOpImage(dst, 10);
934:            //     }    
935:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.