0

We had recently few threads (below) on SO where one of the common suggestion was do not use pointer.

fixed block in .net

In .NET is there any difference between using pointers as function parameters or using the "ref" keyword?

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???

2
  • 2
    Naming variables numPtr, numPtr2 and numPtr3 while writing unsafe code should be a punishable offense. Commented Apr 20, 2012 at 14:32
  • @nikie I agree bad habit of not following coding convention rarely go :( Commented Apr 20, 2012 at 14:33

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

simply superb!! I also believe .Net (CLI) was design such that developer can decide when he/she needs stability (managed code) and when he/she needs performance(unsafe)
2

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.

  1. 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.

  2. 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.

  3. 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.

2 Comments

is it better to do interop write c/c++ code and cross boundary of .net framewrok then going in unsafe territory??? I was wondering if we do interop then we losse any hope of portability(to run on Mono)
@Pritesh: not really. C code is portable as well, so the only different part is the P/Invoke declaration (which can be safely switched with preprocessor).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.