2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: cgmio.c /main/5 1996/07/01 15:34:30 cde-hal $ */
24 /* this is the I/O module for the CGM interpreter */
25 /* we will do all of our I/O with non-specific calls, e.g., fread */
26 /* this should not be too slow since we intend to no random I/O */
27 #include "cgm.h" /* our standard defs */
28 #include "GraphicsP.h"
30 /* necessary globals for the input file */
32 /* we'll get our records BUFSIZ bytes at a time */
33 #define CGMB_SIZE BUFSIZ /* might change later */
34 static unsigned char cgm_buffer[CGMB_SIZE];
35 /* pointers into the input buffer */
36 static unsigned char *begin_ptr, *endin_ptr, *in_ptr;
37 static int io_debug = 0, recs_got, bytes_read;
39 /* function to get an input record, return no of bytes read */
40 static int get_cgm_rec(unsigned char *start_ptr,
46 bytes_got = _DtGrRead(start_ptr, 1, buffer_size, cgmptr);
48 bytes_read += bytes_got;
49 /* printf("bytes_got %d\n",bytes_got); [PLA] */
52 /* function to open the CGM file */
53 /* stream is a file stream */
54 int open_cgm_file(_DtGrStream *stream)
57 fprintf(stderr, "Attempting to open file, %s\n", stream->source.file.filename);
58 /* no uncompress supported */
59 if (!(stream->source.file.fileptr =
60 fopen(stream->source.file.filename, "r"))) {
61 burp(stderr, "couldn't open %s for input\n", stream->source.file.filename);
63 } else if (io_debug) burp(stderr, "opened %s for input\n",
64 stream->source.file.filename);
66 /* get the first record */
67 begin_ptr = cgm_buffer;
68 if ((bytes_got = get_cgm_rec(begin_ptr, CGMB_SIZE, stream)) < 1) {
69 burp(stderr, "empty file %s ?\n", stream->source.file.filename);
72 endin_ptr = begin_ptr + bytes_got;
77 /* function to prepare the CGM buffer */
78 /* stream is a buffer stream */
79 int open_cgm_buffer(_DtGrStream *stream)
83 /* get the first record */
84 begin_ptr = cgm_buffer;
85 if ((bytes_got = get_cgm_rec(begin_ptr, CGMB_SIZE, stream)) < 1) {
86 burp(stderr, "empty file %s ?\n", stream->source.file.filename);
89 endin_ptr = begin_ptr + bytes_got;
94 /* function to get a number of binary format bytes */
95 static int get_b_bytes(unsigned char *out_ptr,
96 int bytes_wanted, _DtGrStream *stream)
100 burp(stderr, "haven't opened file yet !\n");
103 /* check for legitimacy */
104 if (bytes_wanted < 0) {
105 burp(stderr, "negative no of bytes requested (%d) ?\n",
109 if (bytes_wanted % 2) burp(stderr, "odd %d bytes ?\n", bytes_wanted);
111 /* move over bytes from input buffer */
112 for (i=0; (bytes_wanted > 0) && (in_ptr < endin_ptr); ++i) {
113 *out_ptr++ = *in_ptr++;
116 if (!bytes_wanted) return(1); /* finished */
119 while (bytes_wanted >= CGMB_SIZE) { /* read 'em straight in */
120 if ((bytes_got = get_cgm_rec(out_ptr, CGMB_SIZE, stream)) < 1) {
121 burp(stderr, "couldn't get bytes in get_b_bytes\n");
124 out_ptr += bytes_got;
125 bytes_wanted -= bytes_got;
127 /* buffer the rest */
128 while (bytes_wanted > 0) {
129 if ((bytes_got = get_cgm_rec(begin_ptr, CGMB_SIZE, stream)) < 1) {
130 burp(stderr, "couldn't get buffered bytes in get_b_bytes\n");
133 /* realign the pointers */
134 endin_ptr = begin_ptr + bytes_got;
136 /* move over bytes from input buffer */
137 for (i=0; (bytes_wanted > 0) && (in_ptr < endin_ptr); ++i) {
138 *out_ptr++ = *in_ptr++;
147 /* function to input a complete CGM Binary command */
148 unsigned char *get_b_cmd(struct cmd_info_s *cmd_ptr, _DtGrStream *stream)
150 #define INIT_MEM (50 * 1024) /* initial allocation */
151 static unsigned char *mem_ptr = NULL;
152 static int mem_allocated;
153 int data_left, new_len;
155 /* if first time in, get the initial memory allocation */
156 if ((!mem_ptr) && (!(mem_ptr = (unsigned char *) malloc(INIT_MEM)))) {
157 burp(stderr, "couldn't allocate initial memory for get_b_cmd\n");
159 } else mem_allocated = INIT_MEM;
161 /* get the next two bytes */
162 if (!get_b_bytes(mem_ptr, 2, stream)) {
163 burp(stderr, "trouble getting first 2 bytes of command\n");
166 /* mark the position */
167 cmd_ptr->byte_no = bytes_read - (endin_ptr - in_ptr) - 2;
169 /* now decipher the command header (lots of magic numbers !)*/
170 cmd_ptr->Class = (int) ((mem_ptr[0] >> 4) & 15);
171 cmd_ptr->element = (int) (((mem_ptr[0] << 3) & 127) |
172 ((mem_ptr[1] >> 5) & 7));
173 cmd_ptr->p_len = (int) (mem_ptr[1] & 31);
175 /* is this a short form command ? */
176 if (cmd_ptr->p_len < 31) {
177 if (!get_b_bytes(mem_ptr, (cmd_ptr->p_len % 2) ?
178 cmd_ptr->p_len + 1 : cmd_ptr->p_len, stream)) {
179 burp(stderr, "trouble with get_b_bytes\n");
181 } else return(mem_ptr); /* all done */
182 } else { /* long form */
184 cmd_ptr->p_len = 0; /* start fresh */
185 while (data_left) { /* some data still to get */
186 /* need the next two bytes */
187 if (!get_b_bytes(mem_ptr + cmd_ptr->p_len, 2, stream)) {
188 burp(stderr, "trouble with get_b_bytes\n");
191 /* how much to come ? */
192 new_len = (int) (((mem_ptr[cmd_ptr->p_len] & 127) << 8) |
193 mem_ptr[cmd_ptr->p_len + 1]);
194 if (new_len % 2) ++new_len; /* round up */
195 /* any more to come ? */
196 data_left = (mem_ptr[cmd_ptr->p_len] >> 7) & 1;
197 /* do we have enough room ? */
198 if ((cmd_ptr->p_len + new_len) > mem_allocated) {
199 if (!(mem_ptr = (unsigned char *)
200 realloc(mem_ptr, mem_allocated = cmd_ptr->p_len + new_len))) {
201 burp(stderr, "couldn't get %d bytes in get_b_cmd\n",
205 burp(stderr, "increasing to %d bytes allocated\n", mem_allocated);
207 /* get the bytes needed */
208 if (!get_b_bytes(mem_ptr + cmd_ptr->p_len, new_len, stream)) {
209 burp(stderr, "couldn't get next %d bytes in get_b_cmd\n",
213 cmd_ptr->p_len += new_len;
216 return(mem_ptr); /* all done */