cube_io.c 7.8 KB

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