136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * djpeg.c 336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * 4a73e870ad02de20c2b34cb3a5382c2846c2afbe3DRC * This file was part of the Independent JPEG Group's software: 55ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * Copyright (C) 1991-1997, Thomas G. Lane. 6a6ef282a49f2d7d1b4d19cc89f63e81fd66b35b7DRC * libjpeg-turbo Modifications: 70ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * Copyright (C) 2010-2011, 2013-2016, D. R. Commander. 8ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * Copyright (C) 2015, Google, Inc. 936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * For conditions of distribution and use, see the accompanying README file. 1036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * 1136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This file contains a command-line user interface for the JPEG decompressor. 1236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * It should work on any system with Unix- or MS-DOS-style command lines. 1336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * 1436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Two different command line styles are permitted, depending on the 1536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * compile-time switch TWO_FILE_COMMANDLINE: 16e5eaf37440b8e337ab150c017df7c03faf846c51DRC * djpeg [options] inputfile outputfile 17e5eaf37440b8e337ab150c017df7c03faf846c51DRC * djpeg [options] [inputfile] 1836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * In the second style, output is always to standard output, which you'd 1936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * normally redirect to a file or pipe to some other program. Input is 2036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * either from a named file or from standard input (typically redirected). 2136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * The second style is convenient on Unix but is unhelpful on systems that 2236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * don't support pipes. Also, you MUST use the first style if your system 2336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * doesn't do binary I/O to stdin/stdout. 2436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * To simplify script writing, the "-outfile" switch is provided. The syntax 25e5eaf37440b8e337ab150c017df7c03faf846c51DRC * djpeg [options] -outfile outputfile inputfile 2636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * works regardless of which command line style is used. 2736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 2836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 29e5eaf37440b8e337ab150c017df7c03faf846c51DRC#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ 30e5eaf37440b8e337ab150c017df7c03faf846c51DRC#include "jversion.h" /* for version message */ 31ff6961f3d22060adc13cc3e60d42fc480de007e5DRC#include "jconfigint.h" 320ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC#include "wrppm.h" 3336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 34e5eaf37440b8e337ab150c017df7c03faf846c51DRC#include <ctype.h> /* to declare isprint() */ 3536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 36e5eaf37440b8e337ab150c017df7c03faf846c51DRC#ifdef USE_CCOMMAND /* command-line reader for Macintosh */ 3736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef __MWERKS__ 38489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane#include <SIOUX.h> /* Metrowerks needs this */ 39e5eaf37440b8e337ab150c017df7c03faf846c51DRC#include <console.h> /* ... and this */ 4036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 4136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef THINK_C 42e5eaf37440b8e337ab150c017df7c03faf846c51DRC#include <console.h> /* Think declares it here */ 4336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 4436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 4536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 4636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 479ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane/* Create the add-on message string table. */ 489ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane 49e5eaf37440b8e337ab150c017df7c03faf846c51DRC#define JMESSAGE(code,string) string , 509ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane 519ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lanestatic const char * const cdjpeg_message_table[] = { 529ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane#include "cderror.h" 539ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane NULL 549ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane}; 559ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane 569ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane 5736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 5836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This list defines the known output image formats 5936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * (not all of which need be supported by a given version). 6036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * You can change the default output format by defining DEFAULT_FMT; 6136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * indeed, you had better do so if you undefine PPM_SUPPORTED. 6236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 6336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 6436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanetypedef enum { 65e5eaf37440b8e337ab150c017df7c03faf846c51DRC FMT_BMP, /* BMP format (Windows flavor) */ 66e5eaf37440b8e337ab150c017df7c03faf846c51DRC FMT_GIF, /* GIF format */ 67e5eaf37440b8e337ab150c017df7c03faf846c51DRC FMT_OS2, /* BMP format (OS/2 flavor) */ 68e5eaf37440b8e337ab150c017df7c03faf846c51DRC FMT_PPM, /* PPM/PGM (PBMPLUS formats) */ 69e5eaf37440b8e337ab150c017df7c03faf846c51DRC FMT_RLE, /* RLE format */ 70e5eaf37440b8e337ab150c017df7c03faf846c51DRC FMT_TARGA, /* Targa format */ 71e5eaf37440b8e337ab150c017df7c03faf846c51DRC FMT_TIFF /* TIFF format */ 7236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} IMAGE_FORMATS; 7336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 74e5eaf37440b8e337ab150c017df7c03faf846c51DRC#ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */ 75e5eaf37440b8e337ab150c017df7c03faf846c51DRC#define DEFAULT_FMT FMT_PPM 7636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 7736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 7836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanestatic IMAGE_FORMATS requested_fmt; 7936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 8036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 8136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 8236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Argument-parsing code. 8336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * The switch parser is designed to be useful with DOS-style command line 8436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * syntax, ie, intermixed switches and file names, where only the switches 8536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * to the left of a given file name affect processing of that file. 8636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * The main program in this file doesn't actually use this capability... 8736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 8836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 8936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 900ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRCstatic const char *progname; /* program name for error messages */ 910ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRCstatic char *outfilename; /* for -outfile switch */ 920ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRCboolean memsrc; /* for -memsrc switch */ 930ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRCboolean skip, crop; 940ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRCJDIMENSION skip_start, skip_end; 950ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRCJDIMENSION crop_x, crop_y, crop_width, crop_height; 96ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC#define INPUT_BUF_SIZE 4096 9736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 9836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 99489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(void) 10036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneusage (void) 10136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* complain about bad command line */ 10236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 10336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "usage: %s [switches] ", progname); 10436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef TWO_FILE_COMMANDLINE 10536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "inputfile outputfile\n"); 10636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#else 10736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "[inputfile]\n"); 10836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 10936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 11036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "Switches (names may be abbreviated):\n"); 11136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -colors N Reduce image to no more than N colors\n"); 11236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -fast Fast, low-quality processing\n"); 11336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -grayscale Force grayscale output\n"); 1146a833a8ee0433525b1261ef349dabd868b7f6448DRC fprintf(stderr, " -rgb Force RGB output\n"); 11578df2e6115b0e579432d01cb034132cd4402a1baDRC fprintf(stderr, " -rgb565 Force RGB565 output\n"); 11636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef IDCT_SCALING_SUPPORTED 11736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\n"); 11836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 11936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef BMP_SUPPORTED 12036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -bmp Select BMP output format (Windows style)%s\n", 121e5eaf37440b8e337ab150c017df7c03faf846c51DRC (DEFAULT_FMT == FMT_BMP ? " (default)" : "")); 12236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 12336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef GIF_SUPPORTED 12436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -gif Select GIF output format%s\n", 125e5eaf37440b8e337ab150c017df7c03faf846c51DRC (DEFAULT_FMT == FMT_GIF ? " (default)" : "")); 12636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 12736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef BMP_SUPPORTED 12836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n", 129e5eaf37440b8e337ab150c017df7c03faf846c51DRC (DEFAULT_FMT == FMT_OS2 ? " (default)" : "")); 13036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 13136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef PPM_SUPPORTED 13236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n", 133e5eaf37440b8e337ab150c017df7c03faf846c51DRC (DEFAULT_FMT == FMT_PPM ? " (default)" : "")); 13436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 13536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef RLE_SUPPORTED 13636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -rle Select Utah RLE output format%s\n", 137e5eaf37440b8e337ab150c017df7c03faf846c51DRC (DEFAULT_FMT == FMT_RLE ? " (default)" : "")); 13836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 13936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef TARGA_SUPPORTED 14036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -targa Select Targa output format%s\n", 141e5eaf37440b8e337ab150c017df7c03faf846c51DRC (DEFAULT_FMT == FMT_TARGA ? " (default)" : "")); 14236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 14336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "Switches for advanced users:\n"); 14436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef DCT_ISLOW_SUPPORTED 14536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -dct int Use integer DCT method%s\n", 146e5eaf37440b8e337ab150c017df7c03faf846c51DRC (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); 14736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 14836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef DCT_IFAST_SUPPORTED 14936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", 150e5eaf37440b8e337ab150c017df7c03faf846c51DRC (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); 15136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 15236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef DCT_FLOAT_SUPPORTED 15336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -dct float Use floating-point DCT method%s\n", 154e5eaf37440b8e337ab150c017df7c03faf846c51DRC (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); 15536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 15636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -dither fs Use F-S dithering (default)\n"); 15736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -dither none Don't use dithering in quantization\n"); 15836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)\n"); 15936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef QUANT_2PASS_SUPPORTED 16036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -map FILE Map to colors used in named image file\n"); 16136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 16236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n"); 16336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef QUANT_1PASS_SUPPORTED 16436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\n"); 16536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 16636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); 16736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -outfile name Specify name for output file\n"); 168ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) 169ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC fprintf(stderr, " -memsrc Load input file into memory before decompressing\n"); 170ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC#endif 171ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC 1720ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC fprintf(stderr, " -skip Y0,Y1 Decompress all rows except those between Y0 and Y1 (inclusive)\n"); 1730ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC fprintf(stderr, " -crop WxH+X+Y Decompress only a rectangular subregion of the image\n"); 17436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, " -verbose or -debug Emit debug output\n"); 1759665f5e3f9a73ae44f011a20d382af331fdfd594DRC fprintf(stderr, " -version Print version information and exit\n"); 17636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane exit(EXIT_FAILURE); 17736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 17836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 17936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 180489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(int) 18136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneparse_switches (j_decompress_ptr cinfo, int argc, char **argv, 182e5eaf37440b8e337ab150c017df7c03faf846c51DRC int last_file_arg_seen, boolean for_real) 18336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Parse optional switches. 18436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Returns argv[] index of first file-name argument (== argc if none). 18536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Any file names with indexes <= last_file_arg_seen are ignored; 18636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * they have presumably been processed in a previous iteration. 18736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * (Pass 0 for last_file_arg_seen on the first or only iteration.) 18836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * for_real is FALSE on the first (dummy) pass; we may skip any expensive 18936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * processing. 19036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 19136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 19236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane int argn; 19336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane char * arg; 19436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 19536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Set up default JPEG parameters. */ 196e5eaf37440b8e337ab150c017df7c03faf846c51DRC requested_fmt = DEFAULT_FMT; /* set default output file format */ 19736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane outfilename = NULL; 198ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC memsrc = FALSE; 19915884f48eb1a4acd9c6c24291db974c596e71934DRC skip = FALSE; 2000ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC crop = FALSE; 20136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->err->trace_level = 0; 20236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 20336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Scan command line options, adjust parameters */ 20436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 20536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane for (argn = 1; argn < argc; argn++) { 20636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane arg = argv[argn]; 20736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (*arg != '-') { 20836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Not a switch, must be a file name argument */ 20936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (argn <= last_file_arg_seen) { 210e5eaf37440b8e337ab150c017df7c03faf846c51DRC outfilename = NULL; /* -outfile applies to just one input file */ 211e5eaf37440b8e337ab150c017df7c03faf846c51DRC continue; /* ignore this name if previously processed */ 21236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 213e5eaf37440b8e337ab150c017df7c03faf846c51DRC break; /* else done parsing switches */ 21436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 215e5eaf37440b8e337ab150c017df7c03faf846c51DRC arg++; /* advance past switch marker character */ 21636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 21736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (keymatch(arg, "bmp", 1)) { 21836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* BMP output format. */ 21936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane requested_fmt = FMT_BMP; 22036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 22136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) || 222e5eaf37440b8e337ab150c017df7c03faf846c51DRC keymatch(arg, "quantize", 1) || keymatch(arg, "quantise", 1)) { 22336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Do color quantization. */ 22436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane int val; 22536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 226e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (++argn >= argc) /* advance to next argument */ 227e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 22836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (sscanf(argv[argn], "%d", &val) != 1) 229e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 23036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->desired_number_of_colors = val; 23136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->quantize_colors = TRUE; 23236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 23336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "dct", 2)) { 23436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Select IDCT algorithm. */ 235e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (++argn >= argc) /* advance to next argument */ 236e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 23736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (keymatch(argv[argn], "int", 1)) { 238e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->dct_method = JDCT_ISLOW; 23936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(argv[argn], "fast", 2)) { 240e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->dct_method = JDCT_IFAST; 24136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(argv[argn], "float", 2)) { 242e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->dct_method = JDCT_FLOAT; 24336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else 244e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 24536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 24636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "dither", 2)) { 24736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Select dithering algorithm. */ 248e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (++argn >= argc) /* advance to next argument */ 249e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 25036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (keymatch(argv[argn], "fs", 2)) { 251e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->dither_mode = JDITHER_FS; 25236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(argv[argn], "none", 2)) { 253e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->dither_mode = JDITHER_NONE; 25436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(argv[argn], "ordered", 2)) { 255e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->dither_mode = JDITHER_ORDERED; 25636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else 257e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 25836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 25936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { 26036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Enable debug printouts. */ 26136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* On first -d, print version identification */ 26236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane static boolean printed_version = FALSE; 26336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 26436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (! printed_version) { 265e5eaf37440b8e337ab150c017df7c03faf846c51DRC fprintf(stderr, "%s version %s (build %s)\n", 266e5eaf37440b8e337ab150c017df7c03faf846c51DRC PACKAGE_NAME, VERSION, BUILD); 267e5eaf37440b8e337ab150c017df7c03faf846c51DRC fprintf(stderr, "%s\n\n", JCOPYRIGHT); 268e5eaf37440b8e337ab150c017df7c03faf846c51DRC fprintf(stderr, "Emulating The Independent JPEG Group's software, version %s\n\n", 269e5eaf37440b8e337ab150c017df7c03faf846c51DRC JVERSION); 270e5eaf37440b8e337ab150c017df7c03faf846c51DRC printed_version = TRUE; 27136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 27236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->err->trace_level++; 27336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 2749665f5e3f9a73ae44f011a20d382af331fdfd594DRC } else if (keymatch(arg, "version", 4)) { 2759665f5e3f9a73ae44f011a20d382af331fdfd594DRC fprintf(stderr, "%s version %s (build %s)\n", 2769665f5e3f9a73ae44f011a20d382af331fdfd594DRC PACKAGE_NAME, VERSION, BUILD); 277306add8b788c63590c476f693f95527f26909b62DRC exit(EXIT_SUCCESS); 2789665f5e3f9a73ae44f011a20d382af331fdfd594DRC 27936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "fast", 1)) { 28036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Select recommended processing options for quick-and-dirty output. */ 28136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->two_pass_quantize = FALSE; 28236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->dither_mode = JDITHER_ORDERED; 28336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (! cinfo->quantize_colors) /* don't override an earlier -colors */ 284e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->desired_number_of_colors = 216; 28536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->dct_method = JDCT_FASTEST; 28636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->do_fancy_upsampling = FALSE; 28736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 28836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "gif", 1)) { 28936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* GIF output format. */ 29036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane requested_fmt = FMT_GIF; 29136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 29236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { 29336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Force monochrome output. */ 29436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->out_color_space = JCS_GRAYSCALE; 29536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 2966a833a8ee0433525b1261ef349dabd868b7f6448DRC } else if (keymatch(arg, "rgb", 2)) { 2976a833a8ee0433525b1261ef349dabd868b7f6448DRC /* Force RGB output. */ 2986a833a8ee0433525b1261ef349dabd868b7f6448DRC cinfo->out_color_space = JCS_RGB; 2996a833a8ee0433525b1261ef349dabd868b7f6448DRC 30078df2e6115b0e579432d01cb034132cd4402a1baDRC } else if (keymatch(arg, "rgb565", 2)) { 30178df2e6115b0e579432d01cb034132cd4402a1baDRC /* Force RGB565 output. */ 30278df2e6115b0e579432d01cb034132cd4402a1baDRC cinfo->out_color_space = JCS_RGB565; 30378df2e6115b0e579432d01cb034132cd4402a1baDRC 30436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "map", 3)) { 30536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Quantize to a color map taken from an input file. */ 306e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (++argn >= argc) /* advance to next argument */ 307e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 308e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (for_real) { /* too expensive to do twice! */ 309e5eaf37440b8e337ab150c017df7c03faf846c51DRC#ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */ 310e5eaf37440b8e337ab150c017df7c03faf846c51DRC FILE * mapfile; 311e5eaf37440b8e337ab150c017df7c03faf846c51DRC 312e5eaf37440b8e337ab150c017df7c03faf846c51DRC if ((mapfile = fopen(argv[argn], READ_BINARY)) == NULL) { 313e5eaf37440b8e337ab150c017df7c03faf846c51DRC fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); 314e5eaf37440b8e337ab150c017df7c03faf846c51DRC exit(EXIT_FAILURE); 315e5eaf37440b8e337ab150c017df7c03faf846c51DRC } 316e5eaf37440b8e337ab150c017df7c03faf846c51DRC read_color_map(cinfo, mapfile); 317e5eaf37440b8e337ab150c017df7c03faf846c51DRC fclose(mapfile); 318e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->quantize_colors = TRUE; 31936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#else 320e5eaf37440b8e337ab150c017df7c03faf846c51DRC ERREXIT(cinfo, JERR_NOT_COMPILED); 32136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 32236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 32336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 32436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "maxmemory", 3)) { 32536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Maximum memory in Kb (or Mb with 'm'). */ 32636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane long lval; 32736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane char ch = 'x'; 32836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 329e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (++argn >= argc) /* advance to next argument */ 330e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 33136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) 332e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 33336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (ch == 'm' || ch == 'M') 334e5eaf37440b8e337ab150c017df7c03faf846c51DRC lval *= 1000L; 33536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->mem->max_memory_to_use = lval * 1000L; 33636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 33736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "nosmooth", 3)) { 33836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Suppress fancy upsampling */ 33936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->do_fancy_upsampling = FALSE; 34036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 34136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "onepass", 3)) { 34236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Use fast one-pass quantization. */ 34336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->two_pass_quantize = FALSE; 34436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 34536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "os2", 3)) { 34636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* BMP output format (OS/2 flavor). */ 34736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane requested_fmt = FMT_OS2; 34836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 34936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "outfile", 4)) { 35036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Set output file name. */ 351e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (++argn >= argc) /* advance to next argument */ 352e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 353e5eaf37440b8e337ab150c017df7c03faf846c51DRC outfilename = argv[argn]; /* save it away for later use */ 35436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 355ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC } else if (keymatch(arg, "memsrc", 2)) { 356ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC /* Use in-memory source manager */ 357ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) 358ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC memsrc = TRUE; 359ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC#else 360ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC fprintf(stderr, "%s: sorry, in-memory source manager was not compiled in\n", 361ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC progname); 362ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC exit(EXIT_FAILURE); 363ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC#endif 364ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC 36536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) { 36636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* PPM/PGM output format. */ 36736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane requested_fmt = FMT_PPM; 36836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 36936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "rle", 1)) { 37036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* RLE output format. */ 37136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane requested_fmt = FMT_RLE; 37236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 373ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } else if (keymatch(arg, "scale", 2)) { 37436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Scale the output image by a fraction M/N. */ 375e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (++argn >= argc) /* advance to next argument */ 376e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 37736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (sscanf(argv[argn], "%d/%d", 378e5eaf37440b8e337ab150c017df7c03faf846c51DRC &cinfo->scale_num, &cinfo->scale_denom) != 2) 379e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); 38036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 3810ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC } else if (keymatch(arg, "skip", 2)) { 382ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC if (++argn >= argc) 383ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC usage(); 3840ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (sscanf(argv[argn], "%u,%u", &skip_start, &skip_end) != 2 || 3850ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC skip_start > skip_end) 386ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC usage(); 3870ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC skip = TRUE; 38815884f48eb1a4acd9c6c24291db974c596e71934DRC 3890ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC } else if (keymatch(arg, "crop", 2)) { 3900ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC char c; 39115884f48eb1a4acd9c6c24291db974c596e71934DRC if (++argn >= argc) 39215884f48eb1a4acd9c6c24291db974c596e71934DRC usage(); 3930ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (sscanf(argv[argn], "%u%c%u+%u+%u", &crop_width, &c, &crop_height, 3940ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC &crop_x, &crop_y) != 5 || 3950ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (c != 'X' && c != 'x') || crop_width < 1 || crop_height < 1) 39615884f48eb1a4acd9c6c24291db974c596e71934DRC usage(); 3970ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC crop = TRUE; 39815884f48eb1a4acd9c6c24291db974c596e71934DRC 39936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (keymatch(arg, "targa", 1)) { 40036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Targa output format. */ 40136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane requested_fmt = FMT_TARGA; 40236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 40336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else { 404e5eaf37440b8e337ab150c017df7c03faf846c51DRC usage(); /* bogus switch */ 40536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 40636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 40736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 408e5eaf37440b8e337ab150c017df7c03faf846c51DRC return argn; /* return index of next arg (file name) */ 40936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 41036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 41136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 41236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 4135ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * Marker processor for COM and interesting APPn markers. 41436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This replaces the library's built-in processor, which just skips the marker. 4155ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * We want to print out the marker as text, to the extent possible. 41636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Note this code relies on a non-suspending data source. 41736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 41836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 419489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(unsigned int) 42036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanejpeg_getc (j_decompress_ptr cinfo) 42136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Read next byte */ 42236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 42336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane struct jpeg_source_mgr * datasrc = cinfo->src; 42436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 42536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (datasrc->bytes_in_buffer == 0) { 42636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (! (*datasrc->fill_input_buffer) (cinfo)) 42736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane ERREXIT(cinfo, JERR_CANT_SUSPEND); 42836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 42936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane datasrc->bytes_in_buffer--; 43036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane return GETJOCTET(*datasrc->next_input_byte++); 43136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 43236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 43336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 434489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(boolean) 4355ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Laneprint_text_marker (j_decompress_ptr cinfo) 43636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 43736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane boolean traceit = (cinfo->err->trace_level >= 1); 43836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane INT32 length; 43936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane unsigned int ch; 44036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane unsigned int lastch = 0; 44136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 44236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane length = jpeg_getc(cinfo) << 8; 44336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane length += jpeg_getc(cinfo); 444e5eaf37440b8e337ab150c017df7c03faf846c51DRC length -= 2; /* discount the length word itself */ 44536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 4465ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane if (traceit) { 4475ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane if (cinfo->unread_marker == JPEG_COM) 4485ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane fprintf(stderr, "Comment, length %ld:\n", (long) length); 449e5eaf37440b8e337ab150c017df7c03faf846c51DRC else /* assume it is an APPn otherwise */ 4505ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane fprintf(stderr, "APP%d, length %ld:\n", 451e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->unread_marker - JPEG_APP0, (long) length); 4525ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane } 45336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 45436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane while (--length >= 0) { 45536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane ch = jpeg_getc(cinfo); 45636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (traceit) { 45736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Emit the character in a readable form. 45836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Nonprintables are converted to \nnn form, 45936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * while \ is converted to \\. 46036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Newlines in CR, CR/LF, or LF form will be printed as one newline. 46136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 46236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (ch == '\r') { 463e5eaf37440b8e337ab150c017df7c03faf846c51DRC fprintf(stderr, "\n"); 46436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (ch == '\n') { 465e5eaf37440b8e337ab150c017df7c03faf846c51DRC if (lastch != '\r') 466e5eaf37440b8e337ab150c017df7c03faf846c51DRC fprintf(stderr, "\n"); 46736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (ch == '\\') { 468e5eaf37440b8e337ab150c017df7c03faf846c51DRC fprintf(stderr, "\\\\"); 46936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else if (isprint(ch)) { 470e5eaf37440b8e337ab150c017df7c03faf846c51DRC putc(ch, stderr); 47136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else { 472e5eaf37440b8e337ab150c017df7c03faf846c51DRC fprintf(stderr, "\\%03o", ch); 47336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 47436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane lastch = ch; 47536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 47636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 47736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 47836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (traceit) 47936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "\n"); 48036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 48136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane return TRUE; 48236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 48336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 48436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 48536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 48636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * The main program. 48736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 48836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 489489583f5165e05d37302e8eeec58104ea0109127Thomas G. Laneint 49036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanemain (int argc, char **argv) 49136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 49236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane struct jpeg_decompress_struct cinfo; 49336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane struct jpeg_error_mgr jerr; 49436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef PROGRESS_REPORT 49536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane struct cdjpeg_progress_mgr progress; 49636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 49736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane int file_index; 49836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane djpeg_dest_ptr dest_mgr = NULL; 49936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane FILE * input_file; 50036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane FILE * output_file; 501ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC unsigned char *inbuffer = NULL; 502ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC unsigned long insize = 0; 50336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane JDIMENSION num_scanlines; 50436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 50536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* On Mac, fetch a command line. */ 50636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef USE_CCOMMAND 50736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane argc = ccommand(&argv); 50836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 50936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 51036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane progname = argv[0]; 51136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (progname == NULL || progname[0] == 0) 512e5eaf37440b8e337ab150c017df7c03faf846c51DRC progname = "djpeg"; /* in case C library doesn't provide it */ 51336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 51436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Initialize the JPEG decompression object with default error handling. */ 51536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo.err = jpeg_std_error(&jerr); 51636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane jpeg_create_decompress(&cinfo); 51736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Add some application-specific error messages (from cderror.h) */ 5189ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane jerr.addon_message_table = cdjpeg_message_table; 51936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane jerr.first_addon_message = JMSG_FIRSTADDONCODE; 52036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane jerr.last_addon_message = JMSG_LASTADDONCODE; 5215ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane 5225ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane /* Insert custom marker processor for COM and APP12. 5235ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * APP12 is used by some digital camera makers for textual info, 5245ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * so we provide the ability to display it as text. 5255ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * If you like, additional APPn marker types can be selected for display, 52639ea562c074ec74785d68accf10f433849770d1fDRC * but don't try to override APP0 or APP14 this way (see libjpeg.txt). 5275ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane */ 5285ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker); 5295ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker); 53036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 53136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Scan command line to find file names. */ 53236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* It is convenient to use just one switch-parsing routine, but the switch 53336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * values read here are ignored; we will rescan the switches after opening 53436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * the input file. 53536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * (Exception: tracing level set here controls verbosity for COM markers 53636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * found during jpeg_read_header...) 53736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 53836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 53936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); 54036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 54136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef TWO_FILE_COMMANDLINE 54236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Must have either -outfile switch or explicit output file name */ 54336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (outfilename == NULL) { 54436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (file_index != argc-2) { 54536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "%s: must name one input and one output file\n", 546e5eaf37440b8e337ab150c017df7c03faf846c51DRC progname); 54736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane usage(); 54836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 54936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane outfilename = argv[file_index+1]; 55036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else { 55136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (file_index != argc-1) { 55236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "%s: must name one input and one output file\n", 553e5eaf37440b8e337ab150c017df7c03faf846c51DRC progname); 55436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane usage(); 55536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 55636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 55736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#else 55836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Unix style: expect zero or one file name */ 55936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (file_index < argc-1) { 56036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "%s: only one input file\n", progname); 56136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane usage(); 56236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 56336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif /* TWO_FILE_COMMANDLINE */ 56436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 56536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Open the input file. */ 56636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (file_index < argc) { 56736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { 56836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); 56936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane exit(EXIT_FAILURE); 57036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 57136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else { 57236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* default input file is stdin */ 573bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane input_file = read_stdin(); 57436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 57536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 57636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Open the output file. */ 57736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (outfilename != NULL) { 57836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { 57936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane fprintf(stderr, "%s: can't open %s\n", progname, outfilename); 58036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane exit(EXIT_FAILURE); 58136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 58236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else { 58336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* default output file is stdout */ 584bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane output_file = write_stdout(); 58536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 58636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 58736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef PROGRESS_REPORT 588bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane start_progress_monitor((j_common_ptr) &cinfo, &progress); 58936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 59036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 59136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Specify data source for decompression */ 592ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) 593ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC if (memsrc) { 594ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC size_t nbytes; 595ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC do { 596ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC inbuffer = (unsigned char *)realloc(inbuffer, insize + INPUT_BUF_SIZE); 597ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC if (inbuffer == NULL) { 598ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC fprintf(stderr, "%s: memory allocation failure\n", progname); 599ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC exit(EXIT_FAILURE); 600ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC } 601ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC nbytes = JFREAD(input_file, &inbuffer[insize], INPUT_BUF_SIZE); 602c45653e471c496af8bf3c91c70c7ae4e207158c4DRC if (nbytes < INPUT_BUF_SIZE && ferror(input_file)) { 603ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC if (file_index < argc) 604ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC fprintf(stderr, "%s: can't read from %s\n", progname, 605ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC argv[file_index]); 606ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC else 607ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC fprintf(stderr, "%s: can't read from stdin\n", progname); 608ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC } 609736fb06278ec2f0f3cd2d30fa34f17ede47138c4DRC insize += (unsigned long)nbytes; 610ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC } while (nbytes == INPUT_BUF_SIZE); 611ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC fprintf(stderr, "Compressed size: %lu bytes\n", insize); 612ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC jpeg_mem_src(&cinfo, inbuffer, insize); 613ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC } else 614ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC#endif 615ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC jpeg_stdio_src(&cinfo, input_file); 61636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 61736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Read file header, set default decompression parameters */ 61836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane (void) jpeg_read_header(&cinfo, TRUE); 61936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 62036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Adjust default decompression parameters by re-parsing the options */ 62136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane file_index = parse_switches(&cinfo, argc, argv, 0, TRUE); 62236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 62336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Initialize the output module now to let it override any crucial 62436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * option settings (for instance, GIF wants to force color quantization). 62536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 62636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane switch (requested_fmt) { 62736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef BMP_SUPPORTED 62836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case FMT_BMP: 62936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane dest_mgr = jinit_write_bmp(&cinfo, FALSE); 63036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 63136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case FMT_OS2: 63236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane dest_mgr = jinit_write_bmp(&cinfo, TRUE); 63336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 63436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 63536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef GIF_SUPPORTED 63636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case FMT_GIF: 63736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane dest_mgr = jinit_write_gif(&cinfo); 63836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 63936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 64036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef PPM_SUPPORTED 64136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case FMT_PPM: 64236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane dest_mgr = jinit_write_ppm(&cinfo); 64336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 64436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 64536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef RLE_SUPPORTED 64636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case FMT_RLE: 64736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane dest_mgr = jinit_write_rle(&cinfo); 64836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 64936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 65036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef TARGA_SUPPORTED 65136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case FMT_TARGA: 65236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane dest_mgr = jinit_write_targa(&cinfo); 65336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 65436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 65536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane default: 65636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT); 65736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 65836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 65936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane dest_mgr->output_file = output_file; 66036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 66136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Start decompressor */ 662bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (void) jpeg_start_decompress(&cinfo); 66336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 6640ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Skip rows */ 6650ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (skip) { 666ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC JDIMENSION tmp; 667ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 6680ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Check for valid skip_end. We cannot check this value until after 669ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC * jpeg_start_decompress() is called. Note that we have already verified 6700ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * that skip_start <= skip_end. 671ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 6720ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (skip_end > cinfo.output_height - 1) { 6730ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC fprintf(stderr, "%s: skip region exceeds image height %d\n", progname, 6740ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo.output_height); 675ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC exit(EXIT_FAILURE); 676ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 67736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 678ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Write output file header. This is a hack to ensure that the destination 6790ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * manager creates an output image of the proper size. 680ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC */ 681ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC tmp = cinfo.output_height; 6820ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo.output_height -= (skip_end - skip_start + 1); 683ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC (*dest_mgr->start_output) (&cinfo, dest_mgr); 684ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC cinfo.output_height = tmp; 685ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 686ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Process data */ 6870ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC while (cinfo.output_scanline < skip_start) { 6880ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, 6890ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC dest_mgr->buffer_height); 6900ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); 6910ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC } 6920ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC jpeg_skip_scanlines(&cinfo, skip_end - skip_start + 1); 6930ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC while (cinfo.output_scanline < cinfo.output_height) { 6940ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, 6950ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC dest_mgr->buffer_height); 6960ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); 6970ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC } 6980ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 6990ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Decompress a subregion */ 7000ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC } else if (crop) { 7010ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC JDIMENSION tmp; 7020ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 7030ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Check for valid crop dimensions. We cannot check these values until 7040ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * after jpeg_start_decompress() is called. 7050ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC */ 7060ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC if (crop_x + crop_width > cinfo.output_width || 7070ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC crop_y + crop_height > cinfo.output_height) { 7080ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC fprintf(stderr, "%s: crop dimensions exceed image dimensions %d x %d\n", 7090ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC progname, cinfo.output_width, cinfo.output_height); 7100ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC exit(EXIT_FAILURE); 7110ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC } 7120ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 7130ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC jpeg_crop_scanline(&cinfo, &crop_x, &crop_width); 7140ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC ((ppm_dest_ptr) dest_mgr)->buffer_width = cinfo.output_width * 7150ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo.out_color_components * 7160ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC sizeof(JSAMPLE); 7170ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 7180ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Write output file header. This is a hack to ensure that the destination 7190ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC * manager creates an output image of the proper size. 7200ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC */ 7210ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC tmp = cinfo.output_height; 7220ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo.output_height = crop_height; 7230ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (*dest_mgr->start_output) (&cinfo, dest_mgr); 7240ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC cinfo.output_height = tmp; 7250ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC 7260ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Process data */ 7270ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC jpeg_skip_scanlines(&cinfo, crop_y); 7280ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC while (cinfo.output_scanline < crop_y + crop_height) { 7290ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, 7300ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC dest_mgr->buffer_height); 7310ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); 732ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 7330ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC jpeg_skip_scanlines(&cinfo, cinfo.output_height - crop_y - crop_height); 734ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 7350ef076fb7b326dc201b4ab3bd30fefd4e35ad1c4DRC /* Normal full-image decompress */ 736ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } else { 737ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Write output file header */ 738ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC (*dest_mgr->start_output) (&cinfo, dest_mgr); 739ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC 740ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC /* Process data */ 741ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC while (cinfo.output_scanline < cinfo.output_height) { 742ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, 743ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC dest_mgr->buffer_height); 744ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); 745ac30a1bf12751bd82e56158eb9456a28d9c086f3DRC } 74636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 74736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 74836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef PROGRESS_REPORT 74936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Hack: count final pass as done in case finish_output does an extra pass. 75036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * The library won't have updated completed_passes. 75136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 75236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane progress.pub.completed_passes = progress.pub.total_passes; 75336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 75436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 75536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Finish decompression and release memory. 75636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * I must do it in this order because output module has allocated memory 75736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory. 75836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 75936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane (*dest_mgr->finish_output) (&cinfo, dest_mgr); 760bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane (void) jpeg_finish_decompress(&cinfo); 76136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane jpeg_destroy_decompress(&cinfo); 76236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 7639ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane /* Close files, if we opened them */ 7649ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane if (input_file != stdin) 7659ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane fclose(input_file); 7669ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane if (output_file != stdout) 7679ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane fclose(output_file); 7689ba2f5ed3649fb6de83d3c16e4dba1443aaca983Thomas G. Lane 76936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef PROGRESS_REPORT 770bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane end_progress_monitor((j_common_ptr) &cinfo); 77136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 77236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 773ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC if (memsrc && inbuffer != NULL) 774ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC free(inbuffer); 775ab70623eb29e09e67222be5b9e1ea320fe5aa0e9DRC 77636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* All done. */ 77736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); 778e5eaf37440b8e337ab150c017df7c03faf846c51DRC return 0; /* suppress no-return-value warnings */ 77936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 780