Reputation: 1970
We had recently few threads (below) on SO where one of the common suggestion was do not use pointer.
is strings in .net get changed?? is there some bug?
I recently had requirement to convert Bitmap images white background to transparent. I tried around and most optimum implementation I could come up with is below.
public unsafe Bitmap MakeWhiteAreaTransparent(Bitmap source)
{
Bitmap bitmap = new Bitmap(source.Width, source.Height, PixelFormat.Format32bppArgb);
BitmapData bitmapdata = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData data2 = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* numPtr = (int*)bitmapdata.Scan0;
int* numPtr2 = numPtr + (bitmapdata.Width * bitmapdata.Height);
int* numPtr3 = (int*)data2.Scan0;
int num = Color.FromArgb(1, Color.White).ToArgb();
while (numPtr < numPtr2)
{
numPtr++;
Color color = Color.FromArgb(numPtr[0]);
if (((color.R < 200) || (color.G < 200)) || (color.B < 200))
{
numPtr3[0] = color.ToArgb();
}
else
{
numPtr3[0] = num;
}
numPtr3++;
}
source.UnlockBits(bitmapdata);
bitmap.UnlockBits(data2);
return bitmap;
}
I was wondering if I am correct in suing pointer or I should use byte array and System.Runtime.InteropServices.Marshal.Copy and not mug around with pointers???
Upvotes: 0
Views: 144
Reputation: 134045
There is nothing at all wrong with using unsafe code. You use the right tool for the job. Support for unsafe code and pointers is built into the language, which means that the developers thought it was a useful thing -- useful enough to implement at the expense of implementing some other features.
There is a place for unsafe code. As you discovered, it's the fastest way to access the raw data in a bitmap image. Yes, there are ways to do that in safe code, but they're a lot slower. Unsafe code is also the only way to work with memory buffers that are larger than two gigabytes.
And, yes, there are applications in which you really do need to have a single object that is several gigabytes in size. You can dispute this all you like, and I'll just laugh at you like I laughed at the idiots back in the '80s who said things like, "who'd need a whole megabyte of RAM?"
Some would say that if you find yourself needing unsafe code, you should write a native DLL in C++ and call it from your .NET program. That's a stupid idea. First, you might not have the tools or knowledge to build a native DLL. Second, that adds more dependencies in your project. Third, there's no particular benefit. Is it "safer?" No.
Use what you need to get the job done. Make every effort to use safe code. But if you find, after you've tried everything else, that what you need to do requires unsafe code .... use it! That's why support for it was added to the platform.
Upvotes: 2
Reputation: 35594
My opinion is the following: you should use the language in the way it's supposed to be used. The C# is supposed to be used with safe code, leaving unsafe as a last resort where some code needs to be very fast, and is called too often.
Let me put some examples.
You need to do some slow operation, but it can run somewhere in background, not so often, and its speed is not really really critical. In this case you can just use safe code: although this approach might be not squeezing last bits of performance out of your processor, it's considerably less effort in implementation and (which is more important) in maintenance.
You need to speed up the operation, the safe implementation is unacceptably slow. And you tried to improve the algorithm, you did your best and it's still slow. And you tried and see that the unmanaged implementation is reasonably faster. Well, so .NET is not a suitable platform for implementing exactly that part of your code. You implement the code in a native DLL or whatever is available on your platform (perhaps in pure C), and use it through P/Invoke. This way your unsafe code is coded in the appropriate language, and you can use it just by calling the method by P/Invoke, or adding a C++/CLI wrapper, or any other way the interoperation is done in C#. You gain (1) clear separation between managed business logic and native very fast processing code, (2) better maintainability, because now your fast number-crunching or data-shuffling code is in the appropriate environment.
Well, you see that even that approach doesn't work by some reason. Well, in this exceptional case you should perhaps consider using unsafe code in C#. But the chances are high that even this will not help.
Upvotes: 2