
org.monte.media.mpo.MPOFiles Maven / Gradle / Ivy
/*
* @(#)MPOFiles.java 1.0 2011-02-27
*
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*/
package org.monte.media.mpo;
import org.monte.media.jpeg.JFIFInputStream;
import org.monte.media.jpeg.JFIFOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
/**
* Utility methods for {@code MPOFiles}.
*
* @author Werner Randelshofer
* @version 1.0 2011-02-27 Created.
*/
public class MPOFiles {
private MPOFiles() {
}
/** Splits a MPO file into two JPEG files.
*
* A MPO file consists of two or more concatenated JPEG files with
* multi-picture file meta-data in APP2 segments which start with the
* character sequence "MPF\0".
*
* This method writes each JPEG file into a separate file and strips
* the multi-picture meta-data.
*/
public static ArrayList splitMPOFile(File f) throws IOException {
int imgCount = 0;
ArrayList splittedFiles=new ArrayList();
JFIFOutputStream out = null;
byte[] buf = new byte[2048];
JFIFInputStream in = new JFIFInputStream(f);
for (JFIFInputStream.Segment seg = in.getNextSegment(); seg != null; seg = in.getNextSegment()) {
if (seg.marker == JFIFInputStream.SOI_MARKER) {
String ext;
switch (imgCount++) {
case 0:
ext = "_l.JPG";
break;
case 1:
ext = "_r.JPG";
break;
default:
ext = "_" + imgCount + ".JPG";
break;
}
String name = f.getName();
int p = name.lastIndexOf('.');
if (p == -1) {
p = name.length();
}
File imgFile = new File(f.getParentFile(), name.substring(0, p) + ext);
splittedFiles.add(imgFile);
out = new JFIFOutputStream(imgFile);
out.pushSegment(seg.marker);
out.popSegment();
} else if (out != null) {
// Skip APP2 segments which start with the string "MPF\0".
if (seg.marker == JFIFInputStream.APP2_MARKER) {
// read fully up to 4 bytes
int len = 4, off = 0, n = 0;
while (n < len) {
int count = in.read(buf, off + n, len - n);
if (count < 0) {
break;
}
n += count;
}
if (n == 4 && (buf[0] & 0xff) == 'M' && (buf[1] & 0xff) == 'P' && (buf[2] & 0xff) == 'F' && buf[3] == 0) {
continue;
} else {
out.pushSegment(seg.marker);
out.write(buf, 0, n);
}
} else {
out.pushSegment(seg.marker);
}
for (int len = in.read(buf, 0, buf.length); len != -1; len = in.read(buf, 0, buf.length)) {
out.write(buf, 0, len);
}
out.popSegment();
}
}
return splittedFiles;
}
}