www.pudn.com > scaling.rar > scale_vert_h.h


/* ======================================================================== */ 
/*  TEXAS INSTRUMENTS, INC.                                                 */ 
/*                                                                          */ 
/*  NAME                                                                    */ 
/*      scale_vert                                                          */ 
/*                                                                          */ 
/*  USAGE                                                                   */ 
/*      This routine is C-callable and can be called as:                    */ 
/*                                                                          */ 
/*          void scale_vert                                                 */ 
/*          (                                                               */ 
/*              short *in_cols,     // Input image (16-bit pixels)      //  */ 
/*              int    cols,        // Width of the image.              //  */ 
/*              short *out_cols,    // Output image (16-bit pixels)     //  */ 
/*              short *ptr_hh,      // Pointer to filter taps.          //  */ 
/*              short *mod_hh,      // Pointer to rotated filter taps.  //  */ 
/*              int    l_hh,        // Taps per filter (multiple of 4)  //  */ 
/*              int    start_line   // Starting position for filter.    //  */ 
/*          )                                                               */ 
/*                                                                          */ 
/*  DESCRIPTION                                                             */ 
/*      Performs a vertical scaling function on a block of data from a      */ 
/*      frame store.  It uses a scaling filter decided upon by the          */ 
/*      calling function.  The filter is rotated depending on the           */ 
/*      starting line of the circular buffer.  One line of length           */ 
/*      'cols' is produced per function call.  The same filter runs         */ 
/*      along the entire length of buffer and perfoms the filter            */ 
/*      vertically along each set of parallel data points.                  */ 
/*                                                                          */ 
/*      void scale_vert                                                     */ 
/*      (                                                                   */ 
/*          short *ptr_plane_x,                                             */ 
/*          short *ptr_plane_y,                                             */ 
/*          int   n_x,                                                      */ 
/*          short *ptr_hh,                                                  */ 
/*          short *mod_hh,                                                  */ 
/*          int   l_hh,                                                     */ 
/*          int   start_line                                                */ 
/*      )                                                                   */ 
/*      {                                                                   */ 
/*          int     taps_count, sample, i, j, ka;                           */ 
/*          int     max_filt, y0, y1, y2, y3, block;                        */ 
/*          int     t_y0, t_y1, t_y2, t_y3;                                 */ 
/*          short   h0, h1, x0, x1, x2, x3, x01, x11, x21, x31;             */ 
/*          short * ptr_line0_x, * ptr_line1_x;                             */ 
/*          short * ptr_line2_x, * ptr_line3_x;                             */ 
/*          short * ptr_line0_x1, * ptr_line1_x1;                           */ 
/*          short * ptr_line2_x1, * ptr_line3_x1;                           */ 
/*          short * ptr_line0_y,  * filter;                                 */ 
/*                                                                          */ 
/*          taps_count = l_hh - 2;                                          */ 
/*                                                                          */ 
/*          ptr_line0_x = ptr_plane_x;                                      */ 
/*          ptr_line0_y = ptr_plane_y;                                      */ 
/*                                                                          */ 
/*          y0 = 0x0; y1 = 0x0;                                             */ 
/*          y2 = 0x0; y3 = 0x0;                                             */ 
/*                                                                          */ 
/*          max_filt = n_x*l_hh;                                            */ 
/*                                                                          */ 
/*          // if we know the pointer will need to wrap around, a positive  */ 
/*          correction is needed instead of a negative one //               */ 
/*                                                                          */ 
/*          block = n_x*l_hh;                                               */ 
/*          block = block - 4;      // next column on //                    */ 
/*                                                                          */ 
/*          if (!start_line) start_line = l_hh;                             */ 
/*          filter = &ptr_hh[l_hh-start_line];                              */ 
/*          j = start_line;                                                 */ 
/*          for (i = 0; i < l_hh; i++)                                      */ 
/*          {                                                               */ 
/*              mod_hh[i] = *filter++;                                      */ 
/*              j--;                                                        */ 
/*              if (!j) filter= ptr_hh;                                     */ 
/*              if (!j) j = l_hh;                                           */ 
/*          }                                                               */ 
/*          filter = mod_hh;                                                */ 
/*          ka = 0;                                                         */ 
/*                                                                          */ 
/*          ptr_line1_x = ptr_line0_x+1;                                    */ 
/*          ptr_line2_x = ptr_line1_x+1;                                    */ 
/*          ptr_line3_x = ptr_line2_x+1;                                    */ 
/*                                                                          */ 
/*          ptr_line0_x1 = ptr_line0_x+n_x ;                                */ 
/*          ptr_line1_x1 = ptr_line0_x1+1 ;                                 */ 
/*          ptr_line2_x1 = ptr_line1_x1+1 ;                                 */ 
/*          ptr_line3_x1 = ptr_line2_x1+1 ;                                 */ 
/*                                                                          */ 
/*          for ( i = 0; i < max_filt; i+=8)                                */ 
/*          {                                                               */ 
/*              h0 = *filter++;                                             */ 
/*              h1 = *filter++;                                             */ 
/*                                                                          */ 
/*              x0 = ptr_line0_x[ka];                                       */ 
/*              x1 = ptr_line1_x[ka];                                       */ 
/*              x2 = ptr_line2_x[ka];                                       */ 
/*              x3 = ptr_line3_x[ka];                                       */ 
/*                                                                          */ 
/*              x01 = ptr_line0_x1[ka];                                     */ 
/*              x11 = ptr_line1_x1[ka];                                     */ 
/*              x21 = ptr_line2_x1[ka];                                     */ 
/*              x31 = ptr_line3_x1[ka];                                     */ 
/*              ka += 2*n_x;                                                */ 
/*                                                                          */ 
/*              sample = taps_count ;                                       */ 
/*                                                                          */ 
/*              if (!taps_count) filter = mod_hh;                           */ 
/*              if (!taps_count) ka = ka - block;                           */ 
/*              if (!taps_count) taps_count = l_hh ;                        */ 
/*                                                                          */ 
/*              // 2 taps have been used, for 1 point //                    */ 
/*              taps_count -= 2;                                            */ 
/*                                                                          */ 
/*              y0 += (x0*h0 + x01*h1) ;                                    */ 
/*              y1 += (x1*h0 + x11*h1) ;                                    */ 
/*              y2 += (x2*h0 + x21*h1) ;                                    */ 
/*              y3 += (x3*h0 + x31*h1) ;                                    */ 
/*                                                                          */ 
/*              t_y0 = y0 >> 16; t_y1 = y1 >> 16;                           */ 
/*              t_y2 = y2 >> 16; t_y3 = y3 >> 16;                           */ 
/*                                                                          */ 
/*              if (!sample) y0 = 0x0; if (!sample) y1 = 0x0;               */ 
/*              if (!sample) y2 = 0x0; if (!sample) y3 = 0x0;               */ 
/*                                                                          */ 
/*              if (!sample) *ptr_line0_y++ = t_y0;                         */ 
/*              if (!sample) *ptr_line0_y++ = t_y1;                         */ 
/*              if (!sample) *ptr_line0_y++ = t_y2;                         */ 
/*              if (!sample) *ptr_line0_y++ = t_y3;                         */ 
/*          }                                                               */ 
/*      }                                                                   */ 
/*                                                                          */ 
/*  ASSUMPTIONS                                                             */ 
/*      'l_hh' must be divisible by 4.  Pad with zeros for non % 4.         */ 
/*                                                                          */ 
/*      All data must be double word aligned.                               */ 
/*                                                                          */ 
/*      Input and output, mod_hh, ptr_hh, cols must be multiple of 8.       */ 
/*                                                                          */ 
/*      Input filters, hh, must be 12 bit precision.                        */ 
/*                                                                          */ 
/*      The data is in LITTLE ENDIAN format.                                */ 
/*                                                                          */ 
/*      The code is uninterruptable during execution.  Interrupts are       */ 
/*      disabled at the beginning and reenabled at the end.                 */ 
/*                                                                          */ 
/*  TECHNIQUES                                                              */ 
/*      Inner and outer loops are collapsed into 1 loop.                    */ 
/*                                                                          */ 
/*      A load store live too long problem is dealt with using a MPY.       */ 
/*                                                                          */ 
/*      The filter loop is unrolled 4 times with l_hh % 4 == 0.             */ 
/*                                                                          */ 
/*      The output data stores are packed together into words and the       */ 
/*      outer loop is unrolled 8 times to allow 8 parallel filters to       */ 
/*      be convolved at once.                                               */ 
/*                                                                          */ 
/*  NOTES                                                                   */ 
/*      Before calling this function the input data needs to be in Q11      */ 
/*      form. (It is generally the output from the horizontal scaling       */ 
/*      function, scale_horz.)  The results from this function must be      */ 
/*      clipped before displaying as some pixels may go < 0 or > 255.       */ 
/*                                                                          */ 
/*  MEMORY NOTE                                                             */ 
/*      No bank hits occur in this code.                                    */ 
/*                                                                          */ 
/*  CYCLES                                                                  */ 
/*      Formula for execution time:                                         */ 
/*      cycles = (5 * l_hh * cols) / 16  + 6 * l_hh + 32                    */ 
/*      For cols = 800 and l_hh = 4, cycles = 1056.                         */ 
/*                                                                          */ 
/*  CODESIZE                                                                */ 
/*      612 bytes                                                           */ 
/* ------------------------------------------------------------------------ */ 
/*            Copyright (c) 2000 Texas Instruments, Incorporated.           */ 
/*                           All Rights Reserved.                           */ 
/* ======================================================================== */ 
                        void scale_vert_asm 
                        ( 
                            short *ptr_plane_x,  
                            short *ptr_plane_y,  
                            int    n_x,   
                            short *ptr_hh,  
                            short *mod_hh,  
                            int    l_hh, 
                            int    start_line 
                        ); 
/* ======================================================================== */ 
/*  End of file:  scale_vert_h.h                                            */ 
/* ------------------------------------------------------------------------ */ 
/*            Copyright (c) 2000 Texas Instruments, Incorporated.           */ 
/*                           All Rights Reserved.                           */ 
/* ======================================================================== */