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,
|
javax.persistence,
|
||||||
com.raytheon.uf.common.dataplugin.satellite;bundle-version="1.0.0",
|
com.raytheon.uf.common.dataplugin.satellite;bundle-version="1.0.0",
|
||||||
com.raytheon.edex.plugin.satellite;bundle-version="1.12.1174",
|
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
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||||
Import-Package: com.raytheon.uf.common.localization,
|
Import-Package: com.raytheon.uf.common.localization,
|
||||||
com.raytheon.uf.common.menus,
|
com.raytheon.uf.common.menus,
|
||||||
|
|
|
@ -19,9 +19,13 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.edex.plugin.satellite.mcidas;
|
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.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
@ -29,8 +33,12 @@ import java.util.TimeZone;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.opengis.referencing.crs.ProjectedCRS;
|
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.esb.Headers;
|
||||||
import com.raytheon.edex.exception.DecoderException;
|
import com.raytheon.edex.exception.DecoderException;
|
||||||
|
import com.raytheon.edex.plugin.satellite.SatelliteDecoderException;
|
||||||
import com.raytheon.edex.util.satellite.SatSpatialFactory;
|
import com.raytheon.edex.util.satellite.SatSpatialFactory;
|
||||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
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
|
* 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
|
* 07/12/2015 ---- mjames@ucar Account for GOES E and W UNIWISC AREA file numbers
|
||||||
* 01/21/2016 ---- mjames@ucar Cleanup
|
* 01/21/2016 ---- mjames@ucar Cleanup
|
||||||
|
* 10/24/2017 ---- mjames@ucar Native support for PNG-compressed AREA files.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author
|
* @author
|
||||||
|
@ -99,6 +108,10 @@ public class McidasSatelliteDecoder {
|
||||||
|
|
||||||
final int SIZE_OF_AREA = 256;
|
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 HALFPI = Math.PI / 2.;
|
||||||
|
|
||||||
private static final double RTD = 180. / Math.PI;
|
private static final double RTD = 180. / Math.PI;
|
||||||
|
@ -144,7 +157,6 @@ public class McidasSatelliteDecoder {
|
||||||
*/
|
*/
|
||||||
private PluginDataObject[] decodeMcidasArea(byte[] data) throws Exception {
|
private PluginDataObject[] decodeMcidasArea(byte[] data) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
byte[] area = null;
|
byte[] area = null;
|
||||||
byte[] nonAreaBlock = new byte[data.length - SIZE_OF_AREA];
|
byte[] nonAreaBlock = new byte[data.length - SIZE_OF_AREA];
|
||||||
area = new byte[SIZE_OF_AREA];
|
area = new byte[SIZE_OF_AREA];
|
||||||
|
@ -230,21 +242,13 @@ public class McidasSatelliteDecoder {
|
||||||
navsize = calibrationOffset - navBlockOffset;
|
navsize = calibrationOffset - navBlockOffset;
|
||||||
}
|
}
|
||||||
byte[] navigation = new byte[navsize];
|
byte[] navigation = new byte[navsize];
|
||||||
|
byte[] nonNavBlock = new byte[nonAreaBlock.length - navsize];
|
||||||
System.arraycopy(nonAreaBlock, 0, navigation, 0, navsize);
|
System.arraycopy(nonAreaBlock, 0, navigation, 0, navsize);
|
||||||
|
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);
|
||||||
|
|
||||||
/* 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...
|
|
||||||
*/
|
|
||||||
long bandBits = ((long) bandMap33to64 << 32) | bandMap1to32;
|
long bandBits = ((long) bandMap33to64 << 32) | bandMap1to32;
|
||||||
long bandBitsCount = Long.bitCount(bandBits);
|
long bandBitsCount = Long.bitCount(bandBits);
|
||||||
if (nBands != bandBitsCount && nBands > 1) {
|
if (nBands != bandBitsCount && nBands > 1) {
|
||||||
|
@ -281,11 +285,16 @@ public class McidasSatelliteDecoder {
|
||||||
// TODO: Line pad if not a multiple of four bytes
|
// TODO: Line pad if not a multiple of four bytes
|
||||||
if ((linePrefixLength == 0) && (nBytesPerElement == 1)
|
if ((linePrefixLength == 0) && (nBytesPerElement == 1)
|
||||||
&& (nBands == 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) {
|
} else if (nBytesPerElement == 1) {
|
||||||
byte[] imageBytes = new byte[nLines * nElementsPerLine];
|
byte[] imageBytes = new byte[nLines * nElementsPerLine];
|
||||||
|
@ -328,6 +337,47 @@ public class McidasSatelliteDecoder {
|
||||||
return result;
|
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:
|
* Reference:
|
||||||
* http://www.ssec.wisc.edu/mcidas/doc/prog_man/2006/formats-13a.html
|
* 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"?>
|
<?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">
|
<requestPatterns xmlns:ns2="group">
|
||||||
<regex>AREA[0-9]{4}.*</regex>
|
<regex>AREA[0-9]{4}.*</regex>
|
||||||
|
<regex>pnga2area</regex>
|
||||||
<regex>.*uniwisc.*</regex>
|
<regex>.*uniwisc.*</regex>
|
||||||
</requestPatterns>
|
</requestPatterns>
|
||||||
|
|
Loading…
Add table
Reference in a new issue