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 }