import java.util.*;
import java.io.*;
import javax.imageio.*;
import javax.imageio.metadata.*;
import javax.imageio.stream.*;
import org.w3c.dom.*;
import javax.xml.xpath.*;
public class Progressive {
public static void main(String[] args) throws Exception {
if (args.length == 1) {
System.out.println(
"progressive(interlace)=" +
new Progressive().isProgressive(new File(args[0])));
}
else if (args.length == 2) {
new Progressive().toNonProgressive(
new File(args[0]), new File(args[1]));
}
else {
String ls = System.getProperty("line.separator");
System.err.println(
"Usage: " + ls +
" java " + Progressive.class.getName() + " file" + ls +
" java " + Progressive.class.getName() + " src-file dst-file");
System.exit(1);
}
}
public boolean isProgressive(File file) throws IOException {
ImageInputStream iis = null;
ImageReader ir = null;
boolean progressive = false;
try {
iis = ImageIO.createImageInputStream(file);
Iterator it = ImageIO.getImageReaders(iis);
ir = it.hasNext()? (ImageReader)it.next() : null;
if (ir == null) {
throw new UnsupportedOperationException("no readers.");
}
ir.setInput(iis);
int n = ir.getNumImages(true);
for (int i=0; i < n; i++) {
if (isProgressive(ir.getImageMetadata(i))) {
progressive = true;
break;
}
}
}
finally {
if (iis != null) {
try { iis.close(); } catch(IOException ie) {}
}
if (ir != null) {
ir.dispose();
}
}
return progressive;
}
public boolean toNonProgressive(File src, File dst) throws IOException {
ImageInputStream iis = null;
ImageOutputStream ios = null;
ImageReader ir = null;
ImageWriter iw = null;
try {
iis = ImageIO.createImageInputStream(src);
Iterator it = ImageIO.getImageReaders(iis);
ir = it.hasNext()? (ImageReader)it.next() : null;
if (ir == null) {
throw new UnsupportedOperationException("no readers.");
}
ir.setInput(iis, false, true);
IIOMetadata streamMeta = ir.getStreamMetadata();
int n = ir.getNumImages(true);
List images = new ArrayList();
boolean progressive = false;
for (int i=0; i < n; i++) {
IIOImage image = ir.readAll(i, null);
if (isProgressive(image.getMetadata())) {
progressive = true;
}
images.add(image);
}
if (! progressive) {
return false;
}
iw = ImageIO.getImageWriter(ir);
if (iw == null) {
throw new UnsupportedOperationException("no writers.");
}
ImageWriteParam iwp = iw.getDefaultWriteParam();
iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
ios = ImageIO.createImageOutputStream(dst);
iw.setOutput(ios);
if (images.size() == 1){
iw.write(streamMeta, (IIOImage)images.get(0), iwp);
}
else{
iw.prepareWriteSequence(streamMeta);
for (int i=0, cnt=images.size(); i < cnt; i++){
iw.writeToSequence((IIOImage)images.get(i), iwp);
}
iw.endWriteSequence();
}
return true;
}
finally{
if (iis != null){
try{ iis.close(); } catch(IOException ie) {}
}
if (ios != null){
try{ ios.close(); } catch(IOException ie) {}
}
if (ir != null) { ir.dispose(); }
if (iw != null) { iw.dispose(); }
}
}
private static final String EXP = "Compression/NumProgressiveScans/@value";
private boolean isProgressive(IIOMetadata root) {
if (! root.isStandardMetadataFormatSupported()) {
throw new UnsupportedOperationException("metadata format");
}
try {
Node node = root.getAsTree(
IIOMetadataFormatImpl.standardMetadataFormatName);
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
String val = xpath.evaluate(EXP, node);
return val != null && !val.equals("1");
}
catch(XPathExpressionException xpee) {
throw new Error(xpee.toString());
}
}
}