public MediaType detect(InputStream input, Metadata metadata) throws IOException {
        if (input == null) {
            return MediaType.OCTET_STREAM;
        }

        input.mark(offsetRangeEnd + length);
        try {
            int offset = 0;

            // Skip bytes at the beginning, using skip() or read()
            while (offset < offsetRangeBegin) {
                long n = input.skip(offsetRangeBegin - offset);
                if (n > 0) {
                    offset += n;
                } else if (input.read() != -1) {
                    offset += 1;
                } else {
                    return MediaType.OCTET_STREAM;
                }
            }

            // Fill in the comparison window
            byte[] buffer = new byte[length + (offsetRangeEnd - offsetRangeBegin)];
            int n = input.read(buffer);
            if (n > 0) {
                offset += n;
            }
            while (n != -1 && offset < offsetRangeEnd + length) {
                int bufferOffset = offset - offsetRangeBegin;
                n = input.read(buffer, bufferOffset, buffer.length - bufferOffset);
                // increment offset - in case not all read (see testDetectStreamReadProblems)
                if (n > 0) {
                    offset += n;
                }
            }

            if (this.isRegex) {
                int flags = 0;
                if (this.isStringIgnoreCase) {
                    flags = Pattern.CASE_INSENSITIVE;
                }

                Pattern p = Pattern.compile(new String(this.pattern, UTF_8), flags);

                ByteBuffer bb = ByteBuffer.wrap(buffer);
                CharBuffer result = ISO_8859_1.decode(bb);
                Matcher m = p.matcher(result);

                boolean match = false;
                // Loop until we've covered the entire offset range
                for (int i = 0; i <= offsetRangeEnd - offsetRangeBegin; i++) {
                    m.region(i, length + i);
                    match = m.lookingAt(); // match regex from start of region
                    if (match) {
                        return type;
                    }
                }
            } else {
                if (offset < offsetRangeBegin + length) {
                    return MediaType.OCTET_STREAM;
                }
                // Loop until we've covered the entire offset range
                for (int i = 0; i <= offsetRangeEnd - offsetRangeBegin; i++) {
                    boolean match = true;
                    int masked;
                    for (int j = 0; match && j < length; j++) {
                        masked = (buffer[i + j] & mask[j]);
                        if (this.isStringIgnoreCase) {
                            masked = Character.toLowerCase(masked);
                        }
                        match = (masked == pattern[j]);
                    }
                    if (match) {
                        return type;
                    }
                }
            }

            return MediaType.OCTET_STREAM;
        } finally {
            input.reset();
        }
    }
@Test
    public void testDetectApplicationEnviHdr() throws Exception {
        InputStream iStream = MagicDetectorTest.class
                .getResourceAsStream("/test-documents/ang20150420t182050_corr_v1e_img.hdr");
        byte[] data = IOUtils.toByteArray(iStream);
        MediaType testMT = new MediaType("application", "envi.hdr");
        Detector detector = new MagicDetector(testMT, data, null, false, 0, 0);
        // Deliberately prevent InputStream.read(...) from reading the entire
        // buffer in one go
        InputStream stream = new RestrictiveInputStream(data);
        assertEquals(testMT, detector.detect(stream, new Metadata()));
    }