home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / compresn / jpegv3sr / jdmain.c < prev    next >
C/C++ Source or Header  |  1992-03-17  |  9KB  |  324 lines

  1. /*
  2.  * jdmain.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains a trivial test user interface for the JPEG decompressor.
  9.  * It should work on any system with Unix- or MS-DOS-style command lines.
  10.  *
  11.  * Two different command line styles are permitted, depending on the
  12.  * compile-time switch TWO_FILE_COMMANDLINE:
  13.  *    djpeg [options]  inputfile outputfile
  14.  *    djpeg [options]  [inputfile]
  15.  * In the second style, output is always to standard output, which you'd
  16.  * normally redirect to a file or pipe to some other program.  Input is
  17.  * either from a named file or from standard input (typically redirected).
  18.  * The second style is convenient on Unix but is unhelpful on systems that
  19.  * don't support pipes.  Also, you MUST use the first style if your system
  20.  * doesn't do binary I/O to stdin/stdout.
  21.  */
  22.  
  23. #include "jinclude.h"
  24. #ifdef INCLUDES_ARE_ANSI
  25. #include <stdlib.h>        /* to declare exit() */
  26. #endif
  27. #ifdef NEED_SIGNAL_CATCHER
  28. #include <signal.h>        /* to declare signal() */
  29. #endif
  30.  
  31. #ifdef THINK_C
  32. #include <console.h>        /* command-line reader for Macintosh */
  33. #endif
  34.  
  35. #ifdef DONT_USE_B_MODE        /* define mode parameters for fopen() */
  36. #define READ_BINARY    "r"
  37. #define WRITE_BINARY    "w"
  38. #else
  39. #define READ_BINARY    "rb"
  40. #define WRITE_BINARY    "wb"
  41. #endif
  42.  
  43. #ifndef EXIT_FAILURE        /* define exit() codes if not provided */
  44. #define EXIT_FAILURE  1
  45. #endif
  46. #ifndef EXIT_SUCCESS
  47. #ifdef VMS
  48. #define EXIT_SUCCESS  1        /* VMS is very nonstandard */
  49. #else
  50. #define EXIT_SUCCESS  0
  51. #endif
  52. #endif
  53.  
  54.  
  55. #include "jversion.h"        /* for version message */
  56.  
  57.  
  58. /*
  59.  * PD version of getopt(3).
  60.  */
  61.  
  62. #include "egetopt.c"
  63.  
  64.  
  65. /*
  66.  * This list defines the known output image formats
  67.  * (not all of which need be supported by a given version).
  68.  * You can change the default output format by defining DEFAULT_FMT;
  69.  * indeed, you had better do so if you undefine PPM_SUPPORTED.
  70.  */
  71.  
  72. typedef enum {
  73.     FMT_GIF,        /* GIF format */
  74.     FMT_PPM,        /* PPM/PGM (PBMPLUS formats) */
  75.     FMT_RLE,        /* RLE format */
  76.     FMT_TARGA,        /* Targa format */
  77.     FMT_TIFF        /* TIFF format */
  78. } IMAGE_FORMATS;
  79.  
  80. #ifndef DEFAULT_FMT        /* so can override from CFLAGS in Makefile */
  81. #define DEFAULT_FMT    FMT_PPM
  82. #endif
  83.  
  84. static IMAGE_FORMATS requested_fmt;
  85.  
  86.  
  87. /*
  88.  * This routine gets control after the input file header has been read.
  89.  * It must determine what output file format is to be written,
  90.  * and make any other decompression parameter changes that are desirable.
  91.  */
  92.  
  93. METHODDEF void
  94. d_ui_method_selection (decompress_info_ptr cinfo)
  95. {
  96.   /* if grayscale or CMYK input, force similar output; */
  97.   /* else leave the output colorspace as set by options. */
  98.   if (cinfo->jpeg_color_space == CS_GRAYSCALE)
  99.     cinfo->out_color_space = CS_GRAYSCALE;
  100.   else if (cinfo->jpeg_color_space == CS_CMYK)
  101.     cinfo->out_color_space = CS_CMYK;
  102.  
  103.   /* select output file format */
  104.   /* Note: jselwxxx routine may make additional parameter changes,
  105.    * such as forcing color quantization if it's a colormapped format.
  106.    */
  107.   switch (requested_fmt) {
  108. #ifdef GIF_SUPPORTED
  109.   case FMT_GIF:
  110.     jselwgif(cinfo);
  111.     break;
  112. #endif
  113. #ifdef PPM_SUPPORTED
  114.   case FMT_PPM:
  115.     jselwppm(cinfo);
  116.     break;
  117. #endif
  118. #ifdef RLE_SUPPORTED
  119.   case FMT_RLE:
  120.     jselwrle(cinfo);
  121.     break;
  122. #endif
  123. #ifdef TARGA_SUPPORTED
  124.   case FMT_TARGA:
  125.     jselwtarga(cinfo);
  126.     break;
  127. #endif
  128.   default:
  129.     ERREXIT(cinfo->emethods, "Unsupported output file format");
  130.     break;
  131.   }
  132. }
  133.  
  134.  
  135. /*
  136.  * Signal catcher to ensure that temporary files are removed before aborting.
  137.  * NB: for Amiga Manx C this is actually a global routine named _abort();
  138.  * see -Dsignal_catcher=_abort in CFLAGS.  Talk about bogus...
  139.  */
  140.  
  141. #ifdef NEED_SIGNAL_CATCHER
  142.  
  143. static external_methods_ptr emethods; /* for access to free_all */
  144.  
  145. GLOBAL void
  146. signal_catcher (int signum)
  147. {
  148.   emethods->trace_level = 0;    /* turn off trace output */
  149.   (*emethods->free_all) ();    /* clean up memory allocation & temp files */
  150.   exit(EXIT_FAILURE);
  151. }
  152.  
  153. #endif
  154.  
  155.  
  156. LOCAL void
  157. usage (char * progname)
  158. /* complain about bad command line */
  159. {
  160.   fprintf(stderr, "usage: %s ", progname);
  161.   fprintf(stderr, "[-G] [-P] [-R] [-T] [-b] [-g] [-q colors] [-1] [-D] [-d] [-m mem]");
  162. #ifdef TWO_FILE_COMMANDLINE
  163.   fprintf(stderr, " inputfile outputfile\n");
  164. #else
  165.   fprintf(stderr, " [inputfile]\n");
  166. #endif
  167.   exit(EXIT_FAILURE);
  168. }
  169.  
  170.  
  171. /*
  172.  * The main program.
  173.  */
  174.  
  175. GLOBAL int
  176. main (int argc, char **argv)
  177. {
  178.   struct decompress_info_struct cinfo;
  179.   struct decompress_methods_struct dc_methods;
  180.   struct external_methods_struct e_methods;
  181.   int c;
  182.  
  183.   /* On Mac, fetch a command line. */
  184. #ifdef THINK_C
  185.   argc = ccommand(&argv);
  186. #endif
  187.  
  188.   /* Initialize the system-dependent method pointers. */
  189.   cinfo.methods = &dc_methods;
  190.   cinfo.emethods = &e_methods;
  191.   jselerror(&e_methods);    /* error/trace message routines */
  192.   jselmemmgr(&e_methods);    /* memory allocation routines */
  193.   dc_methods.d_ui_method_selection = d_ui_method_selection;
  194.  
  195.   /* Now OK to enable signal catcher. */
  196. #ifdef NEED_SIGNAL_CATCHER
  197.   emethods = &e_methods;
  198.   signal(SIGINT, signal_catcher);
  199. #ifdef SIGTERM            /* not all systems have SIGTERM */
  200.   signal(SIGTERM, signal_catcher);
  201. #endif
  202. #endif
  203.  
  204.   /* Set up default JPEG parameters. */
  205.   j_d_defaults(&cinfo, TRUE);
  206.   requested_fmt = DEFAULT_FMT;    /* set default output file format */
  207.  
  208.   /* Scan command line options, adjust parameters */
  209.   
  210.   while ((c = egetopt(argc, argv, "GPRTbgq:1Dm:d")) != EOF)
  211.     switch (c) {
  212.     case 'G':            /* GIF output format. */
  213.       requested_fmt = FMT_GIF;
  214.       break;
  215.     case 'P':            /* PPM output format. */
  216.       requested_fmt = FMT_PPM;
  217.       break;
  218.     case 'R':            /* RLE output format. */
  219.       requested_fmt = FMT_RLE;
  220.       break;
  221.     case 'T':            /* Targa output format. */
  222.       requested_fmt = FMT_TARGA;
  223.       break;
  224.     case 'b':            /* Enable cross-block smoothing. */
  225.       cinfo.do_block_smoothing = TRUE;
  226.       break;
  227.     case 'g':            /* Force grayscale output. */
  228.       cinfo.out_color_space = CS_GRAYSCALE;
  229.       break;
  230.     case 'q':            /* Do color quantization. */
  231.       { int val;
  232.     if (optarg == NULL)
  233.       usage(argv[0]);
  234.     if (sscanf(optarg, "%d", &val) != 1)
  235.       usage(argv[0]);
  236.     cinfo.desired_number_of_colors = val;
  237.       }
  238.       cinfo.quantize_colors = TRUE;
  239.       break;
  240.     case '1':            /* Use fast one-pass quantization. */
  241.       cinfo.two_pass_quantize = FALSE;
  242.       break;
  243.     case 'D':            /* Suppress dithering in color quantization. */
  244.       cinfo.use_dithering = FALSE;
  245.       break;
  246.     case 'm':            /* Maximum memory in Kb (or Mb with 'm'). */
  247.       { long lval;
  248.     char ch = 'x';
  249.  
  250.     if (optarg == NULL)
  251.       usage(argv[0]);
  252.     if (sscanf(optarg, "%ld%c", &lval, &ch) < 1)
  253.       usage(argv[0]);
  254.     if (ch == 'm' || ch == 'M')
  255.       lval *= 1000L;
  256.     e_methods.max_memory_to_use = lval * 1000L;
  257.       }
  258.       break;
  259.     case 'd':            /* Debugging. */
  260.       e_methods.trace_level++;
  261.       break;
  262.     case '?':
  263.     default:
  264.       usage(argv[0]);
  265.       break;
  266.     }
  267.  
  268.   /* If -d appeared, print version identification */
  269.   if (e_methods.trace_level > 0)
  270.     fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n",
  271.         JVERSION, JCOPYRIGHT);
  272.  
  273.   /* Select the input and output files */
  274.  
  275. #ifdef TWO_FILE_COMMANDLINE
  276.  
  277.   if (optind != argc-2) {
  278.     fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
  279.     usage(argv[0]);
  280.   }
  281.   if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  282.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  283.     exit(EXIT_FAILURE);
  284.   }
  285.   if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
  286.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
  287.     exit(EXIT_FAILURE);
  288.   }
  289.  
  290. #else /* not TWO_FILE_COMMANDLINE -- use Unix style */
  291.  
  292.   cinfo.input_file = stdin;    /* default input file */
  293.   cinfo.output_file = stdout;    /* always the output file */
  294.  
  295.   if (optind < argc-1) {
  296.     fprintf(stderr, "%s: only one input file\n", argv[0]);
  297.     usage(argv[0]);
  298.   }
  299.   if (optind < argc) {
  300.     if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  301.       fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  302.       exit(EXIT_FAILURE);
  303.     }
  304.   }
  305.  
  306. #endif /* TWO_FILE_COMMANDLINE */
  307.   
  308.   /* Set up to read a JFIF or baseline-JPEG file. */
  309.   /* A smarter UI would inspect the first few bytes of the input file */
  310.   /* to determine its type. */
  311. #ifdef JFIF_SUPPORTED
  312.   jselrjfif(&cinfo);
  313. #else
  314.   You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
  315. #endif
  316.  
  317.   /* Do it to it! */
  318.   jpeg_decompress(&cinfo);
  319.  
  320.   /* All done. */
  321.   exit(EXIT_SUCCESS);
  322.   return 0;            /* suppress no-return-value warnings */
  323. }
  324.