Advertisement
Guest User

Untitled

a guest
Jul 28th, 2015
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.49 KB | None | 0 0
  1. /* A small tool for splitting MPO files into their JPG components.
  2. * $Id: mposplit.c,v 1.3 2011/07/07 00:11:38 chris Exp $
  3. * Copyright (C) 2009-2011, Christian Steinruecken. All rights reserved.
  4. *
  5. * This code is released under the Revised BSD Licence.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * - Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * - Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * - The names of the author(s) and contributors may not be used to
  17. * endorse or promote products derived from this software without
  18. * specific prior written permission.
  19. *
  20. * DISCLAIMER:
  21. * This software is provided by the copyright holders and contributors
  22. * "as is" and any express or implied warranties, including, but not
  23. * limited to, the implied warranties of merchantability and fitness for
  24. * a particular purpose are disclaimed. In no event shall the copyright
  25. * holders be liable for any direct, indirect, incidental, special,
  26. * exemplary, or consequential damages (including, but not limited to,
  27. * procurement of substitute goods or services; loss of use, data, or
  28. * profits; or business interruption) however caused and on any theory of
  29. * liability, whether in contract, strict liability, or tort (including
  30. * negligence or otherwise) arising in any way out of the use of this
  31. * software, even if advised of the possibility of such damage. */
  32.  
  33. /*
  34. 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.
  35. All modifications from Christian Steinruecken's original code Copyright (C) 2012, Maurice Ferguson. All rights reserved.
  36. */
  37.  
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41.  
  42. #include <sys/stat.h> //for stat function (distinguishes files from directories)
  43. #include <sys/types.h> //
  44. #include <dirent.h> //for opendir, readdir, closedir functions
  45.  
  46. void parseFileList(int list_size, char **list);
  47. void getDirContents(char *dir);
  48. void extractFile(char **argv, int filenum);
  49. void writeView (char *filename, int views, char *previous, char *view);
  50.  
  51. int main(int argc, char **argv) {
  52. //char c;
  53.  
  54. if (argc<2){
  55. //complain if there's not at least one filename parameter.
  56. fprintf(stdout,"\nUsage:\n\t%s [filename]...\n", argv[0]);
  57. 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");
  58. exit(-1);
  59. }
  60. parseFileList(argc, argv);
  61.  
  62. printf("\n");
  63.  
  64. return 0;
  65. }
  66.  
  67. void parseFileList(int list_size, char **list){
  68. //loop through checking whether each list item is a file or directory.
  69. //for directories, get list of files and recursively call self.
  70. //for files, call extractFile.
  71. int file_num;
  72. for(file_num=1; file_num<list_size; file_num++){
  73. int status;
  74. struct stat st_buf;
  75. //fprintf(stderr,"%s",list[file_num]);
  76. status=stat(list[file_num], &st_buf);
  77. if(status!=0){
  78. fprintf(stderr,"Error checking argument. %s\n\n",list[file_num]);
  79. exit(-1);
  80. }
  81.  
  82. if( S_ISDIR(st_buf.st_mode) ){
  83. fprintf(stdout,"\"%s\": Directory\n",list[file_num]);
  84. getDirContents(list[file_num]);
  85.  
  86. }
  87. else {extractFile(list, file_num);}
  88. }
  89.  
  90. }
  91.  
  92. void getDirContents(char *dir_name){
  93.  
  94. //get listing of directory contents
  95. DIR *dir=opendir(dir_name);
  96. if(dir==NULL){
  97. printf("Error: Couldn't open directory \"%s\".\n", dir_name);
  98. return;//continue;
  99. }
  100. struct dirent *x;
  101.  
  102. //initialize new_list with one empty string
  103. char **new_list=malloc(sizeof(char*)*1);
  104. new_list[0]=malloc(sizeof(char)*1);
  105. strcpy(new_list[0],"");
  106. int new_list_size=1;
  107. char *tmp_list_item=NULL;
  108.  
  109. //populate new_list from readdir output
  110. while( (x=readdir(dir)) !=NULL){
  111. if(strncmp(x[0].d_name,".", 1)==0){
  112. //short-circuit any files starting with "."
  113. continue;
  114. }
  115. new_list_size++;
  116.  
  117. //build path string from dir_name and x
  118. tmp_list_item=realloc(tmp_list_item,strlen(dir_name)+strlen(x[0].d_name)+2);
  119. strcpy(tmp_list_item,dir_name);
  120. strcat(tmp_list_item,"/");
  121. strcat(tmp_list_item,x[0].d_name);
  122.  
  123. new_list=realloc(new_list, sizeof(char*)*new_list_size);
  124. new_list[new_list_size-1]=
  125. realloc(NULL, sizeof(char)*strlen(tmp_list_item)+1);
  126. strncpy(
  127. new_list[new_list_size-1],
  128. tmp_list_item,
  129. strlen(tmp_list_item)
  130. );
  131. free(tmp_list_item);
  132. }
  133.  
  134. closedir(dir);
  135.  
  136. //the recursive call
  137. parseFileList(new_list_size, new_list);
  138.  
  139. //free memory used to store this file list
  140. int i;
  141. for(i=0;i<new_list_size;i++){
  142. free(new_list[i]);
  143. }
  144. free(new_list);
  145. }
  146.  
  147. void extractFile(char **argv, int filenum){
  148. char* filename;
  149. FILE* f;
  150. int views; // number of views (JPG components)
  151. long length; // total length of the file (and consequently, of the buffer)
  152. size_t amount; // amount read
  153. char* buffer=NULL;
  154. char* viewfilename=(char*)malloc(256);
  155.  
  156. views=0;
  157. filename=argv[filenum];
  158. f=fopen(filename,"rb");
  159. if(f==NULL){
  160. fprintf(stderr,"Error opening file \"%s\".\n",filename);
  161. exit(-1);
  162. }
  163.  
  164. //remove extension
  165. char* ext1=strstr(filename,".mpo");
  166. char* ext2=strstr(filename,".MPO");
  167. if(ext1!=NULL)
  168. ext1[0]='\0';
  169. else if(ext2!=NULL)
  170. ext2[0]='\0';
  171. else{
  172. fprintf(stderr,"\t\"%s\": Skipped. (Not an MPO file or missing filename extension.)\n",filename);
  173. return;
  174. }
  175.  
  176. //obtain file size
  177. fseek(f, 0, SEEK_END);
  178. length=ftell(f);
  179. rewind(f);
  180.  
  181. // allocate memory to contain the whole file
  182. buffer=(char*)realloc(buffer, sizeof(char)*length);
  183. if (buffer==NULL){
  184. fprintf(stderr,"Failed to allocate memory.\n");
  185. exit(-1);
  186. }
  187. else {
  188. fprintf(stdout,"\t\"%s\":\n\t\tAllocated %ld chars of memory.\n", filename, length);
  189. }
  190. amount=fread(buffer,1,length,f);
  191. if (amount!=length){
  192. fprintf(stderr,"Error loading file. Stopped at %d.\n",(int)amount);
  193. exit(-1);
  194. }
  195. fclose(f);
  196. printf("\t\tLoaded file.\n");
  197.  
  198. // NOW find the individual JPGs...
  199. char* view=buffer;//view points to beginning of buffer
  200. char* previous=NULL;
  201. while (view < buffer+length-4){//until you reach the end of buffer
  202. if ( ((char) view[0] % 255) == (char) 0xff) {
  203. if ( ((char) view[1] % 255) == (char) 0xd8) {
  204. if ( ((char) view[2] % 255) == (char) 0xff) {
  205. if ( ((char) view[3] % 255) == (char) 0xe1) {
  206. fprintf(stdout, "\t\tView found at offset %ld\n", view-buffer);
  207. views++;
  208. if (previous!=NULL){
  209. // copy out the previous view
  210. writeView(filename, views, previous, view);
  211. }
  212. previous= view;
  213. view+=4;
  214. } else{view+=2;}//if 1st, 2nd, & 3rd match, but 4th doesn't, skip 1st & 2nd
  215. } else{view+=3;}//if 1st & 2nd match, but 3rd doesn't, skip all 3
  216. } else{view+=2;}//if 1st letter matches, but 2nd doesn't, skip both
  217. } else{view+=1;}//if 1st letter isn't right, skip it.
  218. }
  219.  
  220. if (views>1) {
  221. // copy out the last view
  222. views++;
  223. view=buffer+length;
  224. writeView(filename, views, previous, view);
  225. }
  226. else if(views==0){
  227. fprintf(stdout, "\tNo views found.\n");
  228. }
  229. free(viewfilename);
  230. free(buffer);
  231. }
  232.  
  233. void writeView (char *filename, int views, char *previous, char *view){
  234. char *viewfilename=(char*)malloc(256);
  235. sprintf(viewfilename, "%s.view%d.jpg", filename, views-1);
  236. FILE* viewfile = fopen(viewfilename, "wb");
  237. fwrite(previous, 1, view-previous, viewfile);
  238. fclose(viewfile);
  239. fprintf(stdout, "\t\tCreated %s\n",viewfilename);
  240. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement