private unsafe Stream GetBitmapStream(ReadOnlySpan <byte> rawData) { try { short signature = MemoryMarshal.Read <short>(rawData); if (signature != 0x1c15) { return(null); } // The data is in the form of OBJECTHEADER. It's an encoded format that Access uses to push imagesinto the DB. OBJECTHEADER pHeader = MemoryMarshal.Read <OBJECTHEADER>(rawData); // pHeader.signature will always be 0x1c15. // "PBrush" should be the 6 chars after position 12 as well. if (rawData.Length <= pHeader.headersize + 18 || !rawData.Slice(pHeader.headersize + 12, 6).SequenceEqual(PBrush)) { return(null); } // We can safely trust that we've got a bitmap. // The start of our bitmap data in the rawdata is always 78. return(new MemoryStream(rawData.Slice(78).ToArray())); } catch (OutOfMemoryException) // This exception may be caused by creating a new MemoryStream. { } catch (ArgumentOutOfRangeException) // This exception may get thrown by MemoryMarshal when input array size is less than the size of the output type. { } return(null); }
private unsafe Stream GetBitmapStream(byte[] rawData) { Debug.Assert(rawData != null, "rawData is null."); 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 (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, here is a KB: // // http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q175261 // OBJECTHEADER pHeader = (OBJECTHEADER)Marshal.PtrToStructure(addr, typeof(OBJECTHEADER)); // // "PBrush" should be the 6 chars after position 12 as well. // string strPBrush = System.Text.Encoding.ASCII.GetString(rawData, pHeader.headersize + 12, 6); if (strPBrush != "PBrush") { return(null); } // OK, now we can safely trust that we've got a bitmap. byte[] searchArray = System.Text.Encoding.ASCII.GetBytes("BM"); // // Search for "BMP" 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++) { if (searchArray[0] == pByte[i] && searchArray[1] == pByte[i + 1]) { // // found the bitmap data. // return(new MemoryStream(rawData, i, rawData.Length - i)); } } } return(null); }