public WritableRaster readAsRaster()

in endorsed/src/org.apache.sis.storage.sql/main/org/apache/sis/storage/sql/postgis/RasterReader.java [184:299]


    public WritableRaster readAsRaster(final ChannelDataInput input) throws IOException {
        final ByteOrder order;
        switch (input.readUnsignedByte()) {
            case 0:  order = ByteOrder.BIG_ENDIAN;    break;
            case 1:  order = ByteOrder.LITTLE_ENDIAN; break;
            default: throw malformed(input);
        }
        input.buffer.order(order);
        final int version = input.readUnsignedShort();
        if (version != 0) {
            throw new IOException(Errors.format(Errors.Keys.UnsupportedFormatVersion_2, "WKB", version));
        }
        final int  numBands = input.readUnsignedShort();
        final double scaleX = input.readDouble();
        final double scaleY = input.readDouble();
        final double ipX    = input.readDouble();
        final double ipY    = input.readDouble();
        final double skewX  = input.readDouble();
        final double skewY  = input.readDouble();
        gridToCRS = new AffineTransform2D(scaleX, skewY, skewX, scaleY, ipX, ipY);
        srid = input.readInt();
        if (numBands == 0) {      // Empty raster.
            return null;
        }
        final int width  = input.readUnsignedShort();
        final int height = input.readUnsignedShort();
        final Band[] bands = new Band[numBands];
        for (int i=0; i<numBands; i++) {
            final Band band = new Band(input.readUnsignedByte());
            final int dataType = band.getDataBufferType();
            final Number nodata;
            switch (dataType) {
                case DataBuffer.TYPE_BYTE:                 nodata = input.readUnsignedByte(); break;
                case DataBuffer.TYPE_BYTE | OPPOSITE_SIGN: nodata = input.readByte(); break;
                case DataBuffer.TYPE_SHORT:                nodata = input.readShort(); break;
                case DataBuffer.TYPE_USHORT:               nodata = input.readUnsignedShort(); break;
                case DataBuffer.TYPE_INT:                  nodata = input.readInt(); break;
                case DataBuffer.TYPE_INT | OPPOSITE_SIGN:  nodata = input.readUnsignedInt(); break;
                case DataBuffer.TYPE_FLOAT:                nodata = input.readFloat(); break;
                case DataBuffer.TYPE_DOUBLE:               nodata = input.readDouble(); break;
                case DataBuffer.TYPE_UNDEFINED:            // For detecting case conflict at compile time.
                default: throw malformed(input);
            }
            if (band.hasNodata()) {
                band.noDataValue = nodata;
            }
            if (band.isOffline()) {
                throw new RasterFormatException("Offline raster data is not yet supported.");
            } else {
                /*
                 * Read sample values for the current band.
                 * We ignore the signed or unsigned nature of values here.
                 */
                final int sampleSize  = band.getDataTypeSize();                 // In bits: 1, 2, 4, 8, 16, 32 or 64.
                final int elementSize = DataBuffer.getDataTypeSize(dataType);   // Same as above except for 1, 2, 4.
                final int length = Math.toIntExact(JDK18.ceilDiv(Math.multiplyFull(width, height) * sampleSize, elementSize));
                final Object data;
                switch (dataType & ~OPPOSITE_SIGN) {
                    case DataBuffer.TYPE_USHORT:
                    case DataBuffer.TYPE_SHORT:  data =            input.readShorts (length);  break;
                    case DataBuffer.TYPE_BYTE:   data =            input.readBytes  (length);  break;
                    case DataBuffer.TYPE_INT:    data =            input.readInts   (length);  break;
                    case DataBuffer.TYPE_FLOAT:  data = band.toNaN(input.readFloats (length)); break;
                    case DataBuffer.TYPE_DOUBLE: data = band.toNaN(input.readDoubles(length)); break;
                    default: throw malformed(input);
                }
                band.data = data;
            }
            bands[i] = band;
        }
        /*
         * All bands should be of the same type. We could convert data to
         * a common type (the largest one), but this is not yet implemented.
         */
        final Band firstBand = bands[0];
        int dataType = firstBand.getDataBufferType();
        final int length = Array.getLength(firstBand.data);
        final Object[] arrays = (Object[]) Array.newInstance(firstBand.data.getClass(), numBands);
        arrays[0] = firstBand.data;
        for (int b=1; b<numBands; b++) {
            final Band band = bands[b];
            if (band.getDataBufferType() != dataType || Array.getLength(band.data) != length) {
                throw new RasterFormatException("Bands of different types are not yet supported.");
            }
            arrays[b] = band.data;
        }
        this.bands = bands;
        /*
         * Create the `DataBuffer` and `SampleModel` for the bands.
         * Objects are only wrappers; pixel values are not copied.
         */
        final DataBuffer buffer;
        switch (dataType &= ~OPPOSITE_SIGN) {
            case DataBuffer.TYPE_BYTE:    buffer = new DataBufferByte  ((byte  [][]) arrays, length); break;
            case DataBuffer.TYPE_SHORT:   buffer = new DataBufferShort ((short [][]) arrays, length); break;
            case DataBuffer.TYPE_USHORT:  buffer = new DataBufferUShort((short [][]) arrays, length); break;
            case DataBuffer.TYPE_INT:     buffer = new DataBufferInt   ((int   [][]) arrays, length); break;
            case DataBuffer.TYPE_FLOAT:   buffer = new DataBufferFloat ((float [][]) arrays, length); break;
            case DataBuffer.TYPE_DOUBLE:  buffer = new DataBufferDouble((double[][]) arrays, length); break;
            default: throw malformed(input);
        }
        SampleModel model;
        final int sampleSize = firstBand.getDataTypeSize();
        if (sampleSize >= Byte.SIZE) {
            model = new BandedSampleModel(dataType, width, height, numBands);
        } else if (numBands == 1) {
            model = new MultiPixelPackedSampleModel(dataType, width, height, sampleSize);
        } else {
            throw new RasterFormatException("Multi-bands packed model is not yet supported.");
        }
        if (model.equals(cachedModel)) {
            model = cachedModel;
        }
        cachedModel = model;
        return WritableRaster.createWritableRaster(model, buffer, null);
    }