Skip to main content
GameDev.net gamedev.net
🔒 Locked

Managed access to unmanaged byte array

Started by FeverGames Mar 2, 2009 at 12:22 PM 8 replies 1.6k views
Original Post
FeverGames
FeverGames
Hey guys, i was wondering, i have the following code:

		[StructLayout( LayoutKind.Sequential )]
		private struct GDImage
		{
			public IntPtr 	pixels;
			public int 		sx;
			public int 		sy;
			public int 		colorsTotal;
			[MarshalAs( UnmanagedType.ByValArray, SizeConst=GD_MAX_COLORS )]
			public int[] 	red;
			[MarshalAs( UnmanagedType.ByValArray, SizeConst=GD_MAX_COLORS )]
			public int[] 	green;
			[MarshalAs( UnmanagedType.ByValArray, SizeConst=GD_MAX_COLORS )]
			public int[] 	blue;
			[MarshalAs( UnmanagedType.ByValArray, SizeConst=GD_MAX_COLORS )]
			public int[] 	open;
			public int 		transparent;
			public IntPtr 	polyInts;
			public int 		polyAllocated;
			public IntPtr 	brush;
			public IntPtr 	tile;  
			[MarshalAs( UnmanagedType.ByValArray, SizeConst=GD_MAX_COLORS )]
			public int[] 	brushColorMap;
			[MarshalAs( UnmanagedType.ByValArray, SizeConst=GD_MAX_COLORS )]
			public int[] 	tileColorMap;
			public int 		styleLength;
			public int 		stylePos;
			public IntPtr 	style;
			public int 		interlace;
			public int 		thick;
			[MarshalAs( UnmanagedType.ByValArray, SizeConst=GD_MAX_COLORS )]
			public int[] 	alpha; 
			public int 		trueColor;
			public IntPtr	tpixels;
			public int		alphaBlendingFlag;
			public int		saveAlphaFlag;



			private static Hashtable mFieldOffsets;
			static GDImage()
			{
				// Cache field offsets for faster lookup
				mFieldOffsets = new Hashtable();
				Type t = typeof(GDImage);
				foreach (System.Reflection.FieldInfo field in t.GetFields())
				{
					mFieldOffsets[field.Name] = Marshal.OffsetOf(t, field.Name).ToInt32();
				}
			}

			/// <summary>
			/// Returns the offset in bytes from the start of the GDImage structure
			/// to the given field
			/// </summary>
			/// <param name="field">Field name</param>
			/// <returns>Offset in bytes</returns>
			public static int GetOffset(string field)
			{
				return (int)mFieldOffsets[field];
			}
		}


where public IntPtr pixels; This pointer actually points to a unsigned char array in C. How can i access this array in C#? I do not know how many pixels are avaible up front, so i would somehow have to do something at runtime. Kind regards
FeverGames
FeverGames
frick i forgot to mention,

the array is a multidimensional array of pixels, as following:

pixels[y][x]
Zahlman
Zahlman
Quote:
Original post by FeverGames
frick i forgot to mention,

the array is a multidimensional array of pixels, as following:

pixels[y][x]


If it's sized at compile time in the C code, that doesn't matter; it's stored as a contiguous block of x*y many elements.

If it's sized at runtime... how exactly have you implemented it?
FeverGames
FeverGames
well the thing is it is the libGD i am using, and a modified version of it's csharp wrapper. I am trying to code a buffer system for loading clipmaps
Codeka
Codeka
Quote:
Original post by FeverGames
well the thing is it is the libGD i am using, and a modified version of it's csharp wrapper. I am trying to code a buffer system for loading clipmaps


What does the unmanaged version of the structure look like, and how do you use it?
Promit
Promit
Quote:
Original post by FeverGames
This pointer actually points to a unsigned char array in C. How can i access this array in C#? I do not know how many pixels are avaible up front, so i would somehow have to do something at runtime.
Is it not in those sx and sy members right next to it?

SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
FeverGames
FeverGames
Quote:
Original post by Promit
Quote:
Original post by FeverGames
This pointer actually points to a unsigned char array in C. How can i access this array in C#? I do not know how many pixels are avaible up front, so i would somehow have to do something at runtime.
Is it not in those sx and sy members right next to it?


No the received pixel (by using sx and sy) is an index into the texture pallette

a similar method but then in C:

1141	BGD_DECLARE(int) gdImageGetPixel (gdImagePtr im, int x, int y)1142	{1143	  if (gdImageBoundsSafeMacro (im, x, y))1144	    {1145	      if (im->trueColor)1146		{1147		  return im->tpixels[y][x];1148		}1149	      else1150		{1151		  return im->pixels[y][x];1152		}1153	    }1154	  else1155	    {1156	      return 0;1157	    }1158	}


i wanted to see if it was possible to make the access faster by moving the array to c# and doing this code myself

the unmanged structure:

  typedef struct gdImageStruct150	  {151	    /* Palette-based image pixels */152	    unsigned char **pixels;153	    int sx;154	    int sy;155	    /* These are valid in palette images only. See also156	       'alpha', which appears later in the structure to157	       preserve binary backwards compatibility */158	    int colorsTotal;159	    int red[gdMaxColors];160	    int green[gdMaxColors];161	    int blue[gdMaxColors];162	    int open[gdMaxColors];163	    /* For backwards compatibility, this is set to the164	       first palette entry with 100% transparency,165	       and is also set and reset by the166	       gdImageColorTransparent function. Newer167	       applications can allocate palette entries168	       with any desired level of transparency; however,169	       bear in mind that many viewers, notably170	       many web browsers, fail to implement171	       full alpha channel for PNG and provide172	       support for full opacity or transparency only. */173	    int transparent;174	    int *polyInts;175	    int polyAllocated;176	    struct gdImageStruct *brush;177	    struct gdImageStruct *tile;178	    int brushColorMap[gdMaxColors];179	    int tileColorMap[gdMaxColors];180	    int styleLength;181	    int stylePos;182	    int *style;183	    int interlace;184	    /* New in 2.0: thickness of line. Initialized to 1. */185	    int thick;186	    /* New in 2.0: alpha channel for palettes. Note that only187	       Macintosh Internet Explorer and (possibly) Netscape 6188	       really support multiple levels of transparency in189	       palettes, to my knowledge, as of 2/15/01. Most190	       common browsers will display 100% opaque and191	       100% transparent correctly, and do something192	       unpredictable and/or undesirable for levels193	       in between. TBB */194	    int alpha[gdMaxColors];195	    /* Truecolor flag and pixels. New 2.0 fields appear here at the196	       end to minimize breakage of existing object code. */197	    int trueColor;198	    int **tpixels;199	    /* Should alpha channel be copied, or applied, each time a200	       pixel is drawn? This applies to truecolor images only.201	       No attempt is made to alpha-blend in palette images,202	       even if semitransparent palette entries exist.203	       To do that, build your image as a truecolor image,204	       then quantize down to 8 bits. */205	    int alphaBlendingFlag;206	    /* Should the alpha channel of the image be saved? This affects207	       PNG at the moment; other future formats may also208	       have that capability. JPEG doesn't. */209	    int saveAlphaFlag;210	211	    /* There should NEVER BE ACCESSOR MACROS FOR ITEMS BELOW HERE, so this212	       part of the structure can be safely changed in new releases. */213	214	    /* 2.0.12: anti-aliased globals. 2.0.26: just a few vestiges after215	      switching to the fast, memory-cheap implementation from PHP-gd. */216	    int AA;217	    int AA_color;218	    int AA_dont_blend;219	220	    /* 2.0.12: simple clipping rectangle. These values221	      must be checked for safety when set; please use222	      gdImageSetClip */223	    int cx1;224	    int cy1;225	    int cx2;226	    int cy2;227	  }228	  gdImage;
Codeka
Codeka
Quote:
Original post by FeverGames
unsigned char **pixels;



So if you use Marshal.Copy, the first thing you copy is an array of IntPtr's (i.e. this overload), and then you use Marshal.Copy again to copy each row one at a time.
FeverGames
FeverGames
oh my, i already was trying to use the Marshal.Copy but i figured it would copy the whole array to a one dimensional array!

this really saves my day, it speeded up the progres from using lots of cycles to almost zero!

thanks a lot for your help guys from slimdx, Codeka and Zahlman!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.