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);
  }

}
Exemple #2
0
/*
 * 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;
}
Exemple #3
0
/* 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;
}
Exemple #4
0
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;
}
Exemple #5
0
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 );
}
Exemple #6
0
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 ++;
  }
}
Exemple #7
0
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
}
Exemple #8
0
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;
}
Exemple #9
0
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);
}
Exemple #10
0
/*
 * 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;
}