Logo Search packages:      
Sourcecode: djvulibre version File versions

void GPixmap::stencil ( const GBitmap bm,
const GPixmap pm,
int  pms,
const GRect pmr,
double  corr = 1.0 
)

Resample color pixmap and performs color corrected alpha blending. This function conceptually computes an intermediate color image by first upsampling the GPixmap pm# by a factor pms:1# (see {upsample}), extracting the sub-image designated by rectangle pmr# and applying color correction corr# (see {color_correct}). This intermediate color image is then blended into this pixel map according to the alpha map bm# (see {blend}).

Definition at line 1522 of file GPixmap.cpp.

References GPixel::b, GBitmap::columns(), columns(), GPixel::g, GBitmap::get_grays(), GPixel::r, GBitmap::rows(), rows(), GBitmap::rowsize(), rowsize(), GRect::xmax, GRect::xmin, GRect::ymax, and GRect::ymin.

{
  // Check arguments
  GRect rect(0, 0, pm->columns()*pms, pm->rows()*pms);
  if (pmr != 0)
    {
      if (pmr->xmin < rect.xmin || 
          pmr->ymin < rect.ymin || 
          pmr->xmax > rect.xmax || 
          pmr->ymax > rect.ymax  )
        G_THROW( ERR_MSG("GPixmap.overflow5") );
      rect = *pmr;
    }
  // Compute number of rows
  int xrows = nrows;
  if ((int)bm->rows() < xrows)
    xrows = bm->rows();
  if (rect.height() < xrows)
    xrows = rect.height();
  // Compute number of columns
  int xcolumns = ncolumns;
  if ((int)bm->columns() < xcolumns)
    xcolumns = bm->columns();
  if (rect.width() < xcolumns)
    xcolumns = rect.width();
  // Precompute multiplier map
  unsigned int multiplier[256];
  unsigned int maxgray = bm->get_grays() - 1;
  for (unsigned int i=1; i<maxgray ; i++)
    multiplier[i] = 0x10000 * i / maxgray;
  // Prepare color correction table
  unsigned char gtable[256];
  color_correction_table_cache(corr, gtable);
  // Compute starting point in blown up foreground pixmap
  int fgy, fgy1, fgxz, fgx1z;
  euclidian_ratio(rect.ymin, pms, fgy, fgy1);
  euclidian_ratio(rect.xmin, pms, fgxz, fgx1z);
  const GPixel *fg = (*pm)[fgy];
  const unsigned char *src = (*bm)[0];
  GPixel *dst = (*this)[0];
  // Loop over rows
  for (int y=0; y<xrows; y++)
  {
    // Loop over columns
    int fgx = fgxz;
    int fgx1 = fgx1z;
    for (int x=0; x<xcolumns; x++)
    {
      unsigned char srcpix = src[x];
      // Perform pixel operation
      if (srcpix > 0)
      {
        if (srcpix >= maxgray)
        {
          dst[x].b = gtable[fg[fgx].b];
          dst[x].g = gtable[fg[fgx].g];
          dst[x].r = gtable[fg[fgx].r];
        }
        else
        {
          unsigned int level = multiplier[srcpix];
          dst[x].b -= (((int)dst[x].b - (int)gtable[fg[fgx].b]) * level) >> 16;
          dst[x].g -= (((int)dst[x].g - (int)gtable[fg[fgx].g]) * level) >> 16;
          dst[x].r -= (((int)dst[x].r - (int)gtable[fg[fgx].r]) * level) >> 16;
        }
      }
      // Next column
      if (++fgx1 >= pms)
      {
        fgx1 = 0;
        fgx += 1;
      }
    }
    // Next line
    dst += rowsize();
    src += bm->rowsize();
    if (++fgy1 >= pms)
    {
      fgy1 = 0;
      fg += pm->rowsize();
    } 
  }
}


Generated by  Doxygen 1.6.0   Back to index