@Override
    public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IOException {
      if (stream == null) {
        throw new IllegalStateException("output == null!");
      }
      boolean lossless = WebpMetadata.DEFAULT_LOSSLESS;
      float quality = WebpMetadata.DEFAULT_ENCODING_QUALITY;
      if (param != null && param.canWriteCompressed()) {
        lossless = false;
        if (param.getCompressionMode() == ImageWriteParam.MODE_EXPLICIT) {
          quality = param.getCompressionQuality();
        }
      }

      Raster srcRas = getRaster(image);

      int minX = srcRas.getMinX();
      int minY = srcRas.getMinY();
      int width = srcRas.getWidth();
      int height = srcRas.getHeight();
      int maxX = minX + width;
      int maxY = minY + height;

      byte[] data = new byte[width * height * 4];
      // TODO: This code is the inefficient fallback dealing with any color/sample model.
      // However, we've restricted things in the canEncodeImage method so we might as well try
      // to do it more efficiently
      int index = 0;
      SampleModel sampleModel = srcRas.getSampleModel();
      int bands = sampleModel.getNumBands();
      if (bands == 1) {
        // Indexed image but not found in raster
        return;
      }
      assert bands >= 2 && bands <= 4; // enforced in canEncodeImage
      DataBuffer buffer = srcRas.getDataBuffer();
      if (bands >= 3) {
        for (int y = minY; y < maxY; y++) {
          for (int x = minX; x < maxX; x++) {
            for (int band = 0; band < bands; band++) {
              int sample = sampleModel.getSample(x, y, band, buffer);
              data[index++] = (byte)sample;
            }
            if (bands == 3) {
              data[index++] = (byte)255; // implicit alpha in an RGB (not RGBA) image
            }
          }
        }
      }
      else {
        assert bands == 2;
        for (int y = minY; y < maxY; y++) {
          for (int x = minX; x < maxX; x++) {
            byte sample = (byte)sampleModel.getSample(x, y, 0, buffer);
            data[index++] = sample;
            data[index++] = sample;
            data[index++] = sample;
            byte alpha = (byte)sampleModel.getSample(x, y, 1, buffer);
            data[index++] = alpha;
          }
        }
      }

      // See https://developers.google.com/speed/webp/docs/api
      byte[] encoded;
      if (lossless) {
        encoded = libwebp.WebPEncodeLosslessRGBA(data, width, height, 4 * width);
      }
      else {
        encoded = libwebp.WebPEncodeRGBA(data, width, height, 4 * width, (int)(100 * quality));
      }
      stream.write(encoded);
    }
@Override
    public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param)