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

Parsing Transform tags #2

Open
fabulousduck opened this issue Oct 4, 2018 · 12 comments
Open

Parsing Transform tags #2

fabulousduck opened this issue Oct 4, 2018 · 12 comments

Comments

@fabulousduck
Copy link

Within the prtr ICC profile, a set of tags which I will list below define a set of color transform. The issue here is that these tags can regularly defy the size set for them in the tag in the tag table. A solution on how to parse them would be nice as I cannot figure this out myself.

Some info about these special tags can be found in this doc.

  • A2B0
  • A2B2
  • A2B1
  • B2A0
  • B2A1
  • B2A2
@lovell
Copy link
Owner

lovell commented Oct 4, 2018

Hello, at the moment this module only looks for tags with a tagType it knows about, namely desc and text - https://github.com/lovell/icc/blob/master/index.js#L83-L109

Perhaps it should provide a bit more data about the presence of other tags, including the 6 you list, exposing the raw data as a Buffer. In the case of the A2B and B2A tags, these would be look up tables (LUTs) with a tagType of mft1 (8 bit) or mft2 (16-bit).

Happy to accept a PR if you're able.

@fabulousduck
Copy link
Author

I will try to implement this tag in my ICC implementation first. When I get that working i will port that tag implementation to you ICC parser.

@xi xi mentioned this issue Dec 13, 2018
@tristaaan
Copy link

What is the status of this, I've looked through #3 and seems to meet the goals of this issue? I'd be interested in extending this so that functions could be derived from the A2Bx, B2Ax tables.

@lovell
Copy link
Owner

lovell commented Jan 2, 2020

I'd be very happy to accept a new PR if you're able, thank you. The work in #3 could be used as the basis with the addition of more unit tests to cover all the extra logic.

@lovell
Copy link
Owner

lovell commented Mar 27, 2023

I've added a few new tests and fixtures to the repo, including the ICC "probe" profiles that include sample transform tags. This should make testing a little easier should anyone like to work on a follow up to the original PR at #3.

@Aminelahlou
Copy link

Aminelahlou commented Apr 28, 2023

I am trying to work on a PR, do you have an idea how you would like the final json format to be ?

Would it be something like this ? with a major of upgrade since we put all previous answers in a key header

{
header: {
        version: '2.1',
        intent: 'Perceptual',
        cmm: 'Adobe',
        deviceClass: 'Printer',
        colorSpace: 'CMYK',
        connectionSpace: 'Lab',
        platform: 'Apple',
        manufacturer: 'Adobe',
        creator: 'Adobe',
        tagCount: 10,
    },
tables:
    {
        A2B0: [],
        A2B2: [],
        A2B1: [],
        B2A0: [],
        B2A1: [],
        B2A2: [],
        gamt: []
    }
}

or should we just have something like this

{
version: '2.1',
intent: 'Perceptual',
cmm: 'Adobe',
deviceClass: 'Printer',
colorSpace: 'CMYK',
connectionSpace: 'Lab',
platform: 'Apple',
manufacturer: 'Adobe',
creator: 'Adobe',
tagCount: 10,
tables:
    {
        A2B0: [],
        A2B2: [],
        A2B1: [],
        B2A0: [],
        B2A1: [],
        B2A2: [],
        gamt: []
    }
}

EDIT: I have written some code that looks ok and would need some refining,

EDIT2: I put the changes in a cloned repo here: https://github.com/Aminelahlou/icc/

@lovell
Copy link
Owner

lovell commented Apr 30, 2023

@Aminelahlou Thank you very much for picking this up and tackling it again.

I think I'd prefer not to alter the existing response structure and instead add to it.

Perhaps we can have A2B0, A2B1 and A2B2 as direct properties in the response? Or maybe an a2b property with perceptual, colorimetric and saturation as children might be easier to understand?

In terms of what lives under this, the structure in the closed-but-not-forgotten PR #3 looked pretty good to me.

https://github.com/lovell/icc/pull/3/files#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346R62

If the raw lookup table data could use the relevant TypedArray e.g. Uint8Array or Uint16Array then that would be great.

{
  version: '2.1',
  ...
  a2b: {
    perceptual: {
      inputChannels: ...
      matrix: ...
      ...
    },
    colorimetric: { ... }
    ...
  }
}

@MathieuLoutre
Copy link

I'm trying to achieve this at the moment. Is there anything wrong with what PR #3 is doing at the moment? I see it needs more tests but the current state of parsing is useful (not sure returning a buffer instead of a processed array makes sense). I'm working on attaching functions for A2B/B2A/gamt but I'm struggling with the testing step.

I see the probe profile in the fixtures but I'm unsure about how to proceed to see if the extracted tables are correct or if the transform functions derived give the correct output.

@lovell
Copy link
Owner

lovell commented Sep 26, 2023

@MathieuLoutre Thanks for taking a look at this, always happy to accept/review a (partial) PR if you're able.

If you hadn't seen, the expected behaviour of the probe profile is documented at https://www.color.org/probeprofile.xalter

The rendering intent transforms (BToA tags) of the probe profile ignore the a* and b* components of incoming PCS colors, and map the L* components directly to monotone tints of process colorants. (L* = 0 is rendered as maximum colorant coverage, and L* = 100 is rendered as unmarked media.) The B2A0 tag (perceptual rendering intent transform) renders the L* values as tints of pure cyan. The B2A1 tag (relative colorimetric intent transform) renders them as tints of pure magenta, and the B2A2 tag (saturation intent transform) renders them as tints of pure yellow.

@MathieuLoutre
Copy link

Thanks @lovell! I had a look at this page but couldn't make sense of it at the time of my previous comment. Now that I've worked with ICC profiles for a few days, I think I understand it.

At the moment, the unit tests have something like this:

const B2A0Min = profile.B2A0.transform([0, 0.5, 0.5]);
assert.deepStrictEqual(B2A0Min, [1, 0, 0, 0])
const B2A0Max = profile.B2A0.transform([1, 0.5, 0.5]);
assert.deepStrictEqual(B2A0Max, [0, 0, 0, 0])

This passes successfully (transform is the function that takes the input and passes it through the various tables). However, it's maybe a little unclear from the above text whether a value of 0.5 in L* should yield a value of 0.5 in Cyan. That's what I understood from "monotone tints of process colorants" but at the moment, that returns 1 for C as well.

That being said, I'm. not sure how to approach the unit tests which currently verify the output with deepStrictEqual and as a result, we'd need a source of truth for each table. Would you be happy to exclude the tables from the equal check and use the transform functions as a way to verify that they're correct?

@lovell
Copy link
Owner

lovell commented Oct 2, 2023

...use the transform functions as a way to verify that they're correct?

That sounds sensible, yes please.

@MathieuLoutre
Copy link

Hi @lovell! I've made a new PR (#7) that picks up the work from #3. The A2B0 tests are failing (everything else seems fine). I can't pick out why. It returns 0.61 instead of a value between 0.7 and 1 as explained in https://www.color.org/probeprofile.xalter.

Any ideas?

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

No branches or pull requests

5 participants