Re: [Lcms-user] Difficulty with cmsTransform in C#

2016-07-07 Thread Edgar Loser
> Does this code actually work for you?

Yes is does.
Perhaps I should have mentioned that you need at least .Net 4
In 3.5 it's available but does not work...
(s. 
https://social.msdn.microsoft.com/Forums/en-US/be7ad7d6-972f-4a39-ae90-55660d66c561/iccprofildaten-via-colorcontext?forum=wpfde)

The second thing that might cause some trouble: some jpeg (of digicams) 
do not really contain an icc profile, they are just tagged (in exif) to 
be SRGB or AdobeRGB. E.g. if exif:InteroperabilityIndex contains R03 
it's an AdobeRGB image, s 
http://regex.info/blog/photo-tech/color-spaces-page7
But! I just checked my AdobeRGB images taken with my Nikon or my Canon, 
and in every case ColorContext did work...

> Where does the "StreamToArray" method comes from?
The StreamToArray is a simple helper method (I forgot to cite) e.g.:
public static Byte[] StreamToArray(Stream input) {
if (input is MemoryStream) {
   return (input as MemoryStream).ToArray();
} else {
   using (MemoryStream ms = new MemoryStream()) {
  input.CopyTo(ms);
  return ms.ToArray();
   }
}
}

Edgar








>
> First of all, when creating a BitmapFrame with PreservePixelFormats the
> ColorContext is *always* nill!!!
> It does not work for me, with the JPEG files I tried.
>
> I would *love* for the ColorContext to come across as I would be able to
> create an ICC profile from memory, the way to do it.
> It is perfect! Except, it does not work.
>
> In all my testing, so far, I have NOT been able to retrieve a ColorContext
> (embedded ICC profile) from a JPEG image.
>
> Second question...
>
>
> Best / Roger
>
>
> --
> Attend Shape: An AT Tech Expo July 15-16. Meet us at AT Park in San
> Francisco, CA to explore cutting-edge tech and listen to tech luminaries
> present their vision of the future. This family event has something for
> everyone, including kids. Get more information and register today.
> http://sdm.link/attshape
> ___
> Lcms-user mailing list
> Lcms-user@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lcms-user
>

-- 
lakeBits Inh. Edgar Loser
Haydnstr. 25
78464 Konstanz
Tel 0049 7531 5844154 0
Fax 0049 7531 5844154 9
http://www.colymp.com/
mailto:lo...@colymp.com

--
Attend Shape: An AT Tech Expo July 15-16. Meet us at AT Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
___
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user


Re: [Lcms-user] Difficulty with cmsTransform in C#

2016-07-06 Thread Roger Breton
Edgar,

You wrote :

> // create lcms inputprofile
>  IntPtr inputProfileH = IntPtr.Zero;
>I f (biFrm.ColorContexts != null) {
>   byte[] inputProfile =
> StreamToArray(biFrm.ColorContexts[0].OpenProfileStream());
>   inputProfileH =
> Basic.Lcms.NativeMethods.cmsOpenProfileFromMem(inputProfile,
> (uint)inputProfile.Length);

Does this code actually work for you?

First of all, when creating a BitmapFrame with PreservePixelFormats the
ColorContext is *always* nill!!!
It does not work for me, with the JPEG files I tried.

I would *love* for the ColorContext to come across as I would be able to
create an ICC profile from memory, the way to do it.
It is perfect! Except, it does not work.

In all my testing, so far, I have NOT been able to retrieve a ColorContext
(embedded ICC profile) from a JPEG image.

Second question...

Where does the "StreamToArray" method comes from?

Best / Roger


--
Attend Shape: An AT Tech Expo July 15-16. Meet us at AT Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
___
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user


Re: [Lcms-user] Difficulty with cmsTransform in C#

2016-06-30 Thread Edgar Loser
> If I could develop my application strictly in C, my problems accessing
> LittleCMS would be non-existent,
> but I need to develop in C# :(

Working with C# is not too bad!

>[...]
> cmsDoTransform(cmsHTRANSFORM Transform, const void * InputBuffer,
>   void * OutputBuffer,
>   cmsUInt32Number Size);
>
> (Not sure what the 'const' keyword in front of the first void * statement
> does?)

By writing 'const' Marti is telling us, that cmsDoTransform will not 
touch the data in InputBuffer. I.e. we can either pass a const void* or 
we can pass a void*. If he would had omit to write 'const' and we would 
have just a const void* inputBuffer we could not pass this pointer to 
cmsDoTransform (compiler error)... (s. 
http://stackoverflow.com/questions/4064286/c-const-keyword-explanation)

> [DllImport(lcms2Path, CallingConvention = CallingConvention.Winapi)]
> static extern void cmsDoTransform(IntPtr xform, IntPtr inputColors [in],
> IntPtr outputColors [out], uint Size);
>
> So my question becomes how do I pass pointers to the these buffers in my new
> declaration?
> I read somewhere about the need to use the keyword 'unsafe' but I am not
> sure.
> Also read about the need to use the attributes [in] and [out] in marshalling
> the data.
> (The Marshalling of data is a HUGE topic in itself as I found out through my
> hours of reading online)
>
> Ultimately, my goal is is to convert JPEG or TIFF images from one color
> space to another through LittleCMS.

It's not that difficult...
Here is what I'm using (somehow stripped, without error handling, 
without cleanup...)

public static class NativeMethods {
[DllImport("lcms2.dll")]
public static extern void cmsDoTransform(
[In] IntPtr Transform,
[In] byte[] InputBuffer,
[Out] byte[] OutputBuffer,
[In] UInt32 Size);
}

// We use WPF classes to read binary data of the images:
// Namespace:   System.Windows.Media.Imaging
// Assembly:  PresentationCore (in PresentationCore.dll)
BitmapDecoder biDec = BitmapDecoder.Create(.)
BitmapFrame biFrm = biDec.Frames[0];

PixelFormat inputFormat = biFrm.Format;
uint lcmsInputFormat = 0;
FormatConvertedBitmap fcb = null; // if we have an input format 
that we cannot use direktly in lcms
// we have to create a temporary bitmap with lcms compatible format and 
use this instead of biFrm
if (inputFormat == PixelFormats.Bgra32) {
lcmsInputFormat = 0x44499; // Lcms.Format.TYPE_BGRA_8;
} else if (inputFormat == PixelFormats.Bgr24) {
lcmsInputFormat = 0x40419; // Lcms.Format.TYPE_BGR_8;
} else {
inputFormat = PixelFormats.Bgra32;  // we enforce Bgra32 format
lcmsInputFormat = 0x44499; // Lcms.Format.TYPE_BGRA_8;
fcb = new FormatConvertedBitmap(biFrm, inputFormat, null, 0);
if (fcb == null) {
throw new Exception("Unable to create FormatConvertedBitmap");
}
}

// create lcms inputprofile
IntPtr inputProfileH = IntPtr.Zero;
if (biFrm.ColorContexts != null) {
byte[] inputProfile = 
StreamToArray(biFrm.ColorContexts[0].OpenProfileStream());
inputProfileH = 
Basic.Lcms.NativeMethods.cmsOpenProfileFromMem(inputProfile, 
(uint)inputProfile.Length);
} else {
inputProfileH = Basic.Lcms.NativeMethods.cmsCreate_sRGBProfile();
}

IntPtr outputProfileH = .; // create your lcms output profile

IntPtr lcmsTrafo = NativeMethods.cmsCreateTransform(
inputProfileH
, lcmsInputFormat
, outputProfileH
, lcmsInputFormat   // output format = input format
, YourRenderingIntent
, 0);

// copy image data to byte[]
int stride = biFrm.PixelWidth * inputFormat.BitsPerPixel / 8;
Byte[] inputBitmapData = new Byte[stride * biFrm.PixelHeight];
if (fcb == null) {  // we copy pixel data from original image
biFrm.CopyPixels(inputBitmapData, stride, 0);
} else {// we copy pixel data from format converted bitmap
fcb.CopyPixels(inputBitmapData, stride, 0);
}

// I have to copy the whole data, to get a copy of alpha channel (lcms 2.7)
Byte[] outputBitmapData = inputBitmapData.Clone() as Byte[];

NativeMethods.cmsDoTransform(lcmsTrafo, inputBitmapData, 
outputBitmapData, (uint)(biFrm.PixelWidth * biFrm.PixelHeight));

// create a new image, based on outputBitmapData:
BitmapSource ccb = BitmapSource.Create(
biFrm.PixelWidth, biFrm.PixelHeight
, biFrm.DpiX, biFrm.DpiY
, inputFormat
, null
, outputBitmapData
, stride);

// create e.g. .png file:
BitmapEncoder biEnc = new PngBitmapEncoder();
biEnc.Frames.Add(BitmapFrame.Create(ccb));
biEnc.Save(YourOutputStream);

-- 
lakeBits Inh. Edgar Loser
Haydnstr. 25
78464 Konstanz
Tel 0049 7531 5844154 0
Fax 0049 7531 5844154 9
http://www.colymp.com/
mailto:lo...@colymp.com


Re: [Lcms-user] Difficulty with cmsTransform in C#

2016-06-29 Thread Roger Breton
If I could develop my application strictly in C, my problems accessing
LittleCMS would be non-existent, 
but I need to develop in C# :(

I am seeking help with re-coding the cmsDoTransform declaration.

Right now, I use this :

 [DllImport(@lcmsPath, CallingConvention = CallingConvention.Winapi)]
static extern void cmsDoTransform(
   IntPtr xform,
   [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2), In] double[]
inputColors, 
   [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3), Out] double[]
outputColors, uint Size);

In code, I use this :

double[] input = { 0.5, 0.5, 0.5, 0 };
double[] output = { 0, 0, 0, 0 };
cmsDoTransform(xform, input, output, 1);

As you can see, I pass individual RGB values [in], recovering CMYK values
[out]. 

The cmsCreateTransform looks like this :

IntPtr xform = cmsCreateTransform(hSRGB, TYPE_RGB_DBL, hDestination,
TYPE_CMYK_DBL, INTENT_RELATIVE_COLORIMETRIC, 0);

Works perfect. 

But now, I need to pass 'pixels' (to convert bitmap images) values instead
of individual device values. 
Obviously, I need to modify the pinvoke declaration to accommodate the
difference in data type.

I am no C# specialist (maybe someday?) but I read that I may not need very
meticulous marshalling of data between my C# and lcms.dll.
So I am looking for a way to rewrite the declaration to accommodate more
than just 'double'. 

In C, the original cmsDoTransform function require a Handle to the Transform
(another pointer), pointers to an input and output buffers, and the size of
the buffer themselves :

cmsDoTransform(cmsHTRANSFORM Transform, const void * InputBuffer,
  void * OutputBuffer,
  cmsUInt32Number Size);

(Not sure what the 'const' keyword in front of the first void * statement
does?)

So my first awkward/intuitive shot at rewriting the function in C# call
looks like this :

[DllImport(lcms2Path, CallingConvention = CallingConvention.Winapi)]
static extern void cmsDoTransform(IntPtr xform, IntPtr inputColors [in],
IntPtr outputColors [out], uint Size);

I have not tried running this code yet but I have been reading quite a bit
about pointers and how they have a fixed size, no matter the type of data
they point to. 

So my question becomes how do I pass pointers to the these buffers in my new
declaration? 
I read somewhere about the need to use the keyword 'unsafe' but I am not
sure. 
Also read about the need to use the attributes [in] and [out] in marshalling
the data. 
(The Marshalling of data is a HUGE topic in itself as I found out through my
hours of reading online)

Ultimately, my goal is is to convert JPEG or TIFF images from one color
space to another through LittleCMS. 

Thank you so much in advance for your kind help.

/ Roger Breton



--
Attend Shape: An AT Tech Expo July 15-16. Meet us at AT Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
___
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user


Re: [Lcms-user] Difficulty with cmsTransform in C#

2016-06-17 Thread Edgar Loser
Did you declare input[] and output[] as volatile?
(s. https://msdn.microsoft.com/de-de/library/x13ttww7.aspx)

Edgar


Am 16.06.2016 um 21:25 schrieb Roger Breton:
> Tengo una pequena problema...
>
> I need to convert 400 RGB values to Lab using a monitor profile.
>
> I use the following C# code :
>
>   string Source = "Monitor.icm";
>   IntPtr hSource = cmsOpenProfileFromFile(Source, "r");
>
>   xform = cmsCreateTransform(hSource, TYPE_RGB_DBL, hLab2, TYPE_Lab_DBL,
> INTENT_ABSOLUTE_COLORIMETRIC, 0);
>
>   for (int i = 0; i < 400; i++)
>   {
>   input[0] = R[i];
>   input[1] = G[i];
>   input[2] = B[i];
>
>cmsDoTransform(xform, input, output, 1);
>
>L = output[0];
>a = output[1];
>b = output[2];
> }
>
> First time through the loop I get valid Lab results.
> But subsequent passage through the loop always return the same Lab values?
> The input[] values do change as expected.
>
> When I use this code outside of a loop, it works perfect.
>
> / Roger Breton
>
>
> --
> What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
> patterns at an interface-level. Reveals which users, apps, and protocols are
> consuming the most bandwidth. Provides multi-vendor support for NetFlow,
> J-Flow, sFlow and other flows. Make informed decisions using capacity planning
> reports. http://sdm.link/zohomanageengine
> ___
> Lcms-user mailing list
> Lcms-user@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lcms-user
>

-- 
lakeBits Inh. Edgar Loser
Haydnstr. 25
78464 Konstanz
Tel 0049 7531 5844154 0
Fax 0049 7531 5844154 9
http://www.colymp.com/
mailto:lo...@colymp.com

--
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports. http://sdm.link/zohomanageengine
___
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user


[Lcms-user] Difficulty with cmsTransform in C#

2016-06-16 Thread Roger Breton
Tengo una pequena problema...

I need to convert 400 RGB values to Lab using a monitor profile.

I use the following C# code :

  string Source = "Monitor.icm";
  IntPtr hSource = cmsOpenProfileFromFile(Source, "r");

  xform = cmsCreateTransform(hSource, TYPE_RGB_DBL, hLab2, TYPE_Lab_DBL,
INTENT_ABSOLUTE_COLORIMETRIC, 0);

  for (int i = 0; i < 400; i++)
  {
  input[0] = R[i];
  input[1] = G[i];
  input[2] = B[i];

   cmsDoTransform(xform, input, output, 1);

   L = output[0];
   a = output[1];
   b = output[2];
}

First time through the loop I get valid Lab results.
But subsequent passage through the loop always return the same Lab values?
The input[] values do change as expected.

When I use this code outside of a loop, it works perfect.

/ Roger Breton


--
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports. http://sdm.link/zohomanageengine
___
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user