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

Add new PixelAlphaRepresentation property and implement for TPixel types #1420

Merged
merged 11 commits into from
Nov 20, 2020

Conversation

JimBobSquarePants
Copy link
Member

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following matches the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

The first in several PRs targetting #1396

  • Adds a new nullable PixelAlphaRepresentation property to the PixelTypeInfo class which describes the pixel alpha behavior for the image pixel format.
  • Implements the property values for all TPixel types.
  • Adds tests for each implementation.

I've automated the test generation using T4 as there's a lot of repetition.

Follow up PRs will wire up image formats and optimize methods based upon the new information.

@codecov
Copy link

codecov bot commented Nov 8, 2020

Codecov Report

Merging #1420 (8a065ac) into master (f77801e) will increase coverage by 0.56%.
The diff coverage is 85.36%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1420      +/-   ##
==========================================
+ Coverage   83.07%   83.63%   +0.56%     
==========================================
  Files         707      733      +26     
  Lines       31831    31919      +88     
  Branches     3590     3590              
==========================================
+ Hits        26445    26697     +252     
+ Misses       4669     4508     -161     
+ Partials      717      714       -3     
Flag Coverage Δ
unittests 83.63% <85.36%> (+0.56%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...ions/Generated/Argb32.PixelOperations.Generated.cs 100.00% <ø> (ø)
...tions/Generated/Bgr24.PixelOperations.Generated.cs 100.00% <ø> (ø)
...ions/Generated/Bgra32.PixelOperations.Generated.cs 100.00% <ø> (ø)
...ns/Generated/Bgra5551.PixelOperations.Generated.cs 98.16% <ø> (ø)
...rations/Generated/L16.PixelOperations.Generated.cs 100.00% <ø> (ø)
...erations/Generated/L8.PixelOperations.Generated.cs 100.00% <ø> (ø)
...ations/Generated/La16.PixelOperations.Generated.cs 98.16% <ø> (ø)
...ations/Generated/La32.PixelOperations.Generated.cs 98.16% <ø> (ø)
...tions/Generated/Rgb24.PixelOperations.Generated.cs 100.00% <ø> (ø)
...tions/Generated/Rgb48.PixelOperations.Generated.cs 100.00% <ø> (ø)
... and 91 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f77801e...8a065ac. Read the comment docs.

@JimBobSquarePants JimBobSquarePants requested a review from a team November 9, 2020 15:27
Copy link
Member

@antonfirsov antonfirsov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something, it's not clear from the PR if we intended to control PixelTypeInfo for pixel types like HalfVector4 from T4 or from regular .cs.

The product changes look good otherwise, but also want to have a look at tests.

@JimBobSquarePants
Copy link
Member Author

Unless I'm missing something, it's not clear from the PR if we intended to control PixelTypeInfo for pixel types like HalfVector4 from T4 or from regular .cs.

Normally cs. That's what I've done with all the existing types that are not already using T4 for the pixel operations. I added the codegen to the original ones because I didn't want to create multiple classes but I've just pushed a change that separates out the generation so we can't accidently assign None

@JimBobSquarePants JimBobSquarePants requested review from antonfirsov and a team November 16, 2020 14:39
@JimBobSquarePants
Copy link
Member Author

How are we doing here? I'd like to merge and move on.

@antonfirsov
Copy link
Member

@JimBobSquarePants I can take a final look tomorrow (sill want to check the tests), but if its too late feel free to merge. You can also base next PR on current state since the product changes look good.

@JimBobSquarePants
Copy link
Member Author

Yeah, no worries. This PR adds a lot of (admittedly autogenerated) tests so well worth a review.

Copy link
Member

@antonfirsov antonfirsov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Concerns about exposing an unimplemented feature.
  2. I think in tests we should use T4 only when it's absolutely necessary, and whenever it's possible to implement a test in the base type, we should push the code up.

public void PixelTypeInfoHasCorrectAlphaRepresentation()
{
var alphaRepresentation = <#=pixelType#>.PixelOperations.Instance.GetPixelTypeInfo().AlphaRepresentation;
Assert.Equal(<#=alpha#>, alphaRepresentation);
Copy link
Member

@antonfirsov antonfirsov Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned whether this type of testing is valuable here. It's almost a copy-paste of the product logic.

I would rather try something like this in the base type:

[Fact]
public void PixelAlphaRepresentation_DefinesPresenceOfAlphaChannel()
{
    TPixel pixel = default;
    pixel.FromRgba32(new Rgba32(0, 0, 0, 123));

    Rgba32 dest;
    pixel.ToRgba32(ref dest);

    bool hasAlpha = GetPixelTypeInfo().AlphaRepresentation != PixelAlphaRepresentation.None;
    byte exectedAlpha = hasAlpha ? 123 : 255;    

    Assert.Equal(expectedAlpha, dest.A);
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All I'm testing here is the correct assignment of the value. Any behavior based upon that value is the responsibility of the caller.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That test could be useful though to check I assigned it correctly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All I'm testing here is the correct assignment of the value.

My point explained further:
it's very easy to make a mistake in such a test here (tempting to copy-paste product code to test code brainlessly, especially if it's generated), but practically impossible, if the test is validating against actual behavior.

But I'm fine with keeping this as an improvement opportunity for later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented a version of the test in the base class. The original test remains in the generated versions though as I do not use code generation for this property in the source.

/// If a color channel value in a premultiplied format is greater than the alpha
/// channel, the standard source-over blending math results in an additive blend.
/// </summary>
Associated,
Copy link
Member

@antonfirsov antonfirsov Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless we know image formats where we can report this by Identify this will be a completely unimplemented virtual feature for now. I know it's me who proposed the API, but now I'm concerned exposing as-is, feels a bit misleading and confusing.

How about replacing the summary with the text "Reserved for future use", and moving the docs into a comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dunno... We'd then have to have a tracking issue etc. What if someone want to implement their own pixel format type and use it to represent already premultiplied pixel data?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a pixel had premultiplied alpha would it break any of our processors methods? if it would then either we need to go though and add checks to any that it will break even if we don't do anything else with it or we need to fix them so they function with eather type.

Copy link
Member Author

@JimBobSquarePants JimBobSquarePants Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unlikely I think that it would break anything. I couldn't be 100% sure though but since no one has raised an issue suggesting that it does so far I think we're ok.

Copy link
Member

@antonfirsov antonfirsov Nov 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will only make difference when we start utilizing it in ResizeProcessor. There's still some non-trivial work out there: Should we watch for the value in the processor code, before calling PixelOperations.To/FromVector4? Or should we do it right in the converter method overriding request to PixelConversionModifiers.Premultiply?

Other than this I don't really see open questions here according to my understanding of the feature, but I'm generally reluctant for defining public API-s for stuff that is not even prototyped.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be overthinking in this case, IDK.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the best place to do the check is in PixelConversionModifiers.Premultiply. However, there are still per-pixel calls to Premultiply in the convolution API.

Copy link
Member

@antonfirsov antonfirsov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, great job!

@JimBobSquarePants JimBobSquarePants merged commit a9e2b4c into master Nov 20, 2020
@JimBobSquarePants JimBobSquarePants deleted the js/pixel-type-info branch November 20, 2020 12:01
JimBobSquarePants added a commit that referenced this pull request Mar 13, 2021
Add new PixelAlphaRepresentation property and implement for TPixel types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants