void KmlRenderer::processLayer(layerObj *layer, outputFormatObj *format) { int i; const char *asRaster = NULL; int nMaxFeatures = -1; const char *pszTmp; char szTmp[10]; if (!layer) return; /*turn of labelcache*/ layer->labelcache = MS_OFF; /*if there are labels we want the coordinates to be the center of the element.*/ for(i=0; i<layer->numclasses; i++) if(layer->_class[i]->numlabels > 0) layer->_class[i]->labels[0]->position = MS_XY; /*we do not want to draw multiple styles. the new rendering architecture does not allow to know if we are dealing with a multi-style. So here we remove all styles beside the first one*/ for(i=0; i<layer->numclasses; i++) { while (layer->_class[i]->numstyles > 1) msDeleteStyle(layer->_class[i], layer->_class[i]->numstyles-1); } /*if layer has a metadata KML_OUTPUTASRASTER set to true, add a processing directive to use an agg driver*/ asRaster = msLookupHashTable(&layer->metadata, "kml_outputasraster"); if (!asRaster) asRaster = msLookupHashTable(&(layer->map->web.metadata), "kml_outputasraster"); if (asRaster && (strcasecmp(asRaster, "true") == 0 || strcasecmp(asRaster, "yes") == 0)) msLayerAddProcessing(layer, "RENDERER=png24"); /*set a maxfeaturestodraw, if not already set*/ pszTmp = msLookupHashTable(&layer->metadata, "maxfeaturestodraw"); if (pszTmp) nMaxFeatures = atoi(pszTmp); else { pszTmp = msLookupHashTable(&layer->map->web.metadata, "maxfeaturestodraw"); if (pszTmp) nMaxFeatures = atoi(pszTmp); } if (nMaxFeatures < 0 && format) nMaxFeatures = atoi(msGetOutputFormatOption( format, "maxfeaturestodraw", "-1")); if (nMaxFeatures < 0 && format) { snprintf(szTmp, sizeof(szTmp), "%d", KML_MAXFEATURES_TODRAW); msSetOutputFormatOption( format, "maxfeaturestodraw", szTmp); } }
/* * Initialize the renderer, create buffer, allocate memory. */ imageObj *utfgridCreateImage(int width, int height, outputFormatObj *format, colorObj * bg) { UTFGridRenderer *r; r = new UTFGridRenderer; r->data = new lookupTable; r->utfresolution = atof(msGetOutputFormatOption(format, "UTFRESOLUTION", "4")); if(r->utfresolution < 1) { msSetError(MS_MISCERR, "UTFRESOLUTION smaller that 1 in the mapfile.", "utfgridCreateImage()"); return NULL; } r->layerwatch = 0; r->renderlayer = 0; r->useutfitem = 0; r->useutfdata = 0; r->duplicates = EQUAL("true", msGetOutputFormatOption(format, "DUPLICATES", "true")); r->utfvalue = 0; r->buffer = (band_type*)msSmallMalloc(width/r->utfresolution * height/r->utfresolution * sizeof(band_type)); /* AGG specific operations */ r->m_rendering_buffer.attach(r->buffer, width/r->utfresolution, height/r->utfresolution, width/r->utfresolution); r->m_pixel_format.attach(r->m_rendering_buffer); r->m_renderer_base.attach(r->m_pixel_format); r->m_renderer_scanline.attach(r->m_renderer_base); r->m_renderer_base.clear(UTF_WATER); r->m_rasterizer.gamma(mapserver::gamma_none()); r->utflayer = NULL; imageObj *image = NULL; image = (imageObj *) msSmallCalloc(1,sizeof(imageObj)); image->img.plugin = (void*) r; return image; }
/* image i/o */ imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, colorObj * bg) { imageObj *image = NULL; if (format->imagemode != MS_IMAGEMODE_RGB && format->imagemode != MS_IMAGEMODE_RGBA) { msSetError(MS_MISCERR, "AGG2 driver only supports RGB or RGBA pixel models.", "agg2CreateImage()"); return image; } image = (imageObj *) calloc(1, sizeof (imageObj)); MS_CHECK_ALLOC(image, sizeof (imageObj), NULL); AGG2Renderer *r = new AGG2Renderer(); r->buffer = (band_type*)malloc(width * height * 4 * sizeof(band_type)); if (r->buffer == NULL) { msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "agg2CreateImage()", __FILE__, __LINE__, (unsigned int)(width * height * 4 * sizeof(band_type))); free(image); return NULL; } r->m_rendering_buffer.attach(r->buffer, width, height, width * 4); r->m_pixel_format.attach(r->m_rendering_buffer); r->m_renderer_base.attach(r->m_pixel_format); r->m_renderer_scanline.attach(r->m_renderer_base); r->default_gamma = atof(msGetOutputFormatOption( format, "GAMMA", "0.75" )); if(r->default_gamma <= 0.0 || r->default_gamma >= 1.0) { r->default_gamma = 0.75; } r->gamma_function.set(0,r->default_gamma); r->m_rasterizer_aa_gamma.gamma(r->gamma_function); if( bg && !format->transparent ) r->m_renderer_base.clear(aggColor(bg)); else r->m_renderer_base.clear(AGG_NO_COLOR); if (!bg || format->transparent || format->imagemode == MS_IMAGEMODE_RGBA ) { r->use_alpha = true; } else { r->use_alpha = false; } image->img.plugin = (void*) r; return image; }
int msOutputFormatValidate( outputFormatObj *format, int issue_error ) { int result = MS_TRUE; char *driver_ext; format->bands = atoi(msGetOutputFormatOption( format, "BAND_COUNT", "1" )); /* Enforce the requirement that JPEG be RGB and TRANSPARENT=OFF */ driver_ext = strstr(format->driver,"/"); if( driver_ext && ++driver_ext && !strcasecmp(driver_ext,"JPEG")) { if( format->transparent ) { if( issue_error ) msSetError( MS_MISCERR, "JPEG OUTPUTFORMAT %s has TRANSPARENT set ON, but this is not supported.\n" "It has been disabled.\n", "msOutputFormatValidate()", format->name ); else msDebug( "JPEG OUTPUTFORMAT %s has TRANSPARENT set ON, but this is not supported.\n" "It has been disabled.\n", format->name ); format->transparent = MS_FALSE; result = MS_FALSE; } if( format->imagemode == MS_IMAGEMODE_RGBA ) { if( issue_error ) msSetError( MS_MISCERR, "JPEG OUTPUTFORMAT %s has IMAGEMODE RGBA, but this is not supported.\n" "IMAGEMODE forced to RGB.\n", "msOutputFormatValidate()", format->name ); else msDebug( "JPEG OUTPUTFORMAT %s has IMAGEMODE RGBA, but this is not supported.\n" "IMAGEMODE forced to RGB.\n", format->name ); format->imagemode = MS_IMAGEMODE_RGB; result = MS_FALSE; } } if( format->transparent && format->imagemode == MS_IMAGEMODE_RGB ) { if( issue_error ) msSetError( MS_MISCERR, "OUTPUTFORMAT %s has TRANSPARENT set ON, but an IMAGEMODE\n" "of RGB instead of RGBA. Changing imagemode to RGBA.\n", "msOutputFormatValidate()", format->name ); else msDebug("OUTPUTFORMAT %s has TRANSPARENT set ON, but an IMAGEMODE\n" "of RGB instead of RGBA. Changing imagemode to RGBA.\n", format->name ); format->imagemode = MS_IMAGEMODE_RGBA; result = MS_FALSE; } /* Special checking around RAWMODE image modes. */ if( format->imagemode == MS_IMAGEMODE_INT16 || format->imagemode == MS_IMAGEMODE_FLOAT32 || format->imagemode == MS_IMAGEMODE_BYTE ) { if( strncmp(format->driver,"GDAL/",5) != 0 ) { result = MS_FALSE; if( issue_error ) msSetError( MS_MISCERR, "OUTPUTFORMAT %s has IMAGEMODE BYTE/INT16/FLOAT32, but this is only supported for GDAL drivers.", "msOutputFormatValidate()", format->name ); else msDebug( "OUTPUTFORMAT %s has IMAGEMODE BYTE/INT16/FLOAT32, but this is only supported for GDAL drivers.", format->name ); } if( format->renderer != MS_RENDER_WITH_RAWDATA ) /* see bug 724 */ format->renderer = MS_RENDER_WITH_RAWDATA; } if( !strcasecmp(format->driver,"AGG/MIXED") ) { if( !msGetOutputFormatOption(format, "TRANSPARENT_FORMAT", NULL) ) { result = MS_FALSE; if( issue_error ) msSetError( MS_MISCERR, "OUTPUTFORMAT %s lacks a 'TRANSPARENT_FORMAT' FORMATOPTION.", "msOutputFormatValidate()", format->name ); else msDebug( "OUTPUTFORMAT %s lacks a 'TRANSPARENT_FORMAT' FORMATOPTION.", format->name ); } if( !msGetOutputFormatOption(format, "OPAQUE_FORMAT", NULL) ) { result = MS_FALSE; if( issue_error ) msSetError( MS_MISCERR, "OUTPUTFORMAT %s lacks a 'OPAQUE_FORMAT' FORMATOPTION.", "msOutputFormatValidate()", format->name ); else msDebug( "OUTPUTFORMAT %s lacks a 'OPAQUE_FORMAT' FORMATOPTION.", format->name ); } } return result; }
void msApplyOutputFormat( outputFormatObj **target, outputFormatObj *format, int transparent, int interlaced, int imagequality ) { int change_needed = MS_FALSE; int old_imagequality, old_interlaced; outputFormatObj *formatToFree = NULL; assert( target != NULL ); if( *target != NULL && MS_REFCNT_DECR_IS_ZERO( (*target) ) ) { formatToFree = *target; *target = NULL; } if( format == NULL ) { if( formatToFree ) msFreeOutputFormat( formatToFree ); *target = NULL; return; } msOutputFormatValidate( format, MS_FALSE ); /* -------------------------------------------------------------------- */ /* Do we need to change any values? If not, then just apply */ /* and return. */ /* -------------------------------------------------------------------- */ if( transparent != MS_NOOVERRIDE && !format->transparent != !transparent ) change_needed = MS_TRUE; old_imagequality = atoi(msGetOutputFormatOption( format, "QUALITY", "75")); if( imagequality != MS_NOOVERRIDE && old_imagequality != imagequality ) change_needed = MS_TRUE; old_interlaced = strcasecmp(msGetOutputFormatOption( format, "INTERLACE", "ON"), "OFF") != 0; if( interlaced != MS_NOOVERRIDE && !interlaced != !old_interlaced ) change_needed = MS_TRUE; if( change_needed ) { char new_value[128]; if( format->refcount > 0 ) format = msCloneOutputFormat( format ); if( transparent != MS_NOOVERRIDE ) { format->transparent = transparent; if( format->imagemode == MS_IMAGEMODE_RGB ) format->imagemode = MS_IMAGEMODE_RGBA; } if( imagequality != MS_NOOVERRIDE && imagequality != old_imagequality ) { snprintf( new_value, sizeof(new_value), "%d", imagequality ); msSetOutputFormatOption( format, "QUALITY", new_value ); } if( interlaced != MS_NOOVERRIDE && !interlaced != !old_interlaced ) { if( interlaced ) msSetOutputFormatOption( format, "INTERLACE", "ON" ); else msSetOutputFormatOption( format, "INTERLACE", "OFF" ); } } *target = format; format->refcount++; if( MS_RENDERER_PLUGIN(format) ) { msInitializeRendererVTable(format); } if( formatToFree ) msFreeOutputFormat( formatToFree ); }
void msOutputFormatResolveFromImage( mapObj *map, imageObj* img ) { outputFormatObj* format = map->outputformat; assert( img->format == format ); assert( img->format->refcount >= 2 ); if( format->renderer == MS_RENDER_WITH_AGG && strcmp(format->driver, "AGG/MIXED") == 0 && (format->imagemode == MS_IMAGEMODE_RGB || format->imagemode == MS_IMAGEMODE_RGBA) ) { outputFormatObj * new_format; int has_non_opaque_pixels = MS_FALSE; const char* underlying_driver_type = NULL; const char* underlying_driver_name = NULL; // Check if the image has non opaque pixels if( format->imagemode == MS_IMAGEMODE_RGBA ) { rasterBufferObj rb; int ret; ret = format->vtable->getRasterBufferHandle(img,&rb); assert( ret == MS_SUCCESS ); if( rb.data.rgba.a ) { int row; for(row=0; row<rb.height && !has_non_opaque_pixels; row++) { int col; unsigned char *a; a=rb.data.rgba.a+row*rb.data.rgba.row_step; for(col=0; col<rb.width && !has_non_opaque_pixels; col++) { if(*a < 255) { has_non_opaque_pixels = MS_TRUE; } a+=rb.data.rgba.pixel_step; } } } } underlying_driver_type = ( has_non_opaque_pixels ) ? "TRANSPARENT_FORMAT" : "OPAQUE_FORMAT"; underlying_driver_name = msGetOutputFormatOption(format, underlying_driver_type, NULL); if( underlying_driver_name == NULL ) { msSetError(MS_MISCERR, "Missing %s format option on %s.", "msOutputFormatResolveFromImage()", underlying_driver_type, format->name ); return; } new_format = msSelectOutputFormat( map, underlying_driver_name ); if( new_format == NULL ) { msSetError(MS_MISCERR, "Cannot find %s output format.", "msOutputFormatResolveFromImage()", underlying_driver_name ); return; } if( new_format->renderer != MS_RENDER_WITH_AGG ) { msSetError(MS_MISCERR, "%s cannot be used as the %s format of %s since it is not AGG based.", "msOutputFormatResolveFromImage()", underlying_driver_name, underlying_driver_type, format->name ); return; } msApplyOutputFormat( &(map->outputformat), new_format, has_non_opaque_pixels, MS_NOOVERRIDE, MS_NOOVERRIDE ); msFreeOutputFormat( format ); img->format = map->outputformat; img->format->refcount ++; } }
static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_renderer *r) { /* We need a GDAL 1.10 PDF driver at runtime, but as far as the C API is concerned, GDAL 1.9 is */ /* largely sufficient. */ #if defined(USE_GDAL) && defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900 GDALDatasetH hDS = NULL; const char* pszGEO_ENCODING = NULL; GDALDriverH hPDFDriver = NULL; const char* pszVirtualIO = NULL; int bVirtualIO = FALSE; char* pszTmpFilename = NULL; VSILFILE* fp = NULL; if (map == NULL) return; pszGEO_ENCODING = msGetOutputFormatOption(img->format, "GEO_ENCODING", NULL); if (pszGEO_ENCODING == NULL) return; msGDALInitialize(); hPDFDriver = GDALGetDriverByName("PDF"); if (hPDFDriver == NULL) return; /* When compiled against libpoppler, the PDF driver is VirtualIO capable */ /* but not, when it is compiled against libpodofo. */ pszVirtualIO = GDALGetMetadataItem( hPDFDriver, GDAL_DCAP_VIRTUALIO, NULL ); if (pszVirtualIO) bVirtualIO = CSLTestBoolean(pszVirtualIO); if (bVirtualIO) pszTmpFilename = msTmpFile(map, NULL, "/vsimem/mscairopdf/", "pdf"); else pszTmpFilename = msTmpFile(map, map->mappath, NULL, "pdf"); /* Copy content of outputStream buffer into file */ fp = VSIFOpenL(pszTmpFilename, "wb"); if (fp == NULL) { msFree(pszTmpFilename); return; } VSIFWriteL(r->outputStream->data, 1, r->outputStream->size, fp); VSIFCloseL(fp); fp = NULL; hDS = GDALOpen(pszTmpFilename, GA_Update); if ( hDS != NULL ) { char* pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); if( pszWKT != NULL ) { double adfGeoTransform[6]; int i; /* Add user-specified options */ for( i = 0; i < img->format->numformatoptions; i++ ) { const char* pszOption = img->format->formatoptions[i]; if( strncasecmp(pszOption,"METADATA_ITEM:",14) == 0 ) { char* pszKey = NULL; const char* pszValue = CPLParseNameValue(pszOption + 14, &pszKey); if( pszKey != NULL ) { GDALSetMetadataItem(hDS, pszKey, pszValue, NULL); CPLFree(pszKey); } } } /* We need to rescale the geotransform because GDAL will not necessary */ /* open the PDF with the DPI that was used to generate it */ memcpy(adfGeoTransform, map->gt.geotransform, 6 * sizeof(double)); adfGeoTransform[1] = adfGeoTransform[1] * map->width / GDALGetRasterXSize(hDS); adfGeoTransform[5] = adfGeoTransform[5] * map->height / GDALGetRasterYSize(hDS); GDALSetGeoTransform(hDS, adfGeoTransform); GDALSetProjection(hDS, pszWKT); msFree( pszWKT ); pszWKT = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", pszGEO_ENCODING); GDALClose(hDS); hDS = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", NULL); /* We need to replace the buffer with the content of the GDAL file */ fp = VSIFOpenL(pszTmpFilename, "rb"); if( fp != NULL ) { int nFileSize; VSIFSeekL(fp, 0, SEEK_END); nFileSize = (int)VSIFTellL(fp); msBufferResize(r->outputStream, nFileSize); VSIFSeekL(fp, 0, SEEK_SET); r->outputStream->size = VSIFReadL(r->outputStream->data, 1, nFileSize, fp); VSIFCloseL(fp); fp = NULL; } } } if ( hDS != NULL ) GDALClose(hDS); VSIUnlink(pszTmpFilename); msFree(pszTmpFilename); #endif }
int msSaveImageGDAL( mapObj *map, imageObj *image, char *filename ) { int bFileIsTemporary = MS_FALSE; GDALDatasetH hMemDS, hOutputDS; GDALDriverH hMemDriver, hOutputDriver; int nBands = 1; int iLine; GByte *pabyAlphaLine = NULL; char **papszOptions = NULL; outputFormatObj *format = image->format; rasterBufferObj rb; GDALDataType eDataType = GDT_Byte; int bUseXmp = MS_FALSE; msGDALInitialize(); memset(&rb,0,sizeof(rasterBufferObj)); #ifdef USE_EXEMPI if( map != NULL ) { bUseXmp = msXmpPresent(map); } #endif /* -------------------------------------------------------------------- */ /* Identify the proposed output driver. */ /* -------------------------------------------------------------------- */ msAcquireLock( TLOCK_GDAL ); hOutputDriver = GDALGetDriverByName( format->driver+5 ); if( hOutputDriver == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to find %s driver.", "msSaveImageGDAL()", format->driver+5 ); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* We will need to write the output to a temporary file and */ /* then stream to stdout if no filename is passed. If the */ /* driver supports virtualio then we hold the temporary file in */ /* memory, otherwise we try to put it in a reasonable temporary */ /* file location. */ /* -------------------------------------------------------------------- */ if( filename == NULL ) { const char *pszExtension = format->extension; if( pszExtension == NULL ) pszExtension = "img.tmp"; if( bUseXmp == MS_FALSE && GDALGetMetadataItem( hOutputDriver, GDAL_DCAP_VIRTUALIO, NULL ) != NULL ) { CleanVSIDir( "/vsimem/msout" ); filename = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension ); } if( filename == NULL && map != NULL) filename = msTmpFile(map, map->mappath,NULL,pszExtension); else if( filename == NULL ) { filename = msTmpFile(map, NULL, NULL, pszExtension ); } bFileIsTemporary = MS_TRUE; } /* -------------------------------------------------------------------- */ /* Establish the characteristics of our memory, and final */ /* dataset. */ /* -------------------------------------------------------------------- */ if( format->imagemode == MS_IMAGEMODE_RGB ) { nBands = 3; assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); format->vtable->getRasterBufferHandle(image,&rb); } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { pabyAlphaLine = (GByte *) calloc(image->width,1); if (pabyAlphaLine == NULL) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", image->width); return MS_FAILURE; } nBands = 4; assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); format->vtable->getRasterBufferHandle(image,&rb); } else if( format->imagemode == MS_IMAGEMODE_INT16 ) { nBands = format->bands; eDataType = GDT_Int16; } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) { nBands = format->bands; eDataType = GDT_Float32; } else if( format->imagemode == MS_IMAGEMODE_BYTE ) { nBands = format->bands; eDataType = GDT_Byte; } else { #ifdef USE_GD assert( format->imagemode == MS_IMAGEMODE_PC256 && format->renderer == MS_RENDER_WITH_GD ); #else { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "GD not compiled in. This is a bug.", "msSaveImageGDAL()"); return MS_FAILURE; } #endif } /* -------------------------------------------------------------------- */ /* Create a memory dataset which we can use as a source for a */ /* CreateCopy(). */ /* -------------------------------------------------------------------- */ hMemDriver = GDALGetDriverByName( "MEM" ); if( hMemDriver == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to find MEM driver.", "msSaveImageGDAL()" ); return MS_FAILURE; } hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp", image->width, image->height, nBands, eDataType, NULL ); if( hMemDS == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to create MEM dataset.", "msSaveImageGDAL()" ); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* Copy the gd image into the memory dataset. */ /* -------------------------------------------------------------------- */ for( iLine = 0; iLine < image->height; iLine++ ) { int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 ); if( format->imagemode == MS_IMAGEMODE_INT16 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_16bit + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Int16, 2, 0 ); } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_float + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Float32, 4, 0 ); } else if( format->imagemode == MS_IMAGEMODE_BYTE ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_byte + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Byte, 1, 0 ); } #ifdef USE_GD else if(format->renderer == MS_RENDER_WITH_GD) { gdImagePtr img = (gdImagePtr)image->img.plugin; GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, img->pixels[iLine], image->width, 1, GDT_Byte, 0, 0 ); } #endif else { GByte *pabyData; unsigned char *pixptr = NULL; assert( rb.type == MS_BUFFER_BYTE_RGBA ); switch(iBand) { case 0: pixptr = rb.data.rgba.r; break; case 1: pixptr = rb.data.rgba.g; break; case 2: pixptr = rb.data.rgba.b; break; case 3: pixptr = rb.data.rgba.a; break; } assert(pixptr); if( pixptr == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Missing RGB or A buffer.\n", "msSaveImageGDAL()" ); return MS_FAILURE; } pabyData = (GByte *)(pixptr + iLine*rb.data.rgba.row_step); if( rb.data.rgba.a == NULL || iBand == 3 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, pabyData, image->width, 1, GDT_Byte, rb.data.rgba.pixel_step, 0 ); } else { /* We need to un-pre-multiple RGB by alpha. */ GByte *pabyUPM = (GByte*) malloc(image->width); GByte *pabyAlpha= (GByte *)(rb.data.rgba.a + iLine*rb.data.rgba.row_step); int i; for( i = 0; i < image->width; i++ ) { int alpha = pabyAlpha[i*rb.data.rgba.pixel_step]; if( alpha == 0 ) pabyUPM[i] = 0; else { int result = (pabyData[i*rb.data.rgba.pixel_step] * 255) / alpha; if( result > 255 ) result = 255; pabyUPM[i] = result; } } GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, pabyUPM, image->width, 1, GDT_Byte, 1, 0 ); free( pabyUPM ); } } } } if( pabyAlphaLine != NULL ) free( pabyAlphaLine ); /* -------------------------------------------------------------------- */ /* Attach the palette if appropriate. */ /* -------------------------------------------------------------------- */ #ifdef USE_GD if( format->renderer == MS_RENDER_WITH_GD ) { GDALColorEntry sEntry; int iColor; GDALColorTableH hCT; gdImagePtr img = (gdImagePtr)image->img.plugin; hCT = GDALCreateColorTable( GPI_RGB ); for( iColor = 0; iColor < img->colorsTotal; iColor++ ) { sEntry.c1 = img->red[iColor]; sEntry.c2 = img->green[iColor]; sEntry.c3 = img->blue[iColor]; if( iColor == gdImageGetTransparent( img ) ) sEntry.c4 = 0; else if( iColor == 0 && gdImageGetTransparent( img ) == -1 && format->transparent ) sEntry.c4 = 0; else sEntry.c4 = 255; GDALSetColorEntry( hCT, iColor, &sEntry ); } GDALSetRasterColorTable( GDALGetRasterBand( hMemDS, 1 ), hCT ); GDALDestroyColorTable( hCT ); } else #endif if( format->imagemode == MS_IMAGEMODE_RGB ) { GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand ); } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand ); } /* -------------------------------------------------------------------- */ /* Assign the projection and coordinate system to the memory */ /* dataset. */ /* -------------------------------------------------------------------- */ if( map != NULL ) { char *pszWKT; GDALSetGeoTransform( hMemDS, map->gt.geotransform ); pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); if( pszWKT != NULL ) { GDALSetProjection( hMemDS, pszWKT ); msFree( pszWKT ); } } /* -------------------------------------------------------------------- */ /* Possibly assign a nodata value. */ /* -------------------------------------------------------------------- */ if( msGetOutputFormatOption(format,"NULLVALUE",NULL) != NULL ) { int iBand; const char *nullvalue = msGetOutputFormatOption(format, "NULLVALUE",NULL); for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 ); GDALSetRasterNoDataValue( hBand, atof(nullvalue) ); } } /* -------------------------------------------------------------------- */ /* Try to save resolution in the output file. */ /* -------------------------------------------------------------------- */ if( image->resolution > 0 ) { char res[30]; sprintf( res, "%lf", image->resolution ); GDALSetMetadataItem( hMemDS, "TIFFTAG_XRESOLUTION", res, NULL ); GDALSetMetadataItem( hMemDS, "TIFFTAG_YRESOLUTION", res, NULL ); GDALSetMetadataItem( hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL ); } /* -------------------------------------------------------------------- */ /* Create a disk image in the selected output format from the */ /* memory image. */ /* -------------------------------------------------------------------- */ papszOptions = (char**)calloc(sizeof(char *),(format->numformatoptions+1)); if (papszOptions == NULL) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", (unsigned int)(sizeof(char *)*(format->numformatoptions+1))); return MS_FAILURE; } memcpy( papszOptions, format->formatoptions, sizeof(char *) * format->numformatoptions ); hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE, papszOptions, NULL, NULL ); free( papszOptions ); if( hOutputDS == NULL ) { GDALClose( hMemDS ); msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to create output %s file.\n%s", "msSaveImageGDAL()", format->driver+5, CPLGetLastErrorMsg() ); return MS_FAILURE; } /* closing the memory DS also frees all associated resources. */ GDALClose( hMemDS ); GDALClose( hOutputDS ); msReleaseLock( TLOCK_GDAL ); /* -------------------------------------------------------------------- */ /* Are we writing license info into the image? */ /* If so, add it to the temp file on disk now. */ /* -------------------------------------------------------------------- */ #ifdef USE_EXEMPI if ( bUseXmp == MS_TRUE ) { if( msXmpWrite(map, filename) == MS_FAILURE ) { /* Something bad happened. */ msSetError( MS_MISCERR, "XMP write to %s failed.\n", "msSaveImageGDAL()", filename); return MS_FAILURE; } } #endif /* -------------------------------------------------------------------- */ /* Is this supposed to be a temporary file? If so, stream to */ /* stdout and delete the file. */ /* -------------------------------------------------------------------- */ if( bFileIsTemporary ) { FILE *fp; unsigned char block[4000]; int bytes_read; if( msIO_needBinaryStdout() == MS_FAILURE ) return MS_FAILURE; /* We aren't sure how far back GDAL exports the VSI*L API, so we only use it if we suspect we need it. But we do need it if holding temporary file in memory. */ fp = VSIFOpenL( filename, "rb" ); if( fp == NULL ) { msSetError( MS_MISCERR, "Failed to open %s for streaming to stdout.", "msSaveImageGDAL()", filename ); return MS_FAILURE; } while( (bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0 ) msIO_fwrite( block, 1, bytes_read, stdout ); VSIFCloseL( fp ); VSIUnlink( filename ); CleanVSIDir( "/vsimem/msout" ); free( filename ); } return MS_SUCCESS; }
int msSaveImageIM(imageObj* img, char *filename, outputFormatObj *format ) { FILE *stream; char workbuffer[5000]; int nSize=0, size=0, iIndice=0; DEBUG_IF printf("msSaveImageIM\n<BR>"); if(filename != NULL && strlen(filename) > 0) { stream = fopen(filename, "wb"); if(!stream) { msSetError(MS_IOERR, "(%s)", "msSaveImage()", filename); return(MS_FAILURE); } } else { /* use stdout */ #ifdef _WIN32 /* * Change stdout mode to binary on win32 platforms */ if(_setmode( _fileno(stdout), _O_BINARY) == -1) { msSetError(MS_IOERR, "Unable to change stdout to binary mode.", "msSaveImage()"); return(MS_FAILURE); } #endif stream = stdout; } if( strcasecmp(format->driver,"imagemap") == 0 ) { DEBUG_IF printf("ALLOCD %d<BR>\n", img->size); /* DEBUG_IF printf("F %s<BR>\n", img->img.imagemap); */ DEBUG_IF printf("FLEN %d<BR>\n", (int)strlen(img->img.imagemap)); if (dxf == 2) { msIO_fprintf(stream, "%s", layerlist); } else if (dxf) { msIO_fprintf(stream, " 0\nSECTION\n 2\nHEADER\n 9\n$ACADVER\n 1\nAC1009\n0\nENDSEC\n 0\nSECTION\n 2\nTABLES\n 0\nTABLE\n%s0\nENDTAB\n0\nENDSEC\n 0\nSECTION\n 2\nBLOCKS\n0\nENDSEC\n 0\nSECTION\n 2\nENTITIES\n", layerlist); } else { msIO_fprintf(stream, "<map name=\"%s\" width=\"%d\" height=\"%d\">\n", mapName, img->width, img->height); } nSize = sizeof(workbuffer); size = strlen(img->img.imagemap); if (size > nSize) { iIndice = 0; while ((iIndice + nSize) <= size) { snprintf(workbuffer, sizeof(workbuffer), "%s", img->img.imagemap+iIndice ); workbuffer[nSize-1] = '\0'; msIO_fwrite(workbuffer, strlen(workbuffer), 1, stream); iIndice +=nSize-1; } if (iIndice < size) { sprintf(workbuffer, "%s", img->img.imagemap+iIndice ); msIO_fprintf(stream, "%s", workbuffer); } } else msIO_fwrite(img->img.imagemap, size, 1, stream); if( strcasecmp("OFF",msGetOutputFormatOption( format, "SKIPENDTAG", "OFF" )) == 0) { if (dxf == 2) msIO_fprintf(stream, "END"); else if (dxf) msIO_fprintf(stream, "0\nENDSEC\n0\nEOF\n"); else msIO_fprintf(stream, "</map>"); } } else { msSetError(MS_MISCERR, "Unknown output image type driver: %s.", "msSaveImage()", format->driver ); return(MS_FAILURE); } if(filename != NULL && strlen(filename) > 0) fclose(stream); return(MS_SUCCESS); }
/* * Utility function to create a IM image. Returns * a pointer to an imageObj structure. */ imageObj *msImageCreateIM(int width, int height, outputFormatObj *format, char *imagepath, char *imageurl, double resolution, double defresolution) { imageObj *image=NULL; if (setvbuf(stdout, NULL, _IONBF , 0)) { printf("Whoops..."); }; DEBUG_IF printf("msImageCreateIM<BR>\n"); if (width > 0 && height > 0) { image = (imageObj *)msSmallCalloc(1,sizeof(imageObj)); imgStr.string = &(image->img.imagemap); imgStr.alloc_size = &(image->size); image->format = format; format->refcount++; image->width = width; image->height = height; image->imagepath = NULL; image->imageurl = NULL; image->resolution = resolution; image->resolutionfactor = resolution/defresolution; if( strcasecmp("ON",msGetOutputFormatOption( format, "DXF", "OFF" )) == 0) { dxf = 1; im_iprintf(&layerStr, " 2\nLAYER\n 70\n 10\n"); } else dxf = 0; if( strcasecmp("ON",msGetOutputFormatOption( format, "SCRIPT", "OFF" )) == 0) { dxf = 2; im_iprintf(&layerStr, ""); } /* get href formation string options */ polyHrefFmt = makeFmtSafe(msGetOutputFormatOption ( format, "POLYHREF", "javascript:Clicked('%s');"), 1); polyMOverFmt = makeFmtSafe(msGetOutputFormatOption ( format, "POLYMOUSEOVER", ""), 1); polyMOutFmt = makeFmtSafe(msGetOutputFormatOption ( format, "POLYMOUSEOUT", ""), 1); symbolHrefFmt = makeFmtSafe(msGetOutputFormatOption ( format, "SYMBOLHREF", "javascript:SymbolClicked();"), 1); symbolMOverFmt = makeFmtSafe(msGetOutputFormatOption ( format, "SYMBOLMOUSEOVER", ""), 1); symbolMOutFmt = makeFmtSafe(msGetOutputFormatOption ( format, "SYMBOLMOUSEOUT", ""), 1); /* get name of client-side image map */ mapName = msGetOutputFormatOption ( format, "MAPNAME", "map1" ); /* should we suppress area declarations with no title? */ if( strcasecmp("YES",msGetOutputFormatOption( format, "SUPPRESS", "NO" )) == 0) { suppressEmpty=1; } lname = msStrdup("NONE"); *(imgStr.string) = msStrdup(""); if (*(imgStr.string)) { *(imgStr.alloc_size) = imgStr.string_len = strlen(*(imgStr.string)); } else { *(imgStr.alloc_size) = imgStr.string_len = 0; } if (imagepath) { image->imagepath = msStrdup(imagepath); } if (imageurl) { image->imageurl = msStrdup(imageurl); } return image; } else { msSetError(MS_IMGERR, "Cannot create IM image of size %d x %d.", "msImageCreateIM()", width, height ); } return image; }