From 68709912bf146c9989832811997003b09805d8f8 Mon Sep 17 00:00:00 2001 From: Marcel Reutegger Date: Sun, 11 Aug 2024 17:26:42 +0200 Subject: [PATCH 1/2] Use MutableInteger as context for LASreadItem.read() and LASreadItemCompressed.init() --- .../mreutegg/laszip4j/laszip/LASreadItem.java | 2 +- .../laszip/LASreadItemCompressed.java | 2 +- .../LASreadItemCompressed_BYTE14_v3.java | 14 ++++---- .../laszip/LASreadItemCompressed_BYTE_v1.java | 4 +-- .../laszip/LASreadItemCompressed_BYTE_v2.java | 4 +-- .../LASreadItemCompressed_GPSTIME11_v1.java | 4 +-- .../LASreadItemCompressed_GPSTIME11_v2.java | 4 +-- .../LASreadItemCompressed_POINT10_v1.java | 4 +-- .../LASreadItemCompressed_POINT10_v2.java | 4 +-- .../LASreadItemCompressed_POINT14_v3.java | 6 ++-- .../LASreadItemCompressed_RGB12_v1.java | 4 +-- .../LASreadItemCompressed_RGB12_v2.java | 4 +-- .../LASreadItemCompressed_RGB14_v3.java | 12 +++---- .../LASreadItemCompressed_RGBNIR14_v3.java | 12 +++---- ...LASreadItemCompressed_WAVEPACKET13_v1.java | 4 +-- ...LASreadItemCompressed_WAVEPACKET14_v3.java | 12 +++---- .../laszip4j/laszip/LASreadItemRaw_BYTE.java | 2 +- .../laszip/LASreadItemRaw_GPSTIME11.java | 2 +- .../laszip/LASreadItemRaw_POINT10.java | 2 +- .../laszip/LASreadItemRaw_POINT14.java | 2 +- .../laszip4j/laszip/LASreadItemRaw_RGB12.java | 2 +- .../laszip/LASreadItemRaw_RGBNIR14.java | 2 +- .../laszip/LASreadItemRaw_WAVEPACKET13.java | 2 +- .../laszip4j/laszip/LASreadPoint.java | 11 +++--- .../laszip4j/laszip/MutableInteger.java | 34 +++++++++++++++++++ 25 files changed, 96 insertions(+), 59 deletions(-) create mode 100644 src/main/java/com/github/mreutegg/laszip4j/laszip/MutableInteger.java diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItem.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItem.java index 8454323..8f476c5 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItem.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItem.java @@ -12,5 +12,5 @@ public abstract class LASreadItem { - public abstract PointDataRecord read(int context); + public abstract PointDataRecord read(MutableInteger context); } diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed.java index 72f548e..f1b1e81 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed.java @@ -12,6 +12,6 @@ public abstract class LASreadItemCompressed extends LASreadItem { - public abstract void init(PointDataRecord seedItem, int context); + public abstract void init(PointDataRecord seedItem, MutableInteger context); public abstract boolean chunk_sizes(); } diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE14_v3.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE14_v3.java index f0d9943..1b34fc5 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE14_v3.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE14_v3.java @@ -93,7 +93,7 @@ public LASreadItemCompressed_BYTE14_v3(IByteStreamInProvider instreamProvider, i } @Override - public void init(PointDataRecord seedItem, int context) { + public void init(PointDataRecord seedItem, MutableInteger context) { int i; @@ -183,7 +183,7 @@ public void init(PointDataRecord seedItem, int context) { /* set scanner channel as current context */ - current_context = context; // all other items use context set by POINT14 reader + current_context = context.get(); // all other items use context set by POINT14 reader /* create and init models and decompressors */ @@ -206,22 +206,22 @@ public boolean chunk_sizes() { } @Override - public PointDataRecord read(int context) { + public PointDataRecord read(MutableInteger context) { // get last PointDataRecordBytes last_item = contexts[current_context].last_item; // check for context switch - if (current_context != context) + if (current_context != context.get()) { - current_context = context; // all other items use context set by POINT14 reader + current_context = context.get(); // all other items use context set by POINT14 reader if (contexts[current_context].unused) { createAndInitModelsAndDecompressors(current_context, last_item); + last_item = contexts[current_context].last_item; } - last_item = contexts[current_context].last_item; - } + } // decompress PointDataRecordBytes result = new PointDataRecordBytes(number); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE_v1.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE_v1.java index d7edd44..cb68de9 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE_v1.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE_v1.java @@ -29,7 +29,7 @@ public LASreadItemCompressed_BYTE_v1(ArithmeticDecoder dec, int number) } @Override - public void init(PointDataRecord seedItem, int notUsed) + public void init(PointDataRecord seedItem, MutableInteger notUsed) { /* init state */ @@ -41,7 +41,7 @@ public void init(PointDataRecord seedItem, int notUsed) } @Override - public PointDataRecord read(int notUsed) + public PointDataRecord read(MutableInteger notUsed) { PointDataRecordBytes result = new PointDataRecordBytes(number); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE_v2.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE_v2.java index 9ad5937..4298f12 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE_v2.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_BYTE_v2.java @@ -39,7 +39,7 @@ public LASreadItemCompressed_BYTE_v2(ArithmeticDecoder dec, int number) } @Override - public void init(PointDataRecord seedItem, int notUsed) + public void init(PointDataRecord seedItem, MutableInteger notUsed) { int i; /* init state */ @@ -54,7 +54,7 @@ public void init(PointDataRecord seedItem, int notUsed) } @Override - public PointDataRecord read(int notUsed) + public PointDataRecord read(MutableInteger notUsed) { PointDataRecordBytes result = new PointDataRecordBytes(number); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_GPSTIME11_v1.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_GPSTIME11_v1.java index f0022bf..2cab9a7 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_GPSTIME11_v1.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_GPSTIME11_v1.java @@ -37,7 +37,7 @@ public LASreadItemCompressed_GPSTIME11_v1(ArithmeticDecoder dec) } @Override - public void init(PointDataRecord seedItem, int notUsed) + public void init(PointDataRecord seedItem, MutableInteger notUsed) { /* init state */ last_gpstime_diff = 0; @@ -52,7 +52,7 @@ public void init(PointDataRecord seedItem, int notUsed) } @Override - public PointDataRecordGpsTime read(int notUsed) + public PointDataRecordGpsTime read(MutableInteger notUsed) { int multi; if (last_gpstime_diff == 0) // if the last integer difference was zero diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_GPSTIME11_v2.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_GPSTIME11_v2.java index 6a73201..0928d21 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_GPSTIME11_v2.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_GPSTIME11_v2.java @@ -42,7 +42,7 @@ public LASreadItemCompressed_GPSTIME11_v2(ArithmeticDecoder dec) } @Override - public void init(PointDataRecord seedItem, int notUsed) + public void init(PointDataRecord seedItem, MutableInteger notUsed) { /* init state */ last = 0; next = 0; @@ -68,7 +68,7 @@ public void init(PointDataRecord seedItem, int notUsed) } @Override - public PointDataRecord read(int notUsed) + public PointDataRecord read(MutableInteger notUsed) { PointDataRecordGpsTime result = new PointDataRecordGpsTime(); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT10_v1.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT10_v1.java index 1149b91..c9b2717 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT10_v1.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT10_v1.java @@ -53,7 +53,7 @@ public LASreadItemCompressed_POINT10_v1(ArithmeticDecoder dec) { } @Override - public void init(PointDataRecord seedItem, int notUsed) { + public void init(PointDataRecord seedItem, MutableInteger notUsed) { int i; @@ -81,7 +81,7 @@ public void init(PointDataRecord seedItem, int notUsed) { } @Override - public PointDataRecord read(int notUsed) { + public PointDataRecord read(MutableInteger notUsed) { // find median difference for x and y from 3 preceding differences int median_x; diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT10_v2.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT10_v2.java index b42de24..87af5bd 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT10_v2.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT10_v2.java @@ -62,7 +62,7 @@ public LASreadItemCompressed_POINT10_v2(ArithmeticDecoder dec) } @Override - public void init(PointDataRecord seedItem, int notUsed) + public void init(PointDataRecord seedItem, MutableInteger notUsed) { int i; // unsigned @@ -99,7 +99,7 @@ public void init(PointDataRecord seedItem, int notUsed) } @Override - public PointDataRecord read(int notUsed) + public PointDataRecord read(MutableInteger notUsed) { int r, n, m, l; // unsigned int k_bits; // unsigned diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT14_v3.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT14_v3.java index 3c27ae3..2dcaec9 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT14_v3.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_POINT14_v3.java @@ -154,7 +154,7 @@ public LASreadItemCompressed_POINT14_v3(IByteStreamInProvider instreamProvider, } @Override - public void init(PointDataRecord seedItem, int notUsed) { + public void init(PointDataRecord seedItem, MutableInteger context) { ByteStreamIn instream = instreamProvider.getByteStreamIn(); @@ -404,6 +404,7 @@ public void init(PointDataRecord seedItem, int notUsed) { /* set scanner channel as current context */ current_context = ((PointDataRecordPoint14)seedItem).getScannerChannel(); + context.set(current_context); // the POINT14 reader sets context for all other items /* create and init models and decompressors */ @@ -411,7 +412,7 @@ public void init(PointDataRecord seedItem, int notUsed) { } @Override - public PointDataRecord read(int context) + public PointDataRecord read(MutableInteger context) { // get last @@ -449,6 +450,7 @@ public PointDataRecord read(int context) } // switch context to current scanner channel current_context = scanner_channel; + context.set(current_context); // the POINT14 reader sets context for all other items // get last for new context last_item = contexts[current_context].last_item; diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB12_v1.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB12_v1.java index 4ca122a..cf1dc31 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB12_v1.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB12_v1.java @@ -32,7 +32,7 @@ public LASreadItemCompressed_RGB12_v1(ArithmeticDecoder dec) } @Override - public void init(PointDataRecord seedItem, int notUsed) + public void init(PointDataRecord seedItem, MutableInteger notUsed) { /* init state */ @@ -44,7 +44,7 @@ public void init(PointDataRecord seedItem, int notUsed) } @Override - public PointDataRecord read(int notUsed) + public PointDataRecord read(MutableInteger notUsed) { PointDataRecordRGB result = new PointDataRecordRGB(); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB12_v2.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB12_v2.java index ddb429c..ee4af1d 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB12_v2.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB12_v2.java @@ -43,7 +43,7 @@ public LASreadItemCompressed_RGB12_v2(ArithmeticDecoder dec) } @Override - public void init(PointDataRecord seedItem, int notUsed) + public void init(PointDataRecord seedItem, MutableInteger notUsed) { /* init state */ @@ -60,7 +60,7 @@ public void init(PointDataRecord seedItem, int notUsed) } @Override - public PointDataRecord read(int notUsed) + public PointDataRecord read(MutableInteger notUsed) { int corr; int diff = 0; diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB14_v3.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB14_v3.java index c6ea8d3..2d3ba0c 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB14_v3.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGB14_v3.java @@ -51,7 +51,7 @@ public LASreadItemCompressed_RGB14_v3(IByteStreamInProvider instreamProvider, in } @Override - public void init(PointDataRecord seedItem, int context) { + public void init(PointDataRecord seedItem, MutableInteger context) { ByteStreamIn instream = instreamProvider.getByteStreamIn(); @@ -101,7 +101,7 @@ public void init(PointDataRecord seedItem, int context) { contexts[c].unused = true; } - current_context = context; // all other items use context set by POINT14 reader + current_context = context.get(); // all other items use context set by POINT14 reader createAndInitModelsAndDecompressors(current_context, (PointDataRecordRGB)seedItem); } @@ -118,7 +118,7 @@ public boolean chunk_sizes() { } @Override - public PointDataRecord read(int context) { + public PointDataRecord read(MutableInteger context) { PointDataRecordRGB result = new PointDataRecordRGB(); @@ -127,14 +127,14 @@ public PointDataRecord read(int context) { // check for context switch - if (current_context != context) + if (current_context != context.get()) { - current_context = context; // all other items use context set by POINT14 reader + current_context = context.get(); // all other items use context set by POINT14 reader if (contexts[current_context].unused) { createAndInitModelsAndDecompressors(current_context, last_item); + last_item = contexts[current_context].last_item; } - last_item = contexts[current_context].last_item; } // decompress diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGBNIR14_v3.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGBNIR14_v3.java index 9c03621..ef25d0e 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGBNIR14_v3.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_RGBNIR14_v3.java @@ -76,7 +76,7 @@ public LASreadItemCompressed_RGBNIR14_v3(IByteStreamInProvider instreamProvider, } @Override - public void init(PointDataRecord seedItem, int context) { + public void init(PointDataRecord seedItem, MutableInteger context) { ByteStreamIn instream = instreamProvider.getByteStreamIn(); @@ -156,7 +156,7 @@ public void init(PointDataRecord seedItem, int context) { /* set scanner channel as current context */ - current_context = context; // all other items use context set by POINT14 reader + current_context = context.get(); // all other items use context set by POINT14 reader /* create and init models and decompressors */ @@ -176,7 +176,7 @@ public boolean chunk_sizes() { } @Override - public PointDataRecord read(int context) { + public PointDataRecord read(MutableInteger context) { // get last @@ -184,14 +184,14 @@ public PointDataRecord read(int context) { // check for context switch - if (current_context != context) + if (current_context != context.get()) { - current_context = context; // all other items use context set by POINT14 reader + current_context = context.get(); // all other items use context set by POINT14 reader if (contexts[current_context].unused) { createAndInitModelsAndDecompressors(current_context, last_item); + last_item = contexts[current_context].last_item; } - last_item = contexts[current_context].last_item; } // decompress diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_WAVEPACKET13_v1.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_WAVEPACKET13_v1.java index 3b9d4f5..3f2a50c 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_WAVEPACKET13_v1.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_WAVEPACKET13_v1.java @@ -45,7 +45,7 @@ public LASreadItemCompressed_WAVEPACKET13_v1(ArithmeticDecoder dec) last_item = null; } - public void init(PointDataRecord seedItem, int notUsed) + public void init(PointDataRecord seedItem, MutableInteger notUsed) { /* init state */ last_diff_32 = 0; @@ -66,7 +66,7 @@ public void init(PointDataRecord seedItem, int notUsed) last_item = new PointDataRecordWavepacket((PointDataRecordWavepacket)seedItem); } - public PointDataRecord read(int notUsed) + public PointDataRecord read(MutableInteger notUsed) { PointDataRecordWavepacket result = new PointDataRecordWavepacket(); result.DescriptorIndex = (short)dec.decodeSymbol(m_packet_index); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_WAVEPACKET14_v3.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_WAVEPACKET14_v3.java index e78c4f7..b7c07b9 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_WAVEPACKET14_v3.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemCompressed_WAVEPACKET14_v3.java @@ -61,7 +61,7 @@ public LASreadItemCompressed_WAVEPACKET14_v3(IByteStreamInProvider instreamProvi } @Override - public void init(PointDataRecord seedItem, int context) { + public void init(PointDataRecord seedItem, MutableInteger context) { ByteStreamIn instream = instreamProvider.getByteStreamIn(); @@ -114,7 +114,7 @@ public void init(PointDataRecord seedItem, int context) { /* set scanner channel as current context */ - current_context = context; // all other items use context set by POINT14 reader + current_context = context.get(); // all other items use context set by POINT14 reader /* create and init models and decompressors */ @@ -134,21 +134,21 @@ public boolean chunk_sizes() { } @Override - public PointDataRecord read(int context) { + public PointDataRecord read(MutableInteger context) { // get last PointDataRecordWavepacket last_item = contexts[current_context].last_item; // check for context switch - if (current_context != context) + if (current_context != context.get()) { - current_context = context; // all other items use context set by POINT14 reader + current_context = context.get(); // all other items use context set by POINT14 reader if (contexts[current_context].unused) { createAndInitModelsAndDecompressors(current_context, last_item); + last_item = contexts[current_context].last_item; } - last_item = contexts[current_context].last_item; } // decompress diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_BYTE.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_BYTE.java index afa0a6c..c4911cd 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_BYTE.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_BYTE.java @@ -19,7 +19,7 @@ public LASreadItemRaw_BYTE(int byteCount) { } @Override - public PointDataRecordBytes read(int notUsed) { + public PointDataRecordBytes read(MutableInteger notUsed) { PointDataRecordBytes result = new PointDataRecordBytes(byteCount); instream.getBytes(result.Bytes, byteCount); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_GPSTIME11.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_GPSTIME11.java index 1ad88f3..ab8d73a 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_GPSTIME11.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_GPSTIME11.java @@ -18,7 +18,7 @@ public class LASreadItemRaw_GPSTIME11 extends LASreadItemRaw { private ByteBuffer bb = ByteBuffer.allocate(Long.BYTES).order(ByteOrder.LITTLE_ENDIAN); @Override - public PointDataRecordGpsTime read(int notUsed) { + public PointDataRecordGpsTime read(MutableInteger notUsed) { bb.clear(); instream.getBytes(bb.array(), Long.BYTES); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_POINT10.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_POINT10.java index e60f4b3..6bdd8da 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_POINT10.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_POINT10.java @@ -18,7 +18,7 @@ public class LASreadItemRaw_POINT10 extends LASreadItemRaw { private ByteBuffer bb = ByteBuffer.allocate(20).order(ByteOrder.LITTLE_ENDIAN); @Override - public PointDataRecordPoint10 read(int notUsed) { + public PointDataRecordPoint10 read(MutableInteger notUsed) { bb.clear(); instream.getBytes(bb.array(), 20); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_POINT14.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_POINT14.java index 25c7e2c..bbe231b 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_POINT14.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_POINT14.java @@ -18,7 +18,7 @@ public class LASreadItemRaw_POINT14 extends LASreadItemRaw { private ByteBuffer bb = ByteBuffer.allocate(30).order(ByteOrder.LITTLE_ENDIAN); @Override - public PointDataRecordPoint14 read(int notUsed) { + public PointDataRecordPoint14 read(MutableInteger notUsed) { bb.clear(); instream.getBytes(bb.array(), 30); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_RGB12.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_RGB12.java index e987516..66c0534 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_RGB12.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_RGB12.java @@ -18,7 +18,7 @@ public class LASreadItemRaw_RGB12 extends LASreadItemRaw { private ByteBuffer bb = ByteBuffer.allocate(6).order(ByteOrder.LITTLE_ENDIAN); @Override - public PointDataRecordRGB read(int notUsed) { + public PointDataRecordRGB read(MutableInteger notUsed) { bb.clear(); instream.getBytes(bb.array(), 6); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_RGBNIR14.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_RGBNIR14.java index a0c6d09..dc79acd 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_RGBNIR14.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_RGBNIR14.java @@ -18,7 +18,7 @@ public class LASreadItemRaw_RGBNIR14 extends LASreadItemRaw { private ByteBuffer bb = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN); @Override - public PointDataRecordRgbNIR read(int notUsed) { + public PointDataRecordRgbNIR read(MutableInteger notUsed) { bb.clear(); instream.getBytes(bb.array(), 8); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_WAVEPACKET13.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_WAVEPACKET13.java index 32b642d..7114b4a 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_WAVEPACKET13.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadItemRaw_WAVEPACKET13.java @@ -18,7 +18,7 @@ public class LASreadItemRaw_WAVEPACKET13 extends LASreadItemRaw { private ByteBuffer bb = ByteBuffer.allocate(29).order(ByteOrder.LITTLE_ENDIAN); @Override - public PointDataRecordWavepacket read(int notUsed) { + public PointDataRecordWavepacket read(MutableInteger notUsed) { bb.clear(); instream.getBytes(bb.array(), 29); diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadPoint.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadPoint.java index 6020e6c..6a63591 100644 --- a/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadPoint.java +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/LASreadPoint.java @@ -361,6 +361,7 @@ else if (Integer.compareUnsigned(current, target) < 0) public boolean read(PointDataRecord[] pointRecords) { int i; // unsigned + MutableInteger context = new MutableInteger(0); try { @@ -407,14 +408,14 @@ else if (chunk_totals != null) // variable sized chunks? { for (i = 0; i < num_readers; i++) { - pointRecords[i] = readers[i].read( i > 0 ? pointRecords[0].CompressionContext : 0); + pointRecords[i] = readers[i].read(context); } } else { for (i = 0; i < num_readers; i++) { - pointRecords[i] = readers_raw[i].read(0); + pointRecords[i] = readers_raw[i].read(context); } if (layered_las14_compression) { @@ -429,14 +430,14 @@ else if (chunk_totals != null) // variable sized chunks? } for (i = 0; i < num_readers; i++) { - ((LASreadItemCompressed)(readers_compressed[i])).init(pointRecords[i], i > 0 ? pointRecords[0].CompressionContext : 0); + ((LASreadItemCompressed)(readers_compressed[i])).init(pointRecords[i], context); } } else { for (i = 0; i < num_readers; i++) { - ((LASreadItemCompressed)(readers_compressed[i])).init(pointRecords[i], i > 0 ? pointRecords[0].CompressionContext : 0); + ((LASreadItemCompressed)(readers_compressed[i])).init(pointRecords[i], context); } dec.init(instream); } @@ -448,7 +449,7 @@ else if (chunk_totals != null) // variable sized chunks? { for (i = 0; i < num_readers; i++) { - pointRecords[i] = readers[i].read( i > 0 ? pointRecords[0].CompressionContext : 0); + pointRecords[i] = readers[i].read(context); } } } diff --git a/src/main/java/com/github/mreutegg/laszip4j/laszip/MutableInteger.java b/src/main/java/com/github/mreutegg/laszip4j/laszip/MutableInteger.java new file mode 100644 index 0000000..6c8b76f --- /dev/null +++ b/src/main/java/com/github/mreutegg/laszip4j/laszip/MutableInteger.java @@ -0,0 +1,34 @@ +/* + * Copyright 2024 Marcel Reutegger + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package com.github.mreutegg.laszip4j.laszip; + +public final class MutableInteger { + + private int value; + + public MutableInteger(int value) { + this.value = value; + } + + public int get() { + return value; + } + + public void set(int value) { + this.value = value; + } +} From 779762dc6338b40e95707d7319203712d2a27554 Mon Sep 17 00:00:00 2001 From: Marcel Reutegger Date: Sun, 18 Aug 2024 14:13:18 +0200 Subject: [PATCH 2/2] Add test using contributed LAZ 1.4 v3 sample file --- .../github/mreutegg/laszip4j/DataFiles.java | 4 +++ .../mreutegg/laszip4j/LASReaderTest.java | 30 ++++++++++++++++++ .../500m_5460_59370_IM2023_subset.laz | Bin 0 -> 914402 bytes 3 files changed, 34 insertions(+) create mode 100644 src/test/resources/500m_5460_59370_IM2023_subset.laz diff --git a/src/test/java/com/github/mreutegg/laszip4j/DataFiles.java b/src/test/java/com/github/mreutegg/laszip4j/DataFiles.java index bae0a61..ebfc605 100644 --- a/src/test/java/com/github/mreutegg/laszip4j/DataFiles.java +++ b/src/test/java/com/github/mreutegg/laszip4j/DataFiles.java @@ -41,6 +41,9 @@ public class DataFiles extends ExternalResource { private static final String LAZ_14_BASE_URL = "https://github.com/PDAL/data/raw/master/autzen"; public static final int LAZ_14_NUM_POINT_RECORDS = 10653336; + // test file contributed via https://github.com/mreutegg/laszip4j/pull/141 + public static final String LAZ_14_V3_RGB_NAME = "500m_5460_59370_IM2023_subset.laz"; + // file created with txt2las as described here: https://groups.google.com/g/lasroom/c/DWQ2GXKE8f8 public static final String EXTRA_TYPES_NAME = "extra-bytes.las"; @@ -51,6 +54,7 @@ public class DataFiles extends ExternalResource { public final File las = new File(target, LAS_NAME); public final File laz14 = new File(target, LAZ_14_NAME); public final File extraBytes = new File(resources, EXTRA_TYPES_NAME); + public final File laz14v3rgb = new File(resources, LAZ_14_V3_RGB_NAME); @Override protected void before() throws Throwable { diff --git a/src/test/java/com/github/mreutegg/laszip4j/LASReaderTest.java b/src/test/java/com/github/mreutegg/laszip4j/LASReaderTest.java index 0878eed..111fa60 100644 --- a/src/test/java/com/github/mreutegg/laszip4j/LASReaderTest.java +++ b/src/test/java/com/github/mreutegg/laszip4j/LASReaderTest.java @@ -561,4 +561,34 @@ public void readPointWithoutGPSTime() { } } } + + @Test + public void readLaz14v3RGB() { + LASReader reader = new LASReader(files.laz14v3rgb); + + long numPoints = 0; + char minRed = Character.MAX_VALUE; + char maxRed = Character.MIN_VALUE; + char minGreen = Character.MAX_VALUE; + char maxGreen = Character.MIN_VALUE; + char minBlue = Character.MAX_VALUE; + char maxBlue = Character.MIN_VALUE; + for (LASPoint p : reader.getPoints()) { + numPoints++; + minRed = (char) Math.min(minRed, p.getRed()); + maxRed = (char) Math.max(maxRed, p.getRed()); + minGreen = (char) Math.min(minGreen, p.getGreen()); + maxGreen = (char) Math.max(maxGreen, p.getGreen()); + minBlue = (char) Math.min(minBlue, p.getBlue()); + maxBlue = (char) Math.max(maxBlue, p.getBlue()); + } + + assertEquals(56644, numPoints); + assertEquals(10499, minRed); + assertEquals(62736, maxRed); + assertEquals(15324, minGreen); + assertEquals(63068, maxGreen); + assertEquals(21877, minBlue); + assertEquals(63435, maxBlue); + } } diff --git a/src/test/resources/500m_5460_59370_IM2023_subset.laz b/src/test/resources/500m_5460_59370_IM2023_subset.laz new file mode 100644 index 0000000000000000000000000000000000000000..5978206a108b29c0b54baf9fd66ffeb2b363ec7c GIT binary patch literal 914402 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