#include "tree-vect.h"

extern double sqrt (double);
extern double fabs (double);
extern double ceil (double);
extern double floor (double);

extern void abort (void);

#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

typedef struct {
    int initialHeight, initialWidth;
    int rotatedHeight, rotatedWidth;
    int autoCropHeight, autoCropWidth;
} ufraw_data;

void __attribute__((noinline,noclone))
ufraw_test(ufraw_data *uf)
{
  int iWidth = uf->initialWidth;
  int iHeight = uf->initialHeight;
  double aspectRatio = ((double)iWidth) / iHeight;
  double midX = iWidth / 2.0 - 0.5;
  double midY = iHeight / 2.0 - 0.5;
  double maxX = 0, maxY = 0;
  double minX = 999999, minY = 999999;
  double lastX = 0, lastY = 0, area = 0;
  double scale;
  int i;
  for (i = 0; i < iWidth + iHeight - 1; i++)
    {
      int x, y;
      if (i < iWidth) { // Trace the left border of the image
	  x = i;
	  y = 0;
      } else { // Trace the bottom border of the image
	  x = iWidth - 1;
	  y = i - iWidth + 1;
      }
      double srcX = x - midX;
      double srcY = y - midY;
      // A digital planimeter:
      area += srcY * lastX - srcX * lastY;
      lastX = srcX;
      lastY = srcY;
      maxX = MAX(maxX, fabs(srcX));
      maxY = MAX(maxY, fabs(srcY));
      if (fabs(srcX / srcY) > aspectRatio)
	minX = MIN(minX, fabs(srcX));
      else
	minY = MIN(minY, fabs(srcY));
    }
  scale = sqrt((iWidth - 1) * (iHeight - 1) / area);
  uf->rotatedWidth = MIN(ceil(2 * maxX + 1.0) * scale, 2 * iWidth);
  uf->rotatedHeight = MIN(ceil(2 * maxY + 1.0) * scale, 2 * iHeight);
  uf->autoCropWidth = MIN(floor(2 * minX) * scale, 2 * iWidth);
  uf->autoCropHeight = MIN(floor(2 * minY) * scale, 2 * iHeight);
  if (uf->autoCropWidth != 3)
    abort ();
}

int main()
{
  ufraw_data uf_data;
  ufraw_data *uf = &uf_data;
  check_vect ();
  uf->initialWidth = 4;
  uf->initialHeight = 5;
  ufraw_test(uf);
  return 0;
}

