satellite.mcidas decoder native support for UNIWISC PNG-compressed products
This commit is contained in:
parent
3e4b613578
commit
ad45838f9a
3 changed files with 72 additions and 39 deletions
|
@ -11,7 +11,8 @@ Require-Bundle: com.raytheon.edex.common,
|
|||
javax.persistence,
|
||||
com.raytheon.uf.common.dataplugin.satellite;bundle-version="1.0.0",
|
||||
com.raytheon.edex.plugin.satellite;bundle-version="1.12.1174",
|
||||
org.apache.commons.codec;bundle-version="1.10.0"
|
||||
org.apache.commons.codec;bundle-version="1.10.0",
|
||||
ar.com.hjg.pngj;bundle-version="2.1.1"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Import-Package: com.raytheon.uf.common.localization,
|
||||
com.raytheon.uf.common.menus,
|
||||
|
|
|
@ -19,9 +19,13 @@
|
|||
**/
|
||||
package com.raytheon.uf.edex.plugin.satellite.mcidas;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
@ -29,8 +33,12 @@ import java.util.TimeZone;
|
|||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.opengis.referencing.crs.ProjectedCRS;
|
||||
|
||||
import ar.com.hjg.pngj.ImageLineByte;
|
||||
import ar.com.hjg.pngj.PngReaderByte;
|
||||
|
||||
import com.raytheon.edex.esb.Headers;
|
||||
import com.raytheon.edex.exception.DecoderException;
|
||||
import com.raytheon.edex.plugin.satellite.SatelliteDecoderException;
|
||||
import com.raytheon.edex.util.satellite.SatSpatialFactory;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
||||
|
@ -79,6 +87,7 @@ import com.raytheon.uf.edex.plugin.satellite.mcidas.util.McidasSatelliteLookups.
|
|||
* 05/19/2015 ---- mjames@ucar Added decoding of GVAR native projection products
|
||||
* 07/12/2015 ---- mjames@ucar Account for GOES E and W UNIWISC AREA file numbers
|
||||
* 01/21/2016 ---- mjames@ucar Cleanup
|
||||
* 10/24/2017 ---- mjames@ucar Native support for PNG-compressed AREA files.
|
||||
* </pre>
|
||||
*
|
||||
* @author
|
||||
|
@ -99,6 +108,10 @@ public class McidasSatelliteDecoder {
|
|||
|
||||
final int SIZE_OF_AREA = 256;
|
||||
|
||||
final int PNG_HEADER_LENGTH = 240;
|
||||
|
||||
private final byte[] PNG_HDR = { -119, 80, 78, 71 };
|
||||
|
||||
private static final double HALFPI = Math.PI / 2.;
|
||||
|
||||
private static final double RTD = 180. / Math.PI;
|
||||
|
@ -144,7 +157,6 @@ public class McidasSatelliteDecoder {
|
|||
*/
|
||||
private PluginDataObject[] decodeMcidasArea(byte[] data) throws Exception {
|
||||
|
||||
|
||||
byte[] area = null;
|
||||
byte[] nonAreaBlock = new byte[data.length - SIZE_OF_AREA];
|
||||
area = new byte[SIZE_OF_AREA];
|
||||
|
@ -230,21 +242,13 @@ public class McidasSatelliteDecoder {
|
|||
navsize = calibrationOffset - navBlockOffset;
|
||||
}
|
||||
byte[] navigation = new byte[navsize];
|
||||
byte[] nonNavBlock = new byte[nonAreaBlock.length - navsize];
|
||||
System.arraycopy(nonAreaBlock, 0, navigation, 0, navsize);
|
||||
|
||||
/* mjames@ucar
|
||||
* bandMap1to32 is a 32-bit filter band map for multichannel images.
|
||||
* if a bit is set, data exists for the band; band 1 is the least
|
||||
* significant byte (rightmost)
|
||||
*
|
||||
* Example: for GVAR GEWCOMP UNIWISC image,
|
||||
* bandMap1to32 = 4
|
||||
* bandMap33to64 = -1, so
|
||||
* nBands = 1
|
||||
* bandBitsCount = 33
|
||||
*
|
||||
* this is a problem...
|
||||
*/
|
||||
System.arraycopy(nonAreaBlock, navsize, nonNavBlock, 0, nonNavBlock.length);
|
||||
|
||||
byte[] pngBlock = new byte[nonNavBlock.length - PNG_HEADER_LENGTH];
|
||||
System.arraycopy(nonNavBlock, PNG_HEADER_LENGTH, pngBlock, 0, pngBlock.length);
|
||||
|
||||
long bandBits = ((long) bandMap33to64 << 32) | bandMap1to32;
|
||||
long bandBitsCount = Long.bitCount(bandBits);
|
||||
if (nBands != bandBitsCount && nBands > 1) {
|
||||
|
@ -281,11 +285,16 @@ public class McidasSatelliteDecoder {
|
|||
// TODO: Line pad if not a multiple of four bytes
|
||||
if ((linePrefixLength == 0) && (nBytesPerElement == 1)
|
||||
&& (nBands == 1)) {
|
||||
byte[] imageBytes = new byte[nLines * nElementsPerLine];
|
||||
buf.position(dataBlockOffset);
|
||||
buf.get(imageBytes);
|
||||
|
||||
rec.setMessageData(imageBytes);
|
||||
if (isPngCompressed(pngBlock)) {
|
||||
byte[] pngBytes = decompressPngSatellite(pngBlock);
|
||||
rec.setMessageData(pngBytes);
|
||||
} else {
|
||||
byte[] imageBytes = new byte[nLines * nElementsPerLine];
|
||||
buf.position(dataBlockOffset);
|
||||
buf.get(imageBytes);
|
||||
rec.setMessageData(imageBytes);
|
||||
}
|
||||
|
||||
} else if (nBytesPerElement == 1) {
|
||||
byte[] imageBytes = new byte[nLines * nElementsPerLine];
|
||||
|
@ -328,6 +337,47 @@ public class McidasSatelliteDecoder {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to check if file is PNG-compressed.
|
||||
*
|
||||
* @param messageData
|
||||
* @return
|
||||
*/
|
||||
private boolean isPngCompressed(byte[] messageData) {
|
||||
byte[] buffer = new byte[4];
|
||||
System.arraycopy(messageData, 0, buffer, 0, buffer.length);
|
||||
boolean compressed = Arrays.equals(buffer, PNG_HDR);
|
||||
return compressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to handle Unidata PNG compressed satellite data.
|
||||
*
|
||||
* @param messageData
|
||||
* @return
|
||||
* @throws DecoderException
|
||||
*/
|
||||
private byte[] decompressPngSatellite(byte[] messageData)
|
||||
throws SatelliteDecoderException {
|
||||
|
||||
InputStream stream = new ByteArrayInputStream(messageData);
|
||||
PngReaderByte png = new PngReaderByte(stream);
|
||||
|
||||
int MAX_IMAGE_SIZE = 30000000;
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(MAX_IMAGE_SIZE);
|
||||
byte[] inflated = null;
|
||||
|
||||
for (int row=0;row< png.getImgInfo().rows;row++){
|
||||
ImageLineByte line = png.readRowByte();
|
||||
byte [] buf = line.getScanlineByte();
|
||||
bos.write(buf, 0, buf.length);
|
||||
}
|
||||
|
||||
inflated = bos.toByteArray();
|
||||
bos = null;
|
||||
return inflated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference:
|
||||
* http://www.ssec.wisc.edu/mcidas/doc/prog_man/2006/formats-13a.html
|
||||
|
|
|
@ -1,24 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
|
||||
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
|
||||
|
||||
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
|
||||
This_software_product_contains_export-restricted_data_whose
|
||||
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
|
||||
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
|
||||
an_export_license_or_other_authorization.
|
||||
|
||||
Contractor_Name:________Raytheon_Company
|
||||
Contractor_Address:_____6825_Pine_Street,_Suite_340
|
||||
________________________Mail_Stop_B8
|
||||
________________________Omaha,_NE_68106
|
||||
________________________402.291.0100
|
||||
|
||||
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
|
||||
further_licensing_information.
|
||||
-->
|
||||
<requestPatterns xmlns:ns2="group">
|
||||
<regex>AREA[0-9]{4}.*</regex>
|
||||
<regex>pnga2area</regex>
|
||||
<regex>.*uniwisc.*</regex>
|
||||
</requestPatterns>
|
||||
|
|
Loading…
Add table
Reference in a new issue