Hi,

Since your question is quite interesting, I've also forwarded to
mailing list. Hope this is not a problem to you.

> I have been looking at your LCMS 1.09 code, and I have a question
> concerning your interpolation routines, specifically the tetrahedral
> interpolation routine using the Sakamoto algorithm. I have an
> application that requires the use of such an algorithm, and (I hope you
> don't mind) I was going to borrow this routine from your code. The
> function in question is cmsTetrahedralInterp16().

Of course you can borrow any routine, this is the goal of open
source, at least for me. And what you are asking for, is a very
frequent question. So frequent, that I did promote this part
to lcms API in ver 1.09

You can use the low level routines, or, and I will recommend
this latter, use the LUT interface to accomplish same.
The LUT interface is easy to use and allows also to add
pre/post linearization,  and if you plan to convert
RGB -> XYZ the  prelinearization part is really a must.
It can increase a lot the precission whilst
lowering the amount of data (CLUT points) required.

Then, here are the functions needed. More details in lcmsapi.txt

LPLUT  cmsAllocLUT(void);
LPLUT  cmsAllocLinearTable(LPLUT Lut, LPGAMMATABLE Tables[], int nTable);
LPLUT  cmsAlloc3DGrid(LPLUT Lut, int clutPoints, int inputChan, int outputChan);
int cmsSample3DGrid(LPLUT Lut, _cmsSAMPLER Sampler, LPVOID Cargo, DWORD dwFlags);
void   cmsFreeLUT(LPLUT Lut);

void   cmsEvalLUT(LPLUT Lut, WORD In[], WORD Out[]);

The typical procedure is:

- First you allocate an empty LUT by calling cmsAllocLUT()
- Then you add whatsever linearization by means of cmsAllocLinearTable()
- Then you declare your multidimensional table size using cmsAlloc3DGrid()
- Finally, you fill the table by using a callback function and cmsSample3DGrid()

This gives to you a ready to use LUT. You can then evaluate values across
this LUT by using cmsEvalLUT(). Where done, use cmsFreeLUT() to get
rid of the memory.

A couple of comments.  If you plan to use RGB -> XYZ, you should use
a prelinearization table for decoupling gamma of RGB space. You could
use cmsBuildGamma() to create such curve. For example, sRGB to XYZ
needs a gamma curve of approximately gamma=2.2 Avoiding this table
will result in quantization errors due to "impedance" mismatch between
both spaces, XYZ has an aparent gamma of 1.0!

You can use then lcms as a static library and only the needed routines
will got linked. I tried to adjust granularity of library to allow very
lightweight overhead in such cases.

Ok, anyway I will try to answer about the implementation details as well.

> Input[] appears to be the input values, which in my case would be the
> X, Y and Z (input) values I enter to find the corresponding RGB
> (output) values. Output[] appears to be the result of the
> interpolation; the R, G, and B values the function identifies as
> corresponding to my input X, Y and Z values. Correct?

Yes, that is.

> LutTable[] appears to be used by the function DENS, but I am not sure
> about the pointers to Domain and nOutputs. I am assuming that nOutputs
> is the total number of output channels (in my case 3)? But, I am not
> sure about Domain; does that represent the last count in my CLUT (in my
> case 728)?

You can fill the L6PARAMS struct by calling

cmsCalcCLUT16Params(int nSamples, int InputChan, int OutputChan, LPL16PARAMS p);

You need to specify the cube (or hypercube in case of CMYK) side, and the number
of input/output channels. In your case I assume 729 means a cube of 9 gridponts in
each side.

L16PARAMS params;

 cmsCalcCLUT16Params(9, 3, 3, &params);
...

cmsTetrahedralInterp16(Input[],
                                    Output[],
                                     Dens[],  &params);

But again, please note that 9 points is not enough without linearization table. For my 
testings,
you need at least 48!!! points to decouple gamma. But a simple 6 points 
prelinearization and
6 points on grid gives same accurancy as 48 points, so this step is really required.

Hope this helps,
Mart� Maria
The little cms project
http://www.littlecms.com
[EMAIL PROTECTED]


----- Original Message -----
From: "Christopher Brown"
Sent: Friday, November 22, 2002 12:27 AM
Subject: Tetrahedral Interpolation


> Hello Marti -
>
> I have been looking at your LCMS 1.09 code, and I have a question
> concerning your interpolation routines, specifically the tetrahedral
> interpolation routine using the Sakamoto algorithm. I have an
> application that requires the use of such an algorithm, and (I hope you
> don't mind) I was going to borrow this routine from your code. The
> function in question is cmsTetrahedralInterp16().
>
> Basically, what I have is a CLUT comprised of 729 RGB values with
> corresponding XYZ values. The idea would be to take any given set of
> XYZ values, and locate the appropriate corresponding RGB values, based
> on the 729 data points contained in my CLUT. The values in the CLUT are
> currently 16-bits each in the range 0 to 65535.
>
> Now, I think I understand basically what this routine is doing.
> However, I just want to verify a few things. There appear to be four
> values passed to the function: Input[], Output[], LutTable[] and
> LPL16PARAMS.
>
> Input[] appears to be the input values, which in my case would be the
> X, Y and Z (input) values I enter to find the corresponding RGB
> (output) values. Output[] appears to be the result of the
> interpolation; the R, G, and B values the function identifies as
> corresponding to my input X, Y and Z values. Correct?
>
> LutTable[] appears to be used by the function DENS, but I am not sure
> about the pointers to Domain and nOutputs. I am assuming that nOutputs
> is the total number of output channels (in my case 3)? But, I am not
> sure about Domain; does that represent the last count in my CLUT (in my
> case 728)?
>
> Based on this, please let me know if the following is correct:
>
> Domain = 728 (last count in CLUT, 0 - 728)
> clutPoints = 729 (Domain + 1)
> nOutputs = 3
> TotalOut = nOutputs
> Input[] = Input values X, Y and Z
> Output[] = Output values R, G and B
> px = (X * 728) / 65535
> py = (Y * 728) / 65535
> pz = (Z * 728) / 65535
>
> LutTable[] I am not entirely sure about. But, I am assuming that, if
> RGB is my output, then c1 would look at R values, c2 at G values and c3
> at B values? This is the part that I am not clear on. Finally, what is
> LPL16PARAMS?
>
> I apologize for asking so many questions; I want to thank you in
> advance for any help you can give. Do you happen to have any
> information regarding the Sakamoto  algorithm, or can you point me to
> any papers written on the topic? Also, what is your feeling as to how
> this routine compares with your other tetrahedral and trilinear
> interpolation routines, in terms of speed and accuracy? How does it
> compare to the Catmull-Rom interpolation (that is remarked out in your
> code)?
>
> Thanks again for all your help!
>
> Kind Regards,
>
> - Chris Brown
>
>
>



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Lcms-user mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/lcms-user

Reply via email to