views:

100

answers:

3

I have no experience with low level programing and I need this piece of code to not use [StructLayout(LayoutKind.Explicit)]. My site runs on a shared host and in medium trust. So it won't run if this code is in there.

Update: I'm using this inside a Octree to Quantize a png file.

Does anyone know a work around?

Update New question here => http://stackoverflow.com/questions/1099655/is-there-any-way-to-do-image-quantization-safely-and-with-no-marshalling

/// <summary>
        /// Struct that defines a 32 bpp colour
        /// </summary>
        /// <remarks>
        /// This struct is used to read data from a 32 bits per pixel image
        /// in memory, and is ordered in this manner as this is the way that
        /// the data is layed out in memory
        /// </remarks>
        [StructLayout(LayoutKind.Explicit)]
        public struct Color32
        {

            public Color32(IntPtr pSourcePixel)
            {
                this = (Color32)Marshal.PtrToStructure(pSourcePixel, typeof(Color32));

            }

            /// <summary>
            /// Holds the blue component of the colour
            /// </summary>
            [FieldOffset(0)]
            public byte Blue;
            /// <summary>
            /// Holds the green component of the colour
            /// </summary>
            [FieldOffset(1)]
            public byte Green;
            /// <summary>
            /// Holds the red component of the colour
            /// </summary>
            [FieldOffset(2)]
            public byte Red;
            /// <summary>
            /// Holds the alpha component of the colour
            /// </summary>
            [FieldOffset(3)]
            public byte Alpha;

            /// <summary>
            /// Permits the color32 to be treated as an int32
            /// </summary>
            [FieldOffset(0)]
            public int ARGB;

            /// <summary>
            /// Return the color for this Color32 object
            /// </summary>
            public Color Color
            {
                get { return Color.FromArgb(Alpha, Red, Green, Blue); }
            }
        }
A: 

You could just store the int ARGB, and use a BitConverter to convert it to the 4 bytes for your color return.

Even better, just store the int, and use Color.FromArgb(Int32).

Both of these approaches eliminate the need to store the individual bytes, so you can completely eliminate the StructLayout attribute.

Reed Copsey
+1  A: 

Interoperating with native code and memory is an inherently unsafe operation. Any calls to the Marshal class will fail as well. You can't access the memory, or do any Interop unless you have full trust level.

Christopher Karper
I just realized that. :-(
Donny V.
+1  A: 

Marshal.PtrToStructure Method (IntPtr, Type) won't work anyway since it requires

[SecurityPermissionAttribute(
    SecurityAction.LinkDemand, 
    Flags = SecurityPermissionFlag.UnmanagedCode)]

You could deal with the offsets yourself safely, but you would have to do it without using Marshal.
I suggest also moving to using uints for simplicity.

public struct Color32
{
    const uint BlueMask  = 0xFF000000;       
    const uint GreenMask = 0x00FF0000;
    const uint RedMask   = 0x0000FF00;
    const uint AlphaMask = 0x000000FF;
    const int BlueShift  = 24;       
    const int GreenShift = 16;
    const int RedShift   = 8;
    const int AlphaShift = 0;

    private byte GetComponent(uint mask, int shift)
    {
        var b = (this.ARGB & mask);
        return (byte) (b >> shift);            
    } 

    private void SetComponent(int shift, byte value)
    {
        var b = ((uint)value) << shift
        this.ARGB |= b;
    } 

    public byte Blue 
    {
        get { return GetComponent(BlueMask, BlueShift); }
        set { SetComponent(BlueShift, value); }
    }

    public byte Green
    {
        get { return GetComponent(GreenMask, GreenShift); }
        set { SetComponent(GreenShift, value); }
    }

    public byte Red
    {
        get { return GetComponent(RedMask, RedShift); }
        set { SetComponent(RedShift, value); }
    }

    public byte Alpha
    {
        get { return GetComponent(AlphaMask, AlphaShift); }
        set { SetComponent(AlphaShift, value); }
    }

    /// <summary>
    /// Permits the color32 to be treated as an UInt32
    /// </summary>
    public uint ARGB;

    /// <summary>
    /// Return the color for this Color32 object
    /// </summary>
    public Color Color
    {
        get { return Color.FromArgb(Alpha, Red, Green, Blue); }
    }
}

however it would appear that what you want to do is convert an int32 in one byte order to the reverse.
For this you have System.Net.IPAddress.HostToNetworkOrder (nasty usage in this regard, you are simply using it to reverse the endianess rather than being specific about which ordering you intend)

so if you could read your input data as simple int32 values then do:

static Color FromBgra(int bgra)
{
    return Color.FromArgb(System.Net.IPAddress.HostToNetworkOrder(bgra));
}

This would likely be much simpler.

ShuggyCoUk
obviously you can manually inline the get and set of the component if you really want bleeding edge speed, though it strikes me that simply generating the Color struct on the fly directly given your actual usage in the linked question will be better for you
ShuggyCoUk
THank you..this got rid of the struct but I realized my real problem is the Marshal. It won't run under medium trust.
Donny V.
+1 You answered the struct question, so you deserve it.
Donny V.