22package org .openstreetmap .josm .gui .util .imagery ;
33
44import java .awt .Point ;
5+ import java .awt .Rectangle ;
56import java .awt .geom .Point2D ;
67import java .awt .image .BufferedImage ;
78import java .awt .image .DataBuffer ;
9+ import java .awt .image .DataBufferByte ;
810import java .awt .image .DataBufferDouble ;
911import java .awt .image .DataBufferInt ;
1012import java .util .stream .IntStream ;
@@ -249,15 +251,100 @@ private Vector3D rotate(final Vector3D vec) {
249251 return new Vector3D (vecX , YAW_DIRECTION * vecY , vecZ );
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 ));
263350 int ty = (int ) (p .y * (sourceImage .getHeight () - 1 ));
@@ -267,17 +354,17 @@ public void mapping(BufferedImage sourceImage, BufferedImage targetImage) {
267354 } else if (sourceBuffer .getDataType () == DataBuffer .TYPE_DOUBLE && targetBuffer .getDataType () == DataBuffer .TYPE_DOUBLE ) {
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 ));
274361 int ty = (int ) (p .y * (sourceImage .getHeight () - 1 ));
275362 double color = sourceImageBuffer [ty * sourceImage .getWidth () + tx ];
276363 targetImageBuffer [y * targetImage .getWidth () + x ] = color ;
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 )),
283370 (int ) (p .y * (sourceImage .getHeight () - 1 ))));
0 commit comments