📄 rtjpeg.c
字号:
/******************************************************************************* RTjpeg.c libquicktime - A library for reading and writing quicktime/avi/mp4 files. http://libquicktime.sourceforge.net Copyright (C) 2002 Heroine Virtual Ltd. Copyright (C) 2002-2007 Members of the libquicktime project. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA*******************************************************************************/ #include "lqt_private.h"#include <stdlib.h>#include <strings.h>#define __RTJPEG_INTERNAL__#include "RTjpeg.h"#ifdef MMX#include "mmx.h"#endif#define LOG_DOMAIN "rtjpeg"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 uint64_t RTjpeg_aan_tab[64]={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, };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 }; static int RTjpeg_b2s(int16_t *data, int8_t *strm, uint8_t bt8){ register int ci, co=1, tmp; register int16_t ZZvalue; *((uint8_t*)strm)=(uint8_t)(data[RTjpeg_ZZ[0]]>254) ? 254:((data[RTjpeg_ZZ[0]]<0)?0:data[RTjpeg_ZZ[0]]); for(ci=1; ci<=bt8; ci++) { ZZvalue = data[RTjpeg_ZZ[ci]]; if(ZZvalue>0) { strm[co++]=(int8_t)(ZZvalue>127)?127:ZZvalue; } else { strm[co++]=(int8_t)(ZZvalue<-128)?-128:ZZvalue; } } for(; ci<64; ci++) { ZZvalue = data[RTjpeg_ZZ[ci]]; if(ZZvalue>0) { strm[co++]=(int8_t)(ZZvalue>63)?63:ZZvalue; } else if(ZZvalue<0) { strm[co++]=(int8_t)(ZZvalue<-64)?-64:ZZvalue; } else /* compress zeros */ { tmp=ci; do { ci++; } while((ci<64)&&(data[RTjpeg_ZZ[ci]]==0)); strm[co++]=(int8_t)(63+(ci-tmp)); ci--; } } return (int)co;}static int RTjpeg_s2b(int16_t *data, int8_t *strm, uint8_t bt8, uint32_t *qtbl){ int ci=1, co=1, tmp; register int i; i=RTjpeg_ZZ[0]; data[i]=((uint8_t)strm[0])*qtbl[i]; for(co=1; co<=bt8; co++) { i=RTjpeg_ZZ[co]; data[i]=strm[ci++]*qtbl[i]; } 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;}#if defined(MMX)void RTjpeg_quant_init(RTjpeg_t *rtj){ int i; int16_t *qtbl; qtbl=(int16_t *)rtj->lqt; for(i=0; i<64; i++)qtbl[i]=(int16_t)rtj->lqt[i]; qtbl=(int16_t *)rtj->cqt; for(i=0; i<64; i++)qtbl[i]=(int16_t)rtj->cqt[i];}static mmx_t RTjpeg_ones=(mmx_t)(uint64_t)0x0001000100010001LL;static mmx_t RTjpeg_half=(mmx_t)(uint64_t)0x7fff7fff7fff7fffLL;void RTjpeg_quant(int16_t *block, int32_t *qtbl){ int i; mmx_t *bl, *ql; ql=(mmx_t *)qtbl; bl=(mmx_t *)block; movq_m2r(RTjpeg_ones, mm6); movq_m2r(RTjpeg_half, mm7); for(i=16; i; i--) { movq_m2r(*(ql++), mm0); /* quant vals (4) */ movq_m2r(*bl, mm2); /* block vals (4) */ movq_r2r(mm0, mm1); movq_r2r(mm2, mm3); punpcklwd_r2r(mm6, mm0); /* 1 qb 1 qa */ punpckhwd_r2r(mm6, mm1); /* 1 qd 1 qc */ punpcklwd_r2r(mm7, mm2); /* 32767 bb 32767 ba */ punpckhwd_r2r(mm7, mm3); /* 32767 bd 32767 bc */ pmaddwd_r2r(mm2, mm0); /* 32767+bb*qb 32767+ba*qa */ pmaddwd_r2r(mm3, mm1); /* 32767+bd*qd 32767+bc*qc */ psrad_i2r(16, mm0); psrad_i2r(16, mm1); packssdw_r2r(mm1, mm0); movq_r2m(mm0, *(bl++)); }}#elsestatic void RTjpeg_quant_init(RTjpeg_t *rtj){}static void RTjpeg_quant(int16_t *block, int32_t *qtbl){ int i; for(i=0; i<64; i++) block[i]=(int16_t)((block[i]*qtbl[i]+32767)>>16);}#endif/* * Perform the forward DCT on one block of samples. */#ifdef MMXstatic mmx_t RTjpeg_C4 =(mmx_t)(uint64_t)0x2D412D412D412D41LL;static mmx_t RTjpeg_C6 =(mmx_t)(uint64_t)0x187E187E187E187ELL;static mmx_t RTjpeg_C2mC6=(mmx_t)(uint64_t)0x22A322A322A322A3LL;static mmx_t RTjpeg_C2pC6=(mmx_t)(uint64_t)0x539F539F539F539FLL;static mmx_t RTjpeg_zero =(mmx_t)(uint64_t)0x0000000000000000LL;#else#define FIX_0_382683433 ((int32_t) 98) /* FIX(0.382683433) */#define FIX_0_541196100 ((int32_t) 139) /* FIX(0.541196100) */#define FIX_0_707106781 ((int32_t) 181) /* FIX(0.707106781) */#define FIX_1_306562965 ((int32_t) 334) /* FIX(1.306562965) */#define DESCALE10(x) (int16_t)( ((x)+128) >> 8)#define DESCALE20(x) (int16_t)(((x)+32768) >> 16)#define D_MULTIPLY(var,const) ((int32_t) ((var) * (const)))#endifstatic void RTjpeg_dct_init(RTjpeg_t *rtj){ int i; for(i=0; i<64; i++) { rtj->lqt[i]=(((uint64_t)rtj->lqt[i]<<32)/RTjpeg_aan_tab[i]); rtj->cqt[i]=(((uint64_t)rtj->cqt[i]<<32)/RTjpeg_aan_tab[i]); }}static void RTjpeg_dctY(RTjpeg_t *rtj, uint8_t *idata, int rskip){#ifndef MMX int32_t tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; int32_t tmp10, tmp11, tmp12, tmp13; int32_t z1, z2, z3, z4, z5, z11, z13; uint8_t *idataptr; int16_t *odataptr; int32_t *wsptr; int ctr; idataptr = idata; wsptr = rtj->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]; tmp10 = (tmp0 + tmp3); /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = (tmp1 + tmp2); tmp12 = tmp1 - tmp2; wsptr[0] = (tmp10 + tmp11)<<8; /* phase 3 */ wsptr[4] = (tmp10 - tmp11)<<8; z1 = D_MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ wsptr[2] = (tmp13<<8) + z1; /* phase 5 */ wsptr[6] = (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; 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 = rtj->ws; odataptr=rtj->block; 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]; tmp10 = tmp0 + tmp3; /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; odataptr[0] = DESCALE10(tmp10 + tmp11); /* phase 3 */ odataptr[32] = DESCALE10(tmp10 - tmp11); 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; mmx_t *dataptr = (mmx_t *)rtj->block; // int64_t *dataptr = (int64_t *)rtj->block; mmx_t *idata2 = (mmx_t *)idata; // first copy the input 8 bit to the destination 16 bits movq_m2r(RTjpeg_zero, mm2); movq_m2r(*idata2, mm0); movq_r2r(mm0, mm1); punpcklbw_r2r(mm2, mm0); movq_r2m(mm0, *(dataptr)); punpckhbw_r2r(mm2, mm1); movq_r2m(mm1, *(dataptr+1)); idata2 += rskip;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -