[mapserver-commits] r12413 - trunk/mapserver/mapcache/src
svn at osgeo.org
svn at osgeo.org
Fri Aug 26 07:23:38 EDT 2011
Author: tbonfort
Date: 2011-08-26 04:23:38 -0700 (Fri, 26 Aug 2011)
New Revision: 12413
Modified:
trunk/mapserver/mapcache/src/tileset.c
Log:
remove dependency on cairo library, by rolling out our own nearest-neighbour and bilinear
image resampler
needs testing
update issue 93
thomas.bonfort | 2011-07-24 18:54:00 +0200 (Sun, 24 Jul 2011)
Modified: trunk/mapserver/mapcache/src/tileset.c
===================================================================
--- trunk/mapserver/mapcache/src/tileset.c 2011-08-26 11:23:34 UTC (rev 12412)
+++ trunk/mapserver/mapcache/src/tileset.c 2011-08-26 11:23:38 UTC (rev 12413)
@@ -89,43 +89,74 @@
double hresolution = geocache_grid_get_horizontal_resolution(bbox, width);
double vresolution = geocache_grid_get_vertical_resolution(bbox, height);
double tilebbox[4];
+ geocache_tile *toplefttile=NULL;
+ int mx=INT_MAX,my=INT_MAX,Mx=INT_MIN,My=INT_MIN;
+ int i;
geocache_image *image = geocache_image_create(ctx);
image->w = width;
image->h = height;
image->stride = width*4;
image->data = apr_pcalloc(ctx->pool,width*height*4*sizeof(unsigned char));
+ if(ntiles == 0) {
+ return image;
+ }
cairo_surface_t* dstsurface= cairo_image_surface_create_for_data(image->data, CAIRO_FORMAT_ARGB32,
width, height,image->stride);
cairo_t *cr = cr = cairo_create (dstsurface);
- int i;
+ /* compute the number of tiles horizontally and vertically */
for(i=0;i<ntiles;i++) {
geocache_tile *tile = tiles[i];
- double tileresolution = tile->grid_link->grid->levels[tile->z]->resolution;
- geocache_grid_get_extent(ctx,tile->grid_link->grid,
- tile->x, tile->y, tile->z, tilebbox);
+ if(tile->x < mx) mx = tile->x;
+ if(tile->y < my) my = tile->y;
+ if(tile->x > Mx) Mx = tile->x;
+ if(tile->y > My) My = tile->y;
+ }
+ /* create image that will contain the unscaled tiles data */
+ geocache_image *srcimage = geocache_image_create(ctx);
+ srcimage->w = (Mx-mx+1)*tiles[0]->grid_link->grid->tile_sx;
+ srcimage->h = (My-my+1)*tiles[0]->grid_link->grid->tile_sy;
+ srcimage->stride = srcimage->w*4;
+ srcimage->data = apr_pcalloc(ctx->pool,srcimage->w*srcimage->h*4*sizeof(unsigned char));
+ cairo_surface_t* srcsurface= cairo_image_surface_create_for_data(srcimage->data, CAIRO_FORMAT_ARGB32,
+ srcimage->w, srcimage->h,srcimage->stride);
+
+ /* copy the tiles data into the src image */
+ for(i=0;i<ntiles;i++) {
+ geocache_tile *tile = tiles[i];
+ if(tile->x == mx && tile->y == My) {
+ toplefttile = tile;
+ }
+ int ox,oy; /* the offset from the start of the src image to the start of the tile */
+ ox = (tile->x - mx) * tile->grid_link->grid->tile_sx;
+ oy = (My - tile->y) * tile->grid_link->grid->tile_sy;
+ int row;
geocache_image *im = geocache_imageio_decode(ctx,tile->data);
- cairo_surface_t* srcsurface= cairo_image_surface_create_for_data(im->data, CAIRO_FORMAT_ARGB32,
- im->w, im->h,im->stride);
- /*compute the pixel position of top left corner*/
- double dstminx = floor((tilebbox[0]-bbox[0])/hresolution);
- double dstminy = floor((bbox[3]-tilebbox[3])/vresolution);
- double hf = tileresolution/hresolution;
- double vf = tileresolution/vresolution;
- double dstwidth = ceil(im->w*hf);
- double dstheight = ceil(im->h*vf);
- hf = dstwidth/(double)im->w;
- vf = dstheight/(double)im->h;
- cairo_save(cr);
- //cairo_clip(cr);
- cairo_translate (cr, dstminx,dstminy);
- cairo_scale (cr, hf, vf);
- cairo_set_source_surface (cr, srcsurface, 0, 0);
- cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_BILINEAR);
- cairo_paint (cr);
- cairo_restore(cr);
- cairo_surface_destroy(srcsurface);
+ for(row=0;row<tile->grid_link->grid->tile_sy;row++) {
+ unsigned char* dstrow = &(srcimage->data[(oy+row)*srcimage->stride+ox*4]);
+ unsigned char* srcrow = &(im->data[row*im->stride]);
+ memcpy(dstrow,srcrow,im->stride);
+ }
}
+
+ assert(toplefttile);
+
+ /* copy/scale the srcimage onto the destination image */
+ double tileresolution = toplefttile->grid_link->grid->levels[toplefttile->z]->resolution;
+ geocache_grid_get_extent(ctx,toplefttile->grid_link->grid,
+ toplefttile->x, toplefttile->y, toplefttile->z, tilebbox);
+
+ /*compute the pixel position of top left corner*/
+ double dstminx = (tilebbox[0]-bbox[0])/hresolution;
+ double dstminy = (bbox[3]-tilebbox[3])/vresolution;
+ double hf = tileresolution/hresolution;
+ double vf = tileresolution/vresolution;
+ cairo_translate (cr, dstminx,dstminy);
+ cairo_scale (cr, hf, vf);
+ cairo_set_source_surface (cr, srcsurface, 0, 0);
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
+ cairo_paint (cr);
+ cairo_surface_destroy(srcsurface);
cairo_surface_destroy(dstsurface);
cairo_destroy(cr);
return image;
More information about the mapserver-commits
mailing list