예제 #1
0
        /// <summary>
        /// This loosely parses JPEG data so And returns a <code>Tuple&lt;long, long&gt;</code> containing the first And last
        /// offsets of the JPEG bytes within the file. It does Not parse data within the markers; it simply determines their
        /// length where possible And skips over them. This means that it Is possible that it may misidentify the bounds of
        /// faulty JPEGs.
        /// </summary>
        /// <param name="startOfJpeg">The offset of the first byte of the JPEG data.</param>
        /// <param name="offset">Current file offset that will be updated.</param>
        /// <returns>
        /// A Tuple&lt;long, long&gt; containing the offsets of the first And last byte of the JPEG, Or null if no complete
        /// JPEG was found.
        /// </returns>
        /// </summary>
        private Tuple <long, long> WalkJpeg(long startOfJpeg, ref long offset)
        {
            var position = startOfJpeg;

            if (_readable.ReadUInt16(position) != 0xD8FF)
            {
                return(null);
            }

            // TODO:  explain += 2
            position += 2;

            // TODO: again... - 4
            while (position < _readable.Capacity - 4)
            {
                var marker = FlipUShort(_readable.ReadUInt16(position));
                var length = FlipUShort(_readable.ReadUInt16(position + 2));

                if (marker == 0xFFFF)
                {
                    // Skip filler byte
                    position += 1;
                }
                else if ((marker & 0xFF) >= 0xD0 && (marker & 0xFF) <= 0xD7)
                {
                    // RST markers with no params
                    position += 2;
                }
                else if (marker == 0xFFDA)
                {
                    // SOS marker; skip and then continue until EOI
                    position += length + 2;
                    marker    = FlipUShort(_readable.ReadUInt16(position));

                    while (marker != 0xFFD9)
                    {
                        position++;
                        marker = _readable.ReadUInt16(position);
                    }

                    offset = position + 2;
                    return(new Tuple <long, long>(startOfJpeg, position + 1));
                }
                else if ((marker & 0xFF00) == 0xFF00)
                {
                    // All other markers have lengths or are reserved. Skip over.
                    position += length + 2;
                }
                else
                {
                    // No marker found. Invalid JPEG.
                    offset += 1;
                    break;
                }
            }

            return(null);
        }