/* * Parse stream headers until a compressed block or end of stream is reached. Possible return codes: OK - a * compressed block was found FINISH - end of stream was reached MORE - more input is need, parsing was suspended * ERR_HEADER - invalid stream header ERR_STRMCRC - stream CRC does not match ERR_EOF - unterminated stream (EOF * reached before end of stream) garbage is set only when returning FINISH. It is number of garbage bits consumed * after end of stream was reached. */ Status parse(Header hd, BitStream bs, int[] garbage) throws StreamFormatException { assert (state != ACCEPT); while (OK == bs.need(16)) { int word = bs.peek(16); bs.dump(16); switch (state) { case STREAM_MAGIC_1: if (0x425A != word) { hd.bs100k = -1; hd.crc = 0; state = ACCEPT; garbage[0] = 16; return FINISH; } state = STREAM_MAGIC_2; continue; case STREAM_MAGIC_2: if (0x6839 < word || 0x6831 > word) { hd.bs100k = -1; hd.crc = 0; state = ACCEPT; garbage[0] = 32; return FINISH; } bs100k = word & 0xF; state = BLOCK_MAGIC_1; continue; case BLOCK_MAGIC_1: if (0x1772 == word) { state = EOS_2; continue; } if (0x3141 != word) throw new StreamFormatException("ERR_HEADER"); state = BLOCK_MAGIC_2; continue; case BLOCK_MAGIC_2: if (0x5926 != word) throw new StreamFormatException("ERR_HEADER"); state = BLOCK_MAGIC_3; continue; case BLOCK_MAGIC_3: if (0x5359 != word) throw new StreamFormatException("ERR_HEADER"); state = BLOCK_CRC_1; continue; case BLOCK_CRC_1: stored_crc = word; state = BLOCK_CRC_2; continue; case BLOCK_CRC_2: hd.crc = (stored_crc << 16) | word; hd.bs100k = bs100k; computed_crc = (computed_crc << 1) ^ (computed_crc >>> 31) ^ hd.crc; state = BLOCK_MAGIC_1; return OK; case EOS_2: if (0x4538 != word) throw new StreamFormatException("ERR_HEADER"); state = EOS_3; continue; case EOS_3: if (0x5090 != word) throw new StreamFormatException("ERR_HEADER"); state = EOS_CRC_1; continue; case EOS_CRC_1: stored_crc = word; state = EOS_CRC_2; continue; case EOS_CRC_2: stored_crc = (stored_crc << 16) | word; if (stored_crc != computed_crc) throw new StreamFormatException("ERR_STRMCRC"); computed_crc = 0; bs.align(); state = STREAM_MAGIC_1; continue; default: break; } throw new IllegalStateException(); } if (FINISH != bs.need(16)) return MORE; if (state == STREAM_MAGIC_1) { state = ACCEPT; garbage[0] = 0; return FINISH; } if (state == STREAM_MAGIC_2) { state = ACCEPT; garbage[0] = 16; return FINISH; } throw new StreamFormatException("ERR_EOF"); }