author | Claus Gittinger <cg@exept.de> |
Mon, 22 Apr 1996 13:02:23 +0200 | |
changeset 191 | cb2815b77100 |
parent 114 | e577a2f332d0 |
child 200 | 33e4adf6fd59 |
permissions | -rw-r--r-- |
2 | 1 |
" |
21 | 2 |
COPYRIGHT (c) 1992 by Claus Gittinger |
28 | 3 |
All Rights Reserved |
2 | 4 |
|
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
12 |
||
13 |
ImageReader subclass:#PBMReader |
|
28 | 14 |
instanceVariableNames:'' |
15 |
classVariableNames:'' |
|
16 |
poolDictionaries:'' |
|
32 | 17 |
category:'Graphics-Images support' |
2 | 18 |
! |
19 |
||
21 | 20 |
!PBMReader class methodsFor:'documentation'! |
21 |
||
22 |
copyright |
|
23 |
" |
|
24 |
COPYRIGHT (c) 1992 by Claus Gittinger |
|
28 | 25 |
All Rights Reserved |
2 | 26 |
|
21 | 27 |
This software is furnished under a license and may be used |
28 |
only in accordance with the terms of that license and with the |
|
29 |
inclusion of the above copyright notice. This software may not |
|
30 |
be provided or otherwise made available to, or used by, any |
|
31 |
other person. No title to or ownership of the software is |
|
32 |
hereby transferred. |
|
33 |
" |
|
34 |
! |
|
2 | 35 |
|
21 | 36 |
version |
114
e577a2f332d0
uff - version methods changed to return stings
Claus Gittinger <cg@exept.de>
parents:
99
diff
changeset
|
37 |
^ '$Header: /cvs/stx/stx/libview2/PBMReader.st,v 1.14 1995-11-11 16:04:45 cg Exp $' |
21 | 38 |
! |
39 |
||
40 |
documentation |
|
41 |
" |
|
32 | 42 |
this class provides methods for loading and saving Portable BitMap-file |
43 |
images (Jef Poskanzers portable bitmap package). |
|
46 | 44 |
Reading is supported for 1bit (pbm), greyscale (pgm) and 24bit (ppm) formats. |
45 |
Currently, only writing of 1-bit images (Pbm) is supported. |
|
46 |
||
47 |
Q: should we bring this one to perfection and base all others on |
|
48 |
pipe-readers to the various pbmplus converters ? |
|
21 | 49 |
" |
50 |
! ! |
|
2 | 51 |
|
28 | 52 |
!PBMReader class methodsFor:'initialization'! |
53 |
||
54 |
initialize |
|
55 |
Image fileFormats at:'.pbm' put:self. |
|
56 |
Image fileFormats at:'.pgm' put:self. |
|
57 |
Image fileFormats at:'.pnm' put:self. |
|
58 |
! ! |
|
59 |
||
2 | 60 |
!PBMReader methodsFor:'private'! |
61 |
||
46 | 62 |
skipPBMJunkOn:aStream |
2 | 63 |
"This method removes any superfluous characters from the input stream." |
64 |
||
65 |
| char foundNL| |
|
66 |
||
67 |
[ |
|
28 | 68 |
char := aStream peek. |
69 |
char == $# ifTrue:[ |
|
70 |
"Start of a comment. Skip to end-of-line." |
|
46 | 71 |
"/ foundNL := (aStream skipUpTo: Character cr) notNil. |
72 |
foundNL := (aStream skipThrough: Character cr) notNil. |
|
28 | 73 |
foundNL ifFalse: [ |
74 |
"Must be EOF" |
|
75 |
^self |
|
76 |
]. |
|
77 |
char := aStream peek]. |
|
78 |
aStream atEnd not and: [char isSeparator] |
|
2 | 79 |
] whileTrue: [aStream next] |
80 |
! |
|
81 |
||
46 | 82 |
skipXPMJunkOn:aStream |
2 | 83 |
"This method removes any superfluous characters from the input stream." |
84 |
||
85 |
| char | |
|
86 |
||
87 |
[ |
|
28 | 88 |
char := aStream peek. |
89 |
aStream atEnd not and: [char isSeparator not] |
|
2 | 90 |
] whileTrue: [aStream next]. |
91 |
||
92 |
[aStream atEnd not and: [char isSeparator]] whileTrue: [ |
|
28 | 93 |
aStream next. char := aStream peek |
2 | 94 |
]. |
95 |
aStream atEnd ifTrue: [^char]. |
|
96 |
(char isDigit) ifTrue: [ ^char ]. |
|
97 |
(char == $") ifTrue: [ |
|
28 | 98 |
aStream next. |
99 |
char := aStream peek. |
|
100 |
(char isLetterOrDigit |
|
101 |
or: [(char == $#) |
|
102 |
or: [char == Character space]]) ifFalse:[ |
|
103 |
^ self skipXPMJunkOn: aStream |
|
104 |
] ifTrue: [^char] |
|
2 | 105 |
]. |
106 |
||
107 |
^self skipXPMJunkOn: aStream. |
|
108 |
! ! |
|
109 |
||
51 | 110 |
!PBMReader methodsFor:'testing '! |
111 |
||
112 |
canRepresent:anImage |
|
113 |
"return true, if anImage can be represented in my file format. |
|
114 |
Currently only B&W and Depth8 images are supported." |
|
115 |
||
116 |
|depth| |
|
117 |
||
118 |
anImage photometric == #rgb ifTrue:[ |
|
119 |
^ false "/ not yet implemented |
|
120 |
]. |
|
121 |
(depth := anImage depth) == 1 ifTrue:[^ true]. |
|
122 |
depth == 8 ifTrue:[^ true]. |
|
123 |
^ false |
|
124 |
! ! |
|
125 |
||
2 | 126 |
!PBMReader methodsFor:'writing to file'! |
127 |
||
128 |
save:image onFile:aFileName |
|
129 |
"save image as PBM/PGM/PNM file on aFileName" |
|
130 |
||
131 |
outStream := FileStream newFileNamed:aFileName. |
|
132 |
outStream isNil ifTrue:[ |
|
46 | 133 |
'PBMREADER: create error' errorPrintNL. |
28 | 134 |
^ nil |
2 | 135 |
]. |
136 |
||
137 |
width := image width. |
|
138 |
height := image height. |
|
139 |
photometric := image photometric. |
|
140 |
samplesPerPixel := image samplesPerPixel. |
|
141 |
bitsPerSample := image bitsPerSample. |
|
142 |
colorMap := image colorMap. |
|
46 | 143 |
data := image bits. |
2 | 144 |
|
145 |
photometric == #rgb ifTrue:[ |
|
46 | 146 |
^ self writePNMFileOn:outStream |
2 | 147 |
]. |
148 |
samplesPerPixel == 1 ifTrue:[ |
|
28 | 149 |
((bitsPerSample at:1) == 1) ifTrue:[ |
46 | 150 |
^ self writePBMFileOn:outStream |
28 | 151 |
]. |
152 |
((bitsPerSample at:1) == 8) ifTrue:[ |
|
46 | 153 |
^ self writePGMFileOn:outStream |
28 | 154 |
]. |
2 | 155 |
]. |
156 |
self error:'format not supported'. |
|
46 | 157 |
|
158 |
" |
|
159 |
|img| |
|
160 |
||
161 |
img := Image fromFile:'bitmaps/SBrowser.xbm'. |
|
162 |
img inspect. |
|
163 |
PBMReader save:img onFile:'test.pbm'. |
|
164 |
img := Image fromFile:'test.pbm'. |
|
165 |
img inspect. |
|
166 |
||
167 |
||
168 |
|img mono| |
|
169 |
||
170 |
img := Image fromFile:'bitmaps/garfield.gif'. |
|
171 |
img inspect. |
|
172 |
mono := img asMonochromeFormOn:Display. |
|
173 |
img := mono asImage. |
|
174 |
img inspect. |
|
175 |
PBMReader save:img onFile:'test.pbm'. |
|
176 |
img := Image fromFile:'test.pbm'. |
|
177 |
img inspect. |
|
178 |
" |
|
21 | 179 |
! |
180 |
||
46 | 181 |
writePNMFileOn:outStream |
21 | 182 |
self error:'not yet implemented' |
183 |
! |
|
184 |
||
46 | 185 |
writePBMFileOn:aStream |
186 |
"Saves the receivers image on the file fileName in Portable Bitmap format. |
|
187 |
See the class method pbmSyntax for details of the format." |
|
188 |
||
189 |
aStream nextPutAll:'P4'; cr. |
|
190 |
aStream nextPutAll:'# Converted from Smalltalk Form on '. |
|
191 |
aStream nextPutAll:Date today printString. |
|
192 |
aStream nextPutAll:' at ', Time now printString. |
|
193 |
aStream cr. |
|
194 |
aStream nextPutAll:width printString. |
|
195 |
aStream space. |
|
196 |
aStream nextPutAll:height printString. |
|
197 |
aStream cr. |
|
198 |
||
199 |
aStream binary. |
|
200 |
photometric == #blackIs0 ifTrue:[ |
|
201 |
aStream nextPutAll:data. |
|
202 |
] ifFalse:[ |
|
203 |
data invert. |
|
204 |
aStream nextPutAll:data. |
|
205 |
data invert. |
|
206 |
]. |
|
207 |
aStream close. |
|
21 | 208 |
! |
209 |
||
46 | 210 |
writePGMFileOn:outStream |
21 | 211 |
self error:'not yet implemented' |
2 | 212 |
! ! |
213 |
||
214 |
!PBMReader methodsFor:'reading from file'! |
|
215 |
||
46 | 216 |
fromStream:aStream |
2 | 217 |
"read a Portable bitmap file format as of Jef Poskanzers Portable Bitmap Package. |
218 |
supported are PBM, PGB and PNM files." |
|
219 |
||
220 |
| pnmType | |
|
221 |
||
46 | 222 |
inStream := aStream. |
223 |
inStream text. |
|
10 | 224 |
|
2 | 225 |
inStream next == $P ifFalse:[ |
46 | 226 |
'PBMREADER: PNM format' errorPrintNL. |
28 | 227 |
^nil |
2 | 228 |
]. |
229 |
pnmType := inStream next. |
|
230 |
pnmType == $4 ifTrue: [ |
|
46 | 231 |
^ self readDepth1PBMStream:aStream |
2 | 232 |
]. |
233 |
pnmType == $5 ifTrue: [ |
|
46 | 234 |
^ self readDepth8PGMStream:aStream |
2 | 235 |
]. |
236 |
pnmType == $6 ifTrue: [ |
|
46 | 237 |
^ self readDepth24PPMStream:aStream |
2 | 238 |
]. |
46 | 239 |
'PBMREADER: No recognized PNM file format' errorPrintNL. |
2 | 240 |
^ nil |
241 |
||
46 | 242 |
" |
243 |
PBMReader fromFile:'bitmaps/testimg.ppm' |
|
244 |
PBMReader fromFile:'../../fileIn/bitmaps/keyboard.pbm' |
|
245 |
" |
|
2 | 246 |
! |
247 |
||
46 | 248 |
readDepth1PBMStream:aStream |
249 |
"import portable bitmap (PBM); P4 is already read" |
|
2 | 250 |
|
46 | 251 |
self skipPBMJunkOn:aStream. |
252 |
width := Integer readFrom:aStream. |
|
253 |
width > 0 ifFalse: [ |
|
254 |
'PBMREADER: Invalid width' errorPrintNL. |
|
28 | 255 |
^ nil |
2 | 256 |
]. |
257 |
||
46 | 258 |
self skipPBMJunkOn:aStream. |
259 |
height := Integer readFrom:aStream. |
|
260 |
height > 0 ifFalse: [ |
|
261 |
'PBMREADER: Invalid height' errorPrintNL. |
|
28 | 262 |
^ nil |
21 | 263 |
]. |
2 | 264 |
|
46 | 265 |
aStream nextLine "skipThrough: Character cr". |
266 |
aStream binary. |
|
267 |
data := aStream contents. |
|
2 | 268 |
|
46 | 269 |
photometric := #blackIs0. |
2 | 270 |
samplesPerPixel := 1. |
271 |
bitsPerSample := #(1). |
|
272 |
! |
|
273 |
||
46 | 274 |
readDepth8PGMStream:aStream |
275 |
"import portable gray map (PGM); P5 is already read" |
|
2 | 276 |
|
277 |
|maxval| |
|
278 |
||
46 | 279 |
self skipPBMJunkOn:aStream. |
280 |
width := Integer readFrom:aStream. |
|
281 |
width > 0 ifFalse:[ |
|
282 |
'PBMREADER: Invalid width' errorPrintNL. |
|
28 | 283 |
^ nil |
2 | 284 |
]. |
46 | 285 |
self skipPBMJunkOn:aStream. |
286 |
height := Integer readFrom:aStream. |
|
287 |
height > 0 ifFalse:[ |
|
288 |
'PBMREADER: Invalid height' errorPrintNL. |
|
28 | 289 |
^ nil |
2 | 290 |
]. |
46 | 291 |
self skipPBMJunkOn:aStream. |
292 |
maxval := Integer readFrom:aStream. |
|
293 |
maxval >= 256 ifTrue:[ |
|
294 |
'PBMREADER: Invalid format' errorPrintNL. |
|
28 | 295 |
^ nil |
2 | 296 |
]. |
46 | 297 |
aStream skipThrough: Character cr. |
298 |
aStream binary. |
|
299 |
data := aStream contents. |
|
2 | 300 |
|
301 |
photometric := #blackIs0. |
|
302 |
samplesPerPixel := 1. |
|
303 |
bitsPerSample := #(8). |
|
304 |
! |
|
305 |
||
46 | 306 |
readDepth24PPMStream:aStream |
307 |
"import portable pixmap (PPM); P6 is already read" |
|
2 | 308 |
|
309 |
| maxval | |
|
310 |
||
46 | 311 |
self skipPBMJunkOn:aStream. |
312 |
width := Integer readFrom:aStream. |
|
313 |
width > 0 ifFalse: [ |
|
314 |
'PBMREADER: Invalid width' errorPrintNL. |
|
28 | 315 |
^ nil |
2 | 316 |
]. |
317 |
||
46 | 318 |
self skipPBMJunkOn:aStream. |
319 |
height := Integer readFrom:aStream. |
|
320 |
height > 0 ifFalse: [ |
|
321 |
'PBMREADER: Invalid height' errorPrintNL. |
|
28 | 322 |
^ nil |
21 | 323 |
]. |
2 | 324 |
|
46 | 325 |
self skipPBMJunkOn:aStream. |
326 |
maxval := Integer readFrom:aStream. |
|
327 |
maxval >= 256 ifTrue: [ |
|
328 |
'PBMREADER: format error' errorPrintNL. |
|
28 | 329 |
^ nil |
21 | 330 |
]. |
2 | 331 |
|
46 | 332 |
aStream skipThrough: Character cr. |
333 |
aStream binary. |
|
2 | 334 |
|
46 | 335 |
data := aStream contents. |
2 | 336 |
photometric := #rgb. |
337 |
samplesPerPixel := 3. |
|
338 |
bitsPerSample := #(8 8 8). |
|
339 |
! ! |