📄 codec2.c
字号:
/*************************************************************
Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
Group. If you use this software, you agree to the following: This
program package is purely experimental, and is licensed "as is".
Permission is granted to use, modify, and distribute this program
without charge for any purpose, provided this license/ disclaimer
notice appears in the copies. No warranty or maintenance is given,
either expressed or implied. In no event shall the author(s) be
liable to you or a third party for any special, incidental,
consequential, or other damages, arising out of the use or inability
to use the program for any purpose (or the loss of data), even if we
have been advised of such possibilities. Any public reference or
advertisement of this source code should refer to it as the Portable
Video Research Group (PVRG) code, and not by any author(s) (or
Stanford University) name.
*************************************************************/
/*
************************************************************
codec.c
This file contains the routines to run-length encode the ac and dc
coefficients.
************************************************************
*/
/*LABEL codec.c */
#include <math.h>
#include "globals2.h"
#include "csize2.h"
//#define fputv_en mputv_en
#define fgetv mgetv2
//#define fputb mputb_en
#define fgetb mgetb2
/*PUBLIC*/
//extern void EncodeAC_en();
//extern void CBPEncodeAC_en();
extern void DecodeAC2();
extern void CBPDecodeAC2();
extern int DecodeDC2();
//extern void EncodeDC_en();
/*PRIVATE*/
extern int bit_set_mask2[];
extern int Loud2;
extern int NumberNZ2;
extern FRAME *CFrame2;
extern IMAGE *CImage2;
extern DHUFF *T1DHuff2;
extern DHUFF *T2DHuff2;
extern EHUFF *T1EHuff2;
extern EHUFF *T2EHuff2;
int extend_mask2[] = {
0xFFFFFFFE,
0xFFFFFFFC,
0xFFFFFFF8,
0xFFFFFFF0,
0xFFFFFFE0,
0xFFFFFFC0,
0xFFFFFF80,
0xFFFFFF00,
0xFFFFFE00,
0xFFFFFC00,
0xFFFFF800,
0xFFFFF000,
0xFFFFE000,
0xFFFFC000,
0xFFFF8000,
0xFFFF0000,
0xFFFE0000,
0xFFFC0000,
0xFFF80000,
0xFFF00000
};
int CodedBlockBits2=0;
int EOBBits2=0;
/*START*/
/*BFUNC
EncodeAC_en() encodes the quantized coefficient matrix input by the first
Huffman table. The index is an offset into the matrix.
EFUNC*/
//void EncodeAC_en(index,matrix)
// int index;
// int *matrix;
//void EncodeAC_en(int index,int *matrix)
//{
// BEGIN("EncodeAC_en");
// int k,r,l,code,retval,Start;
//
// Start=swtell_en();
// for(r=0,k=index-1;++k<BLOCKSIZE;)
// {
// l = matrix[k];
// if (!l) {r++;}
// else
// {
// code = abs(l) | (r << 8);
// if (code != HUFFMAN_ESCAPE) {retval=Encode_en(code,T1EHuff2);}
// else {retval=0;}
// if (!retval)
// {
// Encode_en(HUFFMAN_ESCAPE,T1EHuff2);
// fputv_en(6,r);
// fputv_en(8,l);
// }
// else
// {
// if (l < 0){fputb(1);}
// else {fputb(0);}
// }
// r=0;
// NumberNZ2++;
// }
// }
// CodedBlockBits2+=(swtell_en()-Start);
// EOBBits2+=Encode_en(0,T1EHuff2);
//}
/*BFUNC
CBPEncodeAC_en() encodes the AC block matrix when we know there exists a
non-zero coefficient in the matrix. Thus the EOB cannot occur as the
first element and we save countless bits...
EFUNC*/
//void CBPEncodeAC_en(index,matrix)
// int index;
// int *matrix;
//void CBPEncodeAC_en(int index,int *matrix)
//{
// BEGIN("CBPEncodeAC_en");
// int k,r,l,code,retval,ovfl,Start;
//
// Start=swtell_en();
// for(ovfl=1,r=0,k=index-1;++k<BLOCKSIZE;)
// {
// l = matrix[k];
// if (!l) {r++;}
// else
// {
// code = abs(l) | (r << 8);
// if (code != HUFFMAN_ESCAPE) {retval=Encode_en(code,T2EHuff2);}
// else {retval=0;}
// if (!retval)
// {
// Encode_en(HUFFMAN_ESCAPE,T2EHuff2);
// fputv_en(6,r);
// fputv_en(8,l);
// }
// else
// {
// if (l < 0) {fputb(1);}
// else {fputb(0);}
// }
// ovfl=0;
// NumberNZ2++;
// break;
// }
// }
// if (ovfl)
// {
// WHEREAMI();
// printf("CBP2 block without any coefficients.\n");
// return;
// }
// for(r=0;++k<BLOCKSIZE;)
// {
// l = matrix[k];
// if (!l) {r++;}
// else
// {
// code = abs(l) | (r << 8);
// if (code != HUFFMAN_ESCAPE) {retval=Encode_en(code,T1EHuff2);}
// else {retval=0;}
// if (!retval)
// {
// Encode_en(HUFFMAN_ESCAPE,T1EHuff2);
// fputv_en(6,r);
// fputv_en(8,l);
// }
// else
// {
// if (l < 0) {fputb(1);}
// else {fputb(0);}
// }
// r=0;
// NumberNZ2++;
// }
// }
// CodedBlockBits2+=(swtell_en()-Start);
// EOBBits2+=Encode_en(0,T1EHuff2);
//}
/*BFUNC
DecodeAC2() decodes from the stream and puts the elements into the matrix
starting from the value of index. The matrix must be given as input and
initialized to a value at least as large as 64.
EFUNC*/
//void DecodeAC2(index,matrix)
// int index;
// int *matrix;
void DecodeAC2(int index,int *matrix)
{
BEGIN("DecodeAC2");
int k,r,l;
int *mptr;
static int i=0;
for(mptr=matrix+index;mptr<matrix+BLOCKSIZE;mptr++) {*mptr = 0;}
for(k=index;k<BLOCKSIZE;) /* JPEG Mistake */
{
r = Decode2(T1DHuff2);
if (!r) {return;} /*Eof*/
if (r == HUFFMAN_ESCAPE)
{
r = fgetv(6);
l = fgetv(8);
}
else
{
l = r & 0xff;
r = r >> 8;
if (fgetb())
{
l = -l;
}
}
if (l & bit_set_mask2[7])
{
l |= extend_mask2[7];
}
k += r;
matrix[k++] = l;
NumberNZ2++;
}
r=Decode2(T1DHuff2);
printf("======== r = Decode2 = %d\n",r);
if (r)
{
WHEREAMI();
printf("EOB expected, found 0x%x.\n",r);
// exit(1);
}
//i++;
//if(i==2){
// exit(1);
//}
// exit(1);
}
/*BFUNC
CBPDecodeAC2() decodes the stream when we assume the input cannot begin
with an EOB Huffman code. Thus we use a different Huffman table. The
input index is the offset within the matrix and the matrix must
already be defined to be greater than 64 elements of int.
EFUNC*/
//void CBPDecodeAC2(index,matrix)
// int index;
// int *matrix;
void CBPDecodeAC2(int index,int *matrix)
{
BEGIN("CBPDecodeAC2");
int k,r,l;
int *mptr;
for(mptr=matrix+index;mptr<matrix+BLOCKSIZE;mptr++) {*mptr = 0;}
k = index;
r = Decode2(T2DHuff2);
if (!r)
{
WHEREAMI();
printf("Bad EOF in CBP2 block.\n");
return;
}
if (r==HUFFMAN_ESCAPE)
{
r = fgetv(6);
l = fgetv(8);
}
else
{
l = r & 0xff;
r = r >> 8;
if (fgetb()) {l = -l;}
}
if (l & bit_set_mask2[7])
{
l |= extend_mask2[7];
}
k += r;
matrix[k++] = l;
NumberNZ2++;
while(k<BLOCKSIZE)
{
r = Decode2(T1DHuff2);
if (!r) {return;} /*Eof*/
if (r == HUFFMAN_ESCAPE)
{
r = fgetv(6);
l = fgetv(8);
}
else
{
l = r & 0xff;
r = r >> 8;
if (fgetb()) {l = -l;}
}
if (l & bit_set_mask2[7]) {l |= extend_mask2[7];}
k += r;
matrix[k++] = l;
NumberNZ2++;
}
// printf("\n***************************************begin***********************************************\n");
printf("r=Decode2(T1DHuff2) = %d\n",r=Decode2(T1DHuff2));
// printf("r = %d\n",r);
// printf("\n*************************************** end ***********************************************\n");
// if (r=Decode2(T1DHuff2))
if(r)
{
WHEREAMI();
printf("EOB expected, found 0x%x.\n",r);
printf("at run length k=%d\n",k);
}
}
/*BFUNC
DecodeDC2() decodes a dc element from the stream.
EFUNC*/
int DecodeDC2()
{
BEGIN("DecodeDC2");
int l;
l = fgetv(8);
if (l==255)
{
l=128;
}
if (l!=1)
{
NumberNZ2++;
}
return(l);
}
/*BFUNC
EncodeDC_en() encodes the coefficient input into the output2 stream.
EFUNC*/
//void EncodeDC_en(int coef)
//{
// if (coef > 254) {coef=254;}
// if (coef < 1) {coef=1;}
// if (coef!=1) {NumberNZ2++;}
// if (coef==128) {coef=255;}
// fputv_en(8,coef);
// CodedBlockBits2+=8;
//}
/*END*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -