Welcome to LEAD Support Forum Login | Register | Faq  

    LEAD Support Forum
  Resource to find answers and post technical questions about LEAD products.
Search    
   

Saving RasterImages to SQL 2005
Started by mbsiehs at 10-01-2007 10:47. Topic has 19 replies.

Print Search « Previous Thread Next Thread »
  10-01-2007, 10:47
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Saving RasterImages to SQL 2005
Reply Quote
I'm trying to save a RasterImage to a SQL database via a MemoryStream with little success.  It appears that my examples in the documentation all save to a file, but if I'm overlooking something sorry for wasting your time.  Anyway, the first save works fine under most circumstances, but after saving another image I get the following exception message:

"Attempted to read or write protected memory.  This is often an indication that other memory is corrupt."

If I try to save again after the exception (which I catch), I get the following exception message:

"Invalid parameter passed."

I'm developing in C# with .NET 2.0 and LeadTools v. 15.  Below is the code where I load my SqlParameter object.  I start the RasterCodec engine at the beginning of a try and shut it down in the matching finally.  What am I doing wrong?

                            if (image.HighResolutionImage != null)
                            {
                                codecs = new RasterCodecs();
                                MemoryStream memoryStream = new MemoryStream();

                                codecs.Save(
                                    image.HighResolutionImage, memoryStream, RasterImageFormat.Cmp, 24);
                                byte[] blob = memoryStream.GetBuffer();
                                SqlParameter parameter = new SqlParameter(
                                    "@picture",
                                    SqlDbType.Image,
                                    blob.Length,
                                    ParameterDirection.Input,
                                    false, 0, 0, null,
                                    DataRowVersion.Current,
                                    blob);
                                sqlCmd.Parameters.Add(parameter);
                                memoryStream.Close();
                                codecs.Dispose();
                            }

                            if (image.LowResolutionImage != null)
                            {
                                codecs = new RasterCodecs();
                                MemoryStream memoryStream = new MemoryStream();

                                codecs.Save(
                                    image.LowResolutionImage, memoryStream, RasterImageFormat.Cmp, 24, 1, 1, 1, CodecsSavePageMode.Replace);
                                byte[] blob = memoryStream.GetBuffer();
                                SqlParameter parameter = new SqlParameter(
                                    "@thumbnail",
                                    SqlDbType.Image,
                                    blob.Length,
                                    ParameterDirection.Input,
                                    false, 0, 0, null,
                                    DataRowVersion.Current,
                                    blob);
                                sqlCmd.Parameters.Add(parameter);
                                memoryStream.Close();
                                codecs.Dispose();
                            }





   Report 
  10-01-2007, 16:38
jigar is not online. Last active: 11/18/2008 10:04:38 AM jigar



Top 10 Posts
Joined on 08-22-2007
Posts 446
Re: Saving RasterImages to SQL 2005
Reply Quote
Which line from above throws that error?  What's the stack-trace of that exception?  Can you provide a sample scaled down program that I can use to replicate the issue here?  You can put it in a zip file and send it to support@leadtools.com with my name in it and mention this post.

I used your code above and there weren't any errors thrown.  I made my own try-finally block (no catch blocks).  I commented out the sqlCmd statements, and the two if-statements for my test.  I called Startup() at the very beginning of the try block and Shutdown() in the finally block.  No issues.  I also put the whole try-finally block into a for-loop, and iterated it 5 times without any issues.  A sample program that throws the error on your end would be easier to replicate and debug here.

Thank You.

LEADTOOLS Technical Support
   Report 
  10-02-2007, 16:02
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Re: Saving RasterImages to SQL 2005
Reply Quote
The problem has disappeared -- which makes me a bit nervous but my experience tells me that it's not a LEAD issue.  I've played with it all day with no error.  Thanks for your response.

   Report 
  10-02-2007, 17:33
jigar is not online. Last active: 11/18/2008 10:04:38 AM jigar



Top 10 Posts
Joined on 08-22-2007
Posts 446
Re: Saving RasterImages to SQL 2005
Reply Quote
"Attempted to read or write protected memory.  This is often an indication that other memory is corrupt." is thrown by the .NET Framework.  LEADTOOLS uses many .NET methods, so the error is indirectly thrown.  Most of the times it's when you don't call the Startup() method for any of our engines (RasterCodecs, RasterDocumentEngine, etc).  But since you were calling that, that couldn't have been an issue.  Next time it happens, I would say check the stack trace to see which method threw the exception.

LEADTOOLS Technical Support
   Report 
  10-19-2007, 16:49
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Re: Saving RasterImages to SQL 2005
Reply Quote
The problem persists and through some testing I have discovered some information that may assist in identifying what I'm missing.

The above code throws the exception for a subset of the *.jpg files with which I am testing.  The Leadtools.Codecs.cmp.dll is in the output folder as it should be.  The application does not throw an exception for any *.bmp files.  I'm wondering if the problem is with the bits per pixel somehow, but it seems to be image independent.  I have also noticed that one *.jpg that consistently produces the problem takes an unusually long time to load from the RasterOpenDialog, both in the preview window and then the OK button is activated.  Not all *.jpgs do that.  The troubeling *.jpg is not large at all, in fact it's only 146K whereas the same image but *.bmp is 9MB.  To make things even more interesting, the troubeling file opens fine in the Main 32-bit Demo and it saves to a file in *.cmp format just fine (I'm going to a memory stream) -- so I don't think the file is corrupt in any way.  In fact, other than the latency in my code it loads just fine.

What could cause one *.jpg to throw the exception and not another when saving it to a memory stream via RasterCodecs.Save()?

Thanks a lot for your time.
Matt

PS -- a snapshot of the stack can be emailed on request.  I tried posting a jpg and it wasn't readable, and a bitmap was too big.

   Report 
  10-22-2007, 10:09
jigar is not online. Last active: 11/18/2008 10:04:38 AM jigar



Top 10 Posts
Joined on 08-22-2007
Posts 446
Re: Saving RasterImages to SQL 2005
Reply Quote
Not sure on why it would throw an exception on a memory stream.  Can you send the actual jpg file that's giving you trouble?  I can do some tests here with it.  You can send it to support@leadtools.com and mention this post, and I'll take a hold of that email.

LEADTOOLS Technical Support
   Report 
  10-23-2007, 17:42
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Re: Saving RasterImages to SQL 2005
Reply Quote
I have sent the image in question.  Other images throw an exception when saving to a MemoryStream, but none with the frequency of the image in question.  I have also considered that it may be in the acquisition phase of the image, so I am posting that code below as well.  The only thought I have against that hypothesis is that they always load into a RasterImage object just fine.  But it is a thought.

I really appreciate your time with this one.

Matt

         public void GetLeadtoolsImages()
        {
            RasterOpenDialog dialog = null;
            RasterCodecs codecs = null;
          
            RasterCodecs.Startup();
            codecs = new RasterCodecs();

            dialog = new RasterOpenDialog(codecs);
            dialog.DereferenceLinks = true;
            dialog.CheckFileExists = false;
            dialog.CheckPathExists = true;
            dialog.EnableSizing = true;
            dialog.Filter = new RasterOpenDialogLoadFormat[]
            {
                new RasterOpenDialogLoadFormat("Bitmap", "*.bmp"),
                new RasterOpenDialogLoadFormat("JPG", "*.jpg"),
                new RasterOpenDialogLoadFormat("LEAD", "*.cmp")
            };
            dialog.FilterIndex = 1;
            dialog.LoadFileImage = true;
            dialog.LoadOptions = false;
            dialog.LoadRotated = true;
            dialog.LoadCompressed = true;
            dialog.Multiselect = false;
            dialog.ShowGeneralOptions = true;
            dialog.ShowLoadCompressed = true;
            dialog.ShowLoadOptions = true;
            dialog.ShowLoadRotated = true;
            dialog.ShowMultipage = true;
            dialog.ShowPdfOptions = false;
            dialog.ShowPreview = true;
            dialog.ShowProgressive = true;
            dialog.ShowRasterOptions = true;
            dialog.ShowTotalPages = true;
            dialog.ShowDeletePage = true;
            dialog.ShowFileInformation = true;
            dialog.UseFileStamptoPreview = true;
            dialog.PreviewWindowVisible = true;
            dialog.GenerateThumbnail = false;
            dialog.Title = "IMPROVIS Open Image Dialog";
            dialog.FileName = string.Empty;

            if (dialog.ShowDialog(this.parent) == DialogResult.OK)
                // this will just generate other copies of the image via a RasterImage constructor
                ImageManipulator.GetLeadtoolsImages(this.imageView, dialog.OpenedFileData[0].Image);

            codecs.Dispose();
            RasterCodecs.Shutdown();
        }


   Report 
  10-24-2007, 12:50
jigar is not online. Last active: 11/18/2008 10:04:38 AM jigar



Top 10 Posts
Joined on 08-22-2007
Posts 446
Re: Saving RasterImages to SQL 2005
Reply Quote
Hello Matt,

I ran your code above, no errors.  I also added a save statement that saves to the memory stream, and called it 500 times in a for-loop.  No errors thrown.  What does your save function look like saving to the memory?  Also can you post the code where you take the MemoryStream and insert in to the database?

Thanks.

LEADTOOLS Technical Support
   Report 
  11-05-2007, 9:06
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Re: Saving RasterImages to SQL 2005
Reply Quote
Forgive the long delay since my last post -- I'm working this application from many different angles.  But the priority to fix this problem has greatly increased.

My original post above contains my save code, and the exception is always thrown at RasterCodecs.Save(), so I don't think it has anything to do with my database.  I have done more testing my modifying the save code (above) to use the following:

                                codecs.Save(
                                    image.HighResolutionImage, stream, RasterImageFormat.Cmp,
                                    image.HighResolutionImage.BitsPerPixel);
and

                                codecs.Save(
                                    image.LowResolutionImage, stream, RasterImageFormat.Cmp,
                                    image.LowResolutionImage.BitsPerPixel);

because I was questioning whether hard-coding the 24 for BPP was causing the error.  It is not.

Furthermore, the problem seems not to be dependent on file types like I had originally supposed.  Our QA department is getting the exception with some BMPs and some JPGs, but not all.  My hope is to work this out and then upgrade to medical to save with lossless compression, but BMP and JPG is good enough for now.

I am using RasterPro for .NET, version 15.  We develop under .NET 2.0.

Thanks for continuing to assist me.  I really appreciate your time.

Matt

   Report 
  11-05-2007, 11:59
jigar is not online. Last active: 11/18/2008 10:04:38 AM jigar



Top 10 Posts
Joined on 08-22-2007
Posts 446
Re: Saving RasterImages to SQL 2005
Reply Quote
Hi Matt,

Do you have a stack trace of that error?  Can you post it here?

Also, how big is your application?  I'd like to replicate it here with it, and see how it occurs.  Try to scale the app down as much as possible and then email it to me by replying to one of the emails that I sent you.  You can leave out the DLLs to keep the filesize small.

Thanks.

LEADTOOLS Technical Support
   Report 
  11-07-2007, 10:49
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Re: Saving RasterImages to SQL 2005
Reply Quote
I've done some more testing to try to uncover clues about this.  The stack trace is below:

A first chance exception of type 'System.NullReferenceException' occurred in Leadtools.dll
   at Leadtools.RasterImage.get_BitsPerPixel()
   at HzObj.Clinical.Series.SavePatientSeries(Patient patient) in C:\dev\HzSys\HzObj\Clinical\Series.cs:line 773

My program allows the entry of x-ray images from various sources -- this source is from a file.  I have a series object that contains one or more RasterImage objects that will be saved to the database.  I have set up a series with four images each obtained from a file.  When I try to save the series, the exception occurs on the first image of the series sometimes, sometimes the second, etc.  There's not a pattern that I can tell.

I have broken into the file input code and have verified that the BitsPerPixel property is properly set when I obtain my images (8), but when I brake into the RasterImage.Save() method before it executes, I can clearly see that the BitsPerPixel property is going to return a NullReferenceException.  I don't know what could cause that.

Because of the size of our application and company policies, I can't send you the executable without going through a lot of steps.  What I am in the process of doing is writing a small application that does this same thing (in fact I'm copying/pasting the code in most cases).  I can get that to you.

I have noticed behavior like this in the past when an object has its Dispose() method called, but I'm not doing that on any RasterImage.

As always, thanks for the help.

Matt

   Report 
  11-07-2007, 11:19
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Re: Saving RasterImages to SQL 2005
Reply Quote
The other exception that happens at the same location is as follows:

A first chance exception of type 'System.AccessViolationException' occurred in Leadtools.dll
   at L_MemoryCopy(Void* , Void* , UInt32 )
   at LT_Namespace.L_CopyMemory<unsigned char,unsigned char>(Byte* dest, Byte* src, UInt32 count)
   at L_GetBitmapRow(_BITMAPHANDLE* , Byte* , Int32 , UInt32 )
   at Leadtools.Internal.LtKrnExports.L_GetBitmapRow(Void* pBitmap, Byte* pBuffer, Int32 nRow, UInt32 uBytes)
   at L_GetBitmapRow(_BITMAPHANDLE* pBitmap, Byte* pBuffer, Int32 nRow, UInt32 uBytes)
   at fltSaveCMP(_SAVEDISPATCH* )
   at Leadtools.Codecs.Cmp.CmpCodec.fltSave(IntPtr dispatch)
   at ManagedFLTSAVE(Int32 fmt, _SAVEDISPATCH* dis)
   at L_SaveFile(Char* , _BITMAPHANDLE* , Int32 , Int32 , Int32 , UInt32 , IntPtr , Void* , _SAVEFILEOPTION* )
   at Leadtools.Codecs.RasterCodecs.SaveOnePage(Int32 page, SaveParams saveParams)
   at Leadtools.Codecs.RasterCodecs.DoSave(SaveParams saveParams)
   at Leadtools.Codecs.RasterCodecs.Save(RasterImage image, Stream stream, RasterImageFormat format, Int32 bitsPerPixel)
   at HzObj.Clinical.Series.SavePatientSeries(Patient patient) in C:\dev\HzSys\HzObj\Clinical\Series.cs:line 773

Notice that they originate from the same line.  Line 773 was included in my original post, but this is it:

                                codecs.Save(
                                    image.HighResolutionImage, stream, RasterImageFormat.Cmp,
                                    image.HighResolutionImage.BitsPerPixel);
Where stream is a .NET MemoryStream.

I just got this exception on an image (BMP) and turned around and loaded/saved it again and it worked.  Odd.

Thanks.

   Report 
  11-07-2007, 12:55
jigar is not online. Last active: 11/18/2008 10:04:38 AM jigar



Top 10 Posts
Joined on 08-22-2007
Posts 446
Re: Saving RasterImages to SQL 2005
Reply Quote
That does seem odd.  Our Leadtools.dll wraps around our API and it seems to be happening at the API level.  I'm going to wait for your sample application and test it with that.  Make sure you add "Attn: Jigar" in the subject and the body of the message so that it comes to me.

Thanks.

LEADTOOLS Technical Support
   Report 
  11-07-2007, 16:00
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Re: Saving RasterImages to SQL 2005
Reply Quote
Jigar,

In the process of creating the sample application, I have come across a good clue.

First, I decided that the two exceptions are in fact different problems, and in all probability those problems came from the same source -- which is to say that I'm probably doing something in my code that's questionable at times and not others.  Following that line of thinking, I decided to tackle the "Attempted to read or write protected memory" exception and like your sample application, mine wasn't crashing.  I started adding more and more functionality and it didn't crash.  Eventually I decided that the problem wasn't with the MemoryStream at all, and that the protected memory was in fact the RasterImage.  I replace my call to RasterCodec.Save() with the following:

                                codecs.Save(
                                    new RasterImage(image.HighResolutionImage), stream, RasterImageFormat.Cmp,
                                    image.HighResolutionImage.BitsPerPixel);

And that did it.  I have saved many images with no exception.  That tells me that somewhere I'm doing something to HighResolutionImage that would lock if from a read into the MemoryStream object.  And sometimes it is locked and not others (I use the term "locked" loosely -- not in the traditional database locking way).  Assuming my hypothesis is correct, do you have any ideas as to what could cause the data of a RasterImage from being accessed?

The other issue is with multiple images being saved iteratively in the code.  Somehow I'm still getting the exception from accessing BitsPerPixel -- I'll continue with my sample application for that one too.

Thanks.
Matt

   Report 
  11-08-2007, 10:39
mbsiehs is not online. Last active: 6/24/2008 8:44:40 PM mbsiehs

Top 50 Posts
Joined on 09-27-2007
Posts 32
Re: Saving RasterImages to SQL 2005
Reply Quote
More information...

In more testing, I started suspecting that the crash was only on the HighResolutionImage (see my original post) and not the LowResolutionImage, so I switch the order in which they were saved to MemoryStreams.  This was an attempt to see if the the anomaly was related to a specific image and sure enough the exception was still thrown for the HighResolutionImage.  Given that, I started searching for how I handled the imaged differently through the capture-save process and there were two differences...1) I don't draw the high resolution image and 2) I don't resize it via ResizeCommand (I do both to the low resolution image).  As an experiment I decided to resize the high resolution image to its same size.  Sure enough, when I do that as the image is captured, no exception is thrown on save.

Of course that's a band-aid, but it's one that gives me information as to the problem.  For efficiency reasons I don't want to run the ResizeCommand action if I don't have to. 

Here is a copy of my image capture functionality with the new resizing that worked:

        public static void GetLeadtoolsImages(Series.ImageView imageView, Leadtools.RasterImage sourceImage)
        {
            // testing
            ResizeCommand command = new ResizeCommand();

            if ((imageView == null) || (sourceImage == null))
                return;

            //imageView.HighResolutionImage = sourceImage;  < this is the OpenedFileData[0].Image returned from RasterOpenDialog
            // this fixes the problem for some reason
            imageView.HighResolutionImage = new RasterImage(
                RasterMemoryFlags.Conventional,
                (int) (sourceImage.Width),
                (int) (sourceImage.Height),
                sourceImage.BitsPerPixel,
                sourceImage.Order,
                sourceImage.ViewPerspective,
                sourceImage.GetPalette(),
                IntPtr.Zero,
                0);
            command = new ResizeCommand();
            command.DestinationImage = imageView.HighResolutionImage;
            command.Flags = RasterSizeFlags.Bicubic;
            command.Run(sourceImage);

            imageView.OriginalPixelSize = new Size(
                imageView.HighResolutionImage.Width, imageView.HighResolutionImage.Height);

            ImageManipulator.GetOtherLeadtoolsImages(imageView);
            imageView.IsNew = true;
        }

So given the "Attempted to read or write..." exception is with reading the RasterImage and not the writing to the MemoryStream, what side effect of either 1) resizing or 2) saving a new image generated from the old one via the RasterImage(RasterImage) constructor (earlier post) is resetting the accessibility of the RasterImage?

Thanks again for your help on this.
Matt

By the way, that action seemed to fix the BitsPerPixel problem as well.


   Report 
Post
 Page 1 of 2 (20 items) 1 2 »
LEAD Support Fo... » Developer » Database » Saving RasterImages to SQL 2005

Powered by Community Server, by Telligent Systems