1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
% Copyright (C) 1996, 1999 Aladdin Enterprises. All rights reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
% $Id$
% viewpcx.ps
% Display a PCX file.
% Requires the Level 2 `image' operator (to handle variable pixel widths).
% If SCALE is defined, maps input pixels to output pixels with that scale;
% if SCALE is undefined, scales the image to fit the page.
% ****NOTE: does not handle multi-plane images with palette.
/pcxbytes [
0 1 255 {
64 string exch 0 1 63 {
3 copy exch put pop
} for pop
} for
] readonly def
/readpcx { % - readpcx <str>
f % gets replaced
dup read not {
pop ()
} {
dup 192 lt {
( ) dup 0 4 -1 roll put exch pop
} {
192 sub //pcxbytes 3 -1 roll read pop get exch 0 exch getinterval
} ifelse
} ifelse
} def
/get2 % <string> <index> get2 <int>
{ 2 copy get 3 1 roll 1 add get 8 bitshift add
} bind def
/dsproc
{ df s readstring pop % s gets filled in
s1 () ne { df s1 readstring pop pop } if % discard padding bytes
} def % don't bind, must be writable
/viewpcx % <filename> viewpcx -
{ 100 dict begin
/fname 1 index def
/f exch (r) file def
% Read and unpack the header.
/header f 128 string readstring pop def
/version header 1 get def
/bpp header 3 get def
/w header 8 get2 header 4 get2 sub 1 add def
/h header 10 get2 header 6 get2 sub 1 add def
/nplanes header 65 get def
/bpl header 66 get2 def
/palinfo header 68 get2 def
/nbits bpp nplanes mul def
version 5 eq
{ nbits 8 le
{ /cspace
[/Indexed /DeviceRGB 1 bpp bitshift 1 sub
f fileposition
1 nbits bitshift 3 mul string
fname status pop pop pop exch pop
1 index length sub f exch setfileposition
f exch readstring pop
exch f exch setfileposition
] def
/decode [0 cspace 2 get] def
}
{ /cspace /DeviceRGB def
/decode [0 1 0 1 0 1] def
}
ifelse
}
{ /cspace
[/Indexed /DeviceRGB 1 bpp bitshift 1 sub
header 16 1 nbits bitshift 16 .min 3 mul getinterval
] def
/decode [0 cspace 2 get] def
}
ifelse
% Set up scaling.
/SCALE where
{ pop
% Map pixels SCALE-for-1. Assume orthogonal transformation.
w 1 0 dtransform add abs div SCALE mul
h 0 1 dtransform add abs div SCALE mul
}
{ % Scale the image (uniformly) to fit the page.
clippath pathbbox pop pop translate
pathbbox .min exch pop exch pop ceiling
dup h w gt { w mul h div exch } { h mul w div } ifelse
}
ifelse scale
% Since the number of bytes per line is always even,
% it may not match the width specification.
/wbpl w bpp mul 7 add 8 idiv def
% Define the data source procedure.
/s1 bpl wbpl sub string def
/df /readpcx load copyarray dup 0 f put cvx bind readonly
0 () /SubFileDecode filter def
/dsource [ nplanes
{ /dsproc load copyarray
dup 1 wbpl string put
cvx bind readonly
}
repeat ] def
% Construct the image dictionary.
20 dict begin % image dictionary
/ImageType 1 def
/Width w def
/Height h def
/ImageMatrix [w 0 0 h neg 0 h] def
/BitsPerComponent bpp def
/Decode decode def
/DataSource dsource dup length 1 gt
{ /MultipleDataSources true def }
{ 0 get }
ifelse def
currentdict end
% Finally, display the image.
cspace setcolorspace
image
showpage
df closefile
f closefile
end
} bind def
% If the program was invoked from the command line, run it now.
[ shellarguments
{ counttomark 1 ge
{ ] { viewpcx } forall
}
{ cleartomark
(Usage: gs -- viewpcx.ps filename.pcx ...\n) print
( e.g.: gs -- viewpcx.ps my.pcx another.pcx\n) print flush
}
ifelse
}
{ pop
}
ifelse
|