home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-16 | 57.3 KB | 1,602 lines |
- Newsgroups: comp.sources.misc
- From: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Subject: v34i059: jpeg - JPEG image compression, Part05/18
- Message-ID: <1992Dec17.041700.23384@sparky.imd.sterling.com>
- X-Md4-Signature: ece542448522b9ffc18afbf6155d885a
- Date: Thu, 17 Dec 1992 04:17:00 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Posting-number: Volume 34, Issue 59
- Archive-name: jpeg/part05
- 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: ansi2knr.c jdpipe.c makvms.opt
- # Wrapped by kent@sparky on Wed Dec 16 20:52:26 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 5 (of 18)."'
- if test -f 'ansi2knr.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ansi2knr.c'\"
- else
- echo shar: Extracting \"'ansi2knr.c'\" \(16228 characters\)
- sed "s/^X//" >'ansi2knr.c' <<'END_OF_FILE'
- X/* Copyright (C) 1989, 1991 Aladdin Enterprises. All rights reserved.
- X Distributed by Free Software Foundation, Inc.
- X
- XThis file is part of Ghostscript.
- X
- XGhostscript is distributed in the hope that it will be useful, but
- XWITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- Xto anyone for the consequences of using it or for whether it serves any
- Xparticular purpose or works at all, unless he says so in writing. Refer
- Xto the Ghostscript General Public License for full details.
- X
- XEveryone is granted permission to copy, modify and redistribute
- XGhostscript, but only under the conditions described in the Ghostscript
- XGeneral Public License. A copy of this license is supposed to have been
- Xgiven to you along with Ghostscript so you can know your rights and
- Xresponsibilities. It should be in a file named COPYING. Among other
- Xthings, the copyright notice and this notice must be preserved on all
- Xcopies. */
- X
- X/*
- X---------- Here is the GhostScript file COPYING, referred to above ----------
- X----- These terms do NOT apply to the JPEG software itself; see README ------
- X
- X GHOSTSCRIPT GENERAL PUBLIC LICENSE
- X (Clarified 11 Feb 1988)
- X
- X Copyright (C) 1988 Richard M. Stallman
- X Everyone is permitted to copy and distribute verbatim copies of this
- X license, but changing it is not allowed. You can also use this wording
- X to make the terms for other programs.
- X
- X The license agreements of most software companies keep you at the
- Xmercy of those companies. By contrast, our general public license is
- Xintended to give everyone the right to share Ghostscript. To make sure
- Xthat you get the rights we want you to have, we need to make
- Xrestrictions that forbid anyone to deny you these rights or to ask you
- Xto surrender the rights. Hence this license agreement.
- X
- X Specifically, we want to make sure that you have the right to give
- Xaway copies of Ghostscript, that you receive source code or else can get
- Xit if you want it, that you can change Ghostscript or use pieces of it
- Xin new free programs, and that you know you can do these things.
- X
- X To make sure that everyone has such rights, we have to forbid you to
- Xdeprive anyone else of these rights. For example, if you distribute
- Xcopies of Ghostscript, you must give the recipients all the rights that
- Xyou have. You must make sure that they, too, receive or can get the
- Xsource code. And you must tell them their rights.
- X
- X Also, for our own protection, we must make certain that everyone finds
- Xout that there is no warranty for Ghostscript. If Ghostscript is
- Xmodified by someone else and passed on, we want its recipients to know
- Xthat what they have is not what we distributed, so that any problems
- Xintroduced by others will not reflect on our reputation.
- X
- X Therefore we (Richard M. Stallman and the Free Software Foundation,
- XInc.) make the following terms which say what you must do to be allowed
- Xto distribute or change Ghostscript.
- X
- X
- X COPYING POLICIES
- X
- X 1. You may copy and distribute verbatim copies of Ghostscript source
- Xcode as you receive it, in any medium, provided that you conspicuously
- Xand appropriately publish on each copy a valid copyright and license
- Xnotice "Copyright (C) 1989 Aladdin Enterprises. All rights reserved.
- XDistributed by Free Software Foundation, Inc." (or with whatever year is
- Xappropriate); keep intact the notices on all files that refer to this
- XLicense Agreement and to the absence of any warranty; and give any other
- Xrecipients of the Ghostscript program a copy of this License Agreement
- Xalong with the program. You may charge a distribution fee for the
- Xphysical act of transferring a copy.
- X
- X 2. You may modify your copy or copies of Ghostscript or any portion of
- Xit, and copy and distribute such modifications under the terms of
- XParagraph 1 above, provided that you also do the following:
- X
- X a) cause the modified files to carry prominent notices stating
- X that you changed the files and the date of any change; and
- X
- X b) cause the whole of any work that you distribute or publish,
- X that in whole or in part contains or is a derivative of Ghostscript
- X or any part thereof, to be licensed at no charge to all third
- X parties on terms identical to those contained in this License
- X Agreement (except that you may choose to grant more extensive
- X warranty protection to some or all third parties, at your option).
- X
- X c) You may charge a distribution fee for the physical act of
- X transferring a copy, and you may at your option offer warranty
- X protection in exchange for a fee.
- X
- XMere aggregation of another unrelated program with this program (or its
- Xderivative) on a volume of a storage or distribution medium does not bring
- Xthe other program under the scope of these terms.
- X
- X 3. You may copy and distribute Ghostscript (or a portion or derivative
- Xof it, under Paragraph 2) in object code or executable form under the
- Xterms of Paragraphs 1 and 2 above provided that you also do one of the
- Xfollowing:
- X
- X a) accompany it with the complete corresponding machine-readable
- X source code, which must be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X b) accompany it with a written offer, valid for at least three
- X years, to give any third party free (except for a nominal
- X shipping charge) a complete machine-readable copy of the
- X corresponding source code, to be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X c) accompany it with the information you received as to where the
- X corresponding source code may be obtained. (This alternative is
- X allowed only for noncommercial distribution and only if you
- X received the program in object code or executable form alone.)
- X
- XFor an executable file, complete source code means all the source code for
- Xall modules it contains; but, as a special exception, it need not include
- Xsource code for modules which are standard libraries that accompany the
- Xoperating system on which the executable file runs.
- X
- X 4. You may not copy, sublicense, distribute or transfer Ghostscript
- Xexcept as expressly provided under this License Agreement. Any attempt
- Xotherwise to copy, sublicense, distribute or transfer Ghostscript is
- Xvoid and your rights to use the program under this License agreement
- Xshall be automatically terminated. However, parties who have received
- Xcomputer software programs from you with this License Agreement will not
- Xhave their licenses terminated so long as such parties remain in full
- Xcompliance.
- X
- X 5. If you wish to incorporate parts of Ghostscript into other free
- Xprograms whose distribution conditions are different, write to the Free
- XSoftware Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not
- Xyet worked out a simple rule that can be stated here, but we will often
- Xpermit this. We will be guided by the two goals of preserving the free
- Xstatus of all derivatives of our free software and of promoting the
- Xsharing and reuse of software.
- X
- XYour comments and suggestions about our licensing policies and our
- Xsoftware are welcome! Please contact the Free Software Foundation,
- XInc., 675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
- X
- X NO WARRANTY
- X
- X BECAUSE GHOSTSCRIPT IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
- XNO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
- XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD
- XM. STALLMAN, ALADDIN ENTERPRISES, L. PETER DEUTSCH, AND/OR OTHER PARTIES
- XPROVIDE GHOSTSCRIPT "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
- XEXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- XWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
- XENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF GHOSTSCRIPT IS WITH
- XYOU. SHOULD GHOSTSCRIPT PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
- XNECESSARY SERVICING, REPAIR OR CORRECTION.
- X
- X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
- XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., L. PETER DEUTSCH, ALADDIN
- XENTERPRISES, AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE
- XGHOSTSCRIPT AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING
- XANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR
- XCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
- X(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
- XINACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE
- XPROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GHOSTSCRIPT, EVEN IF YOU
- XHAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM
- XBY ANY OTHER PARTY.
- X-------------------- End of file COPYING ------------------------------
- X*/
- X
- X
- X/* ansi2knr.c */
- X/* Convert ANSI function declarations to K&R syntax */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X
- X#ifdef BSD
- X#include <strings.h>
- X#define strchr index
- X#else
- X#ifdef VMS
- X extern char *strcat(), *strchr(), *strcpy(), *strupr();
- X extern int strcmp(), strlen(), strncmp();
- X#else
- X#include <string.h>
- X#endif
- X#endif
- X
- X#ifdef MSDOS
- X#include <malloc.h>
- X#else
- X#ifdef VMS
- X extern char *malloc();
- X extern void free();
- X#else
- X extern char *malloc();
- X extern int free();
- X#endif
- X#endif
- X
- X/* Usage:
- X ansi2knr input_file output_file
- X * If no output_file is supplied, output goes to stdout.
- X * There are no error messages.
- X *
- X * ansi2knr recognizes functions by seeing a non-keyword identifier
- X * at the left margin, followed by a left parenthesis,
- X * with a right parenthesis as the last character on the line.
- X * It will recognize a multi-line header if the last character
- X * on each line but the last is a left parenthesis or comma.
- X * These algorithms ignore whitespace and comments, except that
- X * the function name must be the first thing on the line.
- X * The following constructs will confuse it:
- X - Any other construct that starts at the left margin and
- X follows the above syntax (such as a macro or function call).
- X - Macros that tinker with the syntax of the function header.
- X */
- X
- X/* Scanning macros */
- X#define isidchar(ch) (isalnum(ch) || (ch) == '_')
- X#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_')
- X
- Xmain(argc, argv)
- X int argc;
- X char *argv[];
- X{ FILE *in, *out;
- X#define bufsize 5000 /* arbitrary size */
- X char *buf;
- X char *line;
- X switch ( argc )
- X {
- X default:
- X printf("Usage: ansi2knr input_file [output_file]\n");
- X exit(0);
- X case 2:
- X out = stdout; break;
- X case 3:
- X out = fopen(argv[2], "w");
- X if ( out == NULL )
- X { fprintf(stderr, "Cannot open %s\n", argv[2]);
- X exit(1);
- X }
- X }
- X in = fopen(argv[1], "r");
- X if ( in == NULL )
- X { fprintf(stderr, "Cannot open %s\n", argv[1]);
- X exit(1);
- X }
- X fprintf(out, "#line 1 \"%s\"\n", argv[1]);
- X buf = malloc(bufsize);
- X line = buf;
- X while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
- X { switch ( test1(buf) )
- X {
- X case 1: /* a function */
- X convert1(buf, out);
- X break;
- X case -1: /* maybe the start of a function */
- X line = buf + strlen(buf);
- X if ( line != buf + (bufsize - 1) ) /* overflow check */
- X continue;
- X /* falls through */
- X default: /* not a function */
- X fputs(buf, out);
- X break;
- X }
- X line = buf;
- X }
- X if ( line != buf ) fputs(buf, out);
- X free(buf);
- X fclose(out);
- X fclose(in);
- X return 0;
- X}
- X
- X/* Skip over space and comments, in either direction. */
- Xchar *
- Xskipspace(p, dir)
- X register char *p;
- X register int dir; /* 1 for forward, -1 for backward */
- X{ for ( ; ; )
- X { while ( isspace(*p) ) p += dir;
- X if ( !(*p == '/' && p[dir] == '*') ) break;
- X p += dir; p += dir;
- X while ( !(*p == '*' && p[dir] == '/') )
- X { if ( *p == 0 ) return p; /* multi-line comment?? */
- X p += dir;
- X }
- X p += dir; p += dir;
- X }
- X return p;
- X}
- X
- X/*
- X * Write blanks over part of a string.
- X */
- Xint
- Xwriteblanks(start, end)
- X char *start;
- X char *end;
- X{ char *p;
- X for ( p = start; p < end; p++ ) *p = ' ';
- X return 0;
- X}
- X
- X/*
- X * Test whether the string in buf is a function definition.
- X * The string may contain and/or end with a newline.
- X * Return as follows:
- X * 0 - definitely not a function definition;
- X * 1 - definitely a function definition;
- X * -1 - may be the beginning of a function definition,
- X * append another line and look again.
- X */
- Xint
- Xtest1(buf)
- X char *buf;
- X{ register char *p = buf;
- X char *bend;
- X char *endfn;
- X int contin;
- X if ( !isidfirstchar(*p) )
- X return 0; /* no name at left margin */
- X bend = skipspace(buf + strlen(buf) - 1, -1);
- X switch ( *bend )
- X {
- X case ')': contin = 1; break;
- X case '(':
- X case ',': contin = -1; break;
- X default: return 0; /* not a function */
- X }
- X while ( isidchar(*p) ) p++;
- X endfn = p;
- X p = skipspace(p, 1);
- X if ( *p++ != '(' )
- X return 0; /* not a function */
- X p = skipspace(p, 1);
- X if ( *p == ')' )
- X return 0; /* no parameters */
- X /* Check that the apparent function name isn't a keyword. */
- X /* We only need to check for keywords that could be followed */
- X /* by a left parenthesis (which, unfortunately, is most of them). */
- X { static char *words[] =
- X { "asm", "auto", "case", "char", "const", "double",
- X "extern", "float", "for", "if", "int", "long",
- X "register", "return", "short", "signed", "sizeof",
- X "static", "switch", "typedef", "unsigned",
- X "void", "volatile", "while", 0
- X };
- X char **key = words;
- X char *kp;
- X int len = endfn - buf;
- X while ( (kp = *key) != 0 )
- X { if ( strlen(kp) == len && !strncmp(kp, buf, len) )
- X return 0; /* name is a keyword */
- X key++;
- X }
- X }
- X return contin;
- X}
- X
- Xint
- Xconvert1(buf, out)
- X char *buf;
- X FILE *out;
- X{ char *endfn = strchr(buf, '(') + 1;
- X register char *p;
- X char **breaks;
- X unsigned num_breaks = 2; /* for testing */
- X char **btop;
- X char **bp;
- X char **ap;
- Xtop: p = endfn;
- X breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
- X if ( breaks == 0 )
- X { /* Couldn't allocate break table, give up */
- X fprintf(stderr, "Unable to allocate break table!\n");
- X fputs(buf, out);
- X return -1;
- X }
- X btop = breaks + num_breaks * 2 - 2;
- X bp = breaks;
- X /* Parse the argument list */
- X do
- X { int level = 0;
- X char *end = NULL;
- X if ( bp >= btop )
- X { /* Filled up break table. */
- X /* Allocate a bigger one and start over. */
- X free((char *)breaks);
- X num_breaks <<= 1;
- X goto top;
- X }
- X *bp++ = p;
- X /* Find the end of the argument */
- X for ( ; end == NULL; p++ )
- X { switch(*p)
- X {
- X case ',': if ( !level ) end = p; break;
- X case '(': level++; break;
- X case ')': if ( --level < 0 ) end = p; break;
- X case '/': p = skipspace(p, 1) - 1; break;
- X default: ;
- X }
- X }
- X p--; /* back up over terminator */
- X /* Find the name being declared. */
- X /* This is complicated because of procedure and */
- X /* array modifiers. */
- X for ( ; ; )
- X { p = skipspace(p - 1, -1);
- X switch ( *p )
- X {
- X case ']': /* skip array dimension(s) */
- X case ')': /* skip procedure args OR name */
- X { int level = 1;
- X while ( level )
- X switch ( *--p )
- X {
- X case ']': case ')': level++; break;
- X case '[': case '(': level--; break;
- X case '/': p = skipspace(p, -1) + 1; break;
- X default: ;
- X }
- X }
- X if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
- X { /* We found the name being declared */
- X while ( !isidfirstchar(*p) )
- X p = skipspace(p, 1) + 1;
- X goto found;
- X }
- X break;
- X default: goto found;
- X }
- X }
- Xfound: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
- X { p++;
- X if ( bp == breaks + 1 ) /* sole argument */
- X writeblanks(breaks[0], p);
- X else
- X writeblanks(bp[-1] - 1, p);
- X bp--;
- X }
- X else
- X { while ( isidchar(*p) ) p--;
- X *bp++ = p+1;
- X }
- X p = end;
- X }
- X while ( *p++ == ',' );
- X *bp = p;
- X /* Make a special check for 'void' arglist */
- X if ( bp == breaks+2 )
- X { p = skipspace(breaks[0], 1);
- X if ( !strncmp(p, "void", 4) )
- X { p = skipspace(p+4, 1);
- X if ( p == breaks[2] - 1 )
- X { bp = breaks; /* yup, pretend arglist is empty */
- X writeblanks(breaks[0], p + 1);
- X }
- X }
- X }
- X /* Put out the function name */
- X p = buf;
- X while ( p != endfn ) putc(*p, out), p++;
- X /* Put out the declaration */
- X for ( ap = breaks+1; ap < bp; ap += 2 )
- X { p = *ap;
- X while ( isidchar(*p) ) putc(*p, out), p++;
- X if ( ap < bp - 1 ) fputs(", ", out);
- X }
- X fputs(") ", out);
- X /* Put out the argument declarations */
- X for ( ap = breaks+2; ap <= bp; ap += 2 ) (*ap)[-1] = ';';
- X fputs(breaks[0], out);
- X free((char *)breaks);
- X return 0;
- X}
- END_OF_FILE
- if test 16228 -ne `wc -c <'ansi2knr.c'`; then
- echo shar: \"'ansi2knr.c'\" unpacked with wrong size!
- fi
- # end of 'ansi2knr.c'
- fi
- if test -f 'jdpipe.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jdpipe.c'\"
- else
- echo shar: Extracting \"'jdpipe.c'\" \(38159 characters\)
- sed "s/^X//" >'jdpipe.c' <<'END_OF_FILE'
- X/*
- X * jdpipe.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 decompression pipeline controllers.
- X * These routines are invoked via the d_pipeline_controller method.
- X *
- X * There are two basic pipeline controllers. The simpler one handles a
- X * single-scan JPEG file (single component or fully interleaved) with no
- X * color quantization or 1-pass quantization. In this case, the file can
- X * be processed in one top-to-bottom pass. The more complex controller is
- X * used when 2-pass color quantization is requested and/or the JPEG file
- X * has multiple scans (noninterleaved or partially interleaved). In this
- X * case, the entire image must be buffered up in a "big" array.
- X *
- X * If you need to make a minimal implementation, the more complex controller
- X * can be compiled out by disabling the appropriate configuration options.
- X * We don't recommend this, since then you can't handle all legal JPEG files.
- X */
- X
- X#include "jinclude.h"
- X
- X
- X#ifdef D_MULTISCAN_FILES_SUPPORTED /* wish we could assume ANSI's defined() */
- X#define NEED_COMPLEX_CONTROLLER
- X#else
- X#ifdef QUANT_2PASS_SUPPORTED
- X#define NEED_COMPLEX_CONTROLLER
- X#endif
- X#endif
- X
- X
- X/*
- X * About the data structures:
- X *
- X * The processing chunk size for upsampling 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 while downsampled, 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 * therefore, we read in Vk MCU rows to obtain the same amount of data as we'd
- X * have in an interleaved scan.
- X * To provide context for the upsampling 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 * Cross-block smoothing also needs context above and below the "current" row.
- X * Since this is an optional feature, I've implemented it in a way that is
- X * much simpler but requires more than the minimum amount of memory. We
- X * simply allocate three extra MCU rows worth of coefficient blocks and use
- X * them to "read ahead" one MCU row in the file. For a typical 1000-pixel-wide
- X * image with 2x2,1x1,1x1 sampling, each MCU row is about 50Kb; an 80x86
- X * machine may be unable to apply cross-block smoothing to wider images.
- X */
- X
- X
- X/*
- X * These variables are logically local to the pipeline controller,
- X * but we make them static so that scan_big_image can use them
- X * without having to pass them through the quantization routines.
- X */
- X
- Xstatic int rows_in_mem; /* # of sample rows in full-size buffers */
- X/* Work buffer for data being passed to output module. */
- X/* This has color_out_comps components if not quantizing, */
- X/* but only one component when quantizing. */
- Xstatic JSAMPIMAGE output_workspace;
- X
- X#ifdef NEED_COMPLEX_CONTROLLER
- X/* Full-size image array holding upsampled, but not color-processed data. */
- Xstatic big_sarray_ptr *fullsize_image;
- Xstatic JSAMPIMAGE fullsize_ptrs; /* workspace for access_big_sarray() result */
- X#endif
- X
- X
- X/*
- X * Utility routines: common code for pipeline controllers
- X */
- X
- XLOCAL void
- Xinterleaved_scan_setup (decompress_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 (*cinfo->methods->d_per_scan_method_selection) (cinfo);
- X}
- X
- X
- XLOCAL void
- Xnoninterleaved_scan_setup (decompress_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 (*cinfo->methods->d_per_scan_method_selection) (cinfo);
- X}
- X
- X
- X
- XLOCAL JSAMPIMAGE
- Xalloc_sampimage (decompress_info_ptr cinfo,
- X int num_comps, long num_rows, long num_cols)
- X/* Allocate an in-memory sample image (all components same size) */
- X{
- X JSAMPIMAGE image;
- X int ci;
- X
- X image = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (num_comps * SIZEOF(JSAMPARRAY));
- X for (ci = 0; ci < num_comps; ci++) {
- X image[ci] = (*cinfo->emethods->alloc_small_sarray) (num_cols, num_rows);
- X }
- X return image;
- X}
- X
- X
- X#if 0 /* this routine not currently needed */
- X
- XLOCAL void
- Xfree_sampimage (decompress_info_ptr cinfo, JSAMPIMAGE image, int num_comps)
- X/* Release a sample image created by alloc_sampimage */
- X{
- X int ci;
- X
- X for (ci = 0; ci < num_comps; ci++) {
- X (*cinfo->emethods->free_small_sarray) (image[ci]);
- X }
- X (*cinfo->emethods->free_small) ((void *) image);
- X}
- X
- X#endif
- X
- X
- XLOCAL JBLOCKIMAGE
- Xalloc_MCU_row (decompress_info_ptr cinfo)
- X/* Allocate one MCU row's worth of coefficient blocks */
- X{
- X JBLOCKIMAGE image;
- X int ci;
- X
- X image = (JBLOCKIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->comps_in_scan * SIZEOF(JBLOCKARRAY));
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X image[ci] = (*cinfo->emethods->alloc_small_barray)
- X (cinfo->cur_comp_info[ci]->downsampled_width / DCTSIZE,
- X (long) cinfo->cur_comp_info[ci]->MCU_height);
- X }
- X return image;
- X}
- X
- X
- X#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
- X
- XLOCAL void
- Xfree_MCU_row (decompress_info_ptr cinfo, JBLOCKIMAGE image)
- X/* Release a coefficient block array created by alloc_MCU_row */
- X{
- X int ci;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X (*cinfo->emethods->free_small_barray) (image[ci]);
- X }
- X (*cinfo->emethods->free_small) ((void *) image);
- X}
- X
- X#endif
- X
- X
- XLOCAL void
- Xalloc_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE sampled_data[2])
- X/* Create a downsampled-data buffer having the desired structure */
- X/* (see comments at head of file) */
- X{
- X short ci, vs, i;
- X
- X /* Get top-level space for array pointers */
- X sampled_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->comps_in_scan * SIZEOF(JSAMPARRAY));
- X sampled_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->comps_in_scan * SIZEOF(JSAMPARRAY));
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X vs = cinfo->cur_comp_info[ci]->v_samp_factor; /* row group height */
- X /* Allocate the real storage */
- X sampled_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
- X (cinfo->cur_comp_info[ci]->downsampled_width,
- X (long) (vs * (DCTSIZE+2)));
- X /* Create space for the scrambled-order pointers */
- X sampled_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 sampled_data[1][ci][i] = sampled_data[0][ci][i];
- X }
- X /* Copy the last four row groups in swapped order */
- X for (i = 0; i < vs * 2; i++) {
- X sampled_data[1][ci][vs*DCTSIZE + i] = sampled_data[0][ci][vs*(DCTSIZE-2) + i];
- X sampled_data[1][ci][vs*(DCTSIZE-2) + i] = sampled_data[0][ci][vs*DCTSIZE + i];
- X }
- X }
- X}
- X
- X
- X#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
- X
- XLOCAL void
- Xfree_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE sampled_data[2])
- X/* Release a sampling buffer created by alloc_sampling_buffer */
- X{
- X short ci;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X /* Free the real storage */
- X (*cinfo->emethods->free_small_sarray) (sampled_data[0][ci]);
- X /* Free the scrambled-order pointers */
- X (*cinfo->emethods->free_small) ((void *) sampled_data[1][ci]);
- X }
- X
- X /* Free the top-level space */
- X (*cinfo->emethods->free_small) ((void *) sampled_data[0]);
- X (*cinfo->emethods->free_small) ((void *) sampled_data[1]);
- X}
- X
- X#endif
- X
- X
- X/*
- X * Several decompression processes need to range-limit values to the range
- X * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
- X * due to noise introduced by quantization, roundoff error, etc. These
- X * processes are inner loops and need to be as fast as possible. On most
- X * machines, particularly CPUs with pipelines or instruction prefetch,
- X * a (range-check-less) C table lookup
- X * x = sample_range_limit[x];
- X * is faster than explicit tests
- X * if (x < 0) x = 0;
- X * else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
- X * These processes all use a common table prepared by the routine below.
- X *
- X * The table will work correctly for x within MAXJSAMPLE+1 of the legal
- X * range. This is a much wider range than is needed for most cases,
- X * but the wide range is handy for color quantization.
- X * Note that the table is allocated in near data space on PCs; it's small
- X * enough and used often enough to justify this.
- X */
- X
- XLOCAL void
- Xprepare_range_limit_table (decompress_info_ptr cinfo)
- X/* Allocate and fill in the sample_range_limit table */
- X{
- X JSAMPLE * table;
- X int i;
- X
- X table = (JSAMPLE *) (*cinfo->emethods->alloc_small)
- X (3 * (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
- X cinfo->sample_range_limit = table + (MAXJSAMPLE+1);
- X for (i = 0; i <= MAXJSAMPLE; i++) {
- X table[i] = 0; /* sample_range_limit[x] = 0 for x<0 */
- X table[i+(MAXJSAMPLE+1)] = (JSAMPLE) i; /* sample_range_limit[x] = x */
- X table[i+(MAXJSAMPLE+1)*2] = MAXJSAMPLE; /* x beyond MAXJSAMPLE */
- X }
- X}
- X
- X
- XLOCAL void
- Xduplicate_row (JSAMPARRAY image_data,
- X long num_cols, int source_row, int num_rows)
- X/* Duplicate the source_row at source_row+1 .. source_row+num_rows */
- X/* This happens only at the bottom of the image, */
- X/* so it needn't be super-efficient */
- X{
- X register int row;
- X
- X for (row = 1; row <= num_rows; row++) {
- X jcopy_sample_rows(image_data, source_row, image_data, source_row + row,
- X 1, num_cols);
- X }
- X}
- X
- X
- XLOCAL void
- Xexpand (decompress_info_ptr cinfo,
- X JSAMPIMAGE sampled_data, JSAMPIMAGE fullsize_data,
- X long fullsize_width,
- X short above, short current, short below, short out)
- X/* Do upsampling expansion of a single row group (of each component). */
- X/* above, current, below are indexes of row groups in sampled_data; */
- X/* out is the index of the target row group in fullsize_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 for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X compptr = cinfo->cur_comp_info[ci];
- X vs = compptr->v_samp_factor; /* row group height */
- X
- X if (above >= 0)
- X above_ptr = sampled_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] = sampled_data[ci][0];
- X above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
- X }
- X
- X if (below >= 0)
- X below_ptr = sampled_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] = sampled_data[ci][(current+1)*vs-1];
- X below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
- X }
- X
- X (*cinfo->methods->upsample[ci])
- X (cinfo, (int) ci,
- X compptr->downsampled_width, (int) vs,
- X fullsize_width, (int) cinfo->max_v_samp_factor,
- X above_ptr,
- X sampled_data[ci] + current * vs,
- X below_ptr,
- X fullsize_data[ci] + out * cinfo->max_v_samp_factor);
- X }
- X}
- X
- X
- XLOCAL void
- Xemit_1pass (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE fullsize_data,
- X JSAMPARRAY dummy)
- X/* Do color processing and output of num_rows full-size rows. */
- X/* This is not used when doing 2-pass color quantization. */
- X/* The dummy argument simply lets this be called via scan_big_image. */
- X{
- X if (cinfo->quantize_colors) {
- X (*cinfo->methods->color_quantize) (cinfo, num_rows, fullsize_data,
- X output_workspace[0]);
- X } else {
- X (*cinfo->methods->color_convert) (cinfo, num_rows, cinfo->image_width,
- X fullsize_data, output_workspace);
- X }
- X
- X (*cinfo->methods->put_pixel_rows) (cinfo, num_rows, output_workspace);
- X}
- X
- X
- X/*
- X * Support routines for complex controller.
- X */
- X
- X#ifdef NEED_COMPLEX_CONTROLLER
- X
- XMETHODDEF void
- Xscan_big_image (decompress_info_ptr cinfo, quantize_method_ptr quantize_method)
- X/* Apply quantize_method to entire image stored in fullsize_image[]. */
- X/* This is the "iterator" routine used by the 2-pass color quantizer. */
- X/* We also use it directly in some cases. */
- X{
- X long pixel_rows_output;
- X short ci;
- X
- X for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height;
- X pixel_rows_output += rows_in_mem) {
- X (*cinfo->methods->progress_monitor) (cinfo, pixel_rows_output,
- X cinfo->image_height);
- X /* Realign the big buffers */
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
- X (fullsize_image[ci], pixel_rows_output, FALSE);
- X }
- X /* Let the quantizer have its way with the data.
- X * Note that output_workspace is simply workspace for the quantizer;
- X * when it's ready to output, it must call put_pixel_rows itself.
- X */
- X (*quantize_method) (cinfo,
- X (int) MIN((long) rows_in_mem,
- X cinfo->image_height - pixel_rows_output),
- X fullsize_ptrs, output_workspace[0]);
- X }
- X
- X cinfo->completed_passes++;
- X}
- X
- X#endif /* NEED_COMPLEX_CONTROLLER */
- X
- X
- X/*
- X * Support routines for cross-block smoothing.
- X */
- X
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X
- X
- XLOCAL void
- Xsmooth_mcu_row (decompress_info_ptr cinfo,
- X JBLOCKIMAGE above, JBLOCKIMAGE input, JBLOCKIMAGE below,
- X JBLOCKIMAGE output)
- X/* Apply cross-block smoothing to one MCU row's worth of coefficient blocks. */
- X/* above,below are NULL if at top/bottom of image. */
- X{
- X jpeg_component_info *compptr;
- X short ci, ri, last;
- X JBLOCKROW prev;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X compptr = cinfo->cur_comp_info[ci];
- X last = compptr->MCU_height - 1;
- X
- X if (above == NULL)
- X prev = NULL;
- X else
- X prev = above[ci][last];
- X
- X for (ri = 0; ri < last; ri++) {
- X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
- X prev, input[ci][ri], input[ci][ri+1],
- X output[ci][ri]);
- X prev = input[ci][ri];
- X }
- X
- X if (below == NULL)
- X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
- X prev, input[ci][last], (JBLOCKROW) NULL,
- X output[ci][last]);
- X else
- X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
- X prev, input[ci][last], below[ci][0],
- X output[ci][last]);
- X }
- X}
- X
- X
- XLOCAL void
- Xget_smoothed_row (decompress_info_ptr cinfo, JBLOCKIMAGE coeff_data,
- X JBLOCKIMAGE bsmooth[3], int * whichb, long cur_mcu_row)
- X/* Get an MCU row of coefficients, applying cross-block smoothing. */
- X/* The output row is placed in coeff_data. bsmooth and whichb hold */
- X/* working state, and cur_row is needed to check for image top/bottom. */
- X/* This routine just takes care of the buffering logic. */
- X{
- X int prev, cur, next;
- X
- X /* Special case for top of image: need to pre-fetch a row & init whichb */
- X if (cur_mcu_row == 0) {
- X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[0]);
- X if (cinfo->MCU_rows_in_scan > 1) {
- X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[1]);
- X smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], bsmooth[1],
- X coeff_data);
- X } else {
- X smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], (JBLOCKIMAGE) NULL,
- X coeff_data);
- X }
- X *whichb = 1; /* points to next bsmooth[] element to use */
- X return;
- X }
- X
- X cur = *whichb; /* set up references */
- X prev = (cur == 0 ? 2 : cur - 1);
- X next = (cur == 2 ? 0 : cur + 1);
- X *whichb = next; /* advance whichb for next time */
- X
- X /* Special case for bottom of image: don't read another row */
- X if (cur_mcu_row >= cinfo->MCU_rows_in_scan - 1) {
- X smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], (JBLOCKIMAGE) NULL,
- X coeff_data);
- X return;
- X }
- X
- X /* Normal case: read ahead a new row, smooth the one I got before */
- X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[next]);
- X smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], bsmooth[next],
- X coeff_data);
- X}
- X
- X
- X#endif /* BLOCK_SMOOTHING_SUPPORTED */
- X
- X
- X
- X/*
- X * Decompression pipeline controller used for single-scan files
- X * without 2-pass color quantization.
- X */
- X
- XMETHODDEF void
- Xsimple_dcontroller (decompress_info_ptr cinfo)
- X{
- X long fullsize_width; /* # of samples per row in full-size buffers */
- X long cur_mcu_row; /* counts # of MCU rows processed */
- X long pixel_rows_output; /* # of pixel rows actually emitted */
- X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
- X /* Work buffer for dequantized coefficients (IDCT input) */
- X JBLOCKIMAGE coeff_data;
- X /* Work buffer for cross-block smoothing input */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X JBLOCKIMAGE bsmooth[3]; /* this is optional */
- X int whichb;
- X#endif
- X /* Work buffer for downsampled image data (see comments at head of file) */
- X JSAMPIMAGE sampled_data[2];
- X /* Work buffer for upsampled data */
- X JSAMPIMAGE fullsize_data;
- X int whichss, ri;
- X short i;
- 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 /* Prepare for single scan containing all components */
- X if (cinfo->comps_in_scan == 1) {
- X noninterleaved_scan_setup(cinfo);
- X /* Need to read Vk MCU rows to obtain Vk block 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 provides Vk block rows */
- X mcu_rows_per_loop = 1;
- X }
- X cinfo->total_passes++;
- X
- X /* Allocate working memory: */
- X /* coeff_data holds a single MCU row of coefficient blocks */
- X coeff_data = alloc_MCU_row(cinfo);
- X /* if doing cross-block smoothing, need extra space for its input */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing) {
- X bsmooth[0] = alloc_MCU_row(cinfo);
- X bsmooth[1] = alloc_MCU_row(cinfo);
- X bsmooth[2] = alloc_MCU_row(cinfo);
- X }
- X#endif
- X /* sampled_data is sample data before upsampling */
- X alloc_sampling_buffer(cinfo, sampled_data);
- X /* fullsize_data is sample data after upsampling */
- X fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components,
- X (long) rows_in_mem, fullsize_width);
- X /* output_workspace is the color-processed data */
- X output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
- X (long) rows_in_mem, fullsize_width);
- X prepare_range_limit_table(cinfo);
- 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 output file writer) 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 /* NB: if quantizer needs any "medium" size objects, it must get them */
- X /* at color_quant_init time */
- X
- X /* Initialize to read scan data */
- X
- X (*cinfo->methods->entropy_decode_init) (cinfo);
- X (*cinfo->methods->upsample_init) (cinfo);
- X (*cinfo->methods->disassemble_init) (cinfo);
- X
- X /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
- X
- X pixel_rows_output = 0;
- X whichss = 1; /* arrange to start with sampled_data[0] */
- X
- X for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
- X cur_mcu_row += mcu_rows_per_loop) {
- X (*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
- X cinfo->MCU_rows_in_scan);
- X
- X whichss ^= 1; /* switch to other downsampled-data buffer */
- X
- X /* Obtain v_samp_factor block rows of each component in the scan. */
- X /* This is a single MCU row if interleaved, multiple MCU rows if not. */
- X /* In the noninterleaved case there might be fewer than v_samp_factor */
- X /* block rows remaining; if so, pad with copies of the last pixel row */
- X /* so that upsampling doesn't have to treat it as a special case. */
- X
- X for (ri = 0; ri < mcu_rows_per_loop; ri++) {
- X if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
- X /* OK to actually read an MCU row. */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing)
- X get_smoothed_row(cinfo, coeff_data,
- X bsmooth, &whichb, cur_mcu_row + ri);
- X else
- X#endif
- X (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
- X
- X (*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
- X sampled_data[whichss],
- X ri * DCTSIZE);
- X } else {
- X /* Need to pad out with copies of the last downsampled row. */
- X /* This can only happen if there is just one component. */
- X duplicate_row(sampled_data[whichss][0],
- X cinfo->cur_comp_info[0]->downsampled_width,
- X ri * DCTSIZE - 1, DCTSIZE);
- X }
- X }
- X
- X /* Upsample the data */
- X /* First time through is a special case */
- X
- X if (cur_mcu_row) {
- X /* Expand last row group of previous set */
- X expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
- X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
- X (short) (DCTSIZE-1));
- X /* and dump the previous set's expanded data */
- X emit_1pass (cinfo, rows_in_mem, fullsize_data, (JSAMPARRAY) NULL);
- X pixel_rows_output += rows_in_mem;
- X /* Expand first row group of this set */
- X expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
- X (short) (DCTSIZE+1), (short) 0, (short) 1,
- X (short) 0);
- X } else {
- X /* Expand first row group with dummy above-context */
- X expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
- X (short) (-1), (short) 0, (short) 1,
- X (short) 0);
- X }
- X /* Expand second through next-to-last row groups of this set */
- X for (i = 1; i <= DCTSIZE-2; i++) {
- X expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
- X (short) (i-1), (short) i, (short) (i+1),
- X (short) i);
- X }
- X } /* end of outer loop */
- X
- X /* Expand the last row group with dummy below-context */
- X /* Note whichss points to last buffer side used */
- X expand(cinfo, sampled_data[whichss], fullsize_data, fullsize_width,
- X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
- X (short) (DCTSIZE-1));
- X /* and dump the remaining data (may be less than full height) */
- X emit_1pass (cinfo, (int) (cinfo->image_height - pixel_rows_output),
- X fullsize_data, (JSAMPARRAY) NULL);
- X
- X /* Clean up after the scan */
- X (*cinfo->methods->disassemble_term) (cinfo);
- X (*cinfo->methods->upsample_term) (cinfo);
- X (*cinfo->methods->entropy_decode_term) (cinfo);
- X (*cinfo->methods->read_scan_trailer) (cinfo);
- X cinfo->completed_passes++;
- X
- X /* Verify that we've seen the whole input file */
- X if ((*cinfo->methods->read_scan_header) (cinfo))
- X WARNMS(cinfo->emethods, "Didn't expect more than one scan");
- X
- X /* Release working memory */
- X /* (no work -- we let free_all release what's needful) */
- X}
- X
- X
- X/*
- X * Decompression pipeline controller used for multiple-scan files
- X * and/or 2-pass color quantization.
- X *
- X * The current implementation places the "big" buffer at the stage of
- X * upsampled, non-color-processed data. This is the only place that
- X * makes sense when doing 2-pass quantization. For processing multiple-scan
- X * files without 2-pass quantization, it would be possible to develop another
- X * controller that buffers the downsampled data instead, thus reducing the size
- X * of the temp files (by about a factor of 2 in typical cases). However,
- X * our present upsampling logic is dependent on the assumption that
- X * upsampling occurs during a scan, so it's much easier to do the
- X * enlargement as the JPEG file is read. This also simplifies life for the
- X * memory manager, which would otherwise have to deal with overlapping
- X * access_big_sarray() requests.
- X * At present it appears that most JPEG files will be single-scan,
- X * so it doesn't seem worthwhile to worry about this optimization.
- X */
- X
- X#ifdef NEED_COMPLEX_CONTROLLER
- X
- XMETHODDEF void
- Xcomplex_dcontroller (decompress_info_ptr cinfo)
- X{
- X long fullsize_width; /* # of samples per row in full-size buffers */
- X long cur_mcu_row; /* counts # of MCU rows processed */
- X long pixel_rows_output; /* # of pixel rows actually emitted */
- X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
- X /* Work buffer for dequantized coefficients (IDCT input) */
- X JBLOCKIMAGE coeff_data;
- X /* Work buffer for cross-block smoothing input */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X JBLOCKIMAGE bsmooth[3]; /* this is optional */
- X int whichb;
- X#endif
- X /* Work buffer for downsampled image data (see comments at head of file) */
- X JSAMPIMAGE sampled_data[2];
- X int whichss, ri;
- X short ci, i;
- X boolean single_scan;
- 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 all working memory that doesn't depend on scan info */
- X /* output_workspace is the color-processed data */
- X output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
- X (long) rows_in_mem, fullsize_width);
- X prepare_range_limit_table(cinfo);
- X
- X /* Get a big image: fullsize_image is sample data after upsampling. */
- X fullsize_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small)
- X (cinfo->num_components * SIZEOF(big_sarray_ptr));
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X fullsize_image[ci] = (*cinfo->emethods->request_big_sarray)
- X (fullsize_width,
- X jround_up(cinfo->image_height, (long) rows_in_mem),
- X (long) rows_in_mem);
- X }
- X /* Also get an area for pointers to currently accessible chunks */
- X fullsize_ptrs = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->num_components * SIZEOF(JSAMPARRAY));
- X
- X /* Tell the memory manager to instantiate big arrays */
- X (*cinfo->emethods->alloc_big_arrays)
- X /* extra sarray space is for downsampled-data buffers: */
- X ((long) (fullsize_width /* max width in samples */
- X * cinfo->max_v_samp_factor*(DCTSIZE+2) /* max height */
- X * cinfo->num_components), /* max components per scan */
- X /* extra barray space is for MCU-row buffers: */
- X (long) ((fullsize_width / DCTSIZE) /* max width in blocks */
- X * cinfo->max_v_samp_factor /* max height */
- X * cinfo->num_components /* max components per scan */
- X * (cinfo->do_block_smoothing ? 4 : 1)),/* how many of these we need */
- X /* no extra "medium"-object space */
- X (long) 0);
- X /* NB: if quantizer needs any "medium" size objects, it must get them */
- X /* at color_quant_init time */
- X
- X /* If file is single-scan, we can do color quantization prescan on-the-fly
- X * during the scan (we must be doing 2-pass quantization, else this method
- X * would not have been selected). If it is multiple scans, we have to make
- X * a separate pass after we've collected all the components. (We could save
- X * some I/O by doing CQ prescan during the last scan, but the extra logic
- X * doesn't seem worth the trouble.)
- X */
- X
- X single_scan = (cinfo->comps_in_scan == cinfo->num_components);
- X
- X /* Account for passes needed (color quantizer adds its passes separately).
- X * If multiscan file, we guess that each component has its own scan,
- X * and increment completed_passes by the number of components in the scan.
- X */
- X
- X if (single_scan)
- X cinfo->total_passes++; /* the single scan */
- X else {
- X cinfo->total_passes += cinfo->num_components; /* guessed # of scans */
- X if (cinfo->two_pass_quantize)
- X cinfo->total_passes++; /* account for separate CQ prescan pass */
- X }
- X if (! cinfo->two_pass_quantize)
- X cinfo->total_passes++; /* count output pass unless quantizer does it */
- X
- X /* Loop over scans in file */
- X
- X do {
- X
- X /* Prepare for this scan */
- X if (cinfo->comps_in_scan == 1) {
- X noninterleaved_scan_setup(cinfo);
- X /* Need to read Vk MCU rows to obtain Vk block 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 provides Vk block rows */
- X mcu_rows_per_loop = 1;
- X }
- X
- X /* Allocate scan-local working memory */
- X /* coeff_data holds a single MCU row of coefficient blocks */
- X coeff_data = alloc_MCU_row(cinfo);
- X /* if doing cross-block smoothing, need extra space for its input */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing) {
- X bsmooth[0] = alloc_MCU_row(cinfo);
- X bsmooth[1] = alloc_MCU_row(cinfo);
- X bsmooth[2] = alloc_MCU_row(cinfo);
- X }
- X#endif
- X /* sampled_data is sample data before upsampling */
- X alloc_sampling_buffer(cinfo, sampled_data);
- X
- X /* line up the big buffers for components in this scan */
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
- X (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
- X (long) 0, TRUE);
- X }
- X
- X /* Initialize to read scan data */
- X
- X (*cinfo->methods->entropy_decode_init) (cinfo);
- X (*cinfo->methods->upsample_init) (cinfo);
- X (*cinfo->methods->disassemble_init) (cinfo);
- X
- X /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
- X
- X pixel_rows_output = 0;
- X whichss = 1; /* arrange to start with sampled_data[0] */
- X
- X for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
- X cur_mcu_row += mcu_rows_per_loop) {
- X (*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
- X cinfo->MCU_rows_in_scan);
- X
- X whichss ^= 1; /* switch to other downsampled-data buffer */
- X
- X /* Obtain v_samp_factor block rows of each component in the scan. */
- X /* This is a single MCU row if interleaved, multiple MCU rows if not. */
- X /* In the noninterleaved case there might be fewer than v_samp_factor */
- X /* block rows remaining; if so, pad with copies of the last pixel row */
- X /* so that upsampling doesn't have to treat it as a special case. */
- X
- X for (ri = 0; ri < mcu_rows_per_loop; ri++) {
- X if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
- X /* OK to actually read an MCU row. */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing)
- X get_smoothed_row(cinfo, coeff_data,
- X bsmooth, &whichb, cur_mcu_row + ri);
- X else
- X#endif
- X (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
- X
- X (*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
- X sampled_data[whichss],
- X ri * DCTSIZE);
- X } else {
- X /* Need to pad out with copies of the last downsampled row. */
- X /* This can only happen if there is just one component. */
- X duplicate_row(sampled_data[whichss][0],
- X cinfo->cur_comp_info[0]->downsampled_width,
- X ri * DCTSIZE - 1, DCTSIZE);
- X }
- X }
- X
- X /* Upsample the data */
- X /* First time through is a special case */
- X
- X if (cur_mcu_row) {
- X /* Expand last row group of previous set */
- X expand(cinfo, sampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
- X (short) (DCTSIZE-1));
- X /* If single scan, can do color quantization prescan on-the-fly */
- X if (single_scan)
- X (*cinfo->methods->color_quant_prescan) (cinfo, rows_in_mem,
- X fullsize_ptrs,
- X output_workspace[0]);
- X /* Realign the big buffers */
- X pixel_rows_output += rows_in_mem;
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
- X (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
- X pixel_rows_output, TRUE);
- X }
- X /* Expand first row group of this set */
- X expand(cinfo, sampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) (DCTSIZE+1), (short) 0, (short) 1,
- X (short) 0);
- X } else {
- X /* Expand first row group with dummy above-context */
- X expand(cinfo, sampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) (-1), (short) 0, (short) 1,
- X (short) 0);
- X }
- X /* Expand second through next-to-last row groups of this set */
- X for (i = 1; i <= DCTSIZE-2; i++) {
- X expand(cinfo, sampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) (i-1), (short) i, (short) (i+1),
- X (short) i);
- X }
- X } /* end of loop over scan's data */
- X
- X /* Expand the last row group with dummy below-context */
- X /* Note whichss points to last buffer side used */
- X expand(cinfo, sampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
- X (short) (DCTSIZE-1));
- X /* If single scan, finish on-the-fly color quantization prescan */
- X if (single_scan)
- X (*cinfo->methods->color_quant_prescan) (cinfo,
- X (int) (cinfo->image_height - pixel_rows_output),
- X fullsize_ptrs, output_workspace[0]);
- X
- X /* Clean up after the scan */
- X (*cinfo->methods->disassemble_term) (cinfo);
- X (*cinfo->methods->upsample_term) (cinfo);
- X (*cinfo->methods->entropy_decode_term) (cinfo);
- X (*cinfo->methods->read_scan_trailer) (cinfo);
- X if (single_scan)
- X cinfo->completed_passes++;
- X else
- X cinfo->completed_passes += cinfo->comps_in_scan;
- X
- X /* Release scan-local working memory */
- X free_MCU_row(cinfo, coeff_data);
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing) {
- X free_MCU_row(cinfo, bsmooth[0]);
- X free_MCU_row(cinfo, bsmooth[1]);
- X free_MCU_row(cinfo, bsmooth[2]);
- X }
- X#endif
- X free_sampling_buffer(cinfo, sampled_data);
- X
- X /* Repeat if there is another scan */
- X } while ((!single_scan) && (*cinfo->methods->read_scan_header) (cinfo));
- X
- X if (single_scan) {
- X /* If we expected just one scan, make SURE there's just one */
- X if ((*cinfo->methods->read_scan_header) (cinfo))
- X WARNMS(cinfo->emethods, "Didn't expect more than one scan");
- X /* We did the CQ prescan on-the-fly, so we are all set. */
- X } else {
- X /* For multiple-scan file, do the CQ prescan as a separate pass. */
- X /* The main reason why prescan is passed the output_workspace is */
- X /* so that we can use scan_big_image to call it... */
- X if (cinfo->two_pass_quantize)
- X scan_big_image(cinfo, cinfo->methods->color_quant_prescan);
- X }
- X
- X /* Now that we've collected the data, do color processing and output */
- X if (cinfo->two_pass_quantize)
- X (*cinfo->methods->color_quant_doit) (cinfo, scan_big_image);
- X else
- X scan_big_image(cinfo, emit_1pass);
- X
- X /* Release working memory */
- X /* (no work -- we let free_all release what's needful) */
- X}
- X
- X#endif /* NEED_COMPLEX_CONTROLLER */
- X
- X
- X/*
- X * The method selection routine for decompression pipeline controllers.
- X * Note that at this point we've already read the JPEG header and first SOS,
- X * so we can tell whether the input is one scan or not.
- X */
- X
- XGLOBAL void
- Xjseldpipeline (decompress_info_ptr cinfo)
- X{
- X /* simplify subsequent tests on color quantization */
- X if (! cinfo->quantize_colors)
- X cinfo->two_pass_quantize = FALSE;
- X
- X if (cinfo->comps_in_scan == cinfo->num_components) {
- X /* It's a single-scan file */
- X if (cinfo->two_pass_quantize) {
- X#ifdef NEED_COMPLEX_CONTROLLER
- X cinfo->methods->d_pipeline_controller = complex_dcontroller;
- X#else
- X ERREXIT(cinfo->emethods, "2-pass quantization support was not compiled");
- X#endif
- X } else
- X cinfo->methods->d_pipeline_controller = simple_dcontroller;
- X } else {
- X /* It's a multiple-scan file */
- X#ifdef NEED_COMPLEX_CONTROLLER
- X cinfo->methods->d_pipeline_controller = complex_dcontroller;
- X#else
- X ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
- X#endif
- X }
- X}
- END_OF_FILE
- if test 38159 -ne `wc -c <'jdpipe.c'`; then
- echo shar: \"'jdpipe.c'\" unpacked with wrong size!
- fi
- # end of 'jdpipe.c'
- fi
- if test -f 'makvms.opt' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'makvms.opt'\"
- else
- echo shar: Extracting \"'makvms.opt'\" \(142 characters\)
- sed "s/^X//" >'makvms.opt' <<'END_OF_FILE'
- X! a pointer to the VAX/VMS C Run-Time Shareable Library
- X! This file is needed by makefile.mms and makefile.vms
- XSys$Library:VAXCRTL.EXE /Share
- END_OF_FILE
- if test 142 -ne `wc -c <'makvms.opt'`; then
- echo shar: \"'makvms.opt'\" unpacked with wrong size!
- fi
- # end of 'makvms.opt'
- fi
- echo shar: End of archive 5 \(of 18\).
- cp /dev/null ark5isdone
- 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...
-