Diffstat (limited to 'libopie2/opieui/oimageeffect.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opieui/oimageeffect.cpp | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/libopie2/opieui/oimageeffect.cpp b/libopie2/opieui/oimageeffect.cpp index be47eb2..93719bc 100644 --- a/libopie2/opieui/oimageeffect.cpp +++ b/libopie2/opieui/oimageeffect.cpp @@ -1862,386 +1862,389 @@ bool OImageEffect::blend( // output.setAlphaBuffer(true); // I should do some benchmarks to see if // this is worth the effort register QRgb *i, *o, *b; register int a; register int j,k; for (j=0; j<ch; j++) { b=reinterpret_cast<QRgb *>(&lower.scanLine(y+j) [ (x+cw) << 2 ]); i=reinterpret_cast<QRgb *>(&upper.scanLine(cy+j)[ (cx+cw) << 2 ]); o=reinterpret_cast<QRgb *>(&output.scanLine(j) [ cw << 2 ]); k=cw-1; --b; --i; --o; do { while ( !(a=qAlpha(*i)) && k>0 ) { i--; // *o=0; *o=*b; --o; --b; k--; }; // *o=0xFF; *o = qRgb(qRed(*b) + (((qRed(*i) - qRed(*b)) * a) >> 8), qGreen(*b) + (((qGreen(*i) - qGreen(*b)) * a) >> 8), qBlue(*b) + (((qBlue(*i) - qBlue(*b)) * a) >> 8)); --i; --o; --b; } while (k--); } return true; } bool OImageEffect::blendOnLower( int x, int y, const QImage & upper, const QImage & lower ) { int cx=0, cy=0, cw=upper.width(), ch=upper.height(); if ( upper.depth() != 32 || lower.depth() != 32 ) return false; if ( x + cw > lower.width() || y + ch > lower.height() || x < 0 || y < 0 ) { if ( x > lower.width() || y > lower.height() ) return true; if ( upper.width()<=0 || upper.height() <= 0 ) return true; if ( lower.width()<=0 || lower.height() <= 0 ) return true; if (x<0) {cx=-x; cw+=x; x=0; }; if (cw + x > lower.width()) { cw=lower.width()-x; }; if (y<0) {cy=-y; ch+=y; y=0; }; if (ch + y > lower.height()) { ch=lower.height()-y; }; if ( cx >= upper.width() || cy >= upper.height() ) return true; if ( cw <= 0 || ch <= 0 ) return true; } register uchar *i, *b; register int a; register int k; for (int j=0; j<ch; j++) { b=&lower.scanLine(y+j) [ (x+cw) << 2 ]; i=&upper.scanLine(cy+j)[ (cx+cw) << 2 ]; k=cw-1; --b; --i; do { #ifndef WORDS_BIGENDIAN while ( !(a=*i) && k>0 ) #else while ( !(a=*(i-3)) && k>0 ) #endif { i-=4; b-=4; k--; }; #ifndef WORDS_BIGENDIAN --i; --b; *b += ( ((*i - *b) * a) >> 8 ); --i; --b; *b += ( ((*i - *b) * a) >> 8 ); --i; --b; *b += ( ((*i - *b) * a) >> 8 ); --i; --b; #else *b += ( ((*i - *b) * a) >> 8 ); --i; --b; *b += ( ((*i - *b) * a) >> 8 ); --i; --b; *b += ( ((*i - *b) * a) >> 8 ); i -= 2; b -= 2; #endif } while (k--); } return true; } // For selected icons QImage& OImageEffect::selectedImage( QImage &img, const QColor &col ) { return blend( col, img, 0.5); } // // =================================================================== // Effects originally ported from ImageMagick for PixiePlus, plus a few // new ones. (mosfet 12/29/01) // =================================================================== // void OImageEffect::normalize(QImage &img) { int *histogram, threshold_intensity, intense; int x, y, i; unsigned int gray_value; unsigned int *normalize_map; unsigned int high, low; // allocate histogram and normalize map histogram = (int *)calloc(MaxRGB+1, sizeof(int)); normalize_map = (unsigned int *)malloc((MaxRGB+1)*sizeof(unsigned int)); if(!normalize_map || !histogram){ owarn << "Unable to allocate normalize histogram and map" << oendl; free(normalize_map); free(histogram); return; } // form histogram if(img.depth() > 8){ // DirectClass unsigned int *data; for(y=0; y < img.height(); ++y){ data = (unsigned int *)img.scanLine(y); for(x=0; x < img.width(); ++x){ gray_value = intensityValue(data[x]); histogram[gray_value]++; } } } else{ // PsudeoClass unsigned char *data; unsigned int *cTable = img.colorTable(); for(y=0; y < img.height(); ++y){ data = (unsigned char *)img.scanLine(y); for(x=0; x < img.width(); ++x){ gray_value = intensityValue(*(cTable+data[x])); histogram[gray_value]++; } } } // find histogram boundaries by locating the 1 percent levels threshold_intensity = (img.width()*img.height())/100; intense = 0; for(low=0; low < MaxRGB; ++low){ intense+=histogram[low]; if(intense > threshold_intensity) break; } intense=0; for(high=MaxRGB; high != 0; --high){ intense+=histogram[high]; if(intense > threshold_intensity) break; } if (low == high){ // Unreasonable contrast; use zero threshold to determine boundaries. threshold_intensity=0; intense=0; for(low=0; low < MaxRGB; ++low){ intense+=histogram[low]; if(intense > threshold_intensity) break; } intense=0; for(high=MaxRGB; high != 0; --high) { intense+=histogram[high]; if(intense > threshold_intensity) break; } - if(low == high) + if(low == high) { + free(histogram); + free(normalize_map); return; // zero span bound + } } // Stretch the histogram to create the normalized image mapping. for(i=0; i <= MaxRGB; i++){ if (i < (int) low) normalize_map[i]=0; else{ if(i > (int) high) normalize_map[i]=MaxRGB; else normalize_map[i]=(MaxRGB-1)*(i-low)/(high-low); } } // Normalize if(img.depth() > 8){ // DirectClass unsigned int *data; for(y=0; y < img.height(); ++y){ data = (unsigned int *)img.scanLine(y); for(x=0; x < img.width(); ++x){ data[x] = qRgba(normalize_map[qRed(data[x])], normalize_map[qGreen(data[x])], normalize_map[qBlue(data[x])], qAlpha(data[x])); } } } else{ // PsudeoClass int colors = img.numColors(); unsigned int *cTable = img.colorTable(); for(i=0; i < colors; ++i){ cTable[i] = qRgba(normalize_map[qRed(cTable[i])], normalize_map[qGreen(cTable[i])], normalize_map[qBlue(cTable[i])], qAlpha(cTable[i])); } } free(histogram); free(normalize_map); } void OImageEffect::equalize(QImage &img) { int *histogram, *map, *equalize_map; int x, y, i, j; unsigned int high, low; // allocate histogram and maps histogram = (int *)calloc(MaxRGB+1, sizeof(int)); map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); equalize_map = (int *)malloc((MaxRGB+1)*sizeof(unsigned int)); if(!histogram || !map || !equalize_map){ owarn << "Unable to allocate equalize histogram and maps" << oendl; free(histogram); free(map); free(equalize_map); return; } // form histogram if(img.depth() > 8){ // DirectClass unsigned int *data; for(y=0; y < img.height(); ++y){ data = (unsigned int *)img.scanLine(y); for(x=0; x < img.width(); ++x){ histogram[intensityValue(data[x])]++; } } } else{ // PsudeoClass unsigned char *data; unsigned int *cTable = img.colorTable(); for(y=0; y < img.height(); ++y){ data = (unsigned char *)img.scanLine(y); for(x=0; x < img.width(); ++x){ histogram[intensityValue(*(cTable+data[x]))]++; } } } // integrate the histogram to get the equalization map. j=0; for(i=0; i <= MaxRGB; i++){ j+=histogram[i]; map[i]=j; } free(histogram); if(map[MaxRGB] == 0){ free(equalize_map); free(map); return; } // equalize low=map[0]; high=map[MaxRGB]; for(i=0; i <= MaxRGB; i++) equalize_map[i]=(unsigned int) ((((double) (map[i]-low))*MaxRGB)/QMAX(high-low,1)); free(map); // stretch the histogram if(img.depth() > 8){ // DirectClass unsigned int *data; for(y=0; y < img.height(); ++y){ data = (unsigned int *)img.scanLine(y); for(x=0; x < img.width(); ++x){ data[x] = qRgba(equalize_map[qRed(data[x])], equalize_map[qGreen(data[x])], equalize_map[qBlue(data[x])], qAlpha(data[x])); } } } else{ // PsudeoClass int colors = img.numColors(); unsigned int *cTable = img.colorTable(); for(i=0; i < colors; ++i){ cTable[i] = qRgba(equalize_map[qRed(cTable[i])], equalize_map[qGreen(cTable[i])], equalize_map[qBlue(cTable[i])], qAlpha(cTable[i])); } } free(equalize_map); } QImage OImageEffect::sample(QImage &src, int w, int h) { if(w == src.width() && h == src.height()) return(src); double *x_offset, *y_offset; int j, k, y; register int x; QImage dest(w, h, src.depth()); x_offset = (double *)malloc(w*sizeof(double)); y_offset = (double *)malloc(h*sizeof(double)); if(!x_offset || !y_offset){ owarn << "Unable to allocate pixels buffer" << oendl; free(x_offset); free(y_offset); return(src); } // init pixel offsets for(x=0; x < w; ++x) x_offset[x] = x*src.width()/((double)w); for(y=0; y < h; ++y) y_offset[y] = y*src.height()/((double)h); // sample each row if(src.depth() > 8){ // DirectClass source image unsigned int *srcData, *destData; unsigned int *pixels; pixels = (unsigned int *)malloc(src.width()*sizeof(unsigned int)); if(!pixels){ owarn << "Unable to allocate pixels buffer" << oendl; free(pixels); free(x_offset); free(y_offset); return(src); } j = (-1); for(y=0; y < h; ++y){ destData = (unsigned int *)dest.scanLine(y); if(j != y_offset[y]){ // read a scan line j = (int)(y_offset[y]); srcData = (unsigned int *)src.scanLine(j); (void)memcpy(pixels, srcData, src.width()*sizeof(unsigned int)); } // sample each column for(x=0; x < w; ++x){ k = (int)(x_offset[x]); destData[x] = pixels[k]; } } free(pixels); } else{ // PsudeoClass source image unsigned char *srcData, *destData; unsigned char *pixels; pixels = (unsigned char *)malloc(src.width()*sizeof(unsigned char)); if(!pixels){ owarn << "Unable to allocate pixels buffer" << oendl; free(pixels); free(x_offset); free(y_offset); return(src); } // copy colortable |