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);
        }
Exemplo n.º 2
0
        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);
        }