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