Memeory limitation problems ???

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I Have a PC with dual XEON CPU’s and 4 Giga Byte RAM win Windows XP Pro.
I have 2 problems with it:
(1) Windows is showing only 3.25 Giga byte on the System Properties ?
General tab.
While the bios to see all of the 4 GBytes.
I some article I read that the WinXP Pro can only handle 4GBytes of memory
including the virtual memory, so I set it to not use any page file, but it
did not help.
(2) I want my .NET application to use more then 1.2 GByte of memory, so I
insert at the Boot.ini file the /3GB flag and did reboot. Now I also need to
add to my application linker the /LARGEADDRESSAWARE flag for it to be
IMAGE_FILE_LARGE_ADDRESS_AWARE (see
http://www.microsoft.com/whdc/system/platform/server/PAE/PAEmem.mspx). But I
find no where to put the flag in the project properties.

Can anybody tell me how solve this 2 issues?
 
Sharon said:
I Have a PC with dual XEON CPU’s and 4 Giga Byte RAM win Windows XP Pro.
I have 2 problems with it:
(1) Windows is showing only 3.25 Giga byte on the System Properties ?
General tab.
While the bios to see all of the 4 GBytes.
I some article I read that the WinXP Pro can only handle 4GBytes of memory
including the virtual memory, so I set it to not use any page file, but it
did not help.
(2) I want my .NET application to use more then 1.2 GByte of memory, so I
insert at the Boot.ini file the /3GB flag and did reboot. Now I also need
to
add to my application linker the /LARGEADDRESSAWARE flag for it to be
IMAGE_FILE_LARGE_ADDRESS_AWARE (see
http://www.microsoft.com/whdc/system/platform/server/PAE/PAEmem.mspx). But
I
find no where to put the flag in the project properties.

Can anybody tell me how solve this 2 issues?

1) There is nothing you can do about this. The reason for this is that
system ROM and PCI devices (PCIe, AGP video controller, SATA PCI etc..) are
mapped into the memory space below the 4GB boundary which is no longer
visible to the OS. Some 64bit OS like W2K3 64 and XP 64, have inbuilt memory
remapping features that can reallocate the memory by mapping the used
regions behind the 4GB barrier which is impossible for 32bit systems with a
32bit OS, some motherboard chipsets/BIOS have also an option to remap the
memory used by PCI and other HW devices to be mapped above 4GB but this
requires a 64 bit OS anyway.
2). The only way to set this flag for managed PE execuatbles is through the
editbin.exe utility. But don't expect you will ever be able to allocate more
than 1.2 - 1.5 GB in one contigious block of memory, even with the /3GB RAM
tuning enabled. If this is where you after, forget about it, your only
option is a 64 bit OS.
A serious drawback of /3GB ram tuning is that kernel space is now reduced to
1GB effectively reducing the pooled space and system cache, your system
performance will probably suffer from this, it might even be possible that
the system fails to start or run because some drivers failed to load, though
this can be solved by using the /USERVA switch instead of /3GB in boot.ini
(XP SP2).

Willy.
 
Hi Willy,

Thanks for your replay.

(1) I found a discussions about the same issue:
http://msdn.microsoft.com/newsgroup...harp&mid=d05f7a58-f4f2-4bb4-a43f-0c3b9681dd2b
and it seems to succeed with the 4Mbytes RAM. So I very much need to do it.
Also, the Windows Xp 32 bit Pro documentation indicate that it can consume
up to 4MB.
The BIOS does recognize the extended RAM as 4,192,768 bytes. so I really
need this.
(2) About the drawback - Don't you think that 1GB of RAM should be enough
for the kernel?
 
Sharon said:
Hi Willy,

Thanks for your replay.

(1) I found a discussions about the same issue:
http://msdn.microsoft.com/newsgroup...harp&mid=d05f7a58-f4f2-4bb4-a43f-0c3b9681dd2b
and it seems to succeed with the 4Mbytes RAM. So I very much need to do
it.
Also, the Windows Xp 32 bit Pro documentation indicate that it can consume
up to 4MB.
The BIOS does recognize the extended RAM as 4,192,768 bytes. so I really
need this.
(2) About the drawback - Don't you think that 1GB of RAM should be enough
for the kernel?

1) A windows application is limitted to 2GB or 3GB of virtual address space
depending on the set-up.
If you think you need 3GB you have to set the /3GB switch in boot.ini and
you need to link your application with the /LARGEADDRESSAWARE switch set.
..NET managed application not linked, here you have to pass the exe file to
editbin.exe with the /LARGEADDRESSAWARE switch set (editbin.exe will set the
IMAGE_FILE_LARGE_ADDRESS_AWARE bit in the PE header).

Not sure what you mean with "I really need this".
- Your program will never be able to use 4GB on a 32 bit windows OS. And you
will never be able to use 4GB RAM unless you run a 64 bit windows version
with "memory remapping" enabled (in the BIOS or software).
- Your application will never be able to allocate a single array larger than
~1.5GB, if this is what you want forget this whole /3GB thing, your only
option is Windows XP64 or W2K3 64.

2) I don't know it depends on so many things, it depends on the number and
type of HW devices, it depends on the software running, the number of
processes number of threads etc.
Why do you think 1GB is more than enough for the kernel, while 2GB is not
enough for your single application?

Some KB articles you should read carefully before deciding to go down that
road.

http://support.microsoft.com/default.aspx?scid=kb;en-us;319043
http://support.microsoft.com/kb/316739/EN-US/

Willy.
 
Hi Willy,

Thanks a lot for your prompt replay.

(1) I already did all that is necessary for my application to use more then
2GB and it's working fine now.

When I say "I really need this", I mean that I need the Windows operation
system to recognize all the 4GB installed.

(2) I think that the Windows kernel will run nicely on a 1GB RAM because my
PC is a dedicated PC and I can tell what will run on it, so as I see it 1GB
seems to be fine, after all; Windows XP Pro can run on a 256 MB PC's as well.

After reading the MSDN KB you mentioned, I can see that is for Windows 2003
servers (one of the KB) and the other is saying that it may happen, but it is
not happening in my case as everything is running OK after I applied the /3GB
switch.


So now the only trouble I have is how to make the Windows XP Pro 32 bit with
SP2 to see all of the 4GB installed and not only 3.25 GB ?
 
Sharon said:
Hi Willy,

Thanks a lot for your prompt replay.

(1) I already did all that is necessary for my application to use more
then
2GB and it's working fine now.

When I say "I really need this", I mean that I need the Windows operation
system to recognize all the 4GB installed.

(2) I think that the Windows kernel will run nicely on a 1GB RAM because
my
PC is a dedicated PC and I can tell what will run on it, so as I see it
1GB
seems to be fine, after all; Windows XP Pro can run on a 256 MB PC's as
well.

After reading the MSDN KB you mentioned, I can see that is for Windows
2003
servers (one of the KB) and the other is saying that it may happen, but it
is
not happening in my case as everything is running OK after I applied the
/3GB
switch.


So now the only trouble I have is how to make the Windows XP Pro 32 bit
with
SP2 to see all of the 4GB installed and not only 3.25 GB ?

As I told you previously, the Windows OS CAN see/access most of the 4GB RAM
space, but 'you' can't see all the 4GB RAM, part of this (above 3.25GB in
your case) is taken by the hardware mapping done by the system BIOS, for
instance your video RAM (depending on the size) must be mapped into that 4GB
address space to be addressable by a 32 bit OS. A 64 bit system running a 64
bit OS can remap this area (some chipsets do not !!!, so please check your
systems BIOS to see whether this is possible) to some address outside the
installed RAM space, but this same system running a 32 bit OS cannot, simply
because a 32 bit OS cannot address anything above 4GB.

You remark on point 2 make little sense, you need to make a clear
destinction between RAM space and virtual memory (that is RAM + pagefile
space). A 256 MB RAM system will have a hard time to run anything
significant without a pagefile, don't even try to run a DirectX or OpenGL
application on such system with a 128/256MB RAM video card installed, it
wont work (even not with a 500MB pagefile).
And don't forget that a system with 4GB installed RAM will have a 16 times
larger page table (kernel space) than a 256 MB system.

Willy.
 
I must say it looks a too much memory for only mapping. It's also mean that
the Windows XP OS can not really use 4GB but less. But how much less? 3.25GB
looks like a very much less.

Furthermore, I extended the memory to 4GB in order to allow to my
application to use up to 3GB. But if the OS sees only 3.25GB it will not let
my application use the amount of memory I want it to use.

So my final question is which is very important to me:

In the case I described (4GB RAM that shown as a 3.25GB), does my
application can use up to 3GB (after applying the /3GB in the Boot.ini and
adding the IMAGE_FILE_LARGE_ADDRESS_AWARE flag to my app image header)?
 
Sharon said:
I must say it looks a too much memory for only mapping. It's also mean that
the Windows XP OS can not really use 4GB but less. But how much less?
3.25GB
looks like a very much less.
No, Windows XP 32 cannot use the full 4GB RAM space, because the hardware
components memory must be mapped in this address space, the amount of mapped
memory space depends on the type and number of controllers, expecially video
controllers can take a large amount of this (there are Nvidia boards with
512MB memory on board) and they have to be aligned on a 256MB boundary. In
your case it looks like you have a 256MB video board or at least a board
that is mapped at that address (0XD0000000).
Furthermore, I extended the memory to 4GB in order to allow to my
application to use up to 3GB. But if the OS sees only 3.25GB it will not
let
my application use the amount of memory I want it to use.
Why? 3.25 GB is more than 3GB isn't it? Plus, you don't need 3GB RAM for an
application to consume 3GB of memory, please read my other reply where I
explain the difference between virtual and physical memory.
So my final question is which is very important to me:

In the case I described (4GB RAM that shown as a 3.25GB), does my
application can use up to 3GB (after applying the /3GB in the Boot.ini and
adding the IMAGE_FILE_LARGE_ADDRESS_AWARE flag to my app image header)?
Well you have to be more specific, 3GB is the max. space on a system that
has /3GB enabled and IMAGE_FILE_LARGE_ADDRESS_AWARE set for the application,
BUT that doesn't mean your program code can allocate all 3GB, first you have
your code and the runtimes mapped in this address space, you have the space
reserved by the stacks (1MB per thread) and you have holes in this address
space that can't be used - a 64 KB hole at the start (address range 0-FFFF)
and a hole before the end of the 2GB range (7FFF0000-7FFF0000). And you have
to consider the mapping of the DLL's (code) into that address space (some
are mapped at a very unfortunate location). All these mappings and holes
result in a fragmented virtual memory space,so you don't have one single
large chunk of free memory, no you have several chunks from which the
largest is ~1.4 GB for a minimal .NET application.
That means that at best, the largest array that can be allocated is ~1.4GB
(but that's never guaranteed!!!), allocating four arrays of 0.5 GB plus a
couple of 100MB arrays on a /3GB system, should mostly succeed, but again
this is never guaranteed, VM can become framgmented over time.

One last suggestion, if you absolutely need to allocate a single array
that's larger than say 1GB, you should consider moving to Windows XP 64,
here you can remap the HW to addresses above 4GB and the VM address space is
4GB for 32 bit applications.
Note that whatever OS you are using, the max. size of an array in .NET is
2GB (the max size of whatever CLR object).
Willy.
 
OK, I see what you mean.

Allow to me to explain the real problem and requirements that led to the
trouble at hand;

I'm developing a project that need to take large image at a time, load it
all into memory and do some image processing.
The images are of type TIF file 62992 x 113386 Pixels, Huffman RLE
compression, 3200 x 3200 DPI resolution, binary colored (1 Bit Per Pixel),
file on disk size 43.08 MB (45,169,042 Bytes).
This kind of image should consume 851.66 MB (893,028,184 Bytes) of memory
when loaded (this is what it takes using the IrfanView
http://www.irfanview.com/) and a project at
http://www.codeproject.com/bitmap/graphicsuite.asp), and this is exactly what
I want it to consume. Otherwise; the representation per pixel will be 1 byte
(8 Bits), which means that this kind of image require 6.652 GB (7,142,410,912
Bytes) that I absolutely can not have in any possible way.

I found that the Bitmap object can hold 1 bit per pixel, but for some
reason, it can not handle this kind of picture and throws ArgumentException
saying
"Invalid parameter used". But if I load the image using
Image.FromFile(imageFilePath) it throw en OutOfMemoryException saying "Out Of
Memory" and it's because it consume twice the memory it should (not 8 times
the memory).

So, in order to meet with this requirements we took a dual XEON PC with 4GB
memory and set the Boot.ini with the /3GB and linked our application with the
IMAGE_FILE_LARGE_ADDRESS_AWARE flag to my application image header. Yet it
still fails.

So, we are doing the image processing algorithms using unmanaged C++, but
yet, I need to load a high resolution sample of the image I mentioned above
by loading it to a Bitmap object and reduce it size to loaded to a PictureBox
control.
I already have a very good code for resizing the image, but it required a
Bitmap object, and it fails to load this image as I described above.

Now you have the bigger picture to understand the actual problem.

In this stage, using Windows 64 bit, is not an option, but it's the only
solution, we may use it.

Do I need to change something in my code on in my assembly to use a 64 bit
Windows system?
Can I still work with the same PC hardware (CPU's, devices etc.)?


What do you think?
 
I have some more info:

At the PC device driver a saw that the PC has ASUS Extreme graphics adapter
with 128 MB and another ASUS graphics adapter with 128 MB as Secondary
(memory range D8000000-DFFFFFFF, D0800000-D080FFFF, 000A0000-000BFFFF). The
PC also installed with LAN and GLAN, and a Ceroco Imaging device X64-CL_iPro
Board (memory range D0400000-D07FFFFF).

I have posted another question on the win32.programmer.kernel Discussions, I
the answer I gat is very confusing
http://msdn.microsoft.com/newsgroup...rnel&mid=38a97f2c-2f4e-4d73-8045-ad91520ac866
I actually say that it does see the installed 4GB.

What do you think?
 
See inline

Willy.

Sharon said:
OK, I see what you mean.

Allow to me to explain the real problem and requirements that led to the
trouble at hand;

I'm developing a project that need to take large image at a time, load it
all into memory and do some image processing.
The images are of type TIF file 62992 x 113386 Pixels, Huffman RLE
compression, 3200 x 3200 DPI resolution, binary colored (1 Bit Per Pixel),
file on disk size 43.08 MB (45,169,042 Bytes).
This kind of image should consume 851.66 MB (893,028,184 Bytes) of memory
when loaded (this is what it takes using the IrfanView
http://www.irfanview.com/) and a project at
http://www.codeproject.com/bitmap/graphicsuite.asp), and this is exactly
what
I want it to consume. Otherwise; the representation per pixel will be 1
byte
(8 Bits), which means that this kind of image require 6.652 GB
(7,142,410,912
Bytes) that I absolutely can not have in any possible way.

I found that the Bitmap object can hold 1 bit per pixel, but for some
reason, it can not handle this kind of picture and throws
ArgumentException
saying
"Invalid parameter used". But if I load the image using
Image.FromFile(imageFilePath) it throw en OutOfMemoryException saying "Out
Of
Memory" and it's because it consume twice the memory it should (not 8
times
the memory).

This is how GDI+ works (wrapped by the System.Drawing), Image.FromFile
instructs GDI+ to load the file as a memory mapped object and from that it
builds an imageobject (fi. a Bitmap). That means at some point in time you
have the file data and the bitmap data allocated in unmanaged memory (yes,
they are unmanaged resource), this roughly represents two times the file
data. The same thing is done using IrfanView or any other unmanaged tool,
what's different is that once the Bitmap is built, the file is closed and
the mapped memory released (you can check this with perfmon), while when
using .NET the resources are released when you call Dispose on the image.
So, if it works with the tools you mentioned, it should work with .NET also.
Did you try by simply loading the tiff file using a small console program.

public static int Main()
{
Image i = Image.FromFile(@"YourtTiffFile");
}

So, in order to meet with this requirements we took a dual XEON PC with
4GB
memory and set the Boot.ini with the /3GB and linked our application with
the
IMAGE_FILE_LARGE_ADDRESS_AWARE flag to my application image header. Yet it
still fails.

So, we are doing the image processing algorithms using unmanaged C++, but
yet, I need to load a high resolution sample of the image I mentioned
above
by loading it to a Bitmap object and reduce it size to loaded to a
PictureBox
control.

Why don't you load and reduce it's size using C++ as well?
I already have a very good code for resizing the image, but it required a
Bitmap object, and it fails to load this image as I described above.

Now you have the bigger picture to understand the actual problem.

In this stage, using Windows 64 bit, is not an option, but it's the only
solution, we may use it.

Do I need to change something in my code on in my assembly to use a 64 bit
Windows system?
Can I still work with the same PC hardware (CPU's, devices etc.)?
Don't know for sure, it depends on the exact CPU type (should be 64 bit
capable) and other devices. Anyway, you should try this to be sure. I guess
you can obtain an evaluation versions of W2K3 64bit or XP64 from MS.
 
Sharon said:
I have some more info:

At the PC device driver a saw that the PC has ASUS Extreme graphics
adapter
with 128 MB and another ASUS graphics adapter with 128 MB as Secondary
(memory range D8000000-DFFFFFFF, D0800000-D080FFFF, 000A0000-000BFFFF).
The
PC also installed with LAN and GLAN, and a Ceroco Imaging device
X64-CL_iPro
Board (memory range D0400000-D07FFFFF).

I have posted another question on the win32.programmer.kernel Discussions,
I
the answer I gat is very confusing
http://msdn.microsoft.com/newsgroup...rnel&mid=38a97f2c-2f4e-4d73-8045-ad91520ac866
I actually say that it does see the installed 4GB.

What do you think?

This confirms what I told you before, you have hardware mapped at D0400000
and above, that means that the highest address that can be used by the
software is 0xD03FFFFF, which is 3.253 GB.
The other post at win32.programmer.kernel Discussions, is indeed confusing,
all I can say is that in your case memory from hardware devices is mapped
into the 4GB address space, other systems may run different OS'ses on
different hardware, so it's possible that HW is remapped by the BIOS onto a
range above 4GB.
But again don't waste your time with the amount of memory reported by the
OS, it's not the cause of your problem, believe me.

Another confusing point is that they try to allocate a managed array of
1.3GB
< snip from win32.programmer.kernel Discussions
2> I checked that thread, the line "byte [] c=new byte[1300000000];" failed
with OutOfMemoryException.which fails, again I told you why it fails (1). But your issue is not
related to a managed array, the TIF file and Bitmap are allocated in the
unmanaged heap, see my previous post.

(1) A simple .NET console program can allocate at most ~1.4GB contigious
memory (a single array), a Windows.Forms program using GDI+
(System.Graphics) only ~1.2GB.

This should work on v1.1

public static int Main()
{
byte[] m = new byte[1500000000];
}

Willly.
 
(*) I’m working on a PC with a 1.5 GB RAM, and the IrfanView is successfully
loading the TIF I mentioned when only 937MB are available.
So I wrote a very simple console application that only does:

System.Drawing.Image img = Image.FromFile( @â€The TIFF file Name†);

But I get OutOfMemoryException.
So I guess it’s doing something wrong. Can you tell what is it?


I’m not sure I’m fully understand what you are saying
“this roughly represents two times the file data. The same thing is done
using IrfanView or any other unmanaged tool, what's different is that once
the Bitmap is built, the file is closed and the mapped memory released (you
can check this with perfmon), while when using .NET the resources are
released when you call Dispose on the image.â€

You say that if the IrfanView can do it, I can do it too with .NET.
Can you be more specific? How can I build a Bitmap object in .NET for the
TIFF file I mentioned before so it will consume memory as the IrfanView does
[ ((width * height) / 8) + some extra bytes for header info ] ???


(*) I’m not using C++ to load and reduce its size because of design issues
(different component, different programmers etc.)?
 
Sharon said:
(*) I’m working on a PC with a 1.5 GB RAM, and the IrfanView is
successfully
loading the TIF I mentioned when only 937MB are available.
So I wrote a very simple console application that only does:

System.Drawing.Image img = Image.FromFile( @â€The TIFF file Name†);

But I get OutOfMemoryException.
So I guess it’s doing something wrong. Can you tell what is it?


I’m not sure I’m fully understand what you are saying
“this roughly represents two times the file data. The same thing is done
using IrfanView or any other unmanaged tool, what's different is that once
the Bitmap is built, the file is closed and the mapped memory released
(you
can check this with perfmon), while when using .NET the resources are
released when you call Dispose on the image.â€

You say that if the IrfanView can do it, I can do it too with .NET.
Can you be more specific? How can I build a Bitmap object in .NET for the
TIFF file I mentioned before so it will consume memory as the IrfanView
does
[ ((width * height) / 8) + some extra bytes for header info ] ???


(*) I’m not using C++ to load and reduce its size because of design
issues
(different component, different programmers etc.)?

I'm starting to think that your tiff file contains a non supported Gdi++
pixelformat, could you compile following small program and try to run it.
Note that you sould adapt:
Image::FromFile(L"YourTiffFile", false);
before compiling.

// save as loadtif.cpp, and compile with...
// cl /EHsc /MD loadtif.cpp gdiplus.lib
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
int main()
{
GdiplusStartupInput gdiplusStartupInput;
unsigned long gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Image* image = Image::FromFile(L"YourTiffFile", false);
switch(image->GetPixelFormat())
{
case PixelFormatUndefined:
case PixelFormat1bppIndexed:
case PixelFormat4bppIndexed:
case PixelFormat8bppIndexed:
case PixelFormat16bppGrayScale:
printf("Not supported GDI+ pixelformat\n");
break;
case PixelFormat16bppARGB1555:
printf("PixelFormat16bppARGB1555n");
break;
case PixelFormat24bppRGB:
printf("PixelFormat24bppRGB\n");
break;
case PixelFormat16bppRGB555:
printf("PixelFormat16bppRGB555\n");
break;
case PixelFormat16bppRGB565:
printf("PixelFormat16bppRGB565\n");
break;
case PixelFormat32bppARGB:
printf("PixelFormat32bppARGB\n");
break;
case PixelFormat32bppPARGB:
printf("PixelFormat32bppPARGB\n");
break;
case PixelFormat32bppRGB:
printf("PixelFormat32bppRGB\n");
break;
case PixelFormat48bppRGB:
printf("PixelFormat48bppRGB\n");
break;
case PixelFormat64bppARGB:
printf("PixelFormat64bppARGB\n");
break;
case PixelFormat64bppPARGB:
printf("PixelFormat64bppPARGB\n");
break;
}
Image* pThumbnail = image->GetThumbnailImage(image->GetWidth(),
image->GetHeight(), NULL, NULL);
delete pThumbnail;
delete image;
GdiplusShutdown(gdiplusToken);
return 0;
}
 
Hi Willy,

Ok, I tested my image file (BMP file, 14174x7874 Pixels, 3200x3200 DPI, No
compression, 1 BitsPerPixel, on disk size 13,952,790 Bytes, memory size
13,952,776 Bytes) using your code and it prints that it’s not supported GDI+
pixelformat. It goes to the PixelFormat1bppIndexed case.

I also tested this code on the big image (TIF file, 62992x113386 Pixels,
3200x3200 DPI, Huffman RLE compression, 1 BitsPerPixel, on disk size
45,169,042 Bytes, memory size 893,028,184 Bytes) and it also prints not
supported GDI+ pixelformat, and goes into the PixelFormatUndefined case.

[Not: in .NET the Image.FromFile() is failing to event load this image and
throws OutOfMemory exception. But your code in C++ does succeed to load it.]

Both of these images are black and white images none indexed.

And that I know. The Bitmap/Image object also indicates it’s a
PixelFormat1bppIndexed, but it is not!
The image pixel format is 1 bit per pixel binary image for black and white
and not indexed as the pixel format is indicating.

So now we know why it is not working. But, as you already knows, the
IrfanView, the CodeProject http://www.codeproject.com/bitmap/graphicsuite.asp
and the http://www.codeproject.com/staticctrl/imagepreview.asp are all
successfully loading this image.


When I load my image using:
System.Drawing.Image m_backBuffer =
System.Drawing.Image.FromFile(@"MyImageFileName");

Its ok, but when I try to get it’s graphics by:

Graphics g = Graphics.FromImage(m_backBuffer);

I get:
System.Exception {“A Graphics object cannot be created from an image that
has an indexed pixel format.â€}


How can I work with this kind of images in .NET?

P.S.: I opened a new discussion about the problem that the PictureBox
control is very slow and eats up the memory for every redraw
http://msdn.microsoft.com/newsgroup...harp&mid=3ce449af-5393-45c5-aca3-359da4f3cd74.
This discussion is very much continuing our discussion, so if you can help
me with that, I’ll more then happy.
 
Inline

Willy.

Sharon said:
Hi Willy,

Ok, I tested my image file (BMP file, 14174x7874 Pixels, 3200x3200 DPI, No
compression, 1 BitsPerPixel, on disk size 13,952,790 Bytes, memory size
13,952,776 Bytes) using your code and it prints that it’s not supported
GDI+
pixelformat. It goes to the PixelFormat1bppIndexed case.

I also tested this code on the big image (TIF file, 62992x113386 Pixels,
3200x3200 DPI, Huffman RLE compression, 1 BitsPerPixel, on disk size
45,169,042 Bytes, memory size 893,028,184 Bytes) and it also prints not
supported GDI+ pixelformat, and goes into the PixelFormatUndefined case.

[Not: in .NET the Image.FromFile() is failing to event load this image and
throws OutOfMemory exception. But your code in C++ does succeed to load
it.]
*** Note that Image.FromFile() can throw an OOM exception when the pixel
format is not supported! (Check the MSDN docs). The C++ program loads the
image but it cannot be used to create a Graphics object, as the format is
not supported by GDI+ (see your other .NET tests).

Both of these images are black and white images none indexed.

*** Well according the tests it's an PixelFormat1bppIndexed format right?
And that I know. The Bitmap/Image object also indicates it’s a
PixelFormat1bppIndexed, but it is not!

Hmm.... according GDI+ the first file is PixelFormat1bppIndexed and the
second is a PixelFormatUndefined, both are not supported in GDI+ and as
System.Drawing sits in top of GDI+ it supports the same pixelformats.
it throws an exception (OOM).

The image pixel format is 1 bit per pixel binary image for black and white
and not indexed as the pixel format is indicating.

So now we know why it is not working. But, as you already knows, the
IrfanView, the CodeProject
http://www.codeproject.com/bitmap/graphicsuite.asp
and the http://www.codeproject.com/staticctrl/imagepreview.asp are all
successfully loading this image.

*** My guess is that they are not using GDI+

When I load my image using:
System.Drawing.Image m_backBuffer =
System.Drawing.Image.FromFile(@"MyImageFileName");

Its ok, but when I try to get it’s graphics by:

Graphics g = Graphics.FromImage(m_backBuffer);

I get:
System.Exception {“A Graphics object cannot be created from an image
that
has an indexed pixel format.â€}
*** Here apparantly no OOM exception is being thrown when calling FromFile,
but it throws a "wrong format exception" when attaching to a graphics
object.
How can I work with this kind of images in .NET?

*** Hmmm... as their pixelformats aren't supported, I would say use
supported pixel formats or convert them to supported pixel formats.
 
Hi Willy,

Now we know that the problem is the GDI+ support. We also know that the .Net
controls are using the GDI+, therefore can not support this kind of images.

I also think that the other programs that I mentioned are successfully using
this kind of images, because they are not using GDI, they are using CDC and
are written in C++.

I can not convert this images offline as they are input to my program that
the end user will supply at run time and are changed for every single use.

The conclusion is - or to write a new control in C++ and warp in a C#
control, or to write a C++/C# component that will convert and reduce the size
of the input image, and to go on from there.


I must say I’m very disappointed by the .NET support for large images and
for 1bpp images.
I hope it will have this kind of support in the near future,
 
Sharon said:
Hi Willy,

Now we know that the problem is the GDI+ support. We also know that the
.Net
controls are using the GDI+, therefore can not support this kind of
images.

I also think that the other programs that I mentioned are successfully
using
this kind of images, because they are not using GDI, they are using CDC
and
are written in C++.

I can not convert this images offline as they are input to my program that
the end user will supply at run time and are changed for every single use.

The conclusion is - or to write a new control in C++ and warp in a C#
control, or to write a C++/C# component that will convert and reduce the
size
of the input image, and to go on from there.


I must say I’m very disappointed by the .NET support for large images
and
for 1bpp images.
I hope it will have this kind of support in the near future,

Yes, they are written using C++, but they use MFC (native code Microsoft
Foundation Classes for C++) in top of GDI (GDI32.DLL) just like anything
that runs on windows (which is sitting under GDI+). (Don't know for sure
what you mean by CDC, but I guess you noticed a CDC which stands for Class
Device Context.

What can be done using MFC can also be done with C# (.NET whatever you call
it) and the System.Windows.Forms & System.Drawing namespace classes, but
you are trying to build applications like those you mention by simply
dropping a PictureBox control on a form, well this doesn't work as that's is
not what the control is built for, you need to write code just like the
authors of "graphicsuite" have done, but now using managed code & framework
classes.

Willy.
 
Hi Willy,

It’s sounds very promising, but when I try to load the file image by
Image.FromFile() or by new Bitmap() it fails due to OOM and wrong argument
respectively.
So as you can see, it fails even before I get near the PictureBox control.
Forthermore, as I mentioned before, if I successfully load a smaller image
and try to get its graphics, it fail again on System.Exception {“A Graphics
object cannot be created from an image that has an indexed pixel format.â€}

Yes, when I say CDC I mean device-context class (of the MFC) that works with
the GDI and more.

I’ll be very glad to work with the .NET/C# as you claim I can, but I simply
can’t see how.

Can you post or address me to some sample code that odes that? That load
large 1bppIndexed image and draw on it?

P.S.: You were right, my images are PixelFormat1bppIndexed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top