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