GRASS Programmer's Manual
6.4.1(2011)
|
00001 /* 00002 **************************************************************************** 00003 * 00004 * MODULE: Vector library 00005 * 00006 * AUTHOR(S): Original author CERL, probably Dave Gerdes. 00007 * Update to GRASS 5.7 Radim Blazek. 00008 * 00009 * PURPOSE: Lower level functions for reading/writing/manipulating vectors. 00010 * 00011 * COPYRIGHT: (C) 2001 by the GRASS Development Team 00012 * 00013 * This program is free software under the GNU General Public 00014 * License (>=v2). Read the file COPYING that comes with GRASS 00015 * for details. 00016 * 00017 *****************************************************************************/ 00018 #include <string.h> 00019 #include <grass/gis.h> 00020 #include <grass/Vect.h> 00021 00022 extern void port_init(void); 00023 00024 extern int nat_dbl; 00025 extern int nat_flt; 00026 extern int nat_lng; 00027 extern int nat_int; 00028 extern int nat_shrt; 00029 00030 extern int dbl_order; 00031 extern int flt_order; 00032 extern int lng_order; 00033 extern int int_order; 00034 extern int shrt_order; 00035 00036 extern unsigned char dbl_cnvrt[sizeof(double)]; 00037 extern unsigned char flt_cnvrt[sizeof(float)]; 00038 extern unsigned char lng_cnvrt[sizeof(long)]; 00039 extern unsigned char int_cnvrt[sizeof(int)]; 00040 extern unsigned char shrt_cnvrt[sizeof(short)]; 00041 00042 struct Port_info *Cur_Head; 00043 00044 static char *buffer = NULL; 00045 static int buf_alloced = 0; 00046 00047 static int buf_alloc(int needed) 00048 { 00049 char *p; 00050 int cnt; 00051 00052 if (needed <= buf_alloced) 00053 return (0); 00054 cnt = buf_alloced; 00055 p = dig__alloc_space(needed, &cnt, 100, buffer, 1); 00056 if (p == NULL) 00057 return (dig_out_of_memory()); 00058 buffer = p; 00059 buf_alloced = cnt; 00060 return (0); 00061 } 00062 00063 /***************************** READ ************************************/ 00064 /* These are the routines to read from the Portable Vector Format. 00065 These routines must handle any type size conversions between the 00066 portable format and the native machine. 00067 00068 Return: 0 error 00069 1 OK 00070 00071 */ 00072 00073 00074 /* read doubles from the PVF file */ 00075 int dig__fread_port_D(double *buf, int cnt, GVFILE * fp) 00076 { 00077 int i, j, ret; 00078 unsigned char *c1, *c2; 00079 00080 if (Cur_Head->dbl_quick) { 00081 ret = dig_fread(buf, PORT_DOUBLE, cnt, fp); 00082 if (ret != cnt) 00083 return 0; 00084 } 00085 else { 00086 /* read into buffer */ 00087 buf_alloc(cnt * PORT_DOUBLE); 00088 ret = dig_fread(buffer, PORT_DOUBLE, cnt, fp); 00089 if (ret != cnt) 00090 return 0; 00091 /* read from buffer in changed order */ 00092 c1 = (unsigned char *)buffer; 00093 c2 = (unsigned char *)buf; 00094 for (i = 0; i < cnt; i++) { 00095 for (j = 0; j < PORT_DOUBLE; j++) { 00096 c2[Cur_Head->dbl_cnvrt[j]] = c1[j]; 00097 } 00098 c1 += PORT_DOUBLE; 00099 c2 += sizeof(double); 00100 } 00101 } 00102 return 1; 00103 } 00104 00105 /* read floats from the PVF file */ 00106 int dig__fread_port_F(float *buf, int cnt, GVFILE * fp) 00107 { 00108 int i, j, ret; 00109 unsigned char *c1, *c2; 00110 00111 if (Cur_Head->flt_quick) { 00112 ret = dig_fread(buf, PORT_FLOAT, cnt, fp); 00113 if (ret != cnt) 00114 return 0; 00115 } 00116 else { 00117 /* read into buffer */ 00118 buf_alloc(cnt * PORT_FLOAT); 00119 ret = dig_fread(buffer, PORT_FLOAT, cnt, fp); 00120 if (ret != cnt) 00121 return 0; 00122 /* read from buffer in changed order */ 00123 c1 = (unsigned char *)buffer; 00124 c2 = (unsigned char *)buf; 00125 for (i = 0; i < cnt; i++) { 00126 for (j = 0; j < PORT_FLOAT; j++) { 00127 c2[Cur_Head->flt_cnvrt[j]] = c1[j]; 00128 } 00129 c1 += PORT_FLOAT; 00130 c2 += sizeof(float); 00131 } 00132 } 00133 return 1; 00134 } 00135 00136 /* read longs from the PVF file */ 00137 int dig__fread_port_L(long *buf, int cnt, GVFILE * fp) 00138 { 00139 int i, j, ret; 00140 unsigned char *c1, *c2; 00141 00142 if (Cur_Head->lng_quick) { 00143 if (nat_lng == PORT_LONG) { 00144 ret = dig_fread(buf, PORT_LONG, cnt, fp); 00145 if (ret != cnt) 00146 return 0; 00147 } 00148 else { 00149 /* read into buffer */ 00150 buf_alloc(cnt * PORT_LONG); 00151 ret = dig_fread(buffer, PORT_LONG, cnt, fp); 00152 if (ret != cnt) 00153 return 0; 00154 /* set buffer to zero (positive numbers) */ 00155 memset(buf, 0, cnt * sizeof(long)); 00156 /* read from buffer in changed order */ 00157 c1 = (unsigned char *)buffer; 00158 if (lng_order == ENDIAN_LITTLE) 00159 c2 = (unsigned char *)buf; 00160 else 00161 c2 = (unsigned char *)buf + nat_lng - PORT_LONG; 00162 for (i = 0; i < cnt; i++) { 00163 /* set to FF if the value is negative */ 00164 if (lng_order == ENDIAN_LITTLE) { 00165 if (c1[PORT_LONG - 1] & 0x80) 00166 memset(c2, 0xff, sizeof(long)); 00167 } 00168 else { 00169 if (c1[0] & 0x80) 00170 memset(c2, 0xff, sizeof(long)); 00171 } 00172 memcpy(c2, c1, PORT_LONG); 00173 c1 += PORT_LONG; 00174 c2 += sizeof(long); 00175 } 00176 } 00177 } 00178 else { 00179 /* read into buffer */ 00180 buf_alloc(cnt * PORT_LONG); 00181 ret = dig_fread(buffer, PORT_LONG, cnt, fp); 00182 if (ret != cnt) 00183 return 0; 00184 /* set buffer to zero (positive numbers) */ 00185 memset(buf, 0, cnt * sizeof(long)); 00186 /* read from buffer in changed order */ 00187 c1 = (unsigned char *)buffer; 00188 c2 = (unsigned char *)buf; 00189 for (i = 0; i < cnt; i++) { 00190 /* set to FF if the value is negative */ 00191 if (Cur_Head->byte_order == ENDIAN_LITTLE) { 00192 if (c1[PORT_LONG - 1] & 0x80) 00193 memset(c2, 0xff, sizeof(long)); 00194 } 00195 else { 00196 if (c1[0] & 0x80) 00197 memset(c2, 0xff, sizeof(long)); 00198 } 00199 for (j = 0; j < PORT_LONG; j++) 00200 c2[Cur_Head->lng_cnvrt[j]] = c1[j]; 00201 c1 += PORT_LONG; 00202 c2 += sizeof(long); 00203 } 00204 } 00205 return 1; 00206 } 00207 00208 /* read ints from the PVF file */ 00209 int dig__fread_port_I(int *buf, int cnt, GVFILE * fp) 00210 { 00211 int i, j, ret; 00212 unsigned char *c1, *c2; 00213 00214 if (Cur_Head->int_quick) { 00215 if (nat_int == PORT_INT) { 00216 ret = dig_fread(buf, PORT_INT, cnt, fp); 00217 if (ret != cnt) 00218 return 0; 00219 } 00220 else { 00221 /* read into buffer */ 00222 buf_alloc(cnt * PORT_INT); 00223 ret = dig_fread(buffer, PORT_INT, cnt, fp); 00224 if (ret != cnt) 00225 return 0; 00226 /* set buffer to zero (positive numbers) */ 00227 memset(buf, 0, cnt * sizeof(int)); 00228 /* read from buffer in changed order */ 00229 c1 = (unsigned char *)buffer; 00230 if (int_order == ENDIAN_LITTLE) 00231 c2 = (unsigned char *)buf; 00232 else 00233 c2 = (unsigned char *)buf + nat_int - PORT_INT; 00234 for (i = 0; i < cnt; i++) { 00235 /* set to FF if the value is negative */ 00236 if (int_order == ENDIAN_LITTLE) { 00237 if (c1[PORT_INT - 1] & 0x80) 00238 memset(c2, 0xff, sizeof(int)); 00239 } 00240 else { 00241 if (c1[0] & 0x80) 00242 memset(c2, 0xff, sizeof(int)); 00243 } 00244 memcpy(c2, c1, PORT_INT); 00245 c1 += PORT_INT; 00246 c2 += sizeof(int); 00247 } 00248 } 00249 } 00250 else { 00251 /* read into buffer */ 00252 buf_alloc(cnt * PORT_INT); 00253 ret = dig_fread(buffer, PORT_INT, cnt, fp); 00254 if (ret != cnt) 00255 return 0; 00256 /* set buffer to zero (positive numbers) */ 00257 memset(buf, 0, cnt * sizeof(int)); 00258 /* read from buffer in changed order */ 00259 c1 = (unsigned char *)buffer; 00260 c2 = (unsigned char *)buf; 00261 for (i = 0; i < cnt; i++) { 00262 /* set to FF if the value is negative */ 00263 if (Cur_Head->byte_order == ENDIAN_LITTLE) { 00264 if (c1[PORT_INT - 1] & 0x80) 00265 memset(c2, 0xff, sizeof(int)); 00266 } 00267 else { 00268 if (c1[0] & 0x80) 00269 memset(c2, 0xff, sizeof(int)); 00270 } 00271 for (j = 0; j < PORT_INT; j++) 00272 c2[Cur_Head->int_cnvrt[j]] = c1[j]; 00273 c1 += PORT_INT; 00274 c2 += sizeof(int); 00275 } 00276 } 00277 return 1; 00278 } 00279 00280 /* read shorts from the PVF file */ 00281 int dig__fread_port_S(short *buf, int cnt, GVFILE * fp) 00282 { 00283 int i, j, ret; 00284 unsigned char *c1, *c2; 00285 00286 if (Cur_Head->shrt_quick) { 00287 if (nat_shrt == PORT_SHORT) { 00288 ret = dig_fread(buf, PORT_SHORT, cnt, fp); 00289 if (ret != cnt) 00290 return 0; 00291 } 00292 else { 00293 /* read into buffer */ 00294 buf_alloc(cnt * PORT_SHORT); 00295 if (0 >= (ret = dig_fread(buffer, PORT_SHORT, cnt, fp))) 00296 if (ret != cnt) 00297 return 0; 00298 /* set buffer to zero (positive numbers) */ 00299 memset(buf, 0, cnt * sizeof(short)); 00300 /* read from buffer in changed order */ 00301 c1 = (unsigned char *)buffer; 00302 if (shrt_order == ENDIAN_LITTLE) 00303 c2 = (unsigned char *)buf; 00304 else 00305 c2 = (unsigned char *)buf + nat_shrt - PORT_SHORT; 00306 for (i = 0; i < cnt; i++) { 00307 /* set to FF if the value is negative */ 00308 if (shrt_order == ENDIAN_LITTLE) { 00309 if (c1[PORT_SHORT - 1] & 0x80) 00310 memset(c2, 0xff, sizeof(short)); 00311 } 00312 else { 00313 if (c1[0] & 0x80) 00314 memset(c2, 0xff, sizeof(short)); 00315 } 00316 memcpy(c2, c1, PORT_SHORT); 00317 c1 += PORT_SHORT; 00318 c2 += sizeof(short); 00319 } 00320 } 00321 } 00322 else { 00323 /* read into buffer */ 00324 buf_alloc(cnt * PORT_SHORT); 00325 ret = dig_fread(buffer, PORT_SHORT, cnt, fp); 00326 if (ret != cnt) 00327 return 0; 00328 /* set buffer to zero (positive numbers) */ 00329 memset(buf, 0, cnt * sizeof(short)); 00330 /* read from buffer in changed order */ 00331 c1 = (unsigned char *)buffer; 00332 c2 = (unsigned char *)buf; 00333 for (i = 0; i < cnt; i++) { 00334 /* set to FF if the value is negative */ 00335 if (Cur_Head->byte_order == ENDIAN_LITTLE) { 00336 if (c1[PORT_SHORT - 1] & 0x80) 00337 memset(c2, 0xff, sizeof(short)); 00338 } 00339 else { 00340 if (c1[0] & 0x80) 00341 memset(c2, 0xff, sizeof(short)); 00342 } 00343 for (j = 0; j < PORT_SHORT; j++) 00344 c2[Cur_Head->shrt_cnvrt[j]] = c1[j]; 00345 c1 += PORT_SHORT; 00346 c2 += sizeof(short); 00347 } 00348 } 00349 return 1; 00350 } 00351 00352 /* read chars from the PVF file */ 00353 int dig__fread_port_C(char *buf, int cnt, GVFILE * fp) 00354 { 00355 int ret; 00356 00357 ret = dig_fread(buf, PORT_CHAR, cnt, fp); 00358 if (ret != cnt) 00359 return 0; 00360 return 1; 00361 } 00362 00363 /* read plus_t from the PVF file */ 00364 /* plus_t is defined as int so we only retype pointer and use int function */ 00365 int dig__fread_port_P(plus_t * buf, int cnt, GVFILE * fp) 00366 { 00367 int *ibuf; 00368 00369 ibuf = (int *)buf; 00370 00371 return (dig__fread_port_I(ibuf, cnt, fp)); 00372 } 00373 00374 /***************************** WRITE ************************************/ 00375 00376 int dig__fwrite_port_D(double *buf, /* DOUBLE */ 00377 int cnt, GVFILE * fp) 00378 { 00379 int i, j; 00380 unsigned char *c1, *c2; 00381 00382 if (Cur_Head->dbl_quick) { 00383 if (dig_fwrite(buf, PORT_DOUBLE, cnt, fp) == cnt) 00384 return 1; 00385 } 00386 else { 00387 buf_alloc(cnt * PORT_DOUBLE); 00388 c1 = (unsigned char *)buf; 00389 c2 = (unsigned char *)buffer; 00390 for (i = 0; i < cnt; i++) { 00391 for (j = 0; j < PORT_DOUBLE; j++) 00392 c2[j] = c1[Cur_Head->dbl_cnvrt[j]]; 00393 c1 += sizeof(double); 00394 c2 += PORT_DOUBLE; 00395 } 00396 if (dig_fwrite(buffer, PORT_DOUBLE, cnt, fp) == cnt) 00397 return 1; 00398 } 00399 return 0; 00400 } 00401 00402 int dig__fwrite_port_F(float *buf, /* FLOAT */ 00403 int cnt, GVFILE * fp) 00404 { 00405 int i, j; 00406 unsigned char *c1, *c2; 00407 00408 if (Cur_Head->flt_quick) { 00409 if (dig_fwrite(buf, PORT_FLOAT, cnt, fp) == cnt) 00410 return 1; 00411 } 00412 else { 00413 buf_alloc(cnt * PORT_FLOAT); 00414 c1 = (unsigned char *)buf; 00415 c2 = (unsigned char *)buffer; 00416 for (i = 0; i < cnt; i++) { 00417 for (j = 0; j < PORT_FLOAT; j++) 00418 c2[j] = c1[Cur_Head->flt_cnvrt[j]]; 00419 c1 += sizeof(float); 00420 c2 += PORT_FLOAT; 00421 } 00422 if (dig_fwrite(buffer, PORT_FLOAT, cnt, fp) == cnt) 00423 return 1; 00424 } 00425 return 0; 00426 } 00427 00428 int dig__fwrite_port_L(long *buf, /* LONG */ 00429 int cnt, GVFILE * fp) 00430 { 00431 int i, j; 00432 unsigned char *c1, *c2; 00433 00434 if (Cur_Head->lng_quick) { 00435 if (nat_lng == PORT_LONG) { 00436 if (dig_fwrite(buf, PORT_LONG, cnt, fp) == cnt) 00437 return 1; 00438 } 00439 else { 00440 buf_alloc(cnt * PORT_LONG); 00441 if (lng_order == ENDIAN_LITTLE) 00442 c1 = (unsigned char *)buf; 00443 else 00444 c1 = (unsigned char *)buf + nat_lng - PORT_LONG; 00445 c2 = (unsigned char *)buffer; 00446 for (i = 0; i < cnt; i++) { 00447 memcpy(c2, c1, PORT_LONG); 00448 c1 += PORT_LONG; 00449 c2 += sizeof(long); 00450 } 00451 if (dig_fwrite(buffer, PORT_LONG, cnt, fp) == cnt) 00452 return 1; 00453 } 00454 } 00455 else { 00456 buf_alloc(cnt * PORT_LONG); 00457 c1 = (unsigned char *)buf; 00458 c2 = (unsigned char *)buffer; 00459 for (i = 0; i < cnt; i++) { 00460 for (j = 0; j < PORT_LONG; j++) 00461 c2[j] = c1[Cur_Head->lng_cnvrt[j]]; 00462 c1 += sizeof(long); 00463 c2 += PORT_LONG; 00464 } 00465 if (dig_fwrite(buffer, PORT_LONG, cnt, fp) == cnt) 00466 return 1; 00467 } 00468 return 0; 00469 } 00470 00471 int dig__fwrite_port_I(int *buf, /* INT */ 00472 int cnt, GVFILE * fp) 00473 { 00474 int i, j; 00475 unsigned char *c1, *c2; 00476 00477 if (Cur_Head->int_quick) { 00478 if (nat_int == PORT_INT) { 00479 if (dig_fwrite(buf, PORT_INT, cnt, fp) == cnt) 00480 return 1; 00481 } 00482 else { 00483 buf_alloc(cnt * PORT_INT); 00484 if (int_order == ENDIAN_LITTLE) 00485 c1 = (unsigned char *)buf; 00486 else 00487 c1 = (unsigned char *)buf + nat_int - PORT_INT; 00488 c2 = (unsigned char *)buffer; 00489 for (i = 0; i < cnt; i++) { 00490 memcpy(c2, c1, PORT_INT); 00491 c1 += PORT_INT; 00492 c2 += sizeof(int); 00493 } 00494 if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt) 00495 return 1; 00496 } 00497 } 00498 else { 00499 buf_alloc(cnt * PORT_INT); 00500 c1 = (unsigned char *)buf; 00501 c2 = (unsigned char *)buffer; 00502 for (i = 0; i < cnt; i++) { 00503 for (j = 0; j < PORT_INT; j++) 00504 c2[j] = c1[Cur_Head->int_cnvrt[j]]; 00505 c1 += sizeof(int); 00506 c2 += PORT_INT; 00507 } 00508 if (dig_fwrite(buffer, PORT_INT, cnt, fp) == cnt) 00509 return 1; 00510 } 00511 return 0; 00512 } 00513 00514 int dig__fwrite_port_S(short *buf, /* SHORT */ 00515 int cnt, GVFILE * fp) 00516 { 00517 int i, j; 00518 unsigned char *c1, *c2; 00519 00520 if (Cur_Head->shrt_quick) { 00521 if (nat_shrt == PORT_SHORT) { 00522 if (dig_fwrite(buf, PORT_SHORT, cnt, fp) == cnt) 00523 return 1; 00524 } 00525 else { 00526 buf_alloc(cnt * PORT_SHORT); 00527 if (shrt_order == ENDIAN_LITTLE) 00528 c1 = (unsigned char *)buf; 00529 else 00530 c1 = (unsigned char *)buf + nat_shrt - PORT_SHORT; 00531 c2 = (unsigned char *)buffer; 00532 for (i = 0; i < cnt; i++) { 00533 memcpy(c2, c1, PORT_SHORT); 00534 c1 += PORT_SHORT; 00535 c2 += sizeof(short); 00536 } 00537 if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt) 00538 return 1; 00539 } 00540 } 00541 else { 00542 buf_alloc(cnt * PORT_SHORT); 00543 c1 = (unsigned char *)buf; 00544 c2 = (unsigned char *)buffer; 00545 for (i = 0; i < cnt; i++) { 00546 for (j = 0; j < PORT_SHORT; j++) 00547 c2[j] = c1[Cur_Head->shrt_cnvrt[j]]; 00548 c1 += sizeof(short); 00549 c2 += PORT_SHORT; 00550 } 00551 if (dig_fwrite(buffer, PORT_SHORT, cnt, fp) == cnt) 00552 return 1; 00553 } 00554 return 0; 00555 } 00556 00557 /* plus_t is defined as int so we only retype pointer and use int function */ 00558 int dig__fwrite_port_P(plus_t * buf, /* PLUS_T->INT */ 00559 int cnt, GVFILE * fp) 00560 { 00561 return (dig__fwrite_port_I((int *)buf, cnt, fp)); 00562 } 00563 00564 int dig__fwrite_port_C(char *buf, /* CHAR */ 00565 int cnt, GVFILE * fp) 00566 { 00567 if (dig_fwrite(buf, PORT_CHAR, cnt, fp) == cnt) 00568 return 1; 00569 00570 return 0; 00571 } 00572 00573 /* set portable info structure to byte order of file */ 00574 void dig_init_portable(struct Port_info *port, int byte_order) 00575 { 00576 int i; 00577 00578 port_init(); 00579 00580 port->byte_order = byte_order; 00581 00582 if (port->byte_order == dbl_order) 00583 port->dbl_quick = TRUE; 00584 else 00585 port->dbl_quick = FALSE; 00586 00587 for (i = 0; i < PORT_DOUBLE; i++) { 00588 if (port->byte_order == ENDIAN_BIG) 00589 port->dbl_cnvrt[i] = dbl_cnvrt[i]; 00590 else 00591 port->dbl_cnvrt[i] = dbl_cnvrt[PORT_DOUBLE - i - 1]; 00592 } 00593 00594 if (port->byte_order == flt_order) 00595 port->flt_quick = TRUE; 00596 else 00597 port->flt_quick = FALSE; 00598 00599 for (i = 0; i < PORT_FLOAT; i++) { 00600 if (port->byte_order == ENDIAN_BIG) 00601 port->flt_cnvrt[i] = flt_cnvrt[i]; 00602 else 00603 port->flt_cnvrt[i] = flt_cnvrt[PORT_FLOAT - i - 1]; 00604 } 00605 00606 if (port->byte_order == lng_order) 00607 port->lng_quick = TRUE; 00608 else 00609 port->lng_quick = FALSE; 00610 00611 for (i = 0; i < PORT_LONG; i++) { 00612 if (port->byte_order == ENDIAN_BIG) 00613 port->lng_cnvrt[i] = lng_cnvrt[i]; 00614 else 00615 port->lng_cnvrt[i] = lng_cnvrt[PORT_LONG - i - 1]; 00616 } 00617 00618 if (port->byte_order == int_order) 00619 port->int_quick = TRUE; 00620 else 00621 port->int_quick = FALSE; 00622 00623 for (i = 0; i < PORT_INT; i++) { 00624 if (port->byte_order == ENDIAN_BIG) 00625 port->int_cnvrt[i] = int_cnvrt[i]; 00626 else 00627 port->int_cnvrt[i] = int_cnvrt[PORT_INT - i - 1]; 00628 } 00629 00630 if (port->byte_order == shrt_order) 00631 port->shrt_quick = TRUE; 00632 else 00633 port->shrt_quick = FALSE; 00634 00635 for (i = 0; i < PORT_SHORT; i++) { 00636 if (port->byte_order == ENDIAN_BIG) 00637 port->shrt_cnvrt[i] = shrt_cnvrt[i]; 00638 else 00639 port->shrt_cnvrt[i] = shrt_cnvrt[PORT_SHORT - i - 1]; 00640 } 00641 00642 return; 00643 } 00644 00645 /* set current portable info */ 00646 int dig_set_cur_port(struct Port_info *port) 00647 { 00648 Cur_Head = port; 00649 return 0; 00650 } 00651 00652 int dig__byte_order_out() 00653 { 00654 if (dbl_order == ENDIAN_LITTLE) 00655 return (ENDIAN_LITTLE); 00656 else 00657 return (ENDIAN_BIG); 00658 }