Bitmap LockBits access violation (C#)

Started by
5 comments, last by CProgrammer 16 years, 1 month ago
Hi Everyone, I've got a class thtat grabs a frame from an avi file to Bitmap class. Then I pass the Bitmap to another class which should convert it to OpenGL texture. The problem is that when I try to use LockBits function, I get access violation exception. It's like this:
b = video.GetFrame();
gpu.CreateTexture(b);
where GetFrame() returns:
Bitmap b = new Bitmap(width, height, linesize, PixelFormat.Format24bppRgb, bufferPtr);
return b;
and
public void CreateTexture(Bitmap bitmap)
{
  int[] texture = new int[1];

  Gl.glEnable(Gl.GL_TEXTURE_2D);
  Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);
            
  Gl.glGenTextures(1, texture);
  Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture[0]);

  int w = bitmap.Width;
  int h = bitmap.Height;
  BitmapData data = bitmap.LockBits(new Rectangle(0, 0, w, h),
  ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); //Here I get the error
  (...)
}
What am I doing wrong? Ahh, I'm using Tao Framework to access OpenGL functions. -- Best regards, Mateusz
Advertisement
see if any of this works

class GlImage{                public GlImage(Image image) {            Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);            System.Drawing.Imaging.BitmapData bitmapdata;            Bitmap bitmap = new Bitmap(image);            bitmapdata = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,            System.Drawing.Imaging.PixelFormat.Format32bppPArgb);                     int[] ids = new int[1];            Gl.glGenTextures(1, ids);            imageid = ids[0];            width = bitmap.Width;            height = bitmap.Height;                        Gl.glBindTexture(Gl.GL_TEXTURE_2D, imageid);                  //Gl.GL_RGBA            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, image.Width, image.Height,            0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);		// Linear Filtering            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);		// Linear Filtering            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP);            Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP);            bitmap.UnlockBits(bitmapdata);        }        private int imageid;        private float height, width;        public float Height        {            get { return height; }        }        public float Width        {            get { return width; }        }        public void Bind() {            Gl.glBindTexture(Gl.GL_TEXTURE_2D, imageid);        }        public static void UnBind()        {            Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);        }         public void Free(){            int[] ids = new int[1];            ids[0] = imageid;            Gl.glDeleteTextures(1, ids);        }            }
Thanks for the anwser!
I've tried to modyfi my function to:
public void CreateTexture(Image image){   Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);   System.Drawing.Imaging.BitmapData bitmapdata;   Bitmap bitmap = new Bitmap(image);   bitmapdata = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly,   System.Drawing.Imaging.PixelFormat.Format32bppPArgb);   int[] ids = new int[1];   Gl.glGenTextures(1, ids);   imageid = ids[0];   width = bitmap.Width;   height = bitmap.Height;   Gl.glBindTexture(Gl.GL_TEXTURE_2D, imageid);      Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, image.Width, image.Height,            0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, bitmapdata.Scan0);   Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);		// Linear Filtering   Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);		// Linear Filtering   Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP);   Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP);   bitmap.UnlockBits(bitmapdata);}

Now I've got the same error in line
Bitmap bitmap = new Bitmap(image);


--
Best regards,
Mateusz
The only thing that I can think of is that unlike other exception system access violation exceptions don't always get throws from exactly where the root problem occurred,

are you using any unsafe code or wrappers to native librarys other than tao.opengl?
Yes, I use Tao.ffmpeg and this function:
unsafe Bitmap SaveFrame(IntPtr pFrame, int width, int height){   try   {      int x, y;      int linesize = width * 3;      byte* scan0 = (byte*)Marshal.ReadIntPtr(pFrame);      IntPtr bufferPtr = Marshal.AllocHGlobal(linesize * height);      byte* buffer = (byte*)bufferPtr;      for (y = 0; y < height; y++)      {         for (x = 0; x < linesize; x = x + 3)         {            *buffer++ = (byte)*(scan0 + y * linesize + x + 2);            *buffer++ = (byte)*(scan0 + y * linesize + x + 1);            *buffer++ = (byte)*(scan0 + y * linesize + x);         }      }            Bitmap b = new Bitmap(width, height, linesize, PixelFormat.Format24bppRgb, bufferPtr);      Marshal.FreeHGlobal(bufferPtr);      return b;   }   catch (Exception ex) { throw new Exception(ex.Message); }}

This code is put togeter from various examples and customized... maybe there is a better way to do it.

--
Best regards,
Mateusz
I finally managed to make it work, as Kaze sad the error was in SaveFrame() function. I've commented out the line:
Marshal.FreeHGlobal(bufferPtr);

And the Access Violation dissapeard!
Thanks for help!

--
Best regards,
Mateusz
You probably shouldnt stop looking yet. If you allocated something and freeing it crashes the app then you likely have a memory problem somewhere else in your code. I may be wrong and I'm not to familiar with Marshal... but that's the first thing that comes to mind.

This topic is closed to new replies.

Advertisement