home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 114 / macaddict114.cdr / Software / Utilities / macam.0.8.4.dmg / macam sources / cameras / ov511_decomp.c < prev    next >
Encoding:
C/C++ Source or Header  |  2005-05-20  |  12.0 KB  |  532 lines

  1. /* OV511 Decompression Support
  2.  *
  3.  * Copyright (c) 1999-2002 Mark W. McClelland. All rights reserved.
  4.  * http://alpha.dyndns.org/ov511/
  5.  *
  6.  * Original decompression code Copyright 1998-2000 OmniVision Technologies
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify it
  9.  * under the terms of the GNU General Public License as published by the
  10.  * Free Software Foundation; version 2 of the License.
  11.  * $Id: ov511_decomp.c,v 1.2 2005/05/20 14:58:37 hxr Exp $
  12.  */
  13.  
  14. #define __NO_VERSION__
  15.  
  16. #if !(__FreeBSD__) && !defined(__APPLE__)
  17.  
  18. #include <linux/config.h>
  19.  
  20. #if defined(OUTSIDE_KERNEL)
  21.     #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
  22.         #define MODVERSIONS
  23.     #endif
  24.  
  25.     #include <linux/version.h>
  26.  
  27.     #ifdef MODVERSIONS
  28.         #include <linux/modversions.h>
  29.     #endif
  30. #else
  31.     #include <linux/version.h>
  32. #endif
  33.  
  34. #include "ov511.h"
  35.  
  36. /******************************************************************************
  37.  * Globals
  38.  ******************************************************************************/
  39.  
  40. extern int debug;
  41.  
  42. #endif
  43.  
  44. /******************************************************************************
  45.  * Decompression Functions
  46.  ******************************************************************************/
  47.  
  48. static void
  49. DecompressYHI(unsigned char *pIn,
  50.           unsigned char *pOut,
  51.           int           *iIn,    /* in/out */
  52.           int           *iOut,    /* in/out */
  53.           const int      w,
  54.           const int      YUVFlag)
  55. {
  56.     short ZigZag[64];
  57.     int temp[64];
  58.     int Zcnt_Flag = 0;
  59.     int Num8_Flag = 0;
  60.     int in_pos = *iIn;
  61.     int out_pos = *iOut;
  62.     int tmp, tmp1, tmp2, tmp3;
  63.     unsigned char header, ZTable[64];
  64.     short tmpl, tmph, half_byte, idx, count;
  65.     unsigned long ZigZag_length = 0, ZT_length, i, j;
  66.     short DeZigZag[64];
  67.  
  68.     const short a = 11584;
  69.     const short b = 16068;
  70.     const short c = 15136;
  71.     const short d = 13624;
  72.     const short e =  9104;
  73.     const short f =  6270;
  74.     const short g =  3196;
  75.  
  76.     int out_idx;
  77.  
  78.     /* Take off every 'Zig' */
  79.     for (i = 0; i < 64; i++) {
  80.         ZigZag[i] = 0;
  81.     }
  82.  
  83.     /*****************************
  84.      * Read in the Y header byte *
  85.      *****************************/
  86.  
  87.     header = pIn[in_pos];
  88.     in_pos++;
  89.  
  90.     ZigZag_length = header & 0x3f;
  91.     ZigZag_length = ZigZag_length + 1;
  92.  
  93.     Num8_Flag = header & 0x40;
  94.     Zcnt_Flag = header & 0x80;
  95.  
  96.     /*************************
  97.      * Read in the Y content *
  98.      *************************/
  99.  
  100.     if (Zcnt_Flag == 0) {    /* Without Zero Table read contents directly */
  101.         /* Read in ZigZag[0] */
  102.         ZigZag[0] = pIn[in_pos++];
  103.         tmpl = pIn[in_pos++];
  104.         tmph = tmpl<<8;
  105.         ZigZag[0] = ZigZag[0] | tmph;
  106.         ZigZag[0] = ZigZag[0]<<4;
  107.         ZigZag[0] = ZigZag[0]>>4;
  108.  
  109.         if (Num8_Flag) { /* 8 Bits */
  110.             for (i = 1; i < ZigZag_length; i++) {
  111.                 ZigZag[i] = pIn[in_pos++];
  112.                 ZigZag[i] = ZigZag[i]<<8;
  113.                 ZigZag[i] = ZigZag[i]>>8;
  114.             }
  115.         } else {   /* 12 bits and has no Zero Table */
  116.             idx = 1;
  117.             half_byte = 0;
  118.             for (i = 1; i < ZigZag_length; i++) {
  119.                 if (half_byte == 0) {
  120.                     ZigZag[i] = pIn[in_pos++];
  121.                     tmpl = pIn[in_pos++];
  122.                     tmph = tmpl<<8;
  123.                     tmph = tmph&0x0f00;
  124.                     ZigZag[i] = ZigZag[i] | tmph;
  125.                     ZigZag[i] = ZigZag[i]<<4;
  126.                     ZigZag[i] = ZigZag[i]>>4;
  127.                     half_byte = 1;
  128.                 } else {
  129.                     ZigZag[i] = pIn[in_pos++];
  130.                     ZigZag[i] = ZigZag[i]<<8;
  131.                     tmpl = tmpl & 0x00f0;
  132.                     ZigZag[i] = ZigZag[i] | tmpl;
  133.                     ZigZag[i] = ZigZag[i]>>4;
  134.                     half_byte = 0;
  135.                 }
  136.             }
  137.         }
  138.     } else {  /* Has Zero Table */
  139.         /* Calculate Z-Table length */
  140.         ZT_length = ZigZag_length/8;
  141.         tmp = ZigZag_length%8;
  142.  
  143.         if (tmp > 0) {
  144.             ZT_length = ZT_length + 1;
  145.         }
  146.  
  147.         /* Read in Zero Table */
  148.         for (j = 0; j < ZT_length; j++) {
  149.             ZTable[j] = pIn[in_pos++];
  150.         }
  151.  
  152.         /* Read in ZigZag[0] */
  153.         ZigZag[0] = pIn[in_pos++];
  154.         tmpl = pIn[in_pos++];
  155.         tmph = tmpl<<8;
  156.         ZigZag[0] = ZigZag[0] | tmph;
  157.         ZigZag[0] = ZigZag[0]<<4;
  158.         ZigZag[0] = ZigZag[0]>>4;
  159.  
  160.         /* Decode ZigZag */
  161.         idx = 0;
  162.         ZTable[idx] = ZTable[idx]<<1;
  163.         count = 7;
  164.  
  165.         if (Num8_Flag) {    /* 8 Bits and has zero table */
  166.             for (i = 1; i < ZigZag_length; i++) {
  167.                 if ((ZTable[idx]&0x80)) {
  168.                     ZigZag[i] = pIn[in_pos++];
  169.                     ZigZag[i] = ZigZag[i]<<8;
  170.                     ZigZag[i] = ZigZag[i]>>8;
  171.                 }
  172.  
  173.                 ZTable[idx]=ZTable[idx]<<1;
  174.                 count--;
  175.                 if (count == 0)    {
  176.                     count = 8;
  177.                     idx++;
  178.                 }
  179.             }
  180.         } else {    /* 12 bits and has Zero Table */
  181.             half_byte = 0;
  182.             for (i = 1; i < ZigZag_length; i++) {
  183.                 if (ZTable[idx]&0x80) {
  184.                     if (half_byte == 0) {
  185.                         ZigZag[i] = pIn[in_pos++];
  186.                         tmpl = pIn[in_pos++];
  187.                         tmph = tmpl <<8;
  188.                         tmph = tmph & 0x0f00;
  189.                         ZigZag[i] = ZigZag[i] | tmph;
  190.                         ZigZag[i] = ZigZag[i]<<4;
  191.                         ZigZag[i] = ZigZag[i]>>4;
  192.                         half_byte = 1;
  193.                     } else {
  194.                         ZigZag[i] = pIn[in_pos++];
  195.                         ZigZag[i] = ZigZag[i]<<8;
  196.                         tmpl = tmpl & 0x00f0;
  197.                         ZigZag[i] = ZigZag[i] | tmpl;
  198.                         ZigZag[i] = ZigZag[i]>>4;
  199.                         half_byte = 0;
  200.                     }
  201.                 }
  202.  
  203.                 ZTable[idx] = ZTable[idx]<<1;
  204.                 count--;
  205.                 if (count == 0)    {
  206.                     count = 8;
  207.                     idx++;
  208.                 }
  209.             }
  210.         }
  211.     }
  212.  
  213.     /*************
  214.      * De-ZigZag *
  215.      *************/
  216.  
  217.     for (j = 0; j < 64; j++) {
  218.         DeZigZag[j] = 0;
  219.     }
  220.  
  221.     if (YUVFlag == 1) {
  222.         DeZigZag[0] = ZigZag[0];
  223.         DeZigZag[1] = ZigZag[1]<<1;
  224.         DeZigZag[2] = ZigZag[5]<<1;
  225.         DeZigZag[3] = ZigZag[6]<<2;
  226.  
  227.         DeZigZag[8] = ZigZag[2]<<1;
  228.         DeZigZag[9] = ZigZag[4]<<1;
  229.         DeZigZag[10] = ZigZag[7]<<1;
  230.         DeZigZag[11] = ZigZag[13]<<2;
  231.  
  232.         DeZigZag[16] = ZigZag[3]<<1;
  233.         DeZigZag[17] = ZigZag[8]<<1;
  234.         DeZigZag[18] = ZigZag[12]<<2;
  235.         DeZigZag[19] = ZigZag[17]<<2;
  236.  
  237.         DeZigZag[24] = ZigZag[9]<<2;
  238.         DeZigZag[25] = ZigZag[11]<<2;
  239.         DeZigZag[26] = ZigZag[18]<<2;
  240.         DeZigZag[27] = ZigZag[24]<<3;
  241.     } else {
  242.         DeZigZag[0] = ZigZag[0];
  243.         DeZigZag[1] = ZigZag[1]<<2;
  244.         DeZigZag[2] = ZigZag[5]<<2;
  245.         DeZigZag[3] = ZigZag[6]<<3;
  246.  
  247.         DeZigZag[8] = ZigZag[2]<<2;
  248.         DeZigZag[9] = ZigZag[4]<<2;
  249.         DeZigZag[10] = ZigZag[7]<<2;
  250.         DeZigZag[11] = ZigZag[13]<<4;
  251.  
  252.         DeZigZag[16] = ZigZag[3]<<2;
  253.         DeZigZag[17] = ZigZag[8]<<2;
  254.         DeZigZag[18] = ZigZag[12]<<3;
  255.         DeZigZag[19] = ZigZag[17]<<4;
  256.  
  257.         DeZigZag[24] = ZigZag[9]<<3;
  258.         DeZigZag[25] = ZigZag[11]<<4;
  259.         DeZigZag[26] = ZigZag[18]<<4;
  260.         DeZigZag[27] = ZigZag[24]<<4;
  261.     }
  262.  
  263.     /*****************
  264.      **** IDCT 1D ****
  265.      *****************/
  266.  
  267. #define IDCT_1D(c0, c1, c2, c3, in)                    \
  268.     do {                                \
  269.         tmp1=((c0)*DeZigZag[in])+((c2)*DeZigZag[(in)+2]);    \
  270.         tmp2=(c1)*DeZigZag[(in)+1];                \
  271.         tmp3=(c3)*DeZigZag[(in)+3];                \
  272.     } while (0)
  273.  
  274. #define COMPOSE_1(out1, out2)        \
  275.     do {                \
  276.         tmp=tmp1+tmp2+tmp3;    \
  277.         temp[out1] = tmp>>15;    \
  278.         tmp=tmp1-tmp2-tmp3;    \
  279.         temp[out2] = tmp>>15;    \
  280.     } while (0)
  281.  
  282. #define COMPOSE_2(out1, out2)        \
  283.     do {                \
  284.         tmp=tmp1+tmp2-tmp3;    \
  285.         temp[out1] = tmp>>15;    \
  286.         tmp=tmp1-tmp2+tmp3;    \
  287.         temp[out2] = tmp>>15;    \
  288.     } while (0)
  289.  
  290.     /* j = 0 */
  291.     IDCT_1D(a, b,  c, d,  0); COMPOSE_1( 0, 56);
  292.     IDCT_1D(a, b,  c, d,  8); COMPOSE_1( 1, 57);
  293.     IDCT_1D(a, b,  c, d, 16); COMPOSE_1( 2, 58);
  294.     IDCT_1D(a, b,  c, d, 24); COMPOSE_1( 3, 59);
  295.  
  296.     /* j = 1 */
  297.     IDCT_1D(a, d,  f, g,  0); COMPOSE_2( 8, 48);
  298.     IDCT_1D(a, d,  f, g,  8); COMPOSE_2( 9, 49);
  299.     IDCT_1D(a, d,  f, g, 16); COMPOSE_2(10, 50);
  300.     IDCT_1D(a, d,  f, g, 24); COMPOSE_2(11, 51);
  301.  
  302.     /* j = 2 */
  303.     IDCT_1D(a, e, -f, b,  0); COMPOSE_2(16, 40);
  304.     IDCT_1D(a, e, -f, b,  8); COMPOSE_2(17, 41);
  305.     IDCT_1D(a, e, -f, b, 16); COMPOSE_2(18, 42);
  306.     IDCT_1D(a, e, -f, b, 24); COMPOSE_2(19, 43);
  307.  
  308.     /* j = 3 */
  309.     IDCT_1D(a, g, -c, e,  0); COMPOSE_2(24, 32);
  310.     IDCT_1D(a, g, -c, e,  8); COMPOSE_2(25, 33);
  311.     IDCT_1D(a, g, -c, e, 16); COMPOSE_2(26, 34);
  312.     IDCT_1D(a, g, -c, e, 24); COMPOSE_2(27, 35);
  313.  
  314. #undef IDCT_1D
  315. #undef COMPOSE_1
  316. #undef COMPOSE_2
  317.  
  318.     /*****************
  319.      **** IDCT 2D ****
  320.      *****************/
  321.  
  322. #define IDCT_2D(c0, c1, c2, c3, in)                \
  323.     do {                            \
  324.         tmp = temp[in]*(c0) + temp[(in)+1]*(c1)        \
  325.             + temp[(in)+2]*(c2) + temp[(in)+3]*(c3);    \
  326.     } while (0)
  327.  
  328. #define STORE(i)                \
  329.     do {                    \
  330.         tmp = tmp >> 15;        \
  331.         tmp = tmp + 128;        \
  332.         if (tmp > 255) tmp = 255;    \
  333.         if (tmp < 0)   tmp = 0;        \
  334.         pOut[i] = (unsigned char) tmp;    \
  335.     } while (0)
  336.  
  337. #define IDCT_2D_ROW(in)                        \
  338.     do {                            \
  339.         IDCT_2D(a,  b,  c,  d, in); STORE(0+out_idx);    \
  340.         IDCT_2D(a,  d,  f, -g, in); STORE(1+out_idx);    \
  341.         IDCT_2D(a,  e, -f, -b, in); STORE(2+out_idx);    \
  342.         IDCT_2D(a,  g, -c, -e, in); STORE(3+out_idx);    \
  343.         IDCT_2D(a, -g, -c,  e, in); STORE(4+out_idx);    \
  344.         IDCT_2D(a, -e, -f,  b, in); STORE(5+out_idx);    \
  345.         IDCT_2D(a, -d,  f,  g, in); STORE(6+out_idx);    \
  346.         IDCT_2D(a, -b,  c, -d, in); STORE(7+out_idx);    \
  347.     } while (0)
  348.  
  349.  
  350. #define IDCT_2D_FAST(c0, c1, c2, c3, in)            \
  351.     do {                            \
  352.         tmp1=((c0)*temp[in])+((c2)*temp[(in)+2]);    \
  353.         tmp2=(c1)*temp[(in)+1];                \
  354.         tmp3=(c3)*temp[(in)+3];                \
  355.     } while (0)
  356.  
  357. #define STORE_FAST_1(out1, out2)                \
  358.     do {                            \
  359.         tmp=tmp1+tmp2+tmp3;                \
  360.         STORE((out1)+out_idx);                \
  361.         tmp=tmp1-tmp2-tmp3;                \
  362.         STORE((out2)+out_idx);                \
  363.     } while (0)
  364.  
  365. #define STORE_FAST_2(out1, out2)                \
  366.     do {                            \
  367.         tmp=tmp1+tmp2-tmp3;                \
  368.         STORE((out1)+out_idx);                \
  369.         tmp=tmp1-tmp2+tmp3;                \
  370.         STORE((out2)+out_idx);                \
  371.     } while (0)
  372.  
  373. #define IDCT_2D_FAST_ROW(in)                        \
  374.     do {                                \
  375.         IDCT_2D_FAST(a, b,  c, d, in);    STORE_FAST_1(0, 7);    \
  376.         IDCT_2D_FAST(a, d,  f, g, in);    STORE_FAST_2(1, 6);    \
  377.         IDCT_2D_FAST(a, e, -f, b, in);    STORE_FAST_2(2, 5);    \
  378.         IDCT_2D_FAST(a, g, -c, e, in);    STORE_FAST_2(3, 4);    \
  379.     } while (0)
  380.  
  381.     out_idx = out_pos;
  382.  
  383.     IDCT_2D_ROW(0);        out_idx += w;
  384.     IDCT_2D_ROW(8);        out_idx += w;
  385.     IDCT_2D_ROW(16);    out_idx += w;
  386.     IDCT_2D_ROW(24);    out_idx += w;
  387.     IDCT_2D_ROW(32);    out_idx += w;
  388.     IDCT_2D_ROW(40);    out_idx += w;
  389.     IDCT_2D_FAST_ROW(48);    out_idx += w;
  390.     IDCT_2D_FAST_ROW(56);
  391.  
  392.     *iIn = in_pos;
  393.     *iOut = out_pos + 8;
  394. }
  395.  
  396. #define DECOMP_Y() DecompressYHI(pIn, pY, &iIn, &iY, w, 1)
  397. #define DECOMP_U() DecompressYHI(pIn, pU, &iIn, &iU, w/2, 2)
  398. #define DECOMP_V() DecompressYHI(pIn, pV, &iIn, &iV, w/2, 2)
  399.  
  400. inline static int
  401. Decompress400HiNoMMX(unsigned char *pIn,
  402.              unsigned char *pOut,
  403.              const int      w,
  404.              const int      h,
  405.              const int      inSize)
  406. {
  407.     unsigned char *pY = pOut;
  408.     int x, y, iIn, iY;
  409.  
  410.     iIn = 0;
  411.     for (y = 0; y < h; y += 8) {
  412.         iY = w*y;
  413.  
  414.         for (x = 0; x < w; x += 8)
  415.             DECOMP_Y();
  416.     }
  417.  
  418.     return 0;
  419. }
  420.  
  421. inline static int
  422. Decompress420HiNoMMX(unsigned char *pIn,
  423.              unsigned char *pOut,
  424.              const int      w,
  425.              const int      h,
  426.              const int      inSize)
  427. {
  428.     unsigned char *pY = pOut;
  429.     unsigned char *pU = pY + w*h;
  430.     unsigned char *pV = pU + w*h/4;
  431.     int xY, xUV, iY, iU, iV, iIn, count;
  432.     const int nBlocks = (w*h) / (32*8);
  433.  
  434.     iIn = 0;
  435.     iY = iU = iV = 0;
  436.     xY = xUV = 0;
  437.  
  438.     for (count = 0; count < nBlocks; count++) {
  439.             DECOMP_U();
  440.             DECOMP_V();    xUV += 16;
  441.             if (xUV >= w) {
  442.                 iU += (w*7)/2;
  443.                 iV += (w*7)/2;
  444.                 xUV = 0;
  445.             }
  446.  
  447.             DECOMP_Y();    xY += 8;
  448.             DECOMP_Y();    xY += 8;
  449.             if (xY >= w) {
  450.                 iY += w*7;
  451.                 xY = 0;
  452.             }
  453.             DECOMP_Y();    xY += 8;
  454.             DECOMP_Y();    xY += 8;
  455.             if (xY >= w) {
  456.                 iY += w*7;
  457.                 xY = 0;
  458.             }
  459.     }
  460.  
  461.     return 0;
  462. }
  463.  
  464. /* Input format is raw isoc. data (with header and packet
  465.  * number stripped, and all-zero blocks removed).
  466.  * Output format is YUV400
  467.  * Returns uncompressed data length if success, or zero if error
  468.  */
  469. #if !(__FreeBSD__) && !defined(__APPLE__)
  470. static 
  471. #endif
  472. int
  473. Decompress400(unsigned char *pIn,
  474.           unsigned char *pOut,
  475.           unsigned char *pTmp,
  476.           int         w,
  477.           int         h,
  478.           int         inSize)
  479. {
  480.     int numpix = w * h;
  481.     int rc;
  482.  
  483. #if !(__FreeBSD__) && !defined(__APPLE__)
  484.     PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize);
  485. #endif
  486.  
  487.     rc = Decompress400HiNoMMX(pIn, pOut, w, h, inSize);
  488.  
  489.     if (rc)
  490.         return 0;
  491.  
  492.     return numpix;
  493. }
  494.  
  495. /* Input format is raw isoc. data (with header and packet
  496.  * number stripped, and all-zero blocks removed).
  497.  * Output format is planar YUV420
  498.  * Returns uncompressed data length if success, or zero if error
  499.  */
  500. #if !(__FreeBSD__) && !defined(__APPLE__)
  501. static int
  502. #else
  503. int
  504. #endif
  505. Decompress420(unsigned char *pIn,
  506.           unsigned char *pOut,
  507.           unsigned char *pTmp,
  508.           int         w,
  509.           int         h,
  510.           int         inSize)
  511. {
  512.     int numpix = w * h;
  513.     int rc;
  514.  
  515. #if !(__FreeBSD__) && !defined(__APPLE__)
  516.     PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize);
  517. #endif
  518.  
  519.     rc = Decompress420HiNoMMX(pIn, pOut, w, h, inSize);
  520.  
  521.     if (rc)
  522.         return 0;
  523.  
  524.     return (numpix * 3 / 2);
  525. }
  526.  
  527. #if !(__FreeBSD__) && !defined(__APPLE__)
  528. struct ov51x_decomp_ops ov511_decomp_ops = {
  529.     .decomp_400 =    Decompress400,
  530.     .decomp_420 =    Decompress420,
  531. };
  532. #endif