cube_io.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #include <stdlib.h>
  2. #include <grass/gis.h>
  3. #include "viz.h"
  4. static unsigned char Buffer[10000]; /* buffer for outputting data to file */
  5. /*
  6. ** Buffer Format:
  7. ** n_thresholds // char //
  8. ** Jump cnt // short //
  9. ** n_polys [n_thresholds] // char (nybble?) //
  10. ** thresh_indexes [n_thresholds] // char //
  11. ** poly_info [n_thresholds] // char v[3][3];n[3][3]; //
  12. **
  13. ** if (n_thresholds < 0) then -n_threshlds == number of consecutive cubes
  14. ** on current row that do NOT contain any threshold info, and thus any
  15. ** data space in draw file.
  16. ** If val[ n_thresholds(i) ] < 0 then next byte is
  17. ** 'n_thresholds(i+(-n_threholds(i)))'
  18. **
  19. ** BUT, this code will simply place a 0 in 1st byte, and send it on to
  20. * lower routine that writes out compressed data.
  21. */
  22. int write_cube(Cube_data * Cube, /* array of poly info by threshold */
  23. int cur_x, file_info * headfax)
  24. {
  25. register int i, j;
  26. register int size; /* final size of data written */
  27. register int offset1; /* pointer to n_polys */
  28. register int offset2; /* pointer to thresh_indexes */
  29. register int offset3 = 0; /* pointer to poly_info */
  30. poly_info *Poly_info;
  31. int t_cnt;
  32. t_cnt = Cube->n_thresh;
  33. Buffer[0] = t_cnt;
  34. if (t_cnt) {
  35. offset1 = 3; /* pointer to n_polys */
  36. offset2 = 3 + t_cnt; /* pointer to thresh_indexes */
  37. offset3 = 3 + t_cnt + t_cnt; /* pointer to poly_info */
  38. /*poly_size = sizeof (poly_info) * t_cnt; */
  39. for (i = 0; i < Cube->n_thresh; i++) { /* n_thresholds loop */
  40. Buffer[offset1++] = Cube->data[i].npoly;
  41. Buffer[offset2++] = Cube->data[i].t_ndx; /* THRESHOLD INDEX */
  42. for (j = 0; j < Cube->data[i].npoly; j++) {
  43. Poly_info = &(Cube->data[i].poly[j]);
  44. /*memcpy (Buffer[offset3], Cube->data[i].poly_info,poly_size); */
  45. Buffer[offset3++] = Poly_info->v1[0];
  46. Buffer[offset3++] = Poly_info->v1[1];
  47. Buffer[offset3++] = Poly_info->v1[2];
  48. Buffer[offset3++] = Poly_info->v2[0];
  49. Buffer[offset3++] = Poly_info->v2[1];
  50. Buffer[offset3++] = Poly_info->v2[2];
  51. Buffer[offset3++] = Poly_info->v3[0];
  52. Buffer[offset3++] = Poly_info->v3[1];
  53. Buffer[offset3++] = Poly_info->v3[2];
  54. Buffer[offset3++] = Poly_info->n1[0];
  55. Buffer[offset3++] = Poly_info->n1[1];
  56. Buffer[offset3++] = Poly_info->n1[2];
  57. /* DEBUG */
  58. if (headfax->linefax.litmodel > 1) { /* 3 normals */
  59. Buffer[offset3++] = Poly_info->n2[0];
  60. Buffer[offset3++] = Poly_info->n2[1];
  61. Buffer[offset3++] = Poly_info->n2[2];
  62. Buffer[offset3++] = Poly_info->n3[0];
  63. Buffer[offset3++] = Poly_info->n3[1];
  64. Buffer[offset3++] = Poly_info->n3[2];
  65. }
  66. }
  67. }
  68. size = offset3 - 3; /* 3 is 1st 3 bytes header */
  69. Buffer[1] = (size >> 8) & 0xff; /* write short Big-endian */
  70. Buffer[2] = size & 0xff;
  71. }
  72. /*fprintf(stderr,"before write_cube_buffer\n"); */
  73. write_cube_buffer(Buffer, offset3, cur_x, headfax); /* write it out to file */
  74. return 0;
  75. }
  76. /*
  77. ** Still have to add code to build index table
  78. ** Also I am going to incorporate this into build_output before we're done
  79. */
  80. int write_cube_buffer(unsigned char *Buffer, int size,
  81. int cur_x, file_info * headfax)
  82. {
  83. static int num_zero = 0;
  84. unsigned char junk;
  85. if (!Buffer[0]) {
  86. num_zero++;
  87. if (num_zero == 126 || cur_x == headfax->xdim - 2) {
  88. junk = 0x80 | num_zero;
  89. fwrite(&junk, 1, 1, headfax->dspfoutfp);
  90. num_zero = 0;
  91. }
  92. }
  93. else {
  94. /* first write out zero data */
  95. if (num_zero) {
  96. junk = 0x80 | num_zero;
  97. fwrite(&junk, 1, 1, headfax->dspfoutfp);
  98. num_zero = 0;
  99. }
  100. /* then the current buffer */
  101. fwrite(Buffer, 1, size, headfax->dspfoutfp);
  102. }
  103. return 0;
  104. }
  105. static long fsize = 0;
  106. static char *fptr = NULL;
  107. /*
  108. ** expects headfax->dspfinfp to be pointing to current cube
  109. ** i.e. already searched up to this point (allowing of course
  110. ** for 0 data already read in
  111. **
  112. ** returns num_thresholds or 0 for no data or -1 on error
  113. **
  114. ** expects linefax and headfax to be filled in.
  115. */
  116. int read_cube(Cube_data * Cube, file_info * headfax)
  117. {
  118. register int offset1, offset2, offset3;
  119. int t_cnt;
  120. int ret;
  121. int i, j, size;
  122. char inchar;
  123. poly_info *Poly_info;
  124. static int first = 1;
  125. FILE *fp;
  126. static int zeros_left = 0; /* move this out if a seek routine is written */
  127. fp = headfax->dspfinfp;
  128. first = !fsize;
  129. if (first)
  130. zeros_left = 0;
  131. while (first) { /* use while instead of if to utilize 'break' !! */
  132. /* try reading the entire file into memory */
  133. long start, stop, i;
  134. int ret;
  135. first = 0;
  136. start = G_ftell(fp);
  137. G_fseek(fp, 0L, 2);
  138. stop = G_ftell(fp);
  139. fsize = stop - start + 1;
  140. G_fseek(fp, start, 0);
  141. if (fptr) {
  142. free(fptr);
  143. fptr = NULL;
  144. }
  145. if (NULL == (fptr = malloc(fsize))) {
  146. /*DEBUG*/ fprintf(stderr, "Malloc failed\n");
  147. fsize = 0;
  148. break;
  149. }
  150. for (i = 0; (ret = fread(fptr + i, 1, 10240, fp)); i += ret) ;
  151. }
  152. if (zeros_left) {
  153. --zeros_left;
  154. return Cube->n_thresh = 0;
  155. }
  156. my_fread(&inchar, 1, 1, fp); /* use signed char */
  157. if (inchar & 0x80) {
  158. zeros_left = (0x7f & inchar) - 1;
  159. return Cube->n_thresh = 0;
  160. }
  161. else /*read in cubefax data */
  162. t_cnt = inchar;
  163. /* read in size info */
  164. my_fread(&inchar, 1, 1, fp); /* read in size of cube data */
  165. size = inchar << 8;
  166. my_fread(&inchar, 1, 1, fp);
  167. size |= inchar;
  168. if (0 >= (ret = my_fread((char *)Buffer, 1, size, fp))) {
  169. fprintf(stderr, "Error reading display file offset %"PRI_OFF_T"\n", G_ftell(fp));
  170. return (-1);
  171. }
  172. if (ret != size) {
  173. fprintf(stderr, "Error (size) reading display file offset %"PRI_OFF_T"\n",
  174. G_ftell(fp));
  175. return (-1);
  176. }
  177. {
  178. offset1 = 0; /* pointer to n_polys */
  179. offset2 = t_cnt; /* pointer to thresh_indexes */
  180. offset3 = t_cnt + t_cnt; /* pointer to poly_info */
  181. for (i = 0; i < t_cnt; i++) { /* n_thresholds loop */
  182. Cube->data[i].npoly = Buffer[offset1++];
  183. Cube->data[i].t_ndx = Buffer[offset2++]; /* THRESHOLD INDEX */
  184. for (j = 0; j < Cube->data[i].npoly; j++) {
  185. Poly_info = &(Cube->data[i].poly[j]);
  186. Poly_info->v1[0] = Buffer[offset3++];
  187. Poly_info->v1[1] = Buffer[offset3++];
  188. Poly_info->v1[2] = Buffer[offset3++];
  189. Poly_info->v2[0] = Buffer[offset3++];
  190. Poly_info->v2[1] = Buffer[offset3++];
  191. Poly_info->v2[2] = Buffer[offset3++];
  192. Poly_info->v3[0] = Buffer[offset3++];
  193. Poly_info->v3[1] = Buffer[offset3++];
  194. Poly_info->v3[2] = Buffer[offset3++];
  195. Poly_info->n1[0] = Buffer[offset3++];
  196. Poly_info->n1[1] = Buffer[offset3++];
  197. Poly_info->n1[2] = Buffer[offset3++];
  198. /*
  199. fprintf(stderr,"# %f ",Poly_info->v1[0]);
  200. fprintf(stderr,"%f ",Poly_info->v1[1]);
  201. fprintf(stderr,"%f \n",Poly_info->v1[2]);
  202. */
  203. if (headfax->linefax.litmodel > 1) { /* 3 normals */
  204. Poly_info->n2[0] = Buffer[offset3++];
  205. Poly_info->n2[1] = Buffer[offset3++];
  206. Poly_info->n2[2] = Buffer[offset3++];
  207. Poly_info->n3[0] = Buffer[offset3++];
  208. Poly_info->n3[1] = Buffer[offset3++];
  209. Poly_info->n3[2] = Buffer[offset3++];
  210. }
  211. }
  212. }
  213. }
  214. return Cube->n_thresh = t_cnt;
  215. }
  216. #ifdef NEWCODE
  217. int my_fread(char *buf, int size, int cnt, FILE * fp)
  218. {
  219. static char in_buf[10240];
  220. static char *start, *end;
  221. char *outp;
  222. int ret;
  223. if (ret = fread(in_buf, 1, 10240, fp)) ;
  224. return 0;
  225. }
  226. #else
  227. static int cptr = 0;
  228. int my_fread(char *buf, int size, int cnt, FILE * fp)
  229. {
  230. if (!fsize)
  231. return fread(buf, size, cnt, fp);
  232. else {
  233. int amt;
  234. amt = size * cnt;
  235. if (cptr + amt >= fsize)
  236. amt = fsize - cptr - 1;
  237. struct_copy(buf, fptr + cptr, amt);
  238. cptr += amt;
  239. return (amt);
  240. }
  241. return 0;
  242. }
  243. int reset_reads(file_info * headfax)
  244. {
  245. if (!fsize)
  246. G_fseek(headfax->dspfinfp, headfax->Dataoff, 0);
  247. else
  248. cptr = 0;
  249. return 0;
  250. }
  251. int new_dspf(file_info * hfax)
  252. {
  253. G_fseek(hfax->dspfinfp, hfax->Dataoff, 0);
  254. cptr = fsize = 0;
  255. return 0;
  256. }
  257. #endif