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

Control of trns chunk #1629

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

mastrodaro
Copy link

Allowed to pass pallete w/o alpha, added alpha parameter to check this while creating png stream. No alpha will result in skiping trns to be generated.

Thanks for contributing!

  • Have you updated CHANGELOG.md?

Copy link
Collaborator

@zbjornson zbjornson left a comment

Choose a reason for hiding this comment

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

Looks good! Thanks for contributing this. I have a slightly different API proposal to consider, but am open to the current API also.

/**
* _For creating indexed PNGs._ Decide to include alpha channel. Defaults to true.
*/
alpha?: boolean
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of adding an export settings, what do you think of reusing the existing alpha setting from the canvas context attributes, e.g.:

const ctx = canvas.getContext("2d", {alpha: false}); // alpha: false
canvas.toBuffer("image/png", {palette: new Uint8Array([r1, g1, b1, r2, g2, b2])}); // so no alpha here

We currently automatically switch to RGB24 if alpha is false:

// alpha: false forces use of RGB24
Local<Value> alpha = Nan::Get(ctxAttributes, Nan::New("alpha").ToLocalChecked()).ToLocalChecked();
if (alpha->IsBoolean() && !Nan::To<bool>(alpha).FromMaybe(false)) {
format = CAIRO_FORMAT_RGB24;

but we don't have to do that since RGB16_565 and RGB30 also have no alpha channel (i.e. {pixelFormat: "RGB30", alpha: false} is valid).

What do you think of that API? If you're okay with it, then the lines I quoted above just need to change to this:

      if (alpha->IsBoolean() && !Nan::To<bool>(alpha).FromMaybe(false) && format == CAIRO_FORMAT_ARGB32) {
        format = CAIRO_FORMAT_RGB24;
      }

and one or two places in this PR need to be updated to (1) store the alpha property value and (2) use it during encoding.

Copy link
Author

Choose a reason for hiding this comment

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

This was my primary idea but after I saw this format selection algorithm I though it was too risky to modify the relation of RGB24 and alpha. I will try to reuse alpha from context creation.

Copy link
Author

Choose a reason for hiding this comment

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

also I dont know how to read value that is set in backend (Imagebackend) [at Context2d CanvasRenderingContext2d.cc] to use used in PNG.h
there is somehow generated cairo_image_surface_get_format and I would like to achieve something like cairo_image_surface_get_alpha after I set alpha in backend

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you need to add a new member to the Context2d or Canvas class that stores whether or not alpha is in use (add to CanvasRenderingContext2d.h or Canvas.h). If you don't do that, then I don't think there's a way for us to know if, say, an A8 image palette has transparency or not.

To use that value when encoding, you could add a property to the PngClosure struct (in closure.h) like bool alpha, and set it on the closure when setting up the PNG encoding task (everywhere you see parsePNGArgs used in Canvas.cc). That closure is passed in to the PNG encoder.

(Sorry for the slow reply, will try to respond faster so we can land this.)

Copy link
Author

Choose a reason for hiding this comment

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

Ok I will try this hopefully tomorrow - last time I had problems to retrieve back data I set on backend.

Copy link
Author

Choose a reason for hiding this comment

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

My changes so far:
same as with format I added alpha

static_cast<ImageBackend*>(canvas->backend())->setFormat(format);
static_cast<ImageBackend*>(canvas->backend())->setAlpha(alpha);

Not sure if needed but also added (similar to format) in header file:

static NAN_GETTER(GetFormat);
static NAN_GETTER(GetAlpha);

Not sure what should be default for alpha in construct - probably true to do not introduce breaking changes.
ImageBackend.h:

bool alpha = true;

So further I added (similar to format) in ImageBackend:

void ImageBackend::setAlpha(bool _alpha) {
	this->alpha = _alpha;
}

and also getter.

In result I was not able to fetch alpha in PNG.h similar as its done with format cairo_format_t format = cairo_image_surface_get_format(surface);

And I assume I should fetch it from surface somehow.

p.s. what exactly is closure, isnt it the params I pass to the canvas.createPNGStream? Then I am trying to move alpha I introduced in this object to the construct of attributes in call canvas.getContext.

Copy link
Collaborator

Choose a reason for hiding this comment

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

static NAN_GETTER(GetFormat);
static NAN_GETTER(GetAlpha);

You can omit these. They're used for adding getters that are accessible from JS. Adding them would mean adding non-standard features, which we try to avoid.

Not sure what should be default for alpha in construct

This shouldn't matter as long as you're setting alpha in all code paths (i.e. for all pixelFormats) in GetContext.

In result I was not able to fetch alpha in PNG.h

I would:

  1. Add bool alpha to PngClosure in closure.h
  2. Set that property everywhere in Canvas.cc where you see parsePNGArgs in use currently, like closure.alpha = canvas->backend()->alpha.
  3. Use it in PNG.h, like closure->closure->alpha.

(Untested, but roughly that...)

what exactly is closure

It's not a great name, especially since we have closure->closure in some places (and they're two different structs/classes!). It's just a struct of data that we define (in closure.h) that libpng passes around through all of its APIs for us, allowing us to have access to whatever data we need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants