4125{
4128 char *junk = NULL;
4130
4132
4133
4134 if (PG_ARGISNULL(0))
4135 PG_RETURN_NULL();
4136
4137
4139 if (arg == NULL) {
4140 elog(ERROR, "RASTER_colorMap: Could not initialize argument structure");
4141 PG_RETURN_NULL();
4142 }
4143
4144
4145 pgraster = (
rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
4146
4147
4151 PG_FREE_IF_COPY(pgraster, 0);
4152 elog(ERROR, "RASTER_colorMap: Could not deserialize raster");
4153 PG_RETURN_NULL();
4154 }
4155
4156
4157 if (!PG_ARGISNULL(1))
4158 arg->
nband = PG_GETARG_INT32(1);
4160
4161
4163 elog(NOTICE,
"Raster does not have band at index %d. Returning empty raster", arg->
nband);
4164
4166 if (raster == NULL) {
4168 PG_FREE_IF_COPY(pgraster, 0);
4169 elog(ERROR, "RASTER_colorMap: Could not create empty raster");
4170 PG_RETURN_NULL();
4171 }
4172
4174 PG_FREE_IF_COPY(pgraster, 0);
4175
4178 if (pgraster == NULL)
4179 PG_RETURN_NULL();
4180
4181 SET_VARSIZE(pgraster, ((
rt_pgraster*) pgraster)->size);
4182 PG_RETURN_POINTER(pgraster);
4183 }
4184
4185
4187 if (arg->
band == NULL) {
4190 PG_FREE_IF_COPY(pgraster, 0);
4191 elog(ERROR, "RASTER_colorMap: Could not get band at index %d", nband);
4192 PG_RETURN_NULL();
4193 }
4194
4195
4196 if (!PG_ARGISNULL(3)) {
4197 char *method = NULL;
4200
4202 pfree(tmp);
4204
4205 if (strcmp(method, "INTERPOLATE") == 0)
4207 else if (strcmp(method, "EXACT") == 0)
4209 else if (strcmp(method, "NEAREST") == 0)
4211 else {
4212 elog(NOTICE, "Unknown value provided for method. Defaulting to INTERPOLATE");
4214 }
4215 }
4216
4217 else
4220
4221
4222 if (PG_ARGISNULL(2)) {
4224 PG_FREE_IF_COPY(pgraster, 0);
4225 elog(ERROR, "RASTER_colorMap: Value must be provided for colormap");
4226 PG_RETURN_NULL();
4227 }
4228 else {
4229 char *tmp = NULL;
4231 char *_entry;
4232 char *_element;
4233 uint32_t i = 0;
4234 uint32_t j = 0;
4235
4237
4238
4239 if (!strlen(colormap)) {
4241 PG_FREE_IF_COPY(pgraster, 0);
4242 elog(ERROR, "RASTER_colorMap: Value must be provided for colormap");
4243 PG_RETURN_NULL();
4244 }
4245
4247 pfree(colormap);
4250 PG_FREE_IF_COPY(pgraster, 0);
4251 elog(ERROR, "RASTER_colorMap: Could not process the value provided for colormap");
4252 PG_RETURN_NULL();
4253 }
4254
4255
4259 PG_FREE_IF_COPY(pgraster, 0);
4260 elog(ERROR, "RASTER_colorMap: Could not allocate memory for colormap entries");
4261 PG_RETURN_NULL();
4262 }
4264
4265
4266 for (i = 0; i < arg->
nentry; i++) {
4267
4270 pfree(tmp);
4272 pfree(_entry);
4274 pfree(tmp);
4275
4278
4279
4280 if (!strlen(_entry)) {
4282 pfree(_entry);
4283 continue;
4284 }
4285
4287 pfree(_entry);
4290 PG_FREE_IF_COPY(pgraster, 0);
4291 elog(ERROR, "RASTER_colorMap: Could not process colormap entry %d", i + 1);
4292 PG_RETURN_NULL();
4293 }
4295 elog(NOTICE, "More than five elements in colormap entry %d. Using at most five elements", i + 1);
4297 }
4298
4299
4302
4303
4304 for (j = 0; j < arg->
nelement; j++) {
4305
4310
4311
4312 if (j == 0) {
4313 char *percent = NULL;
4314
4315
4316 if (
4317 strcmp(_element, "NV") == 0 ||
4318 strcmp(_element, "NULL") == 0 ||
4319 strcmp(_element, "NODATA") == 0
4320 ) {
4322
4324 elog(NOTICE, "More than one NODATA entry found. Using only the first one");
4325 }
4326 else {
4328
4330 }
4331 }
4332
4333 else if ((percent = strchr(_element, '%')) != NULL) {
4336
4337
4340
4343 pfree(_element);
4345 PG_FREE_IF_COPY(pgraster, 0);
4346 elog(ERROR, "RASTER_colorMap: Could not get band's summary stats to process percentages");
4347 PG_RETURN_NULL();
4348 }
4349 }
4350
4351
4352 tmp = palloc(sizeof(char) * (percent - _element + 1));
4353 if (tmp == NULL) {
4354 pfree(_element);
4356 PG_FREE_IF_COPY(pgraster, 0);
4357 elog(ERROR, "RASTER_colorMap: Could not allocate memory for value of percentage");
4358 PG_RETURN_NULL();
4359 }
4360
4361 memcpy(tmp, _element, percent - _element);
4362 tmp[percent - _element] = '\0';
4364
4365
4366 errno = 0;
4367 value = strtod(tmp, NULL);
4368 pfree(tmp);
4369 if (errno != 0 || _element == junk) {
4370 pfree(_element);
4372 PG_FREE_IF_COPY(pgraster, 0);
4373 elog(ERROR, "RASTER_colorMap: Could not process percent string to value");
4374 PG_RETURN_NULL();
4375 }
4376
4377
4378 if (value < 0.) {
4379 elog(NOTICE, "Percentage values cannot be less than zero. Defaulting to zero");
4381 }
4382 else if (value > 100.) {
4383 elog(NOTICE, "Percentage values cannot be greater than 100. Defaulting to 100");
4385 }
4386
4387
4388
4390 }
4391
4392 else {
4393 errno = 0;
4395 if (errno != 0 || _element == junk) {
4396 pfree(_element);
4398 PG_FREE_IF_COPY(pgraster, 0);
4399 elog(ERROR, "RASTER_colorMap: Could not process string to value");
4400 PG_RETURN_NULL();
4401 }
4402 }
4403
4404 }
4405
4406 else {
4408
4409 errno = 0;
4410 value = (int) strtod(_element, &junk);
4411 if (errno != 0 || _element == junk) {
4412 pfree(_element);
4414 PG_FREE_IF_COPY(pgraster, 0);
4415 elog(ERROR, "RASTER_colorMap: Could not process string to value");
4416 PG_RETURN_NULL();
4417 }
4418
4419 if (value > 255) {
4420 elog(NOTICE, "RGBA value cannot be greater than 255. Defaulting to 255");
4422 }
4423 else if (value < 0) {
4424 elog(NOTICE, "RGBA value cannot be less than zero. Defaulting to zero");
4426 }
4428 }
4429
4430 pfree(_element);
4431 }
4432
4433 POSTGIS_RT_DEBUGF(4,
"colormap->entry[%d] (isnodata, value, R, G, B, A) = (%d, %f, %d, %d, %d, %d)",
4441 );
4442
4444 }
4445
4448 }
4449
4450
4452 if (raster == NULL) {
4454 PG_FREE_IF_COPY(pgraster, 0);
4455 elog(ERROR, "RASTER_colorMap: Could not create new raster with applied colormap");
4456 PG_RETURN_NULL();
4457 }
4458
4460 PG_FREE_IF_COPY(pgraster, 0);
4463
4465
4466 if (pgraster == NULL)
4467 PG_RETURN_NULL();
4468
4469 SET_VARSIZE(pgraster, ((
rt_pgraster*) pgraster)->size);
4470 PG_RETURN_POINTER(pgraster);
4471}
rt_raster rt_raster_colormap(rt_raster raster, int nband, rt_colormap colormap)
Returns a new raster with up to four 8BUI bands (RGBA) from applying a colormap to the user-specified...
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
int rt_raster_has_band(rt_raster raster, int nband)
Return TRUE if the raster has a band of this number.
rt_raster rt_raster_clone(rt_raster raster, uint8_t deep)
Clone an existing raster.
void * rt_raster_serialize(rt_raster raster)
Return this raster in serialized form.
rt_bandstats rt_band_get_summary_stats(rt_band band, int exclude_nodata_value, double sample, int inc_vals, uint64_t *cK, double *cM, double *cQ)
Compute summary statistics for a band.
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): ...
char * text_to_cstring(const text *textptr)
char ** rtpg_strsplit(const char *str, const char *delimiter, uint32_t *n)
char * rtpg_strreplace(const char *str, const char *oldstr, const char *newstr, int *count)
char * rtpg_trim(const char *input)
char * rtpg_strtoupper(char *str)
static void rtpg_colormap_arg_destroy(rtpg_colormap_arg arg)
static rtpg_colormap_arg rtpg_colormap_arg_init()
#define POSTGIS_RT_DEBUG(level, msg)
#define POSTGIS_RT_DEBUGF(level, msg,...)
enum rt_colormap_t::@9 method