| synopsis || return value || arguments || prev || next |
bool process( kdu_byte ** channel_bufs, bool expand_monochrome, int pixel_gap, kdu_coords buffer_origin, int row_gap, int suggested_increment, int max_region_pixels, kdu_dims & incomplete_region, kdu_dims & new_region, int precision_bits=8, bool measure_row_gap_in_pixels=true)
[Declared in "../apps/support/kdu_region_decompressor.h"]
This powerful function is the workhorse of a typical interactive image rendering application. It is used to incrementally decompress an active region into identified portions of one or more application-supplied buffers. Each call to the function always decompresses some whole number of lines of a single tile, aiming to produce the number of samples suggested by the suggested_increment argument, unless that value is smaller than a single line of the current tile, or larger than the number of samples remaining in the tile or the buffer. The newly rendered samples are guaranteed to belong to a rectangular region — the function returns this region via the new_region argument. This, and all other regions manipulated by the function are expressed relevant to the rendering canvas (the coordinate system associated with the region argument supplied to the start member function).
Decompressed samples are automatically colour transformed, clipped, level adjusted, interpolated and colour appearance transformed, as necessary. The result is a collection of rendered image pixels, each of which has the number of channels described by the kdu_channel_mapping::num_channels member of the kdu_channel_mapping object passed to start (or just one channel, if no kdu_channel_mapping object was passed to start). The initial kdu_channel_mapping::num_colour_channels of these describe the pixel colour, while any remaining channels describe auxiliary properties such as opacity. Other than these few constraints, the properties of the channels are entirely determined by the way in which the application configures the kdu_channel_mapping object.
The rendered channel samples are written to the buffers supplied via the channel_bufs array. If expand_monochrome is false, this array must have exactly one entry for each of the channels described by the kdu_channel_mapping object supplied to start. The entries may all point to offset locations within a single channel-interleaved rendering buffer, or else they may point to distinct buffers for each channel; this allows the application to render to buffers with a variety of interleaving conventions.
If expand_monochrome is true and the number of colour channels (see kdu_channel_mapping::num_colour_channels) is exactly equal to 1, the function automatically copies the single (monochrome) colour channel into 3 identical colour channels whose buffers appear as the first three entries in the channel_bufs array. This is a convenience feature to support direct rendering of monochrome images into 24- or 32-bpp display buffers, with the same ease as full colour images. Your application is not obliged to use this feature, of course.
Each buffer referenced by the channel_bufs array has horizontally adjacent pixels separated by pixel_gap. Regarding vertical organization, however, two distinct configurations are supported.
If row_gap is 0, successive rows of the region written into new_region are concatenated within each channel buffer, so that the row gap is effectively equal to new_region.size.x — it is determined by the particular dimensions of the region processed by the function. In this case, the buffer_origin argument is ignored.
If row_gap is non-zero, each channel buffer points to the location identified by buffer_origin (on the rendering canvas), and each successive row of the buffer is separated by the amount determined by row_gap. In this case, it is the application's responsibility to ensure that the buffers will not be overwritten if any samples from the incomplete_region are written onto the buffer, taking the buffer_origin into account. In particular, the buffer_origin must not lie beyond the first row or first column of the incomplete_region. Note that the interpretation of row_gap depends upon the measure_row_gap_in_pixels argument.
On entry, the incomplete_region structure identifies the subset of the original region supplied to start, which has not yet been decompressed and is still relevant to the application. The function uses this information to avoid unnecessary processing of tiles which are no longer relevant.
On exit, the upper boundary of the incomplete_region is updated to reflect any completely decompressed rows. Once the region becomes empty, all processing is complete and future calls will return false.
The function may return true, with new_region empty. This can happen, for example, when skipping over a now-defunct tile. The intent is to avoid the possibility that the caller might be forced to wait for an unbounded number of tiles to be loaded (possibly from disk) while hunting for one which has a non-empty intersection with the incomplete_region. In general, the current implementation limits the number of new tiles which will be opened to 1. In this way, a number of calls may be required before the function will return with new_region non-empty.
If the underlying code-stream is found to be sufficiently corrupt that the decompression process must be aborted, the current function will catch any exceptions thrown from an application supplied kdu_error handler, returning false prematurely. This condition will be evident from the fact that incomplete_region is non-empty. You should still call finish and watch the return value from that function.
Java note: if you are invoking this function using the Java native API, the function may not return directly after an internal error in the code-stream, if the kdu_customize_errors function was supplied an object which ultimately throws a Java exception. In this case, the error condition must be caught by a catch statement — i.e., catch(KduException e) — surrounding the call. The catch statement should then call finish and watch its return value, in the same manner described above for direct native callers.
False if the incomplete_region becomes empty as a result of this call, or if an internal error occurs during code-stream data processing and an exception was thrown by the application-supplied kdu_error handler. In either case, the correct response to a false return value is to call finish and check its return value. Note, however, that invocations from Java may cause a KduException Java exception to be thrown, as explained above.
If finish returns false, an internal error has occurred and you must close the kdu_codestream object (possibly re-opening it for subsequent processing, perhaps in a more resilient mode — see kdu_codestream::set_resilient).
If finish returns true, the incomplete region might not have been completed if the present function found that you were attempting to discard too many resolution levels. To check for this possibility, you should always check the value returned by kdu_codestream::get_min_dwt_levels after finish returns true, possibly adjusting the current display resolution before further processing. Note that the value returned by kdu_codestream::get_min_dwt_levels can become smaller over time, as more tiles are visited.
Note carefully that this function may return true, even though it has decompressed no new data of interest to the application ( new_region empty). This is because at most one new tile is opened during each call, and that tile might not have any intersection with the current incomplete_region — the application might have reduced the incomplete region to reflect changing interests.
Array with kdu_channel_mapping::num_channels entries, or kdu_channel_mapping::num_channels+2 entries. The latter applies only if expand_monochrome is true and kdu_channel_mapping::num_colour_channels is equal to 1. If no kdu_channel_mapping object was passed to start, the number of channel buffers is equal to 1 (if expand_monochrome is false) or 3 (if expand_monochrome is true). The entries in the channel_bufs array are not modified by this function.
If true and the number of colour channels identified by kdu_channel_mapping::num_colour_channels is 1, or if no kdu_channel_mapping object was passed to start, the function automatically copies the colour channel data into the first three buffers supplied via the channel_bufs array, and the second real channel, if any, corresponds to the fourth entry in the channel_bufs array.
Separation between consecutive pixels, in each of the channel buffers supplied via the channel_bufs argument.
Location, in rendering canvas coordinates, of the upper left hand corner pixel in each channel buffer supplied via the channel_bufs argument, unless row_gap is 0, in which case, this argument is ignored.
If zero, rendered image lines will simply be concatenated into the channel buffers supplied via channel_bufs, so that the line spacing is given by the value written into new_region.size.x upon return. In this case, buffer_origin is ignored. Otherwise, this argument identifies the separation between vertically adjacent pixels within each of the channel buffers. If measure_row_gap_in_pixels is true, the number of samples between consecutive buffer lines is row_gap* pixel_gap. Otherwise, it is just row_gap.
Suggested number of samples to decompress from the code-stream component associated with the first channel (or the single image component) before returning. Of course, there will often be other image components which must be decompressed as well, in order to reconstruct colour imagery; the number of these samples which will be decompressed is adjusted in a commensurate fashion. Note that the decompressed samples may be subject to interpolation (if the sampling argument supplied to the start member function indicates sampling factors greater than 1); the suggested_increment refers to the number of decompressed samples prior to any such interpolation. Note also that the function is free to make up its own mind exactly how many samples it will process in the current call, which may vary from 0 to the entire incomplete_region. In particular, the function will not open more than one new tile in any given call, and it will not process partial lines from any tile-component which intersects with the incomplete_region.
For interactive applications, typical values for the suggested_increment argument might range from a few thousand, to a few tens of thousands.
If row_gap is 0, and the present argument is 0, the only constraint will be that imposed by max_region_pixels.
Maximum number of pixels which can be written to any channel buffer provided via the channel_bufs argument. This argument is ignored unless row_gap is 0, since only in that case is the number of pixels which can be written governed solely by the size of the buffers. An error will be generated (through kdu_error) if the supplied limit is too small to accommodate even a single line from the new region. For this reason, you should be careful to ensure that max_region_pixels is at least as large as incomplete_region.size.x, unless you have special knowlege of the maximum tile width in the image.
Region on the rendering canvas which is still required by the application. This region should be a subset of the region of interest originally supplied to start. However, it may be much smaller. The function decompresses tiles one by one, as required to fill out the incomplete region, discarding any rows from already open tiles which do not intersect with the incomplete region. On exit, the first row in the incomplete region will be moved down to reflect any completely decompressed image rows. Note, however, that the function may decompress image data and return with new_region non-empty, without actually adjusting the incomplete region. This happens when the function decompresses tile data which intersects with the incomplete region, but one or more tiles remain to the right of that region. Generally speaking, the function advances the top row of the incomplete region only when it decompresses data from right-most tiles which intersect with that region, or when it detects that the identity of the right-most tile has changed (due to the width of the incomplete region shrinking) and that the new right-most tile has already been decompressed.
Used to return the location and dimensions of the region of the image which was actually decompressed and written into the channel buffers supplied via the channel_bufs argument. The region's size and location are all expressed relative to the same rendering canvas as the incomplete_region and buffer_origin arguments. Note that the region might be empty, even though processing is not yet complete.
Indicates the precision of the unsigned integers represented by each sample in each buffer supplied via the channel_bufs argument. This value need not bear any special relationship to the original bit-depth of the compressed image samples. The rendered sample values are written into the buffer as B-bit unsigned integers, where B is the value of precision_bits and the most significant bits of the B-bit integer correspond to the most significant bits of the original image samples. Normally, the value of this argument will be 8 so that the rendered data is always normalized for display on an 8-bit/sample device. There may be more interest in selecting different precisions when using the second form of the overloaded process function.
If true, row_gap is interpreted as the number of whole pixels between consecutive rows in the buffer. Otherwise, it is interpreted as the number of samples only. The latter form can be useful when working with image buffers having alignment constraints which are not based on whole pixels (e.g., Windows bitmap buffers).
| top || synopsis || return value || arguments || prev || next |