PostGIS  2.1.10dev-r@@SVN_REVISION@@
Datum RASTER_addBandRasterArray ( PG_FUNCTION_ARGS  )

Definition at line 5551 of file rt_pg.c.

References FALSE, POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, rtrowdump::raster, rt_raster_copy_band(), rt_raster_deserialize(), rt_raster_destroy(), rt_raster_from_band(), rt_raster_get_num_bands(), rt_raster_serialize(), rt_raster_serialized_t::size, and TRUE.

5552 {
5553  rt_pgraster *pgraster = NULL;
5554  rt_pgraster *pgsrc = NULL;
5555  rt_pgraster *pgrtn = NULL;
5556 
5557  rt_raster raster = NULL;
5558  rt_raster src = NULL;
5559 
5560  int srcnband = 1;
5561  bool appendband = FALSE;
5562  int dstnband = 1;
5563  int srcnumbands = 0;
5564  int dstnumbands = 0;
5565 
5566  ArrayType *array;
5567  Oid etype;
5568  Datum *e;
5569  bool *nulls;
5570  int16 typlen;
5571  bool typbyval;
5572  char typalign;
5573  int n = 0;
5574 
5575  int rtn = 0;
5576  int i = 0;
5577 
5578  /* destination raster */
5579  if (!PG_ARGISNULL(0)) {
5580  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
5581 
5582  /* raster */
5583  raster = rt_raster_deserialize(pgraster, FALSE);
5584  if (!raster) {
5585  PG_FREE_IF_COPY(pgraster, 0);
5586  elog(ERROR, "RASTER_addBandRasterArray: Could not deserialize destination raster");
5587  PG_RETURN_NULL();
5588  }
5589 
5590  POSTGIS_RT_DEBUG(4, "destination raster isn't NULL");
5591  }
5592 
5593  /* source rasters' band index, 1-based */
5594  if (!PG_ARGISNULL(2))
5595  srcnband = PG_GETARG_INT32(2);
5596  if (srcnband < 1) {
5597  elog(NOTICE, "Invalid band index for source rasters (must be 1-based). Returning original raster");
5598  if (raster != NULL) {
5599  rt_raster_destroy(raster);
5600  PG_RETURN_POINTER(pgraster);
5601  }
5602  else
5603  PG_RETURN_NULL();
5604  }
5605  POSTGIS_RT_DEBUGF(4, "srcnband = %d", srcnband);
5606 
5607  /* destination raster's band index, 1-based */
5608  if (!PG_ARGISNULL(3)) {
5609  dstnband = PG_GETARG_INT32(3);
5610  appendband = FALSE;
5611 
5612  if (dstnband < 1) {
5613  elog(NOTICE, "Invalid band index for destination raster (must be 1-based). Returning original raster");
5614  if (raster != NULL) {
5615  rt_raster_destroy(raster);
5616  PG_RETURN_POINTER(pgraster);
5617  }
5618  else
5619  PG_RETURN_NULL();
5620  }
5621  }
5622  else
5623  appendband = TRUE;
5624 
5625  /* additional processing of dstnband */
5626  if (raster != NULL) {
5627  dstnumbands = rt_raster_get_num_bands(raster);
5628 
5629  if (dstnumbands < 1) {
5630  appendband = TRUE;
5631  dstnband = 1;
5632  }
5633  else if (appendband)
5634  dstnband = dstnumbands + 1;
5635  else if (dstnband > dstnumbands) {
5636  elog(NOTICE, "Band index provided for destination raster is greater than the number of bands in the raster. Bands will be appended");
5637  appendband = TRUE;
5638  dstnband = dstnumbands + 1;
5639  }
5640  }
5641  POSTGIS_RT_DEBUGF(4, "appendband = %d", appendband);
5642  POSTGIS_RT_DEBUGF(4, "dstnband = %d", dstnband);
5643 
5644  /* process set of source rasters */
5645  POSTGIS_RT_DEBUG(3, "Processing array of source rasters");
5646  array = PG_GETARG_ARRAYTYPE_P(1);
5647  etype = ARR_ELEMTYPE(array);
5648  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
5649 
5650  deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
5651  &nulls, &n);
5652 
5653  /* decrement srcnband and dstnband by 1, now 0-based */
5654  srcnband--;
5655  dstnband--;
5656  POSTGIS_RT_DEBUGF(4, "0-based nband (src, dst) = (%d, %d)", srcnband, dstnband);
5657 
5658  /* time to copy bands */
5659  for (i = 0; i < n; i++) {
5660  if (nulls[i]) continue;
5661  src = NULL;
5662 
5663  pgsrc = (rt_pgraster *) PG_DETOAST_DATUM(e[i]);
5664  src = rt_raster_deserialize(pgsrc, FALSE);
5665  if (src == NULL) {
5666  pfree(nulls);
5667  pfree(e);
5668  if (raster != NULL)
5669  rt_raster_destroy(raster);
5670  if (pgraster != NULL)
5671  PG_FREE_IF_COPY(pgraster, 0);
5672  elog(ERROR, "RASTER_addBandRasterArray: Could not deserialize source raster at index %d", i + 1);
5673  PG_RETURN_NULL();
5674  }
5675 
5676  srcnumbands = rt_raster_get_num_bands(src);
5677  POSTGIS_RT_DEBUGF(4, "source raster %d has %d bands", i + 1, srcnumbands);
5678 
5679  /* band index isn't valid */
5680  if (srcnband > srcnumbands - 1) {
5681  elog(NOTICE, "Invalid band index for source raster at index %d. Returning original raster", i + 1);
5682  pfree(nulls);
5683  pfree(e);
5684  rt_raster_destroy(src);
5685  if (raster != NULL) {
5686  rt_raster_destroy(raster);
5687  PG_RETURN_POINTER(pgraster);
5688  }
5689  else
5690  PG_RETURN_NULL();
5691  }
5692 
5693  /* destination raster is empty, new raster */
5694  if (raster == NULL) {
5695  uint32_t srcnbands[1] = {srcnband};
5696 
5697  POSTGIS_RT_DEBUG(4, "empty destination raster, using rt_raster_from_band");
5698 
5699  raster = rt_raster_from_band(src, srcnbands, 1);
5700  rt_raster_destroy(src);
5701  if (raster == NULL) {
5702  pfree(nulls);
5703  pfree(e);
5704  if (pgraster != NULL)
5705  PG_FREE_IF_COPY(pgraster, 0);
5706  elog(ERROR, "RASTER_addBandRasterArray: Could not create raster from source raster at index %d", i + 1);
5707  PG_RETURN_NULL();
5708  }
5709  }
5710  /* copy band */
5711  else {
5712  rtn = rt_raster_copy_band(
5713  raster, src,
5714  srcnband, dstnband
5715  );
5716  rt_raster_destroy(src);
5717 
5718  if (rtn == -1 || rt_raster_get_num_bands(raster) == dstnumbands) {
5719  elog(NOTICE, "Could not add band from source raster at index %d to destination raster. Returning original raster", i + 1);
5720  rt_raster_destroy(raster);
5721  pfree(nulls);
5722  pfree(e);
5723  if (pgraster != NULL)
5724  PG_RETURN_POINTER(pgraster);
5725  else
5726  PG_RETURN_NULL();
5727  }
5728  }
5729 
5730  dstnband++;
5731  dstnumbands++;
5732  }
5733 
5734  if (raster != NULL) {
5735  pgrtn = rt_raster_serialize(raster);
5736  rt_raster_destroy(raster);
5737  if (pgraster != NULL)
5738  PG_FREE_IF_COPY(pgraster, 0);
5739  if (!pgrtn)
5740  PG_RETURN_NULL();
5741 
5742  SET_VARSIZE(pgrtn, pgrtn->size);
5743  PG_RETURN_POINTER(pgrtn);
5744  }
5745 
5746  PG_RETURN_NULL();
5747 }
int rt_raster_get_num_bands(rt_raster raster)
Definition: rt_api.c:5677
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_api.c:8158
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_api.c:5387
int rt_raster_copy_band(rt_raster torast, rt_raster fromrast, int fromindex, int toindex)
Copy one band from one raster to another.
Definition: rt_api.c:8582
tuple raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:123
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rt_pg.h:58
rt_raster rt_raster_from_band(rt_raster raster, uint32_t *bandNums, int count)
Construct a new rt_raster from an existing rt_raster and an array of band numbers.
Definition: rt_api.c:8643
#define FALSE
Definition: dbfopen.c:169
Struct definitions.
Definition: rt_api.h:2175
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rt_pg.h:62
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_api.c:8350
#define TRUE
Definition: dbfopen.c:170

Here is the call graph for this function: