PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ RASTER_addBandRasterArray()

Datum RASTER_addBandRasterArray ( PG_FUNCTION_ARGS  )

Definition at line 344 of file rtpg_create.c.

345 {
346  rt_pgraster *pgraster = NULL;
347  rt_pgraster *pgsrc = NULL;
348  rt_pgraster *pgrtn = NULL;
349 
350  rt_raster raster = NULL;
351  rt_raster src = NULL;
352 
353  int srcnband = 1;
354  bool appendband = FALSE;
355  int dstnband = 1;
356  int srcnumbands = 0;
357  int dstnumbands = 0;
358 
359  ArrayType *array;
360  Oid etype;
361  Datum *e;
362  bool *nulls;
363  int16 typlen;
364  bool typbyval;
365  char typalign;
366  int n = 0;
367 
368  int rtn = 0;
369  int i = 0;
370 
371  /* destination raster */
372  if (!PG_ARGISNULL(0)) {
373  pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
374 
375  /* raster */
376  raster = rt_raster_deserialize(pgraster, FALSE);
377  if (!raster) {
378  PG_FREE_IF_COPY(pgraster, 0);
379  elog(ERROR, "RASTER_addBandRasterArray: Could not deserialize destination raster");
380  PG_RETURN_NULL();
381  }
382 
383  POSTGIS_RT_DEBUG(4, "destination raster isn't NULL");
384  }
385 
386  if (PG_ARGISNULL(1))
387  {
388  if (raster != NULL)
389  {
391  PG_RETURN_POINTER(pgraster);
392  }
393  else
394  PG_RETURN_NULL();
395  }
396 
397  /* source rasters' band index, 1-based */
398  if (!PG_ARGISNULL(2))
399  srcnband = PG_GETARG_INT32(2);
400  if (srcnband < 1) {
401  elog(NOTICE, "Invalid band index for source rasters (must be 1-based). Returning original raster");
402  if (raster != NULL) {
404  PG_RETURN_POINTER(pgraster);
405  }
406  else
407  PG_RETURN_NULL();
408  }
409  POSTGIS_RT_DEBUGF(4, "srcnband = %d", srcnband);
410 
411  /* destination raster's band index, 1-based */
412  if (!PG_ARGISNULL(3)) {
413  dstnband = PG_GETARG_INT32(3);
414  appendband = FALSE;
415 
416  if (dstnband < 1) {
417  elog(NOTICE, "Invalid band index for destination raster (must be 1-based). Returning original raster");
418  if (raster != NULL) {
420  PG_RETURN_POINTER(pgraster);
421  }
422  else
423  PG_RETURN_NULL();
424  }
425  }
426  else
427  appendband = TRUE;
428 
429  /* additional processing of dstnband */
430  if (raster != NULL) {
431  dstnumbands = rt_raster_get_num_bands(raster);
432 
433  if (dstnumbands < 1) {
434  appendband = TRUE;
435  dstnband = 1;
436  }
437  else if (appendband)
438  dstnband = dstnumbands + 1;
439  else if (dstnband > dstnumbands) {
440  elog(NOTICE, "Band index provided for destination raster is greater than the number of bands in the raster. Bands will be appended");
441  appendband = TRUE;
442  dstnband = dstnumbands + 1;
443  }
444  }
445  POSTGIS_RT_DEBUGF(4, "appendband = %d", appendband);
446  POSTGIS_RT_DEBUGF(4, "dstnband = %d", dstnband);
447 
448  /* process set of source rasters */
449  POSTGIS_RT_DEBUG(3, "Processing array of source rasters");
450  array = PG_GETARG_ARRAYTYPE_P(1);
451  etype = ARR_ELEMTYPE(array);
452  get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
453 
454  deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
455  &nulls, &n);
456 
457  /* decrement srcnband and dstnband by 1, now 0-based */
458  srcnband--;
459  dstnband--;
460  POSTGIS_RT_DEBUGF(4, "0-based nband (src, dst) = (%d, %d)", srcnband, dstnband);
461 
462  /* time to copy bands */
463  for (i = 0; i < n; i++) {
464  if (nulls[i]) continue;
465  src = NULL;
466 
467  pgsrc = (rt_pgraster *) PG_DETOAST_DATUM(e[i]);
468  src = rt_raster_deserialize(pgsrc, FALSE);
469  if (src == NULL) {
470  pfree(nulls);
471  pfree(e);
472  if (raster != NULL)
474  if (pgraster != NULL)
475  PG_FREE_IF_COPY(pgraster, 0);
476  elog(ERROR, "RASTER_addBandRasterArray: Could not deserialize source raster at index %d", i + 1);
477  PG_RETURN_NULL();
478  }
479 
480  srcnumbands = rt_raster_get_num_bands(src);
481  POSTGIS_RT_DEBUGF(4, "source raster %d has %d bands", i + 1, srcnumbands);
482 
483  /* band index isn't valid */
484  if (srcnband > srcnumbands - 1) {
485  elog(NOTICE, "Invalid band index for source raster at index %d. Returning original raster", i + 1);
486  pfree(nulls);
487  pfree(e);
488  rt_raster_destroy(src);
489  if (raster != NULL) {
491  PG_RETURN_POINTER(pgraster);
492  }
493  else
494  PG_RETURN_NULL();
495  }
496 
497  /* destination raster is empty, new raster */
498  if (raster == NULL) {
499  uint32_t srcnbands[1] = {srcnband};
500 
501  POSTGIS_RT_DEBUG(4, "empty destination raster, using rt_raster_from_band");
502 
503  raster = rt_raster_from_band(src, srcnbands, 1);
504  rt_raster_destroy(src);
505  if (raster == NULL) {
506  pfree(nulls);
507  pfree(e);
508  if (pgraster != NULL)
509  PG_FREE_IF_COPY(pgraster, 0);
510  elog(ERROR, "RASTER_addBandRasterArray: Could not create raster from source raster at index %d", i + 1);
511  PG_RETURN_NULL();
512  }
513  }
514  /* copy band */
515  else {
516  rtn = rt_raster_copy_band(
517  raster, src,
518  srcnband, dstnband
519  );
520  rt_raster_destroy(src);
521 
522  if (rtn == -1 || rt_raster_get_num_bands(raster) == dstnumbands) {
523  elog(NOTICE, "Could not add band from source raster at index %d to destination raster. Returning original raster", i + 1);
525  pfree(nulls);
526  pfree(e);
527  if (pgraster != NULL)
528  PG_RETURN_POINTER(pgraster);
529  else
530  PG_RETURN_NULL();
531  }
532  }
533 
534  dstnband++;
535  dstnumbands++;
536  }
537 
538  if (raster != NULL) {
539  pgrtn = rt_raster_serialize(raster);
541  if (pgraster != NULL)
542  PG_FREE_IF_COPY(pgraster, 0);
543  if (!pgrtn)
544  PG_RETURN_NULL();
545 
546  SET_VARSIZE(pgrtn, pgrtn->size);
547  PG_RETURN_POINTER(pgrtn);
548  }
549 
550  PG_RETURN_NULL();
551 }
#define TRUE
Definition: dbfopen.c:169
#define FALSE
Definition: dbfopen.c:168
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
Definition: rt_serialize.c:521
uint16_t rt_raster_get_num_bands(rt_raster raster)
Definition: rt_raster.c:372
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_raster.c:1435
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_raster.c:1370
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
Definition: rt_serialize.c:725
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
Definition: rtrowdump.py:121
#define POSTGIS_RT_DEBUG(level, msg)
Definition: rtpostgis.h:61
#define POSTGIS_RT_DEBUGF(level, msg,...)
Definition: rtpostgis.h:65
Struct definitions.
Definition: librtcore.h:2250
unsigned int uint32_t
Definition: uthash.h:78

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.

Here is the call graph for this function: