int QccWAVspeckEncode(const QccIMGImageComponent *image, const QccIMGImageComponent *mask, int num_levels, int target_bit_cnt, const QccWAVWavelet *wavelet, QccBitBuffer *output_buffer);
int QccWAVspeckDecodeHeader(QccBitBuffer *input_buffer, int *num_levels, int *num_rows, int *num_cols, double *image_mean, int *max_coefficient_bits);
int QccWAVspeckDecode(QccBitBuffer *input_buffer, QccIMGImageComponent *image, const QccIMGImageComponent *mask, int num_levels, const QccWAVWavelet *wavelet, double image_mean, int max_coefficient_bits, int target_bit_cnt);
QccWAVspeckEncode() encodes an image component, image, using the Set-Partitioning Embedded Block (SPECK) algorithm by Pearlman et al. The SPECK algorithm involves a 2D DWT followed by a progressive "bitplane" coding of the wavelet coefficients using a block-splitting quantization structure based on quadtrees.
image is the image component to be coded and output_buffer is the output bitstream. output_buffer must be of QCCBITBUFFER_OUTPUT type and opened via a prior call to QccBitBufferStart(3) .
num_levels gives the number of levels of dyadic wavelet decomposition to perform, and wavelet is the wavelet to use for decomposition.
The bitstream output from the SPECK encoder is embedded, meaning that any prefix of the bitstream can be decoded to give a valid representation of the image. The SPECK encoder essentially produces output bits until the number of bits output reaches target_bit_cnt, the desired (target) total length of the output bitstream in bits, and then it stops. Note that this is the bitstream length in bits, not the rate of the bitstream (which would be expressed in bits per pixel).
QccWAVspeckEncode() optionally supports the use of a shape-adaptive DWT (SA-DWT) rather than the usual DWT. That is, QccWAVspeckEncode() can call QccWAVSubbandPyramidShapeAdaptiveDWT(3) as the wavelet transform rather than the usual QccWAVSubbandPyramidDWT(3) . The use of a SA-DWT is indicated by a non-NULL mask; if mask is NULL, then the usual DWT is used. In the case of a SA-DWT, mask gives the transparency mask which indicates which pixels of the image are non-transparent and thus have data that is to be transformed. Refer to QccWAVSubbandPyramidShapeAdaptiveDWT(3) for more details on the calculation of this SA-DWT. See "Shape-Adaptive Coding" below for details on how the SPECK algorithm handles shape-adaptive coding.
QccWAVspeckDecodeHeader() decodes the header information in a bitstream previously produced by QccWAVspeckEncode(). The input bitstream is input_buffer which must be of QCCBITBUFFER_INPUT type and opened via a prior call to QccBitBufferStart(3) .
The header information is returned in num_levels (number of levels of wavelet decomposition), num_rows (vertical size of image), num_cols (horizontal size of image), image_mean (the mean value of the original image), and max_coefficient_bits (indicates the precision, in number of bits, of the wavelet coefficient with the largest magnitude).
QccWAVspeckDecode() decodes the bitstream input_buffer, producing the reconstructed image component, image. The bitstream must already have had its header read by a prior call to QccWAVspeckDecodeHeader() (i.e., you call QccWAVspeckDecodeHeader() first and then QccWAVspeckDecode()). If target_bit_cnt is QCCENT_ANYNUMBITS, then decoding stops when the end of the input bitstream is reached; otherwise, decoding stops when target_num_bits from the input bitstream have been decoded.
If a SA-DWT was used in SPECK encoding, then the original transparency mask should be passed to QccWAVspeckDecode() as mask. That is, mask should be the same transparency mask (in the spatial domain) that was passed to QccWAVspeckEncode(). Note that QccWAVspeckDecode() will transform this mask via a Lazy wavelet transform, and then pass the transformed mask to QccWAVSubbandPyramidInverseShapeAdaptiveDWT(3) . If the usual DWT was used in encoding, then mask should be a NULL pointer.
For coding the binary significance map, the SPECK algorithm parititions sets of coefficients into smaller and smaller sets. Unlike zerotree set-partitioning algorithms such as SPIHT, SPECK eliminates the cross-scale aggregation of coefficients and focuses the set-partitioning process instead on sets of contiguous coefficients from within a single subband. Specifically, SPECK codes the significance map with quadtrees, a well known method of spatial partitioning. In quadtree partitioning, the significance state of an entire block of coefficients is tested and coded, the block is subdivided into four subblocks of approximately equal size, and the significance-coding process is repeated recursively on each of the subblocks.
As with SPIHT, the SPECK algorithm stores sets in implicitly sorted lists. Insignificant sets are placed in a list of insigificant sets (LIS). During the sorting pass, each insignificant set in an LIS is tested for significance against the current threshold. If the set becomes significant, it is split into four subsets according to the quadtree decomposition structure described above. The four new sets are placed into an LIS, recursively tested for significance, and split again if needed. SPECK maintains multiple LIS lists in order to implicitly process sets according to their size. During the sorting pass, each time a set is split, the resulting subsets move to the next LIS. When a set is reduced in size to a single coefficient, and that coefficient becomes significant, then the singleton set is moved from its LIS to a list of significant pixels (LSP) for later processing in the refinement pass.
The SPECK implementation in QccPackSPECK follows the algorithm described in the paper by Pearlman, Islam, Nagaraj, and Said, except that, as described by Pearlman et al., the CodeS() procedure partitions a set into four subsets and then, for each subset, encodes the significance state of the subset and recursively calls CodeS() on the subset. On the other hand, in the QccPack implementation, once CodeS() partitions a set into subsets, ProcessS() is called on each subset. ProcessS() then in turn codes the significance state of the subset as well as calls CodeS() for the subset. That is to say, as originally described by Pearlman() et al., recursion in SPECK is limited to within CodeS(), whereas, in the QccPack implementation of SPECK, ProcessS() and CodeS() recursively call one another. This latter recursion strategy is a bit simpler to code, while performance to the original algorithm is identical.
A quantitative comparison follows using the three "standard" images (Lenna, Barbara, and Goldhill) provided with QccPack. In all of the results, the wavelet transform employed is a 5-level dyadic decomposition using the 9/7 Cohen-Daubechies-Feauveau biorthogonal wavelet with symmetric extension at the image boundaries (this is the same transform used in the paper by Pearlman et al.). The RPI results refer to the results reported in the ITCSVT paper by Pearlman et al.
Lenna
-------------------------------------
| Rate | PSNR (db) |
| (bpp) | RPI QccPack |
------------------------------------
| 0.25 | 34.03 | 33.99 |
| 0.5 | 37.10 | 37.10 |
| 1.0 | 40.25 | 40.25 |
-------------------------------------
Barbara
-------------------------------------
| Rate | PSNR (db) |
| (bpp) | RPI QccPack |
------------------------------------
| 0.25 | 27.76 | 27.69 |
| 0.5 | 31.54 | 31.48 |
| 1.0 | 36.49 | 36.44 |
-------------------------------------
Goldhill
-------------------------------------
| Rate | PSNR (db) |
| (bpp) | RPI QccPack |
------------------------------------
| 0.25 | 30.50 | 30.43 |
| 0.5 | 33.03 | 32.95 |
| 1.0 | 36.36 | 36.32 |
-------------------------------------
W. A. Pearlman, A. Islam, N. Nagaraj, and A. Said, "Efficient, Low-Complexity Image Coding with a Set-Partitioning Embedded Block Coder," IEEE Transactions on Circuits and Systems for Video Technology, to appear, 2003.
A. Islam and W. A. Pearlman, "An Embedded and Efficient Low-Complexity Hierarchical Image Coder," in Visual Communications and Image Processing, K. Aizawa, R. L. Stevenson, and Y.-Q. Zhang, Eds., San Jose, CA, January 1999, Proc. SPIE 3653, pp. 294-305.
Z. Lu and W. A. Pearlman, "Wavelet Video Coding of Video Object by Object-Based SPECK Algorithm," in Proceedings of the Picture Coding Symposium, Seoul, Korea, April 2001, pp. 413-416.