00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 #include "cdjpeg.h"             
00015 #include "transupp.h"           
00016 #include "jversion.h"           
00017 
00018 #ifdef USE_CCOMMAND             
00019 #ifdef __MWERKS__
00020 #include <SIOUX.h>              
00021 #include <console.h>            
00022 #endif
00023 #ifdef THINK_C
00024 #include <console.h>            
00025 #endif
00026 #endif
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 static const char * progname;   
00039 static char * outfilename;      
00040 static JCOPY_OPTION copyoption; 
00041 static jpeg_transform_info transformoption; 
00042 
00043 
00044 LOCAL(void)
00045 usage (void)
00046 
00047 {
00048   fprintf(stderr, "usage: %s [switches] ", progname);
00049 #ifdef TWO_FILE_COMMANDLINE
00050   fprintf(stderr, "inputfile outputfile\n");
00051 #else
00052   fprintf(stderr, "[inputfile]\n");
00053 #endif
00054 
00055   fprintf(stderr, "Switches (names may be abbreviated):\n");
00056   fprintf(stderr, "  -copy none     Copy no extra markers from source file\n");
00057   fprintf(stderr, "  -copy comments Copy only comment markers (default)\n");
00058   fprintf(stderr, "  -copy all      Copy all extra markers\n");
00059 #ifdef ENTROPY_OPT_SUPPORTED
00060   fprintf(stderr, "  -optimize      Optimize Huffman table (smaller file, but slow compression)\n");
00061 #endif
00062 #ifdef C_PROGRESSIVE_SUPPORTED
00063   fprintf(stderr, "  -progressive   Create progressive JPEG file\n");
00064 #endif
00065 #if TRANSFORMS_SUPPORTED
00066   fprintf(stderr, "Switches for modifying the image:\n");
00067   fprintf(stderr, "  -grayscale     Reduce to grayscale (omit color data)\n");
00068   fprintf(stderr, "  -flip [horizontal|vertical]  Mirror image (left-right or top-bottom)\n");
00069   fprintf(stderr, "  -rotate [90|180|270]         Rotate image (degrees clockwise)\n");
00070   fprintf(stderr, "  -transpose     Transpose image\n");
00071   fprintf(stderr, "  -transverse    Transverse transpose image\n");
00072   fprintf(stderr, "  -trim          Drop non-transformable edge blocks\n");
00073 #endif 
00074   fprintf(stderr, "Switches for advanced users:\n");
00075   fprintf(stderr, "  -restart N     Set restart interval in rows, or in blocks with B\n");
00076   fprintf(stderr, "  -maxmemory N   Maximum memory to use (in kbytes)\n");
00077   fprintf(stderr, "  -outfile name  Specify name for output file\n");
00078   fprintf(stderr, "  -verbose  or  -debug   Emit debug output\n");
00079   fprintf(stderr, "Switches for wizards:\n");
00080 #ifdef C_ARITH_CODING_SUPPORTED
00081   fprintf(stderr, "  -arithmetic    Use arithmetic coding\n");
00082 #endif
00083 #ifdef C_MULTISCAN_FILES_SUPPORTED
00084   fprintf(stderr, "  -scans file    Create multi-scan JPEG per script file\n");
00085 #endif
00086   exit(EXIT_FAILURE);
00087 }
00088 
00089 
00090 LOCAL(void)
00091 select_transform (JXFORM_CODE transform)
00092 
00093 
00094 
00095 {
00096 #if TRANSFORMS_SUPPORTED
00097   if (transformoption.transform == JXFORM_NONE ||
00098       transformoption.transform == transform) {
00099     transformoption.transform = transform;
00100   } else {
00101     fprintf(stderr, "%s: can only do one image transformation at a time\n",
00102             progname);
00103     usage();
00104   }
00105 #else
00106   fprintf(stderr, "%s: sorry, image transformation was not compiled\n",
00107           progname);
00108   exit(EXIT_FAILURE);
00109 #endif
00110 }
00111 
00112 
00113 LOCAL(int)
00114 parse_switches (j_compress_ptr cinfo, int argc, char **argv,
00115                 int last_file_arg_seen, boolean for_real)
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 {
00125   int argn;
00126   char * arg;
00127   boolean simple_progressive;
00128   char * scansarg = NULL;       
00129 
00130   
00131   simple_progressive = FALSE;
00132   outfilename = NULL;
00133   copyoption = JCOPYOPT_DEFAULT;
00134   transformoption.transform = JXFORM_NONE;
00135   transformoption.trim = FALSE;
00136   transformoption.force_grayscale = FALSE;
00137   cinfo->err->trace_level = 0;
00138 
00139   
00140 
00141   for (argn = 1; argn < argc; argn++) {
00142     arg = argv[argn];
00143     if (*arg != '-') {
00144       
00145       if (argn <= last_file_arg_seen) {
00146         outfilename = NULL;     
00147         continue;               
00148       }
00149       break;                    
00150     }
00151     arg++;                      
00152 
00153     if (keymatch(arg, "arithmetic", 1)) {
00154       
00155 #ifdef C_ARITH_CODING_SUPPORTED
00156       cinfo->arith_code = TRUE;
00157 #else
00158       fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
00159               progname);
00160       exit(EXIT_FAILURE);
00161 #endif
00162 
00163     } else if (keymatch(arg, "copy", 1)) {
00164       
00165       if (++argn >= argc)       
00166         usage();
00167       if (keymatch(argv[argn], "none", 1)) {
00168         copyoption = JCOPYOPT_NONE;
00169       } else if (keymatch(argv[argn], "comments", 1)) {
00170         copyoption = JCOPYOPT_COMMENTS;
00171       } else if (keymatch(argv[argn], "all", 1)) {
00172         copyoption = JCOPYOPT_ALL;
00173       } else
00174         usage();
00175 
00176     } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
00177       
00178       
00179       static boolean printed_version = FALSE;
00180 
00181       if (! printed_version) {
00182         fprintf(stderr, "Independent JPEG Group's JPEGTRAN, version %s\n%s\n",
00183                 JVERSION, JCOPYRIGHT);
00184         printed_version = TRUE;
00185       }
00186       cinfo->err->trace_level++;
00187 
00188     } else if (keymatch(arg, "flip", 1)) {
00189       
00190       if (++argn >= argc)       
00191         usage();
00192       if (keymatch(argv[argn], "horizontal", 1))
00193         select_transform(JXFORM_FLIP_H);
00194       else if (keymatch(argv[argn], "vertical", 1))
00195         select_transform(JXFORM_FLIP_V);
00196       else
00197         usage();
00198 
00199     } else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) {
00200       
00201 #if TRANSFORMS_SUPPORTED
00202       transformoption.force_grayscale = TRUE;
00203 #else
00204       select_transform(JXFORM_NONE);    
00205 #endif
00206 
00207     } else if (keymatch(arg, "maxmemory", 3)) {
00208       
00209       long lval;
00210       char ch = 'x';
00211 
00212       if (++argn >= argc)       
00213         usage();
00214       if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
00215         usage();
00216       if (ch == 'm' || ch == 'M')
00217         lval *= 1000L;
00218       cinfo->mem->max_memory_to_use = lval * 1000L;
00219 
00220     } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
00221       
00222 #ifdef ENTROPY_OPT_SUPPORTED
00223       cinfo->optimize_coding = TRUE;
00224 #else
00225       fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
00226               progname);
00227       exit(EXIT_FAILURE);
00228 #endif
00229 
00230     } else if (keymatch(arg, "outfile", 4)) {
00231       
00232       if (++argn >= argc)       
00233         usage();
00234       outfilename = argv[argn]; 
00235 
00236     } else if (keymatch(arg, "progressive", 1)) {
00237       
00238 #ifdef C_PROGRESSIVE_SUPPORTED
00239       simple_progressive = TRUE;
00240       
00241 #else
00242       fprintf(stderr, "%s: sorry, progressive output was not compiled\n",
00243               progname);
00244       exit(EXIT_FAILURE);
00245 #endif
00246 
00247     } else if (keymatch(arg, "restart", 1)) {
00248       
00249       long lval;
00250       char ch = 'x';
00251 
00252       if (++argn >= argc)       
00253         usage();
00254       if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
00255         usage();
00256       if (lval < 0 || lval > 65535L)
00257         usage();
00258       if (ch == 'b' || ch == 'B') {
00259         cinfo->restart_interval = (unsigned int) lval;
00260         cinfo->restart_in_rows = 0; 
00261       } else {
00262         cinfo->restart_in_rows = (int) lval;
00263         
00264       }
00265 
00266     } else if (keymatch(arg, "rotate", 2)) {
00267       
00268       if (++argn >= argc)       
00269         usage();
00270       if (keymatch(argv[argn], "90", 2))
00271         select_transform(JXFORM_ROT_90);
00272       else if (keymatch(argv[argn], "180", 3))
00273         select_transform(JXFORM_ROT_180);
00274       else if (keymatch(argv[argn], "270", 3))
00275         select_transform(JXFORM_ROT_270);
00276       else
00277         usage();
00278 
00279     } else if (keymatch(arg, "scans", 1)) {
00280       
00281 #ifdef C_MULTISCAN_FILES_SUPPORTED
00282       if (++argn >= argc)       
00283         usage();
00284       scansarg = argv[argn];
00285       
00286 #else
00287       fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n",
00288               progname);
00289       exit(EXIT_FAILURE);
00290 #endif
00291 
00292     } else if (keymatch(arg, "transpose", 1)) {
00293       
00294       select_transform(JXFORM_TRANSPOSE);
00295 
00296     } else if (keymatch(arg, "transverse", 6)) {
00297       
00298       select_transform(JXFORM_TRANSVERSE);
00299 
00300     } else if (keymatch(arg, "trim", 3)) {
00301       
00302       transformoption.trim = TRUE;
00303 
00304     } else {
00305       usage();                  
00306     }
00307   }
00308 
00309   
00310 
00311   if (for_real) {
00312 
00313 #ifdef C_PROGRESSIVE_SUPPORTED
00314     if (simple_progressive)     
00315       jpeg_simple_progression(cinfo);
00316 #endif
00317 
00318 #ifdef C_MULTISCAN_FILES_SUPPORTED
00319     if (scansarg != NULL)       
00320       if (! read_scan_script(cinfo, scansarg))
00321         usage();
00322 #endif
00323   }
00324 
00325   return argn;                  
00326 }
00327 
00328 
00329 
00330 
00331 
00332 
00333 int
00334 main (int argc, char **argv)
00335 {
00336   struct jpeg_decompress_struct srcinfo;
00337   struct jpeg_compress_struct dstinfo;
00338   struct jpeg_error_mgr jsrcerr, jdsterr;
00339 #ifdef PROGRESS_REPORT
00340   struct cdjpeg_progress_mgr progress;
00341 #endif
00342   jvirt_barray_ptr * src_coef_arrays;
00343   jvirt_barray_ptr * dst_coef_arrays;
00344   int file_index;
00345   FILE * input_file;
00346   FILE * output_file;
00347 
00348   
00349 #ifdef USE_CCOMMAND
00350   argc = ccommand(&argv);
00351 #endif
00352 
00353   progname = argv[0];
00354   if (progname == NULL || progname[0] == 0)
00355     progname = "jpegtran";      
00356 
00357   
00358   srcinfo.err = jpeg_std_error(&jsrcerr);
00359   jpeg_create_decompress(&srcinfo);
00360   
00361   dstinfo.err = jpeg_std_error(&jdsterr);
00362   jpeg_create_compress(&dstinfo);
00363 
00364   
00365 
00366 
00367 #ifdef NEED_SIGNAL_CATCHER
00368   enable_signal_catcher((j_common_ptr) &srcinfo);
00369 #endif
00370 
00371   
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379   file_index = parse_switches(&dstinfo, argc, argv, 0, FALSE);
00380   jsrcerr.trace_level = jdsterr.trace_level;
00381   srcinfo.mem->max_memory_to_use = dstinfo.mem->max_memory_to_use;
00382 
00383 #ifdef TWO_FILE_COMMANDLINE
00384   
00385   if (outfilename == NULL) {
00386     if (file_index != argc-2) {
00387       fprintf(stderr, "%s: must name one input and one output file\n",
00388               progname);
00389       usage();
00390     }
00391     outfilename = argv[file_index+1];
00392   } else {
00393     if (file_index != argc-1) {
00394       fprintf(stderr, "%s: must name one input and one output file\n",
00395               progname);
00396       usage();
00397     }
00398   }
00399 #else
00400   
00401   if (file_index < argc-1) {
00402     fprintf(stderr, "%s: only one input file\n", progname);
00403     usage();
00404   }
00405 #endif 
00406 
00407   
00408   if (file_index < argc) {
00409     if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) {
00410       fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]);
00411       exit(EXIT_FAILURE);
00412     }
00413   } else {
00414     
00415     input_file = read_stdin();
00416   }
00417 
00418   
00419   if (outfilename != NULL) {
00420     if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
00421       fprintf(stderr, "%s: can't open %s\n", progname, outfilename);
00422       exit(EXIT_FAILURE);
00423     }
00424   } else {
00425     
00426     output_file = write_stdout();
00427   }
00428 
00429 #ifdef PROGRESS_REPORT
00430   start_progress_monitor((j_common_ptr) &dstinfo, &progress);
00431 #endif
00432 
00433   
00434   jpeg_stdio_src(&srcinfo, input_file);
00435 
00436   
00437   jcopy_markers_setup(&srcinfo, copyoption);
00438 
00439   
00440   (void) jpeg_read_header(&srcinfo, TRUE);
00441 
00442   
00443 
00444 
00445 #if TRANSFORMS_SUPPORTED
00446   jtransform_request_workspace(&srcinfo, &transformoption);
00447 #endif
00448 
00449   
00450   src_coef_arrays = jpeg_read_coefficients(&srcinfo);
00451 
00452   
00453   jpeg_copy_critical_parameters(&srcinfo, &dstinfo);
00454 
00455   
00456 
00457 
00458 #if TRANSFORMS_SUPPORTED
00459   dst_coef_arrays = jtransform_adjust_parameters(&srcinfo, &dstinfo,
00460                                                  src_coef_arrays,
00461                                                  &transformoption);
00462 #else
00463   dst_coef_arrays = src_coef_arrays;
00464 #endif
00465 
00466   
00467   file_index = parse_switches(&dstinfo, argc, argv, 0, TRUE);
00468 
00469   
00470   jpeg_stdio_dest(&dstinfo, output_file);
00471 
00472   
00473   jpeg_write_coefficients(&dstinfo, dst_coef_arrays);
00474 
00475   
00476   jcopy_markers_execute(&srcinfo, &dstinfo, copyoption);
00477 
00478   
00479 #if TRANSFORMS_SUPPORTED
00480   jtransform_execute_transformation(&srcinfo, &dstinfo,
00481                                     src_coef_arrays,
00482                                     &transformoption);
00483 #endif
00484 
00485   
00486   jpeg_finish_compress(&dstinfo);
00487   jpeg_destroy_compress(&dstinfo);
00488   (void) jpeg_finish_decompress(&srcinfo);
00489   jpeg_destroy_decompress(&srcinfo);
00490 
00491   
00492   if (input_file != stdin)
00493     fclose(input_file);
00494   if (output_file != stdout)
00495     fclose(output_file);
00496 
00497 #ifdef PROGRESS_REPORT
00498   end_progress_monitor((j_common_ptr) &dstinfo);
00499 #endif
00500 
00501   
00502   exit(jsrcerr.num_warnings + jdsterr.num_warnings ?EXIT_WARNING:EXIT_SUCCESS);
00503   return 0;                     
00504 }