📄 codeimage.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crblib/inc.h>
#include <crblib/codeutil.h>
#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<sizeY;y++) {
dp = rows[y] + sizeX;
for(x=sizeX;x<im->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<<top_bitpn;
for(bitmask = top_val;bitmask>=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<<top_bitpn;
for(bitmask = top_val;bitmask>=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,x,y; //,r
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<sizeY;y++) {
for(x=sizeX;x--;) *aptr++ += *bptr++;
aptr += im->width - sizeX; bptr += im->width - sizeX;
}
aptr = context; bptr =wavelet->data[p][sizeY];
for(y=0;y<sizeY;y++) {
for(x=sizeX;x--;) *aptr++ += *bptr++;
aptr += im->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<sizeY;y++) {
for(x=0;x<sizeX;x++) {
mse += (*dp) * (*dp); dp++;
}
dp += fullW - sizeX;
}
return mse;
}
void waveletImage(image *im,wavelet *wave,int transform,
int qtype,int qflags,double quantizer,
const coder *coder_template,int stoplen)
{
wave->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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -