main.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /*
  2. * r.in.bin
  3. *
  4. * Copyright (C) 2000 by the GRASS Development Team
  5. * Author: Bob Covill <bcovill tekmap.ns.ca>
  6. *
  7. * This program is free software under the GPL (>=v2)
  8. * Read the file COPYING coming with GRASS for details.
  9. *
  10. */
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include <sys/stat.h>
  15. #include <grass/gis.h>
  16. #include <grass/raster.h>
  17. #include <grass/raster3d.h>
  18. #include <grass/glocale.h>
  19. /* Some global variables */
  20. RASTER3D_Map *map;
  21. RASTER3D_Region region;
  22. FILE *fp;
  23. unsigned char *in_cell;
  24. static void swap_2(void *p) {
  25. unsigned char *q = p;
  26. unsigned char t;
  27. t = q[0];
  28. q[0] = q[1];
  29. q[1] = t;
  30. }
  31. static void swap_4(void *p) {
  32. unsigned char *q = p;
  33. unsigned char t;
  34. t = q[0];
  35. q[0] = q[3];
  36. q[3] = t;
  37. t = q[1];
  38. q[1] = q[2];
  39. q[2] = t;
  40. }
  41. static void swap_8(void *p) {
  42. unsigned char *q = p;
  43. unsigned char t;
  44. t = q[0];
  45. q[0] = q[7];
  46. q[7] = t;
  47. t = q[1];
  48. q[1] = q[6];
  49. q[6] = t;
  50. t = q[2];
  51. q[2] = q[5];
  52. q[5] = t;
  53. t = q[3];
  54. q[3] = q[4];
  55. q[4] = t;
  56. }
  57. static void read_cell(DCELL *out_cell, int is_integer, int is_signed, int bytes,
  58. int byte_swap) {
  59. if (fread(in_cell, bytes, 1, fp) != 1)
  60. G_fatal_error(_("Error reading binary data"));
  61. if (byte_swap) {
  62. switch (bytes) {
  63. case 1:
  64. break;
  65. case 2:
  66. swap_2(in_cell);
  67. break;
  68. case 4:
  69. swap_4(in_cell);
  70. break;
  71. case 8:
  72. swap_8(in_cell);
  73. break;
  74. }
  75. }
  76. if (!is_integer) {
  77. switch (bytes) {
  78. case 4:
  79. *out_cell = (DCELL) *(float *) in_cell;
  80. break;
  81. case 8:
  82. *out_cell = (DCELL) *(double *) in_cell;
  83. break;
  84. }
  85. } else if (is_signed) {
  86. switch (bytes) {
  87. case 1:
  88. *out_cell = (DCELL) *(signed char *) in_cell;
  89. break;
  90. case 2:
  91. *out_cell = (DCELL) *(short *) in_cell;
  92. break;
  93. case 4:
  94. *out_cell = (DCELL) *(int *) in_cell;
  95. break;
  96. #ifdef HAVE_LONG_LONG_INT
  97. case 8:
  98. *out_cell = (DCELL) *(long long *) in_cell;
  99. break;
  100. #endif
  101. }
  102. } else {
  103. switch (bytes) {
  104. case 1:
  105. *out_cell = (DCELL) *(unsigned char *) in_cell;
  106. break;
  107. case 2:
  108. *out_cell = (DCELL) *(unsigned short *) in_cell;
  109. break;
  110. case 4:
  111. *out_cell = (DCELL) *(unsigned int *) in_cell;
  112. break;
  113. #ifdef HAVE_LONG_LONG_INT
  114. case 8:
  115. *out_cell = (DCELL) *(unsigned long long *) in_cell;
  116. break;
  117. #endif
  118. }
  119. }
  120. }
  121. static void bin_to_raster3d(char *null, int map_type, int is_integer,
  122. int is_signed, int bytes, int byte_swap, int row_swap, int depth_swap) {
  123. int x, y, z;
  124. int col, row, depth;
  125. DCELL value;
  126. FCELL fvalue;
  127. DCELL null_value;
  128. int tileX, tileY, tileZ;
  129. if (null)
  130. null_value = atof(null);
  131. Rast3d_get_tile_dimensions_map(map, &tileX, &tileY, &tileZ);
  132. Rast3d_min_unlocked(map, RASTER3D_USE_CACHE_X);
  133. Rast3d_autolock_on(map);
  134. Rast3d_unlock_all(map);
  135. G_message(_("Loading %s data with %i bytes ... (%dx%dx%d)"),
  136. (is_integer? "integer":"floating point "), bytes, region.cols,
  137. region.rows, region.depths);
  138. for (z = 0; z < region.depths; z++) {
  139. G_percent(z, region.depths, 1);
  140. if ((z % tileZ) == 0)
  141. Rast3d_unlock_all(map);
  142. for (y = 0; y < region.rows; y++) {/* go south to north */
  143. for (x = 0; x < region.cols; x++) {
  144. /* From west to east */
  145. col = x;
  146. /* The default is to read rows from north to south */
  147. row = y;
  148. /* From bottom to the top */
  149. depth = z;
  150. /* Read rows as from south to north */
  151. if (row_swap)
  152. row = region.rows - y - 1;
  153. /* Read XY layer from top to bottom */
  154. if (depth_swap)
  155. depth = region.depths - z - 1;
  156. /* Read value from binary file */
  157. read_cell(&value, is_integer, is_signed, bytes, byte_swap);
  158. /* Write value to the 3D raster map */
  159. if (map_type == DCELL_TYPE) {
  160. if (null && value == null_value)
  161. Rast3d_set_null_value(&value, 1, DCELL_TYPE);
  162. Rast3d_put_double(map, col, row, depth, value);
  163. } else {
  164. fvalue = (FCELL) value;
  165. if (null && value == null_value)
  166. Rast3d_set_null_value(&fvalue, 1, FCELL_TYPE);
  167. Rast3d_put_double(map, col, row, depth, fvalue);
  168. }
  169. }
  170. }
  171. }
  172. if (!Rast3d_flush_all_tiles(map))
  173. G_fatal_error(_("Error flushing tiles"));
  174. Rast3d_autolock_off(map);
  175. Rast3d_unlock_all(map);
  176. G_percent(1, 1, 1);
  177. }
  178. int main(int argc, char *argv[]) {
  179. struct GModule *module;
  180. struct {
  181. struct Option *input;
  182. struct Option *output;
  183. struct Option *null;
  184. struct Option *bytes;
  185. struct Option *order;
  186. struct Option *north;
  187. struct Option *south;
  188. struct Option *top;
  189. struct Option *bottom;
  190. struct Option *east;
  191. struct Option *west;
  192. struct Option *rows;
  193. struct Option *cols;
  194. struct Option *depths;
  195. } parm;
  196. struct {
  197. struct Flag *integer_in;
  198. struct Flag *sign;
  199. struct Flag *swap;
  200. struct Flag *depth;
  201. struct Flag *row;
  202. } flag;
  203. const char *input;
  204. const char *output;
  205. int is_integer;
  206. int is_signed;
  207. int bytes;
  208. int order;
  209. int byte_swap;
  210. RASTER_MAP_TYPE map_type;
  211. off_t file_size;
  212. struct History history;
  213. off_t expected;
  214. /* Need to be allocated later */
  215. in_cell = NULL;
  216. G_gisinit(argv[0]);
  217. /* Set description */
  218. module = G_define_module();
  219. G_add_keyword(_("raster"));
  220. G_add_keyword(_("import"));
  221. module->description =
  222. _("Import a binary raster file into a GRASS 3D raster map layer.");
  223. parm.input = G_define_standard_option(G_OPT_F_INPUT);
  224. parm.input->description = _("Binary 3D raster file to be imported");
  225. parm.output = G_define_standard_option(G_OPT_R3_OUTPUT);
  226. parm.bytes = G_define_option();
  227. parm.bytes->key = "bytes";
  228. parm.bytes->type = TYPE_INTEGER;
  229. parm.bytes->required = YES;
  230. parm.bytes->options = "1,2,4,8";
  231. parm.bytes->description = _("Number of bytes per cell in binary file");
  232. parm.bytes->guisection = _("Settings");
  233. parm.order = G_define_option();
  234. parm.order->key = "order";
  235. parm.order->type = TYPE_STRING;
  236. parm.order->required = NO;
  237. parm.order->options = "big,little,native,swap";
  238. parm.order->description = _("Byte order in binary file");
  239. parm.order->answer = "native";
  240. parm.north = G_define_option();
  241. parm.north->key = "north";
  242. parm.north->type = TYPE_DOUBLE;
  243. parm.north->required = YES;
  244. parm.north->description =
  245. _("Northern limit of geographic region (outer edge)");
  246. parm.north->guisection = _("Bounds");
  247. parm.south = G_define_option();
  248. parm.south->key = "south";
  249. parm.south->type = TYPE_DOUBLE;
  250. parm.south->required = YES;
  251. parm.south->description =
  252. _("Southern limit of geographic region (outer edge)");
  253. parm.south->guisection = _("Bounds");
  254. parm.east = G_define_option();
  255. parm.east->key = "east";
  256. parm.east->type = TYPE_DOUBLE;
  257. parm.east->required = YES;
  258. parm.east->description =
  259. _("Eastern limit of geographic region (outer edge)");
  260. parm.east->guisection = _("Bounds");
  261. parm.west = G_define_option();
  262. parm.west->key = "west";
  263. parm.west->type = TYPE_DOUBLE;
  264. parm.west->required = YES;
  265. parm.west->description =
  266. _("Western limit of geographic region (outer edge)");
  267. parm.west->guisection = _("Bounds");
  268. parm.bottom = G_define_option();
  269. parm.bottom->key = "bottom";
  270. parm.bottom->type = TYPE_DOUBLE;
  271. parm.bottom->required = YES;
  272. parm.bottom->description =
  273. _("Bottom limit of geographic region (outer edge)");
  274. parm.bottom->guisection = _("Bounds");
  275. parm.top = G_define_option();
  276. parm.top->key = "top";
  277. parm.top->type = TYPE_DOUBLE;
  278. parm.top->required = YES;
  279. parm.top->description = _("Top limit of geographic region (outer edge)");
  280. parm.top->guisection = _("Bounds");
  281. parm.rows = G_define_option();
  282. parm.rows->key = "rows";
  283. parm.rows->type = TYPE_INTEGER;
  284. parm.rows->required = YES;
  285. parm.rows->description = _("Number of rows");
  286. parm.rows->guisection = _("Bounds");
  287. parm.cols = G_define_option();
  288. parm.cols->key = "cols";
  289. parm.cols->type = TYPE_INTEGER;
  290. parm.cols->required = YES;
  291. parm.cols->description = _("Number of columns");
  292. parm.cols->guisection = _("Bounds");
  293. parm.depths = G_define_option();
  294. parm.depths->key = "depths";
  295. parm.depths->type = TYPE_INTEGER;
  296. parm.depths->required = YES;
  297. parm.depths->description = _("Number of depths");
  298. parm.depths->guisection = _("Bounds");
  299. parm.null = G_define_option();
  300. parm.null->key = "null";
  301. parm.null->type = TYPE_DOUBLE;
  302. parm.null->required = NO;
  303. parm.null->description = _("Set Value to NULL");
  304. parm.null->guisection = _("Settings");
  305. flag.row = G_define_flag();
  306. flag.row->key = 'r';
  307. flag.row->description = _("Switch the row order in output from "
  308. "north->south to south->north");
  309. flag.depth = G_define_flag();
  310. flag.depth->key = 'd';
  311. flag.depth->description = _("Switch the depth order in output "
  312. "from bottom->top to top->bottom");
  313. flag.integer_in = G_define_flag();
  314. flag.integer_in->key = 'i';
  315. flag.integer_in->description =
  316. _("Binary data is of type integer");
  317. flag.sign = G_define_flag();
  318. flag.sign->key = 's';
  319. flag.sign->description = _("Signed data (two's complement)");
  320. flag.sign->guisection = _("Settings");
  321. flag.swap = G_define_flag();
  322. flag.swap->key = 'b';
  323. flag.swap->description = _("Byte Swap the Data During Import");
  324. flag.swap->guisection = _("Settings");
  325. if (G_parser(argc, argv))
  326. exit(EXIT_FAILURE);
  327. input = parm.input->answer;
  328. output = parm.output->answer;
  329. if (G_strcasecmp(parm.order->answer, "big") == 0)
  330. order = 0;
  331. else if (G_strcasecmp(parm.order->answer, "little") == 0)
  332. order = 1;
  333. else if (G_strcasecmp(parm.order->answer, "native") == 0)
  334. order = G_is_little_endian() ? 1 : 0;
  335. else if (G_strcasecmp(parm.order->answer, "swap") == 0)
  336. order = G_is_little_endian() ? 0 : 1;
  337. if (flag.swap->answer) {
  338. if (strcmp(parm.order->answer, "native") != 0)
  339. G_fatal_error(_("order= and -b are mutually exclusive"));
  340. order = G_is_little_endian() ? 0 : 1;
  341. }
  342. byte_swap = order == (G_is_little_endian() ? 0 : 1);
  343. is_signed = !!flag.sign->answer;
  344. is_integer = 0;
  345. bytes = 8;
  346. if (parm.bytes->answer)
  347. bytes = atoi(parm.bytes->answer);
  348. if (!flag.integer_in->answer) {
  349. if (bytes && bytes < 4)
  350. G_fatal_error(
  351. _("bytes=%d; must be 4 or 8 in case of floating point input"),
  352. bytes);
  353. if (!bytes)
  354. bytes = 4;
  355. } else {
  356. is_integer = 1;
  357. }
  358. #ifndef HAVE_LONG_LONG_INT
  359. if (is_integer && bytes > 4)
  360. G_fatal_error(_("Integer input doesn't support size=8 in this build"));
  361. #endif
  362. if (bytes != 1 && bytes != 2 && bytes != 4 && bytes != 8)
  363. G_fatal_error(_("bytes= must be 1, 2, 4 or 8"));
  364. region.zone = G_zone();
  365. region.proj = G_projection();
  366. region.rows = atoi(parm.rows->answer);
  367. region.cols = atoi(parm.cols->answer);
  368. region.depths = atoi(parm.depths->answer);
  369. region.top = atof(parm.top->answer);
  370. region.bottom = atof(parm.bottom->answer);
  371. if (!G_scan_northing(parm.north->answer, &region.north, region.proj))
  372. G_fatal_error(_("Illegal north coordinate <%s>"), parm.north->answer);
  373. if (!G_scan_northing(parm.south->answer, &region.south, region.proj))
  374. G_fatal_error(_("Illegal south coordinate <%s>"), parm.south->answer);
  375. if (!G_scan_easting(parm.east->answer, &region.east, region.proj))
  376. G_fatal_error(_("Illegal east coordinate <%s>"), parm.east->answer);
  377. if (!G_scan_easting(parm.west->answer, &region.west, region.proj))
  378. G_fatal_error(_("Illegal west coordinate <%s>"), parm.west->answer);
  379. Rast3d_adjust_region(&region);
  380. expected = (off_t) region.rows * region.cols * region.depths * bytes;
  381. fp = fopen(input, "rb");
  382. if (!fp)
  383. G_fatal_error(_("Unable to open <%s>"), input);
  384. /* Find File Size in Byte and Check against byte size */
  385. G_fseek(fp, 0, SEEK_END);
  386. file_size = G_ftell(fp);
  387. G_fseek(fp, 0, SEEK_SET);
  388. if (file_size != expected) {
  389. G_warning(_("File Size %lld ... Total Bytes %lld"),
  390. (long long int) file_size, (long long int) expected);
  391. G_fatal_error(_("Bytes do not match file size"));
  392. }
  393. map_type = (bytes > 4 ? DCELL_TYPE : FCELL_TYPE);
  394. if(is_integer && bytes >= 4)
  395. map_type = DCELL_TYPE;
  396. Rast3d_init_defaults();
  397. /*Open the new 3D raster map */
  398. map = Rast3d_open_new_opt_tile_size(output, RASTER3D_USE_CACHE_DEFAULT,
  399. &region, map_type, 32);
  400. if (map == NULL)
  401. G_fatal_error(_("Unable to open 3D raster map"));
  402. in_cell = G_malloc(bytes);
  403. bin_to_raster3d(parm.null->answer, map_type, is_integer, is_signed, bytes,
  404. byte_swap, flag.row->answer, flag.depth->answer);
  405. if (!Rast3d_close(map))
  406. G_fatal_error(_("Unable to close 3D raster map"));
  407. /* write input name to map history */
  408. Rast3d_read_history(output, G_mapset(), &history);
  409. Rast_set_history(&history, HIST_DATSRC_1, input);
  410. Rast3d_write_history(output, &history);
  411. fclose(fp);
  412. if (in_cell)
  413. G_free(in_cell);
  414. return EXIT_SUCCESS;
  415. }