Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rle_cp.c
Go to the documentation of this file.
1 /*
2  * This software is copyrighted as noted below. It may be freely copied,
3  * modified, and redistributed, provided that the copyright notice is
4  * preserved on all copies.
5  *
6  * There is no warranty or other guarantee of fitness for this software,
7  * it is provided solely "as is". Bug reports or fixes may be sent
8  * to the author, who may or may not act on them as he desires.
9  *
10  * You may not include this software in a program or other software product
11  * without supplying the source, or without informing the end-user that the
12  * source is available for no extra charge.
13  *
14  * If you modify this software, you should include a notice giving the
15  * name of the person performing the modification, the date of modification,
16  * and the reason for such modification.
17  */
18 /*
19  * rle_cp.c - Copy the contents of one RLE image file to another.
20  *
21  * Author: Spencer W. Thomas
22  * EECS Dept.
23  * University of Michigan
24  * Date: Wed Jun 27 1990
25  * Copyright (c) 1990, University of Michigan
26  */
27 
28 #include "rle.h"
29 #include "rle_code.h"
30 #include "rle_put.h"
31 
32 /* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */
33 #define VAXSHORT( var, fp )
34  { var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; }
35 
36 /* Instruction format -- first byte is opcode, second is datum. */
37 
38 #define OPCODE(inst) (inst[0] & ~LONG)
39 #define LONGP(inst) (inst[0] & LONG)
40 #define DATUM(inst) (inst[1] & 0xff) /* Make sure it's unsigned. */
41 
42 /* Write a two-byte value in little_endian order. */
43 #define put16(a) (putc((a)&0xff,outfile),putc(((a)>>8)&0xff,outfile))
44 
45 /*****************************************************************
46  * TAG( rle_cp )
47  *
48  * Copy the image described by in_hdr to that described by out_hdr
49  * until an end-of-image is encountered.
50  *
51  * Replaces the fread/fwrite loop used that was before we were
52  * concerned with concatenated images.
53  *
54  * Inputs:
55  * in_hdr: Describes input image.
56  * Outputs:
57  * out_hdr: Describes output image.
58  * Assumptions:
59  * rle_get_setup/rle_put_setup have been called.
60  * in_hdr and out_hdr are compatible -- same number of channels,
61  * same size, all relevant channel bits set.
62  * The scanline most recently read from the input has been
63  * written to the output.
64  * Algorithm:
65  * Minimal processing is done. Each opcode is recognized to the
66  * extent necessary to copy it and its data to the output.
67  */
68 void
70 rle_hdr *in_hdr;
71 rle_hdr *the_hdr;
72 {
73  register FILE *infile = in_hdr->rle_file;
74  register FILE *outfile = the_hdr->rle_file;
75  char inst[2];
76  short nc, buflen;
77  char *buffer;
78 
79  /* Add in vertical skip from last scanline */
80  if ( in_hdr->priv.get.vert_skip > 0 )
81  {
82  in_hdr->priv.get.scan_y += in_hdr->priv.get.vert_skip;
83  if ( in_hdr->priv.get.vert_skip > 1 )
84  rle_skiprow( the_hdr, in_hdr->priv.get.vert_skip - 1 );
85  }
86 
87  if ( in_hdr->priv.get.is_eof )
88  {
89  rle_puteof( the_hdr );
90  return;
91  }
92 
93  if ( the_hdr->priv.put.nblank > 0 )
94  {
95  SkipBlankLines( the_hdr->priv.put.nblank );
96  the_hdr->priv.put.nblank = 0;
97  }
98 
99  /* Allocate memory for reading byte data. */
100  buflen = in_hdr->xmax - in_hdr->xmin + 2;
101  buffer = (char *)malloc( buflen );
102 
103  /* Otherwise, read and write instructions until an EOF
104  * instruction is encountered.
105  */
106  for (;;)
107  {
108  inst[0] = getc( infile );
109  inst[1] = getc( infile );
110 
111  /* Don't 'put' the instruction until we know what it is. */
112  if ( feof(infile) )
113  {
114  in_hdr->priv.get.is_eof = 1;
115  rle_puteof( the_hdr );
116  break; /* <--- one of the exits */
117  }
118 
119  switch( OPCODE(inst) )
120  {
121  case RSkipLinesOp:
122  putc( inst[0], outfile );
123  putc( inst[1], outfile );
124  if ( LONGP(inst) )
125  {
126  putc( getc( infile ), outfile );
127  putc( getc( infile ), outfile );
128  }
129  break; /* need to break for() here, too */
130 
131  case RSetColorOp:
132  putc( inst[0], outfile );
133  putc( inst[1], outfile );
134  break;
135 
136  case RSkipPixelsOp:
137  putc( inst[0], outfile );
138  putc( inst[1], outfile );
139  if ( LONGP(inst) )
140  {
141  putc( getc( infile ), outfile );
142  putc( getc( infile ), outfile );
143  }
144  break;
145 
146  case RByteDataOp:
147  putc( inst[0], outfile );
148  putc( inst[1], outfile );
149  if ( LONGP(inst) )
150  {
151  VAXSHORT( nc, infile );
152  put16( nc );
153  }
154  else
155  nc = DATUM(inst);
156  nc++;
157  nc = 2 * ((nc + 1) / 2);
158  /* Total paranoia. nc should never be > buflen. */
159  while ( nc > buflen )
160  {
161  fread( buffer, nc, 1, infile );
162  fwrite( buffer, nc, 1, outfile );
163  nc -= buflen;
164  }
165 
166  fread( buffer, nc, 1, infile );
167  fwrite( buffer, nc, 1, outfile );
168  break;
169 
170  case RRunDataOp:
171  putc( inst[0], outfile );
172  putc( inst[1], outfile );
173  if ( LONGP(inst) )
174  {
175  putc( getc( infile ), outfile );
176  putc( getc( infile ), outfile );
177  }
178 
179  putc( getc( infile ), outfile );
180  putc( getc( infile ), outfile );
181  break;
182 
183  case REOFOp:
184  in_hdr->priv.get.is_eof = 1;
185  rle_puteof( the_hdr );
186  break;
187 
188  default:
189  fprintf( stderr,
190  "%s: rle_cp: Unrecognized opcode: %d, reading %s\n",
191  the_hdr->cmd, OPCODE(inst), the_hdr->file_name );
192  fflush( the_hdr->rle_file );
193  exit(1);
194  }
195  if ( OPCODE(inst) == REOFOp )
196  break; /* <--- the other loop exit */
197  }
198 
199  /* Just in case the caller does something silly like calling rle_getrow. */
200  in_hdr->priv.get.scan_y = in_hdr->ymax;
201  in_hdr->priv.get.vert_skip = 0;
202 
203  return;
204 }
#define RSetColorOp
Definition: rle_code.h:38
#define RRunDataOp
Definition: rle_code.h:41
int xmin
Definition: rle.h:100
void rle_cp(rle_hdr *in_hdr, rle_hdr *the_hdr)
Definition: rle_cp.c:69
#define RSkipLinesOp
Definition: rle_code.h:37
#define LONGP(inst)
Definition: XtndRunget.c:85
#define REOFOp
Definition: rle_code.h:42
const char * cmd
Definition: rle.h:133
void rle_puteof(rle_hdr *the_hdr)
Definition: rle_putrow.c:474
#define put16(a)
Definition: rle_cp.c:43
int xmax
Definition: rle.h:100
#define RSkipPixelsOp
Definition: rle_code.h:39
#define SkipBlankLines(n)
Definition: rle_put.h:76
#define LONG
Definition: rle_code.h:36
void rle_skiprow(rle_hdr *the_hdr, int nrow)
Definition: rle_putrow.c:393
#define VAXSHORT(var, fp)
Definition: rle_cp.c:33
#define DATUM(inst)
Definition: XtndRunget.c:86
int ymax
Definition: rle.h:100
const char * file_name
Definition: rle.h:134
#define OPCODE(inst)
Definition: XtndRunget.c:84
FILE * rle_file
Definition: rle.h:114
#define RByteDataOp
Definition: rle_code.h:40