Drake's Weblog

3 minute read

The following is the code I got from Andres Hernandez [cybereality] for separating a .mpo file into 2 relative .jpeg files (left and right). The key point is to find the second jpeg’s header “FFD8FFE1” and this is my first time to touch jpeg’s header format. Kinda interesting.

According to Andres’s idea, we all hope everyone could keep sharing any informative stuff to help others’ work or research. And eventually, we could benefit from others’ great achievement :)

Cool, no problem man. It would be cool if you could upload the mac version on that same MTBS thread so it can help others. MTBS can host files, there is a small “browse for file” button under the post box, then click “add file”, so it is very easy to include files in a thread. I am sure there are other mac users that would appreciate it.

Source: Meant to be Seen.

// MPO2Stereo:
// Converts Fujifilm MPO format 3D
// images into JPEG stereo pairs
// code by: 
// Andres Hernandez [cybereality]

#include <iostream>
#include <fstream>

using namespace std;

int fileSize;
char * stereoData;
char * rightData;

int main( int argc, char* argv[] ){
	// title
	printf("\n*********** MPO2Stereo [cybereality] ***********\n");

	// print usage if no arguments
	if(argc == 1){
        printf("Converts MPO files to JPEG stereo pairs.\n");
        printf("Usage: MPO2Stereo.exe File_1.MPO [.. File_N.MPO]\n");
	// loop through each argument
	for( int i = 1; i < argc; i++ ){
        // get the file name
        char fileName[255];
        char fullName[255];
        // locate end of path, which is the last slash in the string
        char *ptr = strrchr(argv[i],'/');
        // make sure its a directory
        if(ptr != NULL){
            // copy remainder of string
            // remember full name
            strcpy(fullName, fileName);
            // check if its an MPO file
            char *MPO = strstr(fileName, ".MPO");
            char *mpo = strstr(fileName, ".mpo");
            // strip file extension
            ptr = strchr(fileName,'.');
            // if the extension exists, truncate it
            if(ptr != 0) *ptr = 0;
            // make sure its an MPO file
            if(MPO == NULL && mpo == NULL){
                printf("Cannot Process: \"%s\". Not An MPO File.\n", fullName);
                // go to next file if any
            } else {
                // print file name
                printf("Processing MPO File: \"%s\"...\n", fullName);
        } else {
            // malformed directory
            printf("Invalid Directory For File: %s\n", argv[i]);
            printf("Must Include Full Directory Path To MPO File.\n");
            // skip

        // load up the MPO file
        ifstream mpoFile (argv[i], ios::in|ios::binary|ios::ate);
        // make sure we can open file
        if (mpoFile.is_open()) {
            // read the image data into a buffer
            fileSize = (int)mpoFile.tellg();
            stereoData = new char [fileSize];
            mpoFile.seekg (0, ios::beg);
            mpoFile.read (stereoData, fileSize);

            // start of the next image
            char startOfImage [8]= { 'F', 'F', 'D', '8', 'F', 'F', 'E', '1' };
            int imageBreak;

            // find the break point between the image pairs
            for(int i=0; i < fileSize; i+=4){
                // get block into a c string
                char block[255];
                // extract the characters
                sprintf(block, "%.2X%.2X%.2X%.2X", 
                (unsigned int)(unsigned char)stereoData[i], 
                (unsigned int)(unsigned char)stereoData[i+1], 
                (unsigned int)(unsigned char)stereoData[i+2], 
                (unsigned int)(unsigned char)stereoData[i+3]);
                // check for start of image
                if(strncmp(block, startOfImage, 8) == 0){
                    // remember where the image starts
                    imageBreak = i;
                    cout << imageBreak << endl;

            // write left image to new file
            char leftName[255];
            sprintf(leftName, "%s_L.JPG", fileName);
            ofstream leftFile;
            leftFile.open (leftName, ios::out | ios::binary);
            if (leftFile.is_open()) {
                leftFile.write (stereoData, imageBreak);
                printf("Created JPEG File: \"%s\".\n", leftName);
            } else {
                printf("Unable To Create JPEG File: \"%s\".\n", leftName);
            // write right image to new file
            char rightName[255];
            sprintf(rightName, "%s_R.JPG", fileName);
            ofstream rightFile;
            rightFile.open (rightName, ios::out | ios::binary);
            if (rightFile.is_open()) {
                rightFile.write (stereoData + imageBreak, fileSize-imageBreak);
                printf("Created JPEG File: \"%s\".\n", rightName);
            } else {
                printf("Unable To Create JPEG File: \"%s\".\n", rightName);
            // delete resources
            delete[] stereoData;
        } else {
            printf("Unable To Open MPO File.\n");
	// all done

	// return
	return 0;
comments powered by Disqus

Recent posts



You're looking at Drake's words or statements. All opinions are my own.