Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/LibJPEG/libjpeg.txt  view on Meta::CPAN

provide this test since it has no idea whether "the buffer is full", or
even whether there is a fixed-size input buffer.)

The input buffer would need to be 64K to allow for arbitrary COM or APPn
markers, but these are handled specially: they are either saved into allocated
memory, or skipped over by calling skip_input_data().  In the former case,
suspension is handled correctly, and in the latter case, the problem of
buffer overrun is placed on skip_input_data's shoulders, as explained above.
Note that if you provide your own marker handling routine for large markers,
you should consider how to deal with buffer overflow.

Multiple-buffer management:

In some applications it is desirable to store the compressed data in a linked
list of buffer areas, so as to avoid data copying.  This can be handled by
having empty_output_buffer() or fill_input_buffer() set the pointer and count
to reference the next available buffer; FALSE is returned only if no more
buffers are available.  Although seemingly straightforward, there is a
pitfall in this approach: the backtrack that occurs when FALSE is returned
could back up into an earlier buffer.  For example, when fill_input_buffer()
is called, the current pointer & count indicate the backtrack restart point.
Since fill_input_buffer() will set the pointer and count to refer to a new
buffer, the restart position must be saved somewhere else.  Suppose a second
call to fill_input_buffer() occurs in the same library call, and no
additional input data is available, so fill_input_buffer must return FALSE.
If the JPEG library has not moved the pointer/count forward in the current
buffer, then *the correct restart point is the saved position in the prior
buffer*.  Prior buffers may be discarded only after the library establishes
a restart point within a later buffer.  Similar remarks apply for output into
a chain of buffers.

The library will never attempt to backtrack over a skip_input_data() call,
so any skipped data can be permanently discarded.  You still have to deal
with the case of skipping not-yet-received data, however.

It's much simpler to use only a single buffer; when fill_input_buffer() is
called, move any unconsumed data (beyond the current pointer/count) down to
the beginning of this buffer and then load new data into the remaining buffer
space.  This approach requires a little more data copying but is far easier
to get right.


Progressive JPEG support
------------------------

Progressive JPEG rearranges the stored data into a series of scans of
increasing quality.  In situations where a JPEG file is transmitted across a
slow communications link, a decoder can generate a low-quality image very
quickly from the first scan, then gradually improve the displayed quality as
more scans are received.  The final image after all scans are complete is
identical to that of a regular (sequential) JPEG file of the same quality
setting.  Progressive JPEG files are often slightly smaller than equivalent
sequential JPEG files, but the possibility of incremental display is the main
reason for using progressive JPEG.

The IJG encoder library generates progressive JPEG files when given a
suitable "scan script" defining how to divide the data into scans.
Creation of progressive JPEG files is otherwise transparent to the encoder.
Progressive JPEG files can also be read transparently by the decoder library.
If the decoding application simply uses the library as defined above, it
will receive a final decoded image without any indication that the file was
progressive.  Of course, this approach does not allow incremental display.
To perform incremental display, an application needs to use the decoder
library's "buffered-image" mode, in which it receives a decoded image
multiple times.

Each displayed scan requires about as much work to decode as a full JPEG
image of the same size, so the decoder must be fairly fast in relation to the
data transmission rate in order to make incremental display useful.  However,
it is possible to skip displaying the image and simply add the incoming bits
to the decoder's coefficient buffer.  This is fast because only Huffman
decoding need be done, not IDCT, upsampling, colorspace conversion, etc.
The IJG decoder library allows the application to switch dynamically between
displaying the image and simply absorbing the incoming bits.  A properly
coded application can automatically adapt the number of display passes to
suit the time available as the image is received.  Also, a final
higher-quality display cycle can be performed from the buffered data after
the end of the file is reached.

Progressive compression:

To create a progressive JPEG file (or a multiple-scan sequential JPEG file),
set the scan_info cinfo field to point to an array of scan descriptors, and
perform compression as usual.  Instead of constructing your own scan list,
you can call the jpeg_simple_progression() helper routine to create a
recommended progression sequence; this method should be used by all
applications that don't want to get involved in the nitty-gritty of
progressive scan sequence design.  (If you want to provide user control of
scan sequences, you may wish to borrow the scan script reading code found
in rdswitch.c, so that you can read scan script files just like cjpeg's.)
When scan_info is not NULL, the compression library will store DCT'd data
into a buffer array as jpeg_write_scanlines() is called, and will emit all
the requested scans during jpeg_finish_compress().  This implies that
multiple-scan output cannot be created with a suspending data destination
manager, since jpeg_finish_compress() does not support suspension.  We
should also note that the compressor currently forces Huffman optimization
mode when creating a progressive JPEG file, because the default Huffman
tables are unsuitable for progressive files.

Progressive decompression:

When buffered-image mode is not used, the decoder library will read all of
a multi-scan file during jpeg_start_decompress(), so that it can provide a
final decoded image.  (Here "multi-scan" means either progressive or
multi-scan sequential.)  This makes multi-scan files transparent to the
decoding application.  However, existing applications that used suspending
input with version 5 of the IJG library will need to be modified to check
for a suspension return from jpeg_start_decompress().

To perform incremental display, an application must use the library's
buffered-image mode.  This is described in the next section.


Buffered-image mode
-------------------

In buffered-image mode, the library stores the partially decoded image in a
coefficient buffer, from which it can be read out as many times as desired.
This mode is typically used for incremental display of progressive JPEG files,
but it can be used with any JPEG file.  Each scan of a progressive JPEG file
adds more data (more detail) to the buffered image.  The application can
display in lockstep with the source file (one display pass per input scan),
or it can allow input processing to outrun display processing.  By making
input and display processing run independently, it is possible for the
application to adapt progressive display to a wide range of data transmission
rates.

The basic control flow for buffered-image decoding is

	jpeg_create_decompress()
	set data source
	jpeg_read_header()
	set overall decompression parameters
	cinfo.buffered_image = TRUE;	/* select buffered-image mode */
	jpeg_start_decompress()
	for (each output pass) {
	    adjust output decompression parameters if required
	    jpeg_start_output()		/* start a new output pass */
	    for (all scanlines in image) {
	        jpeg_read_scanlines()
	        display scanlines
	    }
	    jpeg_finish_output()	/* terminate output pass */
	}
	jpeg_finish_decompress()
	jpeg_destroy_decompress()

This differs from ordinary unbuffered decoding in that there is an additional
level of looping.  The application can choose how many output passes to make
and how to display each pass.

The simplest approach to displaying progressive images is to do one display
pass for each scan appearing in the input file.  In this case the outer loop
condition is typically
	while (! jpeg_input_complete(&cinfo))
and the start-output call should read
	jpeg_start_output(&cinfo, cinfo.input_scan_number);
The second parameter to jpeg_start_output() indicates which scan of the input
file is to be displayed; the scans are numbered starting at 1 for this
purpose.  (You can use a loop counter starting at 1 if you like, but using
the library's input scan counter is easier.)  The library automatically reads
data as necessary to complete each requested scan, and jpeg_finish_output()
advances to the next scan or end-of-image marker (hence input_scan_number
will be incremented by the time control arrives back at jpeg_start_output()).
With this technique, data is read from the input file only as needed, and
input and output processing run in lockstep.

After reading the final scan and reaching the end of the input file, the
buffered image remains available; it can be read additional times by
repeating the jpeg_start_output()/jpeg_read_scanlines()/jpeg_finish_output()
sequence.  For example, a useful technique is to use fast one-pass color
quantization for display passes made while the image is arriving, followed by
a final display pass using two-pass quantization for highest quality.  This
is done by changing the library parameters before the final output pass.
Changing parameters between passes is discussed in detail below.

In general the last scan of a progressive file cannot be recognized as such



( run in 1.225 second using v1.01-cache-2.11-cpan-8450f2e95f3 )