GRASS GIS 8 Programmer's Manual 8.2.0(2022)-exported
cube_io.c
Go to the documentation of this file.
1#include <stdlib.h>
2#include <grass/gis.h>
3#include "viz.h"
4
5static 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
25int 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 */
93int 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
122static long fsize = 0;
123static 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 */
134int 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
251int 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
265static int cptr = 0;
266
267int 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
285int 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
296{
297 G_fseek(hfax->dspfinfp, hfax->Dataoff, 0);
298 cptr = fsize = 0;
299
300 return 0;
301}
302#endif
#define NULL
Definition: ccmath.h:32
int reset_reads(file_info *headfax)
Definition: cube_io.c:285
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:134
int new_dspf(file_info *hfax)
Definition: cube_io.c:295
int my_fread(char *buf, int size, int cnt, FILE *fp)
Definition: cube_io.c:267
int write_cube_buffer(unsigned char *Buffer, int size, int cur_x, file_info *headfax)
Definition: cube_io.c:93
double cur_x
Definition: driver/init.c:32
void G_fseek(FILE *fp, off_t offset, int whence)
Change the file position of the stream.
Definition: gis/seek.c:50
off_t G_ftell(FILE *fp)
Get the current file position of the stream.
Definition: gis/seek.c:29
Definition: viz.h:66
cube_info data[MAXTHRESH]
Definition: viz.h:68
int n_thresh
Definition: viz.h:67
int struct_copy(char *To, char *From, int size)
Definition: struct_copy.c:2
int litmodel
Definition: viz.h:25
poly_info poly[MAXPOLY]
Definition: viz.h:62
int t_ndx
Definition: viz.h:61
int npoly
Definition: viz.h:60
Definition: viz.h:29
int xdim
Definition: viz.h:34
FILE * dspfoutfp
Definition: viz.h:33
cmndln_info linefax
Definition: viz.h:44
long Dataoff
Definition: viz.h:42
FILE * dspfinfp
Definition: viz.h:33
Definition: viz.h:51
float v3[3]
Definition: viz.h:54
float n2[3]
Definition: viz.h:55
float v2[3]
Definition: viz.h:53
float v1[3]
Definition: viz.h:52
float n1[3]
Definition: viz.h:55
float n3[3]
Definition: viz.h:55