#include "jversion.h" /* for version message */
#include "jconfigint.h"
+#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
+extern void *malloc(size_t size);
+extern void free(void *ptr);
+#endif
+
#ifdef USE_CCOMMAND /* command-line reader for Macintosh */
#ifdef __MWERKS__
#include <SIOUX.h> /* Metrowerks needs this */
/* Create the add-on message string table. */
-#define JMESSAGE(code,string) string ,
+#define JMESSAGE(code, string) string,
static const char * const cdjpeg_message_table[] = {
#include "cderror.h"
LOCAL(cjpeg_source_ptr)
-select_file_type (j_compress_ptr cinfo, FILE *infile)
+select_file_type(j_compress_ptr cinfo, FILE *infile)
{
int c;
switch (c) {
#ifdef BMP_SUPPORTED
case 'B':
- return jinit_read_bmp(cinfo);
+ return jinit_read_bmp(cinfo, TRUE);
#endif
#ifdef GIF_SUPPORTED
case 'G':
static const char *progname; /* program name for error messages */
+static char *icc_filename; /* for -icc switch */
static char *outfilename; /* for -outfile switch */
boolean memdst; /* for -memdst switch */
LOCAL(void)
-usage (void)
+usage(void)
/* complain about bad command line */
{
fprintf(stderr, "usage: %s [switches] ", progname);
fprintf(stderr, " -dct float Use floating-point DCT method%s\n",
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
#endif
+ fprintf(stderr, " -icc FILE Embed ICC profile contained in FILE\n");
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
#ifdef INPUT_SMOOTHING_SUPPORTED
fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n");
LOCAL(int)
-parse_switches (j_compress_ptr cinfo, int argc, char **argv,
- int last_file_arg_seen, boolean for_real)
+parse_switches(j_compress_ptr cinfo, int argc, char **argv,
+ int last_file_arg_seen, boolean for_real)
/* Parse optional switches.
* Returns argv[] index of first file-name argument (== argc if none).
* Any file names with indexes <= last_file_arg_seen are ignored;
force_baseline = FALSE; /* by default, allow 16-bit quantizers */
simple_progressive = FALSE;
is_targa = FALSE;
+ icc_filename = NULL;
outfilename = NULL;
memdst = FALSE;
cinfo->err->trace_level = 0;
/* On first -d, print version identification */
static boolean printed_version = FALSE;
- if (! printed_version) {
+ if (!printed_version) {
fprintf(stderr, "%s version %s (build %s)\n",
PACKAGE_NAME, VERSION, BUILD);
fprintf(stderr, "%s\n\n", JCOPYRIGHT);
PACKAGE_NAME, VERSION, BUILD);
exit(EXIT_SUCCESS);
- } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) {
+ } else if (keymatch(arg, "grayscale", 2) ||
+ keymatch(arg, "greyscale", 2)) {
/* Force a monochrome JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
/* Force an RGB JPEG file to be generated. */
jpeg_set_colorspace(cinfo, JCS_RGB);
+ } else if (keymatch(arg, "icc", 1)) {
+ /* Set ICC filename. */
+ if (++argn >= argc) /* advance to next argument */
+ usage();
+ icc_filename = argv[argn];
+
} else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */
long lval;
if (lval < 0 || lval > 65535L)
usage();
if (ch == 'b' || ch == 'B') {
- cinfo->restart_interval = (unsigned int) lval;
+ cinfo->restart_interval = (unsigned int)lval;
cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */
} else {
- cinfo->restart_in_rows = (int) lval;
+ cinfo->restart_in_rows = (int)lval;
/* restart_interval will be computed during startup */
}
/* Set quantization tables for selected quality. */
/* Some or all may be overridden if -qtables is present. */
if (qualityarg != NULL) /* process -quality if it was present */
- if (! set_quality_ratings(cinfo, qualityarg, force_baseline))
+ if (!set_quality_ratings(cinfo, qualityarg, force_baseline))
usage();
if (qtablefile != NULL) /* process -qtables if it was present */
- if (! read_quant_tables(cinfo, qtablefile, force_baseline))
+ if (!read_quant_tables(cinfo, qtablefile, force_baseline))
usage();
if (qslotsarg != NULL) /* process -qslots if it was present */
- if (! set_quant_slots(cinfo, qslotsarg))
+ if (!set_quant_slots(cinfo, qslotsarg))
usage();
if (samplearg != NULL) /* process -sample if it was present */
- if (! set_sample_factors(cinfo, samplearg))
+ if (!set_sample_factors(cinfo, samplearg))
usage();
#ifdef C_PROGRESSIVE_SUPPORTED
#ifdef C_MULTISCAN_FILES_SUPPORTED
if (scansarg != NULL) /* process -scans if it was present */
- if (! read_scan_script(cinfo, scansarg))
+ if (!read_scan_script(cinfo, scansarg))
usage();
#endif
}
*/
int
-main (int argc, char **argv)
+main(int argc, char **argv)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
int file_index;
cjpeg_source_ptr src_mgr;
FILE *input_file;
+ FILE *icc_file;
+ JOCTET *icc_profile = NULL;
+ long icc_len = 0;
FILE *output_file = NULL;
unsigned char *outbuffer = NULL;
unsigned long outsize = 0;
if (!memdst) {
/* Must have either -outfile switch or explicit output file name */
if (outfilename == NULL) {
- if (file_index != argc-2) {
+ if (file_index != argc - 2) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
- outfilename = argv[file_index+1];
+ outfilename = argv[file_index + 1];
} else {
- if (file_index != argc-1) {
+ if (file_index != argc - 1) {
fprintf(stderr, "%s: must name one input and one output file\n",
progname);
usage();
}
#else
/* Unix style: expect zero or one file name */
- if (file_index < argc-1) {
+ if (file_index < argc - 1) {
fprintf(stderr, "%s: only one input file\n", progname);
usage();
}
output_file = write_stdout();
}
+ if (icc_filename != NULL) {
+ if ((icc_file = fopen(icc_filename, READ_BINARY)) == NULL) {
+ fprintf(stderr, "%s: can't open %s\n", progname, icc_filename);
+ exit(EXIT_FAILURE);
+ }
+ if (fseek(icc_file, 0, SEEK_END) < 0 ||
+ (icc_len = ftell(icc_file)) < 1 ||
+ fseek(icc_file, 0, SEEK_SET) < 0) {
+ fprintf(stderr, "%s: can't determine size of %s\n", progname,
+ icc_filename);
+ exit(EXIT_FAILURE);
+ }
+ if ((icc_profile = (JOCTET *)malloc(icc_len)) == NULL) {
+ fprintf(stderr, "%s: can't allocate memory for ICC profile\n", progname);
+ fclose(icc_file);
+ exit(EXIT_FAILURE);
+ }
+ if (fread(icc_profile, icc_len, 1, icc_file) < 1) {
+ fprintf(stderr, "%s: can't read ICC profile from %s\n", progname,
+ icc_filename);
+ free(icc_profile);
+ fclose(icc_file);
+ exit(EXIT_FAILURE);
+ }
+ fclose(icc_file);
+ }
+
#ifdef PROGRESS_REPORT
- start_progress_monitor((j_common_ptr) &cinfo, &progress);
+ start_progress_monitor((j_common_ptr)&cinfo, &progress);
#endif
/* Figure out the input file format, and set up to read it. */
/* Start compressor */
jpeg_start_compress(&cinfo, TRUE);
+ if (icc_profile != NULL)
+ jpeg_write_icc_profile(&cinfo, icc_profile, (unsigned int)icc_len);
+
/* 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);
+ (void)jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
}
/* Finish compression and release memory */
fclose(output_file);
#ifdef PROGRESS_REPORT
- end_progress_monitor((j_common_ptr) &cinfo);
+ end_progress_monitor((j_common_ptr)&cinfo);
#endif
if (memdst) {
free(outbuffer);
}
+ if (icc_profile != NULL)
+ free(icc_profile);
+
/* All done. */
exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS);
return 0; /* suppress no-return-value warnings */