Skip to content

Commit

Permalink
Store the outputformat reference in symbolObj instead of the renderer…
Browse files Browse the repository at this point in the history
… vtable (#3834)
  • Loading branch information
szekerest committed Aug 24, 2014
1 parent 5b9f95d commit f4a4a28
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 75 deletions.
32 changes: 1 addition & 31 deletions mapdraw.c
Expand Up @@ -742,21 +742,6 @@ int msDrawLayer(mapObj *map, layerObj *layer, imageObj *image)
if(retcode != MS_SUCCESS) {
return MS_FAILURE;
}
/*
* hack to work around bug #3834: if we have use an alternate renderer, the symbolset may contain
* symbols that reference it. We want to remove those references before the altFormat is destroyed
* to avoid a segfault and/or a leak, and so the the main renderer doesn't pick the cache up thinking
* it's for him.
*/
for(i=0; i<map->symbolset.numsymbols; i++) {
if (map->symbolset.symbol[i]!=NULL) {
symbolObj *s = map->symbolset.symbol[i];
if(s->renderer == MS_IMAGE_RENDERER(maskLayer->maskimage)) {
MS_IMAGE_RENDERER(maskLayer->maskimage)->freeSymbol(s);
s->renderer = NULL;
}
}
}
/* set the imagetype from the original outputformat back (it was removed by msSelectOutputFormat() */
msFree(map->imagetype);
map->imagetype = msStrdup(image->format->name);
Expand Down Expand Up @@ -825,21 +810,6 @@ int msDrawLayer(mapObj *map, layerObj *layer, imageObj *image)
altrenderer->getRasterBufferHandle(image_draw,&rb);
renderer->mergeRasterBuffer(image,&rb,layer->opacity*0.01,0,0,0,0,rb.width,rb.height);

/*
* hack to work around bug #3834: if we have use an alternate renderer, the symbolset may contain
* symbols that reference it. We want to remove those references before the altFormat is destroyed
* to avoid a segfault and/or a leak, and so the the main renderer doesn't pick the cache up thinking
* it's for him.
*/
for(i=0; i<map->symbolset.numsymbols; i++) {
if (map->symbolset.symbol[i]!=NULL) {
symbolObj *s = map->symbolset.symbol[i];
if(s->renderer == altrenderer) {
altrenderer->freeSymbol(s);
s->renderer = NULL;
}
}
}
msFreeImage(image_draw);

/* set the imagetype from the original outputformat back (it was removed by msSelectOutputFormat() */
Expand Down Expand Up @@ -2058,7 +2028,7 @@ int msDrawShape(mapObj *map, layerObj *layer, shapeObj *shape, imageObj *image,
}
symbol = map->symbolset.symbol[style->symbol];
if (symbol->type == MS_SYMBOL_PIXMAP) {
if (MS_SUCCESS != msPreloadImageSymbol(MS_MAP_RENDERER(map), symbol))
if (MS_SUCCESS != msPreloadImageSymbol(map->outputformat, symbol))
return MS_FAILURE;
} else if (symbol->type == MS_SYMBOL_SVG) {
#ifdef USE_SVG_CAIRO
Expand Down
34 changes: 15 additions & 19 deletions maplegend.c
Expand Up @@ -281,21 +281,6 @@ int msDrawLegendIcon(mapObj *map, layerObj *lp, classObj *theclass,

altrenderer->getRasterBufferHandle(image_draw,&rb);
renderer->mergeRasterBuffer(image,&rb,lp->opacity*0.01,0,0,0,0,rb.width,rb.height);
/*
* hack to work around bug #3834: if we have use an alternate renderer, the symbolset may contain
* symbols that reference it. We want to remove those references before the altFormat is destroyed
* to avoid a segfault and/or a leak, and so the the main renderer doesn't pick the cache up thinking
* it's for him.
*/
for(i=0; i<map->symbolset.numsymbols; i++) {
if (map->symbolset.symbol[i]!=NULL) {
symbolObj *s = map->symbolset.symbol[i];
if(s->renderer == altrenderer) {
altrenderer->freeSymbol(s);
s->renderer = NULL;
}
}
}
msFreeImage(image_draw);

} else if(image != image_draw) {
Expand Down Expand Up @@ -654,8 +639,13 @@ int msEmbedLegend(mapObj *map, imageObj *img)
rendererVTableObj *renderer;

s = msGetSymbolIndex(&(map->symbolset), "legend", MS_FALSE);
if(s != -1)
msRemoveSymbol(&(map->symbolset), s); /* solves some caching issues in AGG with long-running processes */
if(s != -1) {
legendSymbol = msRemoveSymbol(&(map->symbolset), s); /* solves some caching issues in AGG with long-running processes */
if (legendSymbol && legendSymbol->refcount == 0) {
msFreeSymbol(legendSymbol); /* clean up */
msFree(legendSymbol);
}
}

if(msGrowSymbolSet(&map->symbolset) == NULL)
return -1;
Expand Down Expand Up @@ -690,8 +680,14 @@ int msEmbedLegend(mapObj *map, imageObj *img)

if(MS_SUCCESS != renderer->getRasterBufferCopy(image,legendSymbol->pixmap_buffer))
return MS_FAILURE;
legendSymbol->renderer = renderer;

if (legendSymbol->format != map->outputformat) {
/* clean up previous output format */
if( legendSymbol->format && --legendSymbol->format->refcount < 1 )
msFreeOutputFormat( legendSymbol->format );
legendSymbol->format = map->outputformat;
legendSymbol->format->refcount++;
}

msFreeImage( image );

if(!legendSymbol->pixmap_buffer) return(-1); /* something went wrong creating scalebar */
Expand Down
37 changes: 28 additions & 9 deletions maprendering.c
Expand Up @@ -204,7 +204,7 @@ imageObj *getTile(imageObj *img, symbolObj *symbol, symbolStyleObj *s, int widt
renderer->renderTruetypeSymbol(tileimg, p_x, p_y, symbol, s);
break;
case (MS_SYMBOL_PIXMAP):
if(msPreloadImageSymbol(renderer,symbol) != MS_SUCCESS) {
if(msPreloadImageSymbol(img->format,symbol) != MS_SUCCESS) {
return NULL; /* failed to load image, renderer should have set the error message */
}
renderer->renderPixmapSymbol(tileimg, p_x, p_y, symbol, s);
Expand Down Expand Up @@ -256,7 +256,7 @@ imageObj *getTile(imageObj *img, symbolObj *symbol, symbolStyleObj *s, int widt
renderer->renderTruetypeSymbol(tile3img, p_x, p_y, symbol, s);
break;
case (MS_SYMBOL_PIXMAP):
if(msPreloadImageSymbol(renderer,symbol) != MS_SUCCESS) {
if(msPreloadImageSymbol(img->format,symbol) != MS_SUCCESS) {
return NULL; /* failed to load image, renderer should have set the error message */
}
renderer->renderPixmapSymbol(tile3img, p_x, p_y, symbol, s);
Expand Down Expand Up @@ -480,7 +480,13 @@ int msDrawLineSymbol(symbolSetObj *symbolset, imageObj *image, shapeObj *p,

symbol = symbolset->symbol[style->symbol];
/* store a reference to the renderer to be used for freeing */
symbol->renderer = renderer;
if (symbol->format != image->format) {
/* clean up previous output format */
if( symbol->format && --symbol->format->refcount < 1 )
msFreeOutputFormat( symbol->format );
symbol->format = image->format;
symbol->format->refcount++;
}

width = style->width * scalefactor;
width = MS_MIN(width,style->maxwidth*image->resolutionfactor);
Expand Down Expand Up @@ -533,7 +539,7 @@ int msDrawLineSymbol(symbolSetObj *symbolset, imageObj *image, shapeObj *p,
break;
case (MS_SYMBOL_PIXMAP): {
if(!symbol->pixmap_buffer) {
if(MS_SUCCESS != msPreloadImageSymbol(renderer,symbol))
if(MS_SUCCESS != msPreloadImageSymbol(image->format,symbol))
return MS_FAILURE;
}
}
Expand Down Expand Up @@ -630,8 +636,15 @@ int msDrawShadeSymbol(symbolSetObj *symbolset, imageObj *image, shapeObj *p, sty
shapeObj *offsetPolygon = NULL;
symbolObj *symbol = symbolset->symbol[style->symbol];
/* store a reference to the renderer to be used for freeing */
if(style->symbol)
symbol->renderer = renderer;
if(style->symbol) {
if (symbol->format != image->format) {
/* clean up previous output format */
if( symbol->format && --symbol->format->refcount < 1 )
msFreeOutputFormat( symbol->format );
symbol->format = image->format;
symbol->format->refcount++;
}
}

if (style->offsetx != 0 || style->offsety != 0) {
if(style->offsety==-99)
Expand Down Expand Up @@ -689,7 +702,7 @@ int msDrawShadeSymbol(symbolSetObj *symbolset, imageObj *image, shapeObj *p, sty

switch(symbol->type) {
case MS_SYMBOL_PIXMAP:
if(MS_SUCCESS != msPreloadImageSymbol(renderer,symbol)) {
if(MS_SUCCESS != msPreloadImageSymbol(image->format,symbol)) {
ret = MS_FAILURE;
goto cleanup;
}
Expand Down Expand Up @@ -799,7 +812,13 @@ int msDrawMarkerSymbol(symbolSetObj *symbolset,imageObj *image, pointObj *p, sty
double p_x,p_y;
symbolObj *symbol = symbolset->symbol[style->symbol];
/* store a reference to the renderer to be used for freeing */
symbol->renderer = renderer;
if (symbol->format != image->format) {
/* clean up previous output format */
if( symbol->format && --symbol->format->refcount < 1 )
msFreeOutputFormat( symbol->format );
symbol->format = image->format;
symbol->format->refcount++;
}
switch (symbol->type) {
case (MS_SYMBOL_TRUETYPE): {
if (!symbol->full_font_path)
Expand All @@ -813,7 +832,7 @@ int msDrawMarkerSymbol(symbolSetObj *symbolset,imageObj *image, pointObj *p, sty
break;
case (MS_SYMBOL_PIXMAP): {
if (!symbol->pixmap_buffer) {
if (MS_SUCCESS != msPreloadImageSymbol(renderer, symbol))
if (MS_SUCCESS != msPreloadImageSymbol(image->format, symbol))
return MS_FAILURE;
}
}
Expand Down
9 changes: 7 additions & 2 deletions mapscale.c
Expand Up @@ -344,9 +344,14 @@ int msEmbedScalebar(mapObj *map, imageObj *img)
char* imageType = NULL;

index = msGetSymbolIndex(&(map->symbolset), "scalebar", MS_FALSE);
if(index != -1)
msRemoveSymbol(&(map->symbolset), index); /* remove cached symbol in case the function is called multiple
if(index != -1) {
embededSymbol = msRemoveSymbol(&(map->symbolset), index); /* remove cached symbol in case the function is called multiple
times with different zoom levels */
if (embededSymbol && embededSymbol->refcount == 0) {
msFreeSymbol(embededSymbol); /* clean up */
msFree(embededSymbol);
}
}

if((embededSymbol=msGrowSymbolSet(&map->symbolset)) == NULL)
return MS_FAILURE;
Expand Down
2 changes: 1 addition & 1 deletion mapscript/php/mapscript_i.c
Expand Up @@ -2045,7 +2045,7 @@ imageObj *symbolObj_getImage(symbolObj *self, outputFormatObj *input_format)
}

renderer = format->vtable;
msPreloadImageSymbol(renderer, self);
msPreloadImageSymbol(format, self);
if (self->pixmap_buffer) {
image = msImageCreate(self->pixmap_buffer->width, self->pixmap_buffer->height, format, NULL, NULL,
MS_DEFAULT_RESOLUTION, MS_DEFAULT_RESOLUTION, NULL);
Expand Down
2 changes: 1 addition & 1 deletion mapscript/swiginc/symbol.i
Expand Up @@ -130,7 +130,7 @@
}

renderer = format->vtable;
msPreloadImageSymbol(renderer, self);
msPreloadImageSymbol(format, self);
if (self->pixmap_buffer)
{
image = msImageCreate(self->pixmap_buffer->width, self->pixmap_buffer->height, format, NULL, NULL,
Expand Down
7 changes: 4 additions & 3 deletions mapserver.h
Expand Up @@ -106,6 +106,7 @@ typedef uint32_t ms_uint32;
/*forward declaration of rendering object*/
typedef struct rendererVTableObj rendererVTableObj;
typedef struct tileCacheObj tileCacheObj;
typedef struct outputFormatObj outputFormatObj;


/* ms_bitarray is used by the bit mask in mapbit.c */
Expand Down Expand Up @@ -752,7 +753,7 @@ extern "C" {
/* see mapoutput.c for most related code. */
/************************************************************************/

typedef struct {
typedef struct outputFormatObj {
char *name;
char *mimetype;
char *driver;
Expand All @@ -769,7 +770,7 @@ extern "C" {
rendererVTableObj *vtable;
void *device; /* for supporting direct rendering onto a device context */
#endif
} outputFormatObj;
};

/* The following is used for "don't care" values in transparent, interlace and
imagequality values. */
Expand Down Expand Up @@ -2067,7 +2068,7 @@ extern "C" {
MS_DLL_EXPORT symbolObj *msRemoveSymbol(symbolSetObj *symbolset, int index);
MS_DLL_EXPORT int msSaveSymbolSet(symbolSetObj *symbolset, const char *filename);
MS_DLL_EXPORT int msLoadImageSymbol(symbolObj *symbol, const char *filename);
MS_DLL_EXPORT int msPreloadImageSymbol(rendererVTableObj *renderer, symbolObj *symbol);
MS_DLL_EXPORT int msPreloadImageSymbol(outputFormatObj *format, symbolObj *symbol);
MS_DLL_EXPORT int msPreloadSVGSymbol(symbolObj *symbol);
MS_DLL_EXPORT symbolObj *msRotateSymbol(symbolObj *symbol, double angle);

Expand Down
26 changes: 18 additions & 8 deletions mapsymbol.c
Expand Up @@ -111,7 +111,7 @@ void initSymbol(symbolObj *s)
s->sizey = 1;
s->filled = MS_FALSE;
s->numpoints=0;
s->renderer=NULL;
s->format=NULL;
s->renderer_cache = NULL;
s->pixmap_buffer=NULL;
s->imagepath = NULL;
Expand All @@ -136,8 +136,12 @@ int msFreeSymbol(symbolObj *s)
}

if(s->name) free(s->name);
if(s->renderer!=NULL) {
s->renderer->freeSymbol(s);
if(s->format!=NULL) {
if (s->format->vtable!=NULL)
s->format->vtable->freeSymbol(s);
/* clean up output format */
if( --s->format->refcount < 1 )
msFreeOutputFormat( s->format );
}
if(s->pixmap_buffer) {
msFreeRasterBuffer(s->pixmap_buffer);
Expand Down Expand Up @@ -624,7 +628,7 @@ int msGetMarkerSize(symbolSetObj *symbolset, styleObj *style, double *width, dou

symbol = symbolset->symbol[style->symbol];
if (symbol->type == MS_SYMBOL_PIXMAP && !symbol->pixmap_buffer) {
if (MS_SUCCESS != msPreloadImageSymbol(MS_MAP_RENDERER(symbolset->map), symbol))
if (MS_SUCCESS != msPreloadImageSymbol(symbolset->map->outputformat, symbol))
return MS_FAILURE;
}
if(symbol->type == MS_SYMBOL_SVG && !symbol->renderer_cache) {
Expand Down Expand Up @@ -822,22 +826,28 @@ int msLoadImageSymbol(symbolObj *symbol, const char *filename)
return MS_SUCCESS;
}

int msPreloadImageSymbol(rendererVTableObj *renderer, symbolObj *symbol)
int msPreloadImageSymbol(outputFormatObj *format, symbolObj *symbol)
{
if(symbol->pixmap_buffer && symbol->renderer == renderer)
if(symbol->pixmap_buffer && symbol->format == format)
return MS_SUCCESS;
if(symbol->pixmap_buffer) { /* other renderer was used, start again */
msFreeRasterBuffer(symbol->pixmap_buffer);
} else {
symbol->pixmap_buffer = (rasterBufferObj*)calloc(1,sizeof(rasterBufferObj));
}
if(MS_SUCCESS != renderer->loadImageFromFile(symbol->full_pixmap_path, symbol->pixmap_buffer)) {
if(MS_SUCCESS != format->vtable->loadImageFromFile(symbol->full_pixmap_path, symbol->pixmap_buffer)) {
/* Free pixmap_buffer already allocated */
free(symbol->pixmap_buffer);
symbol->pixmap_buffer = NULL;
return MS_FAILURE;
}
symbol->renderer = renderer;
if (symbol->format != format) {
/* clean up previous output format */
if( symbol->format && --symbol->format->refcount < 1 )
msFreeOutputFormat( symbol->format );
symbol->format = format;
symbol->format->refcount++;
}
symbol->sizex = symbol->pixmap_buffer->width;
symbol->sizey = symbol->pixmap_buffer->height;
return MS_SUCCESS;
Expand Down
2 changes: 1 addition & 1 deletion mapsymbol.h
Expand Up @@ -191,7 +191,7 @@ typedef struct {
** MS_SYMBOL_PIXMAP options
*/
#ifndef SWIG
rendererVTableObj *renderer;
outputFormatObj *format;
rasterBufferObj *pixmap_buffer;
void *renderer_cache;
char *full_font_path;
Expand Down

0 comments on commit f4a4a28

Please sign in to comment.