Image scaling - not perfect but fast and better than just copy(w, h) because it 
does at least a little bit of filtering:

/**
 * Scale horizontally by 50%.
 */
void Flmp_Image::half_width()
{
  if (!w() || !h() || !d() || !array) return;
  uncache();
  int dw = w()/2, dh = h(), dd = d(), i, j, k, stride = ld();
  if (stride==0) stride = w()*d();
  uchar *new_array = new uchar[dw*dh*dd];
  
  uchar *dst = new_array;
  for (i=0; i<dh; i++) {
    const uchar *src = array + i*stride;
    for (j=0; j<dw; j++) {
      for (k=0; k<dd; k++) {
        unsigned short a = src[0];
        unsigned short b = src[dd];
        *dst++ = (a+b)>>1;
        src++;
      }
      src+=dd;
    }
  }
  
  if (alloc_array) delete[] (uchar *)array;  
  array = new_array;
  alloc_array = 1;
  ld(0);
  d(dd);
  w(dw);
  h(dh);
}

/**
 * Scale horizontally by 50%.
 */
void Flmp_Image::half_height()
{
  if (!w() || !h() || !d() || !array) return;
  uncache();
  int dw = w(), dh = h()/2, dd = d(), i, j, k, stride = ld();
  if (stride==0) stride = w()*d();
  uchar *new_array = new uchar[dw*dh*dd];
  
  uchar *dst = new_array;
  for (i=0; i<dh; i++) {
    const uchar *src = array + 2*i*stride;
    for (j=0; j<dw; j++) {
      for (k=0; k<dd; k++) {
        unsigned short a = src[0];
        unsigned short b = src[stride];
        *dst++ = (a+b)>>1;
        src++;
      }
    }
  }
  
  if (alloc_array) delete[] (uchar *)array;  
  array = new_array;
  alloc_array = 1;
  ld(0);
  d(dd);
  w(dw);
  h(dh);
}

Fl_Image *Flmp_Image::scale(int W, int H) {
  if (2*W<w() || 2*H<h()) {
    Flmp_Image *img = (Flmp_Image*)copy();
    while (2*W<img->w())
      img->half_width();
    while (2*H<img->h())
      img->half_height();
    Fl_Image *ret = img->copy(W, H);
    delete img;
    return ret;
  }
  return copy(W, H);
}

_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to