Changeset 18398 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2022-03-13T13:34:22+01:00 (3 years ago)
Author:
stoecker
Message:

fix #21693 - patch by GhostFoxSledgehammer - performance optimizations with image display

Location:
trunk/src/org/openstreetmap/josm/gui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/viewers/projections/Equirectangular.java

    r18263 r18398  
    4141            currentOffscreenImage = this.offscreenImage;
    4242        }
    43         currentCameraPlane.mapping(image, currentOffscreenImage);
     43        currentCameraPlane.mapping(image, currentOffscreenImage, visibleRect);
    4444        if (target == null) {
    4545            target = new Rectangle(0, 0, currentOffscreenImage.getWidth(null), currentOffscreenImage.getHeight(null));
  • trunk/src/org/openstreetmap/josm/gui/util/imagery/CameraPlane.java

    r18256 r18398  
    33
    44import java.awt.Point;
     5import java.awt.Rectangle;
    56import java.awt.geom.Point2D;
    67import java.awt.image.BufferedImage;
    78import java.awt.image.DataBuffer;
     9import java.awt.image.DataBufferByte;
    810import java.awt.image.DataBufferDouble;
    911import java.awt.image.DataBufferInt;
     
    250252    }
    251253
    252     public void mapping(BufferedImage sourceImage, BufferedImage targetImage) {
     254    /** Maps a panoramic view of sourceImage into targetImage based on current configuration of Camera Plane
     255     * @param sourceImage The image to paint
     256     * @param targetImage The target image
     257     * @param visibleRect The part of target image which will be visible
     258     */
     259    public void mapping(BufferedImage sourceImage, BufferedImage targetImage, Rectangle visibleRect) {
    253260        DataBuffer sourceBuffer = sourceImage.getRaster().getDataBuffer();
    254261        DataBuffer targetBuffer = targetImage.getRaster().getDataBuffer();
    255262        // Faster mapping
    256         if (sourceBuffer.getDataType() == DataBuffer.TYPE_INT && targetBuffer.getDataType() == DataBuffer.TYPE_INT) {
     263        if (sourceBuffer.getDataType() == DataBuffer.TYPE_BYTE && targetBuffer.getDataType() == DataBuffer.TYPE_BYTE) {
     264            byte[] sourceImageBuffer = ((DataBufferByte) sourceImage.getRaster().getDataBuffer()).getData();
     265            byte[] targetImageBuffer = ((DataBufferByte) targetImage.getRaster().getDataBuffer()).getData();
     266            final boolean sourceHasAlphaChannel = sourceImage.getAlphaRaster() != null;
     267            final boolean targetHasAlphaChannel = targetImage.getAlphaRaster() != null;
     268            if (sourceHasAlphaChannel && targetHasAlphaChannel) {
     269                final int pixelLength = 4;
     270                IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
     271                        .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
     272                            final Point2D.Double p = mapPoint(x, y);
     273                            int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
     274                            int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
     275                            int sourceOffset = (ty * sourceImage.getWidth() + tx) * pixelLength;
     276                            int targetOffset = (y * targetImage.getWidth() + x) * pixelLength;
     277                            byte a = sourceImageBuffer[sourceOffset];
     278                            byte b = sourceImageBuffer[sourceOffset + 1];
     279                            byte g = sourceImageBuffer[sourceOffset + 2];
     280                            byte r = sourceImageBuffer[sourceOffset + 3];
     281                            targetImageBuffer[targetOffset] = a;
     282                            targetImageBuffer[targetOffset + 1] = b;
     283                            targetImageBuffer[targetOffset + 2] = g;
     284                            targetImageBuffer[targetOffset + 3] = r;
     285                        }));
     286            } else if (sourceHasAlphaChannel) {
     287                final int sourcePixelLength = 4;
     288                final int targetPixelLength = 3;
     289                IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
     290                        .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
     291                            final Point2D.Double p = mapPoint(x, y);
     292                            int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
     293                            int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
     294                            int sourceOffset = (ty * sourceImage.getWidth() + tx) * sourcePixelLength;
     295                            int targetOffset = (y * targetImage.getWidth() + x) * targetPixelLength;
     296                            //byte a = sourceImageBuffer[sourceOffset];
     297                            byte b = sourceImageBuffer[sourceOffset + 1];
     298                            byte g = sourceImageBuffer[sourceOffset + 2];
     299                            byte r = sourceImageBuffer[sourceOffset + 3];
     300                            targetImageBuffer[targetOffset] = b;
     301                            targetImageBuffer[targetOffset + 1] = g;
     302                            targetImageBuffer[targetOffset + 2] = r;
     303
     304                        }));
     305            } else if (targetHasAlphaChannel) {
     306                final int sourcePixelLength = 3;
     307                final int targetPixelLength = 4;
     308                IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
     309                        .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
     310                            final Point2D.Double p = mapPoint(x, y);
     311                            int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
     312                            int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
     313                            int sourceOffset = (ty * sourceImage.getWidth() + tx) * sourcePixelLength;
     314                            int targetOffset = (y * targetImage.getWidth() + x) * targetPixelLength;
     315                            byte a = (byte) 255;
     316                            byte b = sourceImageBuffer[sourceOffset];
     317                            byte g = sourceImageBuffer[sourceOffset + 1];
     318                            byte r = sourceImageBuffer[sourceOffset + 2];
     319                            targetImageBuffer[targetOffset] = a;
     320                            targetImageBuffer[targetOffset + 1] = b;
     321                            targetImageBuffer[targetOffset + 2] = g;
     322                            targetImageBuffer[targetOffset + 3] = r;
     323
     324                        }));
     325            } else {
     326                final int pixelLength = 3;
     327                IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
     328                        .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
     329                            final Point2D.Double p = mapPoint(x, y);
     330                            int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
     331                            int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
     332                            int sourceOffset = (ty * sourceImage.getWidth() + tx) * pixelLength;
     333                            int targetOffset = (y * targetImage.getWidth() + x) * pixelLength;
     334                            byte b = sourceImageBuffer[sourceOffset];
     335                            byte g = sourceImageBuffer[sourceOffset + 1];
     336                            byte r = sourceImageBuffer[sourceOffset + 2];
     337                            targetImageBuffer[targetOffset] = b;
     338                            targetImageBuffer[targetOffset + 1] = g;
     339                            targetImageBuffer[targetOffset + 2] = r;
     340                        }));
     341            }
     342        } else if (sourceBuffer.getDataType() == DataBuffer.TYPE_INT
     343                && targetBuffer.getDataType() == DataBuffer.TYPE_INT) {
    257344            int[] sourceImageBuffer = ((DataBufferInt) sourceImage.getRaster().getDataBuffer()).getData();
    258345            int[] targetImageBuffer = ((DataBufferInt) targetImage.getRaster().getDataBuffer()).getData();
    259             IntStream.range(0, targetImage.getHeight()).parallel()
    260                     .forEach(y -> IntStream.range(0, targetImage.getWidth()).forEach(x -> {
     346            IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
     347                    .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
    261348                        final Point2D.Double p = mapPoint(x, y);
    262349                        int tx = (int) (p.x * (sourceImage.getWidth() - 1));
     
    268355            double[] sourceImageBuffer = ((DataBufferDouble) sourceImage.getRaster().getDataBuffer()).getData();
    269356            double[] targetImageBuffer = ((DataBufferDouble) targetImage.getRaster().getDataBuffer()).getData();
    270             IntStream.range(0, targetImage.getHeight()).parallel()
    271                     .forEach(y -> IntStream.range(0, targetImage.getWidth()).forEach(x -> {
     357            IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
     358                    .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
    272359                        final Point2D.Double p = mapPoint(x, y);
    273360                        int tx = (int) (p.x * (sourceImage.getWidth() - 1));
     
    277364                    }));
    278365        } else {
    279             IntStream.range(0, targetImage.getHeight()).parallel()
    280                 .forEach(y -> IntStream.range(0, targetImage.getWidth()).parallel().forEach(x -> {
     366            IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
     367                .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).parallel().forEach(x -> {
    281368                    final Point2D.Double p = mapPoint(x, y);
    282369                    targetImage.setRGB(x, y, sourceImage.getRGB((int) (p.x * (sourceImage.getWidth() - 1)),
Note: See TracChangeset for help on using the changeset viewer.