Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Rik Cabanier
On Wed, May 28, 2014 at 10:36 PM, Noel Gordon noel.gor...@gmail.com wrote:

 canvas.toDataURL supports an optional quality argument for the
 “image/jpeg” mime type to control image compression. Developers have no
 control over “image/png” compression.

 “image/png” is a lossless image compression format and the proposal is to
 allow developers some control over the compression process. For example, a
 developer might request maximum compression once their art work is complete
 to minimize the encoded image size for transmission or storage. Encoding
 speed might be more important while creating the work, and less compression
 (faster encoding) could be requested in that case.

 An optional toDataURL parameter on [0.0 ... 1.0], similar to the optional
 quality argument used for image/jpeg, could be defined for “image/png” to
 control compression:

canvas.toDataURL(“image/png”, [compression-control-value]);

 The default value, and how the browser controls the image encoder to gain
 more compression with increasing values, would be internal implementation
 details of the browser.


This has been requested before. ie
http://lists.whatwg.org/pipermail/help-whatwg.org/2013-May/001209.html
The conclusion was that this can be accomplished using JavaScript. There
are JS libraries that can compress images and performance is very good
these days.

If you're worried about blocking the main thread, you can use workers to do
offline processing.


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Glenn Maynard
On Thu, May 29, 2014 at 1:32 AM, Rik Cabanier caban...@gmail.com wrote:

 This has been requested before. ie

http://lists.whatwg.org/pipermail/help-whatwg.org/2013-May/001209.html
 The conclusion was that this can be accomplished using JavaScript. There
 are JS libraries that can compress images and performance is very good
 these days.


This is a nonsensical conclusion.  People shouldn't have to pull in a PNG
compressor and deflate code when a PNG compression API already exists on
the platform.  This is an argument against adding toDataURL at all, which
is a decision that's already been made.

-- 
Glenn Maynard


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Justin Novosad
On Thu, May 29, 2014 at 9:59 AM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, May 29, 2014 at 1:32 AM, Rik Cabanier caban...@gmail.com wrote:

  This has been requested before. ie
 
 http://lists.whatwg.org/pipermail/help-whatwg.org/2013-May/001209.html
  The conclusion was that this can be accomplished using JavaScript. There
  are JS libraries that can compress images and performance is very good
  these days.
 

 This is a nonsensical conclusion.  People shouldn't have to pull in a PNG
 compressor and deflate code when a PNG compression API already exists on
 the platform.  This is an argument against adding toDataURL at all, which
 is a decision that's already been made.

 +1
I would add that the fact that such libraries even exist despite the fact
that the platform provides a competing API proves that the API is not what
it should be.

Also, an encoder written in JavaScript cannot produce color-managed results
because we do not have any APIs that expose color profiles. I am guessing
that png encoders written in JS probably assume that data returned by
getImageData is in sRGB, which is often not the case.  toDataURL, on the
other hand, has the possibility of encoding into the png, a color profile
that expresses the canvas backing store's color space. I know current
implementations of toDataURL don't do that, but we could and should.

   -Justin


 --
 Glenn Maynard



Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Rik Cabanier
On Thu, May 29, 2014 at 7:45 AM, Justin Novosad ju...@google.com wrote:

 On Thu, May 29, 2014 at 9:59 AM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, May 29, 2014 at 1:32 AM, Rik Cabanier caban...@gmail.com wrote:

  This has been requested before. ie
 
 http://lists.whatwg.org/pipermail/help-whatwg.org/2013-May/001209.html
  The conclusion was that this can be accomplished using JavaScript. There
  are JS libraries that can compress images and performance is very good
  these days.
 

 This is a nonsensical conclusion.  People shouldn't have to pull in a PNG
 compressor and deflate code when a PNG compression API already exists on
 the platform.  This is an argument against adding toDataURL at all, which
 is a decision that's already been made.

 +1
 I would add that the fact that such libraries even exist despite the fact
 that the platform provides a competing API proves that the API is not what
 it should be.

 Also, an encoder written in JavaScript cannot produce color-managed
 results because we do not have any APIs that expose color profiles. I am
 guessing that png encoders written in JS probably assume that data returned
 by getImageData is in sRGB, which is often not the case.  toDataURL, on the
 other hand, has the possibility of encoding into the png, a color profile
 that expresses the canvas backing store's color space. I know current
 implementations of toDataURL don't do that, but we could and should.


I'm not sure if we want to bake in the device's color profile into the
output bitmap by default because on re-import it will then go through color
management and its pixels will look different from the unmanaged canvas
ones.


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Rik Cabanier
On Thu, May 29, 2014 at 6:59 AM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, May 29, 2014 at 1:32 AM, Rik Cabanier caban...@gmail.com wrote:

 This has been requested before. ie

 http://lists.whatwg.org/pipermail/help-whatwg.org/2013-May/001209.html
 The conclusion was that this can be accomplished using JavaScript. There
 are JS libraries that can compress images and performance is very good
 these days.


 This is a nonsensical conclusion.  People shouldn't have to pull in a PNG
 compressor and deflate code when a PNG compression API already exists on
 the platform.  This is an argument against adding toDataURL at all, which
 is a decision that's already been made.


If performance is good, why would this not be acceptable?
It seems that this would be a fragmented solution as file formats and
features would be added at different stages to browser engines. Would there
be a way to feature test that the optional arguments are supported?


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Justin Novosad
On Thu, May 29, 2014 at 11:21 AM, Rik Cabanier caban...@gmail.com wrote:




 On Thu, May 29, 2014 at 7:45 AM, Justin Novosad ju...@google.com wrote:

 On Thu, May 29, 2014 at 9:59 AM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, May 29, 2014 at 1:32 AM, Rik Cabanier caban...@gmail.com
 wrote:

  This has been requested before. ie
 
 http://lists.whatwg.org/pipermail/help-whatwg.org/2013-May/001209.html
  The conclusion was that this can be accomplished using JavaScript.
 There
  are JS libraries that can compress images and performance is very good
  these days.
 

 This is a nonsensical conclusion.  People shouldn't have to pull in a PNG
 compressor and deflate code when a PNG compression API already exists on
 the platform.  This is an argument against adding toDataURL at all, which
 is a decision that's already been made.

 +1
 I would add that the fact that such libraries even exist despite the fact
 that the platform provides a competing API proves that the API is not what
 it should be.

 Also, an encoder written in JavaScript cannot produce color-managed
 results because we do not have any APIs that expose color profiles. I am
 guessing that png encoders written in JS probably assume that data returned
 by getImageData is in sRGB, which is often not the case.  toDataURL, on the
 other hand, has the possibility of encoding into the png, a color profile
 that expresses the canvas backing store's color space. I know current
 implementations of toDataURL don't do that, but we could and should.


 I'm not sure if we want to bake in the device's color profile into the
 output bitmap by default because on re-import it will then go through color
 management and its pixels will look different from the unmanaged canvas
 ones.


I think you meant encode rather than bake in that above sentence.
Correct?  Currently, the non-color managed output of toDataURL has the
display profile baked in.

Take the following code:

var image = newImage()
image.src = canvas.toDataURL('image/png');
image.onload = function() { canvas.drawImage(image, 0, 0); }

Under a non color managed implementation, the above code will not modify
the content of the canvas in any way because there are no color space
conversions since the png is not color managed... All is good.  If
toDataURL encoded a color profile, the behavior would remain unchanged
because the color correction applied during the image decode would do
nothing (converting to and from the same color space). Again, all is good.

However, if the data URL was to be sent over the network to be decoded on a
different machine, then you are screwed with a non-color managed png,
because the sender's display's color profile is baked-in to the image but
there is no color profile meta data to allow the receiver to bring the
image into a known color space.

   -Justin


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Rik Cabanier
On Thu, May 29, 2014 at 8:50 AM, Justin Novosad ju...@google.com wrote:




 On Thu, May 29, 2014 at 11:21 AM, Rik Cabanier caban...@gmail.com wrote:




 On Thu, May 29, 2014 at 7:45 AM, Justin Novosad ju...@google.com wrote:

 On Thu, May 29, 2014 at 9:59 AM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, May 29, 2014 at 1:32 AM, Rik Cabanier caban...@gmail.com
 wrote:

  This has been requested before. ie
 
 http://lists.whatwg.org/pipermail/help-whatwg.org/2013-May/001209.html
  The conclusion was that this can be accomplished using JavaScript.
 There
  are JS libraries that can compress images and performance is very good
  these days.
 

 This is a nonsensical conclusion.  People shouldn't have to pull in a
 PNG
 compressor and deflate code when a PNG compression API already exists on
 the platform.  This is an argument against adding toDataURL at all,
 which
 is a decision that's already been made.

 +1
 I would add that the fact that such libraries even exist despite the
 fact that the platform provides a competing API proves that the API is not
 what it should be.

 Also, an encoder written in JavaScript cannot produce color-managed
 results because we do not have any APIs that expose color profiles. I am
 guessing that png encoders written in JS probably assume that data returned
 by getImageData is in sRGB, which is often not the case.  toDataURL, on the
 other hand, has the possibility of encoding into the png, a color profile
 that expresses the canvas backing store's color space. I know current
 implementations of toDataURL don't do that, but we could and should.


 I'm not sure if we want to bake in the device's color profile into the
 output bitmap by default because on re-import it will then go through color
 management and its pixels will look different from the unmanaged canvas
 ones.


 I think you meant encode rather than bake in that above sentence.
 Correct?  Currently, the non-color managed output of toDataURL has the
 display profile baked in.

 Take the following code:

 var image = newImage()
 image.src = canvas.toDataURL('image/png');
 image.onload = function() { canvas.drawImage(image, 0, 0); }

 Under a non color managed implementation, the above code will not modify
 the content of the canvas in any way because there are no color space
 conversions since the png is not color managed... All is good.  If
 toDataURL encoded a color profile, the behavior would remain unchanged
 because the color correction applied during the image decode would do
 nothing (converting to and from the same color space). Again, all is good.


That's right.
The values of pixels on the canvas are the same on every machine, but we
have many different types of monitors. The png's that are generated should
all be identical pixel-wise but their attached profiles might be different.


 However, if the data URL was to be sent over the network to be decoded on
 a different machine, then you are screwed with a non-color managed png,
 because the sender's display's color profile is baked-in to the image but
 there is no color profile meta data to allow the receiver to bring the
 image into a known color space.


You are screwed either way :-)
I think authors are going to be surprised that pixels will end up
different. (Imagine taking screenshots of achievements in a game that are
put in an online gallery)
If you put the profile in and it is different from sRGB, the png will look
different from the original canvas because you now will go through an
intermediate sRGB space which will warp the color range.

As an example, I did a toDataURL of this codepen example:
http://codepen.io/Boshnik/pen/vFbgw
I then opened it up in Photoshop, attached my monitor profile and wrote a
small script that does a difference on them:
http://cabanier.github.io/BlendExamples/images.htm

If you run windows, you will see that there's content in the canvas output.
For some reason, Mac doesn't do any color conversion on any browser.
Even on my own system, there's a difference because of the sRGB conversion:
http://cabanier.github.io/BlendExamples/screenshot.png


[whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Glenn Maynard
On Thu, May 29, 2014 at 10:29 AM, Rik Cabanier caban...@gmail.com
javascript:_e(%7B%7D,'cvml','caban...@gmail.com'); wrote:

 If performance is good, why would this not be acceptable?


 I don't know why we'd provide an API to compress PNGs, then tell people to
use a script reimplementation if they want to set a common option.

As far as performance, I'm not sure about PNG, but there's no way that a JS
compressor would compete with native for JPEG.  Assembly (MMX, SSE)
optimization gives a significant performance improvement over C, so I doubt
JS will ever be in the running.  (
http://www.libjpeg-turbo.org/About/Performance)


 It seems that this would be a fragmented solution as file formats and
 features would be added at different stages to browser engines. Would there
 be a way to feature test that the optional arguments are supported?


No more than any other new feature.  I don't know if feature testing for
dictionary arguments has been solved yet (it's come up before), but if not
that's something that needs to be figured out in general.

-- 
Glenn Maynard



-- 
Glenn Maynard


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Rik Cabanier
On Thu, May 29, 2014 at 12:17 PM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, May 29, 2014 at 10:29 AM, Rik Cabanier caban...@gmail.com wrote:

 If performance is good, why would this not be acceptable?


  I don't know why we'd provide an API to compress PNGs, then tell people
 to use a script reimplementation if they want to set a common option.

 As far as performance, I'm not sure about PNG, but there's no way that a
 JS compressor would compete with native for JPEG.  Assembly (MMX, SSE)
 optimization gives a significant performance improvement over C, so I doubt
 JS will ever be in the running.  (
 http://www.libjpeg-turbo.org/About/Performance)


MMX, SSE is being addressed using asm.js.
We're also just dealing with screenshots here. I doubt people are going to
do toDataURL at 60fps.




 It seems that this would be a fragmented solution as file formats and
 features would be added at different stages to browser engines. Would there
 be a way to feature test that the optional arguments are supported?


 No more than any other new feature.  I don't know if feature testing for
 dictionary arguments has been solved yet (it's come up before), but if not
 that's something that needs to be figured out in general.



Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Rik Cabanier
On Thu, May 29, 2014 at 1:33 PM, Rik Cabanier caban...@gmail.com wrote:




 On Thu, May 29, 2014 at 12:17 PM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, May 29, 2014 at 10:29 AM, Rik Cabanier caban...@gmail.com
 wrote:

 If performance is good, why would this not be acceptable?


  I don't know why we'd provide an API to compress PNGs, then tell people
 to use a script reimplementation if they want to set a common option.

 As far as performance, I'm not sure about PNG, but there's no way that a
 JS compressor would compete with native for JPEG.  Assembly (MMX, SSE)
 optimization gives a significant performance improvement over C, so I doubt
 JS will ever be in the running.  (
 http://www.libjpeg-turbo.org/About/Performance)


 MMX, SSE is being addressed using asm.js.
 We're also just dealing with screenshots here. I doubt people are going to
 do toDataURL at 60fps.


Here's a link to an experiment:
http://multimedia.cx/eggs/playing-with-emscripten-and-asm-js/



  It seems that this would be a fragmented solution as file formats and
 features would be added at different stages to browser engines. Would there
 be a way to feature test that the optional arguments are supported?


 No more than any other new feature.  I don't know if feature testing for
 dictionary arguments has been solved yet (it's come up before), but if not
 that's something that needs to be figured out in general.






Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Glenn Maynard
On Thu, May 29, 2014 at 3:33 PM, Rik Cabanier caban...@gmail.com wrote:

 MMX, SSE is being addressed using asm.js.


Assembly language is inherently incompatible with the Web.

We already have an API for compressing images, and compression level is
an ordinary input to image compressors, yet you're arguing that rather than
add the option to the API we have, we should require people to bundle their
own image compressors and write MMX assembly on the Web to make it fast.
 Sorry if I think that's a bizarre argument...

We're also just dealing with screenshots here. I doubt people are going to
 do toDataURL at 60fps.


(I hope we can all see more use cases than just screenshots.)

-- 
Glenn Maynard


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Boris Zbarsky

On 5/29/14, 5:13 PM, Glenn Maynard wrote:

Assembly language is inherently incompatible with the Web.


A SIMD API, however is not.  Under the hood, it can be implemented in 
terms of MMX, SSE, NEON, or just by forgetting about the SIMD bit and 
pretending like you have separate operations.  In particular, you could 
have a SIMD API that desugars to plain JS as the default implementation 
in browsers but that JITs can recognize and vectorize as they desire. 
This sort of API will happen, for sure.


No opinion on the PNG encoder thing.

-Boris


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Glenn Maynard
On Thu, May 29, 2014 at 4:21 PM, Boris Zbarsky bzbar...@mit.edu wrote:

 On 5/29/14, 5:13 PM, Glenn Maynard wrote:

 Assembly language is inherently incompatible with the Web.


 A SIMD API, however is not.  Under the hood, it can be implemented in
 terms of MMX, SSE, NEON, or just by forgetting about the SIMD bit and
 pretending like you have separate operations.  In particular, you could
 have a SIMD API that desugars to plain JS as the default implementation in
 browsers but that JITs can recognize and vectorize as they desire. This
 sort of API will happen, for sure.


I doubt it, at least with performance competitive with native assembly.  We
certainly shouldn't delay features while we hope for it.

-- 
Glenn Maynard


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Rik Cabanier
On Thu, May 29, 2014 at 2:28 PM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, May 29, 2014 at 4:21 PM, Boris Zbarsky bzbar...@mit.edu wrote:

  On 5/29/14, 5:13 PM, Glenn Maynard wrote:
 
  Assembly language is inherently incompatible with the Web.
 
 
  A SIMD API, however is not.  Under the hood, it can be implemented in
  terms of MMX, SSE, NEON, or just by forgetting about the SIMD bit and
  pretending like you have separate operations.  In particular, you could
  have a SIMD API that desugars to plain JS as the default implementation
 in
  browsers but that JITs can recognize and vectorize as they desire. This
  sort of API will happen, for sure.
 

 I doubt it, at least with performance competitive with native assembly.  We
 certainly shouldn't delay features while we hope for it.


You don't need to hope for it. The future is already here:
http://www.j15r.com/blog/2014/05/23/Box2d_2014_Update
asm.js will be fast on all modern browsers before this feature would ship.
As an author, I'd certainly prefer the most flexible solution that works
everywhere.


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Glenn Maynard
On Thu, May 29, 2014 at 4:50 PM, Rik Cabanier caban...@gmail.com wrote:

 You don't need to hope for it. The future is already here:
 http://www.j15r.com/blog/2014/05/23/Box2d_2014_Update
 asm.js will be fast on all modern browsers before this feature would ship.
 As an author, I'd certainly prefer the most flexible solution that works
 everywhere.


I don't have the time to read all of this, but it doesn't seem to have
anything to do with SIMD instruction sets (which are notoriously difficult
to generalize).

Anyway, this has derailed the thread.  We have an API for compression
already.  It already supports a compression level argument for JPEG.
 Having an equivalent argument for PNG is a no-brainer.  The only
difference to JPEG is that it should be described as the compression
level rather than quality level, since with PNG it has no effect on
quality, only the file size and time it takes to compress.

-- 
Glenn Maynard


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Nils Dagsson Moskopp
Glenn Maynard gl...@zewt.org writes:

 We have an API for compression already.  It already supports a
 compression level argument for JPEG.  Having an equivalent argument
 for PNG is a no-brainer.  The only difference to JPEG is that it
 should be described as the compression level rather than quality
 level, since with PNG it has no effect on quality, only the file size
 and time it takes to compress.

What benefit does it give then if the result is the same perceptually?

-- 
Nils Dagsson Moskopp // erlehmann
http://dieweltistgarnichtso.net


Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Kornel Lesiński
On 29.05.2014, at 23:19, Glenn Maynard gl...@zewt.org wrote:
 
 Anyway, this has derailed the thread.  We have an API for compression
 already.  It already supports a compression level argument for JPEG.
 Having an equivalent argument for PNG is a no-brainer.  The only
 difference to JPEG is that it should be described as the compression
 level rather than quality level, since with PNG it has no effect on
 quality, only the file size and time it takes to compress.

I don't think it's a no-brainer. There are several ways it could be interpreted:


1. As zlib's compression level

However, this has marginal utility, because these days even the maximum level, 
even on mobile devices, is reasonably fast. Lower level would be useful only 
for very large images on very slow devices, but UAs can have a good heuristic 
for ensuring reasonable compression time without any input from the page's 
author.

I expect exponential increase in computing power make this setting completely 
irrelevant by the time it's implemented in most browsers.


2. Enable brute-force search for best combinations of zlib's compression level, 
memory level and window size 

OptiPNG and pngcrush show that maximum settings in zlib don't always give 
smallest file and best compression is obtained by trying hundreds of 
combinations of zlib parameters.

If browsers choose this approach for a high compression level that will be a 
couple of *orders of magnitude* slower than the first option. If different 
vendors don't agree on orders of magnitude of time it takes to compress an 
image, such parameter could be unusable.


3. Compression parameters in other gzip implementations

For example Zopfli compressor produces files smaller than zlib, but is much 
much slower. Instead of 1-9 scale it takes number of iterations as the 
compression level.

And it can even use a totally different approach to compression level: I've 
modified Zopfli[1] to make it aim for constant processing time on any machine. 
Faster machines will just produce smaller files. Browsers could use this 
approach to ensure every PNG is compressed in  0.5s or so, or the compression 
level parameter could be a number of seconds to spend on the compression.


And that's just for lossless PNG. It's possible to encode standard PNG in a 
*lossy* fashion (http://pngmini.com/lossypng.html), and there are few ways to 
do it:

Images can be converted to PNG-8 (vector quantization is a form of lossy 
compression) and then compression level could be interpreted as number of 
unique colors or mean square error of the quantized image (the latter option is 
used by http://pngquant.org). This generally makes files 3-4 times smaller, but 
has a limit on maximum quality that can be achieved.

For higher quality it's possible to make truecolor PNG lossy by taking 
advantage of the fact that PNG filters are predictors. Instead of writing all 
pixels as they are in the input image the encoder can replace some pixels with 
values matching filters' prediction. This simplifies the data and generally 
halves the file size (and costs almost no extra CPU time). The threshold used 
to choose between source and predicted values for pixels acts similarly to 
JPEG's quality level.

So there are multiple ways such parameter can be interpreted, and it can result 
in wildly different visual quality, file size and time taken to compress the 
image.

-- 
regards, Kornel

[1] https://github.com/pornel/zopfli



Re: [whatwg] Proposal: toDataURL “image/png” compression control

2014-05-29 Thread Glenn Maynard
On Thu, May 29, 2014 at 5:34 PM, Nils Dagsson Moskopp 
n...@dieweltistgarnichtso.net wrote:

  and time it takes to compress.

 What benefit does it give then if the result is the same perceptually?


Time it takes to compress.  There's a big difference between waiting one
second for a quick save and 60 seconds for a high-compression final export.


On Thu, May 29, 2014 at 7:31 PM, Kornel Lesiński kor...@geekhood.net
wrote:

 I don't think it's a no-brainer. There are several ways it could be
 interpreted:


The API is a no-brainer.  That doesn't mean it should be done carelessly.
 That said, how it's implemented is an implementation detail, just like the
JPEG quality parameter, though it should probably be required to never use
lossy compression (strictly speaking this may not actually be required
today...).

FYI, I don't plan to spend much time arguing for this feature.  My main
issue is with the just do it in script argument.  It would probably help
for people more strongly interested in this to show a comparison of
resulting file sizes and the relative amount of time it takes to compress
them.

-- 
Glenn Maynard