Changeset 19088 in josm


Ignore:
Timestamp:
2024-05-29T17:21:56+02:00 (7 months ago)
Author:
taylor.smock
Message:

See #22590, #23055, and #23697: Add additional information to bug report to (hopefully) figure out what is going on

This additionally reduces duplicated code, where the duplicated code differed
only in a few variables.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/util/imagery/CameraPlane.java

    r18877 r19088  
    1515
    1616import jakarta.annotation.Nullable;
     17import org.openstreetmap.josm.tools.bugreport.BugReport;
    1718
    1819/**
     
    266267        // Faster mapping
    267268        if (sourceBuffer.getDataType() == DataBuffer.TYPE_BYTE && targetBuffer.getDataType() == DataBuffer.TYPE_BYTE) {
    268             byte[] sourceImageBuffer = ((DataBufferByte) sourceImage.getRaster().getDataBuffer()).getData();
    269             byte[] targetImageBuffer = ((DataBufferByte) targetImage.getRaster().getDataBuffer()).getData();
    270             final boolean sourceHasAlphaChannel = sourceImage.getAlphaRaster() != null;
    271             final boolean targetHasAlphaChannel = targetImage.getAlphaRaster() != null;
    272             if (sourceHasAlphaChannel && targetHasAlphaChannel) {
    273                 final int pixelLength = 4;
    274                 IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
    275                         .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
    276                             final Point2D.Double p = mapPoint(x, y);
    277                             int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
    278                             int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
    279                             int sourceOffset = (ty * sourceImage.getWidth() + tx) * pixelLength;
    280                             int targetOffset = (y * targetImage.getWidth() + x) * pixelLength;
    281                             byte a = sourceImageBuffer[sourceOffset];
    282                             byte b = sourceImageBuffer[sourceOffset + 1];
    283                             byte g = sourceImageBuffer[sourceOffset + 2];
    284                             byte r = sourceImageBuffer[sourceOffset + 3];
    285                             targetImageBuffer[targetOffset] = a;
    286                             targetImageBuffer[targetOffset + 1] = b;
    287                             targetImageBuffer[targetOffset + 2] = g;
    288                             targetImageBuffer[targetOffset + 3] = r;
    289                         }));
    290             } else if (sourceHasAlphaChannel) {
    291                 final int sourcePixelLength = 4;
    292                 final int targetPixelLength = 3;
    293                 IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
    294                         .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
    295                             final Point2D.Double p = mapPoint(x, y);
    296                             int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
    297                             int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
    298                             int sourceOffset = (ty * sourceImage.getWidth() + tx) * sourcePixelLength;
    299                             int targetOffset = (y * targetImage.getWidth() + x) * targetPixelLength;
    300                             //byte a = sourceImageBuffer[sourceOffset];
    301                             byte b = sourceImageBuffer[sourceOffset + 1];
    302                             byte g = sourceImageBuffer[sourceOffset + 2];
    303                             byte r = sourceImageBuffer[sourceOffset + 3];
    304                             targetImageBuffer[targetOffset] = b;
    305                             targetImageBuffer[targetOffset + 1] = g;
    306                             targetImageBuffer[targetOffset + 2] = r;
    307 
    308                         }));
    309             } else if (targetHasAlphaChannel) {
    310                 final int sourcePixelLength = 3;
    311                 final int targetPixelLength = 4;
    312                 IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
    313                         .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
    314                             final Point2D.Double p = mapPoint(x, y);
    315                             int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
    316                             int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
    317                             int sourceOffset = (ty * sourceImage.getWidth() + tx) * sourcePixelLength;
    318                             int targetOffset = (y * targetImage.getWidth() + x) * targetPixelLength;
    319                             byte a = (byte) 255;
    320                             byte b = sourceImageBuffer[sourceOffset];
    321                             byte g = sourceImageBuffer[sourceOffset + 1];
    322                             byte r = sourceImageBuffer[sourceOffset + 2];
    323                             targetImageBuffer[targetOffset] = a;
    324                             targetImageBuffer[targetOffset + 1] = b;
    325                             targetImageBuffer[targetOffset + 2] = g;
    326                             targetImageBuffer[targetOffset + 3] = r;
    327 
    328                         }));
    329             } else {
    330                 final int pixelLength = 3;
    331                 IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
    332                         .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
    333                             final Point2D.Double p = mapPoint(x, y);
    334                             int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
    335                             int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
    336                             int sourceOffset = (ty * sourceImage.getWidth() + tx) * pixelLength;
    337                             int targetOffset = (y * targetImage.getWidth() + x) * pixelLength;
    338                             byte b = sourceImageBuffer[sourceOffset];
    339                             byte g = sourceImageBuffer[sourceOffset + 1];
    340                             byte r = sourceImageBuffer[sourceOffset + 2];
    341                             targetImageBuffer[targetOffset] = b;
    342                             targetImageBuffer[targetOffset + 1] = g;
    343                             targetImageBuffer[targetOffset + 2] = r;
    344                         }));
    345             }
     269            commonFastByteMapping(sourceImage, targetImage, visibleRect);
    346270        } else if (sourceBuffer.getDataType() == DataBuffer.TYPE_INT
    347271                && targetBuffer.getDataType() == DataBuffer.TYPE_INT) {
     
    377301    }
    378302
     303    private void commonFastByteMapping(BufferedImage sourceImage, BufferedImage targetImage, Rectangle visibleRect) {
     304        final byte[] sourceImageBuffer = ((DataBufferByte) sourceImage.getRaster().getDataBuffer()).getData();
     305        final byte[] targetImageBuffer = ((DataBufferByte) targetImage.getRaster().getDataBuffer()).getData();
     306        final boolean sourceHasAlphaChannel = sourceImage.getAlphaRaster() != null;
     307        final boolean targetHasAlphaChannel = targetImage.getAlphaRaster() != null;
     308        final int sourcePixelLength = sourceHasAlphaChannel ? 4 : 3;
     309        final int targetPixelLength = targetHasAlphaChannel ? 4 : 3;
     310        final int addSourceAlpha = sourceHasAlphaChannel ? 1 : 0;
     311        final int addTargetAlpha = targetHasAlphaChannel ? 1 : 0;
     312        IntStream.range(visibleRect.y, visibleRect.y + visibleRect.height).parallel()
     313                .forEach(y -> IntStream.range(visibleRect.x, visibleRect.x + visibleRect.width).forEach(x -> {
     314                    final Point2D.Double p = mapPoint(x, y);
     315                    int tx = ((int) (p.x * (sourceImage.getWidth() - 1)));
     316                    int ty = ((int) (p.y * (sourceImage.getHeight() - 1)));
     317                    int sourceOffset = (ty * sourceImage.getWidth() + tx) * sourcePixelLength;
     318                    int targetOffset = (y * targetImage.getWidth() + x) * targetPixelLength;
     319                    try {
     320                        // Alpha, if present
     321                        if (targetHasAlphaChannel) {
     322                            byte a = sourceHasAlphaChannel ? sourceImageBuffer[sourceOffset] : (byte) 255;
     323                            targetImageBuffer[targetOffset] = a;
     324                        }
     325                        // Blue
     326                        targetImageBuffer[targetOffset + addTargetAlpha] = sourceImageBuffer[sourceOffset + addSourceAlpha];
     327                        // Green
     328                        targetImageBuffer[targetOffset + addTargetAlpha + 1] = sourceImageBuffer[sourceOffset + addSourceAlpha + 1];
     329                        // Red
     330                        targetImageBuffer[targetOffset + addTargetAlpha + 2] = sourceImageBuffer[sourceOffset + addSourceAlpha + 2];
     331                    } catch (ArrayIndexOutOfBoundsException aioobe) {
     332                        // For debugging #22590, #23055, and #23697
     333                        throw BugReport.intercept(aioobe)
     334                                .put("visibleRect", visibleRect)
     335                                .put("sourceImageBuffer", sourceImageBuffer.length)
     336                                .put("targetImageBuffer", targetImageBuffer.length)
     337                                .put("sourceHasAlphaChannel", sourceHasAlphaChannel)
     338                                .put("targetHasAlphaChannel", targetHasAlphaChannel);
     339                    }
     340                }));
     341    }
     342
    379343    /**
    380344     * Map a real point to the displayed point. This method uses cached vectors.
Note: See TracChangeset for help on using the changeset viewer.