Click here to Skip to main content
15,886,038 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
See more:
Hi,
I try to parallelize sequence code in this article
Steganography: Simple Implementation in C#[^]

I know how to use Parallel.For, but in this case, I need return value (Bitmap object) inside the loop. There is 3 nested for and some if.
Below I post both sequence and modified parallel code and 2 errors regarding that return.

Here are the errors:
Error 2 Cannot convert anonymous method to delegate type 'System.Action<long,system.threading.tasks.parallelloopstate>' because some of the return types in the block are not implicitly convertible to the delegate return type.

Error 1 Since 'System.Action<long,system.threading.tasks.parallelloopstate>' returns void, a return keyword must not be followed by an object expression.

Can someone help me with this? I would be very grateful, because I don't know what to do with it :/


Here is the original sequence code:

C#
public static Bitmap embedText(string text, Bitmap bmp)
    {
        State s = State.hiding;

        int charIndex = 0;
        int charValue = 0;
        long colorUnitIndex = 0;

        int zeros = 0;

        int R = 0, G = 0, B = 0;

        for (int i = 0; i < bmp.Height; i++)
        {
            for (int j = 0; j < bmp.Width; j++)
            {
                Color pixel = bmp.GetPixel(j, i);

                pixel = Color.FromArgb(pixel.R - pixel.R % 2,
                    pixel.G - pixel.G % 2, pixel.B - pixel.B % 2);

                R = pixel.R; G = pixel.G; B = pixel.B;

                for (int n = 0; n < 3; n++)
                {
                    if (colorUnitIndex % 8 == 0)
                    {
                        if (zeros == 8)
                        {
                            if ((colorUnitIndex - 1) % 3 < 2)
                            {
                                bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                            }

                            return bmp;
                        }

                        if (charIndex >= text.Length)
                        {
                            s = State.filling_with_zeros;
                        }
                        else
                        {
                            charValue = text[charIndex++];
                        }
                    }

                    switch (colorUnitIndex % 3)
                    {
                        case 0:
                            {
                                if (s == State.hiding)
                                {
                                    R += charValue % 2;

                                    charValue /= 2;
                                }
                            } break;
                        case 1:
                            {
                                if (s == State.hiding)
                                {
                                    G += charValue % 2;

                                    charValue /= 2;
                                }
                            } break;
                        case 2:
                            {
                                if (s == State.hiding)
                                {
                                    B += charValue % 2;

                                    charValue /= 2;
                                }

                                bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                            } break;
                    }

                    colorUnitIndex++;

                    if (s == State.filling_with_zeros)
                    {
                        zeros++;
                    }
                }
            }
        }

        return bmp;
    }

And there is modified code to parallel version:
C#
public static Bitmap embedText(string text, Bitmap bmp)
        {
            State s = State.hiding;

            int charIndex = 0;
            int charValue = 0;
            long colorUnitIndex = 0;

            int zeros = 0;

            int R = 0, G = 0, B = 0;

            Parallel.For (0, bmp.Height, delegate(int i)
            {
                Parallel.For (0, bmp.Width, delegate(int j)
                {
                    Color pixel = bmp.GetPixel(j, i);

                    pixel = Color.FromArgb(pixel.R - pixel.R % 2,
                        pixel.G - pixel.G % 2, pixel.B - pixel.B % 2);

                    R = pixel.R; G = pixel.G; B = pixel.B;

                    for (int n = 0; n < 3; n++)
                    {
                        if (colorUnitIndex % 8 == 0)
                        {
                            if (zeros == 8)
                            {
                                if ((colorUnitIndex - 1) % 3 < 2)
                                {
                                    bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                                }

                                return bmp; return bmp; //In this line is both 2 errors
                            }

                            if (charIndex >= text.Length)
                            {
                                s = State.filling_with_zeros;
                            }
                            else
                            {
                                charValue = text[charIndex++];
                            }
                        }

                        switch (colorUnitIndex % 3)
                        {
                            case 0:
                                {
                                    if (s == State.hiding)
                                    {
                                        R += charValue % 2;

                                        charValue /= 2;
                                    }
                                } break;
                            case 1:
                                {
                                    if (s == State.hiding)
                                    {
                                        G += charValue % 2;

                                        charValue /= 2;
                                    }
                                } break;
                            case 2:
                                {
                                    if (s == State.hiding)
                                    {
                                        B += charValue % 2;

                                        charValue /= 2;
                                    }

                                    bmp.SetPixel(j, i, Color.FromArgb(R, G, B));
                                } break;
                        }

                        colorUnitIndex++;

                        if (s == State.filling_with_zeros)
                        {
                            zeros++;
                        }
                    }
                }
            });

            return bmp;
        }
Posted
Updated 2-Jan-14 2:12am
v3
Comments
Karthik_Mahalingam 2-Jan-14 8:04am    
please add it in code block..

1 solution

Instead of "parallelizing" the way you do, don't use GetPixel/SetPixel; these methods are prohibitively slow and can only be used to get or set very few pixels. Instead, lock bit and process them in memory:
http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.lockbits%28v=vs.110%29.aspx[^].

See the documentation page for the first of these two methods for code sample.

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900