public void lossyFilterTriple(int lim) {
    System.out.println("Determinating filters and applying lossy filter...");
    long initTime = System.currentTimeMillis();
    lossy = lim;
    if (lineFilter == null) { filterDeterminate(); }
    int slim = 1 << (lim - 1);
    int mod = (1 << lim) + 1;
    int exL = mod - 1;
    int exH = 255 - exL;
    int thisval = 0;
    int err = 0;
    int val, fv, filVal, r;
    int c255 = 0;
    for (int i2 = 0; i2 < biHeight; i2 ++) {
      for (int i = 0; i < biWidth; i ++) {
        for (int i3 = 0; i3 < 3; i3 ++) {
          image.setPoint(i, i2, i3);
          val = image.getIntCurVal();
          fv = filter(i, i2, i3);
          if (fv < 0) { fv += 256; }
          filVal = val - fv;
          r = filVal % mod;
          if (filVal > 0) {
            if (r <= slim) {
              val -= r;
              err += r;
            }
            else {
              val += (mod - r);
              err += (mod - r);
            }
          } else {
            if (-r <= slim) {
              val -= r;
              err -= r;
            }
            else {
              val -= (mod + r);
              err += (mod + r);
            }
          }
          if (val > 255) { val = 255; c255 += 1;}
          image.setCurVal((byte)val);
        }
      }
    }
    System.out.println("Medium lossy filter introduced error is " + (float)err / (biWidth * biHeight * 3) + " per byte");
    System.out.println("Filter determination and lossy filter applying time is " +
                       (System.currentTimeMillis() - initTime) + " ms. ");
  }