Thread: [Lcms-user] Visual C# DLL function declaration
An ICC-based CMM for color management
                
                Brought to you by:
                
                    mm2
                    
                
            
            
        
        
        
    | 
      
      
      From: <lit...@vi...> - 2016-01-19 16:14:03
       | 
| I am using Visual C# 2015 with .NET.
 Made the lcms2.dll without any problem, and also half-made a new lcms2 "header" for my C# project.
 Most of the functions works fine - i can open and close profiles; get  the infos from them, etc. -, but i cannot program the InputBuffer and  OutputBuffer of the function *cmsDoTransform* in the right way.
 If anybody familiar with this problem, please help me.
 
 Here is a simple working example of the cmsGetProfileInfo function declaration:
 
     [DllImport("lcms2.dll")]
     public static extern UInt32 cmsGetProfileInfo(IntPtr hProfile, int  InfoType, string LanguageCode, string CountryCode,  [MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder Buffer, int  BufferSize);
 
 And like most of the other functions its works nice.
 But i stucked in cmsDoTransform, and don't know what would be the ideal  declaration and usage. (Unmanaged Marshal attributes are one path, i  tried a few variations of it without any succes)
 
 E.g.:
     [DllImport("lcms2.dll")]
     public static extern void cmsDoTransform(IntPtr hTransform, IntPtr InputBuffer, IntPtr OutputBuffer,UInt32 Size);
 or
     [DllImport("lcms2.dll")]
     public static extern void cmsDoTransform(IntPtr hTransform, char[] InputBuffer, char[] OutputBuffer,UInt32 Size);
 
 
 For pixel manipulation i use the following code:
 
     Bitmap Source = new Bitmap("test.jpg", true);
     Bitmap Target = new Bitmap(Source.Width, Source.Height, PixelFormat.Format32bppArgb);
 
     Rectangle r1 = new Rectangle(0, 0, Source.Width, Source.Height);
 
     BitmapData sourceData = Source.LockBits(r1, ImageLockMode.ReadOnly, sourcePixelFormat);
     BitmapData targetData = Target.LockBits(r1, ImageLockMode.WriteOnly, sourcePixelFormat);
 
     IntPtr sourcePtr = sourceData.Scan0;
     IntPtr targetPtr = targetData.Scan0;
 
     int bytesPerPixel = ColorDepth / 8;
     int bytes = Source.Width * bytesPerPixel * Source.Height;
 
     byte[] colorValues = new byte[bytes];
 
     Marshal.Copy(sourcePtr, colorValues, 0, bytes);
 
     // Do stuffs here, like:
     // cmsDoTransform(hTransform, sourcePtr, targetPtr, bytes); - Or using the colorValues array, or ???
 
     Marshal.Copy(colorValues, 0, targetPtr, bytes);
 
     Source.UnlockBits(sourceData);
     Target.UnlockBits(targetData);
     ...
 
 During debug, i always got memory error on the second and third argument of the cmsDoTransform function.
 
 *Tamas*
 | 
| 
      
      
      From: Marti M. <mar...@li...> - 2016-01-19 16:39:30
       | 
| Hi,
 
*  // cmsDoTransform(hTransform, sourcePtr, targetPtr, bytes); 
 
It should not be number of bytes but number of píxels. Also, I think you lock only the scanline, not the whole image. 
 
Otherwise it looks fine to me, changing from bytes to scanline pixels should do something. Then iterate for all scanlines,
 
Regards
Marti
 
From: lit...@vi... [mailto:lit...@vi...] 
Sent: martes, 19 de enero de 2016 16:47
To: lcm...@li...
Subject: [Lcms-user] Visual C# DLL function declaration
 
I am using Visual C# 2015 with .NET.
Made the lcms2.dll without any problem, and also half-made a new lcms2 "header" for my C# project.
Most of the functions works fine - i can open and close profiles; get the infos from them, etc. -, but i cannot program the InputBuffer and OutputBuffer of the function *cmsDoTransform* in the right way.
If anybody familiar with this problem, please help me.
Here is a simple working example of the cmsGetProfileInfo function declaration:
    [DllImport("lcms2.dll")]
    public static extern UInt32 cmsGetProfileInfo(IntPtr hProfile, int InfoType, string LanguageCode, string CountryCode, [MarshalAsAttribute(UnmanagedType.LPWStr)] StringBuilder Buffer, int BufferSize);
And like most of the other functions its works nice.
But i stucked in cmsDoTransform, and don't know what would be the ideal declaration and usage. (Unmanaged Marshal attributes are one path, i tried a few variations of it without any succes)
E.g.:
    [DllImport("lcms2.dll")]
    public static extern void cmsDoTransform(IntPtr hTransform, IntPtr InputBuffer, IntPtr OutputBuffer,UInt32 Size);
or
    [DllImport("lcms2.dll")]
    public static extern void cmsDoTransform(IntPtr hTransform, char[] InputBuffer, char[] OutputBuffer,UInt32 Size);
For pixel manipulation i use the following code:
    Bitmap Source = new Bitmap("test.jpg", true);
    Bitmap Target = new Bitmap(Source.Width, Source.Height, PixelFormat.Format32bppArgb);
    Rectangle r1 = new Rectangle(0, 0, Source.Width, Source.Height);
    BitmapData sourceData = Source.LockBits(r1, ImageLockMode.ReadOnly, sourcePixelFormat);
    BitmapData targetData = Target.LockBits(r1, ImageLockMode.WriteOnly, sourcePixelFormat);
    IntPtr sourcePtr = sourceData.Scan0;
    IntPtr targetPtr = targetData.Scan0;
    int bytesPerPixel = ColorDepth / 8;
    int bytes = Source.Width * bytesPerPixel * Source.Height;
    byte[] colorValues = new byte[bytes];
    Marshal.Copy(sourcePtr, colorValues, 0, bytes);
    // Do stuffs here, like:
    // cmsDoTransform(hTransform, sourcePtr, targetPtr, bytes); - Or using the colorValues array, or ???
    Marshal.Copy(colorValues, 0, targetPtr, bytes);
    Source.UnlockBits(sourceData);
    Target.UnlockBits(targetData);
    ...
During debug, i always got memory error on the second and third argument of the cmsDoTransform function.
*Tamas*
 | 
| 
      
      
      From: <lit...@vi...> - 2016-01-20 16:49:30
       | 
| Hi, Thank you for the fast answer. You were right. It seems that little change from byte number to pixel number solved my problem. Huge thanks, *Tamas* |