This is parseblock.c in view mode; [Download] [Up]
/*
* Copyright (c) 1992 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#define NO_SANITY_CHECKS
#include <assert.h>
#include "video.h"
#include "decoders.h"
extern int zigzag_direct[];
/* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
#define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
/*
*--------------------------------------------------------------
*
* ParseReconBlock --
*
* Parse values for block structure from bitstream.
* n is an indication of the position of the block within
* the macroblock (i.e. 0-5) and indicates the type of
* block (i.e. luminance or chrominance). Reconstructs
* coefficients from values parsed and puts in
* block.dct_recon array in vid stream structure.
* sparseFlag is set when the block contains only one
* coeffictient and is used by the IDCT.
*
* Results:
* dct_recon is filled with coefficients forming the block.
*
* Side effects:
* Bit stream irreversibly parsed.
*
*--------------------------------------------------------------
*/
#define DCT_recon blockPtr->dct_recon
#define DCT_dc_y_past blockPtr->dct_dc_y_past
#define DCT_dc_cr_past blockPtr->dct_dc_cr_past
#define DCT_dc_cb_past blockPtr->dct_dc_cb_past
#define DECODE_DCT_COEFF_FIRST DecodeDCTCoeffFirst
#define DECODE_DCT_COEFF_NEXT DecodeDCTCoeffNext
int
ParseReconBlock(n, sparseFlag)
int n;
int *sparseFlag;
{
unsigned int temp_curBits;
int temp_bitOffset;
int temp_bufLength;
unsigned int *temp_bitBuffer;
int retval;
Block *blockPtr = &curVidStream->block;
if (bufLength < 100)
correct_underflow();
temp_curBits = curBits;
temp_bitOffset = bitOffset;
temp_bufLength = bufLength;
temp_bitBuffer = bitBuffer;
{
register unsigned int curBits;
register int bitOffset;
register int bufLength;
register unsigned int *bitBuffer;
int diff;
int size, level, i, run, pos;
short int *reconptr, coeff;
unsigned char *iqmatrixptr, *niqmatrixptr;
int qscale;
curBits = temp_curBits;
bitOffset = temp_bitOffset;
bufLength = temp_bufLength;
bitBuffer = temp_bitBuffer;
*sparseFlag = 0;
reconptr = DCT_recon[0];
/*
* Hand coded version of memset that's a little faster...
* Old call:
* memset((char *) DCT_recon, 0, 64*sizeof(short int));
*/
{
/*old code */
/* short int *p;
int j;
p = reconptr;
for (j=0; j<64; j++)
*p++ = 0;*/
/* patch -pk */
long *p = (long *)reconptr;
p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] =
p[10]= p[11]= p[12]= p[13]= p[14]= p[15]= p[16]= p[17]= p[18]= p[19]=
p[20]= p[21]= p[22]= p[23]= p[24]= p[25]= p[26]= p[27]= p[28]= p[29]=
p[30]= p[31]= 0;
}
if (curVidStream->mblock.mb_intra) {
if (n < 4) {
DecodeDCTDCSizeLum(&size);
if (size != 0) {
get_bitsn(size, &diff);
if (!(diff & bitTest[32-size])) {
diff = rBitMask[size] | (diff + 1);
}
}
else diff = 0;
if (n == 0) {
coeff = diff << 3;
if (curVidStream->mblock.mb_address -
curVidStream->mblock.past_intra_addr > 1)
coeff += 1024;
else coeff += DCT_dc_y_past;
DCT_dc_y_past = coeff;
*reconptr = coeff;
(*sparseFlag)++;
}
else {
coeff = DCT_dc_y_past + (diff << 3);
*reconptr = coeff;
(*sparseFlag)++;
DCT_dc_y_past = coeff;
}
}
else {
DecodeDCTDCSizeChrom(&size);
if (size != 0) {
get_bitsn(size, &diff);
if (!(diff & bitTest[32-size])) {
diff = rBitMask[size] | (diff + 1);
}
}
else diff = 0;
if (n == 4) {
coeff = diff << 3;
if (curVidStream->mblock.mb_address -
curVidStream->mblock.past_intra_addr > 1)
coeff += 1024;
else coeff += DCT_dc_cr_past;
DCT_dc_cr_past = coeff;
*reconptr = coeff;
(*sparseFlag)++;
}
else {
coeff = diff << 3;
if (curVidStream->mblock.mb_address -
curVidStream->mblock.past_intra_addr > 1)
coeff += 1024;
else coeff += DCT_dc_cb_past;
DCT_dc_cb_past = coeff;
*reconptr = coeff;
(*sparseFlag)++;
}
}
i = 0; pos = 0;
if (curVidStream->picture.code_type != 4) {
qscale = curVidStream->slice.quant_scale;
iqmatrixptr = curVidStream->intra_quant_matrix[0];
while(1) {
DECODE_DCT_COEFF_NEXT(&run, &level);
if (run == END_OF_BLOCK) break;
i = i + run + 1;
if (i > 63) {
retval = SKIP_TO_START_CODE;
goto end;
}
pos = zigzag_direct[i];
coeff = (level * qscale * ((int) (*(iqmatrixptr+pos))))
>> 3;
if ((coeff & 1) == 0)
coeff -= Sign(coeff);
if (coeff > 2047) coeff = 2047;
else if (coeff < -2048) coeff = -2048;
*(reconptr+pos) = coeff;
(*sparseFlag)++;
}
/* If only one coefficient, store position + 1 in sparseFlag,
otherwise reset to zero.
*/
if (*sparseFlag == 1) *sparseFlag = pos+1;
else *sparseFlag = 0;
flush_bits(2);
retval = PARSE_OK;
goto end;
}
}
else {
niqmatrixptr = curVidStream->non_intra_quant_matrix[0];
qscale = curVidStream->slice.quant_scale;
DECODE_DCT_COEFF_FIRST(&run, &level);
i = run;
pos = zigzag_direct[i];
coeff = (((level<<1) + Sign(level)) * qscale *
((int) (*(niqmatrixptr+pos)))) >> 4;
if ((coeff & 1) == 0)
coeff -= Sign(coeff);
if (coeff > 2047) coeff = 2047;
else if (coeff < -2048) coeff = -2048;
*(reconptr+pos) = coeff;
(*sparseFlag)++;
if (curVidStream->picture.code_type != 4) {
while(1) {
DECODE_DCT_COEFF_NEXT(&run, &level);
if (run == END_OF_BLOCK) break;
i = i+run+1;
if (i > 63) {
retval = SKIP_TO_START_CODE;
goto end;
}
pos = zigzag_direct[i];
coeff = (((level<<1) + Sign(level)) * qscale *
((int) (*(niqmatrixptr+pos)))) >> 4;
if ((coeff & 1) == 0)
coeff -= Sign(coeff);
if (coeff > 2047) coeff = 2047;
else if (coeff < -2048) coeff = -2048;
*(reconptr+pos) = coeff;
(*sparseFlag)++;
}
/* If only one coefficient, store which one in sparseFlag,
otherwise reset to zero.
*/
if (*sparseFlag == 1) *sparseFlag = pos+1;
else *sparseFlag = 0;
flush_bits(2);
retval = PARSE_OK;
goto end;
}
}
retval = PARSE_OK;
end:
temp_curBits = curBits;
temp_bitOffset = bitOffset;
temp_bufLength = bufLength;
temp_bitBuffer = bitBuffer;
}
curBits = temp_curBits;
bitOffset = temp_bitOffset;
bufLength = temp_bufLength;
bitBuffer = temp_bitBuffer;
return retval;
}
#undef DCT_recon
#undef DCT_dc_y_past
#undef DCT_dc_cr_past
#undef DCT_dc_cb_past
/*
*--------------------------------------------------------------
*
* ParseAwayBlock --
*
* Parses off block values, throwing them away.
* Used with grayscale dithering.
*
* Results:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
int
ParseAwayBlock(n)
int n;
{
unsigned int diff;
unsigned int size, run;
int level;
if (bufLength < 100)
correct_underflow();
if (curVidStream->mblock.mb_intra) {
/* If the block is a luminance block... */
if (n < 4) {
/* Parse and decode size of first coefficient. */
DecodeDCTDCSizeLum(&size);
/* Parse first coefficient. */
if (size != 0) {
get_bitsn(size, &diff);
}
}
/* Otherwise, block is chrominance block... */
else {
/* Parse and decode size of first coefficient. */
DecodeDCTDCSizeChrom(&size);
/* Parse first coefficient. */
if (size != 0) {
get_bitsn(size, &diff);
}
}
}
/* Otherwise, block is not intracoded... */
else {
/* Decode and set first coefficient. */
DECODE_DCT_COEFF_FIRST(&run, &level);
}
/* If picture is not D type (i.e. I, P, or B)... */
if (curVidStream->picture.code_type != 4) {
/* While end of macroblock has not been reached... */
while (1) {
/* Get the dct_coeff_next */
DECODE_DCT_COEFF_NEXT(&run, &level);
if (run == END_OF_BLOCK) break;
}
/* End_of_block */
flush_bits(2);
}
return PARSE_OK;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.