#include "mem.h" #include "wavelet.h" #include "rle.h" #define printf(args...) #define GRAY_CODES 1 #if defined(GRAY_CODES) static inline uint16_t binary_to_gray (uint16_t x) { return x ^ (x >> 1); } static inline uint16_t gray_to_binary (uint16_t x) { int i; for (i=1; i<16; i+=i) x ^= x >> i; return x; } #endif static inline void encode_coeff (ENTROPY_CODER significand_bitstream [], ENTROPY_CODER insignificand_bitstream [], TYPE coeff) { int sign = (coeff >> (8*sizeof(TYPE)-1)) & 1; #if defined(GRAY_CODES) TYPE significance = binary_to_gray(coeff); #else static TYPE mask [2] = { 0, ~0 }; TYPE significance = coeff ^ mask[sign]; #endif int i = TYPE_BITS; do { i--; OUTPUT_BIT(&significand_bitstream[i], (significance >> i) & 1); } while (!((significance >> i) & 1) && i > 0); OUTPUT_BIT(&significand_bitstream[i], sign); while (--i >= 0) OUTPUT_BIT(&insignificand_bitstream[i], (significance >> i) & 1); } static inline TYPE decode_coeff (ENTROPY_CODER significand_bitstream [], ENTROPY_CODER insignificand_bitstream []) { #if !defined(GRAY_CODES) static TYPE mask [2] = { 0, ~0 }; #endif TYPE significance = 0; int sign; int i = TYPE_BITS; do { i--; significance |= INPUT_BIT(&significand_bitstream[i]) << i; /* if (ENTROPY_CODER_EOS(&significand_bitstream[i])) */ /* return 0; */ } while (!significance && i > 0); sign = INPUT_BIT(&significand_bitstream[i]); /* if (ENTROPY_CODER_EOS(&significand_bitstream[i])) */ /* return 0; */ while (--i >= 0) significance |= INPUT_BIT(&insignificand_bitstream[i]) << i; #if defined(GRAY_CODES) significance |= sign << (8*sizeof(TYPE)-1); return gray_to_binary(significance); #else return (significance ^ mask[sign]); #endif } static inline uint32_t skip_0coeffs (Wavelet3DBuf* buf, ENTROPY_CODER s_stream [], ENTROPY_CODER i_stream [], uint32_t limit) { int i; uint32_t skip = limit; for (i=0; i runlength) skip = runlength; if (skip <= 2) return 0; } } ENTROPY_CODER_SKIP(&s_stream[0], 2*skip); /* kill sign+significance bits */ for (i=1; ioffset [level] [quadrant] + z * buf->width * buf->height + y * buf->width + x; encode_coeff (significand_bitstream, insignificand_bitstream, buf->data [index]); } } } } static void encode_coefficients (const Wavelet3DBuf* buf, ENTROPY_CODER s_stream [], ENTROPY_CODER i_stream []) { int level; encode_coeff (s_stream, i_stream, buf->data[0]); for (level=0; levelscales-1; level++) { uint32_t w, h, f, w1, h1, f1; w = buf->w [level]; h = buf->h [level]; f = buf->f [level]; w1 = buf->w [level+1] - w; h1 = buf->h [level+1] - h; f1 = buf->f [level+1] - f; if (w1 > 0) encode_quadrant(buf,level,1,w1,h,f,s_stream,i_stream); if (h1 > 0) encode_quadrant(buf,level,2,w,h1,f,s_stream,i_stream); if (f1 > 0) encode_quadrant(buf,level,3,w,h,f1,s_stream,i_stream); if (w1 > 0 && h1 > 0) encode_quadrant(buf,level,4,w1,h1,f,s_stream,i_stream); if (w1 > 0 && f1 > 0) encode_quadrant(buf,level,5,w1,h,f1,s_stream,i_stream); if (h1 > 0 && f1 > 0) encode_quadrant(buf,level,6,w,h1,f1,s_stream,i_stream); if (h1 > 0 && f1 > 0 && f1 > 0) encode_quadrant (buf,level,7,w1,h1,f1,s_stream,i_stream); } } static inline void decode_quadrant (Wavelet3DBuf* buf, int level, int quadrant, uint32_t w, uint32_t h, uint32_t f, ENTROPY_CODER s_stream [], ENTROPY_CODER i_stream []) { uint32_t x, y, z; z = 0; do { y = 0; do { x = 0; do { uint32_t skip; uint32_t index = buf->offset [level] [quadrant] + z * buf->width * buf->height + y * buf->width + x; buf->data [index] = decode_coeff (s_stream, i_stream); skip = skip_0coeffs (buf, s_stream, i_stream, (w-x-1)+(h-y-1)*w+(f-z-1)*w*h); if (skip > 0) { x += skip; while (x >= w) { y++; x -= w; while (y >= h) { z++; y -= h; if (z >= f) return; } } } x++; } while (x < w); y++; } while (y < h); z++; } while (z < f); } static void decode_coefficients (Wavelet3DBuf* buf, ENTROPY_CODER s_stream [], ENTROPY_CODER i_stream []) { int level; buf->data[0] = decode_coeff (s_stream, i_stream); for (level=0; levelscales-1; level++) { uint32_t w, h, f, w1, h1, f1; w = buf->w [level]; h = buf->h [level]; f = buf->f [level]; w1 = buf->w [level+1] - w; h1 = buf->h [level+1] - h; f1 = buf->f [level+1] - f; if (w1 > 0) decode_quadrant(buf,level,1,w1,h,f,s_stream,i_stream); if (h1 > 0) decode_quadrant(buf,level,2,w,h1,f,s_stream,i_stream); if (f1 > 0) decode_quadrant(buf,level,3,w,h,f1,s_stream,i_stream); if (w1 > 0 && h1 > 0) decode_quadrant(buf,level,4,w1,h1,f,s_stream,i_stream); if (w1 > 0 && f1 > 0) decode_quadrant(buf,level,5,w1,h,f1,s_stream,i_stream); if (h1 > 0 && f1 > 0) decode_quadrant(buf,level,6,w,h1,f1,s_stream,i_stream); if (h1 > 0 && f1 > 0 && f1 > 0) decode_quadrant (buf,level,7,w1,h1,f1,s_stream,i_stream); } } #else static void encode_coefficients (const Wavelet3DBuf* buf, ENTROPY_CODER s_stream [], ENTROPY_CODER i_stream []) { uint32_t i; for (i=0; iwidth*buf->height*buf->frames; i++) encode_coeff(s_stream, i_stream, buf->data[i]); } static void decode_coefficients (Wavelet3DBuf* buf, ENTROPY_CODER s_stream [], ENTROPY_CODER i_stream []) { uint32_t i; for (i=0; iwidth*buf->height*buf->frames; i++) { uint32_t skip; buf->data[i] = decode_coeff(s_stream, i_stream); skip = skip_0coeffs (buf, s_stream, i_stream, buf->width*buf->height*buf->frames - i); i += skip; } } #endif static uint32_t setup_limittabs (ENTROPY_CODER significand_bitstream [], ENTROPY_CODER insignificand_bitstream [], uint32_t significand_limittab [], uint32_t insignificand_limittab [], uint32_t limit) { uint32_t significand_limit; uint32_t insignificand_limit; uint32_t byte_count; int i; assert (limit > 2 * TYPE_BITS * sizeof(uint32_t)); /* limit too small */ printf ("%s: limit == %u\n", __FUNCTION__, limit); byte_count = 2 * TYPE_BITS * sizeof(uint32_t); /* 2 binary coded limittabs */ limit -= byte_count; printf ("%s: rem. limit == %u\n", __FUNCTION__, limit); significand_limit = limit * 7 / 8; insignificand_limit = limit - significand_limit; printf ("%s: limit == %u\n", __FUNCTION__, limit); printf ("significand limit == %u\n", significand_limit); printf ("insignificand limit == %u\n", insignificand_limit); for (i=TYPE_BITS-1; i>=0; i--) { uint32_t s_bytes, i_bytes; if (i > 0) { significand_limittab[i] = (significand_limit + 1) / 2; insignificand_limittab[i] = (insignificand_limit + 1) / 2; } else { significand_limittab[0] = significand_limit; insignificand_limittab[0] = insignificand_limit; } s_bytes = ENTROPY_ENCODER_FLUSH(&significand_bitstream[i]); i_bytes = ENTROPY_ENCODER_FLUSH(&insignificand_bitstream[i]); if (s_bytes < significand_limittab[i]) significand_limittab[i] = s_bytes; if (i_bytes < insignificand_limittab[i]) insignificand_limittab[i] = i_bytes; byte_count += significand_limittab[i]; byte_count += insignificand_limittab[i]; printf ("insignificand_limittab[%i] == %u / %u\n", i, insignificand_limittab[i], i_bytes); printf (" significand_limittab[%i] == %u / %u\n", i, significand_limittab[i], s_bytes); significand_limit -= significand_limittab[i]; insignificand_limit -= insignificand_limittab[i]; } printf ("byte_count == %u\n", byte_count); return byte_count; } /** * write 'em binary for now, should be easy to compress ... */ static uint8_t* write_limittabs (uint8_t *bitstream, uint32_t significand_limittab [], uint32_t insignificand_limittab []) { int i; for (i=0; i=0; i--) { memcpy (bitstream, ENTROPY_CODER_BITSTREAM(&significand_bitstream[i]), significand_limittab[i]); bitstream += significand_limittab[i]; } for (i=TYPE_BITS-1; i>=0; i--) { memcpy (bitstream, ENTROPY_CODER_BITSTREAM(&insignificand_bitstream[i]), insignificand_limittab[i]); bitstream += insignificand_limittab[i]; } } static void split_bitstreams (uint8_t *bitstream, ENTROPY_CODER significand_bitstream [], ENTROPY_CODER insignificand_bitstream [], uint32_t significand_limittab [], uint32_t insignificand_limittab []) { uint32_t byte_count; int i; for (i=TYPE_BITS-1; i>=0; i--) { byte_count = significand_limittab[i]; ENTROPY_DECODER_INIT(&significand_bitstream[i], bitstream, byte_count); bitstream += byte_count; } for (i=TYPE_BITS-1; i>=0; i--) { byte_count = insignificand_limittab[i]; ENTROPY_DECODER_INIT(&insignificand_bitstream[i], bitstream, byte_count); bitstream += byte_count; } } int wavelet_3d_buf_encode_coeff (const Wavelet3DBuf* buf, uint8_t *bitstream, uint32_t limit) { ENTROPY_CODER significand_bitstream [TYPE_BITS]; ENTROPY_CODER insignificand_bitstream [TYPE_BITS]; uint32_t significand_limittab [TYPE_BITS]; uint32_t insignificand_limittab [TYPE_BITS]; uint32_t byte_count; int i; for (i=0; idata, 0, buf->width * buf->height * buf->frames * sizeof(TYPE)); bitstream = read_limittabs (bitstream, significand_limittab, insignificand_limittab); split_bitstreams (bitstream, significand_bitstream, insignificand_bitstream, significand_limittab, insignificand_limittab); decode_coefficients (buf, significand_bitstream, insignificand_bitstream); for (i=0; i