@Override
    public boolean apply(SliceIntArray input, SliceIntArray output)
    {
        if ((!SliceIntArray.isValid(input)) || (!SliceIntArray.isValid(output)))
           return false;
      
        final int[] src = input.array;
        final int[] dst = output.array;
        final int nbChans = this.channels >> 8;
        final int maxShift = this.channels & 0xFF;
        final int h = this.height;
        final int w = this.width;
        final int st = this.stride;

        for (int i=0; i<nbChans; i++)
        {
            int srcStart = input.index;
            int dstStart = output.index;
            final int shift = maxShift - 8*i;
            
            for (int y=h-2; y>0; y--)
            {
               final int srcLine = srcStart + st;
               final int endLine = srcLine + st;
               final int dstLine = dstStart + st;
               final int pixel01 = src[srcStart+1];
               final int pixel10 = src[srcLine];
               final int pixel11 = src[srcLine+1];
               final int pixel21 = src[endLine+1];
               int val01 = (pixel01 >> shift) & 0xFF;
               int val10 = (pixel10 >> shift) & 0xFF;
               int val11 = (pixel11 >> shift) & 0xFF;
               int val21 = (pixel21 >> shift) & 0xFF;

               for (int x=2; x<w; x++)
               {
                 final int pixel02 = src[srcStart+x];
                 final int pixel12 = src[srcLine+x];
                 final int pixel22 = src[endLine+x];
                 int val02 = (pixel02 >> shift) & 0xFF;
                 int val12 = (pixel12 >> shift) & 0xFF;
                 int val22 = (pixel22 >> shift) & 0xFF;
                 int val = - val01 - val10 + 5*val11 - val21 - val12; 
                 val &= ~(val >> 31); 
                 dst[dstLine+x-1] &= ~(255 << shift);
                 dst[dstLine+x-1] |= (val >= 255) ? 255<<shift : val<<shift;

                 // Slide the 3x3 window (reassign 6 pixels: left + center columns)
                 val01 = val02;
                 val10 = val11;
                 val11 = val12;
                 val21 = val22;
              }

              if (this.processBoundaries == true)
              {
                 // Boundary processing (first and last row pixels), just duplicate pixels
                 dst[dstLine] = dst[dstLine+1];
                 dst[dstLine+w-1] = dst[dstLine+w-2];
              }

              srcStart = srcLine;
              dstStart = dstLine;
           }
       }

       final int firstLine = output.index;
       final int lastLine = output.index + st * (h - 1);

       if (this.processBoundaries == true)
       {
          // Duplicate first and last lines
          System.arraycopy(dst, firstLine+st, dst, firstLine, w);
          System.arraycopy(dst, lastLine-st, dst, lastLine, w);
       }

       return true;
    }