示例#1
0
static void 
findpack(struct pam * const imgs,
         unsigned int const imgCt,
         Coord **     const coordsP,
         unsigned int const quality,
         unsigned int const qfactor) {

    Coord * coords;  /* malloc'ed array */
    unsigned int minarea;
    unsigned int i;
    unsigned int rdiv;
    unsigned int cdiv;
    Rectangle * current;  /* malloc'ed array */
    unsigned int z;
    Coord c;

    MALLOCARRAY(coords, imgCt);
  
    if (!coords)
        pm_error("Out of memory allocating %u-element coords array", imgCt);

    z = UINT_MAX;  /* initial value */
    c.x = 0; c.y = 0;  /* initial value */

    if (quality > 1) {
        unsigned int realMinarea;
        for (realMinarea = i = 0; i < imgCt; ++i)
            realMinarea += imgs[i].height * imgs[i].width;
        minarea = realMinarea * qfactor / 100;
    } else
        minarea = UINT_MAX - 1;

    /* It's relatively easy to show that, if all the images
     * are multiples of a particular size, then a best
     * packing will always align the images on a grid of
     * that size.
     *
     * This speeds computation immensely.
     */
    for (rdiv = imgs[0].height, i = 1; i < imgCt; ++i)
        rdiv = gcf(imgs[i].height, rdiv);

    for (cdiv = imgs[0].width, i = 1; i < imgCt; ++i)
        cdiv = gcf(imgs[i].width, cdiv);

    MALLOCARRAY(current, imgCt);

    for (i = 0; i < imgCt; ++i) {
        current[i].size.x = imgs[i].width;
        current[i].size.y = imgs[i].height;
    }
    recursefindpack(current, c, coords, minarea, &z, 0, imgCt, cdiv, rdiv,
                    quality, qfactor);

    free(current);

    *coordsP = coords;
}
示例#2
0
static void 
recursefindpack(Rectangle *    const current,
                Coord          const currentsz,
                Coord *        const best,
                unsigned int   const minarea,
                unsigned int * const maxareaP, 
                unsigned int   const depth,
                unsigned int   const n,
                unsigned int   const xinc,
                unsigned int   const yinc,
                unsigned int   const quality,
                unsigned int   const qfactor) {

    if (depth == n) {
        if (currentsz.x * currentsz.y < *maxareaP) {
            unsigned int i;
            for (i = 0; i < n; ++i)
                best[i] = current[i].ul;
            *maxareaP = currentsz.x * currentsz.y;
        }
    } else {
        unsigned int i;

        Rectangle * const newP = &current[depth];

        for (i = 0; ; ++i) {
            for (newP->ul.x = 0, newP->ul.y = i * yinc;
                 newP->ul.y <= i * yinc;) {

                Coord c;

                c.x = MAX(lr(*newP).x, currentsz.x);
                c.y = MAX(lr(*newP).y, currentsz.y);
                pm_message("current = (%u.%u, %u.%u) new = (%u.%u, %u.%u)",
                           current[0].ul.x, current[0].size.x,
                           current[0].ul.y, current[0].size.y,
                           newP->ul.x,   newP->size.x,
                           newP->ul.y,   newP->size.y);
                if (!collides(*newP, current, depth)) {
                    pm_message("Depth %u: Doesn't collide at i=%u", depth,i);
                    recursefindpack(current, c, best, minarea, maxareaP,
                                    depth + 1, n, xinc, yinc,
                                    quality, qfactor);
                    if (*maxareaP <= minarea)
                        return;
                }
                if (newP->ul.x == (i - 1) * xinc)
                    newP->ul.y = 0;
                if (newP->ul.x < i * xinc)
                    newP->ul.x += xinc;
                else
                    newP->ul.y += yinc;
            }
        }
    }
}
示例#3
0
static void 
findpack(struct pam *imgs, int n, coord *coords)
{
  int minarea;
  int i;
  int rdiv;
  int cdiv;
  int minx = -1;
  int miny = -1;
  coord *current;
  coord *set;
  int z = INT_MAX;
  coord c = { 0, 0 };

  if (quality > 1)
  {
    for (minarea = i = 0; i < n; ++i)
      minarea += imgs[i].height * imgs[i].width,
      minx = imax(minx, imgs[i].width),
      miny = imax(miny, imgs[i].height);

    minarea = minarea * qfactor / 100;
  }
  else
  {
    minarea = INT_MAX - 1;
  }

  /* It's relatively easy to show that, if all the images
   * are multiples of a particular size, then a best
   * packing will always align the images on a grid of
   * that size.
   *
   * This speeds computation immensely.
   */
  for (rdiv = imgs[0].height, i = 1; i < n; ++i)
    rdiv = gcd(imgs[i].height, rdiv);

  for (cdiv = imgs[0].width, i = 1; i < n; ++i)
    cdiv = gcd(imgs[i].width, cdiv);

  MALLOCARRAY(current, n);
  MALLOCARRAY(set, n);
  for (i = 0; i < n; ++i)
    set[i].x = imgs[i].width,
    set[i].y = imgs[i].height;
  recursefindpack(current, c, set, coords, minarea, &z, 0, n, cdiv, rdiv);
}
示例#4
0
static void 
recursefindpack(coord *current, coord currentsz, coord *set, 
                coord *best, int minarea, int *maxarea, 
                int depth, int n, int xinc, int yinc)
{
  coord c;
  if (depth == n)
  {
    if (currentsz.x * currentsz.y < *maxarea)
    {
      memcpy(best, current, sizeof(coord) * n);
      *maxarea = currentsz.x * currentsz.y;
    }
    return;
  }

  for (current[depth].x = 0; 
       imax(current[depth].x + set[depth].x, currentsz.x) * 
           imax(currentsz.y, set[depth].y) < *maxarea; 
       current[depth].x += xinc)
  {
    for (current[depth].y = 0; 
         imax(current[depth].x + set[depth].x, currentsz.x) * 
             imax(currentsz.y, current[depth].y + set[depth].y) < *maxarea; 
         current[depth].y += yinc)
    {
      c.x = imax(current[depth].x + set[depth].x, currentsz.x);
      c.y = imax(current[depth].y + set[depth].y, currentsz.y);
      if (!checkcollision(current, set, &current[depth], &set[depth], depth))
      {
        recursefindpack(current, c, set, best, minarea, maxarea, 
                        depth + 1, n, xinc, yinc);
        if (*maxarea <= minarea)
          return;
      }
    }
  }
}