Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* A small tool for splitting MPO files into their JPG components.
- * $Id: mposplit.c,v 1.3 2011/07/07 00:11:38 chris Exp $
- * Copyright (C) 2009-2011, Christian Steinruecken. All rights reserved.
- *
- * This code is released under the Revised BSD Licence.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * - The names of the author(s) and contributors may not be used to
- * endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * DISCLAIMER:
- * This software is provided by the copyright holders and contributors
- * "as is" and any express or implied warranties, including, but not
- * limited to, the implied warranties of merchantability and fitness for
- * a particular purpose are disclaimed. In no event shall the copyright
- * holders be liable for any direct, indirect, incidental, special,
- * exemplary, or consequential damages (including, but not limited to,
- * procurement of substitute goods or services; loss of use, data, or
- * profits; or business interruption) however caused and on any theory of
- * liability, whether in contract, strict liability, or tort (including
- * negligence or otherwise) arising in any way out of the use of this
- * software, even if advised of the possibility of such damage. */
- /*
- Enhanced by Maurice Ferguson in February 2012 to accept a mixed list of files and folders, and traverse the folders recursively, splitting all contained MPO files.
- All modifications from Christian Steinruecken's original code Copyright (C) 2012, Maurice Ferguson. All rights reserved.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/stat.h> //for stat function (distinguishes files from directories)
- #include <sys/types.h> //
- #include <dirent.h> //for opendir, readdir, closedir functions
- void parseFileList(int list_size, char **list);
- void getDirContents(char *dir);
- void extractFile(char **argv, int filenum);
- void writeView (char *filename, int views, char *previous, char *view);
- int main(int argc, char **argv) {
- //char c;
- if (argc<2){
- //complain if there's not at least one filename parameter.
- fprintf(stdout,"\nUsage:\n\t%s [filename]...\n", argv[0]);
- fprintf(stdout,"Description:\n\tTakes a space-separated list of MultiPicture Object (MPO) files and/or folders of MPO files, and extracts the views from each file.\n\n");
- exit(-1);
- }
- parseFileList(argc, argv);
- printf("\n");
- return 0;
- }
- void parseFileList(int list_size, char **list){
- //loop through checking whether each list item is a file or directory.
- //for directories, get list of files and recursively call self.
- //for files, call extractFile.
- int file_num;
- for(file_num=1; file_num<list_size; file_num++){
- int status;
- struct stat st_buf;
- //fprintf(stderr,"%s",list[file_num]);
- status=stat(list[file_num], &st_buf);
- if(status!=0){
- fprintf(stderr,"Error checking argument. %s\n\n",list[file_num]);
- exit(-1);
- }
- if( S_ISDIR(st_buf.st_mode) ){
- fprintf(stdout,"\"%s\": Directory\n",list[file_num]);
- getDirContents(list[file_num]);
- }
- else {extractFile(list, file_num);}
- }
- }
- void getDirContents(char *dir_name){
- //get listing of directory contents
- DIR *dir=opendir(dir_name);
- if(dir==NULL){
- printf("Error: Couldn't open directory \"%s\".\n", dir_name);
- return;//continue;
- }
- struct dirent *x;
- //initialize new_list with one empty string
- char **new_list=malloc(sizeof(char*)*1);
- new_list[0]=malloc(sizeof(char)*1);
- strcpy(new_list[0],"");
- int new_list_size=1;
- char *tmp_list_item=NULL;
- //populate new_list from readdir output
- while( (x=readdir(dir)) !=NULL){
- if(strncmp(x[0].d_name,".", 1)==0){
- //short-circuit any files starting with "."
- continue;
- }
- new_list_size++;
- //build path string from dir_name and x
- tmp_list_item=realloc(tmp_list_item,strlen(dir_name)+strlen(x[0].d_name)+2);
- strcpy(tmp_list_item,dir_name);
- strcat(tmp_list_item,"/");
- strcat(tmp_list_item,x[0].d_name);
- new_list=realloc(new_list, sizeof(char*)*new_list_size);
- new_list[new_list_size-1]=
- realloc(NULL, sizeof(char)*strlen(tmp_list_item)+1);
- strncpy(
- new_list[new_list_size-1],
- tmp_list_item,
- strlen(tmp_list_item)
- );
- free(tmp_list_item);
- }
- closedir(dir);
- //the recursive call
- parseFileList(new_list_size, new_list);
- //free memory used to store this file list
- int i;
- for(i=0;i<new_list_size;i++){
- free(new_list[i]);
- }
- free(new_list);
- }
- void extractFile(char **argv, int filenum){
- char* filename;
- FILE* f;
- int views; // number of views (JPG components)
- long length; // total length of the file (and consequently, of the buffer)
- size_t amount; // amount read
- char* buffer=NULL;
- char* viewfilename=(char*)malloc(256);
- views=0;
- filename=argv[filenum];
- f=fopen(filename,"rb");
- if(f==NULL){
- fprintf(stderr,"Error opening file \"%s\".\n",filename);
- exit(-1);
- }
- //remove extension
- char* ext1=strstr(filename,".mpo");
- char* ext2=strstr(filename,".MPO");
- if(ext1!=NULL)
- ext1[0]='\0';
- else if(ext2!=NULL)
- ext2[0]='\0';
- else{
- fprintf(stderr,"\t\"%s\": Skipped. (Not an MPO file or missing filename extension.)\n",filename);
- return;
- }
- //obtain file size
- fseek(f, 0, SEEK_END);
- length=ftell(f);
- rewind(f);
- // allocate memory to contain the whole file
- buffer=(char*)realloc(buffer, sizeof(char)*length);
- if (buffer==NULL){
- fprintf(stderr,"Failed to allocate memory.\n");
- exit(-1);
- }
- else {
- fprintf(stdout,"\t\"%s\":\n\t\tAllocated %ld chars of memory.\n", filename, length);
- }
- amount=fread(buffer,1,length,f);
- if (amount!=length){
- fprintf(stderr,"Error loading file. Stopped at %d.\n",(int)amount);
- exit(-1);
- }
- fclose(f);
- printf("\t\tLoaded file.\n");
- // NOW find the individual JPGs...
- char* view=buffer;//view points to beginning of buffer
- char* previous=NULL;
- while (view < buffer+length-4){//until you reach the end of buffer
- if ( ((char) view[0] % 255) == (char) 0xff) {
- if ( ((char) view[1] % 255) == (char) 0xd8) {
- if ( ((char) view[2] % 255) == (char) 0xff) {
- if ( ((char) view[3] % 255) == (char) 0xe1) {
- fprintf(stdout, "\t\tView found at offset %ld\n", view-buffer);
- views++;
- if (previous!=NULL){
- // copy out the previous view
- writeView(filename, views, previous, view);
- }
- previous= view;
- view+=4;
- } else{view+=2;}//if 1st, 2nd, & 3rd match, but 4th doesn't, skip 1st & 2nd
- } else{view+=3;}//if 1st & 2nd match, but 3rd doesn't, skip all 3
- } else{view+=2;}//if 1st letter matches, but 2nd doesn't, skip both
- } else{view+=1;}//if 1st letter isn't right, skip it.
- }
- if (views>1) {
- // copy out the last view
- views++;
- view=buffer+length;
- writeView(filename, views, previous, view);
- }
- else if(views==0){
- fprintf(stdout, "\tNo views found.\n");
- }
- free(viewfilename);
- free(buffer);
- }
- void writeView (char *filename, int views, char *previous, char *view){
- char *viewfilename=(char*)malloc(256);
- sprintf(viewfilename, "%s.view%d.jpg", filename, views-1);
- FILE* viewfile = fopen(viewfilename, "wb");
- fwrite(previous, 1, view-previous, viewfile);
- fclose(viewfile);
- fprintf(stdout, "\t\tCreated %s\n",viewfilename);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement