?? decode.cpp
字號:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
//Header Files
#include "const.h"
extern void init_bdecoder ();
extern void init_sdecoder ();
extern void init_mydecoder ();
extern void stop_mydecoder ();
extern int bdecode_symbol (int);
extern int decode_symbol (int);
//Constant Definitions
//Options included in the encoder
#define OPTION_NEARLY_LOSSLESS
//Misc. constants
#define N_SEQ NUM_CONTEXT /* Number of coding histograms */
#define N_BSEQ NUM_BCONTEXT /* Number of binary coding histograms */
#define UPPER 255 /* Largest possible pixel value */
#define ERR_SPAN (UPPER + 1)
//Macro Definitions
#define ABS(X) (((X) < 0) ? -(X) : (X))
#define MIN(X,Y) (((X) < (Y)) ? (X) : (Y))
#define MAX(X,Y) (((X) < (Y)) ? (Y) : (X))
//NEARLY LOSSLESS COMPRESSION
#ifdef OPTION_NEARLY_LOSSLESS
//Variable Definitions
int tolerance = 7;
int mask = 15;
int QT[8];
int QS[8];
FILE *infile;
FILE *outfile;
#endif
//NEARLY LOSSLESS COMPRESSION
//Misc. operations
//Function : nh
//static int T0 = 5 + 1;
//static int T1 = 15 + 0;
//static int T2 = 25 + 6;
//static int T3 = 42 + 4;
//static int T4 = 60 + 6;
//static int T5 = 85 + 6;
//static int T6 = 140 + 10;
static int T0 = 5 - 1;
static int T1 = 15 - 5;
static int T2 = 25 - 4;
static int T3 = 42;
static int T4 = 60;
static int T5 = 85;
static int T6 = 140;
int nh (int k)
{
if (k <= T0) return (0);
else if (k <= T1) return (1);
else if (k <= T2) return (2);
else if (k <= T3) return (3);
else if (k <= T4) return (4);
else if (k <= T5) return (5);
else if (k <= T6) return (6);
else return (7);
}
//Function : nreremap
int nreremap (int err, int p, int flip)
{
if (err == 0) return (0);
//NEARLY LOSSLESS COMPRESSION
#ifdef OPTION_NEARLY_LOSSLESS
{
if (p <= (UPPER/2))
{
if (err <= 2*((p + tolerance)/mask))
{
if ((err % 2) == 0) err = -err/2;
else err = (err + 1)/2;
}
else
{
if (flip) err = -(err - (p + tolerance)/mask);
else err = err - (p + tolerance)/mask;
}
}
else
{
if (err <= 2*((UPPER - p + tolerance)/mask))
{
if ((err % 2) == 0) err = -err/2;
else err = (err + 1)/2;
}
else
{
if (flip) err = err - (UPPER - p + tolerance)/mask;
else err = -(err - (UPPER - p + tolerance)/mask);
}
}
err = err*mask;
}
#else
if (p <= (UPPER/2))
{
if (err <= 2*p)
{
if ((err % 2) == 0) err = -err/2;
else err = (err + 1)/2;
}
else
{
if (flip) err = -(err - p);
else err = err - p;
}
}
else
{
if (err <= 2*(UPPER - p))
{
if ((err % 2) == 0) err = -err/2;
else err = (err + 1)/2;
}
else
{
if (flip) err = err - (UPPER - p);
else err = -(err - (UPPER - p));
}
}
#endif
//NEARLY LOSSLESS COMPRESSION
return (err);
}
//Operations for saving images
//Function : create_buffer
void create_buffer (unsigned char **u0, unsigned char **u1, unsigned char **u2, int width)
{
//Allocate space for the first line of the image.
if ((*u2 = (unsigned char *) calloc (width + 2, sizeof (unsigned char))) == NULL)
{
fprintf (stderr, "ERROR : not enough space for buffer!\n");
exit (1);
}
//Allocate space for the second line of the image.
if ((*u1 = (unsigned char *) calloc (width + 2, sizeof (unsigned char))) == NULL)
{
fprintf (stderr, "ERROR : not enough space for buffer!\n");
exit (1);
}
//Allocate space for the third line of the image.
if ((*u0 = (unsigned char *) calloc (width + 2, sizeof (unsigned char))) == NULL)
{
fprintf (stderr, "ERROR : not enough space for buffer!\n");
exit (1);
}
}
//Function : update_buffer
void update_buffer (unsigned char **u0, unsigned char **u1, unsigned char **u2, int width)
{
unsigned char *temp;
temp = *u2;
*u2 = *u1;
*u1 = *u0;
*u0 = temp;
//Save a line to the image.
if ((fwrite (*u0 + 1, sizeof (unsigned char), width, outfile)) !=(unsigned int)width)
{
fprintf (stderr, "ERROR : in writing image!\n");
exit (1);
}
}
//Function : flush_buffer
void flush_buffer (unsigned char *u0, unsigned char *u1, unsigned char *u2, int width)
{
//Save the last three lines to the image.
if ((fwrite (u2 + 1, sizeof (unsigned char), width, outfile)) !=(unsigned int)width)
{
fprintf (stderr, "ERROR : in writing image!\n");
exit (1);
}
if ((fwrite (u1 + 1, sizeof (unsigned char), width, outfile)) !=(unsigned int)width)
{
fprintf (stderr, "ERROR : in writing image!\n");
exit (1);
}
if ((fwrite (u0 + 1, sizeof (unsigned char), width, outfile)) !=(unsigned int)width)
{
fprintf (stderr, "ERROR : in writing image!\n");
exit (1);
}
}
//Function : destory_buffer
void destory_buffer (unsigned char **u0, unsigned char **u1, unsigned char **u2)
{
//Free all the buffer space.
free (*u0); *u0 = NULL;
free (*u1); *u1 = NULL;
free (*u2); *u2 = NULL;
}
//Function : decode_buffer
void decode_buffer (unsigned char *u0, unsigned char *u1, unsigned char *u2, int width, int height)
{
register unsigned short ptn, ptn0, ptn1, ptn2;
int *N1, *N2;
int *S1, *S2;
int *Dh, *Dv;
int *Pr;
int *E0, err, aerr, berr;
int H[N_SEQ][ERR_SPAN], BH[N_BSEQ][3];
register int dh, dv, max, min, adjust, temp;
register int symb1, symb2, bflag;
register int nnww, nnw, nn, nne, nww, nw, n, ne, nee, www, ww, w, curr;
register int x, j, k;
//Allocate space ("Gradient")
if ((Dh = (int *) calloc (width + 2, sizeof (int))) == NULL)
{
fprintf (stderr, "ERROR : no enough space for Dh\n");
exit (1);
}
if ((Dv = (int *) calloc (width + 2, sizeof (int))) == NULL)
{
fprintf (stderr, "ERROR : no enough space for Dv\n");
exit (1);
}
memset (Dh, 0, (width + 2)*sizeof (int));
memset (Dv, 0, (width + 2)*sizeof (int));
//Allocate space ("Prediction Error")
if ((E0 = (int *) calloc (width + 2, sizeof (int))) == NULL)
{
fprintf (stderr, "ERROR : no enough space for E0\n");
exit (1);
}
aerr = err = 0;
memset (E0, 0, (width + 2)*sizeof (int));
//lw
if ((Pr = (int *) calloc (width + 2, sizeof (int))) == NULL)
{
fprintf (stderr, "ERROR : no enough space for E0\n");
exit (1);
}
memset (Pr, 0, (width + 2)*sizeof (int));
//Allocate space ("Context Modeling")
if ((N1 = (int *) calloc (4096, sizeof (int))) == NULL)
{
fprintf (stderr, "ERROR : no enough space for N1\n");
exit (1);
}
if ((S1 = (int *) calloc (4096, sizeof (int))) == NULL)
{
fprintf (stderr, "ERROR : no enough space for S1\n");
exit (1);
}
if ((N2 = (int *) calloc (4096, sizeof (int))) == NULL)
{
fprintf (stderr, "ERROR : no enough space for N2\n");
exit (1);
}
if ((S2 = (int *) calloc (4096, sizeof (int))) == NULL)
{
fprintf (stderr, "ERROR : no enough space for S2\n");
exit (1);
}
ptn = ptn0 = ptn1 = ptn2= 0;
memset (N1, 0, 4096*sizeof (int));
memset (S1, 0, 4096*sizeof (int));
memset (N2, 0, 4096*sizeof (int));
memset (S2, 0, 4096*sizeof (int));
//Initialize variables
for (k = 0; k < N_SEQ; ++k)
for (j = 0; j < ERR_SPAN; ++j) H[k][j] = 0;
for (k = 0; k < N_BSEQ; ++k)
for (j = 0; j < 3; ++j) BH[k][j] = 0;
//First pixel in the first row
temp = UPPER/4;
err = nreremap (decode_symbol (3), temp, 0);
aerr = ABS (err);
curr = temp + err;
//NEARLY LOSSLESS COMPRESSION
#ifdef OPTION_NEARLY_LOSSLESS
{
if (curr < 0) curr = 0;
if (curr > UPPER) curr = UPPER;
}
#endif
//NEARLY LOSSLESS COMPRESSION
u2[1] = curr;
u2[0] = u2[1]; /* Duplicate the first pixel */
//Second pixel in the first row
w = u2[1];
temp = w;
k = nh (aerr << 2);
err = nreremap (decode_symbol (k), temp, 0);
aerr = ABS (err);
curr = temp + err;
//NEARLY LOSSLESS COMPRESSION
#ifdef OPTION_NEARLY_LOSSLESS
{
if (curr < 0) curr = 0;
if (curr > UPPER) curr = UPPER;
}
#endif
//NEARLY LOSSLESS COMPRESSION
u2[2] = curr;
//Rest of the first row
for (x = 3; x <= width; ++x)
{
ww = u2[x-2];
w = u2[x-1];
temp = w;
if (temp > UPPER) temp = UPPER;
else if (temp < 0) temp = 0;
k = nh ((aerr + ABS (ww - w)) << 2);
err = nreremap (decode_symbol (k), temp, 0);
aerr = ABS (err);
curr = temp + err;
//NEARLY LOSSLESS COMPRESSION
#ifdef OPTION_NEARLY_LOSSLESS
{
if (curr < 0) curr = 0;
if (curr > UPPER) curr = UPPER;
}
#endif
//NEARLY LOSSLESS COMPRESSION
u2[x] = curr;
}
u2[width+1] = u2[width]; /* Duplicate the last pixel */
//Second row first pixel
n = u2[1];
temp = n;
E0[1] = err = nreremap (decode_symbol (2), temp, 0);
aerr = ABS (err);
curr = temp + err;
//NEARLY LOSSLESS COMPRESSION
#ifdef OPTION_NEARLY_LOSSLESS
{
if (curr < 0) curr = 0;
if (curr > UPPER) curr = UPPER;
}
#endif
//NEARLY LOSSLESS COMPRESSION
u1[1] = curr;
u1[0] = u1[1]; /* Duplicate the first pixel */
//Second row second pixel
nw = u2[1];
n = u2[2];
ne = u2[3];
w = u1[1];
temp = (w + n + 1)/2 + (ne - nw)/4;
if (temp > UPPER) temp = UPPER;
else if (temp < 0) temp = 0;
k = nh (aerr + ABS (n - nw) + ABS (n - ne) + 2*ABS (w - nw));
E0[2] = err = nreremap (decode_symbol (k), temp, 0);
aerr = ABS (err);
curr = temp + err;
//NEARLY LOSSLESS COMPRESSION
#ifdef OPTION_NEARLY_LOSSLESS
{
if (curr < 0) curr = 0;
if (curr > UPPER) curr = UPPER;
}
#endif
//NEARLY LOSSLESS COMPRESSION
u1[2] = curr;
Dh[2] = ABS (curr - w);
Dv[2] = ABS (curr - n);
//2nd row
for (x = 3; x <= width - 1; ++x)
{
nw = u2[x-1];
n = u2[x];
ne = u2[x+1];
ww = u1[x-2];
w = u1[x-1];
temp = (w + n + 1)/2 + (ne - nw)/4;
if (temp > UPPER) temp = UPPER;
else if (temp < 0) temp = 0;
k = nh (aerr + ABS (ww - w) + ABS (n - nw) + ABS (n - ne) + 2*ABS (w - nw));
E0[x] = err = nreremap (decode_symbol (k), temp, 0);
aerr = ABS (err);
curr = temp + err;
//NEARLY LOSSLESS COMPRESSION
#ifdef OPTION_NEARLY_LOSSLESS
{
if (curr < 0) curr = 0;
if (curr > UPPER) curr = UPPER;
}
#endif
//NEARLY LOSSLESS COMPRESSION
u1[x] = curr;
Dh[x] = ABS (curr - w);
Dv[x] = ABS (curr - n);
}
//Second row last pixel
nw = u2[width-1];
n = u2[width];
ww = u1[width-2];
w = u1[width-1];
temp = (w + n + 1)/2;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -