1f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 2f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * cdjpeg.c 3f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 4f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Copyright (C) 1991-1997, Thomas G. Lane. 5f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This file is part of the Independent JPEG Group's software. 6f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * For conditions of distribution and use, see the accompanying README file. 7f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * 8f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * This file contains common support routines used by the IJG application 9f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * programs (cjpeg, djpeg, jpegtran). 10f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 11f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 12f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ 13f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include <ctype.h> /* to declare isupper(), tolower() */ 14f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef NEED_SIGNAL_CATCHER 15f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include <signal.h> /* to declare signal() */ 16f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 17f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef USE_SETMODE 18f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include <fcntl.h> /* to declare setmode()'s parameter macros */ 19f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* If you have setmode() but not <io.h>, just delete this line: */ 20f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#include <io.h> /* to declare setmode() */ 21f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 22f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 23f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 24f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 25f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Signal catcher to ensure that temporary files are removed before aborting. 26f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * NB: for Amiga Manx C this is actually a global routine named _abort(); 27f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus... 28f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 29f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 30f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef NEED_SIGNAL_CATCHER 31f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 32f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgstatic j_common_ptr sig_cinfo; 33f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 34f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgvoid /* must be global for Manx C */ 35f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgsignal_catcher (int signum) 36f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 37f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (sig_cinfo != NULL) { 38f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (sig_cinfo->err != NULL) /* turn off trace output */ 39f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org sig_cinfo->err->trace_level = 0; 40f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */ 41f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 42f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org exit(EXIT_FAILURE); 43f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 44f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 45f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 46f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(void) 47f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgenable_signal_catcher (j_common_ptr cinfo) 48f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 49f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org sig_cinfo = cinfo; 50f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef SIGINT /* not all systems have SIGINT */ 51f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org signal(SIGINT, signal_catcher); 52f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 53f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef SIGTERM /* not all systems have SIGTERM */ 54f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org signal(SIGTERM, signal_catcher); 55f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 56f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 57f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 58f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 59f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 60f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 61f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 62f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Optional progress monitor: display a percent-done figure on stderr. 63f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 64f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 65f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef PROGRESS_REPORT 66f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 67f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgMETHODDEF(void) 68f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgprogress_monitor (j_common_ptr cinfo) 69f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 70f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress; 71f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org int total_passes = prog->pub.total_passes + prog->total_extra_passes; 72f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit); 73f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 74f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (percent_done != prog->percent_done) { 75f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org prog->percent_done = percent_done; 76f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (total_passes > 1) { 77f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org fprintf(stderr, "\rPass %d/%d: %3d%% ", 78f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org prog->pub.completed_passes + prog->completed_extra_passes + 1, 79f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org total_passes, percent_done); 80f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } else { 81f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org fprintf(stderr, "\r %3d%% ", percent_done); 82f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 83f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org fflush(stderr); 84f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 85f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 86f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 87f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 88f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(void) 89f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgstart_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress) 90f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 91f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Enable progress display, unless trace output is on */ 92f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->err->trace_level == 0) { 93f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->pub.progress_monitor = progress_monitor; 94f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->completed_extra_passes = 0; 95f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->total_extra_passes = 0; 96f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org progress->percent_done = -1; 97f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org cinfo->progress = &progress->pub; 98f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 99f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 100f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 101f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 102f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(void) 103f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgend_progress_monitor (j_common_ptr cinfo) 104f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 105f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* Clear away progress display */ 106f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (cinfo->err->trace_level == 0) { 107f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org fprintf(stderr, "\r \r"); 108f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org fflush(stderr); 109f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 110f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 111f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 112f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 113f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 114f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 115f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 116f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Case-insensitive matching of possibly-abbreviated keyword switches. 117f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * keyword is the constant keyword (must be lower case already), 118f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * minchars is length of minimum legal abbreviation. 119f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 120f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 121f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(boolean) 122f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgkeymatch (char * arg, const char * keyword, int minchars) 123f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 124f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register int ca, ck; 125f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org register int nmatched = 0; 126f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 127f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org while ((ca = *arg++) != '\0') { 128f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if ((ck = *keyword++) == '\0') 129f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return FALSE; /* arg longer than keyword, no good */ 130f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (isupper(ca)) /* force arg to lcase (assume ck is already) */ 131f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org ca = tolower(ca); 132f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (ca != ck) 133f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return FALSE; /* no good */ 134f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org nmatched++; /* count matched characters */ 135f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 136f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org /* reached end of argument; fail if it's too short for unique abbrev */ 137f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if (nmatched < minchars) 138f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return FALSE; 139f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return TRUE; /* A-OK */ 140f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 141f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 142f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 143f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org/* 144f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Routines to establish binary I/O mode for stdin and stdout. 145f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org * Non-Unix systems often require some hacking to get out of text mode. 146f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org */ 147f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 148f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(FILE *) 149f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgread_stdin (void) 150f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 151f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org FILE * input_file = stdin; 152f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 153f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef USE_SETMODE /* need to hack file mode? */ 154f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org setmode(fileno(stdin), O_BINARY); 155f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 156f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef USE_FDOPEN /* need to re-open in binary mode? */ 157f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) { 158f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org fprintf(stderr, "Cannot reopen stdin\n"); 159f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org exit(EXIT_FAILURE); 160f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 161f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 162f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return input_file; 163f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 164f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 165f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 166f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgGLOBAL(FILE *) 167f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.orgwrite_stdout (void) 168f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org{ 169f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org FILE * output_file = stdout; 170f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org 171f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef USE_SETMODE /* need to hack file mode? */ 172f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org setmode(fileno(stdout), O_BINARY); 173f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 174f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#ifdef USE_FDOPEN /* need to re-open in binary mode? */ 175f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { 176f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org fprintf(stderr, "Cannot reopen stdout\n"); 177f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org exit(EXIT_FAILURE); 178f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org } 179f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org#endif 180f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org return output_file; 181f0c4f33a4aa0760ba0e12a254b69d996442c9c5hbono@chromium.org} 182