Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement premultiplied alpha in PixelType #52

Closed
2 tasks done
p0nce opened this issue Jun 28, 2023 · 11 comments
Closed
2 tasks done

Implement premultiplied alpha in PixelType #52

p0nce opened this issue Jun 28, 2023 · 11 comments
Labels
enhancement New feature or request

Comments

@p0nce
Copy link
Collaborator

p0nce commented Jun 28, 2023

  • A. If we add 6 new pixel types (lap, rgbap for 8-bit, 16-bit and 32-bit FP), then we can support pre-multiplied with quite a bit of changes. The interesting thing is that PNG with the unspecified ipHone PNG does support premultiplied

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.

  • 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!

  • 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.

@p0nce p0nce added the enhancement New feature or request label Jun 28, 2023
@p0nce
Copy link
Collaborator Author

p0nce commented Jun 28, 2023

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
  • Must choose whether to YAGNI this or not. Pixel Type would become non-POD, because of ICC. Bleh. => YAGNI
    • Can something with an ICC be POD? A reference type for this would be a bit meh. => unrelated

@p0nce
Copy link
Collaborator Author

p0nce commented Jun 30, 2023

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?

@p0nce
Copy link
Collaborator Author

p0nce commented Jul 7, 2023

Very much related to #20

@p0nce
Copy link
Collaborator Author

p0nce commented Jul 21, 2023

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.

@p0nce
Copy link
Collaborator Author

p0nce commented Aug 4, 2023

Premultiplied alpha doesn't seem to strictly need ICC profile or full colorspace struct. We can still chug along, ignoring colorspace.

@p0nce
Copy link
Collaborator Author

p0nce commented Jul 28, 2024

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?

@p0nce
Copy link
Collaborator Author

p0nce commented Jul 28, 2024

This is breaking change, since decoders are now free to give premultiplied output.

  • Implement the premul PixelTypes
  • convert tool can take -premul as flag to encode premultiplied and unpremultiplied
  • Implement that QOIX can encode/decode rgbap8
  • Implement that QOIX can encode/decode rgbap16
  • Implement that QOIX can encode/decode lap16 => this one untested
  • Implement that QOIX can encode/decode lap8
  • Make and document breaking change

@p0nce p0nce changed the title Investigate the idea of premultiplied alpha in PixelType Implement premultiplied alpha in PixelType Jul 28, 2024
@p0nce
Copy link
Collaborator Author

p0nce commented Jul 28, 2024

Encoding 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

@p0nce
Copy link
Collaborator Author

p0nce commented Jul 29, 2024

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.

@p0nce
Copy link
Collaborator Author

p0nce commented Jul 29, 2024

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

@p0nce
Copy link
Collaborator Author

p0nce commented Jul 29, 2024

Available in v3.0.0

@p0nce p0nce closed this as completed Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant