USING THE IJG JPEG LIBRARY Copyright (C) 1994-1998, Thomas G. Lane.This file is part of the Independent JPEG Group's software.For conditions of distribution and use, see the accompanying README file. This file describes how to use the IJG JPEG library within an applicationprogram. Read it if you want to write a program that uses the library. The file example.c provides heavily commented skeleton code for calling theJPEG library. Also see jpeglib.h (the include file to be used by applicationprograms) for full details about data structures and function parameter lists.The library source code, of course, is the ultimate reference. Note that there have been *major* changes from the application interfacepresented by IJG version 4 and earlier versions. The old design had severalinherent limitations, and it had accumulated a lot of cruft as we addedfeatures while trying to minimize application-interface changes. We havesacrificed backward compatibility in the version 5 rewrite, but we think theimprovements justify this. TABLE OF CONTENTS----------------- Overview: Functions provided by the library Outline of typical usageBasic library usage: Data formats Compression details Decompression details Mechanics of usage: include files, linking, etcAdvanced features: Compression parameter selection Decompression parameter selection Special color spaces Error handling Compressed data handling (source and destination managers) I/O suspension Progressive JPEG support Buffered-image mode Abbreviated datastreams and multiple images Special markers Raw (downsampled) image data Really raw data: DCT coefficients Progress monitoring Memory management Memory usage Library compile-time options Portability considerations Notes for MS-DOS implementors You should read at least the overview and basic usage sections before tryingto program with the library. The sections on advanced features can be readif and when you need them. OVERVIEW======== Functions provided by the library--------------------------------- The IJG JPEG library provides C code to read and write JPEG-compressed imagefiles. The surrounding application program receives or supplies image data ascanline at a time, using a straightforward uncompressed image format. Alldetails of color conversion and other preprocessing/postprocessing can behandled by the library. The library includes a substantial amount of code that is not covered by theJPEG standard but is necessary for typical applications of JPEG. Thesefunctions preprocess the image before JPEG compression or postprocess it afterdecompression. They include colorspace conversion, downsampling/upsampling,and color quantization. The application indirectly selects use of this codeby specifying the format in which it wishes to supply or receive image data.For example, if colormapped output is requested, then the decompressionlibrary automatically invokes color quantization. A wide range of quality vs. speed tradeoffs are possible in JPEG processing,and even more so in decompression postprocessing. The decompression libraryprovides multiple implementations that cover most of the useful tradeoffs,ranging from very-high-quality down to fast-preview operation. On thecompression side we have generally not provided low-quality choices, sincecompression is normally less time-critical. It should be understood that thelow-quality modes may not meet the JPEG standard's accuracy requirements;nonetheless, they are useful for viewers. A word about functions *not* provided by the library. We handle a subset ofthe ISO JPEG standard; most baseline, extended-sequential, and progressiveJPEG processes are supported. (Our subset includes all features now in commonuse.) Unsupported ISO options include: * Hierarchical storage * Lossless JPEG * Arithmetic entropy coding (unsupported for legal reasons) * DNL marker * Nonintegral subsampling ratiosWe support both 8- and 12-bit data precision, but this is a compile-timechoice rather than a run-time choice; hence it is difficult to use bothprecisions in a single application. By itself, the library handles only interchange JPEG datastreams --- inparticular the widely used JFIF file format. The library can be used bysurrounding code to process interchange or abbreviated JPEG datastreams thatare embedded in more complex file formats. (For example, this library isused by the free LIBTIFF library to support JPEG compression in TIFF.) Outline of typical usage------------------------ The rough outline of a JPEG compression operation is: Allocate and initialize a JPEG compression object Specify the destination for the compressed data (eg, a file) Set parameters for compression, including image size & colorspace jpeg_start_compress(...); while (scan lines remain to be written) jpeg_write_scanlines(...); jpeg_finish_compress(...); Release the JPEG compression object A JPEG compression object holds parameters and working state for the JPEGlibrary. We make creation/destruction of the object separate from startingor finishing compression of an image; the same object can be re-used for aseries of image compression operations. This makes it easy to re-use thesame parameter settings for a sequence of images. Re-use of a JPEG objectalso has important implications for processing abbreviated JPEG datastreams,as discussed later. The image data to be compressed is supplied to jpeg_write_scanlines() fromin-memory buffers. If the application is doing file-to-file compression,reading image data from the source file is the application's responsibility.The library emits compressed data by calling a "data destination manager",which typically will write the data into a file; but the application canprovide its own destination manager to do something else. Similarly, the rough outline of a JPEG decompression operation is: Allocate and initialize a JPEG decompression object Specify the source of the compressed data (eg, a file) Call jpeg_read_header() to obtain image info Set parameters for decompression jpeg_start_decompress(...); while (scan lines remain to be read) jpeg_read_scanlines(...); jpeg_finish_decompress(...); Release the JPEG decompression object This is comparable to the compression outline except that reading thedatastream header is a separate step. This is helpful because informationabout the image's size, colorspace, etc is available when the applicationselects decompression parameters. For example, the application can choose anoutput scaling ratio that will fit the image into the available screen size. The decompression library obtains compressed data by calling a data sourcemanager, which typically will read the data from a file; but other behaviorscan be obtained with a custom source manager. Decompressed data is deliveredinto in-memory buffers passed to jpeg_read_scanlines(). It is possible to abort an incomplete compression or decompression operationby calling jpeg_abort(); or, if you do not need to retain the JPEG object,simply release it by calling jpeg_destroy(). JPEG compression and decompression objects are two separate struct types.However, they share some common fields, and certain routines such asjpeg_destroy() can work on either type of object. The JPEG library has no static variables: all state is in the compressionor decompression object. Therefore it is possible to process multiplecompression and decompression operations concurrently, using multiple JPEGobjects. Both compression and decompression can be done in an incremental memory-to-memory fashion, if suitable source/destination managers are used. See thesection on "I/O suspension" for more details. BASIC LIBRARY USAGE=================== Data formats------------ Before diving into procedural details, it is helpful to understand theimage data format that the JPEG library expects or returns. The standard input image format is a rectangular array of pixels, with eachpixel having the same number of "component" or "sample" values (colorchannels). You must specify how many components there are and the colorspaceinterpretation of the components. Most applications will use RGB data(three components per pixel) or grayscale data (one component per pixel).PLEASE NOTE THAT RGB DATA IS THREE SAMPLES PER PIXEL, GRAYSCALE ONLY ONE.A remarkable number of people manage to miss this, only to find that theirprograms don't work with grayscale JPEG files. There is no provision for colormapped input. JPEG files are always full-coloror full grayscale (or sometimes another colorspace such as CMYK). You canfeed in a colormapped image by expanding it to full-color format. HoweverJPEG often doesn't work very well with source data that has been colormapped,because of dithering noise. This is discussed in more detail in the JPEG FAQand the other references mentioned in the README file. Pixels are stored by scanlines, with each scanline running from left toright. The component values for each pixel are adjacent in the row; forexample, R,G,B,R,G,B,R,G,B,... for 24-bit RGB color. Each scanline is anarray of data type JSAMPLE --- which is typically "unsigned char", unlessyou've changed jmorecfg.h. (You can also change the RGB pixel layout, sayto B,G,R order, by modifying jmorecfg.h. But see the restrictions listed inthat file before doing so.) A 2-D array of pixels is formed by making a list of pointers to the starts ofscanlines; so the scanlines need not be physically adjacent in memory. Evenif you process just one scanline at a time, you must make a one-elementpointer array to conform to this structure. Pointers to JSAMPLE rows are oftype JSAMPROW, and the pointer to the pointer array is of type JSAMPARRAY. The library accepts or supplies one or more complete scanlines per call.It is not possible to process part of a row at a time. Scanlines are alwaysprocessed top-to-bottom. You can process an entire image in one call if youhave it all in memory, but usually it's simplest to process one scanline ata time. For best results, source data values should have the precision specified byBITS_IN_JSAMPLE (normally 8 bits). For instance, if you choose to compressdata that's only 6 bits/channel, you should left-justify each value in abyte before passing it to the compressor. If you need to compress datathat has more than 8 bits/channel, compile with BITS_IN_JSAMPLE = 12.(See "Library compile-time options", later.) The data format returned by the decompressor is the same in all details,except that colormapped output is supported. (Again, a JPEG file is nevercolormapped. But you can ask the decompressor to perform on-the-fly colorquantization to deliver colormapped output.) If you request colormappedoutput then the returned data array contains a single JSAMPLE per pixel;its value is an index into a color map. The color map is represented asa 2-D JSAMPARRAY in which each row holds the values of one color component,that is, colormap[i][j] is the value of the i'th color component for pixelvalue (map index) j. Note that since the colormap indexes are stored inJSAMPLEs, the maximum number of colors is limited by the size of JSAMPLE(ie, at most 256 colors for an 8-bit JPEG library). Compression details------------------- Here we revisit the JPEG compression outline given in the overview. 1. Allocate and initialize a JPEG compression object. A JPEG compression object is a "struct jpeg_compress_struct". (It also hasa bunch of subsidiary structures which are allocated via malloc(), but theapplication doesn't control those directly.) This struct can be just a localvariable in the calling routine, if a single routine is going to execute thewhole JPEG compression sequence. Otherwise it can be static or allocatedfrom malloc(). You will also need a structure representing a JPEG error handler. The partof this that the library cares about is a "struct jpeg_error_mgr". If youare providing your own error handler, you'll typically want to embed thejpeg_error_mgr struct in a larger structure; this is discussed later under"Error handling". For now we'll assume you are just using the default errorhandler. The default error handler will print JPEG error/warning messageson stderr, and it will call exit() if a fatal error occurs. You must initialize the error handler structure, store a pointer to it intothe JPEG object's "err" field, and then call jpeg_create_compress() toinitialize the rest of the JPEG object. Typical code for this step, if you are using the default error handler, is struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; ... cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_create_compress allocates a small amount of memory, so it could failif you are out of memory. In that case it will exit via the error handler;that's why the error handler must be initialized first. 2. Specify the destination for the compressed data (eg, a file). As previously mentioned, the JPEG library delivers compressed data to a"data destination" module. The library includes one data destinationmodule which knows how to write to a stdio stream. You can use your owndestination module if you want to do something else, as discussed later. If you use the standard destination module, you must open the target stdiostream beforehand. Typical code for this step looks like: FILE * outfile; ... if ((outfile = fopen(filename, "wb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); exit(1); } jpeg_stdio_dest(&cinfo, outfile); where the last line invokes the standard destination module. WARNING: it is critical that the binary compressed data be delivered to theoutput file unchanged. On non-Unix systems the stdio library may performnewline translation or otherwise corrupt binary data. To suppress thisbehavior, you may need to use a "b" option to fopen (as shown above), or usesetmode() or another routine to put the stdio stream in binary mode. Seecjpeg.c and djpeg.c for code that has been found to work on many systems. You can select the data destination after setting other parameters (step 3),if that's more convenient. You may not change the destination betweencalling jpeg_start_compress() and jpeg_finish_compress(). 3. Set parameters for compression, including image size & colorspace. You must supply information about the source image by setting the followingfields in the JPEG object (cinfo structure): image_width Width of image, in pixels image_height Height of image, in pixels input_components Number of color channels (samples per pixel) in_color_space Color space of source image The image dimensions are, hopefully, obvious. JPEG supports image dimensionsof 1 to 64K pixels in either direction. The input color space is typicallyRGB or grayscale, and input_components is 3 or 1 accordingly. (See "Specialcolor spaces", later, for more info.) The in_color_space field must beassigned one of the J_COLOR_SPACE enum constants, typically JCS_RGB orJCS_GRAYSCALE. JPEG has a large number of compression parameters that determine how theimage is encoded. Most applications don't need or want to know about allthese parameters. You can set all the parameters to reasonable defaults bycalling jpeg_set_defaults(); then, if there are particular values you wantto change, you can do so after that. The "Compression parameter selection"section tells about all the parameters. You must set in_color_space correctly before calling jpeg_set_defaults(),because the defaults depend on the source image colorspace. However theother three source image parameters need not be valid until you calljpeg_start_compress(). There's no harm in calling jpeg_set_defaults() morethan once, if that happens to be convenient. Typical code for a 24-bit RGB source image is cinfo.image_width = Width; /* image width and height, in pixels */ cinfo.image_height = Height; cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ jpeg_set_defaults(&cinfo); /* Make optional parameter settings here */ 4. jpeg_start_compress(...); After you have established the data destination and set all the necessarysource image info and other parameters, call jpeg_start_compress() to begina compression cycle. This will initialize internal state, allocate workingstorage, and emit the first few bytes of the JPEG datastream header. Typical code: jpeg_start_compress(&cinfo, TRUE); The "TRUE" parameter ensures that a complete JPEG interchange datastreamwill be written. This is appropriate in most cases. If you think you mightwant to use an abbreviated datastream, read the section on abbreviateddatastreams, below. Once you have called jpeg_start_compress(), you may not alter any JPEGparameters or other fields of the JPEG object until you have completedthe compression cycle. 5. while (scan lines remain to be written) jpeg_write_scanlines(...); Now write all the required image data by calling jpeg_write_scanlines()one or more times. You can pass one or more scanlines in each call, upto the total image height. In most applications it is convenient to passjust one or a few scanlines at a time. The expected format for the passeddata is discussed under "Data formats", above. Image data should be written in top-to-bottom scanline order. The JPEG speccontains some weasel wording about how top and bottom are application-definedterms (a curious interpretation of the English language...) but if you wantyour files to be compatible with everyone else's, you WILL use top-to-bottomorder. If the source data must be read in bottom-to-top order, you can usethe JPEG library's virtual array mechanism to invert the data efficiently.Examples of this can be found in the sample application cjpeg. The library maintains a count of the number of scanlines written so farin the next_scanline field of the JPEG object. Usually you can just usethis variable as the loop counter, so that the loop test looks like"while (cinfo.next_scanline < cinfo.image_height)". Code for this step depends heavily on the way that you store the source data.example.c shows the following code for the case of a full-size 2-D sourcearray containing 3-byte RGB pixels: JSAMPROW row_pointer[1]; /* pointer to a single row */ int row_stride; /* physical row width in buffer */ row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */ while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_write_scanlines() returns the number of scanlines actually written.This will normally be equal to the number passed in, so you can usuallyignore the return value. It is different in just two cases: * If you try to write more scanlines than the declared image height, the additional scanlines are ignored. * If you use a suspending data destination manager, output buffer overrun will cause the compressor to return before accepting all the passed lines. This feature is discussed under "I/O suspension", below. The normal stdio destination manager will NOT cause this to happen.In any case, the return value is the same as the change in the value ofnext_scanline. 6. jpeg_finish_compress(...); After all the image data has been written, call jpeg_finish_compress() tocomplete the compression cycle. This step is ESSENTIAL to ensure that thelast bufferload of data is written to the data destination.jpeg_finish_compress() also releases working memory associated with the JPEGobject. Typical code: jpeg_finish_compress(&cinfo); If using the stdio destination manager, don't forget to close the outputstdio stream (if necessary) afterwards. If you have requested a multi-pass operating mode, such as Huffman codeoptimization, jpeg_finish_compress() will perform the additional passes usingdata buffered by the first pass. In this case jpeg_finish_compress() may takequite a while to complete. With the default compression parameters, this willnot happen. It is an error to call jpeg_finish_compress() before writing the necessarytotal number of scanlines. If you wish to abort compression, calljpeg_abort() as discussed below. After completing a compression cycle, you may dispose of the JPEG objectas discussed next, or you may use it to compress another image. In that casereturn to step 2, 3, or 4 as appropriate. If you do not change thedestination manager, the new datastream will be written to the same target.If you do not change any JPEG parameters, the new datastream will be writtenwith the same parameters as before. Note that you can change the input imagedimensions freely between cycles, but if you change the input colorspace, youshould call jpeg_set_defaults() to adjust for the new colorspace; and thenyou'll need to repeat all of step 3. 7. Release the JPEG compression object. When you are done with a JPEG compression object, destroy it by callingjpeg_destroy_compress(). This will free all subsidiary memory (regardless ofthe previous state of the object). Or you can call jpeg_destroy(), whichworks for either compression or decompression objects --- this may be moreconvenient if you are sharing code between compression and decompressioncases. (Actually, these routines are equivalent except for the declared typeof the passed pointer. To avoid gripes from ANSI C compilers, jpeg_destroy()should be passed a j_common_ptr.) If you allocated the jpeg_compress_struct structure from malloc(), freeingit is your responsibility --- jpeg_destroy() won't. Ditto for the errorhandler structure. Typical code: jpeg_destroy_compress(&cinfo); 8. Aborting. If you decide to abort a compression cycle before finishing, you can clean upin either of two ways: * If you don't need the JPEG object any more, just call jpeg_destroy_compress() or jpeg_destroy() to release memory. This is legitimate at any point after calling jpeg_create_compress() --- in fact, it's safe even if jpeg_create_compress() fails. * If you want to re-use the JPEG object, call jpeg_abort_compress(), or call jpeg_abort() which works on both compression and decompression objects. This will return the object to an idle state, releasing any working memory. jpeg_abort() is allowed at any time after successful object creation. Note that cleaning up the data destination, if required, is yourresponsibility; neither of these routines will call term_destination().Lines 1–500 of 3006. Load more
USING THE IJG JPEG LIBRARY Copyright (C) 1994-1998, Thomas G. Lane. This file is part of the Independent JPEG Group's software. For conditions of distribution and use, see the accompanying README file. This file describes how to use the IJG JPEG library within an application program. Read it if you want to write a program that uses the library. The file example.c provides heavily commented skeleton code for calling the JPEG library. Also see jpeglib.h (the include file to be used by application programs) for full details about data structures and function parameter lists. The library source code, of course, is the ultimate reference. Note that there have been *major* changes from the application interface presented by IJG version 4 and earlier versions. The old design had several inherent limitations, and it had accumulated a lot of cruft as we added features while trying to minimize application-interface changes. We have sacrificed backward compatibility in the version 5 rewrite, but we think the improvements justify this. TABLE OF CONTENTS ----------------- Overview: Functions provided by the library Outline of typical usage Basic library usage: Data formats Compression details Decompression details Mechanics of usage: include files, linking, etc Advanced features: Compression parameter selection Decompression parameter selection Special color spaces Error handling Compressed data handling (source and destination managers) I/O suspension Progressive JPEG support Buffered-image mode Abbreviated datastreams and multiple images Special markers Raw (downsampled) image data Really raw data: DCT coefficients Progress monitoring Memory management Memory usage Library compile-time options Portability considerations Notes for MS-DOS implementors You should read at least the overview and basic usage sections before trying to program with the library. The sections on advanced features can be read if and when you need them. OVERVIEW ======== Functions provided by the library --------------------------------- The IJG JPEG library provides C code to read and write JPEG-compressed image files. The surrounding application program receives or supplies image data a scanline at a time, using a straightforward uncompressed image format. All details of color conversion and other preprocessing/postprocessing can be handled by the library. The library includes a substantial amount of code that is not covered by the JPEG standard but is necessary for typical applications of JPEG. These functions preprocess the image before JPEG compression or postprocess it after decompression. They include colorspace conversion, downsampling/upsampling, and color quantization. The application indirectly selects use of this code by specifying the format in which it wishes to supply or receive image data. For example, if colormapped output is requested, then the decompression library automatically invokes color quantization. A wide range of quality vs. speed tradeoffs are possible in JPEG processing, and even more so in decompression postprocessing. The decompression library provides multiple implementations that cover most of the useful tradeoffs, ranging from very-high-quality down to fast-preview operation. On the compression side we have generally not provided low-quality choices, since compression is normally less time-critical. It should be understood that the low-quality modes may not meet the JPEG standard's accuracy requirements; nonetheless, they are useful for viewers. A word about functions *not* provided by the library. We handle a subset of the ISO JPEG standard; most baseline, extended-sequential, and progressive JPEG processes are supported. (Our subset includes all features now in common use.) Unsupported ISO options include: * Hierarchical storage * Lossless JPEG * Arithmetic entropy coding (unsupported for legal reasons) * DNL marker * Nonintegral subsampling ratios We support both 8- and 12-bit data precision, but this is a compile-time choice rather than a run-time choice; hence it is difficult to use both precisions in a single application. By itself, the library handles only interchange JPEG datastreams --- in particular the widely used JFIF file format. The library can be used by surrounding code to process interchange or abbreviated JPEG datastreams that are embedded in more complex file formats. (For example, this library is used by the free LIBTIFF library to support JPEG compression in TIFF.) Outline of typical usage ------------------------ The rough outline of a JPEG compression operation is: Allocate and initialize a JPEG compression object Specify the destination for the compressed data (eg, a file) Set parameters for compression, including image size & colorspace jpeg_start_compress(...); while (scan lines remain to be written) jpeg_write_scanlines(...); jpeg_finish_compress(...); Release the JPEG compression object A JPEG compression object holds parameters and working state for the JPEG library. We make creation/destruction of the object separate from starting or finishing compression of an image; the same object can be re-used for a series of image compression operations. This makes it easy to re-use the same parameter settings for a sequence of images. Re-use of a JPEG object also has important implications for processing abbreviated JPEG datastreams, as discussed later. The image data to be compressed is supplied to jpeg_write_scanlines() from in-memory buffers. If the application is doing file-to-file compression, reading image data from the source file is the application's responsibility. The library emits compressed data by calling a "data destination manager", which typically will write the data into a file; but the application can provide its own destination manager to do something else. Similarly, the rough outline of a JPEG decompression operation is: Allocate and initialize a JPEG decompression object Specify the source of the compressed data (eg, a file) Call jpeg_read_header() to obtain image info Set parameters for decompression jpeg_start_decompress(...); while (scan lines remain to be read) jpeg_read_scanlines(...); jpeg_finish_decompress(...); Release the JPEG decompression object This is comparable to the compression outline except that reading the datastream header is a separate step. This is helpful because information about the image's size, colorspace, etc is available when the application selects decompression parameters. For example, the application can choose an output scaling ratio that will fit the image into the available screen size. The decompression library obtains compressed data by calling a data source manager, which typically will read the data from a file; but other behaviors can be obtained with a custom source manager. Decompressed data is delivered into in-memory buffers passed to jpeg_read_scanlines(). It is possible to abort an incomplete compression or decompression operation by calling jpeg_abort(); or, if you do not need to retain the JPEG object, simply release it by calling jpeg_destroy(). JPEG compression and decompression objects are two separate struct types. However, they share some common fields, and certain routines such as jpeg_destroy() can work on either type of object. The JPEG library has no static variables: all state is in the compression or decompression object. Therefore it is possible to process multiple compression and decompression operations concurrently, using multiple JPEG objects. Both compression and decompression can be done in an incremental memory-to- memory fashion, if suitable source/destination managers are used. See the section on "I/O suspension" for more details. BASIC LIBRARY USAGE =================== Data formats ------------ Before diving into procedural details, it is helpful to understand the image data format that the JPEG library expects or returns. The standard input image format is a rectangular array of pixels, with each pixel having the same number of "component" or "sample" values (color channels). You must specify how many components there are and the colorspace interpretation of the components. Most applications will use RGB data (three components per pixel) or grayscale data (one component per pixel). PLEASE NOTE THAT RGB DATA IS THREE SAMPLES PER PIXEL, GRAYSCALE ONLY ONE. A remarkable number of people manage to miss this, only to find that their programs don't work with grayscale JPEG files. There is no provision for colormapped input. JPEG files are always full-color or full grayscale (or sometimes another colorspace such as CMYK). You can feed in a colormapped image by expanding it to full-color format. However JPEG often doesn't work very well with source data that has been colormapped, because of dithering noise. This is discussed in more detail in the JPEG FAQ and the other references mentioned in the README file. Pixels are stored by scanlines, with each scanline running from left to right. The component values for each pixel are adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit RGB color. Each scanline is an array of data type JSAMPLE --- which is typically "unsigned char", unless you've changed jmorecfg.h. (You can also change the RGB pixel layout, say to B,G,R order, by modifying jmorecfg.h. But see the restrictions listed in that file before doing so.) A 2-D array of pixels is formed by making a list of pointers to the starts of scanlines; so the scanlines need not be physically adjacent in memory. Even if you process just one scanline at a time, you must make a one-element pointer array to conform to this structure. Pointers to JSAMPLE rows are of type JSAMPROW, and the pointer to the pointer array is of type JSAMPARRAY. The library accepts or supplies one or more complete scanlines per call. It is not possible to process part of a row at a time. Scanlines are always processed top-to-bottom. You can process an entire image in one call if you have it all in memory, but usually it's simplest to process one scanline at a time. For best results, source data values should have the precision specified by BITS_IN_JSAMPLE (normally 8 bits). For instance, if you choose to compress data that's only 6 bits/channel, you should left-justify each value in a byte before passing it to the compressor. If you need to compress data that has more than 8 bits/channel, compile with BITS_IN_JSAMPLE = 12. (See "Library compile-time options", later.) The data format returned by the decompressor is the same in all details, except that colormapped output is supported. (Again, a JPEG file is never colormapped. But you can ask the decompressor to perform on-the-fly color quantization to deliver colormapped output.) If you request colormapped output then the returned data array contains a single JSAMPLE per pixel; its value is an index into a color map. The color map is represented as a 2-D JSAMPARRAY in which each row holds the values of one color component, that is, colormap[i][j] is the value of the i'th color component for pixel value (map index) j. Note that since the colormap indexes are stored in JSAMPLEs, the maximum number of colors is limited by the size of JSAMPLE (ie, at most 256 colors for an 8-bit JPEG library). Compression details ------------------- Here we revisit the JPEG compression outline given in the overview. 1. Allocate and initialize a JPEG compression object. A JPEG compression object is a "struct jpeg_compress_struct". (It also has a bunch of subsidiary structures which are allocated via malloc(), but the application doesn't control those directly.) This struct can be just a local variable in the calling routine, if a single routine is going to execute the whole JPEG compression sequence. Otherwise it can be static or allocated from malloc(). You will also need a structure representing a JPEG error handler. The part of this that the library cares about is a "struct jpeg_error_mgr". If you are providing your own error handler, you'll typically want to embed the jpeg_error_mgr struct in a larger structure; this is discussed later under "Error handling". For now we'll assume you are just using the default error handler. The default error handler will print JPEG error/warning messages on stderr, and it will call exit() if a fatal error occurs. You must initialize the error handler structure, store a pointer to it into the JPEG object's "err" field, and then call jpeg_create_compress() to initialize the rest of the JPEG object. Typical code for this step, if you are using the default error handler, is struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; ... cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_create_compress allocates a small amount of memory, so it could fail if you are out of memory. In that case it will exit via the error handler; that's why the error handler must be initialized first. 2. Specify the destination for the compressed data (eg, a file). As previously mentioned, the JPEG library delivers compressed data to a "data destination" module. The library includes one data destination module which knows how to write to a stdio stream. You can use your own destination module if you want to do something else, as discussed later. If you use the standard destination module, you must open the target stdio stream beforehand. Typical code for this step looks like: FILE * outfile; ... if ((outfile = fopen(filename, "wb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); exit(1); } jpeg_stdio_dest(&cinfo, outfile); where the last line invokes the standard destination module. WARNING: it is critical that the binary compressed data be delivered to the output file unchanged. On non-Unix systems the stdio library may perform newline translation or otherwise corrupt binary data. To suppress this behavior, you may need to use a "b" option to fopen (as shown above), or use setmode() or another routine to put the stdio stream in binary mode. See cjpeg.c and djpeg.c for code that has been found to work on many systems. You can select the data destination after setting other parameters (step 3), if that's more convenient. You may not change the destination between calling jpeg_start_compress() and jpeg_finish_compress(). 3. Set parameters for compression, including image size & colorspace. You must supply information about the source image by setting the following fields in the JPEG object (cinfo structure): image_width Width of image, in pixels image_height Height of image, in pixels input_components Number of color channels (samples per pixel) in_color_space Color space of source image The image dimensions are, hopefully, obvious. JPEG supports image dimensions of 1 to 64K pixels in either direction. The input color space is typically RGB or grayscale, and input_components is 3 or 1 accordingly. (See "Special color spaces", later, for more info.) The in_color_space field must be assigned one of the J_COLOR_SPACE enum constants, typically JCS_RGB or JCS_GRAYSCALE. JPEG has a large number of compression parameters that determine how the image is encoded. Most applications don't need or want to know about all these parameters. You can set all the parameters to reasonable defaults by calling jpeg_set_defaults(); then, if there are particular values you want to change, you can do so after that. The "Compression parameter selection" section tells about all the parameters. You must set in_color_space correctly before calling jpeg_set_defaults(), because the defaults depend on the source image colorspace. However the other three source image parameters need not be valid until you call jpeg_start_compress(). There's no harm in calling jpeg_set_defaults() more than once, if that happens to be convenient. Typical code for a 24-bit RGB source image is cinfo.image_width = Width; /* image width and height, in pixels */ cinfo.image_height = Height; cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ jpeg_set_defaults(&cinfo); /* Make optional parameter settings here */ 4. jpeg_start_compress(...); After you have established the data destination and set all the necessary source image info and other parameters, call jpeg_start_compress() to begin a compression cycle. This will initialize internal state, allocate working storage, and emit the first few bytes of the JPEG datastream header. Typical code: jpeg_start_compress(&cinfo, TRUE); The "TRUE" parameter ensures that a complete JPEG interchange datastream will be written. This is appropriate in most cases. If you think you might want to use an abbreviated datastream, read the section on abbreviated datastreams, below. Once you have called jpeg_start_compress(), you may not alter any JPEG parameters or other fields of the JPEG object until you have completed the compression cycle. 5. while (scan lines remain to be written) jpeg_write_scanlines(...); Now write all the required image data by calling jpeg_write_scanlines() one or more times. You can pass one or more scanlines in each call, up to the total image height. In most applications it is convenient to pass just one or a few scanlines at a time. The expected format for the passed data is discussed under "Data formats", above. Image data should be written in top-to-bottom scanline order. The JPEG spec contains some weasel wording about how top and bottom are application-defined terms (a curious interpretation of the English language...) but if you want your files to be compatible with everyone else's, you WILL use top-to-bottom order. If the source data must be read in bottom-to-top order, you can use the JPEG library's virtual array mechanism to invert the data efficiently. Examples of this can be found in the sample application cjpeg. The library maintains a count of the number of scanlines written so far in the next_scanline field of the JPEG object. Usually you can just use this variable as the loop counter, so that the loop test looks like "while (cinfo.next_scanline < cinfo.image_height)". Code for this step depends heavily on the way that you store the source data. example.c shows the following code for the case of a full-size 2-D source array containing 3-byte RGB pixels: JSAMPROW row_pointer[1]; /* pointer to a single row */ int row_stride; /* physical row width in buffer */ row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */ while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_write_scanlines() returns the number of scanlines actually written. This will normally be equal to the number passed in, so you can usually ignore the return value. It is different in just two cases: * If you try to write more scanlines than the declared image height, the additional scanlines are ignored. * If you use a suspending data destination manager, output buffer overrun will cause the compressor to return before accepting all the passed lines. This feature is discussed under "I/O suspension", below. The normal stdio destination manager will NOT cause this to happen. In any case, the return value is the same as the change in the value of next_scanline. 6. jpeg_finish_compress(...); After all the image data has been written, call jpeg_finish_compress() to complete the compression cycle. This step is ESSENTIAL to ensure that the last bufferload of data is written to the data destination. jpeg_finish_compress() also releases working memory associated with the JPEG object. Typical code: jpeg_finish_compress(&cinfo); If using the stdio destination manager, don't forget to close the output stdio stream (if necessary) afterwards. If you have requested a multi-pass operating mode, such as Huffman code optimization, jpeg_finish_compress() will perform the additional passes using data buffered by the first pass. In this case jpeg_finish_compress() may take quite a while to complete. With the default compression parameters, this will not happen. It is an error to call jpeg_finish_compress() before writing the necessary total number of scanlines. If you wish to abort compression, call jpeg_abort() as discussed below. After completing a compression cycle, you may dispose of the JPEG object as discussed next, or you may use it to compress another image. In that case return to step 2, 3, or 4 as appropriate. If you do not change the destination manager, the new datastream will be written to the same target. If you do not change any JPEG parameters, the new datastream will be written with the same parameters as before. Note that you can change the input image dimensions freely between cycles, but if you change the input colorspace, you should call jpeg_set_defaults() to adjust for the new colorspace; and then you'll need to repeat all of step 3. 7. Release the JPEG compression object. When you are done with a JPEG compression object, destroy it by calling jpeg_destroy_compress(). This will free all subsidiary memory (regardless of the previous state of the object). Or you can call jpeg_destroy(), which works for either compression or decompression objects --- this may be more convenient if you are sharing code between compression and decompression cases. (Actually, these routines are equivalent except for the declared type of the passed pointer. To avoid gripes from ANSI C compilers, jpeg_destroy() should be passed a j_common_ptr.) If you allocated the jpeg_compress_struct structure from malloc(), freeing it is your responsibility --- jpeg_destroy() won't. Ditto for the error handler structure. Typical code: jpeg_destroy_compress(&cinfo); 8. Aborting. If you decide to abort a compression cycle before finishing, you can clean up in either of two ways: * If you don't need the JPEG object any more, just call jpeg_destroy_compress() or jpeg_destroy() to release memory. This is legitimate at any point after calling jpeg_create_compress() --- in fact, it's safe even if jpeg_create_compress() fails. * If you want to re-use the JPEG object, call jpeg_abort_compress(), or call jpeg_abort() which works on both compression and decompression objects. This will return the object to an idle state, releasing any working memory. jpeg_abort() is allowed at any time after successful object creation. Note that cleaning up the data destination, if required, is your responsibility; neither of these routines will call term_destination().