> 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

------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T 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

Reply via email to