diff options
| author | Pixel <Pixel> | 2002-06-21 23:45:51 +0000 | 
|---|---|---|
| committer | Pixel <Pixel> | 2002-06-21 23:45:51 +0000 | 
| commit | cdbb43ea328883261c6f71e6e44b16ae39173fa6 (patch) | |
| tree | 81565694986eef4722a770f1e3a5e7977a359a00 /psxdev | |
| parent | 026e1c60db7b6596a50f325f05fdd54d4a404127 (diff) | |
Still working...
Diffstat (limited to 'psxdev')
| -rw-r--r-- | psxdev/Makefile | 10 | ||||
| -rw-r--r-- | psxdev/bs.c | 348 | ||||
| -rw-r--r-- | psxdev/bs.h | 91 | ||||
| -rw-r--r-- | psxdev/common.h | 47 | ||||
| -rw-r--r-- | psxdev/idctfst.c | 287 | ||||
| -rw-r--r-- | psxdev/jfdctint.c | 291 | ||||
| -rw-r--r-- | psxdev/table.h | 102 | ||||
| -rw-r--r-- | psxdev/vlc.c | 602 | 
8 files changed, 1778 insertions, 0 deletions
| diff --git a/psxdev/Makefile b/psxdev/Makefile new file mode 100644 index 0000000..3db2a0f --- /dev/null +++ b/psxdev/Makefile @@ -0,0 +1,10 @@ +TARGETS=bs.o idctfst.o jfdctint.o vlc.o + +CC=gcc +CPPFLAGS=-march=i386 -O3 + +all: $(TARGETS) + +clean: +	rm -f *.o + diff --git a/psxdev/bs.c b/psxdev/bs.c new file mode 100644 index 0000000..5d7e185 --- /dev/null +++ b/psxdev/bs.c @@ -0,0 +1,348 @@ +/*
 +	(c)2000 by BERO bero@geocities.co.jp
 +
 +	under GPL
 +	
 +	some changes by dbalster@psxdev.de
 +	
 +	- all globals now in a context (to use it as shlib)
 +	- removed debugging printfs
 +*/
 +
 +typedef struct {
 +/* bit i/o */
 +	unsigned int bitbuf;
 +	int bitcount,bs_size,totalbit;
 +	unsigned short *bsbuf;
 +/* huffman */
 +	int last_dc[3];
 +	int _type;
 +	int rlsize;
 +	unsigned char *iqtab;
 +} bs_context_t;
 +
 +#include "bs.h"
 +#include "common.h"
 +
 +static const char *copyright = N_("Copyright (C) 2000 by Daniel Balster <dbalster@psxdev.de>");
 +
 +enum {B,G,R};
 +typedef int BLOCK;
 +
 +#define	DCTSIZE2	64
 +#define	RGB2Y(r,g,b)	(  0.299*(r) + 0.587*(g) + 0.114*(b) )
 +#define	RGB2Cb(r,g,b)	( -0.16874*(r) - 0.33126*(g) +0.5*(b) )
 +#define	RGB2Cr(r,g,b)	(  0.5*(r) - 0.41869*(g) - 0.08131*(b) )
 +
 +/*
 +16x16 RGB -> 8x8 Cb,Cr,Y0,Y1,Y2,Y3
 +
 +[Y0][Y1] [Cb] [Cr]
 +[Y2][Y3]
 +*/
 +#define	Cb	0
 +#define	Cr	DCTSIZE2
 +
 +static void rgb2yuv (unsigned char image[][3], BLOCK *blk)
 +{
 +	int x,y,i;
 +	int tmpblk[16*16][3],(*yuv)[3];
 +	BLOCK *yblk;
 +
 +	yuv=tmpblk;
 +	for(i=0;i<16*16;i++) {
 +		yuv[0][0] = RGB2Y (image[0][R],image[0][G],image[0][B])-128;
 +		yuv[0][1] = RGB2Cb(image[0][R],image[0][G],image[0][B]);
 +		yuv[0][2] = RGB2Cr(image[0][R],image[0][G],image[0][B]);
 +		yuv++; image++;
 +	}
 +
 +	yuv = tmpblk;
 +	yblk = blk+DCTSIZE2*2;
 +	for(y=0;y<16;y+=2,blk+=4,yblk+=8,yuv+=8+16) {
 +		if (y==8) yblk+=DCTSIZE2;
 +		for(x=0;x<4;x++,blk++,yblk+=2,yuv+=2) {
 +			blk[Cb] = (yuv[0][1]+yuv[1][1]+yuv[16][1]+yuv[17][1])/4;
 +			blk[Cr] = (yuv[0][2]+yuv[1][2]+yuv[16][2]+yuv[17][2])/4;
 +			yblk[0] = yuv[ 0][0];
 +			yblk[1] = yuv[ 1][0];
 +			yblk[8] = yuv[16][0];
 +			yblk[9] = yuv[17][0];
 +
 +			blk[4+Cb] = (yuv[8+0][1]+yuv[8+1][1]+yuv[8+16][1]+yuv[8+17][1])/4;
 +			blk[4+Cr] = (yuv[8+0][2]+yuv[8+1][2]+yuv[8+16][2]+yuv[8+17][2])/4;
 +			yblk[DCTSIZE2+0] = yuv[8+ 0][0];
 +			yblk[DCTSIZE2+1] = yuv[8+ 1][0];
 +			yblk[DCTSIZE2+8] = yuv[8+16][0];
 +			yblk[DCTSIZE2+9] = yuv[8+17][0];
 +		}
 +	}
 +}
 +
 +#undef Cb
 +#undef Cr
 +
 +/* bit i/o */
 +#define	BITBUFSIZE	16
 +#define	WriteWord(x)	ctxt->bsbuf[ctxt->bs_size++]=(x)
 +
 +static void putbits_init (bs_context_t *ctxt)
 +{
 +	ctxt->bitbuf = 0;
 +	ctxt->bitcount = BITBUFSIZE;
 +	ctxt->bs_size = 0;
 +	ctxt->totalbit = 0;
 +}
 +
 +static void putbits_flush (bs_context_t *ctxt)
 +{
 +	WriteWord(ctxt->bitbuf);
 +}
 +
 +static void putbits (bs_context_t *ctxt, unsigned int x, unsigned int n)
 +{
 +	ctxt->totalbit+=n;
 +
 +	if (n<ctxt->bitcount) {
 +		ctxt->bitcount-=n;
 +		ctxt->bitbuf |= x << ctxt->bitcount;
 +	} else {
 +		n-=ctxt->bitcount;
 +		WriteWord(ctxt->bitbuf | (x>>n) );
 +		if (n<BITBUFSIZE) {
 +			ctxt->bitcount = BITBUFSIZE-n;
 +		} else {
 +			WriteWord( x>>(n-BITBUFSIZE) );
 +			ctxt->bitcount = BITBUFSIZE*2-n;
 +		}
 +		ctxt->bitbuf = x << ctxt->bitcount;
 +	}
 +}
 +
 +typedef struct {
 +	unsigned char code,nbits;
 +} huff_t;
 +
 +const static huff_t dc_y_table[] = {
 +	{4,3},{0,2},{1,2},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8}
 +};
 +
 +const static huff_t dc_c_table[] = {
 +	{0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}
 +};
 +
 +#include "table.h"
 +
 +static void encode_init (bs_context_t *ctxt, void *outbuf, int type, int q_scale)
 +{
 +	ctxt->_type = type;
 +	ctxt->last_dc[0] = 0;
 +	ctxt->last_dc[1] = 0;
 +	ctxt->last_dc[2] = 0;
 +	ctxt->rlsize = 0;
 +	putbits_init(ctxt);
 +
 +	ctxt->bsbuf = outbuf;
 +	ctxt->bsbuf[1] = 0x3800;
 +	ctxt->bsbuf[2] = q_scale;
 +	ctxt->bsbuf[3] = type;
 +	ctxt->bs_size+=4;
 +}
 +
 +static void encode_finish (bs_context_t *ctxt)
 +{
 +	putbits_flush(ctxt);
 +	ctxt->bsbuf[0] = (((ctxt->rlsize+1)/2)+31)&~31;
 +}
 +
 +static void encode_dc (bs_context_t *ctxt, int n, int level)
 +{
 +	if (ctxt->_type==2) {
 +		putbits(ctxt,level&0x3ff,10);
 +	} else {
 +		const huff_t *table;
 +		int prev,cnt;
 +
 +		level = level/4;
 +		if (n<2) {
 +			table = dc_c_table;
 +			prev = ctxt->last_dc[n];
 +			ctxt->last_dc[n] = level;
 +		} else {
 +			table = dc_y_table;
 +			prev = ctxt->last_dc[2];
 +			ctxt->last_dc[2] = level;
 +		}
 +		level -= prev;
 +		if (level==0) cnt=0;
 +		else {
 +			int alevel = level;
 +			if (alevel<0) alevel=-alevel;
 +			for(cnt=8;(alevel>>cnt)==0;cnt--);
 +			cnt++;
 +			if (level<0) level--;
 +		}
 +		putbits(ctxt,table[cnt].code,table[cnt].nbits);
 +		if (cnt) putbits(ctxt,level&((1<<cnt)-1),cnt);
 +	}
 +	ctxt->rlsize++;
 +}
 +
 +static void encode_ac (bs_context_t *ctxt, int run, int level)
 +{
 +	int abslevel,sign;
 +	if (level>0) {
 +		abslevel = level;
 +		sign = 0;
 +	} else {
 +		abslevel = -level;
 +		sign = 1;
 +	}
 +	if (run<=31 && abslevel<=maxlevel[run]) {
 +		putbits(ctxt,huff_table[run][abslevel-1].code+sign,huff_table[run][abslevel-1].nbits);
 +	} else {
 +		/* ESCAPE */
 +		putbits(ctxt,1,6);
 +		putbits(ctxt,(run<<10)+(level&0x3ff),16);
 +	}
 +	ctxt->rlsize++;
 +}
 +
 +static void encode_eob (bs_context_t *ctxt)
 +{
 +	putbits(ctxt, 2,2);
 +	ctxt->rlsize++;
 +}
 +
 +extern DCT(BLOCK *blk);
 +
 +unsigned char zscan[DCTSIZE2] = {
 +	0 ,1 ,8 ,16,9 ,2 ,3 ,10,
 +	17,24,32,25,18,11,4 ,5 ,
 +	12,19,26,33,40,48,41,34,
 +	27,20,13,6 ,7 ,14,21,28,
 +	35,42,49,56,57,50,43,36,
 +	29,22,15,23,30,37,44,51,
 +	58,59,52,45,38,31,39,46,
 +	53,60,61,54,47,55,62,63
 +};
 +
 +static unsigned char xxx_iqtab[DCTSIZE2] = {
 +	 2,16,19,22,26,27,29,34,
 +	16,16,22,24,27,29,34,37,
 +	19,22,26,27,29,34,34,38,
 +	22,22,26,27,29,34,37,40,
 +	22,26,27,29,32,35,40,48,
 +	26,27,29,32,35,40,48,58,
 +	26,27,29,34,38,46,56,69,
 +	27,29,35,38,46,56,69,83
 +};
 +
 +const unsigned char *bs_iqtab (void) { return xxx_iqtab; }
 +
 +static void blk2huff (bs_context_t *ctxt,BLOCK *blk,int q_scale)
 +{
 +	int i,k,run,level;
 +	for(i=0;i<6;i++) {
 +		DCT(blk);
 +		for(k=0;k<DCTSIZE2;k++) blk[k]>>=3;
 +		level = blk[0]/ctxt->iqtab[0];
 +		encode_dc(ctxt,i,level);
 +		run = 0;
 +		for(k=1;k<64;k++) {
 +			level = blk[zscan[k]]*8/(ctxt->iqtab[zscan[k]]*q_scale);
 +			if (level==0) {
 +				run++;
 +			} else {
 +				encode_ac(ctxt,run,level);
 +				run=0;
 +			}
 +		}
 +		encode_eob(ctxt);
 +		blk+=DCTSIZE2;
 +	}
 +}
 +
 +u_char bs_roundtbl[256*3];
 +
 +void bs_init (void)
 +{
 +	int i;
 +	for(i=0;i<256;i++) {
 +		bs_roundtbl [i]=0;
 +		bs_roundtbl [i+256]=i;
 +		bs_roundtbl [i+512]=255;
 +	}
 +}
 +
 +int bs_encode (bs_header_t *outbuf,bs_input_image_t *img,int type,int q_scale,
 +	unsigned char *myiqtab)
 +{
 +	unsigned char image[16][16][3];
 +	BLOCK blk[6][DCTSIZE2];
 +	bs_context_t *ctxt = malloc(sizeof(bs_context_t));
 +
 +	int x,y,xw,yw,rl;
 +	
 +	ctxt->iqtab = myiqtab ? myiqtab : bs_iqtab();
 +
 +	encode_init (ctxt,outbuf,type,q_scale);
 +
 +	for(x=0;x<img->width;x+=16) {
 +		xw = img->width-x; if (xw>16) xw = 16;
 +		for(y=0;y<img->height;y+=16) {
 +			char *p0 = img->top + x*(img->bit)/8 + y*img->nextline;
 +			int i,j=0;
 +			yw = img->height-y; if (yw>16) yw = 16;
 +
 +			/* get 16x16 image */
 +
 +			for(i=0;i<yw;i++) {
 +				unsigned char *p = p0;
 +				p0+=img->nextline;
 +			  switch(img->bit) {
 +			  case 16:
 +				for(j=0;j<xw;j++) {
 +					int c = *(unsigned short*)p;
 +					image[i][j][B] = ((c>>10)&31)*8;
 +					image[i][j][G] = ((c>>5)&31)*8;
 +					image[i][j][R] = ((c&31))*8;
 +					p+=2;
 +				}
 +				break;
 +			  case 24:
 +				for(j=0;j<xw;j++) {
 +					image[i][j][R] = p[R];
 +					image[i][j][G] = p[G];
 +					image[i][j][B] = p[B];
 +					p+=3;
 +				}
 +				break;
 +			  }
 +				for(;j<16;j++) {
 +					image[i][j][R] = image[i][xw-1][R];
 +					image[i][j][G] = image[i][xw-1][G];
 +					image[i][j][B] = image[i][xw-1][B];
 +				}
 +			}
 +
 +			for(;i<16;i++) {
 +				for(j=0;j<16;j++) {
 +					image[i][j][R] = image[yw-1][j][R];
 +					image[i][j][G] = image[yw-1][j][G];
 +					image[i][j][B] = image[yw-1][j][B];
 +				}
 +			}
 +
 +			rgb2yuv((unsigned char*)image[0],blk[0]);
 +			blk2huff(ctxt,blk[0],q_scale);
 +		}
 +	}
 +
 +	encode_finish(ctxt);
 +	
 +	rl = (ctxt->bs_size * 2);
 +	free (ctxt);
 +	
 +	return rl;
 +}
 diff --git a/psxdev/bs.h b/psxdev/bs.h new file mode 100644 index 0000000..d8d9a6c --- /dev/null +++ b/psxdev/bs.h @@ -0,0 +1,91 @@ +/* $Id: bs.h,v 1.1 2002-06-21 23:45:51 Pixel Exp $ */ + +/* +	libbs - library for the bitstream image format + +	Copyright (C) 1999, 2000 by these people, who contributed to this project + +	  bero@geocities.co.jp +	  Daniel Balster <dbalster@psxdev.de> + +	This program is free software; you can redistribute it and/or modify +	it under the terms of the GNU General Public License as published by +	the Free Software Foundation; either version 2 of the License, or +	(at your option) any later version. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU General Public License for more details. + +	You should have received a copy of the GNU General Public License +	along with this program; if not, write to the Free Software +	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* +	DCT code is based on Independent JPEG Group's sotfware +*/ + +#ifndef __LIB_BS_H +#define __LIB_BS_H + +#define _GNU_SOURCE + +#include <sys/types.h> +#include <stdarg.h> + +typedef struct { +	int width,height; +	int bit; +	int nextline; +	unsigned char *top,*lpbits; +} bs_input_image_t; + +#define BS_MAGIC 0x3800 +#define BS_TYPE 2 + +typedef struct { +	u_short length; +	u_short magic; +	u_short q_scale; +	u_short type; +} bs_header_t; + +/* prototypes */ + +#ifdef __cplusplus +extern "C" { +#endif + +void bs_init (void); + +int bs_encode (				// returns BS image size in bytes +	bs_header_t *outbuf,	// output BS image +	bs_input_image_t *img,	// input image descriptor +	int type,				// image type (use BS_TYPE) +	int q_scale,			// Q scaling factor (1=best,>= lower quality) +	unsigned char *myiqtab	// provide own iqtab (NULL == default) +	); + +void bs_decode_rgb24 ( +	unsigned char *outbuf,	// output RGB bytes (width*height*3) +	bs_header_t *img,		// input BS image +	int width, int height,	// dimension of BS image +	unsigned char *myiqtab +	); + +void bs_decode_rgb15 ( +	unsigned short *outbuf,	// output RGB bytes (width*height*2) +	bs_header_t *img,		// input BS image +	int width, int height,	// dimension of BS image +	unsigned char *myiqtab +	); + +const unsigned char *bs_iqtab (void); + +#ifdef __cplusplus +} +#endif + +#endif /* __LIB_BS_H */ diff --git a/psxdev/common.h b/psxdev/common.h new file mode 100644 index 0000000..ee6e3a1 --- /dev/null +++ b/psxdev/common.h @@ -0,0 +1,47 @@ +/* $Id: common.h,v 1.1 2002-06-21 23:45:51 Pixel Exp $ */ + +/* +	common stuff + +	Copyright (C) 1997, 1998, 1999, 2000 by these people, who contributed to this project + +	  Daniel Balster <dbalster@psxdev.de> + +	This program is free software; you can redistribute it and/or modify +	it under the terms of the GNU General Public License as published by +	the Free Software Foundation; either version 2 of the License, or +	(at your option) any later version. + +	This program is distributed in the hope that it will be useful, +	but WITHOUT ANY WARRANTY; without even the implied warranty of +	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +	GNU General Public License for more details. + +	You should have received a copy of the GNU General Public License +	along with this program; if not, write to the Free Software +	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __COMMON_H +#define __COMMON_H + +#define _GNU_SOURCE +#define _USE_GNU + +#include <sys/types.h> + +#if ENABLE_NLS +#if HAVE_LOCALE_H +#include <locale.h> +#endif +#if HAVE_LIBINTL_H +#include <libintl.h> +#endif +#define _(string) gettext(string) +#define N_(string) (string) +#else +#define _(string) (string) +#define N_(string) (string) +#endif + +#endif diff --git a/psxdev/idctfst.c b/psxdev/idctfst.c new file mode 100644 index 0000000..22faae6 --- /dev/null +++ b/psxdev/idctfst.c @@ -0,0 +1,287 @@ +/* + * jidctfst.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a fast, not so accurate integer implementation of the + * inverse DCT (Discrete Cosine Transform).  In the IJG code, this routine + * must also perform dequantization of the input coefficients. + * + * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT + * on each row (or vice versa, but it's more convenient to emit a row at + * a time).  Direct algorithms are also available, but they are much more + * complex and seem not to be any faster when reduced to code. + * + * This implementation is based on Arai, Agui, and Nakajima's algorithm for + * scaled DCT.  Their original paper (Trans. IEICE E-71(11):1095) is in + * Japanese, but the algorithm is described in the Pennebaker & Mitchell + * JPEG textbook (see REFERENCES section in file README).  The following code + * is based directly on figure 4-8 in P&M. + * While an 8-point DCT cannot be done in less than 11 multiplies, it is + * possible to arrange the computation so that many of the multiplies are + * simple scalings of the final outputs.  These multiplies can then be + * folded into the multiplications or divisions by the JPEG quantization + * table entries.  The AA&N method leaves only 5 multiplies and 29 adds + * to be done in the DCT itself. + * The primary disadvantage of this method is that with fixed-point math, + * accuracy is lost due to imprecise representation of the scaled + * quantization values.  The smaller the quantization table entry, the less + * precise the scaled value, so this implementation does worse with high- + * quality-setting files than with low-quality ones. + */ + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +/* Scaling decisions are generally the same as in the LL&M algorithm; + * see jidctint.c for more details.  However, we choose to descale + * (right shift) multiplication products as soon as they are formed, + * rather than carrying additional fractional bits into subsequent additions. + * This compromises accuracy slightly, but it lets us save a few shifts. + * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) + * everywhere except in the multiplications proper; this saves a good deal + * of work on 16-bit-int machines. + * + * The dequantized coefficients are not integers because the AA&N scaling + * factors have been incorporated.  We represent them scaled up by PASS1_BITS, + * so that the first and second IDCT rounds have the same input scaling. + * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to + * avoid a descaling shift; this compromises accuracy rather drastically + * for small quantization table entries, but it saves a lot of shifts. + * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, + * so we use a much larger scaling factor to preserve accuracy. + * + * A final compromise is to represent the multiplicative constants to only + * 8 fractional bits, rather than 13.  This saves some shifting work on some + * machines, and may also reduce the cost of multiplication (since there + * are fewer one-bits in the constants). + */ +
 +#define	BITS_IN_JSAMPLE	8 + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS  8 +#define PASS1_BITS  2 +#else +#define CONST_BITS  8 +#define PASS1_BITS  1		/* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 8 +#define FIX_1_082392200  (277)		/* FIX(1.082392200) */ +#define FIX_1_414213562  (362)		/* FIX(1.414213562) */ +#define FIX_1_847759065  (473)		/* FIX(1.847759065) */ +#define FIX_2_613125930  (669)		/* FIX(2.613125930) */ +#else +#define FIX_1_082392200  FIX(1.082392200) +#define FIX_1_414213562  FIX(1.414213562) +#define FIX_1_847759065  FIX(1.847759065) +#define FIX_2_613125930  FIX(2.613125930) +#endif + + +/* We can gain a little more speed, with a further compromise in accuracy, + * by omitting the addition in a descaling shift.  This yields an incorrectly + * rounded result half the time... + */ + + +/* Multiply a DCTELEM variable by an INT32 constant, and immediately + * descale to yield a DCTELEM result. + */ + +#define MULTIPLY(var,const)  (DESCALE((var) * (const), CONST_BITS)) + + +/* Dequantize a coefficient by multiplying it by the multiplier-table + * entry; produce a DCTELEM result.  For 8-bit data a 16x16->16 + * multiplication will do.  For 12-bit data, the multiplier table is + * declared INT32, so a 32-bit multiply will be used. + */ +
 +#if BITS_IN_JSAMPLE == 8 +#define DEQUANTIZE(coef,quantval)  (coef) +#else +#define DEQUANTIZE(coef,quantval)  \ +	DESCALE((coef), IFAST_SCALE_BITS-PASS1_BITS) +#endif + + +/* Like DESCALE, but applies to a DCTELEM and produces an int. + * We assume that int right shift is unsigned if INT32 right shift is. + */ + +#define DESCALE(x,n)  ((x)>>(n))
 +#define	RANGE(n)	(n) +#define	BLOCK	int
 + +/* + * Perform dequantization and inverse DCT on one block of coefficients. + */ +#define	DCTSIZE	8
 +#define	DCTSIZE2	64
 +
 +static void IDCT1(BLOCK *block)
 +{
 +	int val = RANGE(DESCALE(block[0], PASS1_BITS+3)); +	int i;
 +	for(i=0;i<DCTSIZE2;i++) block[i]=val;
 +}
 +
 +void IDCT(BLOCK *block,int k)
 +{ +  int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; +  int z5, z10, z11, z12, z13; +  BLOCK *ptr; +  int i; + +  /* Pass 1: process columns from input, store into work array. */ +  switch(k){
 +  case 1:IDCT1(block); return;
 +  }
 + +  ptr = block; +  for (i = 0; i< DCTSIZE; i++,ptr++) { +    /* Due to quantization, we will usually find that many of the input +     * coefficients are zero, especially the AC terms.  We can exploit this +     * by short-circuiting the IDCT calculation for any column in which all +     * the AC terms are zero.  In that case each output is equal to the +     * DC coefficient (with scale factor as needed). +     * With typical images and quantization tables, half or more of the +     * column DCT calculations can be simplified this way. +     */ +     +    if ((ptr[DCTSIZE*1] | ptr[DCTSIZE*2] | ptr[DCTSIZE*3] | +	 ptr[DCTSIZE*4] | ptr[DCTSIZE*5] | ptr[DCTSIZE*6] | +	 ptr[DCTSIZE*7]) == 0) { +      /* AC terms all zero */ +      ptr[DCTSIZE*0] =  +      ptr[DCTSIZE*1] =  +      ptr[DCTSIZE*2] =  +      ptr[DCTSIZE*3] =  +      ptr[DCTSIZE*4] =  +      ptr[DCTSIZE*5] =  +      ptr[DCTSIZE*6] =  +      ptr[DCTSIZE*7] =  +      	ptr[DCTSIZE*0]; +       +      continue; +    } +     +    /* Even part */ + +    z10 = ptr[DCTSIZE*0] + ptr[DCTSIZE*4];	/* phase 3 */ +    z11 = ptr[DCTSIZE*0] - ptr[DCTSIZE*4]; +    z13 = ptr[DCTSIZE*2] + ptr[DCTSIZE*6];	/* phases 5-3 */ +    z12 = MULTIPLY(ptr[DCTSIZE*2] - ptr[DCTSIZE*6], FIX_1_414213562) - z13; /* 2*c4 */ + +    tmp0 = z10 + z13;	/* phase 2 */ +    tmp3 = z10 - z13; +    tmp1 = z11 + z12; +    tmp2 = z11 - z12; +     +    /* Odd part */ + +    z13 = ptr[DCTSIZE*3] + ptr[DCTSIZE*5];		/* phase 6 */ +    z10 = ptr[DCTSIZE*3] - ptr[DCTSIZE*5]; +    z11 = ptr[DCTSIZE*1] + ptr[DCTSIZE*7]; +    z12 = ptr[DCTSIZE*1] - ptr[DCTSIZE*7]; + +    z5 = MULTIPLY(z12 - z10, FIX_1_847759065);
 +    tmp7 = z11 + z13;		/* phase 5 */ +    tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7;	/* phase 2 */ +    tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6; +    tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5; + +    ptr[DCTSIZE*0] = (tmp0 + tmp7); +    ptr[DCTSIZE*7] = (tmp0 - tmp7); +    ptr[DCTSIZE*1] = (tmp1 + tmp6); +    ptr[DCTSIZE*6] = (tmp1 - tmp6); +    ptr[DCTSIZE*2] = (tmp2 + tmp5); +    ptr[DCTSIZE*5] = (tmp2 - tmp5); +    ptr[DCTSIZE*4] = (tmp3 + tmp4); +    ptr[DCTSIZE*3] = (tmp3 - tmp4); + +  } +   +  /* Pass 2: process rows from work array, store into output array. */ +  /* Note that we must descale the results by a factor of 8 == 2**3, */ +  /* and also undo the PASS1_BITS scaling. */ + +  ptr = block; +  for (i = 0; i < DCTSIZE; i++ ,ptr+=DCTSIZE) { +    /* Rows of zeroes can be exploited in the same way as we did with columns. +     * However, the column calculation has created many nonzero AC terms, so +     * the simplification applies less often (typically 5% to 10% of the time). +     * On machines with very fast multiplication, it's possible that the +     * test takes more time than it's worth.  In that case this section +     * may be commented out. +     */ +     +#ifndef NO_ZERO_ROW_TEST +    if ((ptr[1] | ptr[2] | ptr[3] | ptr[4] | ptr[5] | ptr[6] | +	 ptr[7]) == 0) { +      /* AC terms all zero */ +      ptr[0] = 
 +      ptr[1] = 
 +      ptr[2] = 
 +      ptr[3] = 
 +      ptr[4] = 
 +      ptr[5] = 
 +      ptr[6] = 
 +      ptr[7] = 
 +      	RANGE(DESCALE(ptr[0], PASS1_BITS+3));; + +      continue; +    } +#endif +     +    /* Even part */ +
 +    z10 = ptr[0] + ptr[4]; +    z11 = ptr[0] - ptr[4]; +    z13 = ptr[2] + ptr[6]; +    z12 = MULTIPLY(ptr[2] - ptr[6], FIX_1_414213562) - z13; + +    tmp0 = z10 + z13; +    tmp3 = z10 - z13; +    tmp1 = z11 + z12; +    tmp2 = z11 - z12; + +    /* Odd part */ + +    z13 = ptr[3] + ptr[5]; +    z10 = ptr[3] - ptr[5]; +    z11 = ptr[1] + ptr[7]; +    z12 = ptr[1] - ptr[7]; + +    z5 = MULTIPLY(z12 - z10, FIX_1_847759065);
 +    tmp7 = z11 + z13;		/* phase 5 */ +    tmp6 = MULTIPLY(z10, FIX_2_613125930) + z5 - tmp7;	/* phase 2 */ +    tmp5 = MULTIPLY(z11 - z13, FIX_1_414213562) - tmp6; +    tmp4 = MULTIPLY(z12, FIX_1_082392200) - z5 + tmp5; + +    /* Final output stage: scale down by a factor of 8 and range-limit */ + +    ptr[0] = RANGE(DESCALE(tmp0 + tmp7, PASS1_BITS+3));; +    ptr[7] = RANGE(DESCALE(tmp0 - tmp7, PASS1_BITS+3));; +    ptr[1] = RANGE(DESCALE(tmp1 + tmp6, PASS1_BITS+3));; +    ptr[6] = RANGE(DESCALE(tmp1 - tmp6, PASS1_BITS+3));; +    ptr[2] = RANGE(DESCALE(tmp2 + tmp5, PASS1_BITS+3));; +    ptr[5] = RANGE(DESCALE(tmp2 - tmp5, PASS1_BITS+3));; +    ptr[4] = RANGE(DESCALE(tmp3 + tmp4, PASS1_BITS+3));; +    ptr[3] = RANGE(DESCALE(tmp3 - tmp4, PASS1_BITS+3));; + +  } +} + diff --git a/psxdev/jfdctint.c b/psxdev/jfdctint.c new file mode 100644 index 0000000..58bc2e4 --- /dev/null +++ b/psxdev/jfdctint.c @@ -0,0 +1,291 @@ +/* + * jfdctint.c + * + * Copyright (C) 1991-1994, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains a slow-but-accurate integer implementation of the + * forward DCT (Discrete Cosine Transform). + * + * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT + * on each column.  Direct algorithms are also available, but they are + * much more complex and seem not to be any faster when reduced to code. + * + * This implementation is based on an algorithm described in + *   C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT + *   Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, + *   Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. + * The primary algorithm described there uses 11 multiplies and 29 adds. + * We use their alternate method with 12 multiplies and 32 adds. + * The advantage of this method is that no data path contains more than one + * multiplication; this allows a very simple and accurate implementation in + * scaled fixed-point arithmetic, with a minimal number of shifts. + */ + +#define DCT_ISLOW_SUPPORTED
 +#define DCTSIZE 8
 +#define	DCTELEM	int
 +#define	INT32	int
 +#define DESCALE(x,n)  RIGHT_SHIFT((x) + (1 << ((n)-1)), n) +#define	RIGHT_SHIFT(x,n)	((x)>>(n))
 +#define	GLOBAL
 +#define jpeg_fdct_islow DCT +#define SHIFT_TEMPS
 +//#define BITS_IN_JSAMPLE 8
 +//#define MULTIPLY16C16(var,const)	((var) * (const)) +
 +
 +#ifdef DCT_ISLOW_SUPPORTED + + +/* + * This module is specialized to the case DCTSIZE = 8. + */ + +#if DCTSIZE != 8 +  Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */ +#endif + + +/* + * The poop on this scaling stuff is as follows: + * + * Each 1-D DCT step produces outputs which are a factor of sqrt(N) + * larger than the true DCT outputs.  The final outputs are therefore + * a factor of N larger than desired; since N=8 this can be cured by + * a simple right shift at the end of the algorithm.  The advantage of + * this arrangement is that we save two multiplications per 1-D DCT, + * because the y0 and y4 outputs need not be divided by sqrt(N). + * In the IJG code, this factor of 8 is removed by the quantization step + * (in jcdctmgr.c), NOT in this module. + * + * We have to do addition and subtraction of the integer inputs, which + * is no problem, and multiplication by fractional constants, which is + * a problem to do in integer arithmetic.  We multiply all the constants + * by CONST_SCALE and convert them to integer constants (thus retaining + * CONST_BITS bits of precision in the constants).  After doing a + * multiplication we have to divide the product by CONST_SCALE, with proper + * rounding, to produce the correct output.  This division can be done + * cheaply as a right shift of CONST_BITS bits.  We postpone shifting + * as long as possible so that partial sums can be added together with + * full fractional precision. + * + * The outputs of the first pass are scaled up by PASS1_BITS bits so that + * they are represented to better-than-integral precision.  These outputs + * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word + * with the recommended scaling.  (For 12-bit sample data, the intermediate + * array is INT32 anyway.) + * + * To avoid overflow of the 32-bit intermediate results in pass 2, we must + * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26.  Error analysis + * shows that the values given below are the most effective. + */ + +#if BITS_IN_JSAMPLE == 8 +#define CONST_BITS  13 +#define PASS1_BITS  2 +#else +#define CONST_BITS  13 +#define PASS1_BITS  1		/* lose a little precision to avoid overflow */ +#endif + +/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus + * causing a lot of useless floating-point operations at run time. + * To get around this we use the following pre-calculated constants. + * If you change CONST_BITS you may want to add appropriate values. + * (With a reasonable C compiler, you can just rely on the FIX() macro...) + */ + +#if CONST_BITS == 13 +#define FIX_0_298631336  ((INT32)  2446)	/* FIX(0.298631336) */ +#define FIX_0_390180644  ((INT32)  3196)	/* FIX(0.390180644) */ +#define FIX_0_541196100  ((INT32)  4433)	/* FIX(0.541196100) */ +#define FIX_0_765366865  ((INT32)  6270)	/* FIX(0.765366865) */ +#define FIX_0_899976223  ((INT32)  7373)	/* FIX(0.899976223) */ +#define FIX_1_175875602  ((INT32)  9633)	/* FIX(1.175875602) */ +#define FIX_1_501321110  ((INT32)  12299)	/* FIX(1.501321110) */ +#define FIX_1_847759065  ((INT32)  15137)	/* FIX(1.847759065) */ +#define FIX_1_961570560  ((INT32)  16069)	/* FIX(1.961570560) */ +#define FIX_2_053119869  ((INT32)  16819)	/* FIX(2.053119869) */ +#define FIX_2_562915447  ((INT32)  20995)	/* FIX(2.562915447) */ +#define FIX_3_072711026  ((INT32)  25172)	/* FIX(3.072711026) */ +#else +#define FIX_0_298631336  FIX(0.298631336) +#define FIX_0_390180644  FIX(0.390180644) +#define FIX_0_541196100  FIX(0.541196100) +#define FIX_0_765366865  FIX(0.765366865) +#define FIX_0_899976223  FIX(0.899976223) +#define FIX_1_175875602  FIX(1.175875602) +#define FIX_1_501321110  FIX(1.501321110) +#define FIX_1_847759065  FIX(1.847759065) +#define FIX_1_961570560  FIX(1.961570560) +#define FIX_2_053119869  FIX(2.053119869) +#define FIX_2_562915447  FIX(2.562915447) +#define FIX_3_072711026  FIX(3.072711026) +#endif + + +/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. + * For 8-bit samples with the recommended scaling, all the variable + * and constant values involved are no more than 16 bits wide, so a + * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. + * For 12-bit samples, a full 32-bit multiplication will be needed. + */ + +#if BITS_IN_JSAMPLE == 8 +#define MULTIPLY(var,const)  MULTIPLY16C16(var,const) +#else +#define MULTIPLY(var,const)  ((var) * (const)) +#endif + + +/* + * Perform the forward DCT on one block of samples. + */ + +GLOBAL void +jpeg_fdct_islow (DCTELEM * data) +{ +  INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; +  INT32 tmp10, tmp11, tmp12, tmp13; +  INT32 z1, z2, z3, z4, z5; +  DCTELEM *dataptr; +  int ctr; +  SHIFT_TEMPS + +  /* Pass 1: process rows. */ +  /* Note results are scaled up by sqrt(8) compared to a true DCT; */ +  /* furthermore, we scale the results by 2**PASS1_BITS. */ + +  dataptr = data; +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { +    tmp0 = dataptr[0] + dataptr[7]; +    tmp7 = dataptr[0] - dataptr[7]; +    tmp1 = dataptr[1] + dataptr[6]; +    tmp6 = dataptr[1] - dataptr[6]; +    tmp2 = dataptr[2] + dataptr[5]; +    tmp5 = dataptr[2] - dataptr[5]; +    tmp3 = dataptr[3] + dataptr[4]; +    tmp4 = dataptr[3] - dataptr[4]; +     +    /* Even part per LL&M figure 1 --- note that published figure is faulty; +     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". +     */ +     +    tmp10 = tmp0 + tmp3; +    tmp13 = tmp0 - tmp3; +    tmp11 = tmp1 + tmp2; +    tmp12 = tmp1 - tmp2; +     +    dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS); +    dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS); +     +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); +    dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), +				   CONST_BITS-PASS1_BITS); +    dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), +				   CONST_BITS-PASS1_BITS); +     +    /* Odd part per figure 8 --- note paper omits factor of sqrt(2). +     * cK represents cos(K*pi/16). +     * i0..i3 in the paper are tmp4..tmp7 here. +     */ +     +    z1 = tmp4 + tmp7; +    z2 = tmp5 + tmp6; +    z3 = tmp4 + tmp6; +    z4 = tmp5 + tmp7; +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ +     +    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ +    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ +    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ +    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ +     +    z3 += z5; +    z4 += z5; +     +    dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS); +    dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS); +    dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); +    dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); +     +    dataptr += DCTSIZE;		/* advance pointer to next row */ +  } + +  /* Pass 2: process columns. +   * We remove the PASS1_BITS scaling, but leave the results scaled up +   * by an overall factor of 8. +   */ + +  dataptr = data; +  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) { +    tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; +    tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; +    tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; +    tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; +    tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; +    tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; +    tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; +    tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; +     +    /* Even part per LL&M figure 1 --- note that published figure is faulty; +     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6". +     */ +     +    tmp10 = tmp0 + tmp3; +    tmp13 = tmp0 - tmp3; +    tmp11 = tmp1 + tmp2; +    tmp12 = tmp1 - tmp2; +     +    dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS); +    dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS); +     +    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); +    dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), +					   CONST_BITS+PASS1_BITS); +    dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), +					   CONST_BITS+PASS1_BITS); +     +    /* Odd part per figure 8 --- note paper omits factor of sqrt(2). +     * cK represents cos(K*pi/16). +     * i0..i3 in the paper are tmp4..tmp7 here. +     */ +     +    z1 = tmp4 + tmp7; +    z2 = tmp5 + tmp6; +    z3 = tmp4 + tmp6; +    z4 = tmp5 + tmp7; +    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */ +     +    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */ +    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */ +    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */ +    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */ +    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */ +    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */ +    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */ +    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */ +     +    z3 += z5; +    z4 += z5; +     +    dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, +					   CONST_BITS+PASS1_BITS); +    dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, +					   CONST_BITS+PASS1_BITS); +    dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, +					   CONST_BITS+PASS1_BITS); +    dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, +					   CONST_BITS+PASS1_BITS); +     +    dataptr++;			/* advance pointer to next column */ +  } +} + +#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/psxdev/table.h b/psxdev/table.h new file mode 100644 index 0000000..3e50b18 --- /dev/null +++ b/psxdev/table.h @@ -0,0 +1,102 @@ +const static huff_t table0[]={
 +	{6,3},{8,5},{10,6},{12,8},{76,9},{66,9},{20,11},{58,13},{48,13},{38,13},{32,13},{52,14},{50,14},{48,14},{46,14},{62,15},{60,15},{58,15},{56,15},{54,15},{52,15},{50,15},{48,15},{46,15},{44,15},{42,15},{40,15},{38,15},{36,15},{34,15},{32,15},{48,16},{46,16},{44,16},{42,16},{40,16},{38,16},{36,16},{34,16},{32,16},
 +};
 +const static huff_t table1[]={
 +	{6,4},{12,7},{74,9},{24,11},{54,13},{44,14},{42,14},{62,16},{60,16},{58,16},{56,16},{54,16},{52,16},{50,16},{38,17},{36,17},{34,17},{32,17},
 +};
 +const static huff_t table2[]={
 +	{10,5},{8,8},{22,11},{40,13},{40,14},
 +};
 +const static huff_t table3[]={
 +	{14,6},{72,9},{56,13},{38,14},
 +};
 +const static huff_t table4[]={
 +	{12,6},{30,11},{36,13},
 +};
 +const static huff_t table5[]={
 +	{14,7},{18,11},{36,14},
 +};
 +const static huff_t table6[]={
 +	{10,7},{60,13},{40,17},
 +};
 +const static huff_t table7[]={
 +	{8,7},{42,13},
 +};
 +const static huff_t table8[]={
 +	{14,8},{34,13},
 +};
 +const static huff_t table9[]={
 +	{10,8},{34,14},
 +};
 +const static huff_t table10[]={
 +	{78,9},{32,14},
 +};
 +const static huff_t table11[]={
 +	{70,9},{52,17},
 +};
 +const static huff_t table12[]={
 +	{68,9},{50,17},
 +};
 +const static huff_t table13[]={
 +	{64,9},{48,17},
 +};
 +const static huff_t table14[]={
 +	{28,11},{46,17},
 +};
 +const static huff_t table15[]={
 +	{26,11},{44,17},
 +};
 +const static huff_t table16[]={
 +	{16,11},{42,17},
 +};
 +const static huff_t table17[]={
 +	{62,13},
 +};
 +const static huff_t table18[]={
 +	{52,13},
 +};
 +const static huff_t table19[]={
 +	{50,13},
 +};
 +const static huff_t table20[]={
 +	{46,13},
 +};
 +const static huff_t table21[]={
 +	{44,13},
 +};
 +const static huff_t table22[]={
 +	{62,14},
 +};
 +const static huff_t table23[]={
 +	{60,14},
 +};
 +const static huff_t table24[]={
 +	{58,14},
 +};
 +const static huff_t table25[]={
 +	{56,14},
 +};
 +const static huff_t table26[]={
 +	{54,14},
 +};
 +const static huff_t table27[]={
 +	{62,17},
 +};
 +const static huff_t table28[]={
 +	{60,17},
 +};
 +const static huff_t table29[]={
 +	{58,17},
 +};
 +const static huff_t table30[]={
 +	{56,17},
 +};
 +const static huff_t table31[]={
 +	{54,17},
 +};
 +const static huff_t *huff_table[]={
 +	table0,table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table14,table15,table16,table17,table18,table19,table20,table21,table22,table23,table24,table25,table26,table27,table28,table29,table30,table31,
 +};
 +const static int maxlevel[]={
 +	40,18,5,4,3,3,3,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 +};
 diff --git a/psxdev/vlc.c b/psxdev/vlc.c new file mode 100644 index 0000000..aa7e610 --- /dev/null +++ b/psxdev/vlc.c @@ -0,0 +1,602 @@ +#include "bs.h"
 +#include <sys/types.h>
 +
 +#define	SOFT
 +
 +#define	CODE1(a,b,c)	(((a)<<10)|((b)&0x3ff)|((c)<<16))
 +/* run, level, bit */
 +#define	CODE(a,b,c)		CODE1(a,b,c+1),CODE1(a,-b,c+1)
 +#define	CODE0(a,b,c)	CODE1(a,b,c),CODE1(a,b,c)
 +#define	CODE2(a,b,c)	CODE1(a,b,c+1),CODE1(a,b,c+1)
 +#define	RUNOF(a)	((a)>>10)
 +#define	VALOF(a)	((short)((a)<<6)>>6)
 +#define	BITOF(a)	((a)>>16)
 +#define	EOB	0xfe00
 +#define	ESCAPE_CODE	CODE1(63,0,6)
 +#define	EOB_CODE	CODE1(63,512,2)
 +
 +/*
 +	DC code
 +	Y			U,V
 +0	100			00	 		0
 +1	00x			01x			-1,1
 +2	01xx		10xx		-3,-2,2,3
 +3	101xxx		110xxx		-7..-4,4..7
 +4	110xxxx		1110		-15..-8,8..15
 +5	1110xxxxx	11110		-31..-16,16..31
 +6	11110xxxxxx	111110		-63..-32,32..63
 +7	111110		1111110		-127..-64,64..127
 +8	1111110		11111110	-255..-128,128..255
 +	7+8			8+8
 +*/
 +
 +/*
 +	This table based on MPEG2DEC by MPEG Software Simulation Group
 +*/
 +
 +/* Table B-14, DCT coefficients	table zero,
 +* codes	0100 ... 1xxx (used	for	all	other coefficients)
 +*/
 +static const u_long VLCtabnext[12*2] =	{
 +	CODE(0,2,4),  CODE(2,1,4),	CODE2(1,1,3),  CODE2(1,-1,3),
 +	CODE0(63,512,2), CODE0(63,512,2), CODE0(63,512,2), CODE0(63,512,2),	/*EOB*/
 +	CODE2(0,1,2),  CODE2(0,1,2),	CODE2(0,-1,2),  CODE2(0,-1,2)
 +};
 +
 +/* Table B-14, DCT coefficients	table zero,
 +* codes	000001xx ... 00111xxx
 +*/
 +static const u_long VLCtab0[60*2] = {
 +	CODE0(63,0,6), CODE0(63,0,6),CODE0(63,0,6), CODE0(63,0,6), /* ESCAPE */
 +	CODE2(2,2,7), CODE2(2,-2,7), CODE2(9,1,7), CODE2(9,-1,7),
 +	CODE2(0,4,7), CODE2(0,-4,7), CODE2(8,1,7), CODE2(8,-1,7),
 +	CODE2(7,1,6), CODE2(7,1,6), CODE2(7,-1,6), CODE2(7,-1,6),
 +	CODE2(6,1,6), CODE2(6,1,6), CODE2(6,-1,6), CODE2(6,-1,6),
 +	CODE2(1,2,6), CODE2(1,2,6), CODE2(1,-2,6), CODE2(1,-2,6),
 +	CODE2(5,1,6), CODE2(5,1,6), CODE2(5,-1,6), CODE2(5,-1,6),
 +	CODE(13,1,8), CODE(0,6,8), CODE(12,1,8), CODE(11,1,8),
 +	CODE(3,2,8), CODE(1,3,8), CODE(0,5,8), CODE(10,1,8),
 +	CODE2(0,3,5), CODE2(0,3,5), CODE2(0,3,5), CODE2(0,3,5),
 +	CODE2(0,-3,5), CODE2(0,-3,5), CODE2(0,-3,5), CODE2(0,-3,5),
 +	CODE2(4,1,5), CODE2(4,1,5), CODE2(4,1,5), CODE2(4,1,5),
 +	CODE2(4,-1,5), CODE2(4,-1,5), CODE2(4,-1,5), CODE2(4,-1,5),
 +	CODE2(3,1,5), CODE2(3,1,5), CODE2(3,1,5), CODE2(3,1,5),
 +	CODE2(3,-1,5), CODE2(3,-1,5), CODE2(3,-1,5), CODE2(3,-1,5)
 +};
 +
 +/* Table B-14, DCT coefficients	table zero,
 +* codes	0000001000 ... 0000001111
 +*/
 +static const u_long VLCtab1[8*2] =	{
 +	CODE(16,1,10), CODE(5,2,10), CODE(0,7,10), CODE(2,3,10),
 +	CODE(1,4,10), CODE(15,1,10), CODE(14,1,10),	CODE(4,2,10)
 +};
 +
 +/* Table B-14/15, DCT coefficients table zero /	one,
 +* codes	000000010000 ... 000000011111
 +*/
 +static const u_long VLCtab2[16*2] = {
 +	CODE(0,11,12), CODE(8,2,12), CODE(4,3,12), CODE(0,10,12),
 +	CODE(2,4,12), CODE(7,2,12),	CODE(21,1,12), CODE(20,1,12),
 +	CODE(0,9,12), CODE(19,1,12), CODE(18,1,12),	CODE(1,5,12),
 +	CODE(3,3,12), CODE(0,8,12),	CODE(6,2,12), CODE(17,1,12)
 +};
 +
 +/* Table B-14/15, DCT coefficients table zero /	one,
 +* codes	0000000010000 ... 0000000011111
 +*/
 +static const u_long VLCtab3[16*2] = {
 +	CODE(10,2,13), CODE(9,2,13), CODE(5,3,13), CODE(3,4,13),
 +	CODE(2,5,13), CODE(1,7,13),	CODE(1,6,13), CODE(0,15,13),
 +	CODE(0,14,13), CODE(0,13,13), CODE(0,12,13), CODE(26,1,13),
 +	CODE(25,1,13), CODE(24,1,13), CODE(23,1,13), CODE(22,1,13)
 +};
 +
 +/* Table B-14/15, DCT coefficients table zero /	one,
 +* codes	00000000010000 ... 00000000011111
 +*/
 +static const u_long VLCtab4[16*2] = {
 +	CODE(0,31,14), CODE(0,30,14), CODE(0,29,14), CODE(0,28,14),
 +	CODE(0,27,14), CODE(0,26,14), CODE(0,25,14), CODE(0,24,14),
 +	CODE(0,23,14), CODE(0,22,14), CODE(0,21,14), CODE(0,20,14),
 +	CODE(0,19,14), CODE(0,18,14), CODE(0,17,14), CODE(0,16,14)
 +};
 +
 +/* Table B-14/15, DCT coefficients table zero /	one,
 +* codes	000000000010000	...	000000000011111
 +*/
 +static const u_long VLCtab5[16*2] = {
 +	CODE(0,40,15), CODE(0,39,15), CODE(0,38,15), CODE(0,37,15),
 +	CODE(0,36,15), CODE(0,35,15), CODE(0,34,15), CODE(0,33,15),
 +	CODE(0,32,15), CODE(1,14,15), CODE(1,13,15), CODE(1,12,15),
 +	CODE(1,11,15), CODE(1,10,15), CODE(1,9,15),	CODE(1,8,15)
 +};
 +
 +/* Table B-14/15, DCT coefficients table zero /	one,
 +* codes	0000000000010000 ... 0000000000011111
 +*/
 +static const u_long VLCtab6[16*2] = {
 +	CODE(1,18,16), CODE(1,17,16), CODE(1,16,16), CODE(1,15,16),
 +	CODE(6,3,16), CODE(16,2,16), CODE(15,2,16),	CODE(14,2,16),
 +	CODE(13,2,16), CODE(12,2,16), CODE(11,2,16), CODE(31,1,16),
 +	CODE(30,1,16), CODE(29,1,16), CODE(28,1,16), CODE(27,1,16)
 +};
 +
 +/*
 +	DC code
 +	Y				U,V
 +0	100				00	 				0
 +1	00x				01x					-1,1
 +2	01xx			10xx				-3,-2,2,3
 +3	101xxx			110xxx				-7..-4,4..7
 +4	110xxxx			1110xxxx			-15..-8,8..15
 +5	1110xxxxx		11110xxxxx			-31..-16,16..31
 +6	11110xxxxxx		111110xxxxxx		-63..-32,32..63
 +7	111110xxxxxxx	1111110xxxxxxx		-127..-64,64..127
 +8	1111110xxxxxxxx	11111110xxxxxxxx	-255..-128,128..255
 +*/
 +
 +static const u_long DC_Ytab0[48] = {
 +	CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),
 +	CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),
 +	CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),
 +	CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),
 +
 +	CODE1(0,-3,4),CODE1(0,-3,4),CODE1(0,-3,4),CODE1(0,-3,4),
 +	CODE1(0,-2,4),CODE1(0,-2,4),CODE1(0,-2,4),CODE1(0,-2,4),
 +	CODE1(0,2,4),CODE1(0,2,4),CODE1(0,2,4),CODE1(0,2,4),
 +	CODE1(0,3,4),CODE1(0,3,4),CODE1(0,3,4),CODE1(0,3,4),
 +
 +	CODE1(0,0,3),CODE1(0,0,3),CODE1(0,0,3),CODE1(0,0,3),
 +	CODE1(0,0,3),CODE1(0,0,3),CODE1(0,0,3),CODE1(0,0,3),
 +	CODE1(0,-7,6),CODE1(0,-6,6),CODE1(0,-5,6),CODE1(0,-4,6),
 +	CODE1(0,4,6),CODE1(0,5,6),CODE1(0,6,6),CODE1(0,7,6),
 +
 +};
 +
 +static const u_long DC_UVtab0[56] = {
 +	CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),
 +	CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),
 +	CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),
 +	CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),CODE1(0,0,2),
 +
 +	CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),
 +	CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),CODE1(0,-1,3),
 +	CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),
 +	CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),CODE1(0,1,3),
 +
 +	CODE1(0,-3,4),CODE1(0,-3,4),CODE1(0,-3,4),CODE1(0,-3,4),
 +	CODE1(0,-2,4),CODE1(0,-2,4),CODE1(0,-2,4),CODE1(0,-2,4),
 +	CODE1(0,2,4),CODE1(0,2,4),CODE1(0,2,4),CODE1(0,2,4),
 +	CODE1(0,3,4),CODE1(0,3,4),CODE1(0,3,4),CODE1(0,3,4),
 +
 +	CODE1(0,-7,6),CODE1(0,-6,6),CODE1(0,-5,6),CODE1(0,-4,6),
 +	CODE1(0,4,6),CODE1(0,5,6),CODE1(0,6,6),CODE1(0,7,6),
 +};
 +
 +#define	DCTSIZE2	64
 +
 +/* decode one intra	coded MPEG-1 block */
 +
 +#define	Show_Bits(N)	(bitbuf>>(32-(N)))
 +/* 最小有効bit 17 bit*/
 +
 +#define	Flush_Buffer(N) {bitbuf <<=(N);incnt +=(N);while(incnt>=0) {bitbuf |= Get_Word()<<incnt;incnt-=16;}}
 +
 +#define	Init_Buffer() {bitbuf = (mdec_bs[0]<<16)|(mdec_bs[1]);mdec_bs+=2;incnt = -16;}
 +
 +#define	Get_Word()	(*mdec_bs++)
 +#define	Printf	printf
 +
 +
 +int DecDCTvlc(u_short *mdec_bs,u_short *mdec_rl)
 +{
 +//	u_short *mdec_bs = mdecbs,*mdec_rl = mdecrl
 +	u_short *rl_end;
 +	u_long bitbuf;
 +	int incnt; /* 16-有効bit数 x86=char risc = long */
 +	int q_code;
 +	int type,n;
 +	int last_dc[3];
 +
 +/* BS_HDR  u_short rlsize,magic,ver,q_scale */
 +
 +	//printf("%04x,%04x,",mdec_bs[0],mdec_bs[1]);
 +	*(long*)mdec_rl=*(long*)mdec_bs;
 +	mdec_rl+=2;
 +	rl_end = mdec_rl+(int)mdec_bs[0]*2;
 +	q_code = (mdec_bs[2]<<10); /* code = q */
 +	type = mdec_bs[3];
 +	mdec_bs+=4;
 +
 +	Init_Buffer();
 +
 +	n = 0;
 +	last_dc[0]=last_dc[1]=last_dc[2] = 0;
 +	while(mdec_rl<rl_end) {
 +	  u_long code2;
 +		/* DC */
 +	  if (type==2) {
 +		code2 = Show_Bits(10)|(10<<16); /* DC code */
 +	  } else {
 +		code2 = Show_Bits(6);
 +		if (n>=2) {
 +			/* Y */
 +			if (code2<48) {
 +				code2 = DC_Ytab0[code2];
 +				code2 = (code2&0xffff0000)|((last_dc[2]+=VALOF(code2)*4)&0x3ff);
 +			} else {
 +				int nbit,val;
 +				int bit = 3;
 +				while(Show_Bits(bit)&1) { bit++;}
 +				bit++;
 +				nbit = bit*2-1;
 +				val = Show_Bits(nbit)&((1<<bit)-1);
 +				if ((val&(1<<(bit-1)))==0)
 +					val -= (1<<bit)-1;
 +				val = (last_dc[2]+=val*4);
 +				code2 = (nbit<<16) | (val&0x3ff);
 +			}
 +			//printf("%d ",last_dc[2]);
 +		} else {
 +			/* U,V */
 +			if (code2<56) {
 +				code2 = DC_UVtab0[code2];
 +				code2 = (code2&0xffff0000)|((last_dc[n]+=VALOF(code2)*4)&0x3ff);
 +			} else {
 +				int nbit,val;
 +				int bit = 4;
 +				while(Show_Bits(bit)&1) { bit++;}
 +				nbit = bit*2;
 +				val = Show_Bits(nbit)&((1<<bit)-1);
 +				if ((val&(1<<(bit-1)))==0)
 +					val -= (1<<bit)-1;
 +				val = (last_dc[n]+=val*4);
 +				code2 = (nbit<<16) | (val&0x3ff);
 +			}
 +			//printf("%d ",last_dc[n]);
 +		}
 +		if (++n==6) n=0;
 +	  }
 +	//	printf("%d ",VALOF(code2));
 +	  code2 |= q_code;
 +
 +		/* AC */
 +	  for(;;){
 +//		u_long code;
 +#define	code code2
 +#define	SBIT	17
 +		*mdec_rl++=code2;
 +		Flush_Buffer(BITOF(code2));
 +		code = Show_Bits(SBIT);
 +		if      (code>=1<<(SBIT- 2)) {
 +			code2 = VLCtabnext[(code>>12)-8];
 +			if (code2==EOB_CODE) break;
 +		}
 +		else if (code>=1<<(SBIT- 6)) {
 +			code2 = VLCtab0[(code>>8)-8];
 +			if (code2==ESCAPE_CODE) {
 +				Flush_Buffer(6); /* ESCAPE len */
 +				code2 = Show_Bits(16)| (16<<16);
 +			}
 +		}
 +		else if (code>=1<<(SBIT- 7)) code2 = VLCtab1[(code>>6)-16];
 +		else if (code>=1<<(SBIT- 8)) code2 = VLCtab2[(code>>4)-32];
 +		else if (code>=1<<(SBIT- 9)) code2 = VLCtab3[(code>>3)-32];
 +		else if (code>=1<<(SBIT-10)) code2 = VLCtab4[(code>>2)-32];
 +		else if (code>=1<<(SBIT-11)) code2 = VLCtab5[(code>>1)-32];
 +		else if (code>=1<<(SBIT-12)) code2 = VLCtab6[(code>>0)-32];
 +		else {
 +			do {
 +				*mdec_rl++=EOB;
 +			} while(mdec_rl<rl_end);
 +			return 0;
 +		}
 +	  }
 +	  *mdec_rl++=code2; /* EOB code */
 +	  Flush_Buffer(2); /* EOB bitlen */
 +	}
 +	return 0;
 +}
 +
 +
 +
 +/* this table is based on djpeg by Independent Jpeg Group */
 +
 +static const int aanscales[DCTSIZE2] = {
 +	  /* precomputed values scaled up by 14 bits */
 +	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 +	  22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,
 +	  21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,
 +	  19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,
 +	  16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,
 +	  12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,
 +	   8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,
 +	   4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247
 +};
 +
 +extern unsigned char zscan[DCTSIZE2];
 +
 +typedef struct {
 +	int iqtab[DCTSIZE2];
 +	unsigned char *iq_y;
 +	u_short *mdec_rl,*rl_end;
 +	int mdec_mode;
 +} bs_context_t;
 +
 +void iqtab_init(bs_context_t *ctxt)
 +{
 +#define CONST_BITS 14
 +#define	IFAST_SCALE_BITS 2
 +	int i;
 +	for(i=0;i<DCTSIZE2;i++) {
 +		ctxt->iqtab[i] =ctxt->iq_y[i]*aanscales[i]>>(CONST_BITS-IFAST_SCALE_BITS);
 +	}
 +}
 +
 +#define	BLOCK	long
 +
 +extern IDCT(BLOCK *blk,int k);
 +
 +u_short* rl2blk(bs_context_t *ctxt, BLOCK *blk,u_short *mdec_rl)
 +{
 +	int i,k,q_scale,rl;
 +	memset(blk,0,6*DCTSIZE2*sizeof(BLOCK));
 +	for(i=0;i<6;i++) {
 +		rl = *mdec_rl++;
 +		q_scale = RUNOF(rl);
 +		blk[0] = ctxt->iqtab[0]*VALOF(rl);
 +		k = 0;
 +		for(;;) {
 +			rl = *mdec_rl++;
 +			if (rl==EOB) break;
 +			k += RUNOF(rl)+1;
 +			blk[zscan[k]] = ctxt->iqtab[zscan[k]]*q_scale*VALOF(rl)/8;
 +		}
 +
 +		IDCT(blk,k+1);
 +		
 +		blk+=DCTSIZE2;
 +	}
 +	return mdec_rl;
 +}
 +
 +#define	RGB15(r,g,b)	( (((b)&0xf8)<<7)|(((g)&0xf8)<<2)|((r)>>3) )
 +
 +#define	ROUND(r)	bs_roundtbl[(r)+256]
 +#if 1
 +#define	SHIFT	12
 +#define	toFIX(a)	(int)((a)*(1<<SHIFT))
 +#define	toINT(a)	((a)>>SHIFT)
 +#define	FIX_1	toFIX(1)
 +#define	MULR(a)	toINT((a)*toFIX(1.402))
 +#define	MULG(a)	toINT((a)*toFIX(-0.3437))
 +#define	MULG2(a)	toINT((a)*toFIX(-0.7143))
 +#define	MULB(a)	toINT((a)*toFIX(1.772))
 +#else
 +#define	MULR(a)	0
 +#define	MULG(a)	0
 +#define	MULG2(a)	0
 +#define	MULB(a)	0
 +#endif
 +
 +
 +/*
 +int ROUND(int r)
 +{
 +	if (r<0) return 0;
 +	else if (r>255) return 255;
 +	else return r;
 +}
 +*/
 +
 +extern u_char bs_roundtbl[256*3];
 +
 +static void yuv2rgb15(BLOCK *blk,u_short *image)
 +{
 +	int x,yy;
 +	BLOCK *yblk = blk+DCTSIZE2*2;
 +	for(yy=0;yy<16;yy+=2,blk+=4,yblk+=8,image+=8+16) {
 +		if (yy==8) yblk+=DCTSIZE2;
 +		for(x=0;x<4;x++,blk++,yblk+=2,image+=2) {
 +			int r0,b0,g0,y;
 +			r0 = MULR(blk[DCTSIZE2]); /* cr */
 +			g0 = MULG(blk[0])+MULG2(blk[DCTSIZE2]);
 +			b0 = MULB(blk[0]); /* cb */
 +			y = yblk[0]+128;
 +			image[0] = RGB15(ROUND(r0+y),ROUND(g0+y),ROUND(b0+y));
 +			y = yblk[1]+128+4;
 +			image[1] = RGB15(ROUND(r0+y),ROUND(g0+y),ROUND(b0+y));
 +			y = yblk[8]+128+6;
 +			image[16] = RGB15(ROUND(r0+y),ROUND(g0+y),ROUND(b0+y));
 +			y = yblk[9]+128+2;
 +			image[17] = RGB15(ROUND(r0+y),ROUND(g0+y),ROUND(b0+y));
 +			r0 = MULR(blk[4+DCTSIZE2]);
 +			g0 = MULG(blk[4])+MULG2(blk[4+DCTSIZE2]);
 +			b0 = MULB(blk[4]);
 +			y = yblk[DCTSIZE2+0]+128;
 +			image[8+0] = RGB15(ROUND(r0+y),ROUND(g0+y),ROUND(b0+y));
 +			y = yblk[DCTSIZE2+1]+128+4;
 +			image[8+1] = RGB15(ROUND(r0+y),ROUND(g0+y),ROUND(b0+y));
 +			y = yblk[DCTSIZE2+8]+128+6;
 +			image[8+16] = RGB15(ROUND(r0+y),ROUND(g0+y),ROUND(b0+y));
 +			y = yblk[DCTSIZE2+9]+128+2;
 +			image[8+17] = RGB15(ROUND(r0+y),ROUND(g0+y),ROUND(b0+y));
 +		}
 +	}
 +}
 +
 +enum {B,G,R};
 +
 +static void yuv2rgb24(BLOCK *blk,u_char image[][3])
 +{
 +	int x,yy;
 +	BLOCK *yblk = blk+DCTSIZE2*2;
 +	for(yy=0;yy<16;yy+=2,blk+=4,yblk+=8,image+=8+16) {
 +		if (yy==8) yblk+=DCTSIZE2;
 +		for(x=0;x<4;x++,blk++,yblk+=2,image+=2) {
 +			int r0,b0,g0,y;
 +			r0 = MULR(blk[DCTSIZE2]); /* cr */
 +			g0 = MULG(blk[0])+MULG2(blk[DCTSIZE2]);
 +			b0 = MULB(blk[0]); /* cb */
 +			y = yblk[0]+128;
 +			image[0][R] = ROUND(r0+y);
 +			image[0][G] = ROUND(g0+y);
 +			image[0][B] = ROUND(b0+y);
 +			y = yblk[1]+128;
 +			image[1][R] = ROUND(r0+y);
 +			image[1][G] = ROUND(g0+y);
 +			image[1][B] = ROUND(b0+y);
 +			y = yblk[8]+128;
 +			image[16][R] = ROUND(r0+y);
 +			image[16][G] = ROUND(g0+y);
 +			image[16][B] = ROUND(b0+y);
 +			y = yblk[9]+128;
 +			image[17][R] = ROUND(r0+y);
 +			image[17][G] = ROUND(g0+y);
 +			image[17][B] = ROUND(b0+y);
 +
 +			r0 = MULR(blk[4+DCTSIZE2]);
 +			g0 = MULG(blk[4])+MULG2(blk[4+DCTSIZE2]);
 +			b0 = MULB(blk[4]);
 +			y = yblk[DCTSIZE2+0]+128;
 +			image[8+0][R] = ROUND(r0+y);
 +			image[8+0][G] = ROUND(g0+y);
 +			image[8+0][B] = ROUND(b0+y);
 +			y = yblk[DCTSIZE2+1]+128;
 +			image[8+1][R] = ROUND(r0+y);
 +			image[8+1][G] = ROUND(g0+y);
 +			image[8+1][B] = ROUND(b0+y);
 +			y = yblk[DCTSIZE2+8]+128;
 +			image[8+16][R] = ROUND(r0+y);
 +			image[8+16][G] = ROUND(g0+y);
 +			image[8+16][B] = ROUND(b0+y);
 +			y = yblk[DCTSIZE2+9]+128;
 +			image[8+17][R] = ROUND(r0+y);
 +			image[8+17][G] = ROUND(g0+y);
 +			image[8+17][B] = ROUND(b0+y);
 +		}
 +	}
 +}
 +
 +static void DecDCTReset(bs_context_t *ctxt, int mode)
 +{
 +	iqtab_init(ctxt);
 +}
 +
 +static void DecDCTin(bs_context_t *ctxt, u_short *mdecrl,int mode)
 +{
 +	mdecrl+=2;
 +	ctxt->mdec_rl = mdecrl;
 +	ctxt->rl_end = mdecrl+mdecrl[-2]*2;
 +	ctxt->mdec_mode = mode;
 +}
 +
 +static void DecDCTout(bs_context_t *ctxt, u_short *image,int size)
 +{
 +	BLOCK blk[DCTSIZE2*6];
 +	int blocksize=16*16;
 +	if (ctxt->mdec_mode) blocksize = 16*16*3/2;
 +	for(;size>0;size-=blocksize/2,image+=blocksize) {
 +		ctxt->mdec_rl = rl2blk(ctxt,blk,ctxt->mdec_rl);
 +		if (ctxt->mdec_mode==0) yuv2rgb15(blk,image);
 +		else yuv2rgb24(blk,image);
 +	}
 +}
 +
 +void bs_decode_rgb24 (
 +	unsigned char *outbuf,	// output RGB bytes (width*height*3)
 +	bs_header_t *img,		// input BS image
 +	int width, int height,	// dimension of BS image
 +	unsigned char *myiqtab
 +	)
 +{
 +	unsigned short *buf2 = (unsigned short *) outbuf;
 +	unsigned short *bufp = (unsigned short *) img;
 +	bs_context_t ctxt;
 +	unsigned short *rl,*image;
 +	int slice,rlsize;
 +	int mode;
 +	int x,y;
 +	int height2 = (height+15)&~15;
 +	int w;
 +
 +	ctxt.iq_y = myiqtab ? myiqtab : bs_iqtab();
 +	mode=1;
 +	w=24;
 +	width = width*3/2;
 +
 +	image = (unsigned short *) malloc (height2*w*sizeof(short));
 +	rl = (unsigned short *) malloc ((bufp[0]+2)*sizeof(long));
 +
 +	DecDCTReset(&ctxt,0);
 +	DecDCTvlc(bufp,rl);
 +	DecDCTin(&ctxt,rl,mode);
 +
 +	slice = height2*w/2;
 +
 +	for(x=0;x<width;x+=w)
 +	{
 +		short *dst,*src;
 +		DecDCTout(&ctxt,image,slice);
 +		src = image;
 + 		dst = buf2+x+(0)*width;
 + 		for(y=height-1;y>=0;y--)
 + 		{
 + 			memcpy(dst,src,w*2);
 + 			src+=w;
 + 			dst+=width;
 + 		}
 +	}
 +
 +	free (image);
 +	free (rl);
 +}
 +
 +void bs_decode_rgb15 (
 +	unsigned short *outbuf,	// output RGB bytes (width*height*2)
 +	bs_header_t *img,		// input BS image
 +	int width, int height,	// dimension of BS image
 +	unsigned char *myiqtab
 +	)
 +{
 +	unsigned short *buf2 = (unsigned short *) outbuf;
 +	unsigned short *bufp = (unsigned short *) img;
 +	bs_context_t ctxt;
 +	unsigned short *rl,*image;
 +	int slice,rlsize;
 +	int mode;
 +	int x,y;
 +	int height2 = (height+15)&~15;
 +	int w;
 +
 +	ctxt.iq_y = myiqtab ? myiqtab : bs_iqtab();
 +	mode=0;
 +	w=24;
 +
 +	image = (unsigned short *) malloc (height2*w*sizeof(short));
 +	rl = (unsigned short *) malloc ((bufp[0]+2)*sizeof(long));
 +
 +	DecDCTReset(&ctxt,0);
 +	DecDCTvlc(bufp,rl);
 +	DecDCTin(&ctxt,rl,mode);
 +
 +	slice = height2*w/2;
 +
 +	for(x=0;x<width;x+=w)
 +	{
 +		short *dst,*src;
 +		DecDCTout(&ctxt,image,slice);
 +		src = image;
 +		dst = buf2+x+(height-1)*width;
 +		for(y=height-1;y>=0;y--)
 +		{
 +			memcpy(dst,src,w*2);
 +			src+=w;
 +			dst-=width;
 +		}
 +	}
 +
 +	free (image);
 +	free (rl);
 +}
 | 
