home *** CD-ROM | disk | FTP | other *** search
- From: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Newsgroups: comp.sources.misc
- Subject: v44i098: jpeg - JPEG image compression, Part01/27
- Date: 26 Sep 1994 16:13:31 -0500
- Organization: Independent JPEG Group
- Sender: kent@sparky.sterling.com
- Approved: kent@sparky.sterling.com
- Message-ID: <csm-v44i098=jpeg.161317@sparky.sterling.com>
- Keywords: JPEG, image compression
- X-Md4-Signature: c89975bb92623a934ecf73c78eb0bb50
-
- Submitted-by: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Posting-number: Volume 44, Issue 98
- Archive-name: jpeg/part01
- Environment: UNIX, VMS, MS-DOS, Mac, Amiga, Atari, Cray
- Supersedes: jpeg: Volume 34, Issue 55-72
-
- This package contains C software to implement JPEG image compression and
- decompression. JPEG is a standardized compression method for full-color
- and gray-scale images. JPEG is intended for "real-world" scenes; cartoons
- and other non-realistic images are not its strong suit. JPEG is lossy,
- meaning that the output image is not identical to the input image.
- The user can trade off output image quality against compressed file size by
- adjusting a compression parameter.
-
- The IJG code includes a reusable JPEG compression/decompression library,
- plus sample applications "cjpeg" and "djpeg", which perform conversion
- between JPEG JFIF format and image files in PPM/PGM (PBMPLUS), GIF, BMP,
- Utah RLE, and Targa formats. Two small applications "wrjpgcom" and
- "rdjpgcom" insert and extract textual comments in JFIF files.
- The package is highly portable; it has been used successfully on many
- machines ranging from Apple IIs to Crays.
-
- This version 5 supersedes version 4, which was posted in comp.sources.misc
- volume 34. Important user-level improvements over version 4 include:
-
- * Automatic configuration simplifies installation for most Unix systems.
-
- * A range of speed vs. image quality tradeoffs are supported.
- This includes resizing of an image during decompression: scaling down
- by a factor of 1/2, 1/4, or 1/8 is handled very efficiently.
-
- * New programs rdjpgcom and wrjpgcom allow insertion and extraction
- of text comments in a JPEG file.
-
- * cjpeg/djpeg support BMP file format.
-
- The application programmer's interface to the library has changed completely.
- Notable improvements for the programmer include:
-
- * We have eliminated the use of callback routines for handling the
- uncompressed image data. The application now sees the library as a
- set of routines that it calls to read or write image data on a
- scanline-by-scanline basis.
-
- * The application image data is represented in a conventional interleaved-
- pixel format, rather than as a separate array for each color channel.
- This can save a copying step in many programs.
-
- * The handling of compressed data has been cleaned up: the application can
- supply routines to source or sink the compressed data.
-
- * All static state has been eliminated from the library, so that multiple
- instances of compression or decompression can be active concurrently.
-
- * JPEG abbreviated datastream formats are supported, ie, quantization and
- Huffman tables can be stored separately from the image data.
-
- * And not only that, but the documentation of the library has improved
- considerably!
-
- We are releasing this software for both noncommercial and commercial use.
- Companies are welcome to use it as the basis for JPEG-related products.
- We do not ask a royalty, although we do ask for an acknowledgement in
- product literature (see the README file in the distribution for details).
- We hope to make this software industrial-quality --- although, as with
- anything that's free, we offer no warranty and accept no liability.
-
- Please direct any questions about this software to jpeg-info@uunet.uu.net.
-
- Dr. Thomas G. Lane
- organizer, Independent JPEG Group
- -------
- #! /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: README jmemmgr.c jversion.h
- # Wrapped by kent@sparky on Mon Sep 26 15:00:25 1994
- PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 1 (of 27)."'
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(17896 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XThe Independent JPEG Group's JPEG software
- X==========================================
- X
- XREADME for release 5 of 24-Sep-94
- X=================================
- X
- XThis distribution contains the fifth public release of the Independent JPEG
- XGroup's free JPEG software. You are welcome to redistribute this software and
- Xto use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
- X
- XSerious users of this software (particularly those incorporating it into
- Xlarger programs) should contact jpeg-info@uunet.uu.net to be added to our
- Xelectronic mailing list. Mailing list members are notified of updates and
- Xhave a chance to participate in technical discussions, etc.
- X
- XThis software is the work of Tom Lane, Philip Gladstone, Luis Ortiz, Jim
- XBoucher, Lee Crocker, George Phillips, Davide Rossi, Ge' Weijers, and other
- Xmembers of the Independent JPEG Group.
- X
- XIJG is not associated with the official ISO JPEG standards committee.
- X
- X
- XDOCUMENTATION ROADMAP
- X=====================
- X
- XThis file contains the following sections:
- X
- XOVERVIEW General description of JPEG and the IJG software.
- XLEGAL ISSUES Copyright, lack of warranty, terms of distribution.
- XREFERENCES Where to learn more about JPEG.
- XARCHIVE LOCATIONS Where to find newer versions of this software.
- XRELATED SOFTWARE Other stuff you should get.
- XFILE FORMAT WARS Software *not* to get.
- XTO DO Plans for future IJG releases.
- X
- XOther documentation files in the distribution are:
- X
- XUser documentation:
- X install.doc How to configure and install the IJG software.
- X usage.doc Usage instructions for cjpeg, djpeg, rdjpgcom, wrjpgcom.
- X *.1 Unix-style man pages for programs (same info as usage.doc).
- X change.log Version-to-version change highlights.
- XProgrammer and internal documentation:
- X libjpeg.doc How to use the JPEG library in your own programs.
- X example.c Sample code for calling the JPEG library.
- X structure.doc Overview of the JPEG library's internal structure.
- X filelist.doc Road map of IJG files.
- X coderules.doc Coding style rules --- please read if you contribute code.
- X
- XPlease read at least the files install.doc and usage.doc. Useful information
- Xcan also be found in the JPEG FAQ (Frequently Asked Questions) article. See
- XARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
- X
- XIf you want to understand how the JPEG code works, we suggest reading one or
- Xmore of the REFERENCES, then looking at the documentation files (in roughly
- Xthe order listed) before diving into the code.
- X
- X
- XOVERVIEW
- X========
- X
- XThis package contains C software to implement JPEG image compression and
- Xdecompression. JPEG (pronounced "jay-peg") is a standardized compression
- Xmethod for full-color and gray-scale images. JPEG is intended for compressing
- X"real-world" scenes; cartoons and other non-realistic images are not its
- Xstrong suit. JPEG is lossy, meaning that the output image is not necessarily
- Xidentical to the input image. Hence you must not use JPEG if you have to have
- Xidentical output bits. However, on typical images of real-world scenes, very
- Xgood compression levels can be obtained with no visible change, and amazingly
- Xhigh compression levels are possible if you can tolerate a low-quality image.
- XFor more details, see the references, or just experiment with various
- Xcompression settings.
- X
- XWe provide a set of library routines for reading and writing JPEG image files,
- Xplus two simple applications "cjpeg" and "djpeg", which use the library to
- Xperform conversion between JPEG and some other popular image file formats.
- XThe library is intended to be reused in other applications.
- X
- XThis software implements JPEG baseline and extended-sequential compression
- Xprocesses. Provision is made for supporting all variants of these processes,
- Xalthough some uncommon parameter settings aren't implemented yet. For legal
- Xreasons, we are not distributing code for the arithmetic-coding process; see
- XLEGAL ISSUES. At present we have made no provision for supporting the
- Xprogressive, hierarchical, or lossless processes defined in the standard.
- X(Support for progressive mode may be offered in a future release.)
- X
- XIn order to support file conversion and viewing software, we have included
- Xconsiderable functionality beyond the bare JPEG coding/decoding capability;
- Xfor example, the color quantization modules are not strictly part of JPEG
- Xdecoding, but they are essential for output to colormapped file formats or
- Xcolormapped displays. These extra functions can be compiled out of the
- Xlibrary if not required for a particular application. We have also included
- Xtwo simple applications for inserting and extracting textual comments in
- XJFIF files.
- X
- XThe emphasis in designing this software has been on achieving portability and
- Xflexibility, while also making it fast enough to be useful. In particular,
- Xthe software is not intended to be read as a tutorial on JPEG. (See the
- XREFERENCES section for introductory material.) While we hope that the entire
- Xpackage will someday be industrial-strength code, much remains to be done in
- Xperformance tuning and in improving the capabilities of individual modules.
- X
- XWe welcome the use of this software as a component of commercial products.
- XNo royalty is required, but we do ask for an acknowledgement in product
- Xdocumentation, as described under LEGAL ISSUES.
- X
- X
- XLEGAL ISSUES
- X============
- X
- XIn plain English:
- X
- X1. We don't promise that this software works. (But if you find any bugs,
- X please let us know!)
- X2. You can use this software for whatever you want. You don't have to pay us.
- X3. You may not pretend that you wrote this software. If you use it in a
- X program, you must acknowledge somewhere in your documentation that
- X you've used the IJG code.
- X
- XIn legalese:
- X
- XThe authors make NO WARRANTY or representation, either express or implied,
- Xwith respect to this software, its quality, accuracy, merchantability, or
- Xfitness for a particular purpose. This software is provided "AS IS", and you,
- Xits user, assume the entire risk as to its quality and accuracy.
- X
- XThis software is copyright (C) 1991, 1992, 1993, 1994, Thomas G. Lane.
- XAll Rights Reserved except as specified below.
- X
- XPermission is hereby granted to use, copy, modify, and distribute this
- Xsoftware (or portions thereof) for any purpose, without fee, subject to these
- Xconditions:
- X(1) If any part of the source code for this software is distributed, then this
- XREADME file must be included, with this copyright and no-warranty notice
- Xunaltered; and any additions, deletions, or changes to the original files
- Xmust be clearly indicated in accompanying documentation.
- X(2) If only executable code is distributed, then the accompanying
- Xdocumentation must state that "this software is based in part on the work of
- Xthe Independent JPEG Group".
- X(3) Permission for use of this software is granted only if the user accepts
- Xfull responsibility for any undesirable consequences; the authors accept
- XNO LIABILITY for damages of any kind.
- X
- XThese conditions apply to any software derived from or based on the IJG code,
- Xnot just to the unmodified library. If you use our work, you ought to
- Xacknowledge us.
- X
- XPermission is NOT granted for the use of any IJG author's name or company name
- Xin advertising or publicity relating to this software or products derived from
- Xit. This software may be referred to only as "the Independent JPEG Group's
- Xsoftware".
- X
- XWe specifically permit and encourage the use of this software as the basis of
- Xcommercial products, provided that all warranty or liability claims are
- Xassumed by the product vendor.
- X
- X
- Xansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
- Xsole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
- Xansi2knr.c is NOT covered by the above copyright and conditions, but instead
- Xby the usual distribution terms of the Free Software Foundation; principally,
- Xthat you must include source code if you redistribute it. (See the file
- Xansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
- Xof any program generated from the IJG code, this does not limit you more than
- Xthe foregoing paragraphs do.
- X
- XThe configuration script "configure" was produced by GNU Autoconf. Again,
- Xthe FSF copyright terms apply only to configure, not to the IJG code; and
- Xagain, that does not limit your use of the object code.
- X
- XIt appears that the arithmetic coding option of the JPEG spec is covered by
- Xpatents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
- Xlegally be used without obtaining one or more licenses. For this reason,
- Xsupport for arithmetic coding has been removed from the free JPEG software.
- X(Since arithmetic coding provides only a marginal gain over the unpatented
- XHuffman mode, it is unlikely that very many implementations will support it.)
- XSo far as we are aware, there are no patent restrictions on the remaining
- Xcode.
- X
- XWe are required to state that
- X "The Graphics Interchange Format(c) is the Copyright property of
- X CompuServe Incorporated. GIF(sm) is a Service Mark property of
- X CompuServe Incorporated."
- X
- X
- XREFERENCES
- X==========
- X
- XWe highly recommend reading one or more of these references before trying to
- Xunderstand the innards of the JPEG software.
- X
- XThe best short technical introduction to the JPEG compression algorithm is
- X Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
- X Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
- X(Adjacent articles in that issue discuss MPEG motion picture compression,
- Xapplications of JPEG, and related topics.) If you don't have the CACM issue
- Xhandy, a PostScript file containing a revised version of Wallace's article is
- Xavailable at ftp.uu.net, graphics/jpeg/wallace.ps.gz. The file (actually a
- Xpreprint for an article to appear in IEEE Trans. Consumer Electronics) omits
- Xthe sample images that appeared in CACM, but it includes corrections and some
- Xadded material. Note: the Wallace article is copyright ACM and IEEE, and it
- Xmay not be used for commercial purposes.
- X
- XA somewhat less technical, more leisurely introduction to JPEG can be found in
- X"The Data Compression Book" by Mark Nelson, published by M&T Books (Redwood
- XCity, CA), 1991, ISBN 1-55851-216-0. This book provides good explanations and
- Xexample C code for a multitude of compression methods including JPEG. It is
- Xan excellent source if you are comfortable reading C code but don't know much
- Xabout data compression in general. The book's JPEG sample code is far from
- Xindustrial-strength, but when you are ready to look at a full implementation,
- Xyou've got one here...
- X
- XThe best full description of JPEG is the textbook "JPEG Still Image Data
- XCompression Standard" by William B. Pennebaker and Joan L. Mitchell, published
- Xby Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp.
- XThe book includes the complete text of the ISO JPEG standards (DIS 10918-1
- Xand draft DIS 10918-2). This is by far the most complete exposition of JPEG
- Xin existence, and we highly recommend it.
- X
- XThe JPEG standard itself is not available electronically; you must order a
- Xpaper copy through ISO. (Unless you feel a need to own a certified official
- Xcopy, we recommend buying the Pennebaker and Mitchell book instead; it's much
- Xcheaper and includes a great deal of useful explanatory material.) In the US,
- Xcopies of the standard may be ordered from ANSI Sales at (212) 642-4900, or
- Xfrom Global Engineering Documents at (800) 854-7179. (ANSI doesn't take
- Xcredit card orders, but Global does.) It's not cheap: as of 1992, ANSI was
- Xcharging $95 for Part 1 and $47 for Part 2, plus 7% shipping/handling. The
- Xstandard is divided into two parts, Part 1 being the actual specification,
- Xwhile Part 2 covers compliance testing methods. Part 1 is titled "Digital
- XCompression and Coding of Continuous-tone Still Images, Part 1: Requirements
- Xand guidelines" and has document number ISO/IEC IS 10918-1. As of mid-1994,
- XPart 2 is still at Draft International Standard status. It is titled "Digital
- XCompression and Coding of Continuous-tone Still Images, Part 2: Compliance
- Xtesting" and has document number ISO/IEC DIS 10918-2. (The document number
- Xwill change to IS 10918-2 when final approval is obtained.) A Part 3,
- Xcovering extensions, is likely to appear in draft form in late 1994.
- X
- XThe JPEG standard does not specify all details of an interchangeable file
- Xformat. For the omitted details we follow the "JFIF" conventions, revision
- X1.02. A copy of the JFIF spec is available from:
- X Literature Department
- X C-Cube Microsystems, Inc.
- X 1778 McCarthy Blvd.
- X Milpitas, CA 95035
- X phone (408) 944-6300, fax (408) 944-6314
- XA PostScript version of this document is available at ftp.uu.net, file
- Xgraphics/jpeg/jfif.ps.gz. It can also be obtained by e-mail from the C-Cube
- Xmail server, netlib@c3.pla.ca.us. Send the message "send jfif_ps from jpeg"
- Xto the server to obtain the JFIF document; send the message "help" if you have
- Xtrouble.
- X
- XThe TIFF 6.0 file format specification can be obtained by FTP from sgi.com
- X(192.48.153.1), file graphics/tiff/TIFF6.ps.Z; or you can order a printed copy
- Xfrom Aldus Corp. at (206) 628-6593. It should be noted that the TIFF 6.0 spec
- Xof 3-June-92 has a number of serious problems in its JPEG features. A
- Xredesign effort is currently underway to correct these problems; it is
- Xexpected to result in a new, incompatible, spec. IJG intends to support the
- Xcorrected version of TIFF when the new spec is issued.
- X
- X
- XARCHIVE LOCATIONS
- X=================
- X
- XThe "official" archive site for this software is ftp.uu.net (Internet
- Xaddress 192.48.96.9). The most recent released version can always be found
- Xthere in directory graphics/jpeg. This particular version will be archived
- Xas graphics/jpeg/jpegsrc.v5.tar.gz. If you are on the Internet, you
- Xcan retrieve files from ftp.uu.net by standard anonymous FTP. If you don't
- Xhave FTP access, UUNET's archives are also available via UUCP; contact
- Xhelp@uunet.uu.net for information on retrieving files that way.
- X
- XNumerous Internet sites maintain copies of the UUNET files; in particular,
- Xyou can probably find a copy at any site that archives comp.sources.misc
- Xsubmissions. However, only ftp.uu.net is guaranteed to have the latest
- Xofficial version.
- X
- XYou can also obtain this software from CompuServe, in the GRAPHSUPPORT forum
- X(GO GRAPHSUP); this version will be file jpsrc5.zip in library 15. Again,
- XCompuServe is not guaranteed to have the very latest version.
- X
- XThe JPEG FAQ (Frequently Asked Questions) article is a useful source of
- Xgeneral information about JPEG. It is updated constantly and therefore
- Xis not included in this distribution. The FAQ is posted every two weeks
- Xto Usenet newsgroups comp.graphics, news.answers, and other groups. You
- Xcan always obtain the latest version from the news.answers archive at
- Xrtfm.mit.edu (18.181.0.24). By FTP, fetch /pub/usenet/news.answers/jpeg-faq.
- XIf you don't have FTP, send e-mail to mail-server@rtfm.mit.edu with body
- X"send usenet/news.answers/jpeg-faq".
- X
- X
- XRELATED SOFTWARE
- X================
- X
- XNumerous viewing and image manipulation programs now support JPEG. (Quite a
- Xfew of them use this library to do so.) The JPEG FAQ described above lists
- Xsome of the more popular free and shareware viewers, and tells where to
- Xobtain them on Internet.
- X
- XIf you are on a Unix machine, we highly recommend Jef Poskanzer's free
- XPBMPLUS image software, which provides many useful operations on PPM-format
- Ximage files. In particular, it can convert PPM images to and from a wide
- Xrange of other formats. You can obtain this package by FTP from ftp.x.org
- X(contrib/pbmplus*.tar.Z) or ftp.ee.lbl.gov (pbmplus*.tar.Z). There is also
- Xa newer update of this package called NETPBM, available from
- Xwuarchive.wustl.edu under directory /graphics/graphics/packages/NetPBM/.
- XUnfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software
- Xis; you are likely to have difficulty making it work on any non-Unix machine.
- X
- XA different free JPEG implementation, written by the PVRG group at Stanford,
- Xis available from havefun.stanford.edu in directory pub/jpeg. This program
- Xis designed for research and experimentation rather than production use;
- Xit is slower, harder to use, and less portable than the IJG code, but it
- Ximplements a larger subset of the JPEG standard. In particular, it supports
- Xlossless JPEG.
- X
- X
- XFILE FORMAT WARS
- X================
- X
- XSome JPEG programs produce files that are not compatible with our library.
- XThe root of the problem is that the ISO JPEG committee failed to specify a
- Xconcrete file format. Some vendors "filled in the blanks" on their own,
- Xcreating proprietary formats that no one else could read. (For example, none
- Xof the early commercial JPEG implementations for the Macintosh were able to
- Xexchange compressed files.)
- X
- XThe file format we have adopted is called JFIF (see REFERENCES). This format
- Xhas been agreed to by a number of major commercial JPEG vendors, and it has
- Xbecome the de facto standard. JFIF is a minimal or "low end" representation.
- XWork is also going forward to incorporate JPEG compression into the TIFF
- Xstandard, for use in "high end" applications that need to record a lot of
- Xadditional data about an image. We intend to support TIFF in the future.
- XWe hope that these two formats will be sufficient and that other,
- Xincompatible JPEG file formats will not proliferate.
- X
- XIndeed, part of the reason for developing and releasing this free software is
- Xto help force rapid convergence to de facto standards for JPEG file formats.
- XSUPPORT STANDARD, NON-PROPRIETARY FORMATS: demand JFIF or TIFF/JPEG!
- X
- X
- XTO DO
- X=====
- X
- XIn future versions, we are considering supporting progressive JPEG
- Xcompression, the upcoming JPEG Part 3 extensions, and other improvements.
- X
- XAs always, speeding things up is high on our priority list.
- X
- XPlease send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
- END_OF_FILE
- if test 17896 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'jmemmgr.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jmemmgr.c'\"
- else
- echo shar: Extracting \"'jmemmgr.c'\" \(38963 characters\)
- sed "s/^X//" >'jmemmgr.c' <<'END_OF_FILE'
- X/*
- X * jmemmgr.c
- X *
- X * Copyright (C) 1991-1994, 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 the JPEG system-independent memory management
- X * routines. This code is usable across a wide variety of machines; most
- X * of the system dependencies have been isolated in a separate file.
- X * The major functions provided here are:
- X * * pool-based allocation and freeing of memory;
- X * * policy decisions about how to divide available memory among the
- X * virtual arrays;
- X * * control logic for swapping virtual arrays between main memory and
- X * backing storage.
- X * The separate system-dependent file provides the actual backing-storage
- X * access code, and it contains the policy decision about how much total
- X * main memory to use.
- X * This file is system-dependent in the sense that some of its functions
- X * are unnecessary in some systems. For example, if there is enough virtual
- X * memory so that backing storage will never be used, much of the virtual
- X * array control logic could be removed. (Of course, if you have that much
- X * memory then you shouldn't care about a little bit of unused code...)
- X */
- X
- X#define JPEG_INTERNALS
- X#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */
- X#include "jinclude.h"
- X#include "jpeglib.h"
- X#include "jmemsys.h" /* import the system-dependent declarations */
- X
- X#ifndef NO_GETENV
- X#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */
- Xextern char * getenv JPP((const char * name));
- X#endif
- X#endif
- X
- X
- X/*
- X * Some important notes:
- X * The allocation routines provided here must never return NULL.
- X * They should exit to error_exit if unsuccessful.
- X *
- X * It's not a good idea to try to merge the sarray and barray routines,
- X * even though they are textually almost the same, because samples are
- X * usually stored as bytes while coefficients are shorts or ints. Thus,
- X * in machines where byte pointers have a different representation from
- X * word pointers, the resulting machine code could not be the same.
- X */
- X
- X
- X/*
- X * Many machines require storage alignment: longs must start on 4-byte
- X * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc()
- X * always returns pointers that are multiples of the worst-case alignment
- X * requirement, and we had better do so too.
- X * There isn't any really portable way to determine the worst-case alignment
- X * requirement. This module assumes that the alignment requirement is
- X * multiples of sizeof(ALIGN_TYPE).
- X * By default, we define ALIGN_TYPE as double. This is necessary on some
- X * workstations (where doubles really do need 8-byte alignment) and will work
- X * fine on nearly everything. If your machine has lesser alignment needs,
- X * you can save a few bytes by making ALIGN_TYPE smaller.
- X * The only place I know of where this will NOT work is certain Macintosh
- X * 680x0 compilers that define double as a 10-byte IEEE extended float.
- X * Doing 10-byte alignment is counterproductive because longwords won't be
- X * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have
- X * such a compiler.
- X */
- X
- X#ifndef ALIGN_TYPE /* so can override from jconfig.h */
- X#define ALIGN_TYPE double
- X#endif
- X
- X
- X/*
- X * We allocate objects from "pools", where each pool is gotten with a single
- X * request to jpeg_get_small() or jpeg_get_large(). There is no per-object
- X * overhead within a pool, except for alignment padding. Each pool has a
- X * header with a link to the next pool of the same class.
- X * Small and large pool headers are identical except that the latter's
- X * link pointer must be FAR on 80x86 machines.
- X * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
- X * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
- X * of the alignment requirement of ALIGN_TYPE.
- X */
- X
- Xtypedef union small_pool_struct * small_pool_ptr;
- X
- Xtypedef union small_pool_struct {
- X struct {
- X small_pool_ptr next; /* next in list of pools */
- X size_t bytes_used; /* how many bytes already used within pool */
- X size_t bytes_left; /* bytes still available in this pool */
- X } hdr;
- X ALIGN_TYPE dummy; /* included in union to ensure alignment */
- X} small_pool_hdr;
- X
- Xtypedef union large_pool_struct FAR * large_pool_ptr;
- X
- Xtypedef union large_pool_struct {
- X struct {
- X large_pool_ptr next; /* next in list of pools */
- X size_t bytes_used; /* how many bytes already used within pool */
- X size_t bytes_left; /* bytes still available in this pool */
- X } hdr;
- X ALIGN_TYPE dummy; /* included in union to ensure alignment */
- X} large_pool_hdr;
- X
- X
- X/*
- X * Here is the full definition of a memory manager object.
- X */
- X
- Xtypedef struct {
- X struct jpeg_memory_mgr pub; /* public fields */
- X
- X /* Each pool identifier (lifetime class) names a linked list of pools. */
- X small_pool_ptr small_list[JPOOL_NUMPOOLS];
- X large_pool_ptr large_list[JPOOL_NUMPOOLS];
- X
- X /* Since we only have one lifetime class of virtual arrays, only one
- X * linked list is necessary (for each datatype). Note that the virtual
- X * array control blocks being linked together are actually stored somewhere
- X * in the small-pool list.
- X */
- X jvirt_sarray_ptr virt_sarray_list;
- X jvirt_barray_ptr virt_barray_list;
- X
- X /* This counts total space obtained from jpeg_get_small/large */
- X long total_space_allocated;
- X
- X /* alloc_sarray and alloc_barray set this value for use by virtual
- X * array routines.
- X */
- X JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */
- X} my_memory_mgr;
- X
- Xtypedef my_memory_mgr * my_mem_ptr;
- X
- X
- X/*
- X * The control blocks for virtual arrays.
- X * Note that these blocks are allocated in the "small" pool area.
- X * System-dependent info for the associated backing store (if any) is hidden
- X * inside the backing_store_info struct.
- X */
- X
- Xstruct jvirt_sarray_control {
- X JSAMPARRAY mem_buffer; /* => the in-memory buffer */
- X JDIMENSION rows_in_array; /* total virtual array height */
- X JDIMENSION samplesperrow; /* width of array (and of memory buffer) */
- X JDIMENSION unitheight; /* # of rows accessed by access_virt_sarray */
- X JDIMENSION rows_in_mem; /* height of memory buffer */
- X JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
- X JDIMENSION cur_start_row; /* first logical row # in the buffer */
- X boolean dirty; /* do current buffer contents need written? */
- X boolean b_s_open; /* is backing-store data valid? */
- X jvirt_sarray_ptr next; /* link to next virtual sarray control block */
- X backing_store_info b_s_info; /* System-dependent control info */
- X};
- X
- Xstruct jvirt_barray_control {
- X JBLOCKARRAY mem_buffer; /* => the in-memory buffer */
- X JDIMENSION rows_in_array; /* total virtual array height */
- X JDIMENSION blocksperrow; /* width of array (and of memory buffer) */
- X JDIMENSION unitheight; /* # of rows accessed by access_virt_barray */
- X JDIMENSION rows_in_mem; /* height of memory buffer */
- X JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
- X JDIMENSION cur_start_row; /* first logical row # in the buffer */
- X boolean dirty; /* do current buffer contents need written? */
- X boolean b_s_open; /* is backing-store data valid? */
- X jvirt_barray_ptr next; /* link to next virtual barray control block */
- X backing_store_info b_s_info; /* System-dependent control info */
- X};
- X
- X
- X#ifdef MEM_STATS /* optional extra stuff for statistics */
- X
- XLOCAL void
- Xprint_mem_stats (j_common_ptr cinfo, int pool_id)
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X small_pool_ptr shdr_ptr;
- X large_pool_ptr lhdr_ptr;
- X
- X /* Since this is only a debugging stub, we can cheat a little by using
- X * fprintf directly rather than going through the trace message code.
- X * This is helpful because message parm array can't handle longs.
- X */
- X fprintf(stderr, "Freeing pool %d, total space = %ld\n",
- X pool_id, mem->total_space_allocated);
- X
- X for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
- X lhdr_ptr = lhdr_ptr->hdr.next) {
- X fprintf(stderr, " Large chunk used %ld\n",
- X (long) lhdr_ptr->hdr.bytes_used);
- X }
- X
- X for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
- X shdr_ptr = shdr_ptr->hdr.next) {
- X fprintf(stderr, " Small chunk used %ld free %ld\n",
- X (long) shdr_ptr->hdr.bytes_used,
- X (long) shdr_ptr->hdr.bytes_left);
- X }
- X}
- X
- X#endif /* MEM_STATS */
- X
- X
- XLOCAL void
- Xout_of_memory (j_common_ptr cinfo, int which)
- X/* Report an out-of-memory error and stop execution */
- X/* If we compiled MEM_STATS support, report alloc requests before dying */
- X{
- X#ifdef MEM_STATS
- X cinfo->err->trace_level = 2; /* force self_destruct to report stats */
- X#endif
- X ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
- X}
- X
- X
- X/*
- X * Allocation of "small" objects.
- X *
- X * For these, we use pooled storage. When a new pool must be created,
- X * we try to get enough space for the current request plus a "slop" factor,
- X * where the slop will be the amount of leftover space in the new pool.
- X * The speed vs. space tradeoff is largely determined by the slop values.
- X * A different slop value is provided for each pool class (lifetime),
- X * and we also distinguish the first pool of a class from later ones.
- X * NOTE: the values given work fairly well on both 16- and 32-bit-int
- X * machines, but may be too small if longs are 64 bits or more.
- X */
- X
- Xstatic const size_t first_pool_slop[JPOOL_NUMPOOLS] =
- X{
- X 1600, /* first PERMANENT pool */
- X 16000 /* first IMAGE pool */
- X};
- X
- Xstatic const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
- X{
- X 0, /* additional PERMANENT pools */
- X 5000 /* additional IMAGE pools */
- X};
- X
- X#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */
- X
- X
- XMETHODDEF void *
- Xalloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
- X/* Allocate a "small" object */
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X small_pool_ptr hdr_ptr, prev_hdr_ptr;
- X char * data_ptr;
- X size_t odd_bytes, min_request, slop;
- X
- X /* Check for unsatisfiable request (do now to ensure no overflow below) */
- X if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
- X out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
- X
- X /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
- X odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
- X if (odd_bytes > 0)
- X sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
- X
- X /* See if space is available in any existing pool */
- X if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
- X ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
- X prev_hdr_ptr = NULL;
- X hdr_ptr = mem->small_list[pool_id];
- X while (hdr_ptr != NULL) {
- X if (hdr_ptr->hdr.bytes_left >= sizeofobject)
- X break; /* found pool with enough space */
- X prev_hdr_ptr = hdr_ptr;
- X hdr_ptr = hdr_ptr->hdr.next;
- X }
- X
- X /* Time to make a new pool? */
- X if (hdr_ptr == NULL) {
- X /* min_request is what we need now, slop is what will be leftover */
- X min_request = sizeofobject + SIZEOF(small_pool_hdr);
- X if (prev_hdr_ptr == NULL) /* first pool in class? */
- X slop = first_pool_slop[pool_id];
- X else
- X slop = extra_pool_slop[pool_id];
- X /* Don't ask for more than MAX_ALLOC_CHUNK */
- X if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
- X slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
- X /* Try to get space, if fail reduce slop and try again */
- X for (;;) {
- X hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
- X if (hdr_ptr != NULL)
- X break;
- X slop /= 2;
- X if (slop < MIN_SLOP) /* give up when it gets real small */
- X out_of_memory(cinfo, 2); /* jpeg_get_small failed */
- X }
- X mem->total_space_allocated += min_request + slop;
- X /* Success, initialize the new pool header and add to end of list */
- X hdr_ptr->hdr.next = NULL;
- X hdr_ptr->hdr.bytes_used = 0;
- X hdr_ptr->hdr.bytes_left = sizeofobject + slop;
- X if (prev_hdr_ptr == NULL) /* first pool in class? */
- X mem->small_list[pool_id] = hdr_ptr;
- X else
- X prev_hdr_ptr->hdr.next = hdr_ptr;
- X }
- X
- X /* OK, allocate the object from the current pool */
- X data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
- X data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
- X hdr_ptr->hdr.bytes_used += sizeofobject;
- X hdr_ptr->hdr.bytes_left -= sizeofobject;
- X
- X return (void *) data_ptr;
- X}
- X
- X
- X/*
- X * Allocation of "large" objects.
- X *
- X * The external semantics of these are the same as "small" objects,
- X * except that FAR pointers are used on 80x86. However the pool
- X * management heuristics are quite different. We assume that each
- X * request is large enough that it may as well be passed directly to
- X * jpeg_get_large; the pool management just links everything together
- X * so that we can free it all on demand.
- X * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
- X * structures. The routines that create these structures (see below)
- X * deliberately bunch rows together to ensure a large request size.
- X */
- X
- XMETHODDEF void FAR *
- Xalloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
- X/* Allocate a "large" object */
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X large_pool_ptr hdr_ptr;
- X size_t odd_bytes;
- X
- X /* Check for unsatisfiable request (do now to ensure no overflow below) */
- X if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
- X out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
- X
- X /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
- X odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
- X if (odd_bytes > 0)
- X sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
- X
- X /* Always make a new pool */
- X if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
- X ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
- X
- X hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
- X SIZEOF(large_pool_hdr));
- X if (hdr_ptr == NULL)
- X out_of_memory(cinfo, 4); /* jpeg_get_large failed */
- X mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
- X
- X /* Success, initialize the new pool header and add to list */
- X hdr_ptr->hdr.next = mem->large_list[pool_id];
- X /* We maintain space counts in each pool header for statistical purposes,
- X * even though they are not needed for allocation.
- X */
- X hdr_ptr->hdr.bytes_used = sizeofobject;
- X hdr_ptr->hdr.bytes_left = 0;
- X mem->large_list[pool_id] = hdr_ptr;
- X
- X return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
- X}
- X
- X
- X/*
- X * Creation of 2-D sample arrays.
- X * The pointers are in near heap, the samples themselves in FAR heap.
- X *
- X * To minimize allocation overhead and to allow I/O of large contiguous
- X * blocks, we allocate the sample rows in groups of as many rows as possible
- X * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
- X * NB: the virtual array control routines, later in this file, know about
- X * this chunking of rows. The rowsperchunk value is left in the mem manager
- X * object so that it can be saved away if this sarray is the workspace for
- X * a virtual array.
- X */
- X
- XMETHODDEF JSAMPARRAY
- Xalloc_sarray (j_common_ptr cinfo, int pool_id,
- X JDIMENSION samplesperrow, JDIMENSION numrows)
- X/* Allocate a 2-D sample array */
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X JSAMPARRAY result;
- X JSAMPROW workspace;
- X JDIMENSION rowsperchunk, currow, i;
- X long ltemp;
- X
- X /* Calculate max # of rows allowed in one allocation chunk */
- X ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
- X ((long) samplesperrow * SIZEOF(JSAMPLE));
- X if (ltemp <= 0)
- X ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
- X if (ltemp < (long) numrows)
- X rowsperchunk = (JDIMENSION) ltemp;
- X else
- X rowsperchunk = numrows;
- X mem->last_rowsperchunk = rowsperchunk;
- X
- X /* Get space for row pointers (small object) */
- X result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
- X (size_t) (numrows * SIZEOF(JSAMPROW)));
- X
- X /* Get the rows themselves (large objects) */
- X currow = 0;
- X while (currow < numrows) {
- X rowsperchunk = MIN(rowsperchunk, numrows - currow);
- X workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
- X (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
- X * SIZEOF(JSAMPLE)));
- X for (i = rowsperchunk; i > 0; i--) {
- X result[currow++] = workspace;
- X workspace += samplesperrow;
- X }
- X }
- X
- X return result;
- X}
- X
- X
- X/*
- X * Creation of 2-D coefficient-block arrays.
- X * This is essentially the same as the code for sample arrays, above.
- X */
- X
- XMETHODDEF JBLOCKARRAY
- Xalloc_barray (j_common_ptr cinfo, int pool_id,
- X JDIMENSION blocksperrow, JDIMENSION numrows)
- X/* Allocate a 2-D coefficient-block array */
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X JBLOCKARRAY result;
- X JBLOCKROW workspace;
- X JDIMENSION rowsperchunk, currow, i;
- X long ltemp;
- X
- X /* Calculate max # of rows allowed in one allocation chunk */
- X ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
- X ((long) blocksperrow * SIZEOF(JBLOCK));
- X if (ltemp <= 0)
- X ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
- X if (ltemp < (long) numrows)
- X rowsperchunk = (JDIMENSION) ltemp;
- X else
- X rowsperchunk = numrows;
- X mem->last_rowsperchunk = rowsperchunk;
- X
- X /* Get space for row pointers (small object) */
- X result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
- X (size_t) (numrows * SIZEOF(JBLOCKROW)));
- X
- X /* Get the rows themselves (large objects) */
- X currow = 0;
- X while (currow < numrows) {
- X rowsperchunk = MIN(rowsperchunk, numrows - currow);
- X workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
- X (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
- X * SIZEOF(JBLOCK)));
- X for (i = rowsperchunk; i > 0; i--) {
- X result[currow++] = workspace;
- X workspace += blocksperrow;
- X }
- X }
- X
- X return result;
- X}
- X
- X
- X/*
- X * About virtual array management:
- X *
- X * To allow machines with limited memory to handle large images, all
- X * processing in the JPEG system is done a few pixel or block rows at a time.
- X * The above "normal" array routines are only used to allocate strip buffers
- X * (as wide as the image, but just a few rows high).
- X * In some cases multiple passes must be made over the data. In these
- X * cases the virtual array routines are used. The array is still accessed
- X * a strip at a time, but the memory manager must save the whole array
- X * for repeated accesses. The intended implementation is that there is
- X * a strip buffer in memory (as high as is possible given the desired memory
- X * limit), plus a backing file that holds the rest of the array.
- X *
- X * The request_virt_array routines are told the total size of the image and
- X * the unit height, which is the number of rows that will be accessed at once;
- X * the in-memory buffer should be made a multiple of this height for best
- X * efficiency.
- X *
- X * The request routines create control blocks but not the in-memory buffers.
- X * That is postponed until realize_virt_arrays is called. At that time the
- X * total amount of space needed is known (approximately, anyway), so free
- X * memory can be divided up fairly.
- X *
- X * The access_virt_array routines are responsible for making a specific strip
- X * area accessible (after reading or writing the backing file, if necessary).
- X * Note that the access routines are told whether the caller intends to modify
- X * the accessed strip; during a read-only pass this saves having to rewrite
- X * data to disk.
- X *
- X * The typical access pattern is one top-to-bottom pass to write the data,
- X * followed by one or more read-only top-to-bottom passes. However, other
- X * access patterns may occur while reading. For example, translation of image
- X * formats that use bottom-to-top scan order will require bottom-to-top read
- X * passes. The memory manager need not support multiple write passes nor
- X * funny write orders (meaning that rearranging rows must be handled while
- X * reading data out of the virtual array, not while putting it in). THIS WILL
- X * PROBABLY NEED TO CHANGE ... will need multiple write passes for progressive
- X * JPEG decoding.
- X *
- X * In current usage, the access requests are always for nonoverlapping strips;
- X * that is, successive access start_row numbers always differ by exactly the
- X * unitheight. This allows fairly simple buffer dump/reload logic if the
- X * in-memory buffer is made a multiple of the unitheight. The code below
- X * would work with overlapping access requests, but not very efficiently.
- X */
- X
- X
- XMETHODDEF jvirt_sarray_ptr
- Xrequest_virt_sarray (j_common_ptr cinfo, int pool_id,
- X JDIMENSION samplesperrow, JDIMENSION numrows,
- X JDIMENSION unitheight)
- X/* Request a virtual 2-D sample array */
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X jvirt_sarray_ptr result;
- X
- X /* Only IMAGE-lifetime virtual arrays are currently supported */
- X if (pool_id != JPOOL_IMAGE)
- X ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
- X
- X /* Round array size up to a multiple of unitheight */
- X numrows = (JDIMENSION) jround_up((long) numrows, (long) unitheight);
- X
- X /* get control block */
- X result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
- X SIZEOF(struct jvirt_sarray_control));
- X
- X result->mem_buffer = NULL; /* marks array not yet realized */
- X result->rows_in_array = numrows;
- X result->samplesperrow = samplesperrow;
- X result->unitheight = unitheight;
- X result->b_s_open = FALSE; /* no associated backing-store object */
- X result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
- X mem->virt_sarray_list = result;
- X
- X return result;
- X}
- X
- X
- XMETHODDEF jvirt_barray_ptr
- Xrequest_virt_barray (j_common_ptr cinfo, int pool_id,
- X JDIMENSION blocksperrow, JDIMENSION numrows,
- X JDIMENSION unitheight)
- X/* Request a virtual 2-D coefficient-block array */
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X jvirt_barray_ptr result;
- X
- X /* Only IMAGE-lifetime virtual arrays are currently supported */
- X if (pool_id != JPOOL_IMAGE)
- X ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
- X
- X /* Round array size up to a multiple of unitheight */
- X numrows = (JDIMENSION) jround_up((long) numrows, (long) unitheight);
- X
- X /* get control block */
- X result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
- X SIZEOF(struct jvirt_barray_control));
- X
- X result->mem_buffer = NULL; /* marks array not yet realized */
- X result->rows_in_array = numrows;
- X result->blocksperrow = blocksperrow;
- X result->unitheight = unitheight;
- X result->b_s_open = FALSE; /* no associated backing-store object */
- X result->next = mem->virt_barray_list; /* add to list of virtual arrays */
- X mem->virt_barray_list = result;
- X
- X return result;
- X}
- X
- X
- XMETHODDEF void
- Xrealize_virt_arrays (j_common_ptr cinfo)
- X/* Allocate the in-memory buffers for any unrealized virtual arrays */
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X long space_per_unitheight, maximum_space, avail_mem;
- X long unitheights, max_unitheights;
- X jvirt_sarray_ptr sptr;
- X jvirt_barray_ptr bptr;
- X
- X /* Compute the minimum space needed (unitheight rows in each buffer)
- X * and the maximum space needed (full image height in each buffer).
- X * These may be of use to the system-dependent jpeg_mem_available routine.
- X */
- X space_per_unitheight = 0;
- X maximum_space = 0;
- X for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
- X if (sptr->mem_buffer == NULL) { /* if not realized yet */
- X space_per_unitheight += (long) sptr->unitheight *
- X (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
- X maximum_space += (long) sptr->rows_in_array *
- X (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
- X }
- X }
- X for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
- X if (bptr->mem_buffer == NULL) { /* if not realized yet */
- X space_per_unitheight += (long) bptr->unitheight *
- X (long) bptr->blocksperrow * SIZEOF(JBLOCK);
- X maximum_space += (long) bptr->rows_in_array *
- X (long) bptr->blocksperrow * SIZEOF(JBLOCK);
- X }
- X }
- X
- X if (space_per_unitheight <= 0)
- X return; /* no unrealized arrays, no work */
- X
- X /* Determine amount of memory to actually use; this is system-dependent. */
- X avail_mem = jpeg_mem_available(cinfo, space_per_unitheight, maximum_space,
- X mem->total_space_allocated);
- X
- X /* If the maximum space needed is available, make all the buffers full
- X * height; otherwise parcel it out with the same number of unitheights
- X * in each buffer.
- X */
- X if (avail_mem >= maximum_space)
- X max_unitheights = 1000000000L;
- X else {
- X max_unitheights = avail_mem / space_per_unitheight;
- X /* If there doesn't seem to be enough space, try to get the minimum
- X * anyway. This allows a "stub" implementation of jpeg_mem_available().
- X */
- X if (max_unitheights <= 0)
- X max_unitheights = 1;
- X }
- X
- X /* Allocate the in-memory buffers and initialize backing store as needed. */
- X
- X for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
- X if (sptr->mem_buffer == NULL) { /* if not realized yet */
- X unitheights = ((long) sptr->rows_in_array - 1L) / sptr->unitheight + 1L;
- X if (unitheights <= max_unitheights) {
- X /* This buffer fits in memory */
- X sptr->rows_in_mem = sptr->rows_in_array;
- X } else {
- X /* It doesn't fit in memory, create backing store. */
- X sptr->rows_in_mem = (JDIMENSION) (max_unitheights * sptr->unitheight);
- X jpeg_open_backing_store(cinfo, & sptr->b_s_info,
- X (long) sptr->rows_in_array *
- X (long) sptr->samplesperrow *
- X (long) SIZEOF(JSAMPLE));
- X sptr->b_s_open = TRUE;
- X }
- X sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
- X sptr->samplesperrow, sptr->rows_in_mem);
- X sptr->rowsperchunk = mem->last_rowsperchunk;
- X sptr->cur_start_row = 0;
- X sptr->dirty = FALSE;
- X }
- X }
- X
- X for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
- X if (bptr->mem_buffer == NULL) { /* if not realized yet */
- X unitheights = ((long) bptr->rows_in_array - 1L) / bptr->unitheight + 1L;
- X if (unitheights <= max_unitheights) {
- X /* This buffer fits in memory */
- X bptr->rows_in_mem = bptr->rows_in_array;
- X } else {
- X /* It doesn't fit in memory, create backing store. */
- X bptr->rows_in_mem = (JDIMENSION) (max_unitheights * bptr->unitheight);
- X jpeg_open_backing_store(cinfo, & bptr->b_s_info,
- X (long) bptr->rows_in_array *
- X (long) bptr->blocksperrow *
- X (long) SIZEOF(JBLOCK));
- X bptr->b_s_open = TRUE;
- X }
- X bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
- X bptr->blocksperrow, bptr->rows_in_mem);
- X bptr->rowsperchunk = mem->last_rowsperchunk;
- X bptr->cur_start_row = 0;
- X bptr->dirty = FALSE;
- X }
- X }
- X}
- X
- X
- XLOCAL void
- Xdo_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
- X/* Do backing store read or write of a virtual sample array */
- X{
- X long bytesperrow, file_offset, byte_count, rows, i;
- X
- X bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
- X file_offset = ptr->cur_start_row * bytesperrow;
- X /* Loop to read or write each allocation chunk in mem_buffer */
- X for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
- X /* One chunk, but check for short chunk at end of buffer */
- X rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
- X /* Transfer no more than fits in file */
- X rows = MIN(rows, (long) ptr->rows_in_array -
- X ((long) ptr->cur_start_row + i));
- X if (rows <= 0) /* this chunk might be past end of file! */
- X break;
- X byte_count = rows * bytesperrow;
- X if (writing)
- X (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
- X (void FAR *) ptr->mem_buffer[i],
- X file_offset, byte_count);
- X else
- X (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
- X (void FAR *) ptr->mem_buffer[i],
- X file_offset, byte_count);
- X file_offset += byte_count;
- X }
- X}
- X
- X
- XLOCAL void
- Xdo_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
- X/* Do backing store read or write of a virtual coefficient-block array */
- X{
- X long bytesperrow, file_offset, byte_count, rows, i;
- X
- X bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
- X file_offset = ptr->cur_start_row * bytesperrow;
- X /* Loop to read or write each allocation chunk in mem_buffer */
- X for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
- X /* One chunk, but check for short chunk at end of buffer */
- X rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
- X /* Transfer no more than fits in file */
- X rows = MIN(rows, (long) ptr->rows_in_array -
- X ((long) ptr->cur_start_row + i));
- X if (rows <= 0) /* this chunk might be past end of file! */
- X break;
- X byte_count = rows * bytesperrow;
- X if (writing)
- X (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
- X (void FAR *) ptr->mem_buffer[i],
- X file_offset, byte_count);
- X else
- X (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
- X (void FAR *) ptr->mem_buffer[i],
- X file_offset, byte_count);
- X file_offset += byte_count;
- X }
- X}
- X
- X
- XMETHODDEF JSAMPARRAY
- Xaccess_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
- X JDIMENSION start_row, boolean writable)
- X/* Access the part of a virtual sample array starting at start_row */
- X/* and extending for ptr->unitheight rows. writable is true if */
- X/* caller intends to modify the accessed area. */
- X{
- X /* debugging check */
- X if (start_row >= ptr->rows_in_array || ptr->mem_buffer == NULL)
- X ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
- X
- X /* Make the desired part of the virtual array accessible */
- X if (start_row < ptr->cur_start_row ||
- X start_row+ptr->unitheight > ptr->cur_start_row+ptr->rows_in_mem) {
- X if (! ptr->b_s_open)
- X ERREXIT(cinfo, JERR_VIRTUAL_BUG);
- X /* Flush old buffer contents if necessary */
- X if (ptr->dirty) {
- X do_sarray_io(cinfo, ptr, TRUE);
- X ptr->dirty = FALSE;
- X }
- X /* Decide what part of virtual array to access.
- X * Algorithm: if target address > current window, assume forward scan,
- X * load starting at target address. If target address < current window,
- X * assume backward scan, load so that target area is top of window.
- X * Note that when switching from forward write to forward read, will have
- X * start_row = 0, so the limiting case applies and we load from 0 anyway.
- X */
- X if (start_row > ptr->cur_start_row) {
- X ptr->cur_start_row = start_row;
- X } else {
- X /* use long arithmetic here to avoid overflow & unsigned problems */
- X long ltemp;
- X
- X ltemp = (long) start_row + (long) ptr->unitheight -
- X (long) ptr->rows_in_mem;
- X if (ltemp < 0)
- X ltemp = 0; /* don't fall off front end of file */
- X ptr->cur_start_row = (JDIMENSION) ltemp;
- X }
- X /* If reading, read in the selected part of the array.
- X * If we are writing, we need not pre-read the selected portion,
- X * since the access sequence constraints ensure it would be garbage.
- X */
- X if (! writable) {
- X do_sarray_io(cinfo, ptr, FALSE);
- X }
- X }
- X /* Flag the buffer dirty if caller will write in it */
- X if (writable)
- X ptr->dirty = TRUE;
- X /* Return address of proper part of the buffer */
- X return ptr->mem_buffer + (start_row - ptr->cur_start_row);
- X}
- X
- X
- XMETHODDEF JBLOCKARRAY
- Xaccess_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
- X JDIMENSION start_row, boolean writable)
- X/* Access the part of a virtual block array starting at start_row */
- X/* and extending for ptr->unitheight rows. writable is true if */
- X/* caller intends to modify the accessed area. */
- X{
- X /* debugging check */
- X if (start_row >= ptr->rows_in_array || ptr->mem_buffer == NULL)
- X ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
- X
- X /* Make the desired part of the virtual array accessible */
- X if (start_row < ptr->cur_start_row ||
- X start_row+ptr->unitheight > ptr->cur_start_row+ptr->rows_in_mem) {
- X if (! ptr->b_s_open)
- X ERREXIT(cinfo, JERR_VIRTUAL_BUG);
- X /* Flush old buffer contents if necessary */
- X if (ptr->dirty) {
- X do_barray_io(cinfo, ptr, TRUE);
- X ptr->dirty = FALSE;
- X }
- X /* Decide what part of virtual array to access.
- X * Algorithm: if target address > current window, assume forward scan,
- X * load starting at target address. If target address < current window,
- X * assume backward scan, load so that target area is top of window.
- X * Note that when switching from forward write to forward read, will have
- X * start_row = 0, so the limiting case applies and we load from 0 anyway.
- X */
- X if (start_row > ptr->cur_start_row) {
- X ptr->cur_start_row = start_row;
- X } else {
- X /* use long arithmetic here to avoid overflow & unsigned problems */
- X long ltemp;
- X
- X ltemp = (long) start_row + (long) ptr->unitheight -
- X (long) ptr->rows_in_mem;
- X if (ltemp < 0)
- X ltemp = 0; /* don't fall off front end of file */
- X ptr->cur_start_row = (JDIMENSION) ltemp;
- X }
- X /* If reading, read in the selected part of the array.
- X * If we are writing, we need not pre-read the selected portion,
- X * since the access sequence constraints ensure it would be garbage.
- X */
- X if (! writable) {
- X do_barray_io(cinfo, ptr, FALSE);
- X }
- X }
- X /* Flag the buffer dirty if caller will write in it */
- X if (writable)
- X ptr->dirty = TRUE;
- X /* Return address of proper part of the buffer */
- X return ptr->mem_buffer + (start_row - ptr->cur_start_row);
- X}
- X
- X
- X/*
- X * Release all objects belonging to a specified pool.
- X */
- X
- XMETHODDEF void
- Xfree_pool (j_common_ptr cinfo, int pool_id)
- X{
- X my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
- X small_pool_ptr shdr_ptr;
- X large_pool_ptr lhdr_ptr;
- X size_t space_freed;
- X
- X if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
- X ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
- X
- X#ifdef MEM_STATS
- X if (cinfo->err->trace_level > 1)
- X print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
- X#endif
- X
- X /* If freeing IMAGE pool, close any virtual arrays first */
- X if (pool_id == JPOOL_IMAGE) {
- X jvirt_sarray_ptr sptr;
- X jvirt_barray_ptr bptr;
- X
- X for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
- X if (sptr->b_s_open) { /* there may be no backing store */
- X sptr->b_s_open = FALSE; /* prevent recursive close if error */
- X (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
- X }
- X }
- X mem->virt_sarray_list = NULL;
- X for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
- X if (bptr->b_s_open) { /* there may be no backing store */
- X bptr->b_s_open = FALSE; /* prevent recursive close if error */
- X (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
- X }
- X }
- X mem->virt_barray_list = NULL;
- X }
- X
- X /* Release large objects */
- X lhdr_ptr = mem->large_list[pool_id];
- X mem->large_list[pool_id] = NULL;
- X
- X while (lhdr_ptr != NULL) {
- X large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
- X space_freed = lhdr_ptr->hdr.bytes_used +
- X lhdr_ptr->hdr.bytes_left +
- X SIZEOF(large_pool_hdr);
- X jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
- X mem->total_space_allocated -= space_freed;
- X lhdr_ptr = next_lhdr_ptr;
- X }
- X
- X /* Release small objects */
- X shdr_ptr = mem->small_list[pool_id];
- X mem->small_list[pool_id] = NULL;
- X
- X while (shdr_ptr != NULL) {
- X small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
- X space_freed = shdr_ptr->hdr.bytes_used +
- X shdr_ptr->hdr.bytes_left +
- X SIZEOF(small_pool_hdr);
- X jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
- X mem->total_space_allocated -= space_freed;
- X shdr_ptr = next_shdr_ptr;
- X }
- X}
- X
- X
- X/*
- X * Close up shop entirely.
- X * Note that this cannot be called unless cinfo->mem is non-NULL.
- X */
- X
- XMETHODDEF void
- Xself_destruct (j_common_ptr cinfo)
- X{
- X int pool;
- X
- X /* Close all backing store, release all memory.
- X * Releasing pools in reverse order might help avoid fragmentation
- X * with some (brain-damaged) malloc libraries.
- X */
- X for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
- X free_pool(cinfo, pool);
- X }
- X
- X /* Release the memory manager control block too. */
- X jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
- X cinfo->mem = NULL; /* ensures I will be called only once */
- X
- X jpeg_mem_term(cinfo); /* system-dependent cleanup */
- X}
- X
- X
- X/*
- X * Memory manager initialization.
- X * When this is called, only the error manager pointer is valid in cinfo!
- X */
- X
- XGLOBAL void
- Xjinit_memory_mgr (j_common_ptr cinfo)
- X{
- X my_mem_ptr mem;
- X long max_to_use;
- X int pool;
- X size_t test_mac;
- X
- X cinfo->mem = NULL; /* for safety if init fails */
- X
- X /* Check for configuration errors.
- X * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
- X * doesn't reflect any real hardware alignment requirement.
- X * The test is a little tricky: for X>0, X and X-1 have no one-bits
- X * in common if and only if X is a power of 2, ie has only one one-bit.
- X * Some compilers may give an "unreachable code" warning here; ignore it.
- X */
- X if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
- X ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
- X /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
- X * a multiple of SIZEOF(ALIGN_TYPE).
- X * Again, an "unreachable code" warning may be ignored here.
- X * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
- X */
- X test_mac = (size_t) MAX_ALLOC_CHUNK;
- X if ((long) test_mac != MAX_ALLOC_CHUNK ||
- X (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
- X ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
- X
- X max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
- X
- X /* Attempt to allocate memory manager's control block */
- X mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
- X
- X if (mem == NULL) {
- X jpeg_mem_term(cinfo); /* system-dependent cleanup */
- X ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
- X }
- X
- X /* OK, fill in the method pointers */
- X mem->pub.alloc_small = alloc_small;
- X mem->pub.alloc_large = alloc_large;
- X mem->pub.alloc_sarray = alloc_sarray;
- X mem->pub.alloc_barray = alloc_barray;
- X mem->pub.request_virt_sarray = request_virt_sarray;
- X mem->pub.request_virt_barray = request_virt_barray;
- X mem->pub.realize_virt_arrays = realize_virt_arrays;
- X mem->pub.access_virt_sarray = access_virt_sarray;
- X mem->pub.access_virt_barray = access_virt_barray;
- X mem->pub.free_pool = free_pool;
- X mem->pub.self_destruct = self_destruct;
- X
- X /* Initialize working state */
- X mem->pub.max_memory_to_use = max_to_use;
- X
- X for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
- X mem->small_list[pool] = NULL;
- X mem->large_list[pool] = NULL;
- X }
- X mem->virt_sarray_list = NULL;
- X mem->virt_barray_list = NULL;
- X
- X mem->total_space_allocated = SIZEOF(my_memory_mgr);
- X
- X /* Declare ourselves open for business */
- X cinfo->mem = & mem->pub;
- X
- X /* Check for an environment variable JPEGMEM; if found, override the
- X * default max_memory setting from jpeg_mem_init. Note that the
- X * surrounding application may again override this value.
- X * If your system doesn't support getenv(), define NO_GETENV to disable
- X * this feature.
- X */
- X#ifndef NO_GETENV
- X { char * memenv;
- X
- X if ((memenv = getenv("JPEGMEM")) != NULL) {
- X char ch = 'x';
- X
- X if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
- X if (ch == 'm' || ch == 'M')
- X max_to_use *= 1000L;
- X mem->pub.max_memory_to_use = max_to_use * 1000L;
- X }
- X }
- X }
- X#endif
- X
- X}
- END_OF_FILE
- if test 38963 -ne `wc -c <'jmemmgr.c'`; then
- echo shar: \"'jmemmgr.c'\" unpacked with wrong size!
- fi
- # end of 'jmemmgr.c'
- fi
- if test -f 'jversion.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jversion.h'\"
- else
- echo shar: Extracting \"'jversion.h'\" \(357 characters\)
- sed "s/^X//" >'jversion.h' <<'END_OF_FILE'
- X/*
- X * jversion.h
- X *
- X * Copyright (C) 1991-1994, 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 software version identification.
- X */
- X
- X
- X#define JVERSION "5 24-Sep-94"
- X
- X#define JCOPYRIGHT "Copyright (C) 1994, Thomas G. Lane"
- END_OF_FILE
- if test 357 -ne `wc -c <'jversion.h'`; then
- echo shar: \"'jversion.h'\" unpacked with wrong size!
- fi
- # end of 'jversion.h'
- fi
- echo shar: End of archive 1 \(of 27\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 27 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...
-