dwt_aux.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:25k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /* $Id: dwt_aux.cpp,v 1.2 2001/04/19 18:32:09 wmay Exp $ */
  2. /****************************************************************************/
  3. /*   MPEG4 Visual Texture Coding (VTC) Mode Software                        */
  4. /*                                                                          */
  5. /*   This software was jointly developed by the following participants:     */
  6. /*                                                                          */
  7. /*   Single-quant,  multi-quant and flow control                            */
  8. /*   are provided by  Sarnoff Corporation                                   */
  9. /*     Iraj Sodagar   (iraj@sarnoff.com)                                    */
  10. /*     Hung-Ju Lee    (hjlee@sarnoff.com)                                   */
  11. /*     Paul Hatrack   (hatrack@sarnoff.com)                                 */
  12. /*     Shipeng Li     (shipeng@sarnoff.com)                                 */
  13. /*     Bing-Bing Chai (bchai@sarnoff.com)                                   */
  14. /*     B.S. Srinivas  (bsrinivas@sarnoff.com)                               */
  15. /*                                                                          */
  16. /*   Bi-level is provided by Texas Instruments                              */
  17. /*     Jie Liang      (liang@ti.com)                                        */
  18. /*                                                                          */
  19. /*   Shape Coding is provided by  OKI Electric Industry Co., Ltd.           */
  20. /*     Zhixiong Wu    (sgo@hlabs.oki.co.jp)                                 */
  21. /*     Yoshihiro Ueda (yueda@hlabs.oki.co.jp)                               */
  22. /*     Toshifumi Kanamaru (kanamaru@hlabs.oki.co.jp)                        */
  23. /*                                                                          */
  24. /*   OKI, Sharp, Sarnoff, TI and Microsoft contributed to bitstream         */
  25. /*   exchange and bug fixing.                                               */
  26. /*                                                                          */
  27. /*                                                                          */
  28. /* In the course of development of the MPEG-4 standard, this software       */
  29. /* module is an implementation of a part of one or more MPEG-4 tools as     */
  30. /* specified by the MPEG-4 standard.                                        */
  31. /*                                                                          */
  32. /* The copyright of this software belongs to ISO/IEC. ISO/IEC gives use     */
  33. /* of the MPEG-4 standard free license to use this  software module or      */
  34. /* modifications thereof for hardware or software products claiming         */
  35. /* conformance to the MPEG-4 standard.                                      */
  36. /*                                                                          */
  37. /* Those intending to use this software module in hardware or software      */
  38. /* products are advised that use may infringe existing  patents. The        */
  39. /* original developers of this software module and their companies, the     */
  40. /* subsequent editors and their companies, and ISO/IEC have no liability    */
  41. /* and ISO/IEC have no liability for use of this software module or         */
  42. /* modification thereof in an implementation.                               */
  43. /*                                                                          */
  44. /* Permission is granted to MPEG members to use, copy, modify,              */
  45. /* and distribute the software modules ( or portions thereof )              */
  46. /* for standardization activity within ISO/IEC JTC1/SC29/WG11.              */
  47. /*                                                                          */
  48. /* Copyright 1995, 1996, 1997, 1998 ISO/IEC                                 */
  49. /****************************************************************************/
  50. /************************************************************/
  51. /*     Sarnoff Very Low Bit Rate Still Image Coder          */
  52. /*     Copyright 1995, 1996, 1997, 1998 Sarnoff Corporation */
  53. /************************************************************/
  54. #ifndef _DWT_DBL_
  55. #include <stdio.h>
  56. #include <stdlib.h>
  57. #include <string.h>
  58. #include <math.h>
  59. #include <memory.h>
  60. #include "basic.hpp"
  61. #include "dwt.h"
  62. #define _DWT_INT_
  63. #endif /* _DWT_DBL_ */
  64. #undef DWTDATA
  65. #ifdef _DWT_INT_
  66. #define DWTDATA Int
  67. #else
  68. #define DWTDATA double
  69. #endif
  70. #ifdef _DWT_INT_
  71. /* Function:   DecomposeOneLevelInt()
  72.    Description: Pyramid Decompose one level of wavelet coefficients
  73.    Input:
  74.    Width  -- Width of Image; 
  75.    Height -- Height of Image;
  76.    level -- current decomposition level
  77.    Filter     -- Filter Used.
  78.    MaxCoeff, MinCoeff -- bounds of the output data;
  79.    Input/Output:
  80.    OutCoeff   -- Ouput wavelet coefficients
  81.    OutMask    -- Output mask corresponding to wavelet coefficients
  82.    Return: DWT_OK if success.
  83. */
  84. Int VTCDWT:: DecomposeOneLevelInt(Int *OutCoeff, UChar *OutMask, Int Width,
  85. Int Height, Int level, FILTER *Filter,
  86. Int MaxCoeff, Int MinCoeff)
  87. {
  88.   Int *InBuf, *OutBuf ;
  89.   UChar *InMaskBuf, *OutMaskBuf;
  90.   Int width = Width>>(level-1);
  91.   Int height = Height>>(level-1);
  92.   Int MaxLength = (width > height)?width:height;
  93.   Int i,k,ret;
  94.   Int *a;
  95.   UChar *c,*d;
  96.   Int *e;
  97.   /* double check filter type */
  98.   if(Filter->DWT_Type != DWT_INT_TYPE) return(DWT_INTERNAL_ERROR);
  99.   /* allocate line buffers */
  100.   InBuf = (Int *) malloc(sizeof(Int)*MaxLength);
  101.   InMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
  102.   OutBuf = (Int *) malloc(sizeof(Int)*MaxLength);
  103.   OutMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
  104.   if(InBuf==NULL || InMaskBuf ==NULL || OutBuf == NULL || OutMaskBuf==NULL) 
  105.     return(DWT_MEMORY_FAILED);
  106.     
  107.   /* horizontal decomposition first*/
  108.   for(i=0,k=0;i<height;i++,k+=Width) {
  109.     /* get a line of coefficients */
  110.     for(a=InBuf, e=OutCoeff+k;a<InBuf+width;a++,e++) {
  111.      
  112.       *a = (Int) *e;
  113.     }
  114.     /* get a line of mask */
  115.     memcpy(InMaskBuf, OutMask+k, sizeof(UChar)*width);
  116.     /* Perform horizontal SA-DWT */
  117.     ret=SADWT1dInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf, width, Filter, 
  118.    DWT_HORIZONTAL);
  119.     if(ret!=DWT_OK) {
  120.       free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
  121.       return(ret);
  122.     }
  123.     /* put the transformed line back */
  124.     for(a=OutBuf,e=OutCoeff+k;a<OutBuf+width;a++,e++) {
  125.       /* Scale and Leave 3 extra bits for precision reason */
  126.       *a = ROUNDDIV((*a <<3), Filter->Scale);
  127.       if(*a > MaxCoeff || *a < MinCoeff) {
  128. free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
  129. return(DWT_COEFF_OVERFLOW);
  130.       }
  131.       *e = (Int) *a;
  132.     }
  133.     memcpy(OutMask+k, OutMaskBuf, sizeof(UChar)*width);
  134.   }
  135.   /* then vertical decomposition */
  136.   for(i=0;i<width;i++) {
  137.     /* get a column of coefficients */
  138.     for(a=InBuf, e=OutCoeff+i, c= InMaskBuf, d= OutMask+i;
  139. a<InBuf+height; a++, c++, e+=Width, d+=Width) {
  140.       *a=(Int) *e;
  141.       *c = *d;
  142.     }
  143.     /* perform vertical SA-DWT */
  144.     ret=SADWT1dInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf, height, Filter, 
  145.    DWT_VERTICAL);
  146.     if(ret!=DWT_OK) {
  147.       free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
  148.       return(ret);
  149.     }
  150.     /* put the transformed column back */
  151.     for(a=OutBuf, e=OutCoeff+i, c= OutMaskBuf, d= OutMask+i;
  152. a<OutBuf+height; a++, c++, e+=Width, d+=Width) {
  153.       /*Scale and leave the sqrt(2)*sqrt(2) factor in the scale */
  154.       *a = ROUNDDIV(*a, (Filter->Scale<<2)); 
  155.       if(*a > MaxCoeff || *a < MinCoeff) {
  156. free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
  157. return(DWT_COEFF_OVERFLOW);
  158.       }
  159.       *e= (Int) *a;
  160.       *d = *c;
  161.     }
  162.   }
  163.   free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
  164.   return(DWT_OK);
  165. }
  166. #else
  167. /* Function:   DecomposeOneLevelDbl()
  168.    Description: Pyramid Decompose one level of wavelet coefficients
  169.    Input:
  170.    Width  -- Width of Image; 
  171.    Height -- Height of Image;
  172.    level -- current decomposition level
  173.    Filter     -- Filter Used.
  174.    MaxCoeff, MinCoeff -- bounds of the output data;
  175.    Input/Output:
  176.    OutCoeff   -- Ouput wavelet coefficients
  177.    OutMask    -- Output mask corresponding to wavelet coefficients
  178.    Return: DWT_OK if success.
  179. */
  180. Int VTCDWT:: DecomposeOneLevelDbl(double *OutCoeff, UChar *OutMask, Int Width,
  181. Int Height, Int level, FILTER *Filter)
  182. {
  183.   double *InBuf, *OutBuf ;
  184.   UChar *InMaskBuf, *OutMaskBuf;
  185.   Int width = Width>>(level-1);
  186.   Int height = Height>>(level-1);
  187.   Int MaxLength = (width > height)?width:height;
  188.   Int i,k,ret;
  189.   double *a;
  190.   UChar *c,*d;
  191.   double *e;
  192.   /* double check filter type */
  193.   if(Filter->DWT_Type != DWT_DBL_TYPE) return(DWT_INTERNAL_ERROR);
  194.   /* allocate line buffers */
  195.   InBuf = (double *) malloc(sizeof(double)*MaxLength);
  196.   InMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
  197.   OutBuf = (double *) malloc(sizeof(double)*MaxLength);
  198.   OutMaskBuf = (UChar *) malloc(sizeof(UChar)*MaxLength);
  199.   if(InBuf==NULL || InMaskBuf ==NULL || OutBuf == NULL || OutMaskBuf==NULL) 
  200.     return(DWT_MEMORY_FAILED);
  201.     
  202.   /* horizontal decomposition first*/
  203.   for(i=0,k=0;i<height;i++,k+=Width) {
  204.     /* get a line of coefficients */
  205.     for(a=InBuf, e=OutCoeff+k;a<InBuf+width;a++,e++) {
  206.       *a =  *e;
  207.     }
  208.     /* get a line of mask */
  209.     memcpy(InMaskBuf, OutMask+k, sizeof(UChar)*width);
  210.     /* Perform horizontal SA-DWT */
  211.     ret=SADWT1dDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf, width, Filter, 
  212.    DWT_HORIZONTAL);
  213.     if(ret!=DWT_OK) {
  214.       free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
  215.       return(ret);
  216.     }
  217.     /* put the transformed line back */
  218.     for(a=OutBuf,e=OutCoeff+k;a<OutBuf+width;a++,e++) {
  219.       *e =  *a;
  220.     }
  221.     memcpy(OutMask+k, OutMaskBuf, sizeof(UChar)*width);
  222.   }
  223.   /* then vertical decomposition */
  224.   for(i=0;i<width;i++) {
  225.     /* get a column of coefficients */
  226.     for(a=InBuf, e=OutCoeff+i, c= InMaskBuf, d= OutMask+i;
  227. a<InBuf+height; a++, c++, e+=Width, d+=Width) {
  228.       *a = *e;
  229.       *c = *d;
  230.     }
  231.     /* perform vertical SA-DWT */
  232.     ret=SADWT1dDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf, height, Filter, 
  233.    DWT_VERTICAL);
  234.     if(ret!=DWT_OK) {
  235.       free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
  236.       return(ret);
  237.     }
  238.     /* put the transformed column back */
  239.     for(a=OutBuf, e=OutCoeff+i, c= OutMaskBuf, d= OutMask+i;
  240. a<OutBuf+height; a++, c++, e+=Width, d+=Width) {
  241.       *e = *a;
  242.       *d = *c;
  243.     }
  244.   }
  245.   free(InBuf);free(OutBuf);free(InMaskBuf);free(OutMaskBuf);
  246.   return(DWT_OK);
  247. }
  248. #endif
  249. /* Function: SADWT1dInt() or SADWT1dDbl()
  250.    Description:  1-d SA-DWT
  251.    Input:
  252.    InBuf -- Input 1d data buffer
  253.    InMaskBuf -- Input 1d mask buffer
  254.    Length -- length of the input data
  255.    Filter -- filter used
  256.    Direction -- vertical or horizontal decomposition (used for inversible 
  257.    mask decomposition)
  258.    Output:
  259.    
  260.    OutBuf -- Transformed 1d Data
  261.    OutMask -- Mask for the Transformed 1d Data
  262.    Return: return DWT_OK if successful
  263.   
  264. */
  265. #ifdef _DWT_INT_
  266. Int VTCDWT:: SADWT1dInt(Int *InBuf, UChar *InMaskBuf, Int *OutBuf, 
  267.       UChar *OutMaskBuf, Int Length, FILTER *Filter, 
  268.       Int Direction)
  269. {
  270.   switch(Filter->DWT_Class){
  271.   case DWT_ODD_SYMMETRIC:
  272.     return(SADWT1dOddSymInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf, 
  273.     Length, Filter, Direction));
  274.   case DWT_EVEN_SYMMETRIC:
  275.     return(SADWT1dEvenSymInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf, 
  276.      Length, Filter, Direction));
  277.     /*  case ORTHOGONAL:
  278. return(SADWT1dOrthInt(InBuf, InMaskBuf, OutBuf, OutMaskBuf, 
  279.   Length, Filter, Direction)); */
  280.   default:
  281.     return(DWT_FILTER_UNSUPPORTED);
  282.   }
  283. }
  284. #else
  285. Int VTCDWT:: SADWT1dDbl(double *InBuf, UChar *InMaskBuf, double *OutBuf, 
  286.       UChar *OutMaskBuf, Int Length, FILTER *Filter, 
  287.       Int Direction)
  288. {
  289.   switch(Filter->DWT_Class){
  290.   case DWT_ODD_SYMMETRIC:
  291.     return(SADWT1dOddSymDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf, 
  292.     Length, Filter, Direction));
  293.   case DWT_EVEN_SYMMETRIC:
  294.     return(SADWT1dEvenSymDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf, 
  295.      Length, Filter, Direction));
  296.     /*  case ORTHOGONAL:
  297. return(SADWT1dOrthDbl(InBuf, InMaskBuf, OutBuf, OutMaskBuf, 
  298.   Length, Filter, Direction)); */
  299.   default:
  300.     return(DWT_FILTER_UNSUPPORTED);
  301.   }
  302. }
  303. #endif
  304. /* Function: SADWT1dOddSymInt() or SADWT1dOddSymDbl()
  305.    Description: 1D  SA-DWT using Odd Symmetric Filter
  306.    Input:
  307.    InBuf -- Input 1d data buffer
  308.    InMaskBuf -- Input 1d mask buffer
  309.    Length -- length of the input data
  310.    Filter -- filter used
  311.    Direction -- vertical or horizontal decomposition (used for inversible 
  312.    mask decomposition)
  313.    Output:
  314.    
  315.    OutBuf -- Transformed 1d Data
  316.    OutMask -- Mask for the Transformed 1d Data
  317.    Return: return DWT_OK if successful
  318. */
  319. #ifdef _DWT_INT_
  320. Int VTCDWT:: SADWT1dOddSymInt(DWTDATA *InBuf, UChar *InMaskBuf, DWTDATA *OutBuf, 
  321.     UChar *OutMaskBuf, Int Length, FILTER *Filter, 
  322.     Int Direction)
  323. #else
  324. Int VTCDWT:: SADWT1dOddSymDbl(DWTDATA *InBuf, UChar *InMaskBuf, DWTDATA *OutBuf, 
  325.     UChar *OutMaskBuf, Int Length, FILTER *Filter, 
  326.     Int Direction)
  327. #endif
  328. {
  329.   Int i;
  330.   Int SegLength = 0;
  331.   Int odd;
  332.   Int start, end;
  333.   UChar *a, *b, *c;
  334.   Int ret;
  335.   /* double check filter class and type */
  336.   if(Filter->DWT_Class != DWT_ODD_SYMMETRIC) return(DWT_INTERNAL_ERROR);
  337. #ifdef _DWT_INT_
  338.   if(Filter->DWT_Type != DWT_INT_TYPE) return(DWT_INTERNAL_ERROR);
  339. #else
  340.   if(Filter->DWT_Type != DWT_DBL_TYPE) return(DWT_INTERNAL_ERROR);
  341. #endif
  342.   /* double check if Length is even */
  343.   if(Length & 1) return(DWT_INTERNAL_ERROR);
  344.   /* initial mask output */
  345.   for(a=InMaskBuf, b = OutMaskBuf, c= OutMaskBuf+(Length>>1); a<InMaskBuf+Length;) {
  346.     *b++ = *a++;
  347.     *c++ = *a++;
  348.   }
  349.   /* initial OutBuf to zeros */
  350.   memset(OutBuf, (UChar)0, sizeof(DWTDATA)*Length);
  351.   i = 0;
  352.   a = InMaskBuf;
  353.   while(i<Length) {
  354.     /* search for a segment */
  355.     while(i<Length && (a[i])!=DWT_IN) i++;
  356.     start = i;
  357.     if(i >= Length) break;
  358.     while(i<Length && (a[i])==DWT_IN) i++;
  359.     end = i;
  360.     
  361.     SegLength = end-start;
  362.     odd = start%2;
  363.     if(SegLength==1) { /* special case for single poInt */
  364. #ifdef _DWT_INT_
  365.       ret=DecomposeSegmentOddSymInt(InBuf+start, OutBuf+(start>>1), 
  366.     OutBuf+(Length>>1)+(start>>1), odd, 
  367.     SegLength, Filter);
  368. #else
  369.       ret=DecomposeSegmentOddSymDbl(InBuf+start, OutBuf+(start>>1), 
  370.     OutBuf+(Length>>1)+(start>>1), odd, 
  371.     SegLength, Filter);
  372. #endif
  373.       
  374.       if(ret!=DWT_OK) return(ret);
  375.       /* swap the subsampled mask for single poInt if highpass is IN */
  376.       if(Direction == DWT_HORIZONTAL) {
  377. /* After horizontal decomposition, 
  378.    LP mask symbols: IN, OUT0;
  379.    HP mask symbols: IN, OUT0, OUT1 */
  380. if(OutMaskBuf[start>>1]==DWT_OUT0) { 
  381.   OutMaskBuf[start>>1] = DWT_IN;
  382.   OutMaskBuf[(start>>1)+(Length>>1)]=DWT_OUT1;
  383. }
  384.       }
  385.       else { /* vertical */
  386. /* After vertical decomposition, 
  387.    LLP mask symbols: IN, OUT0;
  388.    LHP mask symbols: IN, OUT2, OUT3;
  389.    HLP mask symbols: IN, OUT0, OUT1;
  390.    HHP mask symbols: IN, OUT0, OUT1, OUT2, OUT3 */
  391. if(OutMaskBuf[start>>1] == DWT_OUT0) {
  392.   OutMaskBuf[(start>>1)+(Length>>1)]= DWT_OUT2 ;
  393.   OutMaskBuf[start>>1] = DWT_IN;
  394. }
  395. else if(OutMaskBuf[start>>1] == DWT_OUT1) {
  396.   OutMaskBuf[(start>>1)+(Length>>1)]= DWT_OUT3 ;
  397.   OutMaskBuf[start>>1] = DWT_IN;
  398. }
  399.       }
  400.     }
  401.     else {
  402. #ifdef _DWT_INT_
  403.       ret=DecomposeSegmentOddSymInt(InBuf+start, OutBuf+((start+1)>>1), 
  404.     OutBuf+(Length>>1)+(start>>1), odd, 
  405.     SegLength, Filter);
  406. #else
  407.       ret=DecomposeSegmentOddSymDbl(InBuf+start, OutBuf+((start+1)>>1), 
  408.     OutBuf+(Length>>1)+(start>>1), odd, 
  409.     SegLength, Filter);
  410. #endif
  411.       if(ret!=DWT_OK) return(ret);
  412.     }
  413.   }
  414.   return(DWT_OK);
  415. }
  416. /* 
  417.    Function:  DecomposeSegmentOddSymInt() or  DecomposeSegmentOddSymDbl()
  418.    Description: SA-Decompose a 1D segment based on its InitPos and Length using
  419.                 Odd-Symmetric Filters
  420.    Input:
  421.    In -- Input data segment;
  422.    PosFlag -- Start position of this segment (ODD or EVEN);
  423.    Length -- Length of this Segment;
  424.    Filter -- Filter used;
  425.    
  426.    Output:
  427.    OutL -- Low pass data;
  428.    OutH -- High pass data;
  429.    Return: Return DWT_OK if Successful
  430. */
  431. #ifdef _DWT_INT_
  432. Int VTCDWT:: DecomposeSegmentOddSymInt(DWTDATA *In, DWTDATA *OutL, DWTDATA *OutH, 
  433.      Int PosFlag, Int Length, FILTER *Filter)
  434. #else
  435. Int VTCDWT:: DecomposeSegmentOddSymDbl(DWTDATA *In, DWTDATA *OutL, DWTDATA *OutH, 
  436.      Int PosFlag, Int Length, FILTER *Filter)
  437. #endif
  438. {
  439.   /* filter coefficients */
  440. #ifdef _DWT_INT_
  441.   Short *LPCoeff = (Short *)Filter->LPCoeff, *HPCoeff = (Short *)Filter->HPCoeff; 
  442.   Short *fi;
  443. #else
  444.   double *LPCoeff = (double *)Filter->LPCoeff, *HPCoeff = (double *)Filter->HPCoeff; 
  445.   double *fi;
  446. #endif
  447.   Int ltaps = Filter->LPLength, htaps = Filter->HPLength; /* filter lengths*/
  448.   Int loffset = ltaps/2, hoffset = htaps/2;  /* Filter offset */
  449.   Int border = (ltaps>htaps)?ltaps:htaps; /*the larger of ltaps and htaps */
  450.   Int m, n;
  451.   DWTDATA *f,*pixel, *pixel1, val, *buf, *a;
  452.   Int r = Length-1;
  453.   /* prIntf("Length=%dn", Length); */
  454.   if(Length == 1) {
  455. *OutL = 0; // hjlee 0928
  456. for (m=0; m<ltaps;m++)
  457. *OutL += *In * (*(LPCoeff+m)); 
  458.     /* *OutL = *In * Filter->Scale; */
  459.     return (DWT_OK);
  460.   }
  461.   /* allocate proper buffer */
  462.   buf = (DWTDATA *) malloc((Length+2*border)*sizeof(DWTDATA));
  463.   if(buf==NULL)  return(DWT_MEMORY_FAILED);
  464.   /* now symmetric extend this segment */
  465.   a = buf+border;
  466.   for(m=0;m< Length; m++) {
  467.     a[m] = In[m];
  468.     /* prIntf("%f ", a[m]); */
  469.   }
  470.   /* prIntf("n"); */
  471.   /* symmetric extension */
  472.   for (m=1 ; m<=border; m++)
  473.   {
  474.     a[-m] =  a[m];  /* to allow Shorter seg */
  475.     a[r+m] = a[r-m]; 
  476.   }
  477.   f = buf + border + Length;
  478.   /* always subsample even positions in a line for LP coefficents */
  479.   if (PosFlag==DWT_ODD) a = buf + border + 1;
  480.   else a = buf + border;
  481.   for (; a<f; a +=2)
  482.   {
  483.     /* filter the pixel with lowpass filter */
  484.     for( fi=LPCoeff, pixel=a-loffset, pixel1=pixel+ltaps-1,val=0, n=0; 
  485.  n<(ltaps>>1); 
  486.  n++, fi++, pixel++, pixel1--)
  487.       val += (*fi * (*pixel + *pixel1)); /* symmetric */
  488.     val += (*fi * *pixel);
  489.     *OutL++ = val;
  490.   }
  491.   /* always  subsample odd positions in a line for HP coefficients */
  492.   if (PosFlag==DWT_ODD) a = buf + border;
  493.   else a = buf + border+1;
  494.   for (; a<f; a +=2)
  495.     {
  496.       /* filter the pixel with highpass filter */
  497.       for(fi=HPCoeff, pixel=a-hoffset, pixel1 = pixel+htaps-1, val=0, n=0; 
  498.   n<(htaps>>1); 
  499.   n++, fi++, pixel++, pixel1--)
  500. val += (*fi *  (*pixel + *pixel1));  /* symmetric */
  501.       val += (*fi * *pixel);
  502.       *OutH++ = val;
  503.     }
  504.   free(buf);
  505.   return(DWT_OK);
  506. }
  507. /* Function: SADWT1dEvenSymInt() or SADWT1dEvenSymDbl()
  508.    Description: 1D  SA-DWT using Even Symmetric Filter
  509.    Input:
  510.    InBuf -- Input 1d data buffer
  511.    InMaskBuf -- Input 1d mask buffer
  512.    Length -- length of the input data
  513.    Filter -- filter used
  514.    Direction -- vertical or horizontal decomposition (used for inversible 
  515.    mask decomposition)
  516.    Output:
  517.    
  518.    OutBuf -- Transformed 1d Data
  519.    OutMask -- Mask for the Transformed 1d Data
  520.    Return: return DWT_OK if successful
  521. */
  522. #ifdef _DWT_INT_
  523. Int VTCDWT:: SADWT1dEvenSymInt(DWTDATA *InBuf, UChar *InMaskBuf, DWTDATA *OutBuf, 
  524.      UChar *OutMaskBuf, Int Length, FILTER *Filter, 
  525.      Int Direction)
  526. #else
  527. Int VTCDWT:: SADWT1dEvenSymDbl(DWTDATA *InBuf, UChar *InMaskBuf, DWTDATA *OutBuf, 
  528.      UChar *OutMaskBuf, Int Length, FILTER *Filter, 
  529.      Int Direction)
  530. #endif
  531. {
  532.   Int i;
  533.   Int SegLength = 0;
  534.   Int odd;
  535.   Int start, end;
  536.   UChar *a, *b, *c;
  537.   Int ret;
  538.   /* double check filter class and type */
  539.   if(Filter->DWT_Class != DWT_EVEN_SYMMETRIC) return(DWT_INTERNAL_ERROR);
  540. #ifdef _DWT_INT_
  541.   if(Filter->DWT_Type != DWT_INT_TYPE)  return(DWT_INTERNAL_ERROR);
  542. #else
  543.   if(Filter->DWT_Type != DWT_DBL_TYPE)  return(DWT_INTERNAL_ERROR);
  544. #endif
  545.   /* double check if Length is even */
  546.   if(Length & 1) return(DWT_INTERNAL_ERROR);
  547.   /* initial mask output */
  548.   for(a=InMaskBuf, b = OutMaskBuf, c= OutMaskBuf+(Length>>1); a<InMaskBuf+Length;) {
  549.     *b++ = *a++;
  550.     *c++ = *a++;
  551.   }
  552.   /* initial OutBuf to zeros */
  553.   memset(OutBuf, (UChar)0, sizeof(DWTDATA)*Length);
  554.   
  555.   i = 0;
  556.   a = InMaskBuf;
  557.   while(i<Length) {
  558.     /* search for a segment */
  559.     while(i<Length && (a[i])!=DWT_IN) i++;
  560.     start = i;
  561.     if(i >= Length) break;
  562.     while(i<Length && (a[i])==DWT_IN) i++;
  563.     end = i;
  564.     SegLength = end-start;
  565.     odd = start%2;
  566.     if(SegLength==1) { /* special case for single poInt */
  567. #ifdef _DWT_INT_
  568.       ret=DecomposeSegmentEvenSymInt(InBuf+start, OutBuf+(start>>1), 
  569.      OutBuf+(Length>>1)+(start>>1), odd, 
  570.      SegLength, Filter);
  571. #else
  572.       ret=DecomposeSegmentEvenSymDbl(InBuf+start, OutBuf+(start>>1), 
  573.      OutBuf+(Length>>1)+(start>>1), odd, 
  574.      SegLength, Filter);
  575. #endif
  576.       if(ret!=DWT_OK) return(ret);
  577.  
  578.     }
  579.     else {
  580. #ifdef _DWT_INT_
  581.       ret=DecomposeSegmentEvenSymInt(InBuf+start, OutBuf+(start>>1), 
  582.      OutBuf+(Length>>1)+((start+1)>>1), odd, 
  583.      SegLength, Filter);
  584. #else
  585.       ret=DecomposeSegmentEvenSymDbl(InBuf+start, OutBuf+(start>>1), 
  586.      OutBuf+(Length>>1)+((start+1)>>1), odd, 
  587.      SegLength, Filter);
  588. #endif
  589.       if(ret!=DWT_OK) return(ret);
  590.     }
  591.     /* swap the subsampled mask for the start of segment if it is odd*/
  592.     if(odd) {
  593.       if(Direction == DWT_HORIZONTAL) {
  594. /* After horizontal decomposition, 
  595.    LP mask symbols: IN, OUT0;
  596.    HP mask symbols: IN, OUT0, OUT1 */
  597. if(OutMaskBuf[start>>1]==DWT_OUT0) { 
  598.   OutMaskBuf[start>>1] = DWT_IN;
  599.   OutMaskBuf[(start>>1)+(Length>>1)]=DWT_OUT1;
  600. }
  601.       }
  602.       else { /* vertical */
  603. /* After vertical decomposition, 
  604.    LLP mask symbols: IN, OUT0;
  605.    LHP mask symbols: IN, OUT2, OUT3;
  606.    HLP mask symbols: IN, OUT0, OUT1;
  607.    HHP mask symbols: IN, OUT0, OUT1, OUT2, OUT3 */
  608. if(OutMaskBuf[start>>1] == DWT_OUT0) {
  609.   OutMaskBuf[(start>>1)+(Length>>1)]= DWT_OUT2 ;
  610.   OutMaskBuf[start>>1] = DWT_IN;
  611. }
  612. else if(OutMaskBuf[start>>1] == DWT_OUT1) {
  613.   OutMaskBuf[(start>>1)+(Length>>1)]= DWT_OUT3 ;
  614.   OutMaskBuf[start>>1] = DWT_IN;
  615. }
  616.       }
  617.     }
  618.   }
  619.   return(DWT_OK);
  620. }
  621. /* 
  622.    Function:  DecomposeSegmentEvenSymInt() or DecomposeSegmentEvenSymDbl()
  623.    Description: SA-Decompose a 1D segment based on its InitPos and Length using
  624.                 Even-Symmetric Filters
  625.    Input:
  626.    In -- Input data segment;
  627.    PosFlag -- Start position of this segment (ODD or EVEN);
  628.    Length -- Length of this Segment;
  629.    Filter -- Filter used;
  630.    
  631.    Output:
  632.    OutL -- Low pass data;
  633.    OutH -- High pass data;
  634.    Return: Return DWT_OK if Successful
  635. */
  636. #ifdef _DWT_INT_
  637. Int VTCDWT:: DecomposeSegmentEvenSymInt(DWTDATA *In, DWTDATA *OutL, DWTDATA *OutH, 
  638.       Int PosFlag, Int Length, FILTER *Filter)
  639. #else
  640. Int VTCDWT:: DecomposeSegmentEvenSymDbl(DWTDATA *In, DWTDATA *OutL, DWTDATA *OutH, 
  641.       Int PosFlag, Int Length, FILTER *Filter)
  642. #endif
  643. {
  644.   /* filter coefficients */
  645. #ifdef _DWT_INT_
  646.   Short *LPCoeff = (Short *)Filter->LPCoeff, *HPCoeff = (Short *)Filter->HPCoeff; 
  647.   Short *fi;
  648. #else
  649.   double *LPCoeff = (double *)Filter->LPCoeff, *HPCoeff = (double *)Filter->HPCoeff; 
  650.   double *fi; 
  651. #endif
  652.   Int ltaps = Filter->LPLength, htaps = Filter->HPLength; /* filter lengths*/
  653.   Int loffset = ltaps/2-1, hoffset = htaps/2-1;  /* Filter offset */
  654.   Int border = (ltaps>htaps)?ltaps:htaps; /*the larger of ltaps and htaps */
  655.   Int m, n;
  656.   DWTDATA *f,*pixel, *pixel1, val, *buf, *a;
  657.   Int r = Length-1;
  658.   if(Length == 1) {
  659. *OutL = 0;  // hjlee 0928
  660. for (m=0;m<ltaps; m++)
  661. *OutL += *In * (*(LPCoeff+m));  // hjlee 0928
  662.     /* *OutL = *In * Filter->Scale; */
  663.     return (DWT_OK);
  664.   }
  665.   /* allocate proper buffer */
  666.   buf = (DWTDATA *) malloc((Length+2*border)*sizeof(DWTDATA));
  667.   if(buf==NULL)  return(DWT_MEMORY_FAILED);
  668.   /* now symmetric extend this segment */
  669.   a = buf+border;
  670.   for(m=0;m< Length; m++) {
  671.     a[m] = In[m];
  672.   }
  673.   /* symmetric extension */
  674.   for (m=1 ; m<=border; m++)
  675.   {
  676.     a[-m] =  a[m-1];  /* to allow Shorter seg */
  677.     a[r+m] = a[r-m+1]; 
  678.   }
  679.   f = buf + border + Length;
  680.   /* always subsample even positions in a line for LP coefficents */
  681.   if (PosFlag==DWT_ODD) a = buf + border - 1;
  682.   else a = buf + border;
  683.   for (; a<f; a +=2)
  684.   {
  685.     /* filter the pixel with lowpass filter */
  686.     for( fi=LPCoeff, pixel=a-loffset, pixel1=pixel+ltaps-1, val=0, n=0; 
  687.  n<(ltaps>>1); 
  688.  n++, fi++, pixel++, pixel1--)
  689.       val += (*fi * (*pixel + *pixel1));  /* symmetric */
  690.     *OutL++ = val;
  691.   }
  692.   /* always  subsample even positions in a line for HP coefficients */
  693.   if (PosFlag==DWT_ODD) a = buf + border +1;
  694.   else a = buf + border;
  695.   for (; a<f; a +=2)
  696.     {
  697.       /* filter the pixel with highpass filter */
  698.       for(fi=HPCoeff, pixel=a-hoffset, pixel1 = pixel+htaps-1, val=0, n=0; 
  699.   n<(htaps>>1); 
  700.   n++, fi++, pixel++, pixel1--)
  701. val += (*fi *  (*pixel - *pixel1)); /* antisymmetric */
  702.       *OutH++ = val;
  703.   }
  704.   free(buf);
  705.   return(DWT_OK);
  706. }
  707. #ifdef _DWT_INT_
  708. #undef _DWT_INT_
  709. #define _DWT_DBL_
  710. #include "dwt_aux.cpp"
  711. #endif