📄 cjpeg.c
字号:
#endif } else if (keymatch(arg, "quality", 1)) { /* Quality factor (quantization table scaling factor). */ if (++argn >= argc) /* advance to next argument */ usage(); if (sscanf(argv[argn], "%d", &quality) != 1) usage(); /* Change scale factor in case -qtables is present. */ q_scale_factor = jpeg_quality_scaling(quality); } else if (keymatch(arg, "qslots", 2)) { /* Quantization table slot numbers. */ if (++argn >= argc) /* advance to next argument */ usage(); qslotsarg = argv[argn]; /* Must delay setting qslots until after we have processed any * colorspace-determining switches, since jpeg_set_colorspace sets * default quant table numbers. */ } else if (keymatch(arg, "qtables", 2)) { /* Quantization tables fetched from file. */ if (++argn >= argc) /* advance to next argument */ usage(); qtablefile = argv[argn]; /* We postpone actually reading the file in case -quality comes later. */ } else if (keymatch(arg, "restart", 1)) { /* Restart interval in MCU rows (or in MCUs with 'b'). */ long lval; char ch = 'x'; if (++argn >= argc) /* advance to next argument */ usage(); if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) usage(); if (lval < 0 || lval > 65535L) usage(); if (ch == 'b' || ch == 'B') { cinfo->restart_interval = (unsigned int) lval; cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */ } else { cinfo->restart_in_rows = (int) lval; /* restart_interval will be computed during startup */ } } else if (keymatch(arg, "sample", 2)) { /* Set sampling factors. */ if (++argn >= argc) /* advance to next argument */ usage(); samplearg = argv[argn]; /* Must delay setting sample factors until after we have processed any * colorspace-determining switches, since jpeg_set_colorspace sets * default sampling factors. */ } else if (keymatch(arg, "scans", 2)) { /* Set scan script. */#ifdef C_MULTISCAN_FILES_SUPPORTED if (++argn >= argc) /* advance to next argument */ usage(); scansarg = argv[argn]; /* We must postpone reading the file in case -progressive appears. */#else fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n", progname); exit(EXIT_FAILURE);#endif } else if (keymatch(arg, "smooth", 2)) { /* Set input smoothing factor. */ int val; if (++argn >= argc) /* advance to next argument */ usage(); if (sscanf(argv[argn], "%d", &val) != 1) usage(); if (val < 0 || val > 100) usage(); cinfo->smoothing_factor = val; } else if (keymatch(arg, "targa", 1)) { /* Input file is Targa format. */ is_targa = TRUE; } else { usage(); /* bogus switch */ } } /* Post-switch-scanning cleanup */ if (for_real) { /* Set quantization tables for selected quality. */ /* Some or all may be overridden if -qtables is present. */ jpeg_set_quality(cinfo, quality, force_baseline); if (qtablefile != NULL) /* process -qtables if it was present */ if (! read_quant_tables(cinfo, qtablefile, q_scale_factor, force_baseline)) usage(); if (qslotsarg != NULL) /* process -qslots if it was present */ if (! set_quant_slots(cinfo, qslotsarg)) usage(); if (samplearg != NULL) /* process -sample if it was present */ if (! set_sample_factors(cinfo, samplearg)) usage();#ifdef C_PROGRESSIVE_SUPPORTED if (simple_progressive) /* process -progressive; -scans can override */ jpeg_simple_progression(cinfo);#endif#ifdef C_MULTISCAN_FILES_SUPPORTED if (scansarg != NULL) /* process -scans if it was present */ if (! read_scan_script(cinfo, scansarg)) usage();#endif } return argn; /* return index of next arg (file name) */}/* * Check for overwrite of an existing file; clear it with user */#ifndef NO_OVERWRITE_CHECKLOCAL(boolean)is_write_ok (char * outfname){ FILE * ofile; int ch; ofile = fopen(outfname, READ_BINARY); if (ofile == NULL) return TRUE; /* not present */ fclose(ofile); /* oops, it is present */ for (;;) { fprintf(stderr, "%s already exists, overwrite it? [y/n] ", outfname); fflush(stderr); ch = getc(stdin); if (ch != '\n') /* flush rest of line */ while (getc(stdin) != '\n') /* nothing */; switch (ch) { case 'Y': case 'y': return TRUE; case 'N': case 'n': return FALSE; /* otherwise, ask again */ } }}#endif/* * Process a single input file name, and return its index in argv[]. * File names at or to left of old_file_index have been processed already. */LOCAL(int)process_one_file (int argc, char **argv, int old_file_index){ struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; char *infilename; char workfilename[PATH_MAX];#ifdef PROGRESS_REPORT struct cdjpeg_progress_mgr progress;#endif int file_index; cjpeg_source_ptr src_mgr; FILE * input_file = NULL; FILE * output_file = NULL; JDIMENSION num_scanlines; /* Initialize the JPEG compression object with default error handling. */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); /* Add some application-specific error messages (from cderror.h) */ jerr.addon_message_table = cdjpeg_message_table; jerr.first_addon_message = JMSG_FIRSTADDONCODE; jerr.last_addon_message = JMSG_LASTADDONCODE; /* Now safe to enable signal catcher. */#ifdef NEED_SIGNAL_CATCHER enable_signal_catcher((j_common_ptr) &cinfo);#endif /* Initialize JPEG parameters. * Much of this may be overridden later. * In particular, we don't yet know the input file's color space, * but we need to provide some value for jpeg_set_defaults() to work. */ cinfo.in_color_space = JCS_RGB; /* arbitrary guess */ jpeg_set_defaults(&cinfo); /* Scan command line to find next file name. * It is convenient to use just one switch-parsing routine, but the switch * values read here are ignored; we will rescan the switches after opening * the input file. */ file_index = parse_switches(&cinfo, argc, argv, old_file_index, FALSE); if (file_index >= argc) { fprintf(stderr, "%s: missing input file name\n", progname); usage(); } /* Open the input file. */ infilename = argv[file_index]; if ((input_file = fopen(infilename, READ_BINARY)) == NULL) { fprintf(stderr, "%s: can't open %s\n", progname, infilename); goto fail; }#ifdef PROGRESS_REPORT start_progress_monitor((j_common_ptr) &cinfo, &progress);#endif /* Figure out the input file format, and set up to read it. */ src_mgr = select_file_type(&cinfo, input_file); src_mgr->input_file = input_file; /* Read the input file header to obtain file size & colorspace. */ (*src_mgr->start_input) (&cinfo, src_mgr); /* Now that we know input colorspace, fix colorspace-dependent defaults */ jpeg_default_colorspace(&cinfo); /* Adjust default compression parameters by re-parsing the options */ file_index = parse_switches(&cinfo, argc, argv, old_file_index, TRUE); /* If user didn't supply -outfile switch, select output file name. */ if (outfilename == NULL) { int i; outfilename = workfilename; /* Make outfilename be infilename with .jpg substituted for extension */ strcpy(outfilename, infilename); for (i = strlen(outfilename)-1; i >= 0; i--) { switch (outfilename[i]) { case ':': case '/': case '\\': i = 0; /* stop scanning */ break; case '.': outfilename[i] = '\0'; /* lop off existing extension */ i = 0; /* stop scanning */ break; default: break; /* keep scanning */ } } strcat(outfilename, ".jpg"); } fprintf(stderr, "Compressing %s => %s\n", infilename, outfilename);#ifndef NO_OVERWRITE_CHECK if (! is_write_ok(outfilename)) goto fail;#endif /* Open the output file. */ if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { fprintf(stderr, "%s: can't create %s\n", progname, outfilename); goto fail; } /* Specify data destination for compression */ jpeg_stdio_dest(&cinfo, output_file); /* Start compressor */ jpeg_start_compress(&cinfo, TRUE); /* Process data */ while (cinfo.next_scanline < cinfo.image_height) { num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr); (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines); } /* Finish compression and release memory */ (*src_mgr->finish_input) (&cinfo, src_mgr); jpeg_finish_compress(&cinfo); /* Clean up and exit */fail: jpeg_destroy_compress(&cinfo); if (input_file != NULL) fclose(input_file); if (output_file != NULL) fclose(output_file);#ifdef PROGRESS_REPORT end_progress_monitor((j_common_ptr) &cinfo);#endif /* Disable signal catcher. */#ifdef NEED_SIGNAL_CATCHER enable_signal_catcher((j_common_ptr) NULL);#endif return file_index;}/* * The main program. */intmain (int argc, char **argv){ int file_index; /* On Mac, fetch a command line. */#ifdef USE_CCOMMAND argc = ccommand(&argv);#endif#ifdef MSDOS progname = "cjpeg"; /* DOS tends to be too verbose about argv[0] */#else progname = argv[0]; if (progname == NULL || progname[0] == 0) progname = "cjpeg"; /* in case C library doesn't provide it */#endif /* The default maxmem must be computed only once at program startup, * since releasing memory with free() won't give it back to the OS. */#ifdef FREE_MEM_ESTIMATE default_maxmem = FREE_MEM_ESTIMATE;#else default_maxmem = 0;#endif /* Scan command line, parse switches and locate input file names */ if (argc < 2) usage(); /* nothing on the command line?? */ file_index = 0; while (file_index < argc-1) file_index = process_one_file(argc, argv, file_index); /* All done. */ exit(EXIT_SUCCESS); return 0; /* suppress no-return-value warnings */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -