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