PostGIS  2.2.7dev-r@@SVN_REVISION@@
rt_band.c
Go to the documentation of this file.
1 /*
2  *
3  * WKTRaster - Raster Types for PostGIS
4  * http://trac.osgeo.org/postgis/wiki/WKTRaster
5  *
6  * Copyright (C) 2011-2013 Regents of the University of California
7  * <bkpark@ucdavis.edu>
8  * Copyright (C) 2010-2011 Jorge Arevalo <jorge.arevalo@deimos-space.com>
9  * Copyright (C) 2010-2011 David Zwarg <dzwarg@azavea.com>
10  * Copyright (C) 2009-2011 Pierre Racine <pierre.racine@sbf.ulaval.ca>
11  * Copyright (C) 2009-2011 Mateusz Loskot <mateusz@loskot.net>
12  * Copyright (C) 2008-2009 Sandro Santilli <strk@keybit.net>
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software Foundation,
26  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27  *
28  */
29 
30 #include <stdio.h>
31 
32 #include "librtcore.h"
33 #include "librtcore_internal.h"
34 
35 #include "gdal_vrt.h"
36 
57 rt_band
59  uint16_t width, uint16_t height,
60  rt_pixtype pixtype,
61  uint32_t hasnodata, double nodataval,
62  uint8_t* data
63 ) {
64  rt_band band = NULL;
65 
66  assert(NULL != data);
67 
68  band = rtalloc(sizeof(struct rt_band_t));
69  if (band == NULL) {
70  rterror("rt_band_new_inline: Out of memory allocating rt_band");
71  return NULL;
72  }
73 
74  RASTER_DEBUGF(3, "Created rt_band @ %p with pixtype %s", band, rt_pixtype_name(pixtype));
75 
76  band->pixtype = pixtype;
77  band->offline = 0;
78  band->width = width;
79  band->height = height;
80  band->hasnodata = hasnodata ? 1 : 0;
81  band->isnodata = FALSE; /* we don't know what is in data, so must be FALSE */
82  band->nodataval = 0;
83  band->data.mem = data;
84  band->ownsdata = 0; /* we do NOT own this data!!! */
85  band->raster = NULL;
86 
87  RASTER_DEBUGF(3, "Created rt_band with dimensions %d x %d", band->width, band->height);
88 
89  /* properly set nodataval as it may need to be constrained to the data type */
90  if (hasnodata && rt_band_set_nodata(band, nodataval, NULL) != ES_NONE) {
91  rterror("rt_band_new_inline: Could not set NODATA value");
92  rt_band_destroy(band);
93  return NULL;
94  }
95 
96  return band;
97 }
98 
118 rt_band
120  uint16_t width, uint16_t height,
121  rt_pixtype pixtype,
122  uint32_t hasnodata, double nodataval,
123  uint8_t bandNum, const char* path
124 ) {
125  rt_band band = NULL;
126  int pathlen = 0;
127 
128  assert(NULL != path);
129 
130  band = rtalloc(sizeof(struct rt_band_t));
131  if (band == NULL) {
132  rterror("rt_band_new_offline: Out of memory allocating rt_band");
133  return NULL;
134  }
135 
136  RASTER_DEBUGF(3, "Created rt_band @ %p with pixtype %s",
137  band, rt_pixtype_name(pixtype)
138  );
139 
140  band->pixtype = pixtype;
141  band->offline = 1;
142  band->width = width;
143  band->height = height;
144  band->hasnodata = hasnodata ? 1 : 0;
145  band->nodataval = 0;
146  band->isnodata = FALSE; /* we don't know if the offline band is NODATA */
147  band->ownsdata = 0; /* offline, flag is useless as all offline data cache is owned internally */
148  band->raster = NULL;
149 
150  /* properly set nodataval as it may need to be constrained to the data type */
151  if (hasnodata && rt_band_set_nodata(band, nodataval, NULL) != ES_NONE) {
152  rterror("rt_band_new_offline: Could not set NODATA value");
153  rt_band_destroy(band);
154  return NULL;
155  }
156 
157  band->data.offline.bandNum = bandNum;
158 
159  /* memory for data.offline.path is managed internally */
160  pathlen = strlen(path);
161  band->data.offline.path = rtalloc(sizeof(char) * (pathlen + 1));
162  if (band->data.offline.path == NULL) {
163  rterror("rt_band_new_offline: Out of memory allocating offline path");
164  rt_band_destroy(band);
165  return NULL;
166  }
167  memcpy(band->data.offline.path, path, pathlen);
168  band->data.offline.path[pathlen] = '\0';
169 
170  band->data.offline.mem = NULL;
171 
172  return band;
173 }
174 
185 rt_band
187  rt_band rtn = NULL;
188 
189  assert(band != NULL);
190 
191  /* offline */
192  if (band->offline) {
193  rtn = rt_band_new_offline(
194  band->width, band->height,
195  band->pixtype,
196  band->hasnodata, band->nodataval,
197  band->data.offline.bandNum, (const char *) band->data.offline.path
198  );
199  }
200  /* online */
201  else {
202  uint8_t *data = NULL;
203  data = rtalloc(rt_pixtype_size(band->pixtype) * band->width * band->height);
204  if (data == NULL) {
205  rterror("rt_band_duplicate: Out of memory allocating online band data");
206  return NULL;
207  }
208  memcpy(data, band->data.mem, rt_pixtype_size(band->pixtype) * band->width * band->height);
209 
210  rtn = rt_band_new_inline(
211  band->width, band->height,
212  band->pixtype,
213  band->hasnodata, band->nodataval,
214  data
215  );
216  rt_band_set_ownsdata_flag(rtn, 1); /* we DO own this data!!! */
217  }
218 
219  if (rtn == NULL) {
220  rterror("rt_band_duplicate: Could not copy band");
221  return NULL;
222  }
223 
224  return rtn;
225 }
226 
227 int
229 
230  assert(NULL != band);
231 
232 
233  return band->offline ? 1 : 0;
234 }
235 
241 void
243  if (band == NULL)
244  return;
245 
246  RASTER_DEBUGF(3, "Destroying rt_band @ %p", band);
247 
248  /* offline band */
249  if (band->offline) {
250  /* memory cache */
251  if (band->data.offline.mem != NULL)
252  rtdealloc(band->data.offline.mem);
253  /* offline file path */
254  if (band->data.offline.path != NULL)
255  rtdealloc(band->data.offline.path);
256  }
257  /* inline band and band owns the data */
258  else if (band->data.mem != NULL && band->ownsdata)
259  rtdealloc(band->data.mem);
260 
261  rtdealloc(band);
262 }
263 
264 const char*
266 
267  assert(NULL != band);
268 
269 
270  if (!band->offline) {
271  RASTER_DEBUG(3, "rt_band_get_ext_path: Band is not offline");
272  return NULL;
273  }
274  return band->data.offline.path;
275 }
276 
279  assert(NULL != band);
280  assert(NULL != bandnum);
281 
282  *bandnum = 0;
283 
284  if (!band->offline) {
285  RASTER_DEBUG(3, "rt_band_get_ext_band_num: Band is not offline");
286  return ES_ERROR;
287  }
288 
289  *bandnum = band->data.offline.bandNum;
290 
291  return ES_NONE;
292 }
293 
301 void *
303  assert(NULL != band);
304 
305  if (band->offline) {
306  if (band->data.offline.mem != NULL)
307  return band->data.offline.mem;
308 
309  if (rt_band_load_offline_data(band) != ES_NONE)
310  return NULL;
311  else
312  return band->data.offline.mem;
313  }
314  else
315  return band->data.mem;
316 }
317 
318 /* variable for PostgreSQL GUC: postgis.enable_outdb_rasters */
320 
332  GDALDatasetH hdsSrc = NULL;
333  int nband = 0;
334  VRTDatasetH hdsDst = NULL;
335  VRTSourcedRasterBandH hbandDst = NULL;
336  double gt[6] = {0.};
337  double ogt[6] = {0};
338  double offset[2] = {0};
339 
340  rt_raster _rast = NULL;
341  rt_band _band = NULL;
342  int aligned = 0;
343  int err = ES_NONE;
344 
345  assert(band != NULL);
346  assert(band->raster != NULL);
347 
348  if (!band->offline) {
349  rterror("rt_band_load_offline_data: Band is not offline");
350  return ES_ERROR;
351  }
352  else if (!strlen(band->data.offline.path)) {
353  rterror("rt_band_load_offline_data: Offline band does not a have a specified file");
354  return ES_ERROR;
355  }
356 
357  /* offline_data is disabled */
358  if (!enable_outdb_rasters) {
359  rterror("rt_band_load_offline_data: Access to offline bands disabled");
360  return ES_ERROR;
361  }
362 
364  /*
365  hdsSrc = rt_util_gdal_open(band->data.offline.path, GA_ReadOnly, 1);
366  */
367  hdsSrc = rt_util_gdal_open(band->data.offline.path, GA_ReadOnly, 0);
368  if (hdsSrc == NULL) {
369  rterror("rt_band_load_offline_data: Cannot open offline raster: %s", band->data.offline.path);
370  return ES_ERROR;
371  }
372 
373  /* # of bands */
374  nband = GDALGetRasterCount(hdsSrc);
375  if (!nband) {
376  rterror("rt_band_load_offline_data: No bands found in offline raster: %s", band->data.offline.path);
377  GDALClose(hdsSrc);
378  return ES_ERROR;
379  }
380  /* bandNum is 0-based */
381  else if (band->data.offline.bandNum + 1 > nband) {
382  rterror("rt_band_load_offline_data: Specified band %d not found in offline raster: %s", band->data.offline.bandNum, band->data.offline.path);
383  GDALClose(hdsSrc);
384  return ES_ERROR;
385  }
386 
387  /* get raster's geotransform */
389  RASTER_DEBUGF(3, "Raster geotransform (%f, %f, %f, %f, %f, %f)",
390  gt[0], gt[1], gt[2], gt[3], gt[4], gt[5]);
391 
392  /* get offline raster's geotransform */
393  if (GDALGetGeoTransform(hdsSrc, ogt) != CE_None) {
394  RASTER_DEBUG(4, "Using default geotransform matrix (0, 1, 0, 0, 0, -1)");
395  ogt[0] = 0;
396  ogt[1] = 1;
397  ogt[2] = 0;
398  ogt[3] = 0;
399  ogt[4] = 0;
400  ogt[5] = -1;
401  }
402  RASTER_DEBUGF(3, "Offline geotransform (%f, %f, %f, %f, %f, %f)",
403  ogt[0], ogt[1], ogt[2], ogt[3], ogt[4], ogt[5]);
404 
405  /* are rasters aligned? */
406  _rast = rt_raster_new(1, 1);
408  rt_raster_set_srid(_rast, band->raster->srid);
409  err = rt_raster_same_alignment(band->raster, _rast, &aligned, NULL);
410  rt_raster_destroy(_rast);
411 
412  if (err != ES_NONE) {
413  rterror("rt_band_load_offline_data: Could not test alignment of in-db representation of out-db raster");
414  GDALClose(hdsSrc);
415  return ES_ERROR;
416  }
417  else if (!aligned) {
418  rtwarn("The in-db representation of the out-db raster is not aligned. Band data may be incorrect");
419  }
420 
421  /* get offsets */
423  band->raster,
424  ogt[0], ogt[3],
425  &(offset[0]), &(offset[1]),
426  NULL
427  );
428 
429  RASTER_DEBUGF(4, "offsets: (%f, %f)", offset[0], offset[1]);
430 
431  /* create VRT dataset */
432  hdsDst = VRTCreate(band->width, band->height);
433  GDALSetGeoTransform(hdsDst, gt);
434  /*
435  GDALSetDescription(hdsDst, "/tmp/offline.vrt");
436  */
437 
438  /* add band as simple sources */
439  GDALAddBand(hdsDst, rt_util_pixtype_to_gdal_datatype(band->pixtype), NULL);
440  hbandDst = (VRTSourcedRasterBandH) GDALGetRasterBand(hdsDst, 1);
441 
442  if (band->hasnodata)
443  GDALSetRasterNoDataValue(hbandDst, band->nodataval);
444 
445  VRTAddSimpleSource(
446  hbandDst, GDALGetRasterBand(hdsSrc, band->data.offline.bandNum + 1),
447  fabs(offset[0]), fabs(offset[1]),
448  band->width, band->height,
449  0, 0,
450  band->width, band->height,
451  "near", VRT_NODATA_UNSET
452  );
453 
454  /* make sure VRT reflects all changes */
455  VRTFlushCache(hdsDst);
456 
457  /* convert VRT dataset to rt_raster */
458  _rast = rt_raster_from_gdal_dataset(hdsDst);
459 
460  GDALClose(hdsDst);
461  GDALClose(hdsSrc);
462  /*
463  {
464  FILE *fp;
465  fp = fopen("/tmp/gdal_open_files.log", "w");
466  GDALDumpOpenDatasets(fp);
467  fclose(fp);
468  }
469  */
470 
471  if (_rast == NULL) {
472  rterror("rt_band_load_offline_data: Cannot load data from offline raster: %s", band->data.offline.path);
473  return ES_ERROR;
474  }
475 
476  _band = rt_raster_get_band(_rast, 0);
477  if (_band == NULL) {
478  rterror("rt_band_load_offline_data: Cannot load data from offline raster: %s", band->data.offline.path);
479  rt_raster_destroy(_rast);
480  return ES_ERROR;
481  }
482 
483  /* band->data.offline.mem not NULL, free first */
484  if (band->data.offline.mem != NULL) {
485  rtdealloc(band->data.offline.mem);
486  band->data.offline.mem = NULL;
487  }
488 
489  band->data.offline.mem = _band->data.mem;
490 
491  rtdealloc(_band); /* cannot use rt_band_destroy */
492  rt_raster_destroy(_rast);
493 
494  return ES_NONE;
495 }
496 
499 
500  assert(NULL != band);
501 
502 
503  return band->pixtype;
504 }
505 
506 uint16_t
508 
509  assert(NULL != band);
510 
511 
512  return band->width;
513 }
514 
515 uint16_t
517 
518  assert(NULL != band);
519 
520 
521  return band->height;
522 }
523 
524 /* Get ownsdata flag */
525 int
527  assert(NULL != band);
528 
529  return band->ownsdata ? 1 : 0;
530 }
531 
532 /* set ownsdata flag */
533 void
535  assert(NULL != band);
536 
537  band->ownsdata = flag ? 1 : 0;
538 }
539 
540 int
542  assert(NULL != band);
543 
544  return band->hasnodata ? 1 : 0;
545 }
546 
547 void
549 
550  assert(NULL != band);
551 
552  band->hasnodata = (flag) ? 1 : 0;
553 
554  /* isnodata depends on hasnodata */
555  if (!band->hasnodata && band->isnodata) {
556  RASTER_DEBUG(3, "Setting isnodata to FALSE as band no longer has NODATA");
557  band->isnodata = 0;
558  }
559 }
560 
563  assert(NULL != band);
564 
565  if (!band->hasnodata) {
566  /* silently permit setting isnodata flag to FALSE */
567  if (!flag)
568  band->isnodata = 0;
569  else {
570  rterror("rt_band_set_isnodata_flag: Cannot set isnodata flag as band has no NODATA");
571  return ES_ERROR;
572  }
573  }
574  else
575  band->isnodata = (flag) ? 1 : 0;
576 
577  return ES_NONE;
578 }
579 
580 int
582  assert(NULL != band);
583 
584  if (band->hasnodata)
585  return band->isnodata ? 1 : 0;
586  else
587  return 0;
588 }
589 
600 rt_band_set_nodata(rt_band band, double val, int *converted) {
601  rt_pixtype pixtype = PT_END;
602  int32_t checkvalint = 0;
603  uint32_t checkvaluint = 0;
604  float checkvalfloat = 0;
605  double checkvaldouble = 0;
606 
607  assert(NULL != band);
608 
609  if (converted != NULL)
610  *converted = 0;
611 
612  pixtype = band->pixtype;
613 
614  RASTER_DEBUGF(3, "rt_band_set_nodata: setting nodata value %g with band type %s", val, rt_pixtype_name(pixtype));
615 
616  /* return -1 on out of range */
617  switch (pixtype) {
618  case PT_1BB: {
619  band->nodataval = rt_util_clamp_to_1BB(val);
620  checkvalint = band->nodataval;
621  break;
622  }
623  case PT_2BUI: {
624  band->nodataval = rt_util_clamp_to_2BUI(val);
625  checkvalint = band->nodataval;
626  break;
627  }
628  case PT_4BUI: {
629  band->nodataval = rt_util_clamp_to_4BUI(val);
630  checkvalint = band->nodataval;
631  break;
632  }
633  case PT_8BSI: {
634  band->nodataval = rt_util_clamp_to_8BSI(val);
635  checkvalint = band->nodataval;
636  break;
637  }
638  case PT_8BUI: {
639  band->nodataval = rt_util_clamp_to_8BUI(val);
640  checkvalint = band->nodataval;
641  break;
642  }
643  case PT_16BSI: {
644  band->nodataval = rt_util_clamp_to_16BSI(val);
645  checkvalint = band->nodataval;
646  break;
647  }
648  case PT_16BUI: {
649  band->nodataval = rt_util_clamp_to_16BUI(val);
650  checkvalint = band->nodataval;
651  break;
652  }
653  case PT_32BSI: {
654  band->nodataval = rt_util_clamp_to_32BSI(val);
655  checkvalint = band->nodataval;
656  break;
657  }
658  case PT_32BUI: {
659  band->nodataval = rt_util_clamp_to_32BUI(val);
660  checkvaluint = band->nodataval;
661  break;
662  }
663  case PT_32BF: {
664  band->nodataval = rt_util_clamp_to_32F(val);
665  checkvalfloat = band->nodataval;
666  break;
667  }
668  case PT_64BF: {
669  band->nodataval = val;
670  checkvaldouble = band->nodataval;
671  break;
672  }
673  default: {
674  rterror("rt_band_set_nodata: Unknown pixeltype %d", pixtype);
675  band->hasnodata = 0;
676  return ES_ERROR;
677  }
678  }
679 
680  RASTER_DEBUGF(3, "rt_band_set_nodata: band->hasnodata = %d", band->hasnodata);
681  RASTER_DEBUGF(3, "rt_band_set_nodata: band->nodataval = %f", band->nodataval);
682  /* the nodata value was just set, so this band has NODATA */
683  band->hasnodata = 1;
684 
685  /* also set isnodata flag to false */
686  band->isnodata = 0;
687 
689  val,
690  checkvalint, checkvaluint,
691  checkvalfloat, checkvaldouble,
692  pixtype
693  ) && converted != NULL) {
694  *converted = 1;
695  }
696 
697  return ES_NONE;
698 }
699 
721  rt_band band,
722  int x, int y,
723  void *vals, uint32_t len
724 ) {
725  rt_pixtype pixtype = PT_END;
726  int size = 0;
727  uint8_t *data = NULL;
728  uint32_t offset = 0;
729 
730  assert(NULL != band);
731  assert(vals != NULL && len > 0);
732 
733  RASTER_DEBUGF(3, "length of values = %d", len);
734 
735  if (band->offline) {
736  rterror("rt_band_set_pixel_line not implemented yet for OFFDB bands");
737  return ES_ERROR;
738  }
739 
740  pixtype = band->pixtype;
741  size = rt_pixtype_size(pixtype);
742 
743  if (
744  x < 0 || x >= band->width ||
745  y < 0 || y >= band->height
746  ) {
747  rterror("rt_band_set_pixel_line: Coordinates out of range (%d, %d) vs (%d, %d)", x, y, band->width, band->height);
748  return ES_ERROR;
749  }
750 
751  data = rt_band_get_data(band);
752  offset = x + (y * band->width);
753  RASTER_DEBUGF(4, "offset = %d", offset);
754 
755  /* make sure len of values to copy don't exceed end of data */
756  if (len > (band->width * band->height) - offset) {
757  rterror("rt_band_set_pixel_line: Could not apply pixels as values length exceeds end of data");
758  return ES_ERROR;
759  }
760 
761  switch (pixtype) {
762  case PT_1BB:
763  case PT_2BUI:
764  case PT_4BUI:
765  case PT_8BUI:
766  case PT_8BSI: {
767  uint8_t *ptr = data;
768  ptr += offset;
769  memcpy(ptr, vals, size * len);
770  break;
771  }
772  case PT_16BUI: {
773  uint16_t *ptr = (uint16_t *) data;
774  ptr += offset;
775  memcpy(ptr, vals, size * len);
776  break;
777  }
778  case PT_16BSI: {
779  int16_t *ptr = (int16_t *) data;
780  ptr += offset;
781  memcpy(ptr, vals, size * len);
782  break;
783  }
784  case PT_32BUI: {
785  uint32_t *ptr = (uint32_t *) data;
786  ptr += offset;
787  memcpy(ptr, vals, size * len);
788  break;
789  }
790  case PT_32BSI: {
791  int32_t *ptr = (int32_t *) data;
792  ptr += offset;
793  memcpy(ptr, vals, size * len);
794  break;
795  }
796  case PT_32BF: {
797  float *ptr = (float *) data;
798  ptr += offset;
799  memcpy(ptr, vals, size * len);
800  break;
801  }
802  case PT_64BF: {
803  double *ptr = (double *) data;
804  ptr += offset;
805  memcpy(ptr, vals, size * len);
806  break;
807  }
808  default: {
809  rterror("rt_band_set_pixel_line: Unknown pixeltype %d", pixtype);
810  return ES_ERROR;
811  }
812  }
813 
814 #if POSTGIS_DEBUG_LEVEL > 0
815  {
816  double value;
817  rt_band_get_pixel(band, x, y, &value, NULL);
818  RASTER_DEBUGF(4, "pixel at (%d, %d) = %f", x, y, value);
819  }
820 #endif
821 
822  /* set band's isnodata flag to FALSE */
823  if (rt_band_get_hasnodata_flag(band))
824  rt_band_set_isnodata_flag(band, 0);
825 
826  return ES_NONE;
827 }
828 
842  rt_band band,
843  int x, int y,
844  double val,
845  int *converted
846 ) {
847  rt_pixtype pixtype = PT_END;
848  unsigned char* data = NULL;
849  uint32_t offset = 0;
850 
851  int32_t checkvalint = 0;
852  uint32_t checkvaluint = 0;
853  float checkvalfloat = 0;
854  double checkvaldouble = 0;
855 
856  assert(NULL != band);
857 
858  if (converted != NULL)
859  *converted = 0;
860 
861  if (band->offline) {
862  rterror("rt_band_set_pixel not implemented yet for OFFDB bands");
863  return ES_ERROR;
864  }
865 
866  pixtype = band->pixtype;
867 
868  if (
869  x < 0 || x >= band->width ||
870  y < 0 || y >= band->height
871  ) {
872  rterror("rt_band_set_pixel: Coordinates out of range");
873  return ES_ERROR;
874  }
875 
876  /* check that clamped value isn't clamped NODATA */
877  if (band->hasnodata && pixtype != PT_64BF) {
878  double newval;
879  int corrected;
880 
881  rt_band_corrected_clamped_value(band, val, &newval, &corrected);
882 
883  if (corrected) {
884 #if POSTGIS_RASTER_WARN_ON_TRUNCATION > 0
885  rtwarn("Value for pixel %d x %d has been corrected as clamped value becomes NODATA", x, y);
886 #endif
887  val = newval;
888 
889  if (converted != NULL)
890  *converted = 1;
891  }
892  }
893 
894  data = rt_band_get_data(band);
895  offset = x + (y * band->width);
896 
897  switch (pixtype) {
898  case PT_1BB: {
899  data[offset] = rt_util_clamp_to_1BB(val);
900  checkvalint = data[offset];
901  break;
902  }
903  case PT_2BUI: {
904  data[offset] = rt_util_clamp_to_2BUI(val);
905  checkvalint = data[offset];
906  break;
907  }
908  case PT_4BUI: {
909  data[offset] = rt_util_clamp_to_4BUI(val);
910  checkvalint = data[offset];
911  break;
912  }
913  case PT_8BSI: {
914  data[offset] = rt_util_clamp_to_8BSI(val);
915  checkvalint = (int8_t) data[offset];
916  break;
917  }
918  case PT_8BUI: {
919  data[offset] = rt_util_clamp_to_8BUI(val);
920  checkvalint = data[offset];
921  break;
922  }
923  case PT_16BSI: {
924  int16_t *ptr = (int16_t*) data; /* we assume correct alignment */
925  ptr[offset] = rt_util_clamp_to_16BSI(val);
926  checkvalint = (int16_t) ptr[offset];
927  break;
928  }
929  case PT_16BUI: {
930  uint16_t *ptr = (uint16_t*) data; /* we assume correct alignment */
931  ptr[offset] = rt_util_clamp_to_16BUI(val);
932  checkvalint = ptr[offset];
933  break;
934  }
935  case PT_32BSI: {
936  int32_t *ptr = (int32_t*) data; /* we assume correct alignment */
937  ptr[offset] = rt_util_clamp_to_32BSI(val);
938  checkvalint = (int32_t) ptr[offset];
939  break;
940  }
941  case PT_32BUI: {
942  uint32_t *ptr = (uint32_t*) data; /* we assume correct alignment */
943  ptr[offset] = rt_util_clamp_to_32BUI(val);
944  checkvaluint = ptr[offset];
945  break;
946  }
947  case PT_32BF: {
948  float *ptr = (float*) data; /* we assume correct alignment */
949  ptr[offset] = rt_util_clamp_to_32F(val);
950  checkvalfloat = ptr[offset];
951  break;
952  }
953  case PT_64BF: {
954  double *ptr = (double*) data; /* we assume correct alignment */
955  ptr[offset] = val;
956  checkvaldouble = ptr[offset];
957  break;
958  }
959  default: {
960  rterror("rt_band_set_pixel: Unknown pixeltype %d", pixtype);
961  return ES_ERROR;
962  }
963  }
964 
965  /* If the stored value is not NODATA, reset the isnodata flag */
966  if (!rt_band_clamped_value_is_nodata(band, val)) {
967  RASTER_DEBUG(3, "Band has a value that is not NODATA. Setting isnodata to FALSE");
968  band->isnodata = FALSE;
969  }
970 
971  /* Overflow checking */
973  val,
974  checkvalint, checkvaluint,
975  checkvalfloat, checkvaldouble,
976  pixtype
977  ) && converted != NULL) {
978  *converted = 1;
979  }
980 
981  return ES_NONE;
982 }
983 
1005  rt_band band,
1006  int x, int y,
1007  uint16_t len,
1008  void **vals, uint16_t *nvals
1009 ) {
1010  uint8_t *_vals = NULL;
1011  int pixsize = 0;
1012  uint8_t *data = NULL;
1013  uint32_t offset = 0;
1014  uint16_t _nvals = 0;
1015  int maxlen = 0;
1016  uint8_t *ptr = NULL;
1017 
1018  assert(NULL != band);
1019  assert(vals != NULL && nvals != NULL);
1020 
1021  /* initialize to no values */
1022  *nvals = 0;
1023 
1024  if (
1025  x < 0 || x >= band->width ||
1026  y < 0 || y >= band->height
1027  ) {
1028  rtwarn("Attempting to get pixel values with out of range raster coordinates: (%d, %d)", x, y);
1029  return ES_ERROR;
1030  }
1031 
1032  if (len < 1)
1033  return ES_NONE;
1034 
1035  data = rt_band_get_data(band);
1036  if (data == NULL) {
1037  rterror("rt_band_get_pixel_line: Cannot get band data");
1038  return ES_ERROR;
1039  }
1040 
1041  /* +1 for the nodata value */
1042  offset = x + (y * band->width);
1043  RASTER_DEBUGF(4, "offset = %d", offset);
1044 
1045  pixsize = rt_pixtype_size(band->pixtype);
1046  RASTER_DEBUGF(4, "pixsize = %d", pixsize);
1047 
1048  /* cap _nvals so that it doesn't overflow */
1049  _nvals = len;
1050  maxlen = band->width * band->height;
1051 
1052  if (((int) (offset + _nvals)) > maxlen) {
1053  _nvals = maxlen - offset;
1054  rtwarn("Limiting returning number values to %d", _nvals);
1055  }
1056  RASTER_DEBUGF(4, "_nvals = %d", _nvals);
1057 
1058  ptr = data + (offset * pixsize);
1059 
1060  _vals = rtalloc(_nvals * pixsize);
1061  if (_vals == NULL) {
1062  rterror("rt_band_get_pixel_line: Could not allocate memory for pixel values");
1063  return ES_ERROR;
1064  }
1065 
1066  /* copy pixels */
1067  memcpy(_vals, ptr, _nvals * pixsize);
1068 
1069  *vals = _vals;
1070  *nvals = _nvals;
1071 
1072  return ES_NONE;
1073 }
1074 
1089  rt_band band,
1090  int x, int y,
1091  double *value,
1092  int *nodata
1093 ) {
1094  rt_pixtype pixtype = PT_END;
1095  uint8_t* data = NULL;
1096  uint32_t offset = 0;
1097 
1098  assert(NULL != band);
1099  assert(NULL != value);
1100 
1101  /* set nodata to 0 */
1102  if (nodata != NULL)
1103  *nodata = 0;
1104 
1105  if (
1106  x < 0 || x >= band->width ||
1107  y < 0 || y >= band->height
1108  ) {
1109  rtwarn("Attempting to get pixel value with out of range raster coordinates: (%d, %d)", x, y);
1110  return ES_ERROR;
1111  }
1112 
1113  /* band is NODATA */
1114  if (band->isnodata) {
1115  RASTER_DEBUG(3, "Band's isnodata flag is TRUE. Returning NODATA value");
1116  *value = band->nodataval;
1117  if (nodata != NULL) *nodata = 1;
1118  return ES_NONE;
1119  }
1120 
1121  data = rt_band_get_data(band);
1122  if (data == NULL) {
1123  rterror("rt_band_get_pixel: Cannot get band data");
1124  return ES_ERROR;
1125  }
1126 
1127  /* +1 for the nodata value */
1128  offset = x + (y * band->width);
1129 
1130  pixtype = band->pixtype;
1131 
1132  switch (pixtype) {
1133  case PT_1BB:
1134 #ifdef OPTIMIZE_SPACE
1135  {
1136  int byteOffset = offset / 8;
1137  int bitOffset = offset % 8;
1138  data += byteOffset;
1139 
1140  /* Bit to set is bitOffset into data */
1141  *value = getBits(data, val, 1, bitOffset);
1142  break;
1143  }
1144 #endif
1145  case PT_2BUI:
1146 #ifdef OPTIMIZE_SPACE
1147  {
1148  int byteOffset = offset / 4;
1149  int bitOffset = offset % 4;
1150  data += byteOffset;
1151 
1152  /* Bits to set start at bitOffset into data */
1153  *value = getBits(data, val, 2, bitOffset);
1154  break;
1155  }
1156 #endif
1157  case PT_4BUI:
1158 #ifdef OPTIMIZE_SPACE
1159  {
1160  int byteOffset = offset / 2;
1161  int bitOffset = offset % 2;
1162  data += byteOffset;
1163 
1164  /* Bits to set start at bitOffset into data */
1165  *value = getBits(data, val, 2, bitOffset);
1166  break;
1167  }
1168 #endif
1169  case PT_8BSI: {
1170  int8_t val = data[offset];
1171  *value = val;
1172  break;
1173  }
1174  case PT_8BUI: {
1175  uint8_t val = data[offset];
1176  *value = val;
1177  break;
1178  }
1179  case PT_16BSI: {
1180  int16_t *ptr = (int16_t*) data; /* we assume correct alignment */
1181  *value = ptr[offset];
1182  break;
1183  }
1184  case PT_16BUI: {
1185  uint16_t *ptr = (uint16_t*) data; /* we assume correct alignment */
1186  *value = ptr[offset];
1187  break;
1188  }
1189  case PT_32BSI: {
1190  int32_t *ptr = (int32_t*) data; /* we assume correct alignment */
1191  *value = ptr[offset];
1192  break;
1193  }
1194  case PT_32BUI: {
1195  uint32_t *ptr = (uint32_t*) data; /* we assume correct alignment */
1196  *value = ptr[offset];
1197  break;
1198  }
1199  case PT_32BF: {
1200  float *ptr = (float*) data; /* we assume correct alignment */
1201  *value = ptr[offset];
1202  break;
1203  }
1204  case PT_64BF: {
1205  double *ptr = (double*) data; /* we assume correct alignment */
1206  *value = ptr[offset];
1207  break;
1208  }
1209  default: {
1210  rterror("rt_band_get_pixel: Unknown pixeltype %d", pixtype);
1211  return ES_ERROR;
1212  }
1213  }
1214 
1215  /* set NODATA flag */
1216  if (band->hasnodata && nodata != NULL) {
1217  if (rt_band_clamped_value_is_nodata(band, *value))
1218  *nodata = 1;
1219  }
1220 
1221  return ES_NONE;
1222 }
1223 
1242  rt_band band,
1243  int x, int y,
1244  uint16_t distancex, uint16_t distancey,
1245  int exclude_nodata_value,
1246  rt_pixel *npixels
1247 ) {
1248  rt_pixel npixel = NULL;
1249  int extent[4] = {0};
1250  int max_extent[4] = {0};
1251  int d0 = 0;
1252  int distance[2] = {0};
1253  uint32_t _d[2] = {0};
1254  uint32_t i = 0;
1255  uint32_t j = 0;
1256  uint32_t k = 0;
1257  int _max = 0;
1258  int _x = 0;
1259  int _y = 0;
1260  int *_min = NULL;
1261  double pixval = 0;
1262  double minval = 0;
1263  uint32_t count = 0;
1264  int isnodata = 0;
1265 
1266  int inextent = 0;
1267 
1268  assert(NULL != band);
1269  assert(NULL != npixels);
1270 
1271  RASTER_DEBUG(3, "Starting");
1272 
1273  /* process distance */
1274  distance[0] = distancex;
1275  distance[1] = distancey;
1276 
1277  /* no distance, means get nearest pixels and return */
1278  if (!distance[0] && !distance[1])
1279  d0 = 1;
1280 
1281  RASTER_DEBUGF(4, "Selected pixel: %d x %d", x, y);
1282  RASTER_DEBUGF(4, "Distances: %d x %d", distance[0], distance[1]);
1283 
1284  /* shortcuts if outside band extent */
1285  if (
1286  exclude_nodata_value && (
1287  (x < 0 || x > band->width) ||
1288  (y < 0 || y > band->height)
1289  )
1290  ) {
1291  /* no distances specified, jump to pixel close to extent */
1292  if (d0) {
1293  if (x < 0)
1294  x = -1;
1295  else if (x > band->width)
1296  x = band->width;
1297 
1298  if (y < 0)
1299  y = -1;
1300  else if (y > band->height)
1301  y = band->height;
1302 
1303  RASTER_DEBUGF(4, "Moved selected pixel: %d x %d", x, y);
1304  }
1305  /*
1306  distances specified
1307  if distances won't capture extent of band, return 0
1308  */
1309  else if (
1310  ((x < 0 && abs(x) > distance[0]) || (x - band->width >= distance[0])) ||
1311  ((y < 0 && abs(y) > distance[1]) || (y - band->height >= distance[1]))
1312  ) {
1313  RASTER_DEBUG(4, "No nearest pixels possible for provided pixel and distances");
1314  return 0;
1315  }
1316  }
1317 
1318  /* no NODATA, exclude is FALSE */
1319  if (!band->hasnodata)
1320  exclude_nodata_value = FALSE;
1321  /* band is NODATA and excluding NODATA */
1322  else if (exclude_nodata_value && band->isnodata) {
1323  RASTER_DEBUG(4, "No nearest pixels possible as band is NODATA and excluding NODATA values");
1324  return 0;
1325  }
1326 
1327  /* determine the maximum distance to prevent an infinite loop */
1328  if (d0) {
1329  int a, b;
1330 
1331  /* X axis */
1332  a = abs(x);
1333  b = abs(x - band->width);
1334 
1335  if (a > b)
1336  distance[0] = a;
1337  else
1338  distance[0] = b;
1339 
1340  /* Y axis */
1341  a = abs(y);
1342  b = abs(y - band->height);
1343  if (a > b)
1344  distance[1] = a;
1345  else
1346  distance[1] = b;
1347 
1348  RASTER_DEBUGF(4, "Maximum distances: %d x %d", distance[0], distance[1]);
1349  }
1350 
1351  /* minimum possible value for pixel type */
1352  minval = rt_pixtype_get_min_value(band->pixtype);
1353  RASTER_DEBUGF(4, "pixtype: %s", rt_pixtype_name(band->pixtype));
1354  RASTER_DEBUGF(4, "minval: %f", minval);
1355 
1356  /* set variables */
1357  count = 0;
1358  *npixels = NULL;
1359 
1360  /* maximum extent */
1361  max_extent[0] = x - distance[0]; /* min X */
1362  max_extent[1] = y - distance[1]; /* min Y */
1363  max_extent[2] = x + distance[0]; /* max X */
1364  max_extent[3] = y + distance[1]; /* max Y */
1365  RASTER_DEBUGF(4, "Maximum Extent: (%d, %d, %d, %d)",
1366  max_extent[0], max_extent[1], max_extent[2], max_extent[3]);
1367 
1368  _d[0] = 0;
1369  _d[1] = 0;
1370  do {
1371  _d[0]++;
1372  _d[1]++;
1373 
1374  extent[0] = x - _d[0]; /* min x */
1375  extent[1] = y - _d[1]; /* min y */
1376  extent[2] = x + _d[0]; /* max x */
1377  extent[3] = y + _d[1]; /* max y */
1378 
1379  RASTER_DEBUGF(4, "Processing distances: %d x %d", _d[0], _d[1]);
1380  RASTER_DEBUGF(4, "Extent: (%d, %d, %d, %d)",
1381  extent[0], extent[1], extent[2], extent[3]);
1382 
1383  for (i = 0; i < 2; i++) {
1384 
1385  /* by row */
1386  if (i < 1)
1387  _max = extent[2] - extent[0] + 1;
1388  /* by column */
1389  else
1390  _max = extent[3] - extent[1] + 1;
1391  _max = abs(_max);
1392 
1393  for (j = 0; j < 2; j++) {
1394  /* by row */
1395  if (i < 1) {
1396  _x = extent[0];
1397  _min = &_x;
1398 
1399  /* top row */
1400  if (j < 1)
1401  _y = extent[1];
1402  /* bottom row */
1403  else
1404  _y = extent[3];
1405  }
1406  /* by column */
1407  else {
1408  _y = extent[1] + 1;
1409  _min = &_y;
1410 
1411  /* left column */
1412  if (j < 1) {
1413  _x = extent[0];
1414  _max -= 2;
1415  }
1416  /* right column */
1417  else
1418  _x = extent[2];
1419  }
1420 
1421  RASTER_DEBUGF(4, "_min, _max: %d, %d", *_min, _max);
1422  for (k = 0; k < _max; k++) {
1423  /* check that _x and _y are not outside max extent */
1424  if (
1425  _x < max_extent[0] || _x > max_extent[2] ||
1426  _y < max_extent[1] || _y > max_extent[3]
1427  ) {
1428  (*_min)++;
1429  continue;
1430  }
1431 
1432  /* outside band extent, set to NODATA */
1433  if (
1434  (_x < 0 || _x >= band->width) ||
1435  (_y < 0 || _y >= band->height)
1436  ) {
1437  /* no NODATA, set to minimum possible value */
1438  if (!band->hasnodata)
1439  pixval = minval;
1440  /* has NODATA, use NODATA */
1441  else
1442  pixval = band->nodataval;
1443  RASTER_DEBUGF(4, "NODATA pixel outside band extent: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1444  inextent = 0;
1445  isnodata = 1;
1446  }
1447  else {
1448  if (rt_band_get_pixel(
1449  band,
1450  _x, _y,
1451  &pixval,
1452  &isnodata
1453  ) != ES_NONE) {
1454  rterror("rt_band_get_nearest_pixel: Could not get pixel value");
1455  if (count) rtdealloc(*npixels);
1456  return -1;
1457  }
1458  RASTER_DEBUGF(4, "Pixel: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1459  inextent = 1;
1460  }
1461 
1462  /* use pixval? */
1463  if (!exclude_nodata_value || (exclude_nodata_value && !isnodata)) {
1464  /* add pixel to result set */
1465  RASTER_DEBUGF(4, "Adding pixel to set of nearest pixels: (x, y, val) = (%d, %d, %f)", _x, _y, pixval);
1466  count++;
1467 
1468  if (*npixels == NULL)
1469  *npixels = (rt_pixel) rtalloc(sizeof(struct rt_pixel_t) * count);
1470  else
1471  *npixels = (rt_pixel) rtrealloc(*npixels, sizeof(struct rt_pixel_t) * count);
1472  if (*npixels == NULL) {
1473  rterror("rt_band_get_nearest_pixel: Could not allocate memory for nearest pixel(s)");
1474  return -1;
1475  }
1476 
1477  npixel = &((*npixels)[count - 1]);
1478  npixel->x = _x;
1479  npixel->y = _y;
1480  npixel->value = pixval;
1481 
1482  /* special case for when outside band extent */
1483  if (!inextent && !band->hasnodata)
1484  npixel->nodata = 1;
1485  else
1486  npixel->nodata = 0;
1487  }
1488 
1489  (*_min)++;
1490  }
1491  }
1492  }
1493 
1494  /* distance threshholds met */
1495  if (_d[0] >= distance[0] && _d[1] >= distance[1])
1496  break;
1497  else if (d0 && count)
1498  break;
1499  }
1500  while (1);
1501 
1502  RASTER_DEBUGF(3, "Nearest pixels in return: %d", count);
1503 
1504  return count;
1505 }
1506 
1518 int
1520  rt_band band, int exclude_nodata_value,
1521  double *searchset, int searchcount,
1522  rt_pixel *pixels
1523 ) {
1524  int x;
1525  int y;
1526  int i;
1527  double pixval;
1528  int err;
1529  int count = 0;
1530  int isnodata = 0;
1531  int isequal = 0;
1532 
1533  rt_pixel pixel = NULL;
1534 
1535  assert(NULL != band);
1536  assert(NULL != pixels);
1537  assert(NULL != searchset && searchcount > 0);
1538 
1539  if (!band->hasnodata)
1540  exclude_nodata_value = FALSE;
1541  /* band is NODATA and exclude_nodata_value = TRUE, nothing to search */
1542  else if (exclude_nodata_value && band->isnodata) {
1543  RASTER_DEBUG(4, "Pixels cannot be searched as band is NODATA and excluding NODATA values");
1544  return 0;
1545  }
1546 
1547  for (x = 0; x < band->width; x++) {
1548  for (y = 0; y < band->height; y++) {
1549  err = rt_band_get_pixel(band, x, y, &pixval, &isnodata);
1550  if (err != ES_NONE) {
1551  rterror("rt_band_get_pixel_of_value: Cannot get band pixel");
1552  return -1;
1553  }
1554  else if (exclude_nodata_value && isnodata)
1555  continue;
1556 
1557  for (i = 0; i < searchcount; i++) {
1558  if (rt_pixtype_compare_clamped_values(band->pixtype, searchset[i], pixval, &isequal) != ES_NONE) {
1559  continue;
1560  }
1561 
1562  if (FLT_NEQ(pixval, searchset[i]) || !isequal)
1563  continue;
1564 
1565  /* match found */
1566  count++;
1567  if (*pixels == NULL)
1568  *pixels = (rt_pixel) rtalloc(sizeof(struct rt_pixel_t) * count);
1569  else
1570  *pixels = (rt_pixel) rtrealloc(*pixels, sizeof(struct rt_pixel_t) * count);
1571  if (*pixels == NULL) {
1572  rterror("rt_band_get_pixel_of_value: Could not allocate memory for pixel(s)");
1573  return -1;
1574  }
1575 
1576  pixel = &((*pixels)[count - 1]);
1577  pixel->x = x;
1578  pixel->y = y;
1579  pixel->nodata = 0;
1580  pixel->value = pixval;
1581  }
1582  }
1583  }
1584 
1585  return count;
1586 }
1587 
1597 rt_band_get_nodata(rt_band band, double *nodata) {
1598  assert(NULL != band);
1599  assert(NULL != nodata);
1600 
1601  *nodata = band->nodataval;
1602 
1603  if (!band->hasnodata) {
1604  rterror("rt_band_get_nodata: Band has no NODATA value");
1605  return ES_ERROR;
1606  }
1607 
1608  return ES_NONE;
1609 }
1610 
1611 double
1613  assert(NULL != band);
1614 
1615  return rt_pixtype_get_min_value(band->pixtype);
1616 }
1617 
1618 int
1620  int i, j, err;
1621  double pxValue;
1622  int isnodata = 0;
1623 
1624  assert(NULL != band);
1625 
1626  /* Check if band has nodata value */
1627  if (!band->hasnodata) {
1628  RASTER_DEBUG(3, "Band has no NODATA value");
1629  band->isnodata = FALSE;
1630  return FALSE;
1631  }
1632 
1633  pxValue = band->nodataval;
1634 
1635  /* Check all pixels */
1636  for (i = 0; i < band->width; i++) {
1637  for (j = 0; j < band->height; j++) {
1638  err = rt_band_get_pixel(band, i, j, &pxValue, &isnodata);
1639  if (err != ES_NONE) {
1640  rterror("rt_band_check_is_nodata: Cannot get band pixel");
1641  return FALSE;
1642  }
1643  else if (!isnodata) {
1644  band->isnodata = FALSE;
1645  return FALSE;
1646  }
1647  }
1648  }
1649 
1650  band->isnodata = TRUE;
1651  return TRUE;
1652 }
1653 
1664 int
1666  int isequal = 0;
1667 
1668  assert(NULL != band);
1669 
1670  /* no NODATA, so never equal */
1671  if (!band->hasnodata)
1672  return 0;
1673 
1674  /* value is exactly NODATA */
1675  if (FLT_EQ(val, band->nodataval))
1676  return 2;
1677 
1678  /* ignore error from rt_pixtype_compare_clamped_values */
1680  band->pixtype,
1681  val, band->nodataval,
1682  &isequal
1683  );
1684 
1685  return isequal ? 1 : 0;
1686 }
1687 
1702  rt_band band,
1703  double val,
1704  double *newval, int *corrected
1705 ) {
1706  double minval = 0.;
1707 
1708  assert(NULL != band);
1709  assert(NULL != newval);
1710 
1711  if (corrected != NULL)
1712  *corrected = 0;
1713 
1714  /* no need to correct if clamped values IS NOT clamped NODATA */
1715  if (rt_band_clamped_value_is_nodata(band, val) != 1) {
1716  *newval = val;
1717  return ES_NONE;
1718  }
1719 
1720  minval = rt_pixtype_get_min_value(band->pixtype);
1721  *newval = val;
1722 
1723  switch (band->pixtype) {
1724  case PT_1BB:
1725  *newval = !band->nodataval;
1726  break;
1727  case PT_2BUI:
1728  if (rt_util_clamp_to_2BUI(val) == rt_util_clamp_to_2BUI(minval))
1729  (*newval)++;
1730  else
1731  (*newval)--;
1732  break;
1733  case PT_4BUI:
1734  if (rt_util_clamp_to_4BUI(val) == rt_util_clamp_to_4BUI(minval))
1735  (*newval)++;
1736  else
1737  (*newval)--;
1738  break;
1739  case PT_8BSI:
1740  if (rt_util_clamp_to_8BSI(val) == rt_util_clamp_to_8BSI(minval))
1741  (*newval)++;
1742  else
1743  (*newval)--;
1744  break;
1745  case PT_8BUI:
1746  if (rt_util_clamp_to_8BUI(val) == rt_util_clamp_to_8BUI(minval))
1747  (*newval)++;
1748  else
1749  (*newval)--;
1750  break;
1751  case PT_16BSI:
1752  if (rt_util_clamp_to_16BSI(val) == rt_util_clamp_to_16BSI(minval))
1753  (*newval)++;
1754  else
1755  (*newval)--;
1756  break;
1757  case PT_16BUI:
1758  if (rt_util_clamp_to_16BUI(val) == rt_util_clamp_to_16BUI(minval))
1759  (*newval)++;
1760  else
1761  (*newval)--;
1762  break;
1763  case PT_32BSI:
1764  if (rt_util_clamp_to_32BSI(val) == rt_util_clamp_to_32BSI(minval))
1765  (*newval)++;
1766  else
1767  (*newval)--;
1768  break;
1769  case PT_32BUI:
1770  if (rt_util_clamp_to_32BUI(val) == rt_util_clamp_to_32BUI(minval))
1771  (*newval)++;
1772  else
1773  (*newval)--;
1774  break;
1775  case PT_32BF:
1777  *newval += FLT_EPSILON;
1778  else
1779  *newval -= FLT_EPSILON;
1780  break;
1781  case PT_64BF:
1782  break;
1783  default:
1784  rterror("rt_band_corrected_clamped_value: Unknown pixeltype %d", band->pixtype);
1785  return ES_ERROR;
1786  }
1787 
1788  if (corrected != NULL)
1789  *corrected = 1;
1790 
1791  return ES_NONE;
1792 }
1793 
rt_errorstate rt_band_set_pixel(rt_band band, int x, int y, double val, int *converted)
Set single pixel's value.
Definition: rt_band.c:841
char enable_outdb_rasters
Definition: rt_band.c:319
int32_t rt_util_clamp_to_32BSI(double value)
Definition: rt_util.c:69
rt_errorstate rt_band_set_nodata(rt_band band, double val, int *converted)
Set nodata value.
Definition: rt_band.c:600
int32_t srid
Definition: librtcore.h:2263
uint32_t rt_util_clamp_to_32BUI(double value)
Definition: rt_util.c:74
int rt_util_gdal_register_all(int force_register_all)
Definition: rt_util.c:334
rt_errorstate rt_raster_same_alignment(rt_raster rast1, rt_raster rast2, int *aligned, char **reason)
tuple data
Definition: ovdump.py:103
rt_band rt_band_new_offline(uint16_t width, uint16_t height, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, uint8_t bandNum, const char *path)
Create an out-db rt_band.
Definition: rt_band.c:119
struct rt_pixel_t * rt_pixel
Definition: librtcore.h:159
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
Definition: rt_band.c:541
void rt_raster_set_geotransform_matrix(rt_raster raster, double *gt)
Set raster's geotransform using 6-element array.
Definition: rt_raster.c:727
rt_raster raster
Definition: librtcore.h:2287
void rt_raster_get_geotransform_matrix(rt_raster raster, double *gt)
Get 6-element array of raster geotransform matrix.
Definition: rt_raster.c:706
rt_pixtype pixtype
Definition: librtcore.h:2277
int rt_band_get_nearest_pixel(rt_band band, int x, int y, uint16_t distancex, uint16_t distancey, int exclude_nodata_value, rt_pixel *npixels)
Get nearest pixel(s) with value (not NODATA) to specified pixel.
Definition: rt_band.c:1241
tuple gt
Definition: window.py:77
rt_pixtype rt_band_get_pixtype(rt_band band)
Return pixeltype of this band.
Definition: rt_band.c:498
#define FLT_EQ(x, y)
Definition: librtcore.h:2197
void rterror(const char *fmt,...)
Wrappers used for reporting errors and info.
Definition: rt_context.c:199
tuple band
Definition: ovdump.py:57
void * rtalloc(size_t size)
Wrappers used for managing memory.
Definition: rt_context.c:171
void * rtrealloc(void *mem, size_t size)
Definition: rt_context.c:179
uint16_t height
Definition: librtcore.h:2280
double value
Definition: librtcore.h:2301
rt_errorstate
Enum definitions.
Definition: librtcore.h:191
uint16_t rt_band_get_width(rt_band band)
Return width of this band.
Definition: rt_band.c:507
rt_pixtype
Definition: librtcore.h:197
int rt_band_check_is_nodata(rt_band band)
Returns TRUE if the band is only nodata values.
Definition: rt_band.c:1619
tuple pixval
Definition: pixval.py:93
rt_errorstate rt_band_get_pixel_line(rt_band band, int x, int y, uint16_t len, void **vals, uint16_t *nvals)
Get values of multiple pixels.
Definition: rt_band.c:1004
void rt_band_set_ownsdata_flag(rt_band band, int flag)
Definition: rt_band.c:534
uint16_t rt_util_clamp_to_16BUI(double value)
Definition: rt_util.c:64
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).
Definition: rt_band.c:278
rt_errorstate rt_band_set_pixel_line(rt_band band, int x, int y, void *vals, uint32_t len)
Set values of multiple pixels.
Definition: rt_band.c:720
GDALDataType rt_util_pixtype_to_gdal_datatype(rt_pixtype pt)
Convert rt_pixtype to GDALDataType.
Definition: rt_util.c:118
Definition: pixval.py:1
void rtwarn(const char *fmt,...)
Definition: rt_context.c:224
tuple nband
Definition: pixval.py:52
rt_band rt_band_duplicate(rt_band band)
Create a new band duplicated from source band.
Definition: rt_band.c:186
union rt_band_t::@6 data
int8_t rt_util_clamp_to_8BSI(double value)
Definition: rt_util.c:49
int rt_util_dbl_trunc_warning(double initialvalue, int32_t checkvalint, uint32_t checkvaluint, float checkvalfloat, double checkvaldouble, rt_pixtype pixtype)
Definition: rt_util.c:625
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
Definition: rt_raster.c:381
#define FLT_NEQ(x, y)
Definition: librtcore.h:2196
int8_t ownsdata
Definition: librtcore.h:2285
int count
Definition: genraster.py:56
rt_errorstate rt_band_get_pixel(rt_band band, int x, int y, double *value, int *nodata)
Get pixel value.
Definition: rt_band.c:1088
double nodataval
Definition: librtcore.h:2284
double rt_pixtype_get_min_value(rt_pixtype pixtype)
Return minimum value possible for pixel type.
Definition: rt_pixel.c:148
void rt_raster_set_srid(rt_raster raster, int32_t srid)
Set raster's SRID.
Definition: rt_raster.c:363
#define RASTER_DEBUGF(level, msg,...)
Definition: librtcore.h:311
void rt_raster_destroy(rt_raster raster)
Release memory associated to a raster.
Definition: rt_raster.c:82
rt_errorstate rt_raster_geopoint_to_cell(rt_raster raster, double xw, double yw, double *xr, double *yr, double *igt)
Convert an xw, yw map point to a xr, yr raster point.
Definition: rt_raster.c:806
uint8_t nodata
Definition: librtcore.h:2300
rt_raster rt_raster_new(uint32_t width, uint32_t height)
Construct a raster with given dimensions.
Definition: rt_raster.c:48
uint16_t width
Definition: librtcore.h:2279
tuple x
Definition: pixval.py:53
Datum distance(PG_FUNCTION_ARGS)
uint8_t rt_util_clamp_to_4BUI(double value)
Definition: rt_util.c:44
uint8_t rt_util_clamp_to_8BUI(double value)
Definition: rt_util.c:54
void rt_band_destroy(rt_band band)
Destroy a raster band.
Definition: rt_band.c:242
int rt_pixtype_size(rt_pixtype pixtype)
Return size in bytes of a value in the given pixtype.
Definition: rt_pixel.c:39
uint8_t rt_util_clamp_to_1BB(double value)
Definition: rt_util.c:34
rt_errorstate rt_band_set_isnodata_flag(rt_band band, int flag)
Set isnodata flag value.
Definition: rt_band.c:562
int rt_band_clamped_value_is_nodata(rt_band band, double val)
Compare clamped value to band's clamped NODATA value.
Definition: rt_band.c:1665
int32_t offline
Definition: librtcore.h:2278
void rtdealloc(void *mem)
Definition: rt_context.c:186
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).
Definition: rt_band.c:265
rt_errorstate rt_band_corrected_clamped_value(rt_band band, double val, double *newval, int *corrected)
Correct value when clamped value is equal to clamped NODATA value.
Definition: rt_band.c:1701
int32_t isnodata
Definition: librtcore.h:2282
void rt_band_set_hasnodata_flag(rt_band band, int flag)
Set hasnodata flag value.
Definition: rt_band.c:548
#define FALSE
Definition: dbfopen.c:168
uint16_t rt_band_get_height(rt_band band)
Return height of this band.
Definition: rt_band.c:516
#define RASTER_DEBUG(level, msg)
Definition: librtcore.h:307
This library is the generic raster handling section of PostGIS.
const char * rt_pixtype_name(rt_pixtype pixtype)
Definition: rt_pixel.c:110
int rt_band_get_ownsdata_flag(rt_band band)
Return 0 (FALSE) or non-zero (TRUE) indicating if rt_band is responsible for managing the memory for ...
Definition: rt_band.c:526
void * mem
Definition: librtcore.h:2290
int32_t hasnodata
Definition: librtcore.h:2281
tuple pixel
Definition: pixval.py:90
uint8_t rt_util_clamp_to_2BUI(double value)
Definition: rt_util.c:39
float rt_util_clamp_to_32F(double value)
Definition: rt_util.c:79
rt_band rt_band_new_inline(uint16_t width, uint16_t height, rt_pixtype pixtype, uint32_t hasnodata, double nodataval, uint8_t *data)
Create an in-db rt_band with no data.
Definition: rt_band.c:58
rt_raster rt_raster_from_gdal_dataset(GDALDatasetH ds)
Return a raster from a GDAL dataset.
Definition: rt_raster.c:2165
rt_errorstate rt_band_load_offline_data(rt_band band)
Load offline band's data.
Definition: rt_band.c:331
int rt_band_is_offline(rt_band band)
Return non-zero if the given band data is on the filesystem.
Definition: rt_band.c:228
#define TRUE
Definition: dbfopen.c:169
void * rt_band_get_data(rt_band band)
Get pointer to raster band data.
Definition: rt_band.c:302
double rt_band_get_min_value(rt_band band)
Returns the minimal possible value for the band according to the pixel type.
Definition: rt_band.c:1612
GDALDatasetH rt_util_gdal_open(const char *fn, GDALAccess fn_access, int shared)
Definition: rt_util.c:379
tuple y
Definition: pixval.py:54
rt_errorstate rt_pixtype_compare_clamped_values(rt_pixtype pixtype, double val, double refval, int *isequal)
Test to see if two values are equal when clamped.
Definition: rt_pixel.c:200
int rt_band_get_pixel_of_value(rt_band band, int exclude_nodata_value, double *searchset, int searchcount, rt_pixel *pixels)
Search band for pixel(s) with search values.
Definition: rt_band.c:1519
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
Definition: rt_band.c:581
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
Definition: rt_band.c:1597
int16_t rt_util_clamp_to_16BSI(double value)
Definition: rt_util.c:59