www.pudn.com > wavecode.rar > codeimage.c
#include#include #include #include #include #include "image.h" #include "coder.h" #include "codezt.h" #include "codeimage.h" #include "quantim.h" /****** coder.c has no idea what an "image" is. image.c has no idea what a "coder is. only this module (and main.c) know about both. ********/ int packed_H_Size(image *im,const coder *coder_template,int levels); int packed_L_Size(image *im,int levels); int packedImageSize(image *im,const coder *coder_template,int levels); int packedImageStopErr(image *im,const coder *coder_template,int levels,int stopSize); void encodeDeltaIm(coder * encoder,image *im,image *wavelet); void encodeImage(coder * encoder,image *im,int levels); void decodeImage(coder * decoder,image *im,int levels); void encodeLL(coder * encoder,image *im); void decodeLL(coder * decoder,image *im); void encodeLL(coder * encoder,image *im) { int p; for(p=0;p<(im->planes);p++) coder_encodeDPCM(encoder,im->data[p][0],im->width,im->height,0); } void decodeLL(coder * decoder,image *im) { int p; for(p=0;p<(im->planes);p++) coder_decodeDPCM(decoder,im->data[p][0],im->width,im->height,0); } void encodeImage(coder * encoder,image *im,int levels) { int p,l,sizeX,sizeY; int **rows; if ( encoder->encodeSubbandBP ) errexit("error : this coder is for wavelet packets only"); if ( encoder->encodeBandZT ) { encodeImageZT(encoder,im,levels); return; } encoder->w->stopline = - 1; /** the LL band is already sent **/ if ( encoder->encodeBandBP ) { int val,top_val,top_bitpn,bitmask; int *dp,x,y; /** <> ; different top_val per plane? **/ top_val = 0; for(p=0;p<(im->planes);p++) { rows = im->data[p]; sizeX = (im->width) >> levels; sizeY = (im->height) >> levels; for(y=0;y width;x++) { val = *dp++; if ( val < 0 ) val = -val; if ( val > top_val ) top_val = val; } } dp = rows[y]; for(x=(im->height-sizeY)*(im->width);x--;) { val = *dp++; if ( val < 0 ) val = -val; if ( val > top_val ) top_val = val; } } for(top_bitpn=0;(1<<(top_bitpn+1))<=top_val;top_bitpn++) ; cu_putExpanding_ari(top_bitpn,encoder->arith,16,8); top_val = 1< =1;bitmask>>=1) { for (l = levels; l > 0; l--) { sizeX = (im->width) >> l; sizeY = (im->height) >> l; for(p=0;p<(im->planes);p++) { rows = im->data[p]; if ( ! coder_timetostop(encoder) ) encoder->encodeBandBP(encoder,rows[0] + sizeX, sizeX, sizeY, im->width, rows[0] + (sizeX>>1),bitmask); if ( ! coder_timetostop(encoder) ) encoder->encodeBandBP(encoder,rows[sizeY], sizeX, sizeY, im->width, rows[(sizeY>>1)],bitmask); if ( ! coder_timetostop(encoder) ) encoder->encodeBandBP(encoder,rows[sizeY]+sizeX, sizeX, sizeY, im->width, rows[(sizeY>>1)]+ (sizeX>>1),bitmask); } } } } else { for (l = levels; l > 0; l--) { sizeX = (im->width) >> l; sizeY = (im->height) >> l; for(p=0;p<(im->planes);p++) { rows = im->data[p]; if ( ! coder_timetostop(encoder) ) encoder->encodeBand(encoder,rows[0] + sizeX, sizeX, sizeY, im->width, rows[0] + (sizeX>>1)); if ( ! coder_timetostop(encoder) ) encoder->encodeBand(encoder,rows[sizeY], sizeX, sizeY, im->width, rows[(sizeY>>1)]); if ( ! coder_timetostop(encoder) ) encoder->encodeBand(encoder,rows[sizeY]+sizeX, sizeX, sizeY, im->width, rows[(sizeY>>1)]+ (sizeX>>1)); } } } if ( encoder->w->stopline < 0 ) encoder->w->stopline = im->height + 1; } void decodeImage(coder * decoder,image *im,int levels) { int p,l,sizeX,sizeY; int **rows; if ( decoder->decodeBandZT ) { decodeImageZT(decoder,im,levels); return; } if ( decoder->decodeBandBP ) { int top_val,top_bitpn,bitmask; top_bitpn = cu_getExpanding_ari(decoder->arith,16,8); top_val = 1< =1;bitmask>>=1) { for (l = levels; l > 0; l--) { sizeX = (im->width) >> l; sizeY = (im->height) >> l; for(p=0;p<(im->planes);p++) { rows = im->data[p]; if ( ! coder_timetostopd(decoder,0) ) decoder->decodeBandBP(decoder,rows[0] + sizeX, sizeX, sizeY, im->width, rows[0] + (sizeX>>1),bitmask); if ( ! coder_timetostopd(decoder,0) ) decoder->decodeBandBP(decoder,rows[sizeY], sizeX, sizeY, im->width, rows[(sizeY>>1)],bitmask); if ( ! coder_timetostopd(decoder,0) ) decoder->decodeBandBP(decoder,rows[sizeY]+sizeX, sizeX, sizeY, im->width, rows[(sizeY>>1)]+ (sizeX>>1),bitmask); } } } } else { for (l = levels; l > 0; l--) { sizeX = (im->width) >> l; sizeY = (im->height) >> l; for(p=0;p<(im->planes);p++) { rows = im->data[p]; if ( ! coder_timetostopd(decoder,0) ) decoder->decodeBand(decoder,rows[0] + sizeX, sizeX, sizeY, im->width, rows[0] + (sizeX>>1)); if ( ! coder_timetostopd(decoder,0) ) decoder->decodeBand(decoder,rows[sizeY], sizeX, sizeY, im->width, rows[(sizeY>>1)]); if ( ! coder_timetostopd(decoder,0) ) decoder->decodeBand(decoder,rows[sizeY]+sizeX, sizeX, sizeY, im->width, rows[(sizeY>>1)]+ (sizeX>>1)); } } } } void encodeDeltaIm(coder * encoder,image *im,image *wavelet) { int p,sizeX,sizeY,r,x,y; int *context,*aptr,*bptr; if ( ! encoder->encodeBand ) { errputs("error : no encoder->encodeBand "); return; } for(p=0;p<(im->planes);p++) { sizeX = im->width>>1; sizeY = im->height>>1; context = wavelet->data[p][sizeY] + sizeX; aptr = context; bptr =wavelet->data[p][0] + sizeX; for(y=0;y width - sizeX; bptr += im->width - sizeX; } aptr = context; bptr =wavelet->data[p][sizeY]; for(y=0;y width - sizeX; bptr += im->width - sizeX; } encoder->encodeBand(encoder,im->data[p][0],im->width,im->height,im->width,context); /** average the three big bands in wavelet **/ } } int mseBand(int * plane,int sizeX,int sizeY,int fullW) { int x,y; int *dp; int mse; mse = 0; dp = plane; for(y=0;y transform = transform; smartfree(wave->qi); wave->qi = doTransQuantIm(im,wave->levels,wave->transform, qtype,qflags,quantizer, stoplen,coder_template); encodeWavelet(im,wave,coder_template,stoplen); } void imageWavelet(image *im,wavelet *wave) { decodeWavelet(im,wave); deTransQuantIm(im,wave->levels,wave->transform,wave->qi); } image * makeImageWavelet(wavelet *wave) { image *im; if ( (im = newImage(wave->width,wave->height,wave->planes)) == NULL) return NULL; imageWavelet(im,wave); return im; } wavelet * makeWavelet(image *im,const coder *coder_template,int levels,int stoplen) { wavelet *wavelet; if ( (wavelet = newWavelet(im,levels)) == NULL ) return NULL; encodeWavelet(im,wavelet,coder_template,stoplen); return wavelet; } void encodeWaveletLL(image *im,wavelet *wavelet) { coder *encoder; encoder = coder_create_write(NULL,wavelet,LONG_MAX); encodeLL(encoder,im); coder_flush_write(encoder); coder_destroy(encoder); } void decodeWaveletLL(wavelet *wavelet,image *im) { coder *decoderLL; if ( (decoderLL = coder_create_read(wavelet)) == NULL ) errexit("decoder_create LL failed!"); decodeLL(decoderLL,im); coder_flush_read(decoderLL); coder_destroy(decoderLL); } void encodeWavelet(image *im,wavelet *wavelet,const coder *coder_template,int stoplen) { coder *encoder; if ( (encoder = coder_create_write(coder_template,wavelet,stoplen)) == NULL ) errexit("coder_create_write failed!"); encoder->init(encoder); encodeImage(encoder,im,wavelet->levels); coder_flush_write(encoder); encoder->free(encoder); coder_destroy(encoder); } void decodeWavelet(image *im,wavelet *wavelet) { coder *decoder; if ( (decoder = coder_create_read(wavelet)) == NULL ) errexit("decoder_create main failed!"); decoder->init(decoder); decodeImage(decoder,im,wavelet->levels); decoder->free(decoder); coder_flush_read(decoder); coder_destroy(decoder); } void encodeWaveletAndLL(image *im,wavelet *wavelet,const coder *coder_template,int stoplen) { coder *encoder; int p; if ( (encoder = coder_create_write(coder_template,wavelet,stoplen)) == NULL ) errexit("coder_create_write failed!"); encoder->init(encoder); for(p=0;p<(im->planes);p++) coder_encodeDPCM(encoder,im->data[p][0], (im->width)>>(wavelet->levels),(im->height)>>(wavelet->levels), im->width - ((im->width)>>(wavelet->levels))); encodeImage(encoder,im,wavelet->levels); coder_flush_write(encoder); encoder->free(encoder); coder_destroy(encoder); } void decodeWaveletAndLL(image *im,wavelet *wavelet) { coder *decoder; int p; if ( (decoder = coder_create_read(wavelet)) == NULL ) errexit("decoder_create main failed!"); decoder->init(decoder); for(p=0;p<(im->planes);p++) coder_decodeDPCM(decoder,im->data[p][0], (im->width)>>(wavelet->levels),(im->height)>>(wavelet->levels), im->width - ((im->width)>>(wavelet->levels))); decodeImage(decoder,im,wavelet->levels); decoder->free(decoder); coder_flush_read(decoder); coder_destroy(decoder); } int packedImageStopErr(image *im,const coder *coder_template,int levels,int stopSize) { int p,l,sizeX,sizeY,err; int **rows; coder *encoder; wavelet *wavelet; /** son of a bitch this is a pain in the ass **/ stopSize -= packed_L_Size(im,levels); wavelet = newWavelet(im,levels); encoder = coder_create_write(coder_template,wavelet,stopSize); encoder->init(encoder); if ( ! encoder->encodeBand ) { errputs("error : no encoder->encodeBand "); return 0; } encoder->w->stopline = -1; err = 0; for(p=0;p<(im->planes);p++) { rows = im->data[p]; for (l = levels; l > 0; l--) { sizeX = (im->width) >> l; sizeY = (im->height) >> l; if ( coder_timetostop(encoder) ) { err += mseBand(rows[0] + sizeX, sizeX, sizeY, im->width); } else { encoder->encodeBand(encoder,rows[0] + sizeX, sizeX, sizeY, im->width, rows[0] + (sizeX>>1)); if ( coder_timetostop(encoder) ) { err += mseBand(rows[0] + sizeX + encoder->w->stopline*im->width, sizeX, sizeY - encoder->w->stopline, im->width); } } if ( coder_timetostop(encoder) ) { err += mseBand(rows[sizeY], sizeX, sizeY, im->width); } else { encoder->encodeBand(encoder,rows[sizeY], sizeX, sizeY, im->width, rows[(sizeY>>1)]); if ( coder_timetostop(encoder) ) { err += mseBand(rows[sizeY] + encoder->w->stopline*im->width, sizeX, sizeY - encoder->w->stopline, im->width); } } if ( coder_timetostop(encoder) ) { err += mseBand(rows[sizeY] + sizeX, sizeX, sizeY, im->width); } else { encoder->encodeBand(encoder,rows[sizeY]+sizeX, sizeX, sizeY, im->width, rows[(sizeY>>1)]+ (sizeX>>1)); if ( coder_timetostop(encoder) ) { err += mseBand(rows[sizeY] + sizeX + encoder->w->stopline*im->width, sizeX, sizeY - encoder->w->stopline, im->width); } } } } coder_flush_write(encoder); encoder->free(encoder); coder_destroy(encoder); freeWavelet(wavelet); return err; } int packedImageSize(image *im,const coder *coder_template,int levels) { return( packed_H_Size(im,coder_template,levels) + packed_L_Size(im,levels) ); } int packed_H_Size(image *im,const coder *coder_template,int levels) { int complen; wavelet *wavelet; wavelet = makeWavelet(im,coder_template,levels,LONG_MAX); complen = wavelet->complen - 2; freeWavelet(wavelet); return complen; } int packed_L_Size(image *im,int levels) { int complen; image *ll_band; int ll_width,ll_height; wavelet *wavelet; ll_width = im->width>>levels; ll_height = im->height>>levels; if ( (ll_band = newImage(ll_width,ll_height,im->planes)) == NULL ) errexit("newImage failed"); patchImage(im,ll_band,0,0,ll_width,ll_height,0,0); wavelet = newWavelet(ll_band,0); encodeWaveletLL(ll_band,wavelet); complen = wavelet->complen - 2; freeWavelet(wavelet); freeImage(ll_band); return complen; } int packed_LLband_Size(image *ll_band) { int complen; wavelet *wavelet; wavelet = newWavelet(ll_band,0); encodeWaveletLL(ll_band,wavelet); complen = wavelet->complen - 2; freeWavelet(wavelet); return complen; }