@Override
   public void subSample(int[] input, int[] output) 
   {
      int offs = this.offset;
      final int h = this.height;
      final int w = this.width;
      final int st = this.stride;
      final int[] buf1 = this.buffer1;
      final int[] buf2 = this.buffer2;
      final int count = this.dim * this.dim;
      final SliceIntArray src = new SliceIntArray(buf1, 0);
      final SliceIntArray dst = new SliceIntArray(buf2, 0);
      final int step = this.dim;
      final int stStep = st * step;
      final int count4 = count >> 2;

      for (int y=0; y<h; y+=step)
      {
         for (int x=0; x<w; x+=step)
         {
            int n = 0;
            int iOffs = offs;

            // Fill buf(dim x dim) from input at x,y
            for (int j=0; j<step; j++)
            {                    
               for (int i=0; i<step; i+=8)
               {
                  final int idx = iOffs + x + i;
                  buf1[n]   = input[idx];
                  buf1[n+1] = input[idx+1];
                  buf1[n+2] = input[idx+2];
                  buf1[n+3] = input[idx+3];
                  buf1[n+4] = input[idx+4];
                  buf1[n+5] = input[idx+5];
                  buf1[n+6] = input[idx+6];
                  buf1[n+7] = input[idx+7];
                  n += 8;   
               }
               
               iOffs += st;
            }
            
            src.index = 0;
            dst.index = 0;
            src.length = count;
            this.fdct.forward(src, dst);
           
            // Pack and clear DCT high frequency bands (3/4 coefficients)
            for (int i=count4; i<count; i++)
               buf1[i] = 0;

            for (int i=0; i<count4; i++)
               buf1[i] = buf2[this.scan[i]];
            
            src.index = 0;
            dst.index = 0;
            src.length = count4;
            this.idct.inverse(src, dst);
            int oOffs = (offs >> 2) + (x >> 1);
            n = 0;
          
            // Fill output at x,y from buf(dim/2 x dim/2)
            for (int j=0; j+j<step; j++)
            {
               for (int i=0; i+i<step; i++, n++)
               {
                  final int val = buf2[n];
                  output[oOffs+i] = (val >= 255) ? 255 : val & ~(val>>31); 
               }
                  
               oOffs += (st >> 1);
            }           
         }
         
         offs += stStep;
      }
   }