try {
buf.position( 2 ); // skip JPEG magic number
while ( true ) {
final byte b = buf.get();
if ( b != JPEG_MARKER_BYTE )
throw new BadImageFileException(
jpegFile,
"JPEG marker byte (0xFF) expected; got: 0x"
+ Integer.toHexString( b & 0x00FF )
);
byte segID;
do { // skip padding, if any
segID = buf.get();
} while ( segID == JPEG_MARKER_BYTE );
final int segLength;
switch ( segID ) {
case JPEG_EOI_MARKER:
//
// We should never get here... but just in case.
//
return;
case JPEG_SOS_MARKER:
//
// The Start-of-Scan segment doesn't have a length.
//
segLength = 0;
break;
default:
//
// The segment length includes itself, so subtract 2 to
// get the actual length of the segment data.
//
segLength = buf.getUnsignedShort() - 2;
final int segRemaining = buf.remaining();
if ( segLength > segRemaining )
throw new BadImageFileException(
jpegFile,
"JPEG segment length (" + segLength
+ ") > actual length (" + segRemaining + ')'
);
break;
}
final int savedPos = buf.position();
final boolean continueParsing =
handler.gotSegment( segID, segLength, jpegFile, buf );
if ( segID == JPEG_SOS_MARKER || !continueParsing )
break;
buf.position( savedPos + segLength );
}
}
catch ( BufferUnderflowException e ) {
throw new BadImageFileException( jpegFile, e );
}
catch ( IllegalArgumentException e ) {
throw new BadImageFileException( jpegFile, e );
}
}