📄 ov511_decomp.c
字号:
/* OV511 Decompression Support Module
*
* Copyright (c) 1999-2002 Mark W. McClelland. All rights reserved.
* Original decompression code Copyright 1998-2000 OmniVision Technologies
*
* Please see the file: linux/Documentation/usb/ov511.txt
* and the web site at: http://alpha.dyndns.org/ov511/
* for more info.
*
* 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; version 2 of the License.
*
* 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.
*
*/
#include <linux/config.h>
#if defined(OUTSIDE_KERNEL)
#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
#define MODVERSIONS
#endif
#include <linux/version.h>
#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif
#else
#include <linux/version.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include "ov511.h"
/******************************************************************************
* Version Information
******************************************************************************/
#define DRIVER_VERSION "v1.6"
#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org>, OmniVision \
Technologies <http://www.ovt.com/>"
#define DRIVER_DESC "OV511 Decompression Module"
/******************************************************************************
* Prototypes
******************************************************************************/
extern int ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops,
int ov518, int mmx);
extern void ov511_deregister_decomp_module(int ov518, int mmx);
/******************************************************************************
* Decompression Module Interface Constants
******************************************************************************/
static const int interface_ver = DECOMP_INTERFACE_VER;
static const int ov518 = 0;
static const int mmx = 0;
/******************************************************************************
* Module Features
******************************************************************************/
static int debug;
MODULE_PARM(debug, "i");
MODULE_PARM_DESC(debug,
"Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
#if defined(MODULE_LICENSE) /* Introduced in ~2.4.10 */
MODULE_LICENSE("GPL");
#endif
/******************************************************************************
* Decompression Functions
******************************************************************************/
static void
DecompressYHI(unsigned char *pIn,
unsigned char *pOut,
int *iIn, /* in/out */
int *iOut, /* in/out */
const int w,
const int YUVFlag)
{
short ZigZag[64];
int temp[64];
int Zcnt_Flag = 0;
int Num8_Flag = 0;
int in_pos = *iIn;
int out_pos = *iOut;
int tmp, tmp1, tmp2, tmp3;
unsigned char header, ZTable[64];
short tmpl, tmph, half_byte, idx, count;
unsigned long ZigZag_length = 0, ZT_length, i, j;
short DeZigZag[64];
const short a = 11584;
const short b = 16068;
const short c = 15136;
const short d = 13624;
const short e = 9104;
const short f = 6270;
const short g = 3196;
int out_idx;
/* Take off every 'Zig' */
for (i = 0; i < 64; i++) {
ZigZag[i] = 0;
}
/*****************************
* Read in the Y header byte *
*****************************/
header = pIn[in_pos];
in_pos++;
ZigZag_length = header & 0x3f;
ZigZag_length = ZigZag_length + 1;
Num8_Flag = header & 0x40;
Zcnt_Flag = header & 0x80;
/*************************
* Read in the Y content *
*************************/
if (Zcnt_Flag == 0) { /* Without Zero Table read contents directly */
/* Read in ZigZag[0] */
ZigZag[0] = pIn[in_pos++];
tmpl = pIn[in_pos++];
tmph = tmpl<<8;
ZigZag[0] = ZigZag[0] | tmph;
ZigZag[0] = ZigZag[0]<<4;
ZigZag[0] = ZigZag[0]>>4;
if (Num8_Flag) { /* 8 Bits */
for (i = 1; i < ZigZag_length; i++) {
ZigZag[i] = pIn[in_pos++];
ZigZag[i] = ZigZag[i]<<8;
ZigZag[i] = ZigZag[i]>>8;
}
} else { /* 12 bits and has no Zero Table */
idx = 1;
half_byte = 0;
for (i = 1; i < ZigZag_length; i++) {
if (half_byte == 0) {
ZigZag[i] = pIn[in_pos++];
tmpl = pIn[in_pos++];
tmph = tmpl<<8;
tmph = tmph&0x0f00;
ZigZag[i] = ZigZag[i] | tmph;
ZigZag[i] = ZigZag[i]<<4;
ZigZag[i] = ZigZag[i]>>4;
half_byte = 1;
} else {
ZigZag[i] = pIn[in_pos++];
ZigZag[i] = ZigZag[i]<<8;
tmpl = tmpl & 0x00f0;
ZigZag[i] = ZigZag[i] | tmpl;
ZigZag[i] = ZigZag[i]>>4;
half_byte = 0;
}
}
}
} else { /* Has Zero Table */
/* Calculate Z-Table length */
ZT_length = ZigZag_length/8;
tmp = ZigZag_length%8;
if (tmp > 0) {
ZT_length = ZT_length + 1;
}
/* Read in Zero Table */
for (j = 0; j < ZT_length; j++) {
ZTable[j] = pIn[in_pos++];
}
/* Read in ZigZag[0] */
ZigZag[0] = pIn[in_pos++];
tmpl = pIn[in_pos++];
tmph = tmpl<<8;
ZigZag[0] = ZigZag[0] | tmph;
ZigZag[0] = ZigZag[0]<<4;
ZigZag[0] = ZigZag[0]>>4;
/* Decode ZigZag */
idx = 0;
ZTable[idx] = ZTable[idx]<<1;
count = 7;
if (Num8_Flag) { /* 8 Bits and has zero table */
for (i = 1; i < ZigZag_length; i++) {
if ((ZTable[idx]&0x80)) {
ZigZag[i] = pIn[in_pos++];
ZigZag[i] = ZigZag[i]<<8;
ZigZag[i] = ZigZag[i]>>8;
}
ZTable[idx]=ZTable[idx]<<1;
count--;
if (count == 0) {
count = 8;
idx++;
}
}
} else { /* 12 bits and has Zero Table */
half_byte = 0;
for (i = 1; i < ZigZag_length; i++) {
if (ZTable[idx]&0x80) {
if (half_byte == 0) {
ZigZag[i] = pIn[in_pos++];
tmpl = pIn[in_pos++];
tmph = tmpl <<8;
tmph = tmph & 0x0f00;
ZigZag[i] = ZigZag[i] | tmph;
ZigZag[i] = ZigZag[i]<<4;
ZigZag[i] = ZigZag[i]>>4;
half_byte = 1;
} else {
ZigZag[i] = pIn[in_pos++];
ZigZag[i] = ZigZag[i]<<8;
tmpl = tmpl & 0x00f0;
ZigZag[i] = ZigZag[i] | tmpl;
ZigZag[i] = ZigZag[i]>>4;
half_byte = 0;
}
}
ZTable[idx] = ZTable[idx]<<1;
count--;
if (count == 0) {
count = 8;
idx++;
}
}
}
}
/*************
* De-ZigZag *
*************/
for (j = 0; j < 64; j++) {
DeZigZag[j] = 0;
}
if (YUVFlag == 1) {
DeZigZag[0] = ZigZag[0];
DeZigZag[1] = ZigZag[1]<<1;
DeZigZag[2] = ZigZag[5]<<1;
DeZigZag[3] = ZigZag[6]<<2;
DeZigZag[8] = ZigZag[2]<<1;
DeZigZag[9] = ZigZag[4]<<1;
DeZigZag[10] = ZigZag[7]<<1;
DeZigZag[11] = ZigZag[13]<<2;
DeZigZag[16] = ZigZag[3]<<1;
DeZigZag[17] = ZigZag[8]<<1;
DeZigZag[18] = ZigZag[12]<<2;
DeZigZag[19] = ZigZag[17]<<2;
DeZigZag[24] = ZigZag[9]<<2;
DeZigZag[25] = ZigZag[11]<<2;
DeZigZag[26] = ZigZag[18]<<2;
DeZigZag[27] = ZigZag[24]<<3;
} else {
DeZigZag[0] = ZigZag[0];
DeZigZag[1] = ZigZag[1]<<2;
DeZigZag[2] = ZigZag[5]<<2;
DeZigZag[3] = ZigZag[6]<<3;
DeZigZag[8] = ZigZag[2]<<2;
DeZigZag[9] = ZigZag[4]<<2;
DeZigZag[10] = ZigZag[7]<<2;
DeZigZag[11] = ZigZag[13]<<4;
DeZigZag[16] = ZigZag[3]<<2;
DeZigZag[17] = ZigZag[8]<<2;
DeZigZag[18] = ZigZag[12]<<3;
DeZigZag[19] = ZigZag[17]<<4;
DeZigZag[24] = ZigZag[9]<<3;
DeZigZag[25] = ZigZag[11]<<4;
DeZigZag[26] = ZigZag[18]<<4;
DeZigZag[27] = ZigZag[24]<<4;
}
#if 0
/* Dequante */
if (YUVFlag == 1) {
/* Dequante Y */
for (i=0; i<64; i++) {
ZigZag[i] = DeZigZag[i]<<DQTY[i];
}
} else {
/* Dequante UV */
for (i=0; i<64; i++) {
ZigZag[i] = DeZigZag[i]<<DQTUV[i];
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -