2009-05-13 02:58:57 +00:00
|
|
|
|
/*
|
2001-12-27 21:27:29 +00:00
|
|
|
|
RTjpeg (C) Justin Schoeman 1998 (justin@suntiger.ee.up.ac.za)
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
With modifications by:
|
|
|
|
|
(c) 1998, 1999 by Joerg Walter <trouble@moes.pmnet.uni-oldenburg.de>
|
|
|
|
|
and
|
|
|
|
|
(c) 1999 by Wim Taymans <wim.taymans@tvd.be>
|
|
|
|
|
|
|
|
|
|
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
|
2007-01-22 08:02:06 +00:00
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2001-12-27 21:27:29 +00:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2001-12-27 22:07:37 +00:00
|
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
2006-12-07 11:58:07 +00:00
|
|
|
|
#include "mpbswap.h"
|
2008-04-06 18:17:59 +00:00
|
|
|
|
#include "rtjpegn.h"
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if HAVE_MMX
|
2001-12-27 21:27:29 +00:00
|
|
|
|
#include "mmx.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//#define SHOWBLOCK 1
|
|
|
|
|
#define BETTERCOMPRESSION 1
|
|
|
|
|
|
|
|
|
|
static const unsigned char RTjpeg_ZZ[64]={
|
|
|
|
|
0,
|
|
|
|
|
8, 1,
|
|
|
|
|
2, 9, 16,
|
|
|
|
|
24, 17, 10, 3,
|
|
|
|
|
4, 11, 18, 25, 32,
|
|
|
|
|
40, 33, 26, 19, 12, 5,
|
|
|
|
|
6, 13, 20, 27, 34, 41, 48,
|
|
|
|
|
56, 49, 42, 35, 28, 21, 14, 7,
|
|
|
|
|
15, 22, 29, 36, 43, 50, 57,
|
|
|
|
|
58, 51, 44, 37, 30, 23,
|
|
|
|
|
31, 38, 45, 52, 59,
|
|
|
|
|
60, 53, 46, 39,
|
|
|
|
|
47, 54, 61,
|
|
|
|
|
62, 55,
|
|
|
|
|
63 };
|
|
|
|
|
|
|
|
|
|
static const __u64 RTjpeg_aan_tab[64]={
|
2009-05-13 02:58:57 +00:00
|
|
|
|
4294967296ULL, 5957222912ULL, 5611718144ULL, 5050464768ULL, 4294967296ULL, 3374581504ULL, 2324432128ULL, 1184891264ULL,
|
|
|
|
|
5957222912ULL, 8263040512ULL, 7783580160ULL, 7005009920ULL, 5957222912ULL, 4680582144ULL, 3224107520ULL, 1643641088ULL,
|
|
|
|
|
5611718144ULL, 7783580160ULL, 7331904512ULL, 6598688768ULL, 5611718144ULL, 4408998912ULL, 3036936960ULL, 1548224000ULL,
|
|
|
|
|
5050464768ULL, 7005009920ULL, 6598688768ULL, 5938608128ULL, 5050464768ULL, 3968072960ULL, 2733115392ULL, 1393296000ULL,
|
|
|
|
|
4294967296ULL, 5957222912ULL, 5611718144ULL, 5050464768ULL, 4294967296ULL, 3374581504ULL, 2324432128ULL, 1184891264ULL,
|
|
|
|
|
3374581504ULL, 4680582144ULL, 4408998912ULL, 3968072960ULL, 3374581504ULL, 2651326208ULL, 1826357504ULL, 931136000ULL,
|
|
|
|
|
2324432128ULL, 3224107520ULL, 3036936960ULL, 2733115392ULL, 2324432128ULL, 1826357504ULL, 1258030336ULL, 641204288ULL,
|
|
|
|
|
1184891264ULL, 1643641088ULL, 1548224000ULL, 1393296000ULL, 1184891264ULL, 931136000ULL, 641204288ULL, 326894240ULL,
|
2001-12-27 21:27:29 +00:00
|
|
|
|
};
|
|
|
|
|
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if !HAVE_MMX
|
2001-12-27 21:27:29 +00:00
|
|
|
|
static __s32 RTjpeg_ws[64+31];
|
|
|
|
|
#endif
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static __u8 RTjpeg_alldata[2*64+4*64+4*64+4*64+4*64+32];
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2001-12-28 18:01:42 +00:00
|
|
|
|
static __s16 *block; // rh
|
|
|
|
|
static __s16 *RTjpeg_block;
|
|
|
|
|
static __s32 *RTjpeg_lqt;
|
|
|
|
|
static __s32 *RTjpeg_cqt;
|
|
|
|
|
static __u32 *RTjpeg_liqt;
|
|
|
|
|
static __u32 *RTjpeg_ciqt;
|
|
|
|
|
|
|
|
|
|
static unsigned char RTjpeg_lb8;
|
|
|
|
|
static unsigned char RTjpeg_cb8;
|
|
|
|
|
static int RTjpeg_width, RTjpeg_height;
|
|
|
|
|
static int RTjpeg_Ywidth, RTjpeg_Cwidth;
|
|
|
|
|
static int RTjpeg_Ysize, RTjpeg_Csize;
|
|
|
|
|
|
|
|
|
|
static __s16 *RTjpeg_old=NULL;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if HAVE_MMX
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static mmx_t RTjpeg_lmask;
|
|
|
|
|
static mmx_t RTjpeg_cmask;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
#else
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static __u16 RTjpeg_lmask;
|
|
|
|
|
static __u16 RTjpeg_cmask;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static const unsigned char RTjpeg_lum_quant_tbl[64] = {
|
|
|
|
|
16, 11, 10, 16, 24, 40, 51, 61,
|
|
|
|
|
12, 12, 14, 19, 26, 58, 60, 55,
|
|
|
|
|
14, 13, 16, 24, 40, 57, 69, 56,
|
|
|
|
|
14, 17, 22, 29, 51, 87, 80, 62,
|
|
|
|
|
18, 22, 37, 56, 68, 109, 103, 77,
|
|
|
|
|
24, 35, 55, 64, 81, 104, 113, 92,
|
|
|
|
|
49, 64, 78, 87, 103, 121, 120, 101,
|
|
|
|
|
72, 92, 95, 98, 112, 100, 103, 99
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const unsigned char RTjpeg_chrom_quant_tbl[64] = {
|
|
|
|
|
17, 18, 24, 47, 99, 99, 99, 99,
|
|
|
|
|
18, 21, 26, 66, 99, 99, 99, 99,
|
|
|
|
|
24, 26, 56, 99, 99, 99, 99, 99,
|
|
|
|
|
47, 66, 99, 99, 99, 99, 99, 99,
|
|
|
|
|
99, 99, 99, 99, 99, 99, 99, 99,
|
|
|
|
|
99, 99, 99, 99, 99, 99, 99, 99,
|
|
|
|
|
99, 99, 99, 99, 99, 99, 99, 99,
|
|
|
|
|
99, 99, 99, 99, 99, 99, 99, 99
|
|
|
|
|
};
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
#ifdef BETTERCOMPRESSION
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------*/
|
|
|
|
|
/* better encoding, but needs a lot more cpu time */
|
|
|
|
|
/* seems to be more effective than old method +lzo */
|
|
|
|
|
/* with this encoding lzo isn't efficient anymore */
|
|
|
|
|
/* there is still more potential for better */
|
|
|
|
|
/* encoding but that would need even more cputime */
|
|
|
|
|
/* anyway your mileage may vary */
|
|
|
|
|
/* */
|
|
|
|
|
/* written by Martin BIELY and Roman HOCHLEITNER */
|
|
|
|
|
/*--------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
/* +++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|
|
|
|
/* Block to Stream (encoding) */
|
|
|
|
|
/* */
|
|
|
|
|
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static int RTjpeg_b2s(__s16 *data, __s8 *strm, __u8 bt8)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
register int ci, co=1;
|
|
|
|
|
register __s16 ZZvalue;
|
|
|
|
|
register unsigned char bitten;
|
|
|
|
|
register unsigned char bitoff;
|
|
|
|
|
|
|
|
|
|
#ifdef SHOWBLOCK
|
|
|
|
|
|
|
|
|
|
int ii;
|
|
|
|
|
for (ii=0; ii < 64; ii++) {
|
|
|
|
|
fprintf(stdout, "%d ", data[RTjpeg_ZZ[ii]]);
|
|
|
|
|
}
|
|
|
|
|
fprintf(stdout, "\n\n");
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// first byte allways written
|
2004-05-01 18:42:50 +00:00
|
|
|
|
((__u8*)strm)[0]=
|
2001-12-27 21:27:29 +00:00
|
|
|
|
(__u8)(data[RTjpeg_ZZ[0]]>254) ? 254:((data[RTjpeg_ZZ[0]]<0)?0:data[RTjpeg_ZZ[0]]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ci=63;
|
|
|
|
|
while (data[RTjpeg_ZZ[ci]]==0 && ci>0) ci--;
|
|
|
|
|
|
|
|
|
|
bitten = ((unsigned char)ci) << 2;
|
|
|
|
|
|
|
|
|
|
if (ci==0) {
|
2009-05-13 02:58:57 +00:00
|
|
|
|
((__u8*)strm)[1]= bitten;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
co = 2;
|
|
|
|
|
return (int)co;
|
|
|
|
|
}
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
|
|
|
|
/* bitoff=0 because the high 6bit contain first non zero position */
|
2001-12-27 21:27:29 +00:00
|
|
|
|
bitoff = 0;
|
|
|
|
|
co = 1;
|
|
|
|
|
|
|
|
|
|
for(; ci>0; ci--) {
|
|
|
|
|
|
|
|
|
|
ZZvalue = data[RTjpeg_ZZ[ci]];
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
switch(ZZvalue) {
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
bitten |= (0x01<<bitoff);
|
|
|
|
|
break;
|
|
|
|
|
case -1:
|
|
|
|
|
bitten |= (0x03<<bitoff);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
bitten |= (0x02<<bitoff);
|
|
|
|
|
goto HERZWEH;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( bitoff == 0 ) {
|
2009-05-13 02:58:57 +00:00
|
|
|
|
((__u8*)strm)[co]= bitten;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
bitten = 0;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
bitoff = 8;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
co++;
|
|
|
|
|
} /* "fall through" */
|
2009-05-13 02:58:57 +00:00
|
|
|
|
bitoff-=2;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
}
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
/* ci must be 0 */
|
|
|
|
|
if(bitoff != 6) {
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
((__u8*)strm)[co]= bitten;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
co++;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
}
|
|
|
|
|
goto BAUCHWEH;
|
|
|
|
|
|
|
|
|
|
HERZWEH:
|
|
|
|
|
/* ci cannot be 0 */
|
|
|
|
|
/* correct bitoff to nibble boundaries */
|
|
|
|
|
|
|
|
|
|
switch(bitoff){
|
|
|
|
|
case 4:
|
|
|
|
|
case 6:
|
|
|
|
|
bitoff = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
case 0:
|
2009-05-13 02:58:57 +00:00
|
|
|
|
((__u8*)strm)[co]= bitten;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
bitoff = 4;
|
|
|
|
|
co++;
|
|
|
|
|
bitten = 0; // clear half nibble values in bitten
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(; ci>0; ci--) {
|
|
|
|
|
|
|
|
|
|
ZZvalue = data[RTjpeg_ZZ[ci]];
|
|
|
|
|
|
|
|
|
|
if( (ZZvalue > 7) || (ZZvalue < -7) ) {
|
|
|
|
|
bitten |= (0x08<<bitoff);
|
|
|
|
|
goto HIRNWEH;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
bitten |= (ZZvalue&0xf)<<bitoff;
|
|
|
|
|
|
|
|
|
|
if( bitoff == 0 ) {
|
2009-05-13 02:58:57 +00:00
|
|
|
|
((__u8*)strm)[co]= bitten;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
bitten = 0;
|
|
|
|
|
bitoff = 8;
|
|
|
|
|
co++;
|
|
|
|
|
} /* "fall thru" */
|
|
|
|
|
bitoff-=4;
|
|
|
|
|
}
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
/* ci must be 0 */
|
|
|
|
|
if( bitoff == 0 ) {
|
2009-05-13 02:58:57 +00:00
|
|
|
|
((__u8*)strm)[co]= bitten;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
co++;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
goto BAUCHWEH;
|
|
|
|
|
|
|
|
|
|
HIRNWEH:
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
((__u8*)strm)[co]= bitten;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
co++;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
/* bitting is over now we bite */
|
|
|
|
|
for(; ci>0; ci--) {
|
|
|
|
|
|
|
|
|
|
ZZvalue = data[RTjpeg_ZZ[ci]];
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
if(ZZvalue>0)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
strm[co++]=(__s8)(ZZvalue>127)?127:ZZvalue;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
strm[co++]=(__s8)(ZZvalue<-128)?-128:ZZvalue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
BAUCHWEH:
|
|
|
|
|
/* we gotoo much now we are ill */
|
|
|
|
|
#ifdef SHOWBLOCK
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
fprintf(stdout, "\nco = '%d'\n", co);
|
|
|
|
|
for (i=0; i < co+2; i++) {
|
|
|
|
|
fprintf(stdout, "%d ", strm[i]);
|
|
|
|
|
}
|
|
|
|
|
fprintf(stdout, "\n\n");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return (int)co;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static int RTjpeg_b2s(__s16 *data, __s8 *strm, __u8 bt8)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
register int ci, co=1, tmp;
|
|
|
|
|
register __s16 ZZvalue;
|
|
|
|
|
|
|
|
|
|
#ifdef SHOWBLOCK
|
|
|
|
|
|
|
|
|
|
int ii;
|
|
|
|
|
for (ii=0; ii < 64; ii++) {
|
|
|
|
|
fprintf(stdout, "%d ", data[RTjpeg_ZZ[ii]]);
|
|
|
|
|
}
|
|
|
|
|
fprintf(stdout, "\n\n");
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
(__u8)strm[0]=(__u8)(data[RTjpeg_ZZ[0]]>254) ? 254:((data[RTjpeg_ZZ[0]]<0)?0:data[RTjpeg_ZZ[0]]);
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
for(ci=1; ci<=bt8; ci++)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
ZZvalue = data[RTjpeg_ZZ[ci]];
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
if(ZZvalue>0)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
strm[co++]=(__s8)(ZZvalue>127)?127:ZZvalue;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
strm[co++]=(__s8)(ZZvalue<-128)?-128:ZZvalue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
for(; ci<64; ci++)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
ZZvalue = data[RTjpeg_ZZ[ci]];
|
|
|
|
|
|
|
|
|
|
if(ZZvalue>0)
|
|
|
|
|
{
|
|
|
|
|
strm[co++]=(__s8)(ZZvalue>63)?63:ZZvalue;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
else if(ZZvalue<0)
|
|
|
|
|
{
|
|
|
|
|
strm[co++]=(__s8)(ZZvalue<-64)?-64:ZZvalue;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
else /* compress zeros */
|
|
|
|
|
{
|
|
|
|
|
tmp=ci;
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
ci++;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
while((ci<64)&&(data[RTjpeg_ZZ[ci]]==0));
|
|
|
|
|
|
|
|
|
|
strm[co++]=(__s8)(63+(ci-tmp));
|
|
|
|
|
ci--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return (int)co;
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static int RTjpeg_s2b(__s16 *data, __s8 *strm, __u8 bt8, __u32 *qtbl)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
int ci=1, co=1, tmp;
|
|
|
|
|
register int i;
|
|
|
|
|
|
|
|
|
|
i=RTjpeg_ZZ[0];
|
|
|
|
|
data[i]=((__u8)strm[0])*qtbl[i];
|
|
|
|
|
|
|
|
|
|
for(co=1; co<=bt8; co++)
|
|
|
|
|
{
|
|
|
|
|
i=RTjpeg_ZZ[co];
|
|
|
|
|
data[i]=strm[ci++]*qtbl[i];
|
|
|
|
|
}
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
for(; co<64; co++)
|
|
|
|
|
{
|
|
|
|
|
if(strm[ci]>63)
|
|
|
|
|
{
|
|
|
|
|
tmp=co+strm[ci]-63;
|
|
|
|
|
for(; co<tmp; co++)data[RTjpeg_ZZ[co]]=0;
|
|
|
|
|
co--;
|
|
|
|
|
} else
|
|
|
|
|
{
|
|
|
|
|
i=RTjpeg_ZZ[co];
|
|
|
|
|
data[i]=strm[ci]*qtbl[i];
|
|
|
|
|
}
|
|
|
|
|
ci++;
|
|
|
|
|
}
|
|
|
|
|
return (int)ci;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if HAVE_MMX
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static void RTjpeg_quant_init(void)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
__s16 *qtbl;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
qtbl=(__s16 *)RTjpeg_lqt;
|
|
|
|
|
for(i=0; i<64; i++)qtbl[i]=(__s16)RTjpeg_lqt[i];
|
|
|
|
|
|
|
|
|
|
qtbl=(__s16 *)RTjpeg_cqt;
|
|
|
|
|
for(i=0; i<64; i++)qtbl[i]=(__s16)RTjpeg_cqt[i];
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-02 03:35:50 +00:00
|
|
|
|
static mmx_t RTjpeg_ones={0x0001000100010001LL};
|
|
|
|
|
static mmx_t RTjpeg_half={0x7fff7fff7fff7fffLL};
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static void RTjpeg_quant(__s16 *block, __s32 *qtbl)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
mmx_t *bl, *ql;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
ql=(mmx_t *)qtbl;
|
|
|
|
|
bl=(mmx_t *)block;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
movq_m2r(RTjpeg_ones, mm6);
|
|
|
|
|
movq_m2r(RTjpeg_half, mm7);
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
for(i=16; i; i--)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
movq_m2r(*(ql++), mm0); /* quant vals (4) */
|
|
|
|
|
movq_m2r(*bl, mm2); /* block vals (4) */
|
|
|
|
|
movq_r2r(mm0, mm1);
|
|
|
|
|
movq_r2r(mm2, mm3);
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
punpcklwd_r2r(mm6, mm0); /* 1 qb 1 qa */
|
|
|
|
|
punpckhwd_r2r(mm6, mm1); /* 1 qd 1 qc */
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
punpcklwd_r2r(mm7, mm2); /* 32767 bb 32767 ba */
|
|
|
|
|
punpckhwd_r2r(mm7, mm3); /* 32767 bd 32767 bc */
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
pmaddwd_r2r(mm2, mm0); /* 32767+bb*qb 32767+ba*qa */
|
|
|
|
|
pmaddwd_r2r(mm3, mm1); /* 32767+bd*qd 32767+bc*qc */
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
psrad_i2r(16, mm0);
|
|
|
|
|
psrad_i2r(16, mm1);
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
packssdw_r2r(mm1, mm0);
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
movq_r2m(mm0, *(bl++));
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#else
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static void RTjpeg_quant_init(void)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static void RTjpeg_quant(__s16 *block, __s32 *qtbl)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
for(i=0; i<64; i++)
|
|
|
|
|
block[i]=(__s16)((block[i]*qtbl[i]+32767)>>16);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Perform the forward DCT on one block of samples.
|
|
|
|
|
*/
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if HAVE_MMX
|
2004-08-02 03:35:50 +00:00
|
|
|
|
static mmx_t RTjpeg_C4 ={0x2D412D412D412D41LL};
|
|
|
|
|
static mmx_t RTjpeg_C6 ={0x187E187E187E187ELL};
|
|
|
|
|
static mmx_t RTjpeg_C2mC6={0x22A322A322A322A3LL};
|
|
|
|
|
static mmx_t RTjpeg_C2pC6={0x539F539F539F539FLL};
|
|
|
|
|
static mmx_t RTjpeg_zero ={0x0000000000000000LL};
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
#define FIX_0_382683433 ((__s32) 98) /* FIX(0.382683433) */
|
|
|
|
|
#define FIX_0_541196100 ((__s32) 139) /* FIX(0.541196100) */
|
|
|
|
|
#define FIX_0_707106781 ((__s32) 181) /* FIX(0.707106781) */
|
|
|
|
|
#define FIX_1_306562965 ((__s32) 334) /* FIX(1.306562965) */
|
|
|
|
|
|
|
|
|
|
#define DESCALE10(x) (__s16)( ((x)+128) >> 8)
|
|
|
|
|
#define DESCALE20(x) (__s16)(((x)+32768) >> 16)
|
|
|
|
|
#define D_MULTIPLY(var,const) ((__s32) ((var) * (const)))
|
|
|
|
|
#endif
|
|
|
|
|
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static void RTjpeg_dct_init(void)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
for(i=0; i<64; i++)
|
|
|
|
|
{
|
|
|
|
|
RTjpeg_lqt[i]=(((__u64)RTjpeg_lqt[i]<<32)/RTjpeg_aan_tab[i]);
|
|
|
|
|
RTjpeg_cqt[i]=(((__u64)RTjpeg_cqt[i]<<32)/RTjpeg_aan_tab[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static void RTjpeg_dctY(__u8 *idata, __s16 *odata, int rskip)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if !HAVE_MMX
|
2001-12-27 21:27:29 +00:00
|
|
|
|
__s32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
|
|
|
|
__s32 tmp10, tmp11, tmp12, tmp13;
|
|
|
|
|
__s32 z1, z2, z3, z4, z5, z11, z13;
|
|
|
|
|
__u8 *idataptr;
|
|
|
|
|
__s16 *odataptr;
|
|
|
|
|
__s32 *wsptr;
|
|
|
|
|
int ctr;
|
|
|
|
|
|
|
|
|
|
idataptr = idata;
|
|
|
|
|
wsptr = RTjpeg_ws;
|
|
|
|
|
for (ctr = 7; ctr >= 0; ctr--) {
|
|
|
|
|
tmp0 = idataptr[0] + idataptr[7];
|
|
|
|
|
tmp7 = idataptr[0] - idataptr[7];
|
|
|
|
|
tmp1 = idataptr[1] + idataptr[6];
|
|
|
|
|
tmp6 = idataptr[1] - idataptr[6];
|
|
|
|
|
tmp2 = idataptr[2] + idataptr[5];
|
|
|
|
|
tmp5 = idataptr[2] - idataptr[5];
|
|
|
|
|
tmp3 = idataptr[3] + idataptr[4];
|
|
|
|
|
tmp4 = idataptr[3] - idataptr[4];
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
tmp10 = (tmp0 + tmp3); /* phase 2 */
|
|
|
|
|
tmp13 = tmp0 - tmp3;
|
|
|
|
|
tmp11 = (tmp1 + tmp2);
|
|
|
|
|
tmp12 = tmp1 - tmp2;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
wsptr[0] = (tmp10 + tmp11)<<8; /* phase 3 */
|
|
|
|
|
wsptr[4] = (tmp10 - tmp11)<<8;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
z1 = D_MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
|
|
|
|
|
wsptr[2] = (tmp13<<8) + z1; /* phase 5 */
|
|
|
|
|
wsptr[6] = (tmp13<<8) - z1;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
tmp10 = tmp4 + tmp5; /* phase 2 */
|
|
|
|
|
tmp11 = tmp5 + tmp6;
|
|
|
|
|
tmp12 = tmp6 + tmp7;
|
|
|
|
|
|
|
|
|
|
z5 = D_MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
|
|
|
|
|
z2 = D_MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
|
|
|
|
|
z4 = D_MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
|
|
|
|
|
z3 = D_MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
|
|
|
|
|
|
|
|
|
|
z11 = (tmp7<<8) + z3; /* phase 5 */
|
|
|
|
|
z13 = (tmp7<<8) - z3;
|
|
|
|
|
|
|
|
|
|
wsptr[5] = z13 + z2; /* phase 6 */
|
|
|
|
|
wsptr[3] = z13 - z2;
|
|
|
|
|
wsptr[1] = z11 + z4;
|
|
|
|
|
wsptr[7] = z11 - z4;
|
|
|
|
|
|
|
|
|
|
idataptr += rskip<<3; /* advance pointer to next row */
|
|
|
|
|
wsptr += 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wsptr = RTjpeg_ws;
|
|
|
|
|
odataptr=odata;
|
|
|
|
|
for (ctr = 7; ctr >= 0; ctr--) {
|
|
|
|
|
tmp0 = wsptr[0] + wsptr[56];
|
|
|
|
|
tmp7 = wsptr[0] - wsptr[56];
|
|
|
|
|
tmp1 = wsptr[8] + wsptr[48];
|
|
|
|
|
tmp6 = wsptr[8] - wsptr[48];
|
|
|
|
|
tmp2 = wsptr[16] + wsptr[40];
|
|
|
|
|
tmp5 = wsptr[16] - wsptr[40];
|
|
|
|
|
tmp3 = wsptr[24] + wsptr[32];
|
|
|
|
|
tmp4 = wsptr[24] - wsptr[32];
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
tmp10 = tmp0 + tmp3; /* phase 2 */
|
|
|
|
|
tmp13 = tmp0 - tmp3;
|
|
|
|
|
tmp11 = tmp1 + tmp2;
|
|
|
|
|
tmp12 = tmp1 - tmp2;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
odataptr[0] = DESCALE10(tmp10 + tmp11); /* phase 3 */
|
|
|
|
|
odataptr[32] = DESCALE10(tmp10 - tmp11);
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
z1 = D_MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
|
|
|
|
|
odataptr[16] = DESCALE20((tmp13<<8) + z1); /* phase 5 */
|
|
|
|
|
odataptr[48] = DESCALE20((tmp13<<8) - z1);
|
|
|
|
|
|
|
|
|
|
tmp10 = tmp4 + tmp5; /* phase 2 */
|
|
|
|
|
tmp11 = tmp5 + tmp6;
|
|
|
|
|
tmp12 = tmp6 + tmp7;
|
|
|
|
|
|
|
|
|
|
z5 = D_MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
|
|
|
|
|
z2 = D_MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
|
|
|
|
|
z4 = D_MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
|
|
|
|
|
z3 = D_MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
|
|
|
|
|
|
|
|
|
|
z11 = (tmp7<<8) + z3; /* phase 5 */
|
|
|
|
|
z13 = (tmp7<<8) - z3;
|
|
|
|
|
|
|
|
|
|
odataptr[40] = DESCALE20(z13 + z2); /* phase 6 */
|
|
|
|
|
odataptr[24] = DESCALE20(z13 - z2);
|
|
|
|
|
odataptr[8] = DESCALE20(z11 + z4);
|
|
|
|
|
odataptr[56] = DESCALE20(z11 - z4);
|
|
|
|
|
|
|
|
|
|
odataptr++; /* advance pointer to next column */
|
|
|
|
|
wsptr++;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
volatile mmx_t tmp6, tmp7;
|
|
|
|
|
register mmx_t *dataptr = (mmx_t *)odata;
|
|
|
|
|
mmx_t *idata2 = (mmx_t *)idata;
|
|
|
|
|
|
|
|
|
|
// first copy the input 8 bit to the destination 16 bits
|
|
|
|
|
|
|
|
|
|
movq_m2r(RTjpeg_zero, mm2);
|
|
|
|
|
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*idata2, mm0);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklbw_r2r(mm2, mm0);
|
|
|
|
|
movq_r2m(mm0, *(dataptr));
|
|
|
|
|
|
|
|
|
|
punpckhbw_r2r(mm2, mm1);
|
|
|
|
|
movq_r2m(mm1, *(dataptr+1));
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
idata2 += rskip;
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*idata2, mm0);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklbw_r2r(mm2, mm0);
|
|
|
|
|
movq_r2m(mm0, *(dataptr+2));
|
|
|
|
|
|
|
|
|
|
punpckhbw_r2r(mm2, mm1);
|
|
|
|
|
movq_r2m(mm1, *(dataptr+3));
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
idata2 += rskip;
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*idata2, mm0);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklbw_r2r(mm2, mm0);
|
|
|
|
|
movq_r2m(mm0, *(dataptr+4));
|
|
|
|
|
|
|
|
|
|
punpckhbw_r2r(mm2, mm1);
|
|
|
|
|
movq_r2m(mm1, *(dataptr+5));
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
idata2 += rskip;
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*idata2, mm0);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklbw_r2r(mm2, mm0);
|
|
|
|
|
movq_r2m(mm0, *(dataptr+6));
|
|
|
|
|
|
|
|
|
|
punpckhbw_r2r(mm2, mm1);
|
|
|
|
|
movq_r2m(mm1, *(dataptr+7));
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
idata2 += rskip;
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*idata2, mm0);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklbw_r2r(mm2, mm0);
|
|
|
|
|
movq_r2m(mm0, *(dataptr+8));
|
|
|
|
|
|
|
|
|
|
punpckhbw_r2r(mm2, mm1);
|
|
|
|
|
movq_r2m(mm1, *(dataptr+9));
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
idata2 += rskip;
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*idata2, mm0);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklbw_r2r(mm2, mm0);
|
|
|
|
|
movq_r2m(mm0, *(dataptr+10));
|
|
|
|
|
|
|
|
|
|
punpckhbw_r2r(mm2, mm1);
|
|
|
|
|
movq_r2m(mm1, *(dataptr+11));
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
idata2 += rskip;
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*idata2, mm0);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklbw_r2r(mm2, mm0);
|
|
|
|
|
movq_r2m(mm0, *(dataptr+12));
|
|
|
|
|
|
|
|
|
|
punpckhbw_r2r(mm2, mm1);
|
|
|
|
|
movq_r2m(mm1, *(dataptr+13));
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
idata2 += rskip;
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*idata2, mm0);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklbw_r2r(mm2, mm0);
|
|
|
|
|
movq_r2m(mm0, *(dataptr+14));
|
|
|
|
|
|
|
|
|
|
punpckhbw_r2r(mm2, mm1);
|
|
|
|
|
movq_r2m(mm1, *(dataptr+15));
|
|
|
|
|
|
|
|
|
|
/* Start Transpose to do calculations on rows */
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+9), mm7); // m03:m02|m01:m00 - first line (line 4)and copy into m5
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+13), mm6); // m23:m22|m21:m20 - third line (line 6)and copy into m2
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_r2r(mm7, mm5);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+11), mm7); // m11:m01|m10:m00 - interleave first and second lines
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_r2r(mm6, mm2);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+15), mm6); // m31:m21|m30:m20 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm7, mm1);
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*(dataptr+11), mm3); // m13:m13|m11:m10 - second line
|
2001-12-27 21:27:29 +00:00
|
|
|
|
punpckldq_r2r(mm6, mm7); // m30:m20|m10:m00 - interleave to produce result 1
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+15), mm0); // m13:m13|m11:m10 - fourth line
|
|
|
|
|
punpckhdq_r2r(mm6, mm1); // m31:m21|m11:m01 - interleave to produce result 2
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7,*(dataptr+9)); // write result 1
|
|
|
|
|
punpckhwd_r2r(mm3, mm5); // m13:m03|m12:m02 - interleave first and second lines
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
movq_r2m(mm1,*(dataptr+11)); // write result 2
|
|
|
|
|
punpckhwd_r2r(mm0, mm2); // m33:m23|m32:m22 - interleave third and fourth lines
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm5, mm1);
|
|
|
|
|
punpckldq_r2r(mm2, mm5); // m32:m22|m12:m02 - interleave to produce result 3
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+1), mm0); // m03:m02|m01:m00 - first line, 4x4
|
|
|
|
|
punpckhdq_r2r(mm2, mm1); // m33:m23|m13:m03 - interleave to produce result 4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm5,*(dataptr+13)); // write result 3
|
|
|
|
|
|
|
|
|
|
// last 4x4 done
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm1, *(dataptr+15)); // write result 4, last 4x4
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+5), mm2); // m23:m22|m21:m20 - third line
|
|
|
|
|
movq_r2r(mm0, mm6);
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+3), mm0); // m11:m01|m10:m00 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm2, mm7);
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+7), mm2); // m31:m21|m30:m20 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm0, mm4);
|
|
|
|
|
|
|
|
|
|
//
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(*(dataptr+8), mm1); // n03:n02|n01:n00 - first line
|
2001-12-27 21:27:29 +00:00
|
|
|
|
punpckldq_r2r(mm2, mm0); // m30:m20|m10:m00 - interleave to produce first result
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+12), mm3); // n23:n22|n21:n20 - third line
|
|
|
|
|
punpckhdq_r2r(mm2, mm4); // m31:m21|m11:m01 - interleave to produce second result
|
|
|
|
|
|
|
|
|
|
punpckhwd_m2r(*(dataptr+3), mm6); // m13:m03|m12:m02 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm1, mm2); // copy first line
|
|
|
|
|
|
|
|
|
|
punpckhwd_m2r(*(dataptr+7), mm7); // m33:m23|m32:m22 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm6, mm5); // copy first intermediate result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+8)); // write result 1
|
|
|
|
|
punpckhdq_r2r(mm7, mm5); // m33:m23|m13:m03 - produce third result
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+10), mm1); // n11:n01|n10:n00 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm3, mm0); // copy third line
|
|
|
|
|
|
|
|
|
|
punpckhwd_m2r(*(dataptr+10), mm2); // n13:n03|n12:n02 - interleave first and second lines
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm4, *(dataptr+10)); // write result 2 out
|
|
|
|
|
punpckldq_r2r(mm7, mm6); // m32:m22|m12:m02 - produce fourth result
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+14), mm3); // n31:n21|n30:n20 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm1, mm4);
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, *(dataptr+12)); // write result 3 out
|
|
|
|
|
punpckldq_r2r(mm3, mm1); // n30:n20|n10:n00 - produce first result
|
|
|
|
|
|
|
|
|
|
punpckhwd_m2r(*(dataptr+14), mm0); // n33:n23|n32:n22 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm2, mm6);
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm5, *(dataptr+14)); // write result 4 out
|
|
|
|
|
punpckhdq_r2r(mm3, mm4); // n31:n21|n11:n01- produce second result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm1, *(dataptr+1)); // write result 5 out - (first result for other 4 x 4 block)
|
|
|
|
|
punpckldq_r2r(mm0, mm2); // n32:n22|n12:n02- produce third result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm4, *(dataptr+3)); // write result 6 out
|
|
|
|
|
punpckhdq_r2r(mm0, mm6); // n33:n23|n13:n03 - produce fourth result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm2, *(dataptr+5)); // write result 7 out
|
|
|
|
|
|
|
|
|
|
movq_m2r(*dataptr, mm0); // m03:m02|m01:m00 - first line, first 4x4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, *(dataptr+7)); // write result 8 out
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Do first 4x4 quadrant, which is used in the beginning of the DCT:
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+4), mm7); // m23:m22|m21:m20 - third line
|
|
|
|
|
movq_r2r(mm0, mm2);
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+2), mm0); // m11:m01|m10:m00 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm7, mm4);
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+6), mm7); // m31:m21|m30:m20 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm0, mm1);
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+2), mm6); // m13:m12|m11:m10 - second line
|
|
|
|
|
punpckldq_r2r(mm7, mm0); // m30:m20|m10:m00 - interleave to produce result 1
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+6), mm5); // m33:m32|m31:m30 - fourth line
|
|
|
|
|
punpckhdq_r2r(mm7, mm1); // m31:m21|m11:m01 - interleave to produce result 2
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm0, mm7); // write result 1
|
|
|
|
|
punpckhwd_r2r(mm6, mm2); // m13:m03|m12:m02 - interleave first and second lines
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+14), mm7); // tmp07=x0-x7 /* Stage 1 */
|
|
|
|
|
movq_r2r(mm1, mm6); // write result 2
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+14), mm0); // tmp00=x0+x7 /* Stage 1 */
|
|
|
|
|
punpckhwd_r2r(mm5, mm4); // m33:m23|m32:m22 - interleave third and fourth lines
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+12), mm1); // tmp01=x1+x6 /* Stage 1 */
|
|
|
|
|
movq_r2r(mm2, mm3); // copy first intermediate result
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+12), mm6); // tmp06=x1-x6 /* Stage 1 */
|
|
|
|
|
punpckldq_r2r(mm4, mm2); // m32:m22|m12:m02 - interleave to produce result 3
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7, tmp7);
|
|
|
|
|
movq_r2r(mm2, mm5); // write result 3
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, tmp6);
|
|
|
|
|
punpckhdq_r2r(mm4, mm3); // m33:m23|m13:m03 - interleave to produce result 4
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+10), mm2); // tmp02=x2+5 /* Stage 1 */
|
|
|
|
|
movq_r2r(mm3, mm4); // write result 4
|
|
|
|
|
|
|
|
|
|
/************************************************************************************************
|
|
|
|
|
End of Transpose
|
|
|
|
|
************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+8), mm3); // tmp03=x3+x4 /* stage 1*/
|
|
|
|
|
movq_r2r(mm0, mm7);
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+8), mm4); // tmp04=x3-x4 /* stage 1*/
|
|
|
|
|
movq_r2r(mm1, mm6);
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm3, mm0); // tmp10 = tmp00 + tmp03 /* even 2 */
|
|
|
|
|
psubw_r2r(mm3, mm7); // tmp13 = tmp00 - tmp03 /* even 2 */
|
|
|
|
|
|
|
|
|
|
psubw_r2r(mm2, mm6); // tmp12 = tmp01 - tmp02 /* even 2 */
|
|
|
|
|
paddw_r2r(mm2, mm1); // tmp11 = tmp01 + tmp02 /* even 2 */
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+10), mm5); // tmp05=x2-x5 /* stage 1*/
|
|
|
|
|
paddw_r2r(mm7, mm6); // tmp12 + tmp13
|
|
|
|
|
|
|
|
|
|
/* stage 3 */
|
|
|
|
|
|
|
|
|
|
movq_m2r(tmp6, mm2);
|
|
|
|
|
movq_r2r(mm0, mm3);
|
|
|
|
|
|
|
|
|
|
psllw_i2r(2, mm6); // m8 * 2^2
|
2009-05-13 02:58:57 +00:00
|
|
|
|
paddw_r2r(mm1, mm0);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C4, mm6); // z1
|
2009-05-13 02:58:57 +00:00
|
|
|
|
psubw_r2r(mm1, mm3);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *dataptr);
|
|
|
|
|
movq_r2r(mm7, mm0);
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
/* Odd part */
|
|
|
|
|
movq_r2m(mm3, *(dataptr+8));
|
|
|
|
|
paddw_r2r(mm5, mm4); // tmp10
|
|
|
|
|
|
|
|
|
|
movq_m2r(tmp7, mm3);
|
|
|
|
|
paddw_r2r(mm6, mm0); // tmp32
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm2, mm5); // tmp11
|
|
|
|
|
psubw_r2r(mm6, mm7); // tmp33
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+4));
|
|
|
|
|
paddw_r2r(mm3, mm2); // tmp12
|
|
|
|
|
|
|
|
|
|
/* stage 4 */
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7, *(dataptr+12));
|
|
|
|
|
movq_r2r(mm4, mm1); // copy of tmp10
|
|
|
|
|
|
|
|
|
|
psubw_r2r(mm2, mm1); // tmp10 - tmp12
|
|
|
|
|
psllw_i2r(2, mm4); // m8 * 2^2
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
movq_m2r(RTjpeg_C2mC6, mm0);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
psllw_i2r(2, mm1);
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C6, mm1); // z5
|
|
|
|
|
psllw_i2r(2, mm2);
|
|
|
|
|
|
|
|
|
|
pmulhw_r2r(mm0, mm4); // z5
|
|
|
|
|
|
|
|
|
|
/* stage 5 */
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C2pC6, mm2);
|
|
|
|
|
psllw_i2r(2, mm5);
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C4, mm5); // z3
|
|
|
|
|
movq_r2r(mm3, mm0); // copy tmp7
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+1), mm7);
|
|
|
|
|
paddw_r2r(mm1, mm4); // z2
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm1, mm2); // z4
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm5, mm0); // z11
|
|
|
|
|
psubw_r2r(mm5, mm3); // z13
|
|
|
|
|
|
|
|
|
|
/* stage 6 */
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm3, mm5); // copy z13
|
|
|
|
|
psubw_r2r(mm4, mm3); // y3=z13 - z2
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm4, mm5); // y5=z13 + z2
|
|
|
|
|
movq_r2r(mm0, mm6); // copy z11
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm3, *(dataptr+6)); //save y3
|
|
|
|
|
psubw_r2r(mm2, mm0); // y7=z11 - z4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm5, *(dataptr+10)); //save y5
|
|
|
|
|
paddw_r2r(mm2, mm6); // y1=z11 + z4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+14)); //save y7
|
|
|
|
|
|
|
|
|
|
/************************************************
|
|
|
|
|
* End of 1st 4 rows
|
|
|
|
|
************************************************/
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+3), mm1); // load x1 /* stage 1 */
|
|
|
|
|
movq_r2r(mm7, mm0); // copy x0
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, *(dataptr+2)); //save y1
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+5), mm2); // load x2 /* stage 1 */
|
|
|
|
|
movq_r2r(mm1, mm6); // copy x1
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+15), mm0); // tmp00 = x0 + x7
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+7), mm3); // load x3 /* stage 1 */
|
|
|
|
|
movq_r2r(mm2, mm5); // copy x2
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+15), mm7); // tmp07 = x0 - x7
|
|
|
|
|
movq_r2r(mm3, mm4); // copy x3
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+13), mm1); // tmp01 = x1 + x6
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7, tmp7); // save tmp07
|
|
|
|
|
movq_r2r(mm0, mm7); // copy tmp00
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+13), mm6); // tmp06 = x1 - x6
|
|
|
|
|
|
|
|
|
|
/* stage 2, Even Part */
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+9), mm3); // tmp03 = x3 + x4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, tmp6); // save tmp07
|
|
|
|
|
movq_r2r(mm1, mm6); // copy tmp01
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+11), mm2); // tmp02 = x2 + x5
|
|
|
|
|
paddw_r2r(mm3, mm0); // tmp10 = tmp00 + tmp03
|
|
|
|
|
|
|
|
|
|
psubw_r2r(mm3, mm7); // tmp13 = tmp00 - tmp03
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+9), mm4); // tmp04 = x3 - x4
|
|
|
|
|
psubw_r2r(mm2, mm6); // tmp12 = tmp01 - tmp02
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm2, mm1); // tmp11 = tmp01 + tmp02
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+11), mm5); // tmp05 = x2 - x5
|
|
|
|
|
paddw_r2r(mm7, mm6); // tmp12 + tmp13
|
|
|
|
|
|
|
|
|
|
/* stage 3, Even and stage 4 & 5 even */
|
|
|
|
|
|
|
|
|
|
movq_m2r(tmp6, mm2); // load tmp6
|
|
|
|
|
movq_r2r(mm0, mm3); // copy tmp10
|
|
|
|
|
|
|
|
|
|
psllw_i2r(2, mm6); // shift z1
|
|
|
|
|
paddw_r2r(mm1, mm0); // y0=tmp10 + tmp11
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C4, mm6); // z1
|
|
|
|
|
psubw_r2r(mm1, mm3); // y4=tmp10 - tmp11
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+1)); //save y0
|
|
|
|
|
movq_r2r(mm7, mm0); // copy tmp13
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
/* odd part */
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm3, *(dataptr+9)); //save y4
|
|
|
|
|
paddw_r2r(mm5, mm4); // tmp10 = tmp4 + tmp5
|
|
|
|
|
|
|
|
|
|
movq_m2r(tmp7, mm3); // load tmp7
|
|
|
|
|
paddw_r2r(mm6, mm0); // tmp32 = tmp13 + z1
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm2, mm5); // tmp11 = tmp5 + tmp6
|
|
|
|
|
psubw_r2r(mm6, mm7); // tmp33 = tmp13 - z1
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+5)); //save y2
|
|
|
|
|
paddw_r2r(mm3, mm2); // tmp12 = tmp6 + tmp7
|
|
|
|
|
|
|
|
|
|
/* stage 4 */
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7, *(dataptr+13)); //save y6
|
|
|
|
|
movq_r2r(mm4, mm1); // copy tmp10
|
|
|
|
|
|
|
|
|
|
psubw_r2r(mm2, mm1); // tmp10 - tmp12
|
|
|
|
|
psllw_i2r(2, mm4); // shift tmp10
|
|
|
|
|
|
|
|
|
|
movq_m2r(RTjpeg_C2mC6, mm0); // load C2mC6
|
|
|
|
|
psllw_i2r(2, mm1); // shift (tmp10-tmp12)
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C6, mm1); // z5
|
2009-05-13 02:58:57 +00:00
|
|
|
|
psllw_i2r(2, mm5); // prepare for multiply
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
pmulhw_r2r(mm0, mm4); // multiply by converted real
|
|
|
|
|
|
|
|
|
|
/* stage 5 */
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C4, mm5); // z3
|
2009-05-13 02:58:57 +00:00
|
|
|
|
psllw_i2r(2, mm2); // prepare for multiply
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C2pC6, mm2); // multiply
|
|
|
|
|
movq_r2r(mm3, mm0); // copy tmp7
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+9), mm7); // m03:m02|m01:m00 - first line (line 4)and copy into mm7
|
|
|
|
|
paddw_r2r(mm1, mm4); // z2
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm5, mm0); // z11
|
|
|
|
|
psubw_r2r(mm5, mm3); // z13
|
|
|
|
|
|
|
|
|
|
/* stage 6 */
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm3, mm5); // copy z13
|
|
|
|
|
paddw_r2r(mm1, mm2); // z4
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm0, mm6); // copy z11
|
|
|
|
|
psubw_r2r(mm4, mm5); // y3
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm2, mm6); // y1
|
|
|
|
|
paddw_r2r(mm4, mm3); // y5
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm5, *(dataptr+7)); //save y3
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, *(dataptr+3)); //save y1
|
|
|
|
|
psubw_r2r(mm2, mm0); // y7
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
/************************************************************************************************
|
|
|
|
|
Start of Transpose
|
|
|
|
|
************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+13), mm6); // m23:m22|m21:m20 - third line (line 6)and copy into m2
|
|
|
|
|
movq_r2r(mm7, mm5); // copy first line
|
|
|
|
|
|
|
|
|
|
punpcklwd_r2r(mm3, mm7); // m11:m01|m10:m00 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm6, mm2); // copy third line
|
|
|
|
|
|
|
|
|
|
punpcklwd_r2r(mm0, mm6); // m31:m21|m30:m20 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm7, mm1); // copy first intermediate result
|
|
|
|
|
|
|
|
|
|
punpckldq_r2r(mm6, mm7); // m30:m20|m10:m00 - interleave to produce result 1
|
|
|
|
|
|
|
|
|
|
punpckhdq_r2r(mm6, mm1); // m31:m21|m11:m01 - interleave to produce result 2
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7, *(dataptr+9)); // write result 1
|
|
|
|
|
punpckhwd_r2r(mm3, mm5); // m13:m03|m12:m02 - interleave first and second lines
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm1, *(dataptr+11)); // write result 2
|
|
|
|
|
punpckhwd_r2r(mm0, mm2); // m33:m23|m32:m22 - interleave third and fourth lines
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm5, mm1); // copy first intermediate result
|
|
|
|
|
punpckldq_r2r(mm2, mm5); // m32:m22|m12:m02 - interleave to produce result 3
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+1), mm0); // m03:m02|m01:m00 - first line, 4x4
|
|
|
|
|
punpckhdq_r2r(mm2, mm1); // m33:m23|m13:m03 - interleave to produce result 4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm5, *(dataptr+13)); // write result 3
|
|
|
|
|
|
|
|
|
|
/****** last 4x4 done */
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm1, *(dataptr+15)); // write result 4, last 4x4
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+5), mm2); // m23:m22|m21:m20 - third line
|
|
|
|
|
movq_r2r(mm0, mm6); // copy first line
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+3), mm0); // m11:m01|m10:m00 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm2, mm7); // copy third line
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+7), mm2); // m31:m21|m30:m20 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm0, mm4); // copy first intermediate result
|
|
|
|
|
|
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+8), mm1); // n03:n02|n01:n00 - first line
|
2001-12-27 21:27:29 +00:00
|
|
|
|
punpckldq_r2r(mm2, mm0); // m30:m20|m10:m00 - interleave to produce first result
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+12), mm3); // n23:n22|n21:n20 - third line
|
|
|
|
|
punpckhdq_r2r(mm2, mm4); // m31:m21|m11:m01 - interleave to produce second result
|
|
|
|
|
|
|
|
|
|
punpckhwd_m2r(*(dataptr+3), mm6); // m13:m03|m12:m02 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm1, mm2); // copy first line
|
|
|
|
|
|
|
|
|
|
punpckhwd_m2r(*(dataptr+7), mm7); // m33:m23|m32:m22 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm6, mm5); // copy first intermediate result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+8)); // write result 1
|
|
|
|
|
punpckhdq_r2r(mm7, mm5); // m33:m23|m13:m03 - produce third result
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+10), mm1); // n11:n01|n10:n00 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm3, mm0); // copy third line
|
|
|
|
|
|
|
|
|
|
punpckhwd_m2r(*(dataptr+10), mm2); // n13:n03|n12:n02 - interleave first and second lines
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm4, *(dataptr+10)); // write result 2 out
|
|
|
|
|
punpckldq_r2r(mm7, mm6); // m32:m22|m12:m02 - produce fourth result
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+14), mm3); // n33:n23|n32:n22 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm1, mm4); // copy second intermediate result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, *(dataptr+12)); // write result 3 out
|
2009-05-13 02:58:57 +00:00
|
|
|
|
punpckldq_r2r(mm3, mm1); //
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
punpckhwd_m2r(*(dataptr+14), mm0); // n33:n23|n32:n22 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm2, mm6); // copy second intermediate result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm5, *(dataptr+14)); // write result 4 out
|
|
|
|
|
punpckhdq_r2r(mm3, mm4); // n31:n21|n11:n01- produce second result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm1, *(dataptr+1)); // write result 5 out - (first result for other 4 x 4 block)
|
|
|
|
|
punpckldq_r2r(mm0, mm2); // n32:n22|n12:n02- produce third result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm4, *(dataptr+3)); // write result 6 out
|
|
|
|
|
punpckhdq_r2r(mm0, mm6); // n33:n23|n13:n03 - produce fourth result
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm2, *(dataptr+5)); // write result 7 out
|
|
|
|
|
|
|
|
|
|
movq_m2r(*dataptr, mm0); // m03:m02|m01:m00 - first line, first 4x4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, *(dataptr+7)); // write result 8 out
|
|
|
|
|
|
|
|
|
|
// Do first 4x4 quadrant, which is used in the beginning of the DCT:
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+4), mm7); // m23:m22|m21:m20 - third line
|
|
|
|
|
movq_r2r(mm0, mm2); // copy first line
|
|
|
|
|
|
|
|
|
|
punpcklwd_m2r(*(dataptr+2), mm0); // m11:m01|m10:m00 - interleave first and second lines
|
|
|
|
|
movq_r2r(mm7, mm4); // copy third line
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
punpcklwd_m2r(*(dataptr+6), mm7); // m31:m21|m30:m20 - interleave third and fourth lines
|
|
|
|
|
movq_r2r(mm0, mm1); // copy first intermediate result
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+2), mm6); // m13:m12|m11:m10 - second line
|
|
|
|
|
punpckldq_r2r(mm7, mm0); // m30:m20|m10:m00 - interleave to produce result 1
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+6), mm5); // m33:m32|m31:m30 - fourth line
|
|
|
|
|
punpckhdq_r2r(mm7, mm1); // m31:m21|m11:m01 - interleave to produce result 2
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm0, mm7); // write result 1
|
|
|
|
|
punpckhwd_r2r(mm6, mm2); // m13:m03|m12:m02 - interleave first and second lines
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+14), mm7); // tmp07=x0-x7 /* Stage 1 */
|
|
|
|
|
movq_r2r(mm1, mm6); // write result 2
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+14), mm0); // tmp00=x0+x7 /* Stage 1 */
|
|
|
|
|
punpckhwd_r2r(mm5, mm4); // m33:m23|m32:m22 - interleave third and fourth lines
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+12), mm1); // tmp01=x1+x6 /* Stage 1 */
|
|
|
|
|
movq_r2r(mm2, mm3); // copy first intermediate result
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+12), mm6); // tmp06=x1-x6 /* Stage 1 */
|
|
|
|
|
punpckldq_r2r(mm4, mm2); // m32:m22|m12:m02 - interleave to produce result 3
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7, tmp7); // save tmp07
|
|
|
|
|
movq_r2r(mm2, mm5); // write result 3
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, tmp6); // save tmp06
|
|
|
|
|
|
|
|
|
|
punpckhdq_r2r(mm4, mm3); // m33:m23|m13:m03 - interleave to produce result 4
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+10), mm2); // tmp02=x2+x5 /* stage 1 */
|
|
|
|
|
movq_r2r(mm3, mm4); // write result 4
|
|
|
|
|
|
|
|
|
|
/************************************************************************************************
|
|
|
|
|
End of Transpose 2
|
|
|
|
|
************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+8), mm3); // tmp03=x3+x4 /* stage 1*/
|
|
|
|
|
movq_r2r(mm0, mm7);
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+8), mm4); // tmp04=x3-x4 /* stage 1*/
|
|
|
|
|
movq_r2r(mm1, mm6);
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm3, mm0); // tmp10 = tmp00 + tmp03 /* even 2 */
|
|
|
|
|
psubw_r2r(mm3, mm7); // tmp13 = tmp00 - tmp03 /* even 2 */
|
|
|
|
|
|
|
|
|
|
psubw_r2r(mm2, mm6); // tmp12 = tmp01 - tmp02 /* even 2 */
|
|
|
|
|
paddw_r2r(mm2, mm1); // tmp11 = tmp01 + tmp02 /* even 2 */
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+10), mm5); // tmp05=x2-x5 /* stage 1*/
|
|
|
|
|
paddw_r2r(mm7, mm6); // tmp12 + tmp13
|
|
|
|
|
|
|
|
|
|
/* stage 3 */
|
|
|
|
|
|
|
|
|
|
movq_m2r(tmp6, mm2);
|
|
|
|
|
movq_r2r(mm0, mm3);
|
|
|
|
|
|
|
|
|
|
psllw_i2r(2, mm6); // m8 * 2^2
|
2009-05-13 02:58:57 +00:00
|
|
|
|
paddw_r2r(mm1, mm0);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C4, mm6); // z1
|
2009-05-13 02:58:57 +00:00
|
|
|
|
psubw_r2r(mm1, mm3);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *dataptr);
|
|
|
|
|
movq_r2r(mm7, mm0);
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
/* Odd part */
|
|
|
|
|
movq_r2m(mm3, *(dataptr+8));
|
|
|
|
|
paddw_r2r(mm5, mm4); // tmp10
|
|
|
|
|
|
|
|
|
|
movq_m2r(tmp7, mm3);
|
|
|
|
|
paddw_r2r(mm6, mm0); // tmp32
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm2, mm5); // tmp11
|
|
|
|
|
psubw_r2r(mm6, mm7); // tmp33
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+4));
|
|
|
|
|
paddw_r2r(mm3, mm2); // tmp12
|
|
|
|
|
|
|
|
|
|
/* stage 4 */
|
|
|
|
|
movq_r2m(mm7, *(dataptr+12));
|
|
|
|
|
movq_r2r(mm4, mm1); // copy of tmp10
|
|
|
|
|
|
|
|
|
|
psubw_r2r(mm2, mm1); // tmp10 - tmp12
|
|
|
|
|
psllw_i2r(2, mm4); // m8 * 2^2
|
|
|
|
|
|
|
|
|
|
movq_m2r(RTjpeg_C2mC6, mm0);
|
|
|
|
|
psllw_i2r(2, mm1);
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C6, mm1); // z5
|
|
|
|
|
psllw_i2r(2, mm2);
|
|
|
|
|
|
|
|
|
|
pmulhw_r2r(mm0, mm4); // z5
|
|
|
|
|
|
|
|
|
|
/* stage 5 */
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C2pC6, mm2);
|
|
|
|
|
psllw_i2r(2, mm5);
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C4, mm5); // z3
|
|
|
|
|
movq_r2r(mm3, mm0); // copy tmp7
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+1), mm7);
|
|
|
|
|
paddw_r2r(mm1, mm4); // z2
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm1, mm2); // z4
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm5, mm0); // z11
|
|
|
|
|
psubw_r2r(mm5, mm3); // z13
|
|
|
|
|
|
|
|
|
|
/* stage 6 */
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm3, mm5); // copy z13
|
|
|
|
|
psubw_r2r(mm4, mm3); // y3=z13 - z2
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm4, mm5); // y5=z13 + z2
|
|
|
|
|
movq_r2r(mm0, mm6); // copy z11
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm3, *(dataptr+6)); //save y3
|
|
|
|
|
psubw_r2r(mm2, mm0); // y7=z11 - z4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm5, *(dataptr+10)); //save y5
|
|
|
|
|
paddw_r2r(mm2, mm6); // y1=z11 + z4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+14)); //save y7
|
|
|
|
|
|
|
|
|
|
/************************************************
|
|
|
|
|
* End of 1st 4 rows
|
|
|
|
|
************************************************/
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+3), mm1); // load x1 /* stage 1 */
|
|
|
|
|
movq_r2r(mm7, mm0); // copy x0
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, *(dataptr+2)); //save y1
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+5), mm2); // load x2 /* stage 1 */
|
|
|
|
|
movq_r2r(mm1, mm6); // copy x1
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+15), mm0); // tmp00 = x0 + x7
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+7), mm3); // load x3 /* stage 1 */
|
|
|
|
|
movq_r2r(mm2, mm5); // copy x2
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+15), mm7); // tmp07 = x0 - x7
|
|
|
|
|
movq_r2r(mm3, mm4); // copy x3
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+13), mm1); // tmp01 = x1 + x6
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7, tmp7); // save tmp07
|
|
|
|
|
movq_r2r(mm0, mm7); // copy tmp00
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+13), mm6); // tmp06 = x1 - x6
|
|
|
|
|
|
|
|
|
|
/* stage 2, Even Part */
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+9), mm3); // tmp03 = x3 + x4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, tmp6); // save tmp07
|
|
|
|
|
movq_r2r(mm1, mm6); // copy tmp01
|
|
|
|
|
|
|
|
|
|
paddw_m2r(*(dataptr+11), mm2); // tmp02 = x2 + x5
|
|
|
|
|
paddw_r2r(mm3, mm0); // tmp10 = tmp00 + tmp03
|
|
|
|
|
|
|
|
|
|
psubw_r2r(mm3, mm7); // tmp13 = tmp00 - tmp03
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+9), mm4); // tmp04 = x3 - x4
|
|
|
|
|
psubw_r2r(mm2, mm6); // tmp12 = tmp01 - tmp02
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm2, mm1); // tmp11 = tmp01 + tmp02
|
|
|
|
|
|
|
|
|
|
psubw_m2r(*(dataptr+11), mm5); // tmp05 = x2 - x5
|
|
|
|
|
paddw_r2r(mm7, mm6); // tmp12 + tmp13
|
|
|
|
|
|
|
|
|
|
/* stage 3, Even and stage 4 & 5 even */
|
|
|
|
|
|
|
|
|
|
movq_m2r(tmp6, mm2); // load tmp6
|
|
|
|
|
movq_r2r(mm0, mm3); // copy tmp10
|
|
|
|
|
|
|
|
|
|
psllw_i2r(2, mm6); // shift z1
|
|
|
|
|
paddw_r2r(mm1, mm0); // y0=tmp10 + tmp11
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C4, mm6); // z1
|
|
|
|
|
psubw_r2r(mm1, mm3); // y4=tmp10 - tmp11
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+1)); //save y0
|
|
|
|
|
movq_r2r(mm7, mm0); // copy tmp13
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
/* odd part */
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm3, *(dataptr+9)); //save y4
|
|
|
|
|
paddw_r2r(mm5, mm4); // tmp10 = tmp4 + tmp5
|
|
|
|
|
|
|
|
|
|
movq_m2r(tmp7, mm3); // load tmp7
|
|
|
|
|
paddw_r2r(mm6, mm0); // tmp32 = tmp13 + z1
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm2, mm5); // tmp11 = tmp5 + tmp6
|
|
|
|
|
psubw_r2r(mm6, mm7); // tmp33 = tmp13 - z1
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+5)); //save y2
|
|
|
|
|
paddw_r2r(mm3, mm2); // tmp12 = tmp6 + tmp7
|
|
|
|
|
|
|
|
|
|
/* stage 4 */
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm7, *(dataptr+13)); //save y6
|
|
|
|
|
movq_r2r(mm4, mm1); // copy tmp10
|
|
|
|
|
|
|
|
|
|
psubw_r2r(mm2, mm1); // tmp10 - tmp12
|
|
|
|
|
psllw_i2r(2, mm4); // shift tmp10
|
|
|
|
|
|
|
|
|
|
movq_m2r(RTjpeg_C2mC6, mm0); // load C2mC6
|
|
|
|
|
psllw_i2r(2, mm1); // shift (tmp10-tmp12)
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C6, mm1); // z5
|
2009-05-13 02:58:57 +00:00
|
|
|
|
psllw_i2r(2, mm5); // prepare for multiply
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
pmulhw_r2r(mm0, mm4); // multiply by converted real
|
|
|
|
|
|
|
|
|
|
/* stage 5 */
|
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C4, mm5); // z3
|
2009-05-13 02:58:57 +00:00
|
|
|
|
psllw_i2r(2, mm2); // prepare for multiply
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
pmulhw_m2r(RTjpeg_C2pC6, mm2); // multiply
|
|
|
|
|
movq_r2r(mm3, mm0); // copy tmp7
|
|
|
|
|
|
|
|
|
|
movq_m2r(*(dataptr+9), mm7); // m03:m02|m01:m00 - first line (line 4)and copy into mm7
|
|
|
|
|
paddw_r2r(mm1, mm4); // z2
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm5, mm0); // z11
|
|
|
|
|
psubw_r2r(mm5, mm3); // z13
|
|
|
|
|
|
|
|
|
|
/* stage 6 */
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm3, mm5); // copy z13
|
|
|
|
|
paddw_r2r(mm1, mm2); // z4
|
|
|
|
|
|
|
|
|
|
movq_r2r(mm0, mm6); // copy z11
|
|
|
|
|
psubw_r2r(mm4, mm5); // y3
|
|
|
|
|
|
|
|
|
|
paddw_r2r(mm2, mm6); // y1
|
|
|
|
|
paddw_r2r(mm4, mm3); // y5
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm5, *(dataptr+7)); //save y3
|
|
|
|
|
psubw_r2r(mm2, mm0); // y<>=z11 - z4
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm3, *(dataptr+11)); //save y5
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm6, *(dataptr+3)); //save y1
|
|
|
|
|
|
|
|
|
|
movq_r2m(mm0, *(dataptr+15)); //save y7
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
Main Routines
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
This file contains most of the initialisation and control functions
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
(C) Justin Schoeman 1998
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
*/
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
/*
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
Private function
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
Initialise all the cache-aliged data blocks
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
*/
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
static void RTjpeg_init_data(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned long dptr;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
dptr=(unsigned long)&(RTjpeg_alldata[0]);
|
|
|
|
|
dptr+=32;
|
|
|
|
|
dptr=dptr>>5;
|
|
|
|
|
dptr=dptr<<5; /* cache align data */
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_block=(__s16 *)dptr;
|
|
|
|
|
dptr+=sizeof(__s16)*64;
|
|
|
|
|
RTjpeg_lqt=(__s32 *)dptr;
|
|
|
|
|
dptr+=sizeof(__s32)*64;
|
|
|
|
|
RTjpeg_cqt=(__s32 *)dptr;
|
|
|
|
|
dptr+=sizeof(__s32)*64;
|
|
|
|
|
RTjpeg_liqt=(__u32 *)dptr;
|
|
|
|
|
dptr+=sizeof(__u32)*64;
|
|
|
|
|
RTjpeg_ciqt=(__u32 *)dptr;
|
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
/*
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
External Function
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
Re-set quality factor
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
Input: buf -> pointer to 128 ints for quant values store to pass back to
|
|
|
|
|
init_decompress.
|
|
|
|
|
Q -> quality factor (192=best, 32=worst)
|
|
|
|
|
*/
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
static void RTjpeg_init_Q(__u8 Q)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
__u64 qual;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
qual=(__u64)Q<<(32-7); /* 32 bit FP, 255=2, 0=0 */
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
for(i=0; i<64; i++)
|
|
|
|
|
{
|
|
|
|
|
RTjpeg_lqt[i]=(__s32)((qual/((__u64)RTjpeg_lum_quant_tbl[i]<<16))>>3);
|
|
|
|
|
if(RTjpeg_lqt[i]==0)RTjpeg_lqt[i]=1;
|
|
|
|
|
RTjpeg_cqt[i]=(__s32)((qual/((__u64)RTjpeg_chrom_quant_tbl[i]<<16))>>3);
|
|
|
|
|
if(RTjpeg_cqt[i]==0)RTjpeg_cqt[i]=1;
|
|
|
|
|
RTjpeg_liqt[i]=(1<<16)/(RTjpeg_lqt[i]<<3);
|
|
|
|
|
RTjpeg_ciqt[i]=(1<<16)/(RTjpeg_cqt[i]<<3);
|
|
|
|
|
RTjpeg_lqt[i]=((1<<16)/RTjpeg_liqt[i])>>3;
|
|
|
|
|
RTjpeg_cqt[i]=((1<<16)/RTjpeg_ciqt[i])>>3;
|
|
|
|
|
}
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_lb8=0;
|
|
|
|
|
while(RTjpeg_liqt[RTjpeg_ZZ[++RTjpeg_lb8]]<=8);
|
|
|
|
|
RTjpeg_lb8--;
|
|
|
|
|
RTjpeg_cb8=0;
|
|
|
|
|
while(RTjpeg_ciqt[RTjpeg_ZZ[++RTjpeg_cb8]]<=8);
|
|
|
|
|
RTjpeg_cb8--;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_dct_init();
|
|
|
|
|
RTjpeg_quant_init();
|
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
/*
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
External Function
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
Initialise compression.
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-05-13 02:58:57 +00:00
|
|
|
|
Input: buf -> pointer to 128 ints for quant values store to pass back to
|
2009-03-08 13:32:42 +00:00
|
|
|
|
init_decompress.
|
|
|
|
|
width -> width of image
|
|
|
|
|
height -> height of image
|
|
|
|
|
Q -> quality factor (192=best, 32=worst)
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
*/
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
void RTjpeg_init_compress(__u32 *buf, int width, int height, __u8 Q)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
__u64 qual;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_init_data();
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_width=width;
|
|
|
|
|
RTjpeg_height=height;
|
|
|
|
|
RTjpeg_Ywidth = RTjpeg_width>>3;
|
|
|
|
|
RTjpeg_Ysize=width * height;
|
|
|
|
|
RTjpeg_Cwidth = RTjpeg_width>>4;
|
|
|
|
|
RTjpeg_Csize= (width>>1) * height;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
qual=(__u64)Q<<(32-7); /* 32 bit FP, 255=2, 0=0 */
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
for(i=0; i<64; i++)
|
|
|
|
|
{
|
|
|
|
|
RTjpeg_lqt[i]=(__s32)((qual/((__u64)RTjpeg_lum_quant_tbl[i]<<16))>>3);
|
|
|
|
|
if(RTjpeg_lqt[i]==0)RTjpeg_lqt[i]=1;
|
|
|
|
|
RTjpeg_cqt[i]=(__s32)((qual/((__u64)RTjpeg_chrom_quant_tbl[i]<<16))>>3);
|
|
|
|
|
if(RTjpeg_cqt[i]==0)RTjpeg_cqt[i]=1;
|
|
|
|
|
RTjpeg_liqt[i]=(1<<16)/(RTjpeg_lqt[i]<<3);
|
|
|
|
|
RTjpeg_ciqt[i]=(1<<16)/(RTjpeg_cqt[i]<<3);
|
|
|
|
|
RTjpeg_lqt[i]=((1<<16)/RTjpeg_liqt[i])>>3;
|
|
|
|
|
RTjpeg_cqt[i]=((1<<16)/RTjpeg_ciqt[i])>>3;
|
|
|
|
|
}
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_lb8=0;
|
|
|
|
|
while(RTjpeg_liqt[RTjpeg_ZZ[++RTjpeg_lb8]]<=8);
|
|
|
|
|
RTjpeg_lb8--;
|
|
|
|
|
RTjpeg_cb8=0;
|
|
|
|
|
while(RTjpeg_ciqt[RTjpeg_ZZ[++RTjpeg_cb8]]<=8);
|
|
|
|
|
RTjpeg_cb8--;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_dct_init();
|
|
|
|
|
RTjpeg_quant_init();
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
for(i=0; i<64; i++)
|
|
|
|
|
buf[i]=le2me_32(RTjpeg_liqt[i]);
|
|
|
|
|
for(i=0; i<64; i++)
|
|
|
|
|
buf[64+i]=le2me_32(RTjpeg_ciqt[i]);
|
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
int RTjpeg_compressYUV420(__s8 *sp, unsigned char *bp)
|
|
|
|
|
{
|
|
|
|
|
__s8 * sb;
|
|
|
|
|
register __s8 * bp1 = bp + (RTjpeg_width<<3);
|
|
|
|
|
register __s8 * bp2 = bp + RTjpeg_Ysize;
|
|
|
|
|
register __s8 * bp3 = bp2 + (RTjpeg_Csize>>1);
|
|
|
|
|
register int i, j, k;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
#if HAVE_MMX
|
|
|
|
|
emms();
|
|
|
|
|
#endif
|
|
|
|
|
sb=sp;
|
|
|
|
|
/* Y */
|
|
|
|
|
for(i=RTjpeg_height>>1; i; i-=8)
|
|
|
|
|
{
|
|
|
|
|
for(j=0, k=0; j<RTjpeg_width; j+=16, k+=8)
|
|
|
|
|
{
|
|
|
|
|
RTjpeg_dctY(bp+j, RTjpeg_block, RTjpeg_Ywidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_lqt);
|
|
|
|
|
sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_lb8);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_dctY(bp+j+8, RTjpeg_block, RTjpeg_Ywidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_lqt);
|
|
|
|
|
sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_lb8);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_dctY(bp1+j, RTjpeg_block, RTjpeg_Ywidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_lqt);
|
|
|
|
|
sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_lb8);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_dctY(bp1+j+8, RTjpeg_block, RTjpeg_Ywidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_lqt);
|
|
|
|
|
sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_lb8);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_dctY(bp2+k, RTjpeg_block, RTjpeg_Cwidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_cqt);
|
|
|
|
|
sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_cb8);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:32:42 +00:00
|
|
|
|
RTjpeg_dctY(bp3+k, RTjpeg_block, RTjpeg_Cwidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_cqt);
|
|
|
|
|
sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_cb8);
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
bp+=RTjpeg_width<<4;
|
|
|
|
|
bp1+=RTjpeg_width<<4;
|
|
|
|
|
bp2+=RTjpeg_width<<2;
|
|
|
|
|
bp3+=RTjpeg_width<<2;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
}
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if HAVE_MMX
|
2001-12-27 21:27:29 +00:00
|
|
|
|
emms();
|
|
|
|
|
#endif
|
|
|
|
|
return (sp-sb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
External Function
|
|
|
|
|
|
|
|
|
|
Initialise additional data structures for motion compensation
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void RTjpeg_init_mcompress(void)
|
|
|
|
|
{
|
|
|
|
|
unsigned long tmp;
|
|
|
|
|
|
|
|
|
|
if(!RTjpeg_old)
|
|
|
|
|
{
|
|
|
|
|
RTjpeg_old=malloc((4*RTjpeg_width*RTjpeg_height)+32);
|
|
|
|
|
tmp=(unsigned long)RTjpeg_old;
|
|
|
|
|
tmp+=32;
|
|
|
|
|
tmp=tmp>>5;
|
|
|
|
|
RTjpeg_old=(__s16 *)(tmp<<5);
|
|
|
|
|
}
|
|
|
|
|
if (!RTjpeg_old)
|
|
|
|
|
{
|
|
|
|
|
fprintf(stderr, "RTjpeg: Could not allocate memory\n");
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
2005-02-04 18:31:04 +00:00
|
|
|
|
memset(RTjpeg_old, 0, ((4*RTjpeg_width*RTjpeg_height)));
|
2001-12-27 21:27:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if HAVE_MMX
|
2001-12-27 21:27:29 +00:00
|
|
|
|
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static int RTjpeg_bcomp(__s16 *old, mmx_t *mask)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
mmx_t *mold=(mmx_t *)old;
|
|
|
|
|
mmx_t *mblock=(mmx_t *)RTjpeg_block;
|
|
|
|
|
volatile mmx_t result;
|
2004-08-02 03:35:50 +00:00
|
|
|
|
static mmx_t neg={0xffffffffffffffffULL};
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
movq_m2r(*mask, mm7);
|
|
|
|
|
movq_m2r(neg, mm6);
|
|
|
|
|
pxor_r2r(mm5, mm5);
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
for(i=0; i<8; i++)
|
|
|
|
|
{
|
|
|
|
|
movq_m2r(*(mblock++), mm0);
|
|
|
|
|
movq_m2r(*(mblock++), mm2);
|
|
|
|
|
movq_m2r(*(mold++), mm1);
|
|
|
|
|
movq_m2r(*(mold++), mm3);
|
|
|
|
|
psubsw_r2r(mm1, mm0);
|
|
|
|
|
psubsw_r2r(mm3, mm2);
|
|
|
|
|
movq_r2r(mm0, mm1);
|
|
|
|
|
movq_r2r(mm2, mm3);
|
|
|
|
|
pcmpgtw_r2r(mm7, mm0);
|
|
|
|
|
pcmpgtw_r2r(mm7, mm2);
|
|
|
|
|
pxor_r2r(mm6, mm1);
|
|
|
|
|
pxor_r2r(mm6, mm3);
|
|
|
|
|
pcmpgtw_r2r(mm7, mm1);
|
|
|
|
|
pcmpgtw_r2r(mm7, mm3);
|
|
|
|
|
por_r2r(mm0, mm5);
|
|
|
|
|
por_r2r(mm2, mm5);
|
|
|
|
|
por_r2r(mm1, mm5);
|
|
|
|
|
por_r2r(mm3, mm5);
|
|
|
|
|
}
|
|
|
|
|
movq_r2m(mm5, result);
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
if(result.q)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
2009-03-08 13:08:22 +00:00
|
|
|
|
static int RTjpeg_bcomp(__s16 *old, __u16 *mask)
|
2001-12-27 21:27:29 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for(i=0; i<64; i++)
|
|
|
|
|
if(abs(old[i]-RTjpeg_block[i])>*mask)
|
|
|
|
|
{
|
|
|
|
|
for(i=0; i<16; i++)((__u64 *)old)[i]=((__u64 *)RTjpeg_block)[i];
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
int RTjpeg_mcompressYUV420(__s8 *sp, unsigned char *bp, __u16 lmask, __u16 cmask)
|
|
|
|
|
{
|
|
|
|
|
__s8 * sb;
|
|
|
|
|
register __s8 * bp1 = bp + (RTjpeg_width<<3);
|
|
|
|
|
register __s8 * bp2 = bp + RTjpeg_Ysize;
|
|
|
|
|
register __s8 * bp3 = bp2 + (RTjpeg_Csize>>1);
|
|
|
|
|
register int i, j, k;
|
|
|
|
|
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if HAVE_MMX
|
2001-12-27 21:27:29 +00:00
|
|
|
|
emms();
|
2005-10-04 12:15:12 +00:00
|
|
|
|
RTjpeg_lmask.uq=((__u64)lmask<<48)|((__u64)lmask<<32)|((__u64)lmask<<16)|lmask;
|
|
|
|
|
RTjpeg_cmask.uq=((__u64)cmask<<48)|((__u64)cmask<<32)|((__u64)cmask<<16)|cmask;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
#else
|
2005-10-04 19:44:42 +00:00
|
|
|
|
RTjpeg_lmask=lmask;
|
|
|
|
|
RTjpeg_cmask=cmask;
|
2001-12-27 21:27:29 +00:00
|
|
|
|
#endif
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
sb=sp;
|
|
|
|
|
block=RTjpeg_old;
|
|
|
|
|
/* Y */
|
|
|
|
|
for(i=RTjpeg_height>>1; i; i-=8)
|
|
|
|
|
{
|
|
|
|
|
for(j=0, k=0; j<RTjpeg_width; j+=16, k+=8)
|
|
|
|
|
{
|
|
|
|
|
RTjpeg_dctY(bp+j, RTjpeg_block, RTjpeg_Ywidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_lqt);
|
|
|
|
|
if(RTjpeg_bcomp(block, &RTjpeg_lmask))
|
|
|
|
|
{
|
|
|
|
|
*((__u8 *)sp++)=255;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
else sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_lb8);
|
|
|
|
|
block+=64;
|
|
|
|
|
|
|
|
|
|
RTjpeg_dctY(bp+j+8, RTjpeg_block, RTjpeg_Ywidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_lqt);
|
|
|
|
|
if(RTjpeg_bcomp(block, &RTjpeg_lmask))
|
|
|
|
|
{
|
|
|
|
|
*((__u8 *)sp++)=255;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
else sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_lb8);
|
|
|
|
|
block+=64;
|
|
|
|
|
|
|
|
|
|
RTjpeg_dctY(bp1+j, RTjpeg_block, RTjpeg_Ywidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_lqt);
|
|
|
|
|
if(RTjpeg_bcomp(block, &RTjpeg_lmask))
|
|
|
|
|
{
|
|
|
|
|
*((__u8 *)sp++)=255;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
else sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_lb8);
|
|
|
|
|
block+=64;
|
|
|
|
|
|
|
|
|
|
RTjpeg_dctY(bp1+j+8, RTjpeg_block, RTjpeg_Ywidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_lqt);
|
|
|
|
|
if(RTjpeg_bcomp(block, &RTjpeg_lmask))
|
|
|
|
|
{
|
|
|
|
|
*((__u8 *)sp++)=255;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
else sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_lb8);
|
|
|
|
|
block+=64;
|
|
|
|
|
|
|
|
|
|
RTjpeg_dctY(bp2+k, RTjpeg_block, RTjpeg_Cwidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_cqt);
|
|
|
|
|
if(RTjpeg_bcomp(block, &RTjpeg_cmask))
|
|
|
|
|
{
|
|
|
|
|
*((__u8 *)sp++)=255;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
else sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_cb8);
|
|
|
|
|
block+=64;
|
|
|
|
|
|
|
|
|
|
RTjpeg_dctY(bp3+k, RTjpeg_block, RTjpeg_Cwidth);
|
|
|
|
|
RTjpeg_quant(RTjpeg_block, RTjpeg_cqt);
|
|
|
|
|
if(RTjpeg_bcomp(block, &RTjpeg_cmask))
|
|
|
|
|
{
|
|
|
|
|
*((__u8 *)sp++)=255;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
}
|
2001-12-27 21:27:29 +00:00
|
|
|
|
else sp+=RTjpeg_b2s(RTjpeg_block, sp, RTjpeg_cb8);
|
|
|
|
|
block+=64;
|
|
|
|
|
}
|
|
|
|
|
bp+=RTjpeg_width<<4;
|
|
|
|
|
bp1+=RTjpeg_width<<4;
|
|
|
|
|
bp2+=RTjpeg_width<<2;
|
|
|
|
|
bp3+=RTjpeg_width<<2;
|
2009-05-13 02:58:57 +00:00
|
|
|
|
|
2001-12-27 21:27:29 +00:00
|
|
|
|
}
|
2009-01-16 12:37:56 +00:00
|
|
|
|
#if HAVE_MMX
|
2001-12-27 21:27:29 +00:00
|
|
|
|
emms();
|
|
|
|
|
#endif
|
|
|
|
|
return (sp-sb);
|
|
|
|
|
}
|