Hi,

Long code using C#, which I don't master. I would like to have a small 
program, preferable in C/C++, that illustrates the error. Also you are 
using a DLL, which can be an old version.  I can tell you the color 
translator uses same approach (shared profiles) and it works fine. You 
can safely share same hProfile on different threads, each thread have to 
use a different transform, because the caching mechanism. You need the 
library compiled with multithreading capabilities enabled, the toggle is 
set by default, but this was not supported on old versions.

- Make sure you are using "modern" code. Latest 2.8 is recommended.
- Make sure you manage properly the shared resources in your part of code.

If anyway you get the error, please report it to me. Try to do a small 
program that shows the error.  I am glad to get bug reports as this 
helps in getting a better product.

Regards
Marti.


On 08/01/2017 20:52, liti1...@vipmail.hu wrote:
> Hi Marti,
> Also forgot to mention, that i use c#.
>
> Try to simplify the codes here.
> This is working solution if use without multi-threading:
> ***
>          [DllImport("lcms2.dll")]
>          public static extern IntPtr cmsCreateTransform(IntPtr hInputProfile, 
> UInt32 InputFormat, IntPtr hOutputProfile, UInt32 OutputFormat, UInt32 
> Intent, UInt32 dwFlags);
>
>          [DllImport("lcms2.dll")]
>          public static extern void cmsDoTransformLineStride(IntPtr 
> hTransform, byte[] InputBuffer, byte[] OutputBuffer, UInt32 PixelsPerLine, 
> UInt32 LineCount,
>                                                                     UInt32 
> BytesPerLineIn, UInt32 BytesPerLineOut, UInt32 BytesPerPlaneIn, UInt32 
> BytesPerPlaneOut);
>
>          public static class Profiles
>          {
>              private static IntPtr __hMonitor = IntPtr.Zero;
>              public static IntPtr hMonitor { get { return __hMonitor; } set { 
> __hMonitor = value; } }
>              // etc.
>          }
>
>          [HandleProcessCorruptedStateExceptions]
>          public BitmapSource LoadSingleFile(string filename)
>          {
>              var ms = LoadImageFileToMemoryStream(filename);
>              BitmapFrame bf = BitmapFrame.Create(ms, 
> BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
>
>              IntPtr hInput, hMonitor;
>              byte[] inputProfile = 
> StreamToByteArray(bf.ColorContexts[0].OpenProfileStream());   // Check it 
> before, if not available, create one on-the-fly in the actual format
>              hInput = cmsOpenProfileFromMem(inputProfile, 
> (uint)inputProfile.Length);
>
>              // Monitor Profile: opened earlier and located in 
> Profiles.hMonitor;
>
>              IntPtr hTransform = IntPtr.Zero;
>
>              int BytesPerPixelIn = 0;
>              int StrideIn = 0;
>              int SizeIn = 0;
>              byte[] PixelsIn;
>              UInt32 TypeIn = 0;
>
>              int BytesPerPixelOut = 0;
>              int StrideOut = 0;
>              int SizeOut = 0;
>              byte[] PixelsOut;
>              UInt32 TypeOut = 0;
>
>              // CHECK INPUT FORMATS
>              if (bf.Format == PixelFormats.Bgr24)
>              {
>                  BytesPerPixelIn = BytesPerPixelOut = 3;
>                  StrideIn = StrideOut = ((bf.PixelWidth * BytesPerPixelIn) + 
> (bf.PixelWidth % 4));
>                  SizeIn = SizeOut = StrideIn * bf.PixelHeight;
>                  PixelsIn = new byte[SizeIn];
>                  PixelsOut = new byte[SizeOut];
>                  TypeIn = TypeOut = LittleCMS.LCMS.TYPE_BGR_8;
>
>                  bf.CopyPixels(PixelsIn, StrideIn, 0);
>              }
>              else if (bf.Format == PixelFormats.Cmyk32)
>              {
>                  BytesPerPixelIn = bf.Format.BitsPerPixel / 8;   // In this 
> case: 4
>                  BytesPerPixelOut = 3;
>                  StrideIn = ((bf.PixelWidth * BytesPerPixelIn) + 
> (bf.PixelWidth % 4));
>                  StrideOut = ((bf.PixelWidth * BytesPerPixelOut) + 
> (bf.PixelWidth % 4));
>                  SizeIn = StrideIn * bf.PixelHeight;
>                  SizeOut = StrideOut * bf.PixelHeight;
>                  PixelsIn = new byte[SizeIn];
>                  PixelsOut = new byte[SizeOut];
>                  TypeIn = LittleCMS.LCMS.TYPE_CMYK_8;
>                  TypeOut = LittleCMS.LCMS.TYPE_BGR_8;
>
>                  bf.CopyPixels(PixelsIn, StrideIn, 0);
>              }
>              // etc., etc., etc....
>              else
>              {
>                  // Using FormatConvertedBitmap class and do the first step
>                  var fcb = new FormatConvertedBitmap(bmp, 
> System.Windows.Media.PixelFormats.Bgr24, null, 0));
>              }
>
>              // Create the transform
>              try
>              {
>                  hTransform = cmsCreateTransform(hInput, TypeIn, hMonitor, 
> TypeOut, iFlags, dwFlags);
>              }
>              catch (AccessViolationException)
>              {
>                  return null;
>              }
>              catch (Exception e)
>              {
>                  return null;
>              }
>
>              // Do the transform: VERSION 1. simple transform
>              try
>              {
>                  cmsDoTransformLineStride(hTransform, PixelsIn, PixelsOut, 
> (uint)bf.PixelWidth, (uint)partHeight, (uint)StrideIn, (uint)StrideOut, 0, 0);
>              }
>              catch (AccessViolationException)
>              {
>                  return null;
>              }
>              catch (Exception e)
>              {
>                  return null;
>              }
>
>              // Do the transform: VERSION 2: This is also a single thread 
> version, what i can change to use multi-threaded, and works fine.
>              try
>              {
>                  int cores = Environment.ProcessorCount; ;
>                  int partHeight = bf.PixelHeight / cores;
>                  int lastPlaceIn = 0, lastPlaceOut = 0;
>                  for (int i = 0; i < cores; i++)
>                  {
>                      int tSizeIn = 0;
>                      int tSizeOut = 0;
>                      if (i == (cores - 1))
>                      {
>                          partHeight = (bf.PixelHeight - (cores - 1) * 
> partHeight);
>                      }
>
>                      tSizeIn = partHeight * StrideIn;
>                      tSizeOut = partHeight * StrideOut;
>
>                      byte[] tPixelsIn = new byte[tSizeIn];
>                      byte[] tPixelsOut = new byte[tSizeOut];
>
>                      Array.Copy(PixelsIn, lastPlaceIn, tPixelsIn, 0, tSizeIn);
>                      lastPlaceIn = ((i + 1) * partHeight * StrideIn);
>
>                      cmsDoTransformLineStride(hTransform, tPixelsIn, 
> tPixelsOut, (uint)bf.PixelWidth, (uint)partHeight, (uint)StrideIn, 
> (uint)StrideOut, 0, 0);
>
>                      if (i == (cores - 1))
>                          Array.Copy(tPixelsOut, 0, PixelsOut, lastPlaceOut, 
> tSizeOut);
>                      else
>                      {
>                          Array.Copy(tPixelsOut, 0, PixelsOut, lastPlaceOut, 
> tSizeOut);
>                          lastPlaceOut = ((i + 1) * partHeight * StrideOut);
>                      }
>                  }
>                  // catch exceptions....
>
>                  BitmapSource ccb = BitmapSource.Create(bf.PixelWidth, 
> bf.PixelHeight, bf.DpiX, bf.DpiY, PixelFormats.Bgr24, null, PixelsOut, 
> StrideOut);
>                  cmsDeleteTransform(hTransform);
>                  cmsCloseProfile(hInput);
>                  // cmsCloseProfile(hMonitor);    - Not Close Monitor Profile 
> because i would like to use it for the next file(s), too.
>                  return ccb;
>              }
> ***
>
> So, when i open only one image and call the LoadSingleFile method, everything 
> works nice.
> When i load multiple files and use the LoadSingleFile method in a for loop, 
> everything works nice.
> When i load multiple files and put the LoadSingleFiles method in a for loop 
> and each of them starts in different thread, everything works nice till the 
> files has the same sRGB profiles and 24bit depth.
> If i put e.g. a CMYK image (anything else, but different then the previously 
> used format), that is the point where the problem begins....
> The error is about the AccessViolationException during the cmsCreateTransform 
> or rarely in the DoTransform / cmsDeleteTransform / cmsDeleteProfile.
> "Attempted to read or write protected memory. This is often an indication 
> that other memory is corrupt."
> And best error is when the vshost.exe (during debugging) crashed - without 
> any information about the problem.
>
> If i need to use cmsContexts (and the errorhandling) i also have no clues 
> about how to declare them in C-Sharp.
>
> Let me know if you need more infos.
>
> Thanks a lot,
> *Tamas*
>
> -- Eredeti üzenet --
> Feladó: Marti Maria @ LittleCMS  <marti.ma...@littlecms.com>Címzett:  
> <liti1...@vipmail.hu>,  
> <lcms-user@lists.sourceforge.net>Elküldve: 2017. január 8. 19:48Tárgy : 
> Re: [Lcms-user] Multi-Threading in VS
>
> Hi Tamas,
>   
> Could you please detail which errors you get? I'm using multi threading 
> without  problems, so maybe something is wrong, perhaps In the documentation.
>
>   Best regards,
> Marti On 8 Jan 2017, at 18:47, liti1...@vipmail.hu wrote: Dear All,
> I am using lcms2.dll and their standard methods and all of them works fine in 
> a single-thread environment. (I was able to use cmsDoTransformLineStride 
> multi-threaded when this is the only function which is using multiple 
> threads. My question is about e.g. if i would like to use as a batch process 
> across multiple/different image files and the whole image process put into 
> different threads  per files .)
> When i tried to put them in a multi-threaded environment, always get errors. 
> I try to understand the cmsContexts and start to experiment with them, but it 
> seems something i missed.
> Can anybody provide me a simple sample code of how should i use these 
> functions (with dll declaration, too)?
>
> Also, i would be happy if someone provide me a sample about the error 
> handling function.
>
> In case both questions, I'm using WPF in VS 2015.
>
> Thanks,
> *Tamas*
>
> Check out the vibrant tech community on one of the world's most
> e  ngaging tech sites, SlashDot.org! http://sdm.link/slashdot
> Lcms-user mailing list
> Lcms-user@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lcms-user
>
>


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Lcms-user mailing list
Lcms-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lcms-user

Reply via email to