Logo Search packages:      
Sourcecode: djvulibre version File versions

void GPixmap::downsample43 ( const GPixmap src,
const GRect rect = 0 
)

Resets this GPixmap with a rescaled segment of src# (zoom 75%). This function conceptually rescales image src# by a factor #3:4#, and copies rectangle rect# of the rescaled image into the current GPixmap. The full rescaled image is copied if rect# is a null pointer. Both operations are however performed together for efficiency reasons. This function has been superseded by class {GPixmapScaler}.

Definition at line 1102 of file GPixmap.cpp.

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

{
  // check arguments
  int srcwidth = src->columns();
  int srcheight = src->rows();
  int destwidth = (srcwidth * 3 + 3 ) / 4;
  int destheight = (srcheight * 3 + 3) / 4;
  GRect rect(0, 0, destwidth, destheight);
  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.overflow3") );
    rect = *pdr;
    destwidth = rect.width();
    destheight = rect.height();
  }
  // initialize pixmap
  init(destheight, destwidth, 0);

  // compute bounds
  int dxz, dy;   // location of bottomleft block in destination image
  int sxz, sy;   // location of bottomleft block in source image
  euclidian_ratio(rect.ymin, 3, sy, dy);
  euclidian_ratio(rect.xmin, 3, sxz, dxz);
  sxz = 4 * sxz;   
  sy  = 4 * sy;
  dxz = - dxz;
  dy  = - dy;

  // prepare variables
  int sadd = src->rowsize();
  int dadd = this->rowsize();
  const GPixel *sptr = (*src)[0]  + sy * sadd;
  GPixel *dptr = (*this)[0] + dy * dadd;
  int s4add = 4 * sadd;
  int d3add = 3 * dadd;

  // iterate over row blocks
  while (dy < destheight)
  {
    int sx = sxz;
    int dx = dxz;
    // iterate over column blocks
    while (dx < destwidth)
    {
      GPixel xin[16], xout[9];

      if (dx>=0 && dy>=0 && dx+3<=destwidth && dy+3<=destheight)
        {
          if (sx+4<=srcwidth && sy+4<=srcheight)
            {
              downsample_4x4_to_3x3(sptr+sx, sadd, dptr+dx, dadd);
            }
          else
            {
              copy_from_partial(4,4, sptr+sx,sadd,-sx,srcwidth-sx,-sy,srcheight-sy, xin,4);
              downsample_4x4_to_3x3(xin, 4, dptr+dx, dadd);
            }
        }
      else
        {
          if (sx+4<=srcwidth && sy+4<=srcheight)
            {
              downsample_4x4_to_3x3(sptr+sx, sadd, xout, 3);  
              copy_to_partial(3,3, xout, 3, dptr+dx, dadd,-dx,destwidth-dx,-dy,destheight-dy);
            }
          else
            {
              copy_from_partial(4,4, sptr+sx,sadd,-sx,srcwidth-sx,-sy,srcheight-sy, xin,4);
              downsample_4x4_to_3x3(xin, 4, xout, 3);  
              copy_to_partial(3,3, xout,3, dptr+dx,dadd,-dx,destwidth-dx,-dy,destheight-dy);
            }
        }
      // next column
      dx += 3;
      sx += 4;
    }
    // next row
    dy += 3;
    dptr += d3add;
    sy += 4;
    sptr += s4add;
  }
}


Generated by  Doxygen 1.6.0   Back to index