private boolean doParseMoreData()

in imagepipeline/src/main/java/com/facebook/imagepipeline/decoder/ProgressiveJpegParser.java [140:228]


  private boolean doParseMoreData(final InputStream inputStream) {
    final int oldBestScanNumber = mBestScanNumber;
    try {
      int nextByte;
      while (mParserState != NOT_A_JPEG && (nextByte = inputStream.read()) != -1) {
        mBytesParsed++;
        if (mEndMarkerRead) {
          // There should be no more data after the EOI marker, just in case there is lets
          // bail out instead of trying to parse the unknown data
          mParserState = NOT_A_JPEG;
          mEndMarkerRead = false;
          return false;
        }
        switch (mParserState) {
          case READ_FIRST_JPEG_BYTE:
            if (nextByte == JfifUtil.MARKER_FIRST_BYTE) {
              mParserState = READ_SECOND_JPEG_BYTE;
            } else {
              mParserState = NOT_A_JPEG;
            }
            break;

          case READ_SECOND_JPEG_BYTE:
            if (nextByte == JfifUtil.MARKER_SOI) {
              mParserState = READ_MARKER_FIRST_BYTE_OR_ENTROPY_DATA;
            } else {
              mParserState = NOT_A_JPEG;
            }
            break;

          case READ_MARKER_FIRST_BYTE_OR_ENTROPY_DATA:
            if (nextByte == JfifUtil.MARKER_FIRST_BYTE) {
              mParserState = READ_MARKER_SECOND_BYTE;
            }
            break;

          case READ_MARKER_SECOND_BYTE:
            if (nextByte == JfifUtil.MARKER_FIRST_BYTE) {
              mParserState = READ_MARKER_SECOND_BYTE;
            } else if (nextByte == JfifUtil.MARKER_ESCAPE_BYTE) {
              mParserState = READ_MARKER_FIRST_BYTE_OR_ENTROPY_DATA;
            } else if (nextByte == JfifUtil.MARKER_EOI) {
              mEndMarkerRead = true;
              newScanOrImageEndFound(mBytesParsed - 2);
              // There should be no data after the EOI marker, but in case there is, let's process
              // the next byte as a first marker byte.
              mParserState = READ_MARKER_FIRST_BYTE_OR_ENTROPY_DATA;
            } else {
              if (nextByte == JfifUtil.MARKER_SOS) {
                newScanOrImageEndFound(mBytesParsed - 2);
              }

              if (doesMarkerStartSegment(nextByte)) {
                mParserState = READ_SIZE_FIRST_BYTE;
              } else {
                mParserState = READ_MARKER_FIRST_BYTE_OR_ENTROPY_DATA;
              }
            }
            break;

          case READ_SIZE_FIRST_BYTE:
            mParserState = READ_SIZE_SECOND_BYTE;
            break;

          case READ_SIZE_SECOND_BYTE:
            final int size = (mLastByteRead << 8) + nextByte;
            // We need to jump after the end of the segment - skip size-2 next bytes.
            // We might want to skip more data than is available to read, in which case we will
            // consume entire data in inputStream and exit this function before entering another
            // iteration of the loop.
            final int bytesToSkip = size - 2;
            StreamUtil.skip(inputStream, bytesToSkip);
            mBytesParsed += bytesToSkip;
            mParserState = READ_MARKER_FIRST_BYTE_OR_ENTROPY_DATA;
            break;

          case NOT_A_JPEG:
          default:
            Preconditions.checkState(false);
        }

        mLastByteRead = nextByte;
      }
    } catch (IOException ioe) {
      // does not happen, input stream returned by pooled byte buffer does not throw IOExceptions
      Throwables.propagate(ioe);
    }
    return mParserState != NOT_A_JPEG && mBestScanNumber != oldBestScanNumber;
  }