public ImagePyramid(ImageBuffer base) {
      pyramid[0] = new ImageBuffer(base.width + 1, base.height + 1);
      for (int y = 0; y < base.height; y++)
         for (int x = 0; x < base.width; x++)
            pyramid[0].pix[x + y * pyramid[0].width] = base.pix[x + y * base.width];

      for (int level = 1; level < pyramid.length; level++) {

         ImageBuffer parent = pyramid[level - 1];
         int w = parent.getWidth() - 1;
         int h = parent.getHeight() - 1;
         if (w <= 1 || h <= 1)
            break;

         ImageBuffer tmp = new ImageBuffer(w, h / 2 + 1);
         for (int x = 0; x <= w; x++)
            for (int y = 0; y < h; y += 2) {
               int A = parent.get(x, y - 1), B = parent.get(x, y), C = parent.get(x, y + 1), D = parent.get(x, y + 2);
               tmp.set(x, y >> 1, pack(unpack(A, 3) + 3 * (unpack(B, 3) + 3 * unpack(C, 3)) + unpack(D, 3) >> 3,
	                               unpack(A, 2) + 3 * (unpack(B, 2) + 3 * unpack(C, 2)) + unpack(D, 2) >> 3,
	                               unpack(A, 1) + 3 * (unpack(B, 1) + 3 * unpack(C, 1)) + unpack(D, 1) >> 3,
				       unpack(A, 0) + 3 * (unpack(B, 0) + 3 * unpack(C, 0)) + unpack(D, 0) >> 3));
            }

         pyramid[level] = new ImageBuffer(w / 2 + 1, h / 2 + 1);
         for (int x = 0; x <= w; x += 2)
            for (int y = 0; y <= h / 2; y++) {
               int A = tmp.get(x - 1, y), B = tmp.get(x, y), C = tmp.get(x + 1, y), D = tmp.get(x + 2, y);
               pyramid[level].set(x >> 1, y, pack(unpack(A, 3) + 3 * (unpack(B, 3) + 3 * unpack(C, 3)) + unpack(D, 3) >> 3,
	                                          unpack(A, 2) + 3 * (unpack(B, 2) + 3 * unpack(C, 2)) + unpack(D, 2) >> 3,
	                                          unpack(A, 1) + 3 * (unpack(B, 1) + 3 * unpack(C, 1)) + unpack(D, 1) >> 3,
					          unpack(A, 0) + 3 * (unpack(B, 0) + 3 * unpack(C, 0)) + unpack(D, 0) >> 3));
            }
      }
   }