Ticket #188: rt_hasnodata.patch
| File rt_hasnodata.patch, 16.8 KB (added by dzwarg, 2 years ago) |
|---|
-
test/core/testwkb.c
165 165 "0A000000" /* SRID (int32 10) */ 166 166 "0100" /* width (uint16 1) */ 167 167 "0100" /* height (uint16 1) */ 168 " 00" /* First band type (1BB, in memory) */168 "40" /* First band type (1BB, in memory, hasnodata) */ 169 169 "00" /* nodata value (0) */ 170 170 "01" /* pix(0,0) == 1 */ 171 171 ; … … 187 187 CHECK(band); 188 188 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_1BB); 189 189 CHECK(!rt_band_is_offline(ctx, band)); 190 CHECK(rt_band_get_hasnodata_flag(ctx, band)); 190 191 CHECK_EQUALS(rt_band_get_nodata(ctx, band), 0); 191 192 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 1); 192 193 } … … 219 220 "0A000000" /* SRID (int32 10) */ 220 221 "0300" /* width (uint16 3) */ 221 222 "0200" /* height (uint16 2) */ 222 " 03" /* First band type (8BSI, in memory) */223 "43" /* First band type (8BSI, in memory, hasnodata) */ 223 224 "FF" /* nodata value (-1) */ 224 225 "FF" /* pix(0,0) == -1 */ 225 226 "00" /* pix(1,0) == 0 */ … … 246 247 CHECK(band); 247 248 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_8BSI); 248 249 CHECK(!rt_band_is_offline(ctx, band)); 250 CHECK(rt_band_get_hasnodata_flag(ctx,band)); 249 251 CHECK_EQUALS(rt_band_get_nodata(ctx, band), -1); 250 252 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), -1); 251 253 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 0); … … 323 325 CHECK(band); 324 326 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_16BSI); 325 327 CHECK(!rt_band_is_offline(ctx, band)); 328 CHECK(!rt_band_get_hasnodata_flag(ctx, band)); 326 329 CHECK_EQUALS(rt_band_get_nodata(ctx, band), -1); 327 330 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), -1); 328 331 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 0); … … 387 390 CHECK(band); 388 391 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_16BSI); 389 392 CHECK(!rt_band_is_offline(ctx, band)); 393 CHECK(!rt_band_get_hasnodata_flag(ctx,band)); 390 394 CHECK_EQUALS(rt_band_get_nodata(ctx, band), -1); 391 395 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), -1); 392 396 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 0); … … 424 428 "0000000A" /* SRID (int32 10) */ 425 429 "0003" /* width (uint16 3) */ 426 430 "0002" /* height (uint16 2) */ 427 " 85" /* First band type (16BSI, on disk) */431 "C5" /* First band type (16BSI, on disk, hasnodata) */ 428 432 "FFFF" /* nodata value (-1) */ 429 433 "03" /* ext band num == 3 */ 430 434 /* ext band path == /tmp/t.tif */ … … 448 452 CHECK(band); 449 453 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_16BSI); 450 454 CHECK(rt_band_is_offline(ctx, band)); 455 CHECK(rt_band_get_hasnodata_flag(ctx,band)); 451 456 CHECK_EQUALS(rt_band_get_nodata(ctx, band), -1); 452 457 printf("ext band path: %s\n", rt_band_get_ext_path(ctx, band)); 453 458 printf("ext band num: %u\n", rt_band_get_ext_band_num(ctx, band)); … … 483 488 "FFFFFFFF" /* SRID (int32 -1) */ 484 489 "0300" /* width (uint16 3) */ 485 490 "0100" /* height (uint16 1) */ 486 " 05" /* First band type (16BSI, in memory) */491 "45" /* First band type (16BSI, in memory, hasnodata) */ 487 492 "0100" /* nodata value (1) */ 488 493 "0100" /* pix(0,0) == 1 */ 489 494 "B401" /* pix(1,0) == 436 */ … … 507 512 CHECK(band); 508 513 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_16BSI); 509 514 CHECK(!rt_band_is_offline(ctx, band)); 515 CHECK(rt_band_get_hasnodata_flag(ctx,band)); 510 516 CHECK_EQUALS(rt_band_get_nodata(ctx, band), 1); 511 517 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 1); 512 518 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 436); … … 561 567 "FFFFFFFF" /* srid (int32 -1) */ 562 568 "0500" /* width (uint16 5) */ 563 569 "0500" /* height (uint16 5) */ 564 " 04" /* 1st band pixel type (8BUI, in memory) */570 "44" /* 1st band pixel type (8BUI, in memory, hasnodata) */ 565 571 "00" /* 1st band nodata 0 */ 566 572 "FDFEFDFEFEFDFEFEFDF9FAFEFEFCF9FBFDFEFEFDFCFAFEFEFE" /* 1st band pixels */ 567 " 04" /* 2nd band pixel type (8BUI, in memory) */573 "44" /* 2nd band pixel type (8BUI, in memory, hasnodata) */ 568 574 "00" /* 2nd band nodata 0 */ 569 575 "4E627AADD16076B4F9FE6370A9F5FE59637AB0E54F58617087" /* 2nd band pixels */ 570 " 04" /* 3rd band pixel type (8BUI, in memory) */576 "44" /* 3rd band pixel type (8BUI, in memory, hasnodata) */ 571 577 "00" /* 3rd band nodata 0 */ 572 578 "46566487A1506CA2E3FA5A6CAFFBFE4D566DA4CB3E454C5665" /* 3rd band pixels */ 573 579 ; … … 590 596 CHECK(band); 591 597 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_8BUI); 592 598 CHECK(!rt_band_is_offline(ctx, band)); 599 CHECK(rt_band_get_hasnodata_flag(ctx,band)); 593 600 CHECK_EQUALS(rt_band_get_nodata(ctx, band), 0); 594 601 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 253); 595 602 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 254); … … 604 611 CHECK(band); 605 612 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_8BUI); 606 613 CHECK(!rt_band_is_offline(ctx, band)); 614 CHECK(rt_band_get_hasnodata_flag(ctx,band)); 607 615 CHECK_EQUALS(rt_band_get_nodata(ctx, band), 0); 608 616 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 78); 609 617 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 98); … … 618 626 CHECK(band); 619 627 CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_8BUI); 620 628 CHECK(!rt_band_is_offline(ctx, band)); 629 CHECK(rt_band_get_hasnodata_flag(ctx,band)); 621 630 CHECK_EQUALS(rt_band_get_nodata(ctx, band), 0); 622 631 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 70); 623 632 CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 86); -
test/core/testapi.c
26 26 mem = malloc(datasize); 27 27 28 28 rt_band band = rt_band_new_inline(ctx, width, height, 29 pixtype, 0, mem);29 pixtype, 1, 0, mem); 30 30 assert(band); 31 31 bandNum = rt_raster_add_band(ctx, raster, band); 32 32 assert(bandNum>=0); … … 60 60 size_t datasize = width * height; 61 61 rt_raster raster = rt_raster_new(ctx, width, height); 62 62 void * mem = calloc(datasize, sizeof(void)); 63 rt_band band = rt_band_new_inline(ctx, width, height, PT_32BSI, 0, mem);63 rt_band band = rt_band_new_inline(ctx, width, height, PT_32BSI, 1, 0, mem); 64 64 65 65 /* Fill raster */ 66 66 rt_band_set_pixel(ctx, band, 0, 0, 1); … … 864 864 } 865 865 } 866 866 867 static void testBandHasNoData(rt_context ctx, rt_band band) 868 { 869 int flag; 870 int failure; 871 872 flag = rt_band_get_hasnodata_flag(ctx, band); 873 CHECK_EQUALS(flag, 1); 874 875 rt_band_set_hasnodata_flag(ctx, band, 0); 876 flag = rt_band_get_hasnodata_flag(ctx, band); 877 CHECK_EQUALS(flag, 0); 878 879 rt_band_set_hasnodata_flag(ctx, band, 10); 880 flag = rt_band_get_hasnodata_flag(ctx, band); 881 CHECK_EQUALS(flag, 1); 882 883 rt_band_set_hasnodata_flag(ctx, band, -10); 884 flag = rt_band_get_hasnodata_flag(ctx, band); 885 CHECK_EQUALS(flag, 1); 886 } 887 867 888 int 868 889 main() 869 890 { … … 1101 1122 band_64BF = addBand(ctx, raster, PT_64BF); 1102 1123 testBand64BF(ctx, band_64BF); 1103 1124 1125 printf("Testing band hasnodata flag\n"); 1126 testBandHasNoData(ctx, band_64BF); 1127 1104 1128 deepRelease(ctx, raster); 1105 1129 rt_context_destroy(ctx); 1106 1130 -
rt_core/rt_api.c
367 367 int32_t offline; 368 368 uint16_t width; 369 369 uint16_t height; 370 int32_t hasnodata; /* a flag indicating if this band contains nodata values */ 370 371 double nodataval; /* int will be converted ... */ 371 372 int32_t ownsData; /* XXX mloskot: its behaviour needs to be documented */ 372 373 union { … … 378 379 379 380 rt_band 380 381 rt_band_new_inline(rt_context ctx, uint16_t width, uint16_t height, 381 rt_pixtype pixtype, double nodataval, uint8_t* data) 382 rt_pixtype pixtype, uint32_t hasnodata, double nodataval, 383 uint8_t* data) 382 384 { 383 385 rt_band band = NULL; 384 386 … … 401 403 band->offline = 0; 402 404 band->width = width; 403 405 band->height = height; 406 band->hasnodata = hasnodata; 404 407 band->nodataval = nodataval; 405 408 band->data.mem = data; 406 409 band->ownsData = 0; … … 410 413 411 414 rt_band 412 415 rt_band_new_offline(rt_context ctx, uint16_t width, uint16_t height, 413 rt_pixtype pixtype, double nodataval, uint8_t bandNum,414 const char* path)416 rt_pixtype pixtype, uint32_t hasnodata, double nodataval, 417 uint8_t bandNum, const char* path) 415 418 { 416 419 rt_band band = NULL; 417 420 … … 434 437 band->offline = 1; 435 438 band->width = width; 436 439 band->height = height; 440 band->hasnodata = hasnodata; 437 441 band->nodataval = nodataval; 438 442 band->data.offline.bandNum = bandNum; 439 443 … … 469 473 470 474 /* band->data content is externally owned */ 471 475 /* XXX jorgearevalo: not really... rt_band_from_wkb allocates memory for 472 * data.me m476 * data.me 473 477 */ 474 478 ctx->dealloc(band); 475 479 } … … 611 615 #endif /* OPTIMIZE_SPACE */ 612 616 613 617 int 618 rt_band_get_hasnodata_flag(rt_context ctx, rt_band band) 619 { 620 assert(NULL != ctx); 621 assert(NULL != band); 622 623 return band->hasnodata; 624 } 625 626 void 627 rt_band_set_hasnodata_flag(rt_context ctx, rt_band band, int flag) 628 { 629 assert(NULL != ctx); 630 assert(NULL != band); 631 632 band->hasnodata = (flag) ? 1 : 0; 633 } 634 635 int 614 636 rt_band_set_nodata(rt_context ctx, rt_band band, double val) 615 637 { 616 638 rt_pixtype pixtype = PT_END; … … 691 713 break; 692 714 default: 693 715 ctx->err("Unknown pixeltype %d", pixtype); 716 band->hasnodata = 0; 694 717 return -1; 695 718 } 696 719 720 // the NODATA value was just set, so this band has NODATA 721 rt_band_set_hasnodata_flag(ctx, band, 1); 722 697 723 if ( fabs(band->nodataval - val) > 0.0001 ) 698 724 { 699 725 #ifdef RT_WARN_ON_TRUNCATION … … 952 978 assert(NULL != ctx); 953 979 assert(NULL != band); 954 980 955 return band->nodataval; 981 if (!band->hasnodata) 982 ctx->warn("Getting NODATA value for a band without NODATA values. Using %d", band->nodataval); 983 984 return band->nodataval; 956 985 } 957 986 958 987 … … 2020 2049 #define BANDTYPE_FLAGS_MASK 0xF0 2021 2050 #define BANDTYPE_PIXTYPE_MASK 0x0F 2022 2051 #define BANDTYPE_FLAG_OFFDB (1<<7) 2023 #define BANDTYPE_FLAG_ RESERVED1(1<<6)2052 #define BANDTYPE_FLAG_HASNODATA (1<<6) 2024 2053 #define BANDTYPE_FLAG_RESERVED2 (1<<5) 2025 2054 #define BANDTYPE_FLAG_RESERVED3 (1<<4) 2026 2055 2027 2056 #define BANDTYPE_PIXTYPE(x) ((x)&BANDTYPE_PIXTYPE_MASK) 2028 2057 #define BANDTYPE_IS_OFFDB(x) ((x)&BANDTYPE_FLAG_OFFDB) 2058 #define BANDTYPE_HAS_NODATA(x) ((x)&BANDTYPE_FLAG_HASNODATA) 2029 2059 2030 2060 /* Read band from WKB as at start of band */ 2031 2061 static rt_band … … 2067 2097 2068 2098 band->pixtype = type & BANDTYPE_PIXTYPE_MASK; 2069 2099 band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0; 2100 band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1 : 0; 2070 2101 band->width = width; 2071 2102 band->height = height; 2072 2103 2073 2104 #ifdef RT_API_DEBUG 2074 ctx->info(" Band pixtype:%s, offline:%d ",2105 ctx->info(" Band pixtype:%s, offline:%d, hasnodata:%d", 2075 2106 rt_pixtype_name(ctx, band->pixtype), 2076 band->offline); 2107 band->offline, 2108 band->hasnodata); 2077 2109 #endif 2078 2110 2079 2111 /* Check there's enough bytes to read nodata value */ … … 2591 2623 /* Add band type */ 2592 2624 *ptr = band->pixtype; 2593 2625 if ( band->offline ) *ptr |= BANDTYPE_FLAG_OFFDB; 2626 if ( band->hasnodata ) *ptr |= BANDTYPE_FLAG_HASNODATA; 2594 2627 ptr += 1; 2595 2628 2596 2629 #if 0 // no padding required for WKB … … 2765 2798 int pixbytes = rt_pixtype_size(ctx, pixtype); 2766 2799 2767 2800 if ( pixbytes < 1 ) { 2768 ctx->err("Corrupted band: unk onwn pixtype");2801 ctx->err("Corrupted band: unknown pixtype"); 2769 2802 return 0; 2770 2803 } 2771 2804 2772 /* Add space for band type and data padding */2805 /* Add space for band type, hasnodata flag and data padding */ 2773 2806 size += pixbytes; 2774 2807 2775 2808 /* Add space for nodata value */ … … 2872 2905 2873 2906 /* Add band type */ 2874 2907 *ptr = band->pixtype; 2875 if ( band->offline ) 2876 { 2877 *ptr |= BANDTYPE_FLAG_OFFDB; 2878 } 2908 if ( band->offline ) { *ptr |= BANDTYPE_FLAG_OFFDB; } 2909 if ( band->hasnodata ) { *ptr |= BANDTYPE_FLAG_HASNODATA; } 2879 2910 2880 2911 #ifdef RT_API_DEBUG 2881 2912 d_print_binary_hex(ctx, "PIXTYPE", dbg_ptr, size); … … 3068 3099 #endif 3069 3100 3070 3101 band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0; 3102 band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1: 0; 3071 3103 band->width = rast->width; 3072 3104 band->height = rast->height; 3073 3105 band->ownsData = 0; … … 3144 3176 } 3145 3177 3146 3178 #ifdef RT_API_DEBUG 3179 ctx->info(" Has NODATA flag %d", band-hasnodata); 3147 3180 ctx->info(" NODATA value %d", band->nodataval); 3148 3181 #endif 3149 3182 /* Consistency checking (ptr is pixbytes-aligned) */ -
rt_core/rt_api.h
126 126 */ 127 127 rt_band rt_band_new_inline(rt_context ctx, 128 128 uint16_t width, uint16_t height, 129 rt_pixtype pixtype, double nodataval,130 uint8_t* data);129 rt_pixtype pixtype, uint32_t hasnodata, 130 double nodataval, uint8_t* data); 131 131 132 132 /** 133 133 * Create an on-disk rt_band … … 150 150 */ 151 151 rt_band rt_band_new_offline(rt_context ctx, 152 152 uint16_t width, uint16_t height, 153 rt_pixtype pixtype, double nodataval,154 uint8_t bandNum, const char* path);153 rt_pixtype pixtype, uint32_t hasnodata, 154 double nodataval, uint8_t bandNum, const char* path); 155 155 156 156 /** 157 157 * Return non-zero if the given band data is on … … 195 195 /* Destroy a raster band */ 196 196 void rt_band_destroy(rt_context ctx, rt_band band); 197 197 198 /* Set nodata value 198 /** 199 * Get hasnodata flag value 199 200 * @param ctx : context, for thread safety 201 * @param band : the band on which to check the hasnodata flag 202 * @return the hasnodata flag. 203 */ 204 int rt_band_get_hasnodata_flag(rt_context ctx, rt_band band); 205 206 /** 207 * Set hasnodata flag value 208 * @param ctx : context, for thread safety 209 * @param band : the band on which to set the hasnodata flag 210 * @param flag : the new hasnodata flag value. Must be 1 or 0. 211 */ 212 void rt_band_set_hasnodata_flag(rt_context ctx, rt_band band, int flag); 213 214 /** 215 * Set nodata value 216 * @param ctx : context, for thread safety 200 217 * @param band : the band to set nodata value to 201 218 * @param val : the nodata value, must be in the range 202 219 * of values supported by this band's pixeltype … … 208 225 */ 209 226 int rt_band_set_nodata(rt_context ctx, rt_band band, double val); 210 227 211 /* Get nodata value 228 /** 229 * Get nodata value 212 230 * @param ctx : context, for thread safety 213 231 * @param band : the band to set nodata value to 214 232 * @return nodata value 215 233 */ 216 234 double rt_band_get_nodata(rt_context ctx, rt_band band); 217 235 218 /* Set pixel value 236 /** 237 * Set pixel value 219 238 * @param ctx : context, for thread safety 220 239 * @param band : the band to set nodata value to 221 240 * @param x : x ordinate … … 230 249 int rt_band_set_pixel(rt_context ctx, rt_band band, 231 250 uint16_t x, uint16_t y, double val); 232 251 233 /* Get pixel value 252 /** 253 * Get pixel value 234 254 * 235 255 * @param ctx : context, for thread safety 236 256 * @param band : the band to set nodata value to -
doc/RFC1-SerializedFormat
113 113 114 114 There are currently 12 supported pixel value types, so 4 115 115 bits are enough to account for all. We'll reserve 116 the upper 4 bits for generic flags (might eventually add117 hasnodatavalues or others) and define upmost asstorage flag:116 the upper 4 bits for generic flags and define upmost as 117 storage flag: 118 118 119 119 #define BANDTYPE_FLAGS_MASK 0xF0 120 120 #define BANDTYPE_PIXTYPE_MASK 0x0F 121 121 122 122 #define BANDTYPE_FLAG_OFFDB (1<<7) 123 #define BANDTYPE_FLAG_ RESERVED1(1<<6)123 #define BANDTYPE_FLAG_HASNODATA (1<<6) 124 124 #define BANDTYPE_FLAG_RESERVED2 (1<<5) 125 125 #define BANDTYPE_FLAG_RESERVED3 (1<<4) 126 126
