475         FuncCallContext *funcctx;
 
  480         struct bandmetadata {
 
  492         struct bandmetadata *bmd = NULL;
 
  493         struct bandmetadata *bmd2 = NULL;
 
  498         if (SRF_IS_FIRSTCALL()) {
 
  499                 MemoryContext oldcontext;
 
  518                 uint32_t *bandNums = NULL;
 
  519                 const char *chartmp = NULL;
 
  526                 funcctx = SRF_FIRSTCALL_INIT();
 
  529                 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
  532                 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) {
 
  533                         MemoryContextSwitchTo(oldcontext);
 
  535                                 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 
  537                                         "function returning record called in context " 
  538                                         "that cannot accept type record" 
  543                 BlessTupleDesc(tupdesc);
 
  544                 funcctx->tuple_desc = tupdesc;
 
  547                 if (PG_ARGISNULL(0)) {
 
  548                         bmd = (
struct bandmetadata *) palloc(
sizeof(
struct bandmetadata));
 
  549                         bmd->isnullband = 
TRUE;
 
  550                         funcctx->user_fctx = bmd;
 
  551                         funcctx->max_calls = 1;
 
  552                         MemoryContextSwitchTo(oldcontext);
 
  555                 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
 
  560                         PG_FREE_IF_COPY(pgraster, 0);
 
  561                         MemoryContextSwitchTo(oldcontext);
 
  562                         elog(ERROR, 
"RASTER_bandmetadata: Could not deserialize raster");
 
  563                         SRF_RETURN_DONE(funcctx);
 
  569                         elog(NOTICE, 
"Raster provided has no bands");
 
  571                         PG_FREE_IF_COPY(pgraster, 0);
 
  572                         bmd = (
struct bandmetadata *) palloc(
sizeof(
struct bandmetadata));
 
  573                         bmd->isnullband = 
TRUE;
 
  574                         funcctx->user_fctx = bmd;
 
  575                         funcctx->max_calls = 1;
 
  576                         MemoryContextSwitchTo(oldcontext);
 
  581                 array = PG_GETARG_ARRAYTYPE_P(1);
 
  582                 etype = ARR_ELEMTYPE(array);
 
  583                 get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign);
 
  591                                 PG_FREE_IF_COPY(pgraster, 0);
 
  592                                 MemoryContextSwitchTo(oldcontext);
 
  593                                 elog(ERROR, 
"RASTER_bandmetadata: Invalid data type for band number(s)");
 
  594                                 SRF_RETURN_DONE(funcctx);
 
  598                 deconstruct_array(array, etype, typlen, typbyval, typalign, &e,
 
  601                 bandNums = palloc(
sizeof(uint32_t) * n);
 
  602                 for (i = 0, j = 0; i < n; i++) {
 
  603                         if (nulls[i]) 
continue;
 
  607                                         idx = (uint32_t) DatumGetInt16(e[i]);
 
  610                                         idx = (uint32_t) DatumGetInt32(e[i]);
 
  615                         if (idx > numBands || idx < 1) {
 
  616                                 elog(NOTICE, 
"Invalid band index: %d. Indices must be 1-based. Returning NULL", idx);
 
  619                                 PG_FREE_IF_COPY(pgraster, 0);
 
  620                                 bmd = (
struct bandmetadata *) palloc(
sizeof(
struct bandmetadata));
 
  621                                 bmd->isnullband = 
TRUE;
 
  622                                 funcctx->user_fctx = bmd;
 
  623                                 funcctx->max_calls = 1;
 
  624                                 MemoryContextSwitchTo(oldcontext);
 
  635                         bandNums = repalloc(bandNums, 
sizeof(uint32_t) * j);
 
  636                         for (i = 0; i < j; i++)
 
  640                         bandNums = repalloc(bandNums, 
sizeof(uint32_t) * j);
 
  642                 bmd = (
struct bandmetadata *) palloc0(
sizeof(
struct bandmetadata) * j);
 
  644                 for (i = 0; i < j; i++) {
 
  647                                 elog(NOTICE, 
"Could not get raster band at index %d", bandNums[i]);
 
  649                                 PG_FREE_IF_COPY(pgraster, 0);
 
  650                                 bmd[0].isnullband = 
TRUE;
 
  651                                 funcctx->user_fctx = bmd;
 
  652                                 funcctx->max_calls = 1;
 
  653                                 MemoryContextSwitchTo(oldcontext);
 
  658                         bmd[i].bandnum = bandNums[i];
 
  662                         charlen = strlen(chartmp) + 1;
 
  663                         bmd[i].pixeltype = palloc(
sizeof(
char) * charlen);
 
  664                         strncpy(bmd[i].pixeltype, chartmp, charlen);
 
  668                                 bmd[i].hasnodata = 
TRUE;
 
  670                                 bmd[i].hasnodata = 
FALSE;
 
  673                         if (bmd[i].hasnodata)
 
  676                                 bmd[i].nodataval = 0;
 
  681                                 charlen = strlen(chartmp) + 1;
 
  682                                 bmd[i].bandpath = palloc(
sizeof(
char) * charlen);
 
  683                                 strncpy(bmd[i].bandpath, chartmp, charlen);
 
  686                                 bmd[i].bandpath = NULL;
 
  689                         bmd[i].isoutdb = bmd[i].bandpath ? 
TRUE : 
FALSE;
 
  693                                 bmd[i].extbandnum = extbandnum + 1;
 
  695                                 bmd[i].extbandnum = 0;
 
  698                         bmd[i].timestamp = 0;
 
  701                             if( VSIStatL(bmd[i].bandpath, &sStat) == 0 ) {
 
  702                                 bmd[i].filesize = sStat.st_size;
 
  703                                 bmd[i].timestamp = sStat.st_mtime;
 
  711                 PG_FREE_IF_COPY(pgraster, 0);
 
  714                 funcctx->user_fctx = bmd;
 
  717                 funcctx->max_calls = j;
 
  719                 MemoryContextSwitchTo(oldcontext);
 
  725         funcctx = SRF_PERCALL_SETUP();
 
  727         call_cntr = funcctx->call_cntr;
 
  728         max_calls = funcctx->max_calls;
 
  729         tupdesc = funcctx->tuple_desc;
 
  730         bmd2 = funcctx->user_fctx;
 
  733         if (call_cntr < max_calls) {
 
  737                 if (bmd2[0].isnullband) {
 
  741                         result = HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls));
 
  742                         SRF_RETURN_NEXT(funcctx, 
result);
 
  747                 values[0] = UInt32GetDatum(bmd2[call_cntr].bandnum);
 
  748                 values[1] = CStringGetTextDatum(bmd2[call_cntr].pixeltype);
 
  750                 if (bmd2[call_cntr].hasnodata)
 
  751                         values[2] = Float8GetDatum(bmd2[call_cntr].nodataval);
 
  755                 values[3] = BoolGetDatum(bmd2[call_cntr].isoutdb);
 
  756                 if (bmd2[call_cntr].bandpath && strlen(bmd2[call_cntr].bandpath)) {
 
  757                         values[4] = CStringGetTextDatum(bmd2[call_cntr].bandpath);
 
  758                         values[5] = UInt32GetDatum(bmd2[call_cntr].extbandnum);
 
  765                 if (bmd2[call_cntr].filesize)
 
  767                         values[6] = UInt64GetDatum(bmd2[call_cntr].filesize);
 
  768                         values[7] = UInt64GetDatum(bmd2[call_cntr].timestamp);
 
  777                 tuple = heap_form_tuple(tupdesc, values, nulls);
 
  780                 result = HeapTupleGetDatum(tuple);
 
  783                 pfree(bmd2[call_cntr].pixeltype);
 
  784                 if (bmd2[call_cntr].bandpath) pfree(bmd2[call_cntr].bandpath);
 
  786                 SRF_RETURN_NEXT(funcctx, 
result);
 
  791                 SRF_RETURN_DONE(funcctx);
 
char result[OUT_DOUBLE_BUFFER_SIZE]
const char * rt_band_get_ext_path(rt_band band)
Return band's external path (only valid when rt_band_is_offline returns non-zero).
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
void rt_band_destroy(rt_band band)
Destroy a raster band.
uint16_t rt_raster_get_num_bands(rt_raster raster)
rt_errorstate rt_band_get_ext_band_num(rt_band band, uint8_t *bandnum)
Return bands' external band number (only valid when rt_band_is_offline returns non-zero).
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
const char * rt_pixtype_name(rt_pixtype pixtype)
rt_raster rt_raster_deserialize(void *serialized, int header_only)
Return a raster from a serialized form.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...
bool enable_outdb_rasters
#define POSTGIS_RT_DEBUG(level, msg)
#define POSTGIS_RT_DEBUGF(level, msg,...)