/** {@inheritDoc} */
public void outputContents(OutputStream out) throws IOException {
InputStream in = getImage().createInputStream();
in = ImageUtil.decorateMarkSupported(in);
try {
JPEGFile jpeg = new JPEGFile(in);
DataInput din = jpeg.getDataInput();
//Copy the whole JPEG file except:
// - the ICC profile
//TODO Thumbnails could safely be skipped, too.
//TODO Metadata (XMP, IPTC, EXIF) could safely be skipped, too.
while (true) {
int reclen;
int segID = jpeg.readMarkerSegment();
switch (segID) {
case JPEGConstants.SOI:
out.write(0xFF);
out.write(segID);
break;
case JPEGConstants.EOI:
case JPEGConstants.SOS:
out.write(0xFF);
out.write(segID);
IOUtils.copy(in, out); //Just copy the rest!
return;
/*
case JPEGConstants.APP1: //Metadata
case JPEGConstants.APPD:
jpeg.skipCurrentMarkerSegment();
break;*/
case JPEGConstants.APP2: //ICC (see ICC1V42.pdf)
boolean skipICCProfile = false;
in.mark(16);
try {
reclen = jpeg.readSegmentLength();
// Check for ICC profile
byte[] iccString = new byte[11];
din.readFully(iccString);
din.skipBytes(1); //string terminator (null byte)
if ("ICC_PROFILE".equals(new String(iccString, "US-ASCII"))) {
skipICCProfile = (this.image.getICCProfile() != null);
}
} finally {
in.reset();
}
if (skipICCProfile) {
//ICC profile is skipped as it is already embedded as a PDF object
jpeg.skipCurrentMarkerSegment();
break;
}
default:
out.write(0xFF);
out.write(segID);
reclen = jpeg.readSegmentLength();
//write short
out.write((reclen >>> 8) & 0xFF);
out.write((reclen >>> 0) & 0xFF);
int left = reclen - 2;
byte[] buf = new byte[2048];