Re: [img-conversion] Encode and decode should take/produce streams (#15)

So, I've looked in to this a decent bit. Basically, it is pretty reasonable and easy to do APIs of the form

    (streaming input chunks) -> (big binary blob)

i.e. these two are achievable

    (streaming encoded chunks) -> (decoded binary blob)
    (streaming decoded chunks) -> (encoded binary blob)

More concretely, how this probably looks like is a writable stream with a `result` promise. Example, pre-bikeshedding, and applying some speculative fixes for [open writable stream API issues](https://github.com/whatwg/streams/labels/writable%20streams):

```js
const decoder = new ImageDecoder();
// assume it does sniffing on input
// alternately it could accept a target type as a constructor parameter and error if the input does not conform

// Use case 1: manually assembling bytes and feeding them in
const writer = decoder.getWriter();
writer.write(chunk1); // chunks should be Uint8Arrays, or maybe any BufferSource
writer.write(chunk2);
...

decoder.result.then(img => {
  // here img is an ImageBitmap or ImageData or Blob...
  // bikeshed to determine which is most applicable
  // or, let the author choose via a constructor parameter
});

/////////

// Use case 2: piping from a readable stream
// Here we use a fetch body stream as an example.

fetch(...).then(response => response.body.pipeTo(decoder));
decoder.result.then(img => { /* as before */ });
```

Things are basically the same for the encoder example, where you feed it a stream of raw bytes and it gives you back a specified image type.

You probably also want conveniences like `ImageDecoder.canDecode("image/png")` or `ImageEncoder.canEncode("image/jpeg")`. Bikeshedding possibilities there: naming could be can(En|De)code[Type] and return the ""/"maybe"/"probably" values, or maybe for images things are a bit more straightforward than for video/audio, and we could just do `.supports("image/png")` returning a boolean.

---

The above is the most obviously doable API. There are other more complicated possibilities as well.

For example, some versions of image formats support streaming on both sides: you feed in some raw bytes to the encoder, and it progressively gives you parts of the resulting png. Or you feed in some encoded bytes to the decoder, and it gives you progressive scanlines of the jpeg. This would be a transform stream, with { writable, readable } sides. But it only applies to some variants of some image formats, and as the jpeg scanlines example shows, it can involve codec-specific information.

Another potentially-interesting high-level API is something like allowing `imgEl.srcObject = readableStream`, to bypass all this low-level stuff and just tell the browser "please get these bytes into my image in some way." This would be most useful for synthetic streams, instead of ones derived directly from fetch.

----

Hope this helps! I'm happy to start speccing this kind of thing if there's implementer interest.

---
Reply to this email directly or view it on GitHub:
https://github.com/WICG/img-conversion/issues/15#issuecomment-144862477

Received on Thursday, 1 October 2015 22:04:18 UTC