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

Definition at line 7853 of file rt_pg.c.

References FALSE, rt_raster_serialized_t::numBands, POSTGIS_RT_DEBUGF, rtpixdump::rast, rtrowdump::raster, 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.

7854 {
7855  rt_pgraster *pgraster;
7856  rt_pgraster *pgrast;
7857  rt_raster raster;
7858  rt_raster rast;
7859 
7860  bool skip = FALSE;
7861  ArrayType *array;
7862  Oid etype;
7863  Datum *e;
7864  bool *nulls;
7865  int16 typlen;
7866  bool typbyval;
7867  char typalign;
7868 
7869  uint32_t numBands;
7870  uint32_t *bandNums;
7871  uint32 idx = 0;
7872  int n;
7873  int i = 0;
7874  int j = 0;
7875 
7876  if (PG_ARGISNULL(0))
7877  PG_RETURN_NULL();
7878  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
7879 
7880  raster = rt_raster_deserialize(pgraster, FALSE);
7881  if (!raster) {
7882  PG_FREE_IF_COPY(pgraster, 0);
7883  elog(ERROR, "RASTER_band: Could not deserialize raster");
7884  PG_RETURN_NULL();
7885  }
7886 
7887  /* process bandNums */
7888  if (PG_ARGISNULL(1)) {
7889  elog(NOTICE, "Band number(s) not provided. Returning original raster");
7890  skip = TRUE;
7891  }
7892  do {
7893  if (skip) break;
7894 
7895  numBands = rt_raster_get_num_bands(raster);
7896 
7897  array = PG_GETARG_ARRAYTYPE_P(1);
7898  etype = ARR_ELEMTYPE(array);
7899  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
7900 
7901  switch (etype) {
7902  case INT2OID:
7903  case INT4OID:
7904  break;
7905  default:
7906  rt_raster_destroy(raster);
7907  PG_FREE_IF_COPY(pgraster, 0);
7908  elog(ERROR, "RASTER_band: Invalid data type for band number(s)");
7909  PG_RETURN_NULL();
7910  break;
7911  }
7912 
7913  deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
7914  &nulls, &n);
7915 
7916  bandNums = palloc(sizeof(uint32_t) * n);
7917  for (i = 0, j = 0; i < n; i++) {
7918  if (nulls[i]) continue;
7919 
7920  switch (etype) {
7921  case INT2OID:
7922  idx = (uint32_t) DatumGetInt16(e[i]);
7923  break;
7924  case INT4OID:
7925  idx = (uint32_t) DatumGetInt32(e[i]);
7926  break;
7927  }
7928 
7929  POSTGIS_RT_DEBUGF(3, "band idx (before): %d", idx);
7930  if (idx > numBands || idx < 1) {
7931  elog(NOTICE, "Invalid band index (must use 1-based). Returning original raster");
7932  skip = TRUE;
7933  break;
7934  }
7935 
7936  bandNums[j] = idx - 1;
7937  POSTGIS_RT_DEBUGF(3, "bandNums[%d] = %d", j, bandNums[j]);
7938  j++;
7939  }
7940 
7941  if (skip || j < 1) {
7942  pfree(bandNums);
7943  skip = TRUE;
7944  }
7945  }
7946  while (0);
7947 
7948  if (!skip) {
7949  rast = rt_raster_from_band(raster, bandNums, j);
7950  pfree(bandNums);
7951  rt_raster_destroy(raster);
7952  PG_FREE_IF_COPY(pgraster, 0);
7953  if (!rast) {
7954  elog(ERROR, "RASTER_band: Could not create new raster");
7955  PG_RETURN_NULL();
7956  }
7957 
7958  pgrast = rt_raster_serialize(rast);
7959  rt_raster_destroy(rast);
7960 
7961  if (!pgrast)
7962  PG_RETURN_NULL();
7963 
7964  SET_VARSIZE(pgrast, pgrast->size);
7965  PG_RETURN_POINTER(pgrast);
7966  }
7967 
7968  PG_RETURN_POINTER(pgraster);
7969 }
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
tuple rast
Definition: rtpixdump.py:62
tuple raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:123
unsigned int uint32
Definition: shpopen.c:274
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: