home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-16 | 57.5 KB | 1,483 lines |
- Newsgroups: comp.sources.misc
- From: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Subject: v34i062: jpeg - JPEG image compression, Part08/18
- Message-ID: <1992Dec17.041824.23623@sparky.imd.sterling.com>
- X-Md4-Signature: 0589d14067732f495aaa5197d4afa5f6
- Date: Thu, 17 Dec 1992 04:18:24 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Posting-number: Volume 34, Issue 62
- Archive-name: jpeg/part08
- Environment: UNIX, VMS, MS-DOS, Mac, Amiga, Atari, Cray
- Supersedes: jpeg: Volume 29, Issue 1-18
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # Contents: example.c jcarith.c jcpipe.c
- # Wrapped by kent@sparky on Wed Dec 16 20:52:27 1992
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 8 (of 18)."'
- if test -f 'example.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'example.c'\"
- else
- echo shar: Extracting \"'example.c'\" \(26879 characters\)
- sed "s/^X//" >'example.c' <<'END_OF_FILE'
- X/*
- X * example.c
- X *
- X * This file is not actually part of the JPEG software. Rather, it provides
- X * a skeleton that may be useful for constructing applications that use the
- X * JPEG software as subroutines. This code will NOT do anything useful as is.
- X *
- X * This file illustrates how to use the JPEG code as a subroutine library
- X * to read or write JPEG image files. We assume here that you are not
- X * merely interested in converting the image to yet another image file format
- X * (if you are, you should be adding another I/O module to cjpeg/djpeg, not
- X * constructing a new application). Instead, we show how to pass the
- X * decompressed image data into or out of routines that you provide. For
- X * example, a viewer program might use the JPEG decompressor together with
- X * routines that write the decompressed image directly to a display.
- X *
- X * We present these routines in the same coding style used in the JPEG code
- X * (ANSI function definitions, etc); but you are of course free to code your
- X * routines in a different style if you prefer.
- X */
- X
- X/*
- X * Include file for declaring JPEG data structures.
- X * This file also includes some system headers like <stdio.h>;
- X * if you prefer, you can include "jconfig.h" and "jpegdata.h" instead.
- X */
- X
- X#include "jinclude.h"
- X
- X/*
- X * <setjmp.h> is used for the optional error recovery mechanism shown in
- X * the second part of the example.
- X */
- X
- X#include <setjmp.h>
- X
- X
- X
- X/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
- X
- X/* This half of the example shows how to feed data into the JPEG compressor.
- X * We present a minimal version that does not worry about refinements such
- X * as error recovery (the JPEG code will just exit() if it gets an error).
- X */
- X
- X
- X/*
- X * To supply the image data for compression, you must define three routines
- X * input_init, get_input_row, and input_term. These routines will be called
- X * from the JPEG compressor via function pointer values that you store in the
- X * cinfo data structure; hence they need not be globally visible and the exact
- X * names don't matter. (In fact, the "METHODDEF" macro expands to "static" if
- X * you use the unmodified JPEG include files.)
- X *
- X * The input file reading modules (jrdppm.c, jrdgif.c, jrdtarga.c, etc) may be
- X * useful examples of what these routines should actually do, although each of
- X * them is encrusted with a lot of specialized code for its own file format.
- X */
- X
- X
- XMETHODDEF void
- Xinput_init (compress_info_ptr cinfo)
- X/* Initialize for input; return image size and component data. */
- X{
- X /* This routine must return five pieces of information about the incoming
- X * image, and must do any setup needed for the get_input_row routine.
- X * The image information is returned in fields of the cinfo struct.
- X * (If you don't care about modularity, you could initialize these fields
- X * in the main JPEG calling routine, and make this routine be a no-op.)
- X * We show some example values here.
- X */
- X cinfo->image_width = 640; /* width in pixels */
- X cinfo->image_height = 480; /* height in pixels */
- X /* JPEG views an image as being a rectangular array of pixels, with each
- X * pixel having the same number of "component" values (color channels).
- X * You must specify how many components there are and the colorspace
- X * interpretation of the components. Most applications will use RGB data or
- X * grayscale data. If you want to use something else, you'll need to study
- X * and perhaps modify jcdeflts.c, jccolor.c, and jdcolor.c.
- X */
- X cinfo->input_components = 3; /* or 1 for grayscale */
- X cinfo->in_color_space = CS_RGB; /* or CS_GRAYSCALE for grayscale */
- X cinfo->data_precision = 8; /* bits per pixel component value */
- X /* In the current JPEG software, data_precision must be set equal to
- X * BITS_IN_JSAMPLE, which is 8 unless you twiddle jconfig.h. Future
- X * versions might allow you to say either 8 or 12 if compiled with
- X * 12-bit JSAMPLEs, or up to 16 in lossless mode. In any case,
- X * it is up to you to scale incoming pixel values to the range
- X * 0 .. (1<<data_precision)-1.
- X * If your image data format is fixed at a byte per component,
- X * then saying "8" is probably the best long-term solution.
- X */
- X}
- X
- X
- X/*
- X * This function is called repeatedly and must supply the next row of pixels
- X * on each call. The rows MUST be returned in top-to-bottom order if you want
- X * your JPEG files to be compatible with everyone else's. (If you cannot
- X * readily read your data in that order, you'll need an intermediate array to
- X * hold the image. See jrdtarga.c or jrdrle.c for examples of handling
- X * bottom-to-top source data using the JPEG code's portable mechanisms.)
- X * The data is to be returned into a 2-D array of JSAMPLEs, indexed as
- X * JSAMPLE pixel_row[component][column]
- X * where component runs from 0 to cinfo->input_components-1, and column runs
- X * from 0 to cinfo->image_width-1 (column 0 is left edge of image). Note that
- X * this is actually an array of pointers to arrays rather than a true 2D array,
- X * since C does not support variable-size multidimensional arrays.
- X * JSAMPLE is typically typedef'd as "unsigned char".
- X */
- X
- X
- XMETHODDEF void
- Xget_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
- X/* Read next row of pixels into pixel_row[][] */
- X{
- X /* This example shows how you might read RGB data (3 components)
- X * from an input file in which the data is stored 3 bytes per pixel
- X * in left-to-right, top-to-bottom order.
- X */
- X register FILE * infile = cinfo->input_file;
- X register JSAMPROW ptr0, ptr1, ptr2;
- X register long col;
- X
- X ptr0 = pixel_row[0];
- X ptr1 = pixel_row[1];
- X ptr2 = pixel_row[2];
- X for (col = 0; col < cinfo->image_width; col++) {
- X *ptr0++ = (JSAMPLE) getc(infile); /* red */
- X *ptr1++ = (JSAMPLE) getc(infile); /* green */
- X *ptr2++ = (JSAMPLE) getc(infile); /* blue */
- X }
- X}
- X
- X
- XMETHODDEF void
- Xinput_term (compress_info_ptr cinfo)
- X/* Finish up at the end of the input */
- X{
- X /* This termination routine will very often have no work to do, */
- X /* but you must provide it anyway. */
- X /* Note that the JPEG code will only call it during successful exit; */
- X /* if you want it called during error exit, you gotta do that yourself. */
- X}
- X
- X
- X/*
- X * That's it for the routines that deal with reading the input image data.
- X * Now we have overall control and parameter selection routines.
- X */
- X
- X
- X/*
- X * This routine must determine what output JPEG file format is to be written,
- X * and make any other compression parameter changes that are desirable.
- X * This routine gets control after the input file header has been read
- X * (i.e., right after input_init has been called). You could combine its
- X * functions into input_init, or even into the main control routine, but
- X * if you have several different input_init routines, it's a definite win
- X * to keep this separate. You MUST supply this routine even if it's a no-op.
- X */
- X
- XMETHODDEF void
- Xc_ui_method_selection (compress_info_ptr cinfo)
- X{
- X /* If the input is gray scale, generate a monochrome JPEG file. */
- X if (cinfo->in_color_space == CS_GRAYSCALE)
- X j_monochrome_default(cinfo);
- X /* For now, always select JFIF output format. */
- X jselwjfif(cinfo);
- X}
- X
- X
- X/*
- X * OK, here is the main function that actually causes everything to happen.
- X * We assume here that the target filename is supplied by the caller of this
- X * routine, and that all JPEG compression parameters can be default values.
- X */
- X
- XGLOBAL void
- Xwrite_JPEG_file (char * filename)
- X{
- X /* These three structs contain JPEG parameters and working data.
- X * They must survive for the duration of parameter setup and one
- X * call to jpeg_compress; typically, making them local data in the
- X * calling routine is the best strategy.
- X */
- X struct Compress_info_struct cinfo;
- X struct Compress_methods_struct c_methods;
- X struct External_methods_struct e_methods;
- X
- X /* Initialize the system-dependent method pointers. */
- X cinfo.methods = &c_methods; /* links to method structs */
- X cinfo.emethods = &e_methods;
- X /* Here we use the default JPEG error handler, which will just print
- X * an error message on stderr and call exit(). See the second half of
- X * this file for an example of more graceful error recovery.
- X */
- X jselerror(&e_methods); /* select std error/trace message routines */
- X /* Here we use the standard memory manager provided with the JPEG code.
- X * In some cases you might want to replace the memory manager, or at
- X * least the system-dependent part of it, with your own code.
- X */
- X jselmemmgr(&e_methods); /* select std memory allocation routines */
- X /* If the compressor requires full-image buffers (for entropy-coding
- X * optimization or a noninterleaved JPEG file), it will create temporary
- X * files for anything that doesn't fit within the maximum-memory setting.
- X * (Note that temp files are NOT needed if you use the default parameters.)
- X * You can change the default maximum-memory setting by changing
- X * e_methods.max_memory_to_use after jselmemmgr returns.
- X * On some systems you may also need to set up a signal handler to
- X * ensure that temporary files are deleted if the program is interrupted.
- X * (This is most important if you are on MS-DOS and use the jmemdos.c
- X * memory manager back end; it will try to grab extended memory for
- X * temp files, and that space will NOT be freed automatically.)
- X * See jcmain.c or jdmain.c for an example signal handler.
- X */
- X
- X /* Here, set up pointers to your own routines for input data handling
- X * and post-init parameter selection.
- X */
- X c_methods.input_init = input_init;
- X c_methods.get_input_row = get_input_row;
- X c_methods.input_term = input_term;
- X c_methods.c_ui_method_selection = c_ui_method_selection;
- X
- X /* Set up default JPEG parameters in the cinfo data structure. */
- X j_c_defaults(&cinfo, 75, FALSE);
- X /* Note: 75 is the recommended default quality level; you may instead pass
- X * a user-specified quality level. Be aware that values below 25 will cause
- X * non-baseline JPEG files to be created (and a warning message to that
- X * effect to be emitted on stderr). This won't bother our decoder, but some
- X * commercial JPEG implementations may choke on non-baseline JPEG files.
- X * If you want to force baseline compatibility, pass TRUE instead of FALSE.
- X * (If non-baseline files are fine, but you could do without that warning
- X * message, set e_methods.trace_level to -1.)
- X */
- X
- X /* At this point you can modify the default parameters set by j_c_defaults
- X * as needed. For a minimal implementation, you shouldn't need to change
- X * anything. See jcmain.c for some examples of what you might change.
- X */
- X
- X /* Select the input and output files.
- X * Note that cinfo.input_file is only used if your input reading routines
- X * use it; otherwise, you can just make it NULL.
- X * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
- X * requires it in order to write binary files.
- X */
- X
- X cinfo.input_file = NULL; /* if no actual input file involved */
- X
- X if ((cinfo.output_file = fopen(filename, "wb")) == NULL) {
- X fprintf(stderr, "can't open %s\n", filename);
- X exit(1);
- X }
- X
- X /* Here we go! */
- X jpeg_compress(&cinfo);
- X
- X /* That's it, son. Nothin' else to do, except close files. */
- X /* Here we assume only the output file need be closed. */
- X fclose(cinfo.output_file);
- X
- X /* Note: if you want to compress more than one image, we recommend you
- X * repeat this whole routine. You MUST repeat the j_c_defaults()/alter
- X * parameters/jpeg_compress() sequence, as some data structures allocated
- X * in j_c_defaults are freed upon exit from jpeg_compress.
- X */
- X}
- X
- X
- X
- X/******************** JPEG DECOMPRESSION SAMPLE INTERFACE *******************/
- X
- X/* This half of the example shows how to read data from the JPEG decompressor.
- X * It's a little more refined than the above in that we show how to do your
- X * own error recovery. If you don't care about that, you don't need these
- X * next two routines.
- X */
- X
- X
- X/*
- X * These routines replace the default trace/error routines included with the
- X * JPEG code. The example trace_message routine shown here is actually the
- X * same as the standard one, but you could modify it if you don't want messages
- X * sent to stderr. The example error_exit routine is set up to return
- X * control to read_JPEG_file() rather than calling exit(). You can use the
- X * same routines for both compression and decompression error recovery.
- X */
- X
- X/* These static variables are needed by the error routines. */
- Xstatic jmp_buf setjmp_buffer; /* for return to caller */
- Xstatic external_methods_ptr emethods; /* needed for access to message_parm */
- X
- X
- X/* This routine is used for any and all trace, debug, or error printouts
- X * from the JPEG code. The parameter is a printf format string; up to 8
- X * integer data values for the format string have been stored in the
- X * message_parm[] field of the external_methods struct.
- X */
- X
- XMETHODDEF void
- Xtrace_message (const char *msgtext)
- X{
- X fprintf(stderr, msgtext,
- X emethods->message_parm[0], emethods->message_parm[1],
- X emethods->message_parm[2], emethods->message_parm[3],
- X emethods->message_parm[4], emethods->message_parm[5],
- X emethods->message_parm[6], emethods->message_parm[7]);
- X fprintf(stderr, "\n"); /* there is no \n in the format string! */
- X}
- X
- X/*
- X * The error_exit() routine should not return to its caller. The default
- X * routine calls exit(), but here we assume that we want to return to
- X * read_JPEG_file, which has set up a setjmp context for the purpose.
- X * You should make sure that the free_all method is called, either within
- X * error_exit or after the return to the outer-level routine.
- X */
- X
- XMETHODDEF void
- Xerror_exit (const char *msgtext)
- X{
- X trace_message(msgtext); /* report the error message */
- X (*emethods->free_all) (); /* clean up memory allocation & temp files */
- X longjmp(setjmp_buffer, 1); /* return control to outer routine */
- X}
- X
- X
- X
- X/*
- X * To accept the image data from decompression, you must define four routines
- X * output_init, put_color_map, put_pixel_rows, and output_term.
- X *
- X * You must understand the distinction between full color output mode
- X * (N independent color components) and colormapped output mode (a single
- X * output component representing an index into a color map). You should use
- X * colormapped mode to write to a colormapped display screen or output file.
- X * Colormapped mode is also useful for reducing grayscale output to a small
- X * number of gray levels: when using the 1-pass quantizer on grayscale data,
- X * the colormap entries will be evenly spaced from 0 to MAX_JSAMPLE, so you
- X * can regard the indexes are directly representing gray levels at reduced
- X * precision. In any other case, you should not depend on the colormap
- X * entries having any particular order.
- X * To get colormapped output, set cinfo->quantize_colors to TRUE and set
- X * cinfo->desired_number_of_colors to the maximum number of entries in the
- X * colormap. This can be done either in your main routine or in
- X * d_ui_method_selection. For grayscale quantization, also set
- X * cinfo->two_pass_quantize to FALSE to ensure the 1-pass quantizer is used
- X * (presently this is the default, but it may not be so in the future).
- X *
- X * The output file writing modules (jwrppm.c, jwrgif.c, jwrtarga.c, etc) may be
- X * useful examples of what these routines should actually do, although each of
- X * them is encrusted with a lot of specialized code for its own file format.
- X */
- X
- X
- XMETHODDEF void
- Xoutput_init (decompress_info_ptr cinfo)
- X/* This routine should do any setup required */
- X{
- X /* This routine can initialize for output based on the data passed in cinfo.
- X * Useful fields include:
- X * image_width, image_height Pretty obvious, I hope.
- X * data_precision bits per pixel value; typically 8.
- X * out_color_space output colorspace previously requested
- X * color_out_comps number of color components in same
- X * final_out_comps number of components actually output
- X * final_out_comps is 1 if quantize_colors is true, else it is equal to
- X * color_out_comps.
- X *
- X * If you have requested color quantization, the colormap is NOT yet set.
- X * You may wish to defer output initialization until put_color_map is called.
- X */
- X}
- X
- X
- X/*
- X * This routine is called if and only if you have set cinfo->quantize_colors
- X * to TRUE. It is given the selected colormap and can complete any required
- X * initialization. This call will occur after output_init and before any
- X * calls to put_pixel_rows. Note that the colormap pointer is also placed
- X * in a cinfo field, whence it can be used by put_pixel_rows or output_term.
- X * num_colors will be less than or equal to desired_number_of_colors.
- X *
- X * The colormap data is supplied as a 2-D array of JSAMPLEs, indexed as
- X * JSAMPLE colormap[component][indexvalue]
- X * where component runs from 0 to cinfo->color_out_comps-1, and indexvalue
- X * runs from 0 to num_colors-1. Note that this is actually an array of
- X * pointers to arrays rather than a true 2D array, since C does not support
- X * variable-size multidimensional arrays.
- X * JSAMPLE is typically typedef'd as "unsigned char". If you want your code
- X * to be as portable as the JPEG code proper, you should always access JSAMPLE
- X * values with the GETJSAMPLE() macro, which will do the right thing if the
- X * machine has only signed chars.
- X */
- X
- XMETHODDEF void
- Xput_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
- X/* Write the color map */
- X{
- X /* You need not provide this routine if you always set cinfo->quantize_colors
- X * FALSE; but a safer practice is to provide it and have it just print an
- X * error message, like this:
- X */
- X fprintf(stderr, "put_color_map called: there's a bug here somewhere!\n");
- X}
- X
- X
- X/*
- X * This function is called repeatedly, with a few more rows of pixels supplied
- X * on each call. With the current JPEG code, some multiple of 8 rows will be
- X * passed on each call except the last, but it is extremely bad form to depend
- X * on this. You CAN assume num_rows > 0.
- X * The data is supplied in top-to-bottom row order (the standard order within
- X * a JPEG file). If you cannot readily use the data in that order, you'll
- X * need an intermediate array to hold the image. See jwrrle.c for an example
- X * of outputting data in bottom-to-top order.
- X *
- X * The data is supplied as a 3-D array of JSAMPLEs, indexed as
- X * JSAMPLE pixel_data[component][row][column]
- X * where component runs from 0 to cinfo->final_out_comps-1, row runs from 0 to
- X * num_rows-1, and column runs from 0 to cinfo->image_width-1 (column 0 is
- X * left edge of image). Note that this is actually an array of pointers to
- X * pointers to arrays rather than a true 3D array, since C does not support
- X * variable-size multidimensional arrays.
- X * JSAMPLE is typically typedef'd as "unsigned char". If you want your code
- X * to be as portable as the JPEG code proper, you should always access JSAMPLE
- X * values with the GETJSAMPLE() macro, which will do the right thing if the
- X * machine has only signed chars.
- X *
- X * If quantize_colors is true, then there is only one component, and its values
- X * are indexes into the previously supplied colormap. Otherwise the values
- X * are actual data in your selected output colorspace.
- X */
- X
- X
- XMETHODDEF void
- Xput_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
- X/* Write some rows of output data */
- X{
- X /* This example shows how you might write full-color RGB data (3 components)
- X * to an output file in which the data is stored 3 bytes per pixel.
- X */
- X register FILE * outfile = cinfo->output_file;
- X register JSAMPROW ptr0, ptr1, ptr2;
- X register long col;
- X register int row;
- X
- X for (row = 0; row < num_rows; row++) {
- X ptr0 = pixel_data[0][row];
- X ptr1 = pixel_data[1][row];
- X ptr2 = pixel_data[2][row];
- X for (col = 0; col < cinfo->image_width; col++) {
- X putc(GETJSAMPLE(*ptr0), outfile); /* red */
- X ptr0++;
- X putc(GETJSAMPLE(*ptr1), outfile); /* green */
- X ptr1++;
- X putc(GETJSAMPLE(*ptr2), outfile); /* blue */
- X ptr2++;
- X }
- X }
- X}
- X
- X
- XMETHODDEF void
- Xoutput_term (decompress_info_ptr cinfo)
- X/* Finish up at the end of the output */
- X{
- X /* This termination routine may not need to do anything. */
- X /* Note that the JPEG code will only call it during successful exit; */
- X /* if you want it called during error exit, you gotta do that yourself. */
- X}
- X
- X
- X/*
- X * That's it for the routines that deal with writing the output image.
- X * Now we have overall control and parameter selection routines.
- X */
- X
- X
- X/*
- X * This routine gets control after the JPEG file header has been read;
- X * at this point the image size and colorspace are known.
- X * The routine must determine what output routines are to be used, and make
- X * any decompression parameter changes that are desirable. For example,
- X * if it is found that the JPEG file is grayscale, you might want to do
- X * things differently than if it is color. You can also delay setting
- X * quantize_colors and associated options until this point.
- X *
- X * j_d_defaults initializes out_color_space to CS_RGB. If you want grayscale
- X * output you should set out_color_space to CS_GRAYSCALE. Note that you can
- X * force grayscale output from a color JPEG file (though not vice versa).
- X */
- X
- XMETHODDEF void
- Xd_ui_method_selection (decompress_info_ptr cinfo)
- X{
- X /* if grayscale input, force grayscale output; */
- X /* else leave the output colorspace as set by main routine. */
- X if (cinfo->jpeg_color_space == CS_GRAYSCALE)
- X cinfo->out_color_space = CS_GRAYSCALE;
- X
- X /* select output routines */
- X cinfo->methods->output_init = output_init;
- X cinfo->methods->put_color_map = put_color_map;
- X cinfo->methods->put_pixel_rows = put_pixel_rows;
- X cinfo->methods->output_term = output_term;
- X}
- X
- X
- X/*
- X * OK, here is the main function that actually causes everything to happen.
- X * We assume here that the JPEG filename is supplied by the caller of this
- X * routine, and that all decompression parameters can be default values.
- X * The routine returns 1 if successful, 0 if not.
- X */
- X
- XGLOBAL int
- Xread_JPEG_file (char * filename)
- X{
- X /* These three structs contain JPEG parameters and working data.
- X * They must survive for the duration of parameter setup and one
- X * call to jpeg_decompress; typically, making them local data in the
- X * calling routine is the best strategy.
- X */
- X struct Decompress_info_struct cinfo;
- X struct Decompress_methods_struct dc_methods;
- X struct External_methods_struct e_methods;
- X
- X /* Select the input and output files.
- X * In this example we want to open the input file before doing anything else,
- X * so that the setjmp() error recovery below can assume the file is open.
- X * Note that cinfo.output_file is only used if your output handling routines
- X * use it; otherwise, you can just make it NULL.
- X * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
- X * requires it in order to read binary files.
- X */
- X
- X if ((cinfo.input_file = fopen(filename, "rb")) == NULL) {
- X fprintf(stderr, "can't open %s\n", filename);
- X return 0;
- X }
- X
- X cinfo.output_file = NULL; /* if no actual output file involved */
- X
- X /* Initialize the system-dependent method pointers. */
- X cinfo.methods = &dc_methods; /* links to method structs */
- X cinfo.emethods = &e_methods;
- X /* Here we supply our own error handler; compare to use of standard error
- X * handler in the previous write_JPEG_file example.
- X */
- X emethods = &e_methods; /* save struct addr for possible access */
- X e_methods.error_exit = error_exit; /* supply error-exit routine */
- X e_methods.trace_message = trace_message; /* supply trace-message routine */
- X e_methods.trace_level = 0; /* default = no tracing */
- X e_methods.num_warnings = 0; /* no warnings emitted yet */
- X e_methods.first_warning_level = 0; /* display first corrupt-data warning */
- X e_methods.more_warning_level = 3; /* but suppress additional ones */
- X
- X /* prepare setjmp context for possible exit from error_exit */
- X if (setjmp(setjmp_buffer)) {
- X /* If we get here, the JPEG code has signaled an error.
- X * Memory allocation has already been cleaned up (see free_all call in
- X * error_exit), but we need to close the input file before returning.
- X * You might also need to close an output file, etc.
- X */
- X fclose(cinfo.input_file);
- X return 0;
- X }
- X
- X /* Here we use the standard memory manager provided with the JPEG code.
- X * In some cases you might want to replace the memory manager, or at
- X * least the system-dependent part of it, with your own code.
- X */
- X jselmemmgr(&e_methods); /* select std memory allocation routines */
- X /* If the decompressor requires full-image buffers (for two-pass color
- X * quantization or a noninterleaved JPEG file), it will create temporary
- X * files for anything that doesn't fit within the maximum-memory setting.
- X * You can change the default maximum-memory setting by changing
- X * e_methods.max_memory_to_use after jselmemmgr returns.
- X * On some systems you may also need to set up a signal handler to
- X * ensure that temporary files are deleted if the program is interrupted.
- X * (This is most important if you are on MS-DOS and use the jmemdos.c
- X * memory manager back end; it will try to grab extended memory for
- X * temp files, and that space will NOT be freed automatically.)
- X * See jcmain.c or jdmain.c for an example signal handler.
- X */
- X
- X /* Here, set up the pointer to your own routine for post-header-reading
- X * parameter selection. You could also initialize the pointers to the
- X * output data handling routines here, if they are not dependent on the
- X * image type.
- X */
- X dc_methods.d_ui_method_selection = d_ui_method_selection;
- X
- X /* Set up default decompression parameters. */
- X j_d_defaults(&cinfo, TRUE);
- X /* TRUE indicates that an input buffer should be allocated.
- X * In unusual cases you may want to allocate the input buffer yourself;
- X * see jddeflts.c for commentary.
- X */
- X
- X /* At this point you can modify the default parameters set by j_d_defaults
- X * as needed; for example, you can request color quantization or force
- X * grayscale output. See jdmain.c for examples of what you might change.
- X */
- X
- X /* Set up to read a JFIF or baseline-JPEG file. */
- X /* This is the only JPEG file format currently supported. */
- X jselrjfif(&cinfo);
- X
- X /* Here we go! */
- X jpeg_decompress(&cinfo);
- X
- X /* That's it, son. Nothin' else to do, except close files. */
- X /* Here we assume only the input file need be closed. */
- X fclose(cinfo.input_file);
- X
- X /* You might want to test e_methods.num_warnings to see if bad data was
- X * detected. In this example, we just blindly forge ahead.
- X */
- X return 1; /* indicate success */
- X
- X /* Note: if you want to decompress more than one image, we recommend you
- X * repeat this whole routine. You MUST repeat the j_d_defaults()/alter
- X * parameters/jpeg_decompress() sequence, as some data structures allocated
- X * in j_d_defaults are freed upon exit from jpeg_decompress.
- X */
- X}
- END_OF_FILE
- if test 26879 -ne `wc -c <'example.c'`; then
- echo shar: \"'example.c'\" unpacked with wrong size!
- fi
- # end of 'example.c'
- fi
- if test -f 'jcarith.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jcarith.c'\"
- else
- echo shar: Extracting \"'jcarith.c'\" \(1164 characters\)
- sed "s/^X//" >'jcarith.c' <<'END_OF_FILE'
- X/*
- X * jcarith.c
- X *
- X * Copyright (C) 1991, 1992, Thomas G. Lane.
- X * This file is part of the Independent JPEG Group's software.
- X * For conditions of distribution and use, see the accompanying README file.
- X *
- X * This file contains arithmetic entropy encoding routines.
- X * These routines are invoked via the methods entropy_encode,
- X * entropy_encode_init/term, and entropy_optimize.
- X */
- X
- X#include "jinclude.h"
- X
- X#ifdef C_ARITH_CODING_SUPPORTED
- X
- X
- X/*
- X * The arithmetic coding option of the JPEG standard specifies Q-coding,
- X * which is covered by patents held by IBM (and possibly AT&T and Mitsubishi).
- X * At this time it does not appear to be legal for the Independent JPEG
- X * Group to distribute software that implements arithmetic coding.
- X * We have therefore removed arithmetic coding support from the
- X * distributed source code.
- X *
- X * We're not happy about it either.
- X */
- X
- X
- X/*
- X * The method selection routine for arithmetic entropy encoding.
- X */
- X
- XGLOBAL void
- Xjselcarithmetic (compress_info_ptr cinfo)
- X{
- X if (cinfo->arith_code) {
- X ERREXIT(cinfo->emethods, "Sorry, there are legal restrictions on arithmetic coding");
- X }
- X}
- X
- X#endif /* C_ARITH_CODING_SUPPORTED */
- END_OF_FILE
- if test 1164 -ne `wc -c <'jcarith.c'`; then
- echo shar: \"'jcarith.c'\" unpacked with wrong size!
- fi
- # end of 'jcarith.c'
- fi
- if test -f 'jcpipe.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jcpipe.c'\"
- else
- echo shar: Extracting \"'jcpipe.c'\" \(26905 characters\)
- sed "s/^X//" >'jcpipe.c' <<'END_OF_FILE'
- X/*
- X * jcpipe.c
- X *
- X * Copyright (C) 1991, 1992, Thomas G. Lane.
- X * This file is part of the Independent JPEG Group's software.
- X * For conditions of distribution and use, see the accompanying README file.
- X *
- X * This file contains compression pipeline controllers.
- X * These routines are invoked via the c_pipeline_controller method.
- X *
- X * There are four basic pipeline controllers, one for each combination of:
- X * single-scan JPEG file (single component or fully interleaved)
- X * vs. multiple-scan JPEG file (noninterleaved or partially interleaved).
- X *
- X * optimization of entropy encoding parameters
- X * vs. usage of default encoding parameters.
- X *
- X * Note that these conditions determine the needs for "big" arrays:
- X * multiple scans imply a big array for splitting the color components;
- X * entropy encoding optimization needs a big array for the MCU data.
- X *
- X * All but the simplest controller (single-scan, no optimization) can be
- X * compiled out through configuration options, if you need to make a minimal
- X * implementation.
- X */
- X
- X#include "jinclude.h"
- X
- X
- X/*
- X * About the data structures:
- X *
- X * The processing chunk size for downsampling is referred to in this file as
- X * a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
- X * any component after downsampling, or Vmax (max_v_samp_factor) unsubsampled
- X * rows. In an interleaved scan each MCU row contains exactly DCTSIZE row
- X * groups of each component in the scan. In a noninterleaved scan an MCU row
- X * is one row of blocks, which might not be an integral number of row groups;
- X * for convenience we use a buffer of the same size as in interleaved scans,
- X * and process Vk MCU rows in each burst of downsampling.
- X * To provide context for the downsampling step, we have to retain the last
- X * two row groups of the previous MCU row while reading in the next MCU row
- X * (or set of Vk MCU rows). To do this without copying data about, we create
- X * a rather strange data structure. Exactly DCTSIZE+2 row groups of samples
- X * are allocated, but we create two different sets of pointers to this array.
- X * The second set swaps the last two pairs of row groups. By working
- X * alternately with the two sets of pointers, we can access the data in the
- X * desired order.
- X */
- X
- X
- X
- X/*
- X * Utility routines: common code for pipeline controllers
- X */
- X
- XLOCAL void
- Xinterleaved_scan_setup (compress_info_ptr cinfo)
- X/* Compute all derived info for an interleaved (multi-component) scan */
- X/* On entry, cinfo->comps_in_scan and cinfo->cur_comp_info[] are set up */
- X{
- X short ci, mcublks;
- X jpeg_component_info *compptr;
- X
- X if (cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
- X ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
- X
- X cinfo->MCUs_per_row = (cinfo->image_width
- X + cinfo->max_h_samp_factor*DCTSIZE - 1)
- X / (cinfo->max_h_samp_factor*DCTSIZE);
- X
- X cinfo->MCU_rows_in_scan = (cinfo->image_height
- X + cinfo->max_v_samp_factor*DCTSIZE - 1)
- X / (cinfo->max_v_samp_factor*DCTSIZE);
- X
- X cinfo->blocks_in_MCU = 0;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X compptr = cinfo->cur_comp_info[ci];
- X /* for interleaved scan, sampling factors give # of blocks per component */
- X compptr->MCU_width = compptr->h_samp_factor;
- X compptr->MCU_height = compptr->v_samp_factor;
- X compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
- X /* compute physical dimensions of component */
- X compptr->downsampled_width = jround_up(compptr->true_comp_width,
- X (long) (compptr->MCU_width*DCTSIZE));
- X compptr->downsampled_height = jround_up(compptr->true_comp_height,
- X (long) (compptr->MCU_height*DCTSIZE));
- X /* Sanity check */
- X if (compptr->downsampled_width !=
- X (cinfo->MCUs_per_row * (compptr->MCU_width*DCTSIZE)))
- X ERREXIT(cinfo->emethods, "I'm confused about the image width");
- X /* Prepare array describing MCU composition */
- X mcublks = compptr->MCU_blocks;
- X if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
- X ERREXIT(cinfo->emethods, "Sampling factors too large for interleaved scan");
- X while (mcublks-- > 0) {
- X cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
- X }
- X }
- X
- X /* Convert restart specified in rows to actual MCU count. */
- X /* Note that count must fit in 16 bits, so we provide limiting. */
- X if (cinfo->restart_in_rows > 0) {
- X long nominal = cinfo->restart_in_rows * cinfo->MCUs_per_row;
- X cinfo->restart_interval = (UINT16) MIN(nominal, 65535L);
- X }
- X
- X (*cinfo->methods->c_per_scan_method_selection) (cinfo);
- X}
- X
- X
- XLOCAL void
- Xnoninterleaved_scan_setup (compress_info_ptr cinfo)
- X/* Compute all derived info for a noninterleaved (single-component) scan */
- X/* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
- X{
- X jpeg_component_info *compptr = cinfo->cur_comp_info[0];
- X
- X /* for noninterleaved scan, always one block per MCU */
- X compptr->MCU_width = 1;
- X compptr->MCU_height = 1;
- X compptr->MCU_blocks = 1;
- X /* compute physical dimensions of component */
- X compptr->downsampled_width = jround_up(compptr->true_comp_width,
- X (long) DCTSIZE);
- X compptr->downsampled_height = jround_up(compptr->true_comp_height,
- X (long) DCTSIZE);
- X
- X cinfo->MCUs_per_row = compptr->downsampled_width / DCTSIZE;
- X cinfo->MCU_rows_in_scan = compptr->downsampled_height / DCTSIZE;
- X
- X /* Prepare array describing MCU composition */
- X cinfo->blocks_in_MCU = 1;
- X cinfo->MCU_membership[0] = 0;
- X
- X /* Convert restart specified in rows to actual MCU count. */
- X /* Note that count must fit in 16 bits, so we provide limiting. */
- X if (cinfo->restart_in_rows > 0) {
- X long nominal = cinfo->restart_in_rows * cinfo->MCUs_per_row;
- X cinfo->restart_interval = (UINT16) MIN(nominal, 65535L);
- X }
- X
- X (*cinfo->methods->c_per_scan_method_selection) (cinfo);
- X}
- X
- X
- X
- XLOCAL void
- Xalloc_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2],
- X long fullsize_width)
- X/* Create a pre-downsampling data buffer having the desired structure */
- X/* (see comments at head of file) */
- X{
- X short ci, vs, i;
- X
- X vs = cinfo->max_v_samp_factor; /* row group height */
- X
- X /* Get top-level space for array pointers */
- X fullsize_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->num_components * SIZEOF(JSAMPARRAY));
- X fullsize_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->num_components * SIZEOF(JSAMPARRAY));
- X
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X /* Allocate the real storage */
- X fullsize_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
- X (fullsize_width,
- X (long) (vs * (DCTSIZE+2)));
- X /* Create space for the scrambled-order pointers */
- X fullsize_data[1][ci] = (JSAMPARRAY) (*cinfo->emethods->alloc_small)
- X (vs * (DCTSIZE+2) * SIZEOF(JSAMPROW));
- X /* Duplicate the first DCTSIZE-2 row groups */
- X for (i = 0; i < vs * (DCTSIZE-2); i++) {
- X fullsize_data[1][ci][i] = fullsize_data[0][ci][i];
- X }
- X /* Copy the last four row groups in swapped order */
- X for (i = 0; i < vs * 2; i++) {
- X fullsize_data[1][ci][vs*DCTSIZE + i] = fullsize_data[0][ci][vs*(DCTSIZE-2) + i];
- X fullsize_data[1][ci][vs*(DCTSIZE-2) + i] = fullsize_data[0][ci][vs*DCTSIZE + i];
- X }
- X }
- X}
- X
- X
- X#if 0 /* this routine not currently needed */
- X
- XLOCAL void
- Xfree_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2])
- X/* Release a sampling buffer created by alloc_sampling_buffer */
- X{
- X short ci;
- X
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X /* Free the real storage */
- X (*cinfo->emethods->free_small_sarray) (fullsize_data[0][ci]);
- X /* Free the scrambled-order pointers */
- X (*cinfo->emethods->free_small) ((void *) fullsize_data[1][ci]);
- X }
- X
- X /* Free the top-level space */
- X (*cinfo->emethods->free_small) ((void *) fullsize_data[0]);
- X (*cinfo->emethods->free_small) ((void *) fullsize_data[1]);
- X}
- X
- X#endif
- X
- X
- XLOCAL void
- Xdownsample (compress_info_ptr cinfo,
- X JSAMPIMAGE fullsize_data, JSAMPIMAGE sampled_data,
- X long fullsize_width,
- X short above, short current, short below, short out)
- X/* Do downsampling of a single row group (of each component). */
- X/* above, current, below are indexes of row groups in fullsize_data; */
- X/* out is the index of the target row group in sampled_data. */
- X/* Special case: above, below can be -1 to indicate top, bottom of image. */
- X{
- X jpeg_component_info *compptr;
- X JSAMPARRAY above_ptr, below_ptr;
- X JSAMPROW dummy[MAX_SAMP_FACTOR]; /* for downsample expansion at top/bottom */
- X short ci, vs, i;
- X
- X vs = cinfo->max_v_samp_factor; /* row group height */
- X
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X compptr = & cinfo->comp_info[ci];
- X
- X if (above >= 0)
- X above_ptr = fullsize_data[ci] + above * vs;
- X else {
- X /* Top of image: make a dummy above-context with copies of 1st row */
- X /* We assume current=0 in this case */
- X for (i = 0; i < vs; i++)
- X dummy[i] = fullsize_data[ci][0];
- X above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
- X }
- X
- X if (below >= 0)
- X below_ptr = fullsize_data[ci] + below * vs;
- X else {
- X /* Bot of image: make a dummy below-context with copies of last row */
- X for (i = 0; i < vs; i++)
- X dummy[i] = fullsize_data[ci][(current+1)*vs-1];
- X below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
- X }
- X
- X (*cinfo->methods->downsample[ci])
- X (cinfo, (int) ci,
- X fullsize_width, (int) vs,
- X compptr->downsampled_width, (int) compptr->v_samp_factor,
- X above_ptr,
- X fullsize_data[ci] + current * vs,
- X below_ptr,
- X sampled_data[ci] + out * compptr->v_samp_factor);
- X }
- X}
- X
- X
- X/* These variables are initialized by the pipeline controller for use by
- X * MCU_output_catcher.
- X * To avoid a lot of row-pointer overhead, we cram as many MCUs into each
- X * row of whole_scan_MCUs as we can get without exceeding 32Kbytes per row.
- X * NOTE: the "arbitrary" constant here must not exceed MAX_ALLOC_CHUNK
- X * defined in jmemsys.h, which is 64K-epsilon in most DOS implementations.
- X */
- X
- X#define MAX_WHOLE_ROW_BLOCKS ((int) (32768L / SIZEOF(JBLOCK))) /* max blocks/row */
- X
- Xstatic big_barray_ptr whole_scan_MCUs; /* Big array for saving the MCUs */
- Xstatic int MCUs_in_big_row; /* # of MCUs in each row of whole_scan_MCUs */
- Xstatic long next_whole_row; /* next row to access in whole_scan_MCUs */
- Xstatic int next_MCU_index; /* next MCU in current row */
- X
- X
- XMETHODDEF void
- XMCU_output_catcher (compress_info_ptr cinfo, JBLOCK *MCU_data)
- X/* Output method for siphoning off extract_MCUs output into a big array */
- X{
- X static JBLOCKARRAY rowptr;
- X
- X if (next_MCU_index >= MCUs_in_big_row) {
- X rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
- X next_whole_row, TRUE);
- X next_whole_row++;
- X next_MCU_index = 0;
- X }
- X
- X /*
- X * note that on 80x86, the cast applied to MCU_data implies
- X * near to far pointer conversion.
- X */
- X jcopy_block_row((JBLOCKROW) MCU_data,
- X rowptr[0] + next_MCU_index * cinfo->blocks_in_MCU,
- X (long) cinfo->blocks_in_MCU);
- X next_MCU_index++;
- X}
- X
- X
- XMETHODDEF void
- Xdump_scan_MCUs (compress_info_ptr cinfo, MCU_output_method_ptr output_method)
- X/* Dump the MCUs saved in whole_scan_MCUs to the output method. */
- X/* The method may be either the entropy encoder or some routine supplied */
- X/* by the entropy optimizer. */
- X{
- X /* On an 80x86 machine, the entropy encoder expects the passed data block
- X * to be in NEAR memory (for performance reasons), so we have to copy it
- X * back from the big array to a local array. On less brain-damaged CPUs
- X * we needn't do that.
- X */
- X#ifdef NEED_FAR_POINTERS
- X JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
- X#endif
- X long mcurow, mcuindex, next_row;
- X int next_index;
- X JBLOCKARRAY rowptr = NULL; /* init only to suppress compiler complaint */
- X
- X next_row = 0;
- X next_index = MCUs_in_big_row;
- X
- X for (mcurow = 0; mcurow < cinfo->MCU_rows_in_scan; mcurow++) {
- X (*cinfo->methods->progress_monitor) (cinfo, mcurow,
- X cinfo->MCU_rows_in_scan);
- X for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
- X if (next_index >= MCUs_in_big_row) {
- X rowptr = (*cinfo->emethods->access_big_barray) (whole_scan_MCUs,
- X next_row, FALSE);
- X next_row++;
- X next_index = 0;
- X }
- X#ifdef NEED_FAR_POINTERS
- X jcopy_block_row(rowptr[0] + next_index * cinfo->blocks_in_MCU,
- X (JBLOCKROW) MCU_data, /* casts near to far pointer! */
- X (long) cinfo->blocks_in_MCU);
- X (*output_method) (cinfo, MCU_data);
- X#else
- X (*output_method) (cinfo, rowptr[0] + next_index * cinfo->blocks_in_MCU);
- X#endif
- X next_index++;
- X }
- X }
- X
- X cinfo->completed_passes++;
- X}
- X
- X
- X
- X/*
- X * Compression pipeline controller used for single-scan files
- X * with no optimization of entropy parameters.
- X */
- X
- XMETHODDEF void
- Xsingle_ccontroller (compress_info_ptr cinfo)
- X{
- X int rows_in_mem; /* # of sample rows in full-size buffers */
- X long fullsize_width; /* # of samples per row in full-size buffers */
- X long cur_pixel_row; /* counts # of pixel rows processed */
- X long mcu_rows_output; /* # of MCU rows actually emitted */
- X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
- X /* Work buffer for pre-downsampling data (see comments at head of file) */
- X JSAMPIMAGE fullsize_data[2];
- X /* Work buffer for downsampled data */
- X JSAMPIMAGE sampled_data;
- X int rows_this_time;
- X short ci, whichss, i;
- X
- X /* Prepare for single scan containing all components */
- X if (cinfo->num_components > MAX_COMPS_IN_SCAN)
- X ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
- X cinfo->comps_in_scan = cinfo->num_components;
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
- X }
- X if (cinfo->comps_in_scan == 1) {
- X noninterleaved_scan_setup(cinfo);
- X /* Vk block rows constitute the same number of MCU rows */
- X mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
- X } else {
- X interleaved_scan_setup(cinfo);
- X /* in an interleaved scan, one MCU row contains Vk block rows */
- X mcu_rows_per_loop = 1;
- X }
- X cinfo->total_passes++;
- X
- X /* Compute dimensions of full-size pixel buffers */
- X /* Note these are the same whether interleaved or not. */
- X rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
- X fullsize_width = jround_up(cinfo->image_width,
- X (long) (cinfo->max_h_samp_factor * DCTSIZE));
- X
- X /* Allocate working memory: */
- X /* fullsize_data is sample data before downsampling */
- X alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
- X /* sampled_data is sample data after downsampling */
- X sampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->num_components * SIZEOF(JSAMPARRAY));
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X sampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
- X (cinfo->comp_info[ci].downsampled_width,
- X (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
- X }
- X
- X /* Tell the memory manager to instantiate big arrays.
- X * We don't need any big arrays in this controller,
- X * but some other module (like the input file reader) may need one.
- X */
- X (*cinfo->emethods->alloc_big_arrays)
- X ((long) 0, /* no more small sarrays */
- X (long) 0, /* no more small barrays */
- X (long) 0); /* no more "medium" objects */
- X
- X /* Initialize output file & do per-scan object init */
- X
- X (*cinfo->methods->write_scan_header) (cinfo);
- X cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
- X (*cinfo->methods->entropy_encode_init) (cinfo);
- X (*cinfo->methods->downsample_init) (cinfo);
- X (*cinfo->methods->extract_init) (cinfo);
- X
- X /* Loop over input image: rows_in_mem pixel rows are processed per loop */
- X
- X mcu_rows_output = 0;
- X whichss = 1; /* arrange to start with fullsize_data[0] */
- X
- X for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
- X cur_pixel_row += rows_in_mem) {
- X (*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
- X cinfo->image_height);
- X
- X whichss ^= 1; /* switch to other fullsize_data buffer */
- X
- X /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
- X /* Then we have exactly DCTSIZE row groups for downsampling. */
- X rows_this_time = (int) MIN((long) rows_in_mem,
- X cinfo->image_height - cur_pixel_row);
- X
- X (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
- X fullsize_data[whichss]);
- X (*cinfo->methods->edge_expand) (cinfo,
- X cinfo->image_width, rows_this_time,
- X fullsize_width, rows_in_mem,
- X fullsize_data[whichss]);
- X
- X /* Downsample the data (all components) */
- X /* First time through is a special case */
- X
- X if (cur_pixel_row) {
- X /* Downsample last row group of previous set */
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
- X (short) (DCTSIZE-1));
- X /* and dump the previous set's downsampled data */
- X (*cinfo->methods->extract_MCUs) (cinfo, sampled_data,
- X mcu_rows_per_loop,
- X cinfo->methods->entropy_encode);
- X mcu_rows_output += mcu_rows_per_loop;
- X /* Downsample first row group of this set */
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) (DCTSIZE+1), (short) 0, (short) 1,
- X (short) 0);
- X } else {
- X /* Downsample first row group with dummy above-context */
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) (-1), (short) 0, (short) 1,
- X (short) 0);
- X }
- X /* Downsample second through next-to-last row groups of this set */
- X for (i = 1; i <= DCTSIZE-2; i++) {
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) (i-1), (short) i, (short) (i+1),
- X (short) i);
- X }
- X } /* end of outer loop */
- X
- X /* Downsample the last row group with dummy below-context */
- X /* Note whichss points to last buffer side used */
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
- X (short) (DCTSIZE-1));
- X /* Dump the remaining data (may be less than full height if uninterleaved) */
- X (*cinfo->methods->extract_MCUs) (cinfo, sampled_data,
- X (int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
- X cinfo->methods->entropy_encode);
- X
- X /* Finish output file */
- X (*cinfo->methods->extract_term) (cinfo);
- X (*cinfo->methods->downsample_term) (cinfo);
- X (*cinfo->methods->entropy_encode_term) (cinfo);
- X (*cinfo->methods->write_scan_trailer) (cinfo);
- X cinfo->completed_passes++;
- X
- X /* Release working memory */
- X /* (no work -- we let free_all release what's needful) */
- X}
- X
- X
- X/*
- X * Compression pipeline controller used for single-scan files
- X * with optimization of entropy parameters.
- X */
- X
- X#ifdef ENTROPY_OPT_SUPPORTED
- X
- XMETHODDEF void
- Xsingle_eopt_ccontroller (compress_info_ptr cinfo)
- X{
- X int rows_in_mem; /* # of sample rows in full-size buffers */
- X long fullsize_width; /* # of samples per row in full-size buffers */
- X long cur_pixel_row; /* counts # of pixel rows processed */
- X long mcu_rows_output; /* # of MCU rows actually emitted */
- X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
- X /* Work buffer for pre-downsampling data (see comments at head of file) */
- X JSAMPIMAGE fullsize_data[2];
- X /* Work buffer for downsampled data */
- X JSAMPIMAGE sampled_data;
- X int rows_this_time;
- X int blocks_in_big_row;
- X short ci, whichss, i;
- X
- X /* Prepare for single scan containing all components */
- X if (cinfo->num_components > MAX_COMPS_IN_SCAN)
- X ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
- X cinfo->comps_in_scan = cinfo->num_components;
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
- X }
- X if (cinfo->comps_in_scan == 1) {
- X noninterleaved_scan_setup(cinfo);
- X /* Vk block rows constitute the same number of MCU rows */
- X mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
- X } else {
- X interleaved_scan_setup(cinfo);
- X /* in an interleaved scan, one MCU row contains Vk block rows */
- X mcu_rows_per_loop = 1;
- X }
- X cinfo->total_passes += 2; /* entropy encoder must add # passes it uses */
- X
- X /* Compute dimensions of full-size pixel buffers */
- X /* Note these are the same whether interleaved or not. */
- X rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
- X fullsize_width = jround_up(cinfo->image_width,
- X (long) (cinfo->max_h_samp_factor * DCTSIZE));
- X
- X /* Allocate working memory: */
- X /* fullsize_data is sample data before downsampling */
- X alloc_sampling_buffer(cinfo, fullsize_data, fullsize_width);
- X /* sampled_data is sample data after downsampling */
- X sampled_data = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->num_components * SIZEOF(JSAMPARRAY));
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X sampled_data[ci] = (*cinfo->emethods->alloc_small_sarray)
- X (cinfo->comp_info[ci].downsampled_width,
- X (long) (cinfo->comp_info[ci].v_samp_factor * DCTSIZE));
- X }
- X
- X /* Figure # of MCUs to be packed in a row of whole_scan_MCUs */
- X MCUs_in_big_row = MAX_WHOLE_ROW_BLOCKS / cinfo->blocks_in_MCU;
- X blocks_in_big_row = MCUs_in_big_row * cinfo->blocks_in_MCU;
- X
- X /* Request a big array: whole_scan_MCUs saves the MCU data for the scan */
- X whole_scan_MCUs = (*cinfo->emethods->request_big_barray)
- X ((long) blocks_in_big_row,
- X (long) (cinfo->MCUs_per_row * cinfo->MCU_rows_in_scan
- X + MCUs_in_big_row-1) / MCUs_in_big_row,
- X 1L); /* unit height is 1 row */
- X
- X next_whole_row = 0; /* init output ptr for MCU_output_catcher */
- X next_MCU_index = MCUs_in_big_row; /* forces access on first call! */
- X
- X /* Tell the memory manager to instantiate big arrays */
- X (*cinfo->emethods->alloc_big_arrays)
- X ((long) 0, /* no more small sarrays */
- X (long) 0, /* no more small barrays */
- X (long) 0); /* no more "medium" objects */
- X
- X /* Do per-scan object init */
- X
- X (*cinfo->methods->downsample_init) (cinfo);
- X (*cinfo->methods->extract_init) (cinfo);
- X
- X /* Loop over input image: rows_in_mem pixel rows are processed per loop */
- X /* MCU data goes into whole_scan_MCUs, not to the entropy encoder */
- X
- X mcu_rows_output = 0;
- X whichss = 1; /* arrange to start with fullsize_data[0] */
- X
- X for (cur_pixel_row = 0; cur_pixel_row < cinfo->image_height;
- X cur_pixel_row += rows_in_mem) {
- X (*cinfo->methods->progress_monitor) (cinfo, cur_pixel_row,
- X cinfo->image_height);
- X
- X whichss ^= 1; /* switch to other fullsize_data buffer */
- X
- X /* Obtain rows_this_time pixel rows and expand to rows_in_mem rows. */
- X /* Then we have exactly DCTSIZE row groups for downsampling. */
- X rows_this_time = (int) MIN((long) rows_in_mem,
- X cinfo->image_height - cur_pixel_row);
- X
- X (*cinfo->methods->get_sample_rows) (cinfo, rows_this_time,
- X fullsize_data[whichss]);
- X (*cinfo->methods->edge_expand) (cinfo,
- X cinfo->image_width, rows_this_time,
- X fullsize_width, rows_in_mem,
- X fullsize_data[whichss]);
- X
- X /* Downsample the data (all components) */
- X /* First time through is a special case */
- X
- X if (cur_pixel_row) {
- X /* Downsample last row group of previous set */
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
- X (short) (DCTSIZE-1));
- X /* and dump the previous set's downsampled data */
- X (*cinfo->methods->extract_MCUs) (cinfo, sampled_data,
- X mcu_rows_per_loop,
- X MCU_output_catcher);
- X mcu_rows_output += mcu_rows_per_loop;
- X /* Downsample first row group of this set */
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) (DCTSIZE+1), (short) 0, (short) 1,
- X (short) 0);
- X } else {
- X /* Downsample first row group with dummy above-context */
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) (-1), (short) 0, (short) 1,
- X (short) 0);
- X }
- X /* Downsample second through next-to-last row groups of this set */
- X for (i = 1; i <= DCTSIZE-2; i++) {
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) (i-1), (short) i, (short) (i+1),
- X (short) i);
- X }
- X } /* end of outer loop */
- X
- X /* Downsample the last row group with dummy below-context */
- X /* Note whichss points to last buffer side used */
- X downsample(cinfo, fullsize_data[whichss], sampled_data, fullsize_width,
- X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
- X (short) (DCTSIZE-1));
- X /* Dump the remaining data (may be less than full height if uninterleaved) */
- X (*cinfo->methods->extract_MCUs) (cinfo, sampled_data,
- X (int) (cinfo->MCU_rows_in_scan - mcu_rows_output),
- X MCU_output_catcher);
- X
- X /* Clean up after that stuff, then find the optimal entropy parameters */
- X
- X (*cinfo->methods->extract_term) (cinfo);
- X (*cinfo->methods->downsample_term) (cinfo);
- X
- X cinfo->completed_passes++;
- X
- X (*cinfo->methods->entropy_optimize) (cinfo, dump_scan_MCUs);
- X
- X /* Emit scan to output file */
- X /* Note: we can't do write_scan_header until entropy parameters are set! */
- X
- X (*cinfo->methods->write_scan_header) (cinfo);
- X cinfo->methods->entropy_output = cinfo->methods->write_jpeg_data;
- X (*cinfo->methods->entropy_encode_init) (cinfo);
- X dump_scan_MCUs(cinfo, cinfo->methods->entropy_encode);
- X (*cinfo->methods->entropy_encode_term) (cinfo);
- X (*cinfo->methods->write_scan_trailer) (cinfo);
- X
- X /* Release working memory */
- X /* (no work -- we let free_all release what's needful) */
- X}
- X
- X#endif /* ENTROPY_OPT_SUPPORTED */
- X
- X
- X/*
- X * Compression pipeline controller used for multiple-scan files
- X * with no optimization of entropy parameters.
- X */
- X
- X#ifdef C_MULTISCAN_FILES_SUPPORTED
- X
- XMETHODDEF void
- Xmulti_ccontroller (compress_info_ptr cinfo)
- X{
- X ERREXIT(cinfo->emethods, "Not implemented yet");
- X}
- X
- X#endif /* C_MULTISCAN_FILES_SUPPORTED */
- X
- X
- X/*
- X * Compression pipeline controller used for multiple-scan files
- X * with optimization of entropy parameters.
- X */
- X
- X#ifdef C_MULTISCAN_FILES_SUPPORTED
- X#ifdef ENTROPY_OPT_SUPPORTED
- X
- XMETHODDEF void
- Xmulti_eopt_ccontroller (compress_info_ptr cinfo)
- X{
- X ERREXIT(cinfo->emethods, "Not implemented yet");
- X}
- X
- X#endif /* ENTROPY_OPT_SUPPORTED */
- X#endif /* C_MULTISCAN_FILES_SUPPORTED */
- X
- X
- X/*
- X * The method selection routine for compression pipeline controllers.
- X */
- X
- XGLOBAL void
- Xjselcpipeline (compress_info_ptr cinfo)
- X{
- X if (cinfo->interleave || cinfo->num_components == 1) {
- X /* single scan needed */
- X#ifdef ENTROPY_OPT_SUPPORTED
- X if (cinfo->optimize_coding)
- X cinfo->methods->c_pipeline_controller = single_eopt_ccontroller;
- X else
- X#endif
- X cinfo->methods->c_pipeline_controller = single_ccontroller;
- X } else {
- X /* multiple scans needed */
- X#ifdef C_MULTISCAN_FILES_SUPPORTED
- X#ifdef ENTROPY_OPT_SUPPORTED
- X if (cinfo->optimize_coding)
- X cinfo->methods->c_pipeline_controller = multi_eopt_ccontroller;
- X else
- X#endif
- X cinfo->methods->c_pipeline_controller = multi_ccontroller;
- X#else
- X ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
- X#endif
- X }
- X}
- END_OF_FILE
- if test 26905 -ne `wc -c <'jcpipe.c'`; then
- echo shar: \"'jcpipe.c'\" unpacked with wrong size!
- fi
- # end of 'jcpipe.c'
- fi
- echo shar: End of archive 8 \(of 18\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 18 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-