private unsafe Stream GetBitmapStream(byte[] rawData) { try { try { fixed(byte *numRef = rawData) { IntPtr ptr = (IntPtr)numRef; if (ptr == IntPtr.Zero) { return(null); } if ((rawData.Length <= sizeof(SafeNativeMethods.OBJECTHEADER)) || (Marshal.ReadInt16(ptr) != 0x1c15)) { return(null); } SafeNativeMethods.OBJECTHEADER objectheader = (SafeNativeMethods.OBJECTHEADER)Marshal.PtrToStructure(ptr, typeof(SafeNativeMethods.OBJECTHEADER)); if (rawData.Length <= (objectheader.headersize + 0x12)) { return(null); } if (Encoding.ASCII.GetString(rawData, objectheader.headersize + 12, 6) != "PBrush") { return(null); } byte[] bytes = Encoding.ASCII.GetBytes("BM"); for (int i = objectheader.headersize + 0x12; (i < (objectheader.headersize + 510)) && ((i + 1) < rawData.Length); i++) { if ((bytes[0] == numRef[i]) && (bytes[1] == numRef[i + 1])) { return(new MemoryStream(rawData, i, rawData.Length - i)); } } } } finally { numRef = null; } } catch (OutOfMemoryException) { } catch (ArgumentException) { } return(null); }
private unsafe Stream GetBitmapStream(byte[] rawData) { Debug.Assert(rawData != null, "rawData is null."); try { fixed(byte *pByte = rawData) { IntPtr addr = (IntPtr)pByte; if (addr == IntPtr.Zero) { return(null); } // this will be pHeader.signature, but we try to // do this first so we avoid building the structure when we shouldn't // if (rawData.Length <= sizeof(SafeNativeMethods.OBJECTHEADER) || Marshal.ReadInt16(addr) != 0x1c15) { return(null); } // the data is one of these OBJECTHEADER dudes. It's an encoded format that Access uses to push images // into the DB. It's not particularly documented, but I found a KB: // // http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q175261 // SafeNativeMethods.OBJECTHEADER pHeader = (SafeNativeMethods.OBJECTHEADER)Marshal.PtrToStructure(addr, typeof(SafeNativeMethods.OBJECTHEADER)); // "PBrush" should be the 6 chars after position 12 as well. // if (rawData.Length <= pHeader.headersize + 18) { return(null); } string strPBrush = System.Text.Encoding.ASCII.GetString(rawData, pHeader.headersize + 12, 6); if (strPBrush != "PBrush") { return(null); } // okay, now we can safely trust that we've got a bitmap. byte[] searchArray = System.Text.Encoding.ASCII.GetBytes("BM"); // search for "BM" in the data which is the start of our bitmap data... // // 18 is from (12+6) above. // for (int i = pHeader.headersize + 18; i < pHeader.headersize + 510 && i + 1 < rawData.Length; i++) { if (searchArray[0] == pByte[i] && searchArray[1] == pByte[i + 1]) { // found the bitmap data. // return(new MemoryStream(rawData, i, rawData.Length - i)); } } } } catch (OutOfMemoryException) // this exception may be caused by creating a new MemoryStream { } catch (ArgumentException) // may be caused by Marshal.PtrToStructure { } // nevermind... return(null); }