PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ RASTER_addBandRasterArray()

Datum RASTER_addBandRasterArray ( PG_FUNCTION_ARGS  )

Definition at line 344 of file rtpg_create.c.

References FALSE, PG_FUNCTION_INFO_V1(), POSTGIS_RT_DEBUG, POSTGIS_RT_DEBUGF, rtrowdump::raster, RASTER_addBandOutDB(), 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.

Referenced by RASTER_addBand().

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