www.pudn.com > jseg.rar > djpeg.c
/* * djpeg.c * * Copyright (C) 1991-1997, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains a command-line user interface for the JPEG decompressor. * It should work on any system with Unix- or MS-DOS-style command lines. * * Two different command line styles are permitted, depending on the * compile-time switch TWO_FILE_COMMANDLINE: * djpeg [options] inputfile outputfile * djpeg [options] [inputfile] * In the second style, output is always to standard output, which you'd * normally redirect to a file or pipe to some other program. Input is * either from a named file or from standard input (typically redirected). * The second style is convenient on Unix but is unhelpful on systems that * don't support pipes. Also, you MUST use the first style if your system * doesn't do binary I/O to stdin/stdout. * To simplify script writing, the "-outfile" switch is provided. The syntax * djpeg [options] -outfile outputfile inputfile * works regardless of which command line style is used. */ #include/* Common decls for cjpeg/djpeg applications */ #include /* for version message */ #include /* to declare isprint() */ #include "ioutil.h" /* Create the add-on message string table. */ #define JMESSAGE(code,string) string , static const char * const cdjpeg_message_table[] = { #include "cderror.h" NULL }; /* * This list defines the known output image formats * (not all of which need be supported by a given version). * You can change the default output format by defining DEFAULT_FMT; * indeed, you had better do so if you undefine PPM_SUPPORTED. */ typedef enum { FMT_BMP, /* BMP format (Windows flavor) */ FMT_GIF, /* GIF format */ FMT_OS2, /* BMP format (OS/2 flavor) */ FMT_PPM, /* PPM/PGM (PBMPLUS formats) */ FMT_RLE, /* RLE format */ FMT_TARGA, /* Targa format */ FMT_TIFF /* TIFF format */ } IMAGE_FORMATS; #ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */ #define DEFAULT_FMT FMT_PPM #endif static IMAGE_FORMATS requested_fmt; /* * Marker processor for COM and interesting APPn markers. * This replaces the library's built-in processor, which just skips the marker. * We want to print out the marker as text, to the extent possible. * Note this code relies on a non-suspending data source. */ LOCAL(unsigned int) jpeg_getc (j_decompress_ptr cinfo) /* Read next byte */ { struct jpeg_source_mgr * datasrc = cinfo->src; if (datasrc->bytes_in_buffer == 0) { if (! (*datasrc->fill_input_buffer) (cinfo)) ERREXIT(cinfo, JERR_CANT_SUSPEND); } datasrc->bytes_in_buffer--; return GETJOCTET(*datasrc->next_input_byte++); } METHODDEF(boolean) print_text_marker (j_decompress_ptr cinfo) { boolean traceit = (cinfo->err->trace_level >= 1); INT32 length; unsigned int ch; unsigned int lastch = 0; length = jpeg_getc(cinfo) << 8; length += jpeg_getc(cinfo); length -= 2; /* discount the length word itself */ if (traceit) { if (cinfo->unread_marker == JPEG_COM) fprintf(stderr, "Comment, length %ld:\n", (long) length); else /* assume it is an APPn otherwise */ fprintf(stderr, "APP%d, length %ld:\n", cinfo->unread_marker - JPEG_APP0, (long) length); } while (--length >= 0) { ch = jpeg_getc(cinfo); if (traceit) { /* Emit the character in a readable form. * Nonprintables are converted to \nnn form, * while \ is converted to \\. * Newlines in CR, CR/LF, or LF form will be printed as one newline. */ if (ch == '\r') { fprintf(stderr, "\n"); } else if (ch == '\n') { if (lastch != '\r') fprintf(stderr, "\n"); } else if (ch == '\\') { fprintf(stderr, "\\\\"); } else if (isprint(ch)) { putc(ch, stderr); } else { fprintf(stderr, "\\%03o", ch); } lastch = ch; } } if (traceit) fprintf(stderr, "\n"); return TRUE; } /* * The main program. */ int inputimgjpg(char *filename,unsigned char **RGB,int *NY,int *NX) { int dim,i,row_stride; unsigned char *rgbp; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPARRAY buffer; /* Output row buffer */ int file_index; FILE * input_file; FILE * output_file; JDIMENSION num_scanlines; /* Initialize the JPEG decompression object with default error handling. */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); /* Add some application-specific error messages (from cderror.h) */ jerr.addon_message_table = cdjpeg_message_table; jerr.first_addon_message = JMSG_FIRSTADDONCODE; jerr.last_addon_message = JMSG_LASTADDONCODE; /* Insert custom marker processor for COM and APP12. * APP12 is used by some digital camera makers for textual info, * so we provide the ability to display it as text. * If you like, additional APPn marker types can be selected for display, * but don't try to override APP0 or APP14 this way (see libjpeg.doc). */ jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker); jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker); /* Scan command line to find file names. */ /* It is convenient to use just one switch-parsing routine, but the switch * values read here are ignored; we will rescan the switches after opening * the input file. * (Exception: tracing level set here controls verbosity for COM markers * found during jpeg_read_header...) */ /* Open the input file. */ if ((input_file = fopen(filename, READ_BINARY)) == NULL) { fprintf(stderr, "can't open %s\n", filename); exit(EXIT_FAILURE); } /* Specify data source for decompression */ jpeg_stdio_src(&cinfo, input_file); /* Read file header, set default decompression parameters */ (void) jpeg_read_header(&cinfo, TRUE); /* Start decompressor */ (void) jpeg_start_decompress(&cinfo); switch (cinfo.out_color_space) { case JCS_GRAYSCALE: dim = 1; *NY = (int) cinfo.output_height; *NX = (int) cinfo.output_width; *RGB = (unsigned char *)calloc((*NY)*(*NX)*dim,sizeof(unsigned char)); rgbp = *RGB; break; case JCS_RGB: dim = 3; *NY = (int) cinfo.output_height; *NX = (int) cinfo.output_width; *RGB = (unsigned char *)calloc((*NY)*(*NX)*dim,sizeof(unsigned char)); rgbp = *RGB; break; default: ERREXIT(&cinfo, JERR_PPM_COLORSPACE); } row_stride = cinfo.output_width * cinfo.out_color_components; buffer = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); /* Process data */ while (cinfo.output_scanline < cinfo.output_height) { num_scanlines = jpeg_read_scanlines(&cinfo, buffer, 1); for (i=0;i