Welcome Guest! You need to login or register to make posts.

Notification

Icon
Error

Options
Go to last post Go to first unread
Todd Kneib  
#1 Posted : Friday, February 8, 2019 10:43:47 AM(UTC)
Todd Kneib

Rank: Advanced Member

Groups: Member
Joined: 5/10/2006(UTC)
Posts: 32

Thanks: 6 times
I'm having to process an external data file that contains image data, but not in any normal format, and construct the image this is in it. These images are often 9600x101406 24bbp or bigger.

I create a new Aurigma bitmap instance with those dimensions, and then use the Scan0 to directly access the pixels to assign the colors from the external file.

When I get to pixel location row 74566, column 0, I get an access violation. Which is a hair more than 2GB. (74566 * 9600 * 3) = 2,147,500,800

Any ideas on what to do?

.net 4.6.2

Aurigma Graphics Mill, 9.2.23.0 x64

Code:

//must use lingpad 'any cpu' or create a console app set to run as 64bit.
void Main()
{
	int height = 101406;
	int width = 9600;
	var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
	unsafe
	{
		System.Drawing.Color color = System.Drawing.Color.Beige;
		for(int y = 0; y < height; y++)
		{
			if (y % 50 == 0) Console.Write(".");
			if (y % 1000 == 0) Console.WriteLine(" " + y);
			
			byte* rowStartPosition = (byte*)bmp.Scan0.ToPointer() + (y * bmp.Stride);
			for(int x = 0; x < width; x++)
			{
				try
				{
					byte* pixelPostion = rowStartPosition + (x * 3);
					// do real work here 
					//var color = CMYKToRGB(planes[0][x], planes[1][x], planes[2][x], planes[3][x]);
					
					//will crash here when we pass 2GB
					*(pixelPostion + 0) = (byte)color.B;
					*(pixelPostion + 1) = (byte)color.G;
					*(pixelPostion + 2) = (byte)color.R;
				}
				catch(Exception ex) //since it is an Access violation, we cannot not catch it without extra settings
				{
					Console.WriteLine($"Error updating pixel color. x,y {x},{y}. msg: {ex.Message}");
					throw;
				}
			}
		}
	}
}

app.config - to allow memory allocation greater than 2GB

Code:

<configuration>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true"></gcAllowVeryLargeObjects>
  </runtime>
</configuration>

Upon further testing with this simple example, I dont think the Memory, at least not all of it, is getting allocated during the new call. The new call does take a few seconds.

Code:

int height = 101406;
int width = 9600;
var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
bmp.Fill(Color.FromGdiPlusColor(System.Drawing.Color.BlueViolet));

bmp.Save(@"C:\temp\test.jpg");

I get an ArgumentOutOfRangeException during the Save call, the callstack looks like its running the pipeline at the time of save.

Code:

   at Aurigma.GraphicsMill.GMException.ThrowManagedException(IntPtr unmanagedException)
   at Aurigma.GraphicsMill.PipelineElement.RunPipeline()
   at Aurigma.GraphicsMill.Pipeline.Run()
   at Aurigma.GraphicsMill.Bitmap.SaveToWriter(ImageWriter writer)
   at Aurigma.GraphicsMill.Bitmap.Save(String fileName)
   at UserQuery
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

Eugene Kosmin  
#2 Posted : Sunday, February 10, 2019 7:10:00 PM(UTC)
Eugene Kosmin

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 9/19/2006(UTC)
Posts: 505

Was thanked: 41 time(s) in 41 post(s)
Hi Todd,

Try to replace int in your cycles to Int64 type.

Code:
for (System.Int64 y = 0; y < height; y++)
{
    for (System.Int64 x = 0; x < width; x++)
    {
    }
}

Quote:
I get an ArgumentOutOfRangeException during the Save call, the callstack looks like its running the pipeline at the time of save.

Please note that the exception message says "Argument is out of range (Jpeg frame resolution cannot be larger than 66535 x 65535 pixels)."

A lot of image formats has only 2 bytes per image size. JPEG is one of them. TIFF format allows more:

Code:
bmp.Save("out.tif", new TiffSettings() { Compression = CompressionType.Zip });
Best regards,

Eugene Kosmin

The Aurigma Development Team

Todd Kneib  
#3 Posted : Wednesday, February 20, 2019 12:37:05 PM(UTC)
Todd Kneib

Rank: Advanced Member

Groups: Member
Joined: 5/10/2006(UTC)
Posts: 32

Thanks: 6 times
Thanks!

Both of your answers worked. Thanks!

Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.