Closed p0nce closed 4 months ago
In future world, PixelType will probably explode in complexity with opEquals being non-trivial. What would be those additions? I can think of color spaces, specific encoding, chroma sitting, etc. Some types will also not make sense, like:
(RGB, ubyte, premultiplied, null colorspace) // no good to have 'premultiplied alpha' without alpha
The reading of the color library made by Manu is interesting and points towards the likely shape of a future "Colorspace" concept, which would either the same as PixelType or PixelType would be purely derived from it.
Now, is there a way to support the less types "legacy" PixelType?
Very much related to #20
Important to note that some practical overlay images are largely transparent and can benefit a lot from premultiplied encoding, but not really from "ignore color for fully transparent areas" which is a less strong thing somehow. That would make the QOIX codec not lossless in 8-bit contrarily to today.
Premultiplied alpha doesn't seem to strictly need ICC profile or full colorspace struct. We can still chug along, ignoring colorspace.
Numbers for 3 real world overlays with low opacity, 8-bit sRGB
Input | PNG | PNG-premul | Reduction | QOIX | QOIX-premul | Reduction |
---|---|---|---|---|---|---|
Graillon overlay | 582 kb | 332 kb | 0.57 | 643 kb | 425 kb | 0.66 |
Lens overlay | 328 kb | 161 kb | 0.49 | 360 kb | 183 kb | 0.5 |
Inner overlay | 157 kb | 64 kb | 0.4 | 171 kb | 65 kb | 0.38 |
However there is no way to signal premul alpha in PNG in a way that is compatible, apart from doing the whole iphone transformation which is not trivial. Or maybe ICC can do it?
This is breaking change, since decoders are now free to give premultiplied output.
convert
tool can take -premul
as flag to encode premultiplied and unpremultipliedEncoding rgba8 vs rgbap8 images. QOIX is modified to just signal premultiplication, with a QOIX_SRGB_PREMUL = 2 constant.
Without QOIX premul:
*** image of size 553.0 kb: test-images\graillon-overlay.png
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
11.96 ms 7.63 ms 67.44 34.87 10.23670 643.4 kb 1.1635
*** image of size 333.2 kb: test-images\inner-overlay.png
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
12.34 ms 5.18 ms 183.96 138.56 3.09554 360.4 kb 1.0818
*** image of size 155.1 kb: test-images\lens-overlay.png
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
7.32 ms 2.42 ms 181.59 129.64 3.18724 171.2 kb 1.1037
TOTAL decode mpps encode mpps bit-per-pixel
144.33 101.02 5.50649
TOTAL time = 0.268667 secs
With QOIX premul:
*** image of size 553.0 kb: test-images\graillon-overlay.png
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
11.67 ms 4.74 ms 108.60 71.25 6.77234 425.6 kb 0.7697
*** image of size 333.2 kb: test-images\inner-overlay.png
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
12.41 ms 3.57 ms 267.34 187.77 1.57401 183.3 kb 0.5501
*** image of size 155.1 kb: test-images\lens-overlay.png
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
6.82 ms 1.48 ms 296.70 230.61 1.21489 65.3 kb 0.4207
TOTAL decode mpps encode mpps bit-per-pixel
224.21 163.21 3.18708
TOTAL time = 0.086449 secs
QOIX lap8 vs la8
lap8
*** image of size 12.0 kb: test-images\auburn-sounds-grey.png (lap8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
1.05 ms 0.15 ms 1288.41 266.39 0.61613 14.8 kb 1.2399
*** image of size 334.7 kb: test-images\circles-grey.png (lap8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
13.04 ms 0.67 ms 1567.38 114.21 3.36591 430.8 kb 1.2873
*** image of size 124.4 kb: test-images\dice.png (lap8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
5.06 ms 0.34 ms 1415.93 130.75 3.29490 193.1 kb 1.5518
*** image of size 276.4 kb: test-images\fish.png (lap8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
18.86 ms 0.91 ms 2818.71 238.37 1.09694 344.6 kb 1.2466
*** image of size 7.5 kb: test-images\lfo-shapes-grey.png (lap8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
0.41 ms 0.03 ms 1647.06 222.22 1.21186 8.3 kb 1.1098
*** image of size 3.5 kb: test-images\logo-grey.png (lap8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
0.10 ms 0.04 ms 387.46 188.63 2.46763 4.3 kb 1.2366
*** image of size 442.1 kb: test-images\renegate-tsp.png (lap8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
9.04 ms 0.54 ms 927.82 77.56 11.93615 727.3 kb 1.6450
TOTAL decode mpps encode mpps bit-per-pixel
1436.11 176.88 3.42707
TOTAL time = 0.121858 secs
la8
*** image of size 12.0 kb: test-images\auburn-sounds-grey.png (la8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
1.07 ms 0.49 ms 404.78 353.91 0.61613 14.8 kb 1.2399
*** image of size 334.7 kb: test-images\circles-grey.png (la8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
13.96 ms 6.42 ms 163.41 124.96 3.46099 443.0 kb 1.3236
*** image of size 124.4 kb: test-images\dice.png (la8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
5.52 ms 1.87 ms 257.10 172.72 3.26215 191.1 kb 1.5363
*** image of size 276.4 kb: test-images\fish.png (la8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
17.41 ms 7.59 ms 338.93 239.71 1.09476 343.9 kb 1.2441
*** image of size 7.5 kb: test-images\lfo-shapes-grey.png (la8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
0.95 ms 0.22 ms 255.71 204.38 1.31257 9.0 kb 1.2020
*** image of size 3.5 kb: test-images\logo-grey.png (la8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
0.13 ms 0.09 ms 152.51 129.15 2.37946 4.2 kb 1.1924
*** image of size 442.1 kb: test-images\renegate-tsp.png (la8)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
7.86 ms 4.50 ms 110.80 97.99 12.61877 768.9 kb 1.7391
TOTAL decode mpps encode mpps bit-per-pixel
240.46 188.98 3.53498
TOTAL time = 0.315611 secs
this data set has no very transparent overlays though.
QOIX rgba16 vs rgbap16 rgba16
*** image of size 2081.0 kb: test-images\inner-overlay.png (rgba16)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
34.28 ms 11.27 ms 84.65 60.31 6.68820 778.8 kb 0.3742
*** image of size 1342.8 kb: test-images\lens-overlay.png (rgba16)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
20.13 ms 5.62 ms 78.24 57.48 7.66927 411.9 kb 0.3068
TOTAL decode mpps encode mpps bit-per-pixel
81.44 58.90 7.17874
TOTAL time = 0.34264 secs
rgbap16
*** image of size 2081.0 kb: test-images\inner-overlay.png (rgbap16)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
44.53 ms 1.49 ms 642.33 62.97 4.22834 492.3 kb 0.2366
*** image of size 1342.8 kb: test-images\lens-overlay.png (rgbap16)
orig dec decode decode mpps encode mpps bit-per-pixel size reduction
22.48 ms 0.56 ms 784.31 56.29 3.53842 190.1 kb 0.1415
TOTAL decode mpps encode mpps bit-per-pixel
713.32 59.63 3.88338
TOTAL time = 0.109883 secs
Available in v3.0.0
or
B. Decode unpremultiplied always, do not keep track of status, just provide ways to do it and undo it at the discretion of the user. This is simpler, but people will not get the advantages of premultiplied or less often.
[x] Does premultiplied alpha encodes better, and how much better in terms of space? Check with PNG and QOIX. => YES, 2x better for some QOIX overlays!
[x] Implement function to premultiply, or unpremultiply. This is the easy part, already exist in Dplug ImageKnob.
Big question is (above) whether to keep that information in the type system (PixelType) or not. This is NOT a LayoutOptions, and I don't think it should be a separate status also. Premultiplied alpha is better for compositing, but not for editing. It also looses a bit of data, but it repeatable.