public int estimateLimits(long size1, long size2)
 {
  if (0 > size1 || 0 > size2)
   throw new IllegalArgumentException("Negative image size: " + (0 > size1 ? size1 : size2));
  // make size1 the smaller
  if (size1 > size2)
  {
   long temp = size1;
   size1 = size2;
   size2 = temp;
  }
  // size limit: larger image size
  setSizeLimit(size2);
  // memory limit: determine availability
  memoryLimit = 0L;
  long available = getMemoryLimit();
  long ibsize = available >> 3;
  // adjust to smaller size
  if (size1 < ibsize)
   ibsize = size1;
  // adjust to larger size
  if (size2 >> 1 < ibsize)
   ibsize = size2 >> 1;
  // multiply by 3/4
  if (Long.MAX_VALUE / 3 > ibsize)
   ibsize *= 3;
  else
   ibsize = Long.MAX_VALUE;
  ibsize >>= 2;
  // add HORIZON_INCREMENT
  ibsize += HORIZON_INCREMENT;
  // apply constraints
  if (BUFFER_SIZE > ibsize)
   ibsize = BUFFER_SIZE;
  else if (Integer.MAX_VALUE < ibsize)
   ibsize = Integer.MAX_VALUE;
  // update the memory limit
  setMemoryLimit(available - 2 * (ibsize + ByteInputStream.OVERHEAD));
  return (int)ibsize;
 }