📄 ov518_decomp.c
字号:
t=(base - val1 + val2 - val3 - tmp1 - tmp2 - C4 + C20) >> 17; out[19]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; t=(base + val1 - val2 - val3) >> 17; out[20]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t;}#undef TIMES_16382#undef TIMES_23168#undef TIMES_30270#undef TIMES_41986#undef TIMES_35594#undef TIMES_23783#undef TIMES_8351#undef TIMES_17391#undef TIMES_14743#undef TIMES_9851#undef TIMES_3459#undef TIMES_32134#undef TIMES_27242#undef TIMES_18202#undef TIMES_6392#undef TIMES_39550#undef TIMES_6785#undef TIMES_12538/****************************************************************************** * Main Decoder Functions ******************************************************************************//* This function handles the decompression of a single 8x4 block. It is * independent of the palette (YUV422, YUV420, YUV400, GBR422...). cinfo->bytes * determines the positin in the input buffer. */static int decompress8x4(unsigned char *pOut, unsigned char *pIn, int *lastDC, int uvFlag, CompInfo *cinfo){ int i, x, y, dc; int coeffs[32]; int deZigZag[32]; int *dest; int *src; unsigned char *qt = cinfo->qt; if (! uvFlag) { huffmanDecoderY(coeffs, (int*) pIn, cinfo); /* iDPCM and dequantize first coefficient */ dc = (*lastDC) + coeffs[0]; coeffs[0] = dc * (qt[0] + 1); *lastDC = dc; /* ...and the second coefficient */ coeffs[1] = ((qt[1] + 1) * coeffs[1]) >> 1; /* Dequantize, starting at 3rd element */ for (i = 2; i < 32; i++) coeffs[i] = (qt[i] + 1) * coeffs[i]; } else { huffmanDecoderUV(coeffs, (int*) pIn, cinfo); /* iDPCM */ dc = (*lastDC) + coeffs[0]; coeffs[0] = dc; *lastDC = dc; /* Dequantize */ for (i = 0; i < 32; i++) coeffs[i] = (qt[32 + i] + 1) * coeffs[i]; } /* Dezigzag */ for (i = 0; i < 32; i++) deZigZag[i] = coeffs[ZigZag518[i]]; /* Transpose the dezigzagged coefficient matrix */ src = deZigZag; dest = coeffs; for (y = 0; y <= 3; ++y) { for (x = 0; x <= 7; ++x) { dest[x] = src[x * 4]; } src += 1; dest += 8; } /* Do the inverse DCT transform */ DCT_8x4(coeffs, pOut); return 0; /* Always returns 0 */}static inline void copyBlock(unsigned char *src, unsigned char *dest, int destInc){ int i; unsigned int *pSrc, *pDest; for (i = 0; i <= 3; i++) { pSrc = (unsigned int *) src; pDest = (unsigned int *) dest; pDest[0] = pSrc[0]; pDest[1] = pSrc[1]; src += 8; dest += destInc; }}static inline intdecompress400NoMMXOV518(unsigned char *pIn, unsigned char *pOut, unsigned char *pTmp, const int w, const int h, const int numpix, CompInfo *cinfo){ int iOutY, x, y; int lastYDC = 0; /* Start Y loop */ y = 0; do { iOutY = w * y; x = 0; do { decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); copyBlock(pTmp, pOut + iOutY, w); iOutY += 8; x += 8; } while (x < w); y += 4; } while (y < h); /* Did we decode too much? */ if (cinfo->bytes > cinfo->rawLen + 897) return 1; /* Did we decode enough? */ if (cinfo->bytes >= cinfo->rawLen - 897) return 0; else return 1;}static inline intdecompress420NoMMXOV518(unsigned char *pIn, unsigned char *pOut, unsigned char *pTmp, const int w, const int h, const int numpix, CompInfo *cinfo){ unsigned char *pOutU = pOut + numpix; unsigned char *pOutV = pOutU + numpix / 4; int iOutY, iOutU, iOutV, x, y; int lastYDC = 0; int lastUDC = 0; int lastVDC = 0; /* Start Y loop */ y = 0; do { iOutY = w * y; iOutV = iOutU = iOutY / 4; x = 0; do { decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); copyBlock(pTmp, pOut + iOutY, w); iOutY += 8; x += 8; } while (x < w); iOutY = w * (y + 4); x = 0; do { decompress8x4(pTmp, pIn, &lastUDC, 1, cinfo); copyBlock(pTmp, pOutU + iOutU, w/2); iOutU += 8; decompress8x4(pTmp, pIn, &lastVDC, 1, cinfo); copyBlock(pTmp, pOutV + iOutV, w/2); iOutV += 8; decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); copyBlock(pTmp, pOut + iOutY, w); iOutY += 8; decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); copyBlock(pTmp, pOut + iOutY, w); iOutY += 8; x += 16; } while (x < w); y += 8; } while (y < h); /* Did we decode too much? */ if (cinfo->bytes > cinfo->rawLen + 897) return 1; /* Did we decode enough? */ if (cinfo->bytes >= cinfo->rawLen - 897) return 0; else return 1;}/* Get quantization tables from static arrays * Returns: <0 if error, or >=0 otherwise */static intget_qt_static(CompInfo *cinfo){ unsigned char qtY[] = OV518_YQUANTABLE; unsigned char qtUV[] = OV518_UVQUANTABLE; unsigned char qt[64]; memcpy(qt, qtY, 32); memcpy(qt + 32, qtUV, 32); cinfo->qt = qt; return 0;}/* Get quantization tables from input * Returns: <0 if error, or >=0 otherwise */static intget_qt_dynamic(unsigned char *pIn, CompInfo *cinfo){ int rawLen = cinfo->rawLen; /* Make sure input is actually big enough to hold trailer */ if (rawLen < 72) { PDEBUG(1, "Not enough input to decompress"); return -EINVAL; } cinfo->qt = pIn + rawLen - 64; print_qt(cinfo->qt); return 0;}/* Input format is raw isoc. data (with intact SOF header, packet numbers * stripped, and all-zero blocks removed). * Output format is planar YUV400 * Returns uncompressed data length if success, or zero if error */static int Decompress400(unsigned char *pIn, unsigned char *pOut, unsigned char *pTmp, int w, int h, int inSize){ CompInfo cinfo; int numpix = w * h; PDEBUG(4, "%dx%d pIn=%p pOut=%p pTmp=%p inSize=%d", w, h, pIn, pOut, pTmp, inSize); cinfo.bytes = 0; cinfo.bits = 0; cinfo.rawLen = inSize; if (staticquant) { if (get_qt_static(&cinfo) < 0) return 0; } else { if (get_qt_dynamic(pIn, &cinfo) < 0) return 0; } /* Decompress, skipping the 8-byte SOF header */ if (decompress400NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo))// return 0; ; /* Don't return error yet */ return (numpix);}/* Input format is raw isoc. data (with intact SOF header, packet numbers * stripped, and all-zero blocks removed). * Output format is planar YUV420 * Returns uncompressed data length if success, or zero if error */static int Decompress420(unsigned char *pIn, unsigned char *pOut, unsigned char *pTmp, int w, int h, int inSize){ CompInfo cinfo; int numpix = w * h; PDEBUG(4, "%dx%d pIn=%p pOut=%p pTmp=%p inSize=%d", w, h, pIn, pOut, pTmp, inSize); cinfo.bytes = 0; cinfo.bits = 0; cinfo.rawLen = inSize; if (staticquant) { if (get_qt_static(&cinfo) < 0) return 0; } else { if (get_qt_dynamic(pIn, &cinfo) < 0) return 0; } /* Decompress, skipping the 8-byte SOF header */ if (decompress420NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo))// return 0; ; /* Don't return error yet *//* OmniVision may have written this code for the OV518. It isn't tested yet */#if 0 /* For color saturation 8/22/00 */ { int i, u, v; unsigned char *pU = pOut + numpix; unsigned char *pV = pU + numpix/4; for (i = 0; i < numpix/4; i++) { u = (int)*pU; v = (int)*pV; u -= 128; v -= 128; u = (u * 577) >> 10; /* u=0.564 */ v = (v * 730) >> 10; /* v=0.713 */ u += 128; v += 128; *pU++ = (unsigned char)u; *pV++ = (unsigned char)v; } }#endif if (nouv) { int i; unsigned char *pU = pOut + numpix; unsigned char *pV = pU + numpix/4; for (i = 0; i < numpix/4; i++) { *pU++ = 127; *pV++ = 127; } } return (numpix * 3 / 2);}/****************************************************************************** * Module Functions ******************************************************************************/static struct ov51x_decomp_ops decomp_ops = { .decomp_400 = Decompress400, .decomp_420 = Decompress420, .owner = THIS_MODULE,};static int __init decomp_init(void){ int rc; EXPORT_NO_SYMBOLS; rc = ov511_register_decomp_module(DECOMP_INTERFACE_VER, &decomp_ops, ov518, mmx); if (rc) { err("Could not register with ov511 (rc=%d)", rc); return -1; } info(DRIVER_VERSION " : " DRIVER_DESC); PDEBUG(1, "Using %s, %s quantization", IDCT_MESSAGE, staticquant ? "static" : "dynamic"); return 0;}static void __exit decomp_exit(void){ ov511_deregister_decomp_module(ov518, mmx); info("deregistered");}module_init(decomp_init);module_exit(decomp_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -