170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * cdjpeg.c 370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Copyright (C) 1991-1997, Thomas G. Lane. 570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file is part of the Independent JPEG Group's software. 670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For conditions of distribution and use, see the accompanying README file. 770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file contains common support routines used by the IJG application 970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * programs (cjpeg, djpeg, jpegtran). 1070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 1170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ 1370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <ctype.h> /* to declare isupper(), tolower() */ 1470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef NEED_SIGNAL_CATCHER 1570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <signal.h> /* to declare signal() */ 1670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 1770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef USE_SETMODE 1870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <fcntl.h> /* to declare setmode()'s parameter macros */ 1970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* If you have setmode() but not <io.h>, just delete this line: */ 2070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include <io.h> /* to declare setmode() */ 2170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 2270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 2570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Signal catcher to ensure that temporary files are removed before aborting. 2670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * NB: for Amiga Manx C this is actually a global routine named _abort(); 2770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * we put "#define signal_catcher _abort" in jconfig.h. Talk about bogus... 2870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 2970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef NEED_SIGNAL_CATCHER 3170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestatic j_common_ptr sig_cinfo; 3370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinevoid /* must be global for Manx C */ 3570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinesignal_catcher (int signum) 3670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 3770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (sig_cinfo != NULL) { 3870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (sig_cinfo->err != NULL) /* turn off trace output */ 3970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine sig_cinfo->err->trace_level = 0; 4070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_destroy(sig_cinfo); /* clean up memory allocation & temp files */ 4170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 4270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine exit(EXIT_FAILURE); 4370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 4470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 4570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 4670a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 4770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineenable_signal_catcher (j_common_ptr cinfo) 4870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 4970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine sig_cinfo = cinfo; 5070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef SIGINT /* not all systems have SIGINT */ 5170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine signal(SIGINT, signal_catcher); 5270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 5370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef SIGTERM /* not all systems have SIGTERM */ 5470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine signal(SIGTERM, signal_catcher); 5570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 5670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 5770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 5970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 6270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Optional progress monitor: display a percent-done figure on stderr. 6370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 6470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef PROGRESS_REPORT 6670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 6870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineprogress_monitor (j_common_ptr cinfo) 6970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 7070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cd_progress_ptr prog = (cd_progress_ptr) cinfo->progress; 7170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int total_passes = prog->pub.total_passes + prog->total_extra_passes; 7270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int percent_done = (int) (prog->pub.pass_counter*100L/prog->pub.pass_limit); 7370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (percent_done != prog->percent_done) { 7570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prog->percent_done = percent_done; 7670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (total_passes > 1) { 7770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fprintf(stderr, "\rPass %d/%d: %3d%% ", 7870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prog->pub.completed_passes + prog->completed_extra_passes + 1, 7970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine total_passes, percent_done); 8070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 8170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fprintf(stderr, "\r %3d%% ", percent_done); 8270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 8370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fflush(stderr); 8470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 8570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 8670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 8970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestart_progress_monitor (j_common_ptr cinfo, cd_progress_ptr progress) 9070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 9170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Enable progress display, unless trace output is on */ 9270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (cinfo->err->trace_level == 0) { 9370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->pub.progress_monitor = progress_monitor; 9470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->completed_extra_passes = 0; 9570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->total_extra_passes = 0; 9670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine progress->percent_done = -1; 9770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->progress = &progress->pub; 9870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 9970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 10070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 10170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 10270a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 10370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineend_progress_monitor (j_common_ptr cinfo) 10470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 10570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Clear away progress display */ 10670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (cinfo->err->trace_level == 0) { 10770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fprintf(stderr, "\r \r"); 10870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fflush(stderr); 10970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 11070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 11170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 11370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 11670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Case-insensitive matching of possibly-abbreviated keyword switches. 11770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * keyword is the constant keyword (must be lower case already), 11870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * minchars is length of minimum legal abbreviation. 11970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 12070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 12170a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(boolean) 12270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinekeymatch (char * arg, const char * keyword, int minchars) 12370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 12470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register int ca, ck; 12570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register int nmatched = 0; 12670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 12770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while ((ca = *arg++) != '\0') { 12870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if ((ck = *keyword++) == '\0') 12970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return FALSE; /* arg longer than keyword, no good */ 13070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (isupper(ca)) /* force arg to lcase (assume ck is already) */ 13170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ca = tolower(ca); 13270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (ca != ck) 13370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return FALSE; /* no good */ 13470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine nmatched++; /* count matched characters */ 13570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 13670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* reached end of argument; fail if it's too short for unique abbrev */ 13770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (nmatched < minchars) 13870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return FALSE; 13970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return TRUE; /* A-OK */ 14070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 14170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 14270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 14370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 14470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Routines to establish binary I/O mode for stdin and stdout. 14570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Non-Unix systems often require some hacking to get out of text mode. 14670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 14770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 14870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(FILE *) 14970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineread_stdin (void) 15070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 15170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine FILE * input_file = stdin; 15270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 15370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef USE_SETMODE /* need to hack file mode? */ 15470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine setmode(fileno(stdin), O_BINARY); 15570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 15670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef USE_FDOPEN /* need to re-open in binary mode? */ 15770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if ((input_file = fdopen(fileno(stdin), READ_BINARY)) == NULL) { 15870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fprintf(stderr, "Cannot reopen stdin\n"); 15970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine exit(EXIT_FAILURE); 16070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 16170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 16270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return input_file; 16370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 16470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 16570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 16670a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(FILE *) 16770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinewrite_stdout (void) 16870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 16970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine FILE * output_file = stdout; 17070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 17170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef USE_SETMODE /* need to hack file mode? */ 17270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine setmode(fileno(stdout), O_BINARY); 17370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 17470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef USE_FDOPEN /* need to re-open in binary mode? */ 17570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if ((output_file = fdopen(fileno(stdout), WRITE_BINARY)) == NULL) { 17670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fprintf(stderr, "Cannot reopen stdout\n"); 17770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine exit(EXIT_FAILURE); 17870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 17970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 18070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine return output_file; 18170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 182