This morning, I got csharp code working that splits an MPO file from a Fujifilm FinePix Real3D camera into left and right components. Here is the code that does it.
using System;
using System.IO;
using System.Collections;
/// <summary>
/// Breaks an MPO file into two JPG files having names _L.jpg and _R.jpg.
/// Throws error if source file does not have .mpo extension.
/// Works by searching for 4 bytes: ff d8 ff e1 which is the start of both files.
/// Throws error if file does not start with ff d8 ff e1.
/// Throws error if other than one additional ff d8 ff e1 is found.
/// </summary>
/// <param name="sFullFileName">Full path to the .MPO file being split</param>
/// <param name="bOverwrite">If true, it will overwrite any existing left or right files. If false, it throws and error of the target files already exist</param>
public static void SplitMpoFile(string sFullPath, bool bOverwrite) {
string sExt = sFullPath.Substring(sFullPath.Length - 4);
if (sExt.ToUpper() != ".MPO") {
throw new Exception(sFullPath + " does not have .MPO extension.");
}
string sFileNameBase = sFullPath.Substring(0, sFullPath.Length - 4);
string sFileNameLeft = sFileNameBase + "_L.jpg";
string sFileNameRght = sFileNameBase + "_R.jpg";
if (File.Exists(sFileNameLeft)) {
if (bOverwrite) {
File.Delete(sFileNameLeft);
}else{
throw new Exception(sFileNameLeft + " already exists.");
}
}
if (File.Exists(sFileNameRght)) {
if (bOverwrite) {
File.Delete(sFileNameRght);
}else{
throw new Exception(sFileNameRght + " already exists.");
}
}
FileStream fs = new FileStream(sFullPath, FileMode.Open);
long lFileLength = fs.Length;
byte[] bytes = new byte[lFileLength];
BinaryReader br = new BinaryReader(fs);
br.Read(bytes, 0, (int)lFileLength);
br.Close();
fs.Close();
// Verify that file starts with ff d8 ff e1
if (bytes[0] != 255 || bytes[1] != 216 || bytes [2] != 255 || bytes[3] != 225) {
throw new Exception(sFullPath + " does not start with correct code.");
}
// Make an array list of all the places in the file that start with ff d8 ff e1
ArrayList alBreakPoints = new ArrayList(8);
for (int i = 1; i < lFileLength - 4; i++) {
if (bytes[i] == 255 && bytes[i + 1] == 216 && bytes[i + 2] == 255 && bytes[i + 3] == 225) {
alBreakPoints.Add(i);
}
}
// At this point, there should be exactly 1 element in the array list.
if (alBreakPoints.Count != 1) {
throw new Exception(alBreakPoints.Count + " breakpoints found in " + sFullPath);
}
int iBreakPoint = (int)alBreakPoints[0];
// OK - everything looks good here. Output the two parts of the file.
fs = new FileStream(sFileNameLeft, FileMode.CreateNew);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(bytes, 0, iBreakPoint);
bw.Close();
fs.Close();
fs = new FileStream(sFileNameRght, FileMode.CreateNew);
bw = new BinaryWriter(fs);
bw.Write(bytes, iBreakPoint, (int)lFileLength - iBreakPoint);
bw.Close();
fs.Close();
}
No comments:
Post a Comment