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