Show
Ignore:
Timestamp:
03/29/09 07:05:20 (16 months ago)
Author:
artem
Message:

+ applied "hill shading" patch from Marcin Rudowski

a) Raster opacity
b) Raster merging modes (TODO:add more modes, consider agg impl)
c) Raster scaling algos: fast,bilinear,bilinear8

(TODO: add alpha support in bilinear8)

d) improvements to png256

*Great work, thanks!*

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/include/mapnik/image_util.hpp

    r890 r1027  
    273273   } 
    274274    
     275   template <typename Image> 
     276   inline void scale_image_bilinear (Image& target,const Image& source) 
     277   { 
     278 
     279      int source_width=source.width(); 
     280      int source_height=source.height(); 
     281 
     282      int target_width=target.width(); 
     283      int target_height=target.height(); 
     284 
     285      if (source_width<1 || source_height<1 || 
     286          target_width<1 || target_height<1) return; 
     287      int x=0,y=0,xs=0,ys=0; 
     288      int tw2 = target_width/2; 
     289      int th2 = target_height/2; 
     290 
     291 
     292      for (y=0;y<target_height;++y) 
     293      { 
     294        ys = y*source_height/target_height; 
     295        int ys1 = ys+1; 
     296        if (ys1>=source_height) 
     297            ys1--; 
     298        unsigned yprt = y*source_height%target_height; 
     299        unsigned yprt1 = target_height-yprt; 
     300        for (x=0;x<target_width;++x) 
     301        { 
     302            xs = x*source_width/target_width; 
     303            if (source_width>=target_width || source_height>=target_height){ 
     304                target(x,y)=source(xs,ys); 
     305                continue; 
     306            } 
     307            unsigned xprt = x*source_width%target_width; 
     308            unsigned xprt1 = target_width-xprt; 
     309            int xs1 = xs+1; 
     310            if (xs1>=source_width) 
     311                xs1--; 
     312 
     313            unsigned a = source(xs,ys); 
     314            unsigned b = source(xs1,ys); 
     315            unsigned c = source(xs,ys1); 
     316            unsigned d = source(xs1,ys1); 
     317            unsigned out=0; 
     318            unsigned t = 0; 
     319 
     320            for(int i=0; i<4; i++){ 
     321                unsigned p,r,s; 
     322                // X axis 
     323                p = a&0xff; 
     324                r = b&0xff; 
     325                if (p!=r) 
     326                    r = (r*xprt+p*xprt1+tw2)/target_width; 
     327                p = c&0xff; 
     328                s = d&0xff; 
     329                if (p!=s) 
     330                    s = (s*xprt+p*xprt1+tw2)/target_width; 
     331                // Y axis 
     332                if (r!=s) 
     333                    r = (s*yprt+r*yprt1+th2)/target_height; 
     334                // channel up 
     335                out |= r << t; 
     336                t += 8; 
     337                a >>= 8; 
     338                b >>= 8; 
     339                c >>= 8; 
     340                d >>= 8; 
     341            } 
     342            target(x,y)=out; 
     343        } 
     344     } 
     345   } 
     346 
     347   template <typename Image> 
     348   inline void scale_image_bilinear8 (Image& target,const Image& source) 
     349   { 
     350 
     351      int source_width=source.width(); 
     352      int source_height=source.height(); 
     353 
     354      int target_width=target.width(); 
     355      int target_height=target.height(); 
     356 
     357      if (source_width<1 || source_height<1 || 
     358          target_width<1 || target_height<1) return; 
     359      int x=0,y=0,xs=0,ys=0; 
     360      int tw2 = target_width/2; 
     361      int th2 = target_height/2; 
     362 
     363 
     364      for (y=0;y<target_height;++y) 
     365      { 
     366        ys = y*source_height/target_height; 
     367        int ys1 = ys+1; 
     368        if (ys1>=source_height) 
     369            ys1--; 
     370        unsigned yprt = y*source_height%target_height; 
     371        unsigned yprt1 = target_height-yprt; 
     372        for (x=0;x<target_width;++x) 
     373        { 
     374            xs = x*source_width/target_width; 
     375            if (source_width>=target_width || source_height>=target_height){ 
     376                target(x,y)=source(xs,ys); 
     377                continue; 
     378            } 
     379            unsigned xprt = x*source_width%target_width; 
     380            unsigned xprt1 = target_width-xprt; 
     381            int xs1 = xs+1; 
     382            if (xs1>=source_width) 
     383                xs1--; 
     384 
     385            unsigned a = source(xs,ys); 
     386            unsigned b = source(xs1,ys); 
     387            unsigned c = source(xs,ys1); 
     388            unsigned d = source(xs1,ys1); 
     389            unsigned p,r,s; 
     390            // X axis 
     391            p = a&0xff; 
     392            r = b&0xff; 
     393            if (p!=r) 
     394                r = (r*xprt+p*xprt1+tw2)/target_width; 
     395            p = c&0xff; 
     396            s = d&0xff; 
     397            if (p!=s) 
     398                s = (s*xprt+p*xprt1+tw2)/target_width; 
     399            // Y axis 
     400            if (r!=s) 
     401                r = (s*yprt+r*yprt1+th2)/target_height; 
     402            target(x,y)=(0xff<<24) | (r<<16) | (r<<8) | r; 
     403        } 
     404     } 
     405   } 
     406 
    275407   inline MAPNIK_DECL void save_to_file (Image32 const& image, 
    276408                                         std::string const& file,