Logo Search packages:      
Sourcecode: djvulibre version File versions

void GPixmap::downsample ( const GPixmap src,
int  factor,
const GRect rect = 0 
)

Resets this GPixmap with a subsampled segment of color image src#. This function conceptually rescales image src# by a factor #1:factor#, and copies rectangle rect# of the subsampled image into the current GPixmap. The full subsampled image is copied if rect# is a null pointer. Both operations are however performed together for efficiency reasons. Subsampling works by averaging the colors of the source pixels located in small squares of size factor# times factor#.

Definition at line 850 of file GPixmap.cpp.

References GPixel::b, columns(), GPixel::g, GRect::height(), init(), GPixel::r, rows(), rowsize(), GRect::width(), GRect::xmax, GRect::xmin, GRect::ymax, and GRect::ymin.

{
  // check arguments
  GRect rect(0, 0, (src->columns()+factor-1)/factor, (src->rows()+factor-1)/factor);
  if (pdr != 0)
  {
    if (pdr->xmin < rect.xmin || 
        pdr->ymin < rect.ymin || 
        pdr->xmax > rect.xmax || 
        pdr->ymax > rect.ymax  )
      G_THROW( ERR_MSG("GPixmap.overflow1") );
    rect = *pdr;
  }

  // precompute inverse map
  static int invmap[256];
  static int invmapok = 0;
  if (! invmapok)
  {
    invmapok = 1;
    for (int i=1; i<(int)(sizeof(invmap)/sizeof(int)); i++)
      invmap[i] = 0x10000 / i;
  }
  
  // initialise pixmap
  init(rect.height(), rect.width(), 0);

  // determine starting and ending points in source rectangle
  int sy = rect.ymin * factor;
  int sxz = rect.xmin * factor;


  // loop over source rows
  const GPixel *sptr = (*src)[sy];
  GPixel *dptr = (*this)[0];
  for (int y=0; y<nrows; y++)
  {
    int sx = sxz;
    // loop over source columns
    for (int x=0; x<ncolumns; x++)
    {
      int r=0, g=0, b=0, s=0;
      // compute average bounds
      const GPixel *ksptr = sptr;
      int lsy = sy + factor;
      if (lsy > (int)src->rows())
        lsy = (int)src->rows();
      int lsx = sx + factor;
      if (lsx > (int)src->columns())
        lsx = (int)src->columns();
      // compute average
      for (int rsy=sy; rsy<lsy; rsy++)
      {
        for (int rsx = sx; rsx<lsx; rsx++)
        {
          r += ksptr[rsx].r;
          g += ksptr[rsx].g;
          b += ksptr[rsx].b;
          s += 1;
        }
        ksptr += src->rowsize();
      }
      // set pixel color
      if (s >= (int)(sizeof(invmap)/sizeof(int)))
      {
        dptr[x].r = r / s;
        dptr[x].g = g / s;
        dptr[x].b = b / s;
      }
      else
      {
        dptr[x].r = (r*invmap[s] + 0x8000) >> 16;
        dptr[x].g = (g*invmap[s] + 0x8000) >> 16;
        dptr[x].b = (b*invmap[s] + 0x8000) >> 16;
      }
      // next column
      sx = sx + factor;
    }
    // next row
    sy = sy + factor;
    sptr = sptr + factor * src->rowsize();
    dptr = dptr + rowsize();
  }
}


Generated by  Doxygen 1.6.0   Back to index