home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / graphic / jpeg / jdmain.c < prev    next >
Text File  |  1992-04-29  |  11KB  |  366 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. /* Display progress report */
  156.  
  157. METHODDEF void
  158. progress_monitor (decompress_info_ptr cinfo, long loopcounter, long looplimit)
  159. {
  160.   if (cinfo->total_passes > 1) {
  161.     fprintf(stderr, "\rPass %d/%d: %3d%% ",
  162.         cinfo->completed_passes+1, cinfo->total_passes,
  163.         (int) (loopcounter*100L/looplimit));
  164.   } else {
  165.     fprintf(stderr, "\r %3d%% ",
  166.         (int) (loopcounter*100L/looplimit));
  167.   }
  168.   fflush(stderr);
  169. }
  170.  
  171.  
  172. LOCAL void
  173. usage (void)
  174. /* complain about bad command line */
  175. {
  176.   fprintf(stderr, "Usage: djpeg [switches] inputfile outputfile\n");
  177.   fprintf(stderr, "Optional switches:\n");
  178. #ifdef GIF_SUPPORTED
  179.   fprintf(stderr, "  -G          Select GIF output, extension .GIF\n");
  180. #endif
  181. #ifdef PPM_SUPPORTED
  182.   fprintf(stderr, "  -P          Select PPM/PGM output, extension .PPM (default)\n");
  183. #endif
  184. #ifdef RLE_SUPPORTED
  185.   fprintf(stderr, "  -R          Select Utah RLE output, extension .RLE\n");
  186. #endif
  187. #ifdef TARGA_SUPPORTED
  188.   fprintf(stderr, "  -T          Select Targa output, extension .TGA\n");
  189. #endif
  190.   fprintf(stderr, "  -g          Force grayscale output\n");
  191.   fprintf(stderr, "  -q colors   Quantize to no more than N colors\n");
  192.   fprintf(stderr, "  -1          Use 1-pass quantization (fast, low quality)\n");
  193.   fprintf(stderr, "  -D          Don't use dithering in quantization\n");
  194.   fprintf(stderr, "  -b          Apply cross-block smoothing\n");
  195. #ifndef FREE_MEM_ESTIMATE
  196.   fprintf(stderr, "  -m memory   Maximum memory to use (default infinite); see USAGE\n");
  197. #endif
  198.   fprintf(stderr, "  -d          Generate debug output\n");
  199.   exit(EXIT_FAILURE);
  200. }
  201.  
  202.  
  203. /*
  204.  * The main program.
  205.  */
  206.  
  207. GLOBAL int
  208. main (int argc, char **argv)
  209. {
  210.   struct decompress_info_struct cinfo;
  211.   struct decompress_methods_struct dc_methods;
  212.   struct external_methods_struct e_methods;
  213.   int c;
  214.  
  215.   /* On Mac, fetch a command line. */
  216. #ifdef THINK_C
  217.   argc = ccommand(&argv);
  218. #endif
  219.  
  220.   /* Initialize the system-dependent method pointers. */
  221.   cinfo.methods = &dc_methods;
  222.   cinfo.emethods = &e_methods;
  223.   jselerror(&e_methods);    /* error/trace message routines */
  224.   jselmemmgr(&e_methods);    /* memory allocation routines */
  225.   dc_methods.d_ui_method_selection = d_ui_method_selection;
  226.  
  227.   /* Now OK to enable signal catcher. */
  228. #ifdef NEED_SIGNAL_CATCHER
  229.   emethods = &e_methods;
  230.   signal(SIGINT, signal_catcher);
  231. #ifdef SIGTERM            /* not all systems have SIGTERM */
  232.   signal(SIGTERM, signal_catcher);
  233. #endif
  234. #endif
  235.  
  236.   /* Set up default JPEG parameters. */
  237.   j_d_defaults(&cinfo, TRUE);
  238.   requested_fmt = DEFAULT_FMT;    /* set default output file format */
  239.  
  240.   /* Scan command line options, adjust parameters */
  241.   
  242.   while ((c = egetopt(argc, argv, "GPRTbgq:1Dm:d")) != EOF)
  243.     switch (c) {
  244.     case 'G':            /* GIF output format. */
  245.       requested_fmt = FMT_GIF;
  246.       break;
  247.     case 'P':            /* PPM output format. */
  248.       requested_fmt = FMT_PPM;
  249.       break;
  250.     case 'R':            /* RLE output format. */
  251.       requested_fmt = FMT_RLE;
  252.       break;
  253.     case 'T':            /* Targa output format. */
  254.       requested_fmt = FMT_TARGA;
  255.       break;
  256.     case 'b':            /* Enable cross-block smoothing. */
  257.       cinfo.do_block_smoothing = TRUE;
  258.       break;
  259.     case 'g':            /* Force grayscale output. */
  260.       cinfo.out_color_space = CS_GRAYSCALE;
  261.       break;
  262.     case 'q':            /* Do color quantization. */
  263.       { int val;
  264.     if (optarg == NULL)
  265.       usage();
  266.     if (sscanf(optarg, "%d", &val) != 1)
  267.       usage();
  268.     cinfo.desired_number_of_colors = val;
  269.       }
  270.       cinfo.quantize_colors = TRUE;
  271.       break;
  272.     case '1':            /* Use fast one-pass quantization. */
  273.       cinfo.two_pass_quantize = FALSE;
  274.       break;
  275.     case 'D':            /* Suppress dithering in color quantization. */
  276.       cinfo.use_dithering = FALSE;
  277.       break;
  278.     case 'm':            /* Maximum memory in Kb (or Mb with 'm'). */
  279.       { long lval;
  280.     char ch = 'x';
  281.  
  282.     if (optarg == NULL)
  283.       usage();
  284.     if (sscanf(optarg, "%ld%c", &lval, &ch) < 1)
  285.       usage();
  286.     if (ch == 'm' || ch == 'M')
  287.       lval *= 1000L;
  288.     e_methods.max_memory_to_use = lval * 1000L;
  289.       }
  290.       break;
  291.     case 'd':            /* Debugging. */
  292.       e_methods.trace_level++;
  293.       break;
  294.     case '?':
  295.     default:
  296.       usage();
  297.       break;
  298.     }
  299.  
  300.   /* If -d appeared, print version identification */
  301.   if (e_methods.trace_level > 0)
  302.     fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n",
  303.         JVERSION, JCOPYRIGHT);
  304.  
  305.   /* Select the input and output files */
  306.  
  307. #ifdef TWO_FILE_COMMANDLINE
  308.  
  309.   if (optind != argc-2) {
  310.     fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
  311.     usage();
  312.   }
  313.   if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  314.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  315.     exit(EXIT_FAILURE);
  316.   }
  317.   if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
  318.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
  319.     exit(EXIT_FAILURE);
  320.   }
  321.  
  322. #else /* not TWO_FILE_COMMANDLINE -- use Unix style */
  323.  
  324.   cinfo.input_file = stdin;    /* default input file */
  325.   cinfo.output_file = stdout;    /* always the output file */
  326.  
  327.   if (optind < argc-1) {
  328.     fprintf(stderr, "%s: only one input file\n", argv[0]);
  329.     usage();
  330.   }
  331.   if (optind < argc) {
  332.     if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  333.       fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  334.       exit(EXIT_FAILURE);
  335.     }
  336.   }
  337.  
  338. #endif /* TWO_FILE_COMMANDLINE */
  339.  
  340.   /* Start up progress display, unless trace output is on */
  341.   fprintf(stderr, "Decompressing\n");
  342.   if (e_methods.trace_level == 0)
  343.     dc_methods.progress_monitor = progress_monitor;
  344.  
  345.   /* Set up to read a JFIF or baseline-JPEG file. */
  346.   /* A smarter UI would inspect the first few bytes of the input file */
  347.   /* to determine its type. */
  348. #ifdef JFIF_SUPPORTED
  349.   jselrjfif(&cinfo);
  350. #else
  351.   You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
  352. #endif
  353.  
  354.   /* Do it to it! */
  355.   jpeg_decompress(&cinfo);
  356.  
  357.   /* Clear away progress display */
  358.   if (e_methods.trace_level == 0)
  359.     fprintf(stderr, "\r                \r");
  360.   fflush(stderr);
  361.  
  362.   /* All done. */
  363.   exit(EXIT_SUCCESS);
  364.   return 0;            /* suppress no-return-value warnings */
  365. }
  366.