in endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/RasterWriter.java [204:295]
public void write(final Raster raster, final ChannelDataOutput output) throws IOException {
if (gridToCRS == null) {
gridToCRS = new AffineTransform();
}
final SampleModel sm = raster.getSampleModel();
final int numBands = sm.getNumBands();
final int width = raster.getWidth();
final int height = raster.getHeight();
/*
* The `direct` flag tells whether we can write the backing array directly or whether we need
* to use the pixel iterator because of sample model complexity. We can write arrays directly
* if each array contains a single band and the scanline stride is equal to the raster width.
*/
boolean direct = false; // Default value for sample models of unknown type.
int dataType = sm.getDataType();
int pixelType = Band.bufferToPixelType(dataType);
if (sm instanceof SinglePixelPackedSampleModel) {
if (numBands == 1) {
direct = ((SinglePixelPackedSampleModel) sm).getScanlineStride() == width;
} else {
final int sampleSize = Arrays.stream(sm.getSampleSize()).max().orElse(0);
if (sampleSize >= 1 && sampleSize <= Short.SIZE) {
dataType = (sampleSize <= Byte.SIZE ? DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT);
pixelType = Band.bufferToPixelType(dataType);
}
}
} else if (sm instanceof MultiPixelPackedSampleModel) {
if (dataType == DataBuffer.TYPE_BYTE) {
final MultiPixelPackedSampleModel mp = (MultiPixelPackedSampleModel) sm;
final int sampleSize = mp.getPixelBitStride();
direct = (mp.getScanlineStride() * Byte.SIZE == width * sampleSize);
pixelType = Band.sizeToPixelType(sampleSize);
}
} else if (sm instanceof ComponentSampleModel) {
direct = (((ComponentSampleModel) sm).getScanlineStride() == width);
}
/*
* Write the header followed by all bands.
*/
output.buffer.order(byteOrder);
output.writeByte(byteOrder == ByteOrder.LITTLE_ENDIAN ? 1 : 0);
output.writeShort(0); // WKB version number.
output.writeShort(ensureUnsignedShort("numBands", numBands));
output.writeDouble(gridToCRS.getScaleX());
output.writeDouble(gridToCRS.getScaleY());
output.writeDouble(gridToCRS.getTranslateX());
output.writeDouble(gridToCRS.getTranslateY());
output.writeDouble(gridToCRS.getShearX());
output.writeDouble(gridToCRS.getShearY());
output.writeInt(srid);
output.writeShort(ensureUnsignedShort("width", width));
output.writeShort(ensureUnsignedShort("height", height));
for (int b=0; b<numBands; b++) {
final Number fill = (noDataValues != null && b < noDataValues.length) ? noDataValues[b] : null;
final Band band = new Band(pixelType, fill);
output.writeByte(band.header);
switch (dataType) {
case DataBuffer.TYPE_USHORT: // Fall through
case DataBuffer.TYPE_SHORT: output.writeShort (fill != null ? fill.intValue() : 0); break;
case DataBuffer.TYPE_BYTE: output.writeByte (fill != null ? fill.intValue() : 0); break;
case DataBuffer.TYPE_INT: output.writeInt (fill != null ? fill.intValue() : 0); break;
case DataBuffer.TYPE_FLOAT: output.writeFloat (fill != null ? fill.floatValue() : Float.NaN); break;
case DataBuffer.TYPE_DOUBLE: output.writeDouble(fill != null ? fill.doubleValue() : Double.NaN); break;
default: throw new RasterFormatException(Errors.format(Errors.Keys.UnsupportedType_1, dataType));
}
if (direct) {
final DataBuffer buffer = raster.getDataBuffer();
final int offset = buffer.getOffsets()[b];
final int length = width * height;
switch (dataType) {
case DataBuffer.TYPE_BYTE: output.write (((DataBufferByte) buffer).getData(b), offset, length); break;
case DataBuffer.TYPE_USHORT: output.writeShorts (((DataBufferUShort) buffer).getData(b), offset, length); break;
case DataBuffer.TYPE_SHORT: output.writeShorts (((DataBufferShort) buffer).getData(b), offset, length); break;
case DataBuffer.TYPE_INT: output.writeInts (((DataBufferInt) buffer).getData(b), offset, length); break;
case DataBuffer.TYPE_FLOAT: output.writeFloats (((DataBufferFloat) buffer).getData(b), offset, length); break;
case DataBuffer.TYPE_DOUBLE: output.writeDoubles(((DataBufferDouble) buffer).getData(b), offset, length); break;
}
} else {
final PixelIterator it = new PixelIterator.Builder().create(raster);
while (it.next()) {
switch (dataType) {
case DataBuffer.TYPE_USHORT: // Fall through
case DataBuffer.TYPE_SHORT: output.writeShort (it.getSample(b)); break;
case DataBuffer.TYPE_BYTE: output.writeByte (it.getSample(b)); break;
case DataBuffer.TYPE_INT: output.writeInt (it.getSample(b)); break;
case DataBuffer.TYPE_FLOAT: output.writeFloat (it.getSample(b)); break;
case DataBuffer.TYPE_DOUBLE: output.writeDouble(it.getSample(b)); break;
}
}
}
}
}