Skip to content

Commit 7f24638

Browse files
authored
Merge pull request #1394 from dopplershift/fix-nids-deflate
BUG: Fix decompressing all zlib data for NIDS
2 parents c46f966 + a96a0cc commit 7f24638

4 files changed

Lines changed: 83 additions & 71 deletions

File tree

cdm/radial/src/main/java/ucar/nc2/iosp/nids/Nidsheader.java

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,6 @@ void read(ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile ncfile) thro
255255
int rc; /* function return status */
256256
int hoff = 0;
257257
int type;
258-
int zlibed;
259258
boolean isZ = false;
260259
int encrypt;
261260
long actualSize;
@@ -295,8 +294,8 @@ void read(ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile ncfile) thro
295294
// byte[] b4 = new byte[4];
296295
System.arraycopy(b, hoff, b2, 0, 2);
297296

298-
zlibed = isZlibHed(b2);
299-
if (zlibed == 0) {
297+
boolean zlibed = isZlibHed(b2);
298+
if (!zlibed) {
300299
encrypt = IsEncrypt(b2);
301300
if (encrypt == 1) {
302301
log.error("error reading encryted product " + raf.getLocation());
@@ -331,7 +330,7 @@ void read(ucar.unidata.io.RandomAccessFile raf, ucar.nc2.NetcdfFile ncfile) thro
331330
break;
332331
}
333332

334-
if (zlibed == 1) {
333+
if (zlibed) {
335334
isZ = true;
336335
uncompdata = GetZlibedNexr(b, readLen, hoff);
337336
// uncompdata = Nidsiosp.readCompData(hoff, 160) ;
@@ -3282,23 +3281,23 @@ public void close() throws IOException {
32823281

32833282
/**
32843283
* Name: IsZlibed
3285-
*
3284+
* <p>
32863285
* Purpose: Check a two-byte sequence to see if it indicates the start of a zlib-compressed
32873286
* buffer
32883287
*/
3289-
int isZlibHed(byte[] buf) {
3288+
boolean isZlibHed(byte[] buf) {
32903289
short b0 = convertunsignedByte2Short(buf[0]);
32913290
short b1 = convertunsignedByte2Short(buf[1]);
32923291

32933292
if ((b0 & 0xf) == Z_DEFLATED) {
32943293
if ((b0 >> 4) + 8 <= DEF_WBITS) {
32953294
if ((((b0 << 8) + b1) % 31) == 0) {
3296-
return 1;
3295+
return true;
32973296
}
32983297
}
32993298
}
33003299

3301-
return 0;
3300+
return false;
33023301

33033302
}
33043303

@@ -3363,56 +3362,52 @@ byte[] GetZlibedNexr(byte[] buf, int buflen, int hoff) throws IOException {
33633362
// decompress the bytes
33643363
int resultLength;
33653364
int result = 0;
3366-
// byte[] inflateData = null;
3367-
byte[] tmp;
3368-
int uncompLen = 24500; /* length of decompress space */
3369-
byte[] uncomp = new byte[uncompLen];
3370-
Inflater inflater = new Inflater(false);
3365+
byte[] chunk;
3366+
List<byte[]> chunks = new ArrayList<>(1);
3367+
List<Integer> sizes = new ArrayList<>(1);
33713368

3372-
inflater.setInput(buf, hoff, numin - 4);
3373-
int offset = 0;
3374-
int limit = 20000;
3369+
Inflater inf = new Inflater(false);
3370+
inf.setInput(buf, hoff, numin - 4);
33753371

3376-
while (inflater.getRemaining() > 0) {
3372+
while (inf.getRemaining() > 0) {
33773373
try {
3378-
resultLength = inflater.inflate(uncomp, offset, 4000);
3374+
chunk = new byte[4000];
3375+
resultLength = inf.inflate(chunk, 0, 4000);
3376+
chunks.add(chunk);
3377+
sizes.add(resultLength);
33793378
} catch (DataFormatException ex) {
3380-
log.error("nids Inflater", ex);
3381-
throw new IOException(ex.getMessage(), ex);
3382-
}
3383-
offset = offset + resultLength;
3384-
result = result + resultLength;
3385-
if (result > limit) {
3386-
// when uncomp data larger then limit, the uncomp need to increase size
3387-
tmp = new byte[result];
3388-
System.arraycopy(uncomp, 0, tmp, 0, result);
3389-
uncompLen = uncompLen + 10000;
3390-
uncomp = new byte[uncompLen];
3391-
System.arraycopy(tmp, 0, uncomp, 0, result);
3379+
log.error("ERROR on inflation ", ex);
3380+
throw new IOException(ex.getMessage());
33923381
}
3382+
3383+
result += resultLength;
33933384
if (resultLength == 0) {
3394-
int tt = inflater.getRemaining();
3385+
int tt = inf.getRemaining();
33953386
byte[] b2 = new byte[2];
33963387
System.arraycopy(buf, hoff + numin - 4 - tt, b2, 0, 2);
3397-
if (result + tt > uncompLen) {
3398-
tmp = new byte[result];
3399-
System.arraycopy(uncomp, 0, tmp, 0, result);
3400-
uncompLen = uncompLen + 10000;
3401-
uncomp = new byte[uncompLen];
3402-
System.arraycopy(tmp, 0, uncomp, 0, result);
3403-
}
3404-
if (isZlibHed(b2) == 0) {
3405-
System.arraycopy(buf, hoff + numin - 4 - tt, uncomp, result, tt);
3406-
result = result + tt;
3388+
if (!isZlibHed(b2)) {
3389+
chunk = new byte[tt];
3390+
System.arraycopy(buf, hoff + numin - 4 - tt, chunk, 0, tt);
3391+
chunks.add(chunk);
3392+
sizes.add(tt);
3393+
result += tt;
34073394
break;
3395+
} else {
3396+
inf.reset();
3397+
inf.setInput(buf, hoff + numin - 4 - tt, tt);
34083398
}
3409-
inflater.reset();
3410-
inflater.setInput(buf, hoff + numin - 4 - tt, tt);
34113399
}
3400+
}
3401+
inf.end();
34123402

3403+
// Combine the chunks into one buffer
3404+
byte[] uncomp = new byte[result];
3405+
int pos = 0;
3406+
for (int i = 0; i < chunks.size(); ++i) {
3407+
System.arraycopy(chunks.get(i), 0, uncomp, pos, sizes.get(i));
3408+
pos += sizes.get(i);
34133409
}
34143410

3415-
inflater.end();
34163411
/*
34173412
** Find out how long CCB is. This is done by using the lower order
34183413
** 6 bits from the first uncompressed byte and all 8 bits of the

cdm/radial/src/main/java/ucar/nc2/iosp/nids/Nidsiosp.java

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,9 +1490,8 @@ public byte[] readCompData1(byte[] uncomp, long hoff, long doff) {
14901490
*/
14911491
public byte[] readCompData(long hoff, long doff) throws IOException {
14921492
int numin; /* # input bytes processed */
1493-
long pos = 0;
14941493
long len = raf.length();
1495-
raf.seek(pos);
1494+
raf.seek(0);
14961495
numin = (int) (len - hoff);
14971496
// Read in the contents of the NEXRAD Level III product header
14981497

@@ -1506,53 +1505,55 @@ public byte[] readCompData(long hoff, long doff) throws IOException {
15061505
// System.arraycopy( b, (int)hoff, comp, 0, numin -4 );
15071506

15081507
// decompress the bytes
1509-
Inflater inf = new Inflater(false);
1510-
15111508
int resultLength;
15121509
int result = 0;
1513-
// byte[] inflateData = null;
1514-
byte[] tmp;
1515-
int uncompLen = 24500; /* length of decompress space */
1516-
byte[] uncomp = new byte[uncompLen];
1510+
byte[] chunk;
1511+
List<byte[]> chunks = new ArrayList<>(1);
1512+
List<Integer> sizes = new ArrayList<>(1);
15171513

1514+
Inflater inf = new Inflater(false);
15181515
inf.setInput(b, (int) hoff, numin - 4);
1519-
int limit = 20000;
15201516

15211517
while (inf.getRemaining() > 0) {
15221518
try {
1523-
resultLength = inf.inflate(uncomp, result, 4000);
1519+
chunk = new byte[4000];
1520+
resultLength = inf.inflate(chunk, 0, 4000);
1521+
chunks.add(chunk);
1522+
sizes.add(resultLength);
15241523
} catch (DataFormatException ex) {
15251524
logger.error("ERROR on inflation ", ex);
15261525
throw new IOException(ex.getMessage());
15271526
}
15281527

1529-
result = result + resultLength;
1530-
if (result > limit) {
1531-
// when uncomp data larger then limit, the uncomp need to increase size
1532-
tmp = new byte[result];
1533-
System.arraycopy(uncomp, 0, tmp, 0, result);
1534-
uncompLen = uncompLen + 10000;
1535-
uncomp = new byte[uncompLen];
1536-
System.arraycopy(tmp, 0, uncomp, 0, result);
1537-
}
1528+
result += resultLength;
15381529
if (resultLength == 0) {
15391530
int tt = inf.getRemaining();
15401531
byte[] b2 = new byte[2];
15411532
System.arraycopy(b, (int) hoff + numin - 4 - tt, b2, 0, 2);
1542-
if (headerParser.isZlibHed(b2) == 0) {
1543-
System.arraycopy(b, (int) hoff + numin - 4 - tt, uncomp, result, tt);
1544-
result = result + tt;
1533+
if (!headerParser.isZlibHed(b2)) {
1534+
chunk = new byte[tt];
1535+
System.arraycopy(b, (int) hoff + numin - 4 - tt, chunk, 0, tt);
1536+
chunks.add(chunk);
1537+
sizes.add(tt);
1538+
result += tt;
15451539
break;
1540+
} else {
1541+
inf.reset();
1542+
inf.setInput(b, (int) hoff + numin - 4 - tt, tt);
15461543
}
1547-
inf.reset();
1548-
inf.setInput(b, (int) hoff + numin - 4 - tt, tt);
15491544
}
1550-
15511545
}
15521546
inf.end();
15531547

1554-
int off;
1555-
off = 2 * (((uncomp[0] & 0x3F) << 8) | (uncomp[1] & 0xFF));
1548+
// Combine the chunks into one buffer
1549+
byte[] uncomp = new byte[result];
1550+
int pos = 0;
1551+
for (int i = 0; i < chunks.size(); ++i) {
1552+
System.arraycopy(chunks.get(i), 0, uncomp, pos, sizes.get(i));
1553+
pos += sizes.get(i);
1554+
}
1555+
1556+
int off = 2 * (((uncomp[0] & 0x3F) << 8) | (uncomp[1] & 0xFF));
15561557
/* eat WMO and PIL */
15571558
for (int i = 0; i < 2; i++) {
15581559
while ((off < result) && (uncomp[off] != '\n'))
278 KB
Binary file not shown.

cdm/radial/src/test/java/ucar/nc2/iosp/nids/TestNids.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public class TestNids {
4040
private static String digitPrecipArrayFile = TestDir.localTestDataDir + "nids/DPA_20041123_1709";
4141
private static String vertIntegLiquidFile = TestDir.localTestDataDir + "nids/NVL_20041130_1946";
4242
private static String vadWindProfileFile = TestDir.localTestDataDir + "nids/NVW_20041117_1657";
43+
private static String compressedBlockFile = TestDir.localTestDataDir + "nids/Level3_CYS_N0B_20241108_1948.nids";
4344

4445
@Test
4546
public void testNidsReadRadial() throws IOException {
@@ -503,6 +504,21 @@ public void testRadialImageMessagePcode167() throws IOException {
503504
}
504505
}
505506

507+
@Test
508+
public void testNidsCompressedBlock() throws IOException {
509+
NetcdfFile ncfile = null;
510+
try {
511+
System.out.println("**** Open " + compressedBlockFile);
512+
ncfile = NetcdfFile.open(compressedBlockFile);
513+
} catch (java.io.IOException e) {
514+
System.out.println(" fail = " + e);
515+
e.printStackTrace();
516+
assert (false);
517+
}
518+
ncfile.close();
519+
}
520+
521+
506522
private void testReadData(Variable v) {
507523
Array a = null;
508524
assert (null != v);

0 commit comments

Comments
 (0)