1414import ucar .ma2 .ArrayByte ;
1515import ucar .ma2 .ArrayInt ;
1616import ucar .ma2 .ArrayFloat ;
17+ import ucar .ma2 .ArrayShort ;
1718import ucar .ma2 .DataType ;
1819import ucar .ma2 .Index ;
1920import ucar .ma2 .IndexIterator ;
@@ -211,19 +212,15 @@ void writeGrid(GridDatatype grid, Array data, boolean greyScale, double xStart,
211212 // write the data first
212213 MAMath .MinMax dataMinMax = grid .getMinMaxSkipMissingData (data );
213214 if (greyScale ) {
214- ArrayByte result = replaceMissingValuesAndScale (grid , data , dataMinMax );
215- nextStart = geotiff .writeData ((byte []) result .getStorage (), imageNumber );
215+ data = replaceMissingValuesAndScale (grid , data , dataMinMax );
216+ nextStart = writeData (data , DataType .UBYTE );
217+ } else if (dtype == DataType .FLOAT ) {
218+ // Backwards compatibility shim
219+ data = replaceMissingValues (grid , data , dataMinMax );
220+ nextStart = writeData (data , dtype );
216221 } else {
217- if (dtype == DataType .BYTE || dtype == DataType .UBYTE ) {
218- ArrayByte result = coerceByte (data );
219- nextStart = geotiff .writeData ((byte []) result .getStorage (), imageNumber );
220- } else if (dtype .isIntegral ()) {
221- ArrayInt result = coerceInt (data );
222- nextStart = geotiff .writeData ((int []) result .getStorage (), imageNumber );
223- } else {
224- ArrayFloat result = replaceMissingValues (grid , data , dataMinMax );
225- nextStart = geotiff .writeData ((float []) result .getStorage (), imageNumber );
226- }
222+ data = coerceData (data , dtype );
223+ nextStart = writeData (data , dtype );
227224 }
228225
229226 // set the width and the height
@@ -472,8 +469,16 @@ public static HashMap<Integer, Color> createColorMap(int[] flag_values, String[]
472469 return colorMap ;
473470 }
474471
475- private ArrayByte coerceByte (Array data ) {
476- ArrayByte array = (ArrayByte ) Array .factory (DataType .BYTE , data .getShape ());
472+ /**
473+ * Coerce a given data array into an array of bytes.
474+ * Always returns a copy. No data safety check is performed.
475+ *
476+ * @param data input data array (of any data type)
477+ * @param isUnsigned coerce to unsigned bytes
478+ * @return integer data array
479+ */
480+ static ArrayByte coerceByte (Array data , boolean isUnsigned ) {
481+ ArrayByte array = (ArrayByte ) Array .factory (isUnsigned ? DataType .UBYTE : DataType .BYTE , data .getShape ());
477482 IndexIterator dataIter = data .getIndexIterator ();
478483 IndexIterator resultIter = array .getIndexIterator ();
479484
@@ -484,8 +489,56 @@ private ArrayByte coerceByte(Array data) {
484489 return array ;
485490 }
486491
487- private ArrayInt coerceInt (Array data ) {
488- ArrayInt array = (ArrayInt ) Array .factory (DataType .INT , data .getShape ());
492+ /**
493+ * Coerce a given data array into an array of 16-bit integers.
494+ * Always returns a copy. No data safety check is performed.
495+ *
496+ * @param data input data array (of any data type)
497+ * @param isUnsigned coerce to unsigned integers
498+ * @return integer data array
499+ */
500+ static ArrayShort coerceShort (Array data , boolean isUnsigned ) {
501+ ArrayShort array = (ArrayShort ) Array .factory (isUnsigned ? DataType .USHORT : DataType .SHORT , data .getShape ());
502+ IndexIterator dataIter = data .getIndexIterator ();
503+ IndexIterator resultIter = array .getIndexIterator ();
504+
505+ while (dataIter .hasNext ()) {
506+ resultIter .setIntNext (dataIter .getIntNext ());
507+ }
508+
509+ return array ;
510+ }
511+
512+
513+ /**
514+ * Coerce a given data array into an array of 32-bit integers.
515+ * Always returns a copy. No data safety check is performed.
516+ *
517+ * @param data input data array (of any data type)
518+ * @param isUnsigned coerce to unsigned integers
519+ * @return integer data array
520+ */
521+ static ArrayInt coerceInt (Array data , boolean isUnsigned ) {
522+ ArrayInt array = (ArrayInt ) Array .factory (isUnsigned ? DataType .UINT : DataType .INT , data .getShape ());
523+ IndexIterator dataIter = data .getIndexIterator ();
524+ IndexIterator resultIter = array .getIndexIterator ();
525+
526+ while (dataIter .hasNext ()) {
527+ resultIter .setIntNext (dataIter .getIntNext ());
528+ }
529+
530+ return array ;
531+ }
532+
533+ /**
534+ * Coerce a given data array into an array of 32-bit floats.
535+ * Always returns a copy. No data safety check is performed.
536+ *
537+ * @param data input data array (of any data type)
538+ * @return float data array
539+ */
540+ static ArrayFloat coerceFloat (Array data ) {
541+ ArrayFloat array = (ArrayFloat ) Array .factory (DataType .FLOAT , data .getShape ());
489542 IndexIterator dataIter = data .getIndexIterator ();
490543 IndexIterator resultIter = array .getIndexIterator ();
491544
@@ -845,19 +898,15 @@ public void writeGrid(GeoReferencedArray array, boolean greyScale, DataType dtyp
845898 int nextStart ;
846899 MAMath .MinMax dataMinMax = MAMath .getMinMaxSkipMissingData (data , array );
847900 if (greyScale ) {
848- ArrayByte result = replaceMissingValuesAndScale (array , data , dataMinMax );
849- nextStart = geotiff .writeData ((byte []) result .getStorage (), pageNumber );
901+ data = replaceMissingValuesAndScale (array , data , dataMinMax );
902+ nextStart = writeData (data , DataType .UBYTE );
903+ } else if (dtype == DataType .FLOAT ) {
904+ // Backwards compatibility shim
905+ data = replaceMissingValues (array , data , dataMinMax );
906+ nextStart = writeData (data , dtype );
850907 } else {
851- if (dtype == DataType .BYTE || dtype == DataType .UBYTE ) {
852- ArrayByte result = coerceByte (data );
853- nextStart = geotiff .writeData ((byte []) result .getStorage (), pageNumber );
854- } else if (dtype .isIntegral ()) {
855- ArrayInt result = coerceInt (data );
856- nextStart = geotiff .writeData ((int []) result .getStorage (), pageNumber );
857- } else {
858- ArrayFloat result = replaceMissingValues (array , data , dataMinMax );
859- nextStart = geotiff .writeData ((float []) result .getStorage (), pageNumber );
860- }
908+ data = coerceData (data , dtype );
909+ nextStart = writeData (data , dtype );
861910 }
862911
863912 // set the width and the height
@@ -867,5 +916,32 @@ public void writeGrid(GeoReferencedArray array, boolean greyScale, DataType dtyp
867916 writeMetadata (greyScale , xStart , yStart , xInc , yInc , height , width , pageNumber , nextStart , dataMinMax , proj , dtype );
868917 pageNumber ++;
869918 }
919+
920+ static Array coerceData (Array data , DataType dtype ) {
921+ if (dtype == DataType .BYTE || dtype == DataType .UBYTE ) {
922+ data = coerceByte (data , dtype .isUnsigned ());
923+ } else if (dtype == DataType .SHORT || dtype == DataType .USHORT ) {
924+ data = coerceShort (data , dtype .isUnsigned ());
925+ } else if (dtype == DataType .INT || dtype == DataType .UINT ) {
926+ data = coerceInt (data , dtype .isUnsigned ());
927+ } else if (dtype .isFloatingPoint ()) {
928+ data = coerceFloat (data );
929+ }
930+ return data ;
931+ }
932+
933+ private int writeData (Array data , DataType dtype ) throws IOException {
934+ int nextStart ;
935+ if (dtype == DataType .BYTE || dtype == DataType .UBYTE ) {
936+ nextStart = geotiff .writeData ((byte []) data .getStorage (), pageNumber );
937+ } else if (dtype == DataType .SHORT || dtype == DataType .USHORT ) {
938+ nextStart = geotiff .writeData ((short []) data .getStorage (), pageNumber );
939+ } else if (dtype == DataType .INT || dtype == DataType .UINT ) {
940+ nextStart = geotiff .writeData ((int []) data .getStorage (), pageNumber );
941+ } else {
942+ nextStart = geotiff .writeData ((float []) data .getStorage (), pageNumber );
943+ }
944+ return nextStart ;
945+ }
870946}
871947
0 commit comments