author | ca |
Wed, 04 Jun 1997 13:12:51 +0200 | |
changeset 590 | fb2c55428c52 |
parent 523 | f26a8b493514 |
child 624 | e7e4c54dccdc |
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 |
|
200 | 14 |
instanceVariableNames:'' |
15 |
classVariableNames:'' |
|
16 |
poolDictionaries:'' |
|
259 | 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 |
! |
|
35 |
||
36 |
documentation |
|
37 |
" |
|
32 | 38 |
this class provides methods for loading and saving Portable BitMap-file |
39 |
images (Jef Poskanzers portable bitmap package). |
|
200 | 40 |
|
46 | 41 |
Reading is supported for 1bit (pbm), greyscale (pgm) and 24bit (ppm) formats. |
507 | 42 |
(i.e. P1, P3, P4, P5 and P6 formats) |
43 |
Currently, only writing of 1-bit images (pbm) is supported. |
|
46 | 44 |
|
45 |
Q: should we bring this one to perfection and base all others on |
|
46 |
pipe-readers to the various pbmplus converters ? |
|
200 | 47 |
|
48 |
[See also:] |
|
234 | 49 |
Image Form Icon |
200 | 50 |
BlitImageReader FaceReader GIFReader JPEGReader PCXReader |
210 | 51 |
ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader |
209 | 52 |
XBMReader XPMReader XWDReader |
21 | 53 |
" |
54 |
! ! |
|
2 | 55 |
|
28 | 56 |
!PBMReader class methodsFor:'initialization'! |
57 |
||
58 |
initialize |
|
200 | 59 |
"install myself in the Image classes fileFormat table |
60 |
for the `.pbm', '.pgm' and '.pnm' extensions." |
|
61 |
||
398 | 62 |
Image addReader:self suffix:'pbm'. |
63 |
Image addReader:self suffix:'pgm'. |
|
64 |
Image addReader:self suffix:'pnm'. |
|
65 |
||
66 |
"Modified: 1.2.1997 / 15:02:14 / cg" |
|
28 | 67 |
! ! |
68 |
||
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
69 |
!PBMReader class methodsFor:'testing'! |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
70 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
71 |
isValidImageFile:aFileName |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
72 |
"return true, if aFileName contains a PBM image" |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
73 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
74 |
|inStream pnmType| |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
75 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
76 |
inStream := self streamReadingFile:aFileName. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
77 |
inStream isNil ifTrue:[^ false]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
78 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
79 |
inStream text. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
80 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
81 |
inStream next ~~ $P ifTrue:[^ false]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
82 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
83 |
pnmType := inStream next. |
507 | 84 |
(#( $1 $3 $4 $5 $6 ) includes:pnmType) ifFalse:[^ false]. |
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
85 |
^ true |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
86 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
87 |
"Created: 18.6.1996 / 13:58:59 / cg" |
507 | 88 |
"Modified: 4.4.1997 / 11:17:11 / cg" |
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
89 |
! ! |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
90 |
|
2 | 91 |
!PBMReader methodsFor:'private'! |
92 |
||
46 | 93 |
skipPBMJunkOn:aStream |
200 | 94 |
"this method removes any superfluous characters from the input stream." |
2 | 95 |
|
96 |
| char foundNL| |
|
97 |
||
98 |
[ |
|
200 | 99 |
char := aStream peek. |
100 |
char == $# ifTrue:[ |
|
101 |
"Start of a comment. Skip to end-of-line." |
|
46 | 102 |
"/ foundNL := (aStream skipUpTo: Character cr) notNil. |
200 | 103 |
foundNL := (aStream skipThrough: Character cr) notNil. |
104 |
foundNL ifFalse: [ |
|
105 |
"Must be EOF" |
|
106 |
^self |
|
107 |
]. |
|
108 |
char := aStream peek]. |
|
109 |
aStream atEnd not and: [char isSeparator] |
|
2 | 110 |
] whileTrue: [aStream next] |
111 |
! |
|
112 |
||
46 | 113 |
skipXPMJunkOn:aStream |
200 | 114 |
"this method removes any superfluous characters from the input stream." |
2 | 115 |
|
116 |
| char | |
|
117 |
||
118 |
[ |
|
200 | 119 |
char := aStream peek. |
120 |
aStream atEnd not and: [char isSeparator not] |
|
2 | 121 |
] whileTrue: [aStream next]. |
122 |
||
123 |
[aStream atEnd not and: [char isSeparator]] whileTrue: [ |
|
200 | 124 |
aStream next. char := aStream peek |
2 | 125 |
]. |
126 |
aStream atEnd ifTrue: [^char]. |
|
127 |
(char isDigit) ifTrue: [ ^char ]. |
|
128 |
(char == $") ifTrue: [ |
|
200 | 129 |
aStream next. |
130 |
char := aStream peek. |
|
131 |
(char isLetterOrDigit |
|
132 |
or: [(char == $#) |
|
133 |
or: [char == Character space]]) ifFalse:[ |
|
134 |
^ self skipXPMJunkOn: aStream |
|
135 |
] ifTrue: [^char] |
|
2 | 136 |
]. |
137 |
||
138 |
^self skipXPMJunkOn: aStream. |
|
139 |
! ! |
|
140 |
||
200 | 141 |
!PBMReader methodsFor:'reading from file'! |
142 |
||
143 |
fromStream:aStream |
|
507 | 144 |
"read a Portable bitmap file format as of Jeff Poskanzers Portable Bitmap Package. |
200 | 145 |
supported are PBM, PGB and PNM files." |
146 |
||
147 |
| pnmType | |
|
148 |
||
149 |
inStream := aStream. |
|
150 |
inStream text. |
|
151 |
||
152 |
inStream next == $P ifFalse:[ |
|
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
153 |
'PBMREADER: PNM format' errorPrintNL. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
154 |
^nil |
200 | 155 |
]. |
156 |
pnmType := inStream next. |
|
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
157 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
158 |
(pnmType == $1) ifTrue: [ |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
159 |
^ self readDepth1AsciiPBMStream:aStream |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
160 |
]. |
506 | 161 |
(pnmType == $3) ifTrue: [ |
162 |
^ self readDepth24AsciiPBMStream:aStream |
|
163 |
]. |
|
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
164 |
(pnmType == $4) ifTrue: [ |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
165 |
^ self readDepth1PBMStream:aStream |
200 | 166 |
]. |
506 | 167 |
(pnmType == $5) ifTrue: [ |
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
168 |
^ self readDepth8PGMStream:aStream |
200 | 169 |
]. |
506 | 170 |
(pnmType == $6) ifTrue: [ |
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
171 |
^ self readDepth24PPMStream:aStream |
200 | 172 |
]. |
173 |
'PBMREADER: No recognized PNM file format' errorPrintNL. |
|
174 |
^ nil |
|
175 |
||
176 |
" |
|
177 |
PBMReader fromFile:'bitmaps/testimg.ppm' |
|
178 |
PBMReader fromFile:'../../fileIn/bitmaps/keyboard.pbm' |
|
506 | 179 |
PBMReader fromFile:'/home2/cg/ppm2fli_b1-92/jeff.001' |
200 | 180 |
" |
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
181 |
|
507 | 182 |
"Modified: 4.4.1997 / 11:17:24 / cg" |
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
183 |
! |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
184 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
185 |
readDepth1AsciiPBMStream:aStream |
506 | 186 |
"import portable bitmap ascii (PBM, P1 format); P1 is already read" |
303
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
187 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
188 |
|rowBuffer line n bits rowIdx dstIdx bytesPerRow char| |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
189 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
190 |
self skipPBMJunkOn:aStream. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
191 |
width := Integer readFrom:aStream. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
192 |
width > 0 ifFalse: [ |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
193 |
'PBMREADER: Invalid width' errorPrintNL. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
194 |
^ nil |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
195 |
]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
196 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
197 |
self skipPBMJunkOn:aStream. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
198 |
height := Integer readFrom:aStream. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
199 |
height > 0 ifFalse: [ |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
200 |
'PBMREADER: Invalid height' errorPrintNL. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
201 |
^ nil |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
202 |
]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
203 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
204 |
aStream nextLine "skipThrough: Character cr". |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
205 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
206 |
bytesPerRow := (width + 7) // 8. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
207 |
data := ByteArray new:bytesPerRow * height. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
208 |
rowIdx := 1. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
209 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
210 |
1 to:height do:[:row | |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
211 |
dstIdx := rowIdx. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
212 |
bits := 0. n := 0. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
213 |
1 to:width do:[:col | |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
214 |
char := aStream next. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
215 |
[char notNil and:[char isSeparator]] whileTrue:[ |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
216 |
char := aStream next |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
217 |
]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
218 |
bits := bits bitShift:1. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
219 |
char == $1 ifTrue:[ |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
220 |
bits := bits bitOr:1 |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
221 |
]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
222 |
n := n + 1. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
223 |
n == 8 ifTrue:[ |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
224 |
data at:dstIdx put:bits. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
225 |
dstIdx := dstIdx + 1. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
226 |
bits := 0. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
227 |
n := 0. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
228 |
]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
229 |
]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
230 |
n ~~ 0 ifTrue:[ |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
231 |
data at:dstIdx put:bits. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
232 |
]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
233 |
rowIdx := rowIdx + bytesPerRow |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
234 |
]. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
235 |
|
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
236 |
photometric := #whiteIs0. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
237 |
samplesPerPixel := 1. |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
238 |
bitsPerSample := #(1). |
bb6be6b01032
support P1 (ascii-depth1) format
Claus Gittinger <cg@exept.de>
parents:
259
diff
changeset
|
239 |
|
506 | 240 |
"Modified: 4.4.1997 / 11:15:51 / cg" |
200 | 241 |
! |
242 |
||
243 |
readDepth1PBMStream:aStream |
|
506 | 244 |
"import portable bitmap (PBM, P4 format); P4 is already read" |
200 | 245 |
|
523 | 246 |
|bytesPerRow| |
247 |
||
200 | 248 |
self skipPBMJunkOn:aStream. |
523 | 249 |
width := Integer readFrom:aStream onError:0. |
200 | 250 |
width > 0 ifFalse: [ |
506 | 251 |
'PBMREADER: Invalid width' errorPrintNL. |
252 |
^ nil |
|
200 | 253 |
]. |
254 |
||
255 |
self skipPBMJunkOn:aStream. |
|
523 | 256 |
height := Integer readFrom:aStream onError:0. |
200 | 257 |
height > 0 ifFalse: [ |
506 | 258 |
'PBMREADER: Invalid height' errorPrintNL. |
259 |
^ nil |
|
200 | 260 |
]. |
261 |
||
262 |
aStream nextLine "skipThrough: Character cr". |
|
523 | 263 |
|
264 |
bytesPerRow := width // 8. |
|
265 |
((width \\ 8) ~~ 0) ifTrue:[ |
|
266 |
bytesPerRow := bytesPerRow + 1 |
|
267 |
]. |
|
268 |
||
269 |
"/ the rest is the binary image data ... |
|
200 | 270 |
aStream binary. |
523 | 271 |
data := ByteArray uninitializedNew:(bytesPerRow*height). |
272 |
aStream nextBytes:(data size) into:data. |
|
200 | 273 |
|
274 |
photometric := #blackIs0. |
|
275 |
samplesPerPixel := 1. |
|
276 |
bitsPerSample := #(1). |
|
506 | 277 |
|
523 | 278 |
"Modified: 11.4.1997 / 16:48:54 / cg" |
506 | 279 |
! |
280 |
||
281 |
readDepth24AsciiPBMStream:aStream |
|
282 |
"import ascii portable pixmap (PBM, P3 format); P3 is already read" |
|
283 |
||
284 |
|maxval |
|
285 |
nBytes "{Class: SmallInteger }" |
|
286 |
v "{Class: SmallInteger }" |
|
287 |
c| |
|
288 |
||
289 |
self skipPBMJunkOn:aStream. |
|
290 |
width := Integer readFrom:aStream. |
|
291 |
width > 0 ifFalse: [ |
|
292 |
'PBMREADER: Invalid width' errorPrintNL. |
|
293 |
^ nil |
|
294 |
]. |
|
295 |
||
296 |
self skipPBMJunkOn:aStream. |
|
297 |
height := Integer readFrom:aStream. |
|
298 |
height > 0 ifFalse: [ |
|
299 |
'PBMREADER: Invalid height' errorPrintNL. |
|
300 |
^ nil |
|
301 |
]. |
|
302 |
||
303 |
self skipPBMJunkOn:aStream. |
|
304 |
maxval := Integer readFrom:aStream. |
|
305 |
maxval >= 256 ifTrue: [ |
|
306 |
'PBMREADER: format error' errorPrintNL. |
|
307 |
^ nil |
|
308 |
]. |
|
309 |
||
310 |
aStream skipThrough: Character cr. |
|
311 |
||
312 |
nBytes := width*height*3. |
|
313 |
data := ByteArray new:nBytes. |
|
314 |
1 to:nBytes do:[:i | |
|
315 |
aStream skipSeparators. |
|
316 |
v := 0. |
|
317 |
c := aStream next. |
|
318 |
[c isDigit] whileTrue:[ |
|
319 |
v := v * 10 + (c digitValue). |
|
320 |
c := aStream next. |
|
321 |
]. |
|
322 |
data at:i put:v |
|
323 |
]. |
|
324 |
||
325 |
photometric := #rgb. |
|
326 |
samplesPerPixel := 3. |
|
327 |
bitsPerSample := #(8 8 8). |
|
328 |
||
329 |
"Created: 4.4.1997 / 11:08:38 / cg" |
|
330 |
"Modified: 4.4.1997 / 11:16:07 / cg" |
|
200 | 331 |
! |
332 |
||
333 |
readDepth24PPMStream:aStream |
|
506 | 334 |
"import portable pixmap (PPM, P6 format); P6 is already read" |
200 | 335 |
|
336 |
| maxval | |
|
337 |
||
338 |
self skipPBMJunkOn:aStream. |
|
339 |
width := Integer readFrom:aStream. |
|
340 |
width > 0 ifFalse: [ |
|
506 | 341 |
'PBMREADER: Invalid width' errorPrintNL. |
342 |
^ nil |
|
200 | 343 |
]. |
344 |
||
345 |
self skipPBMJunkOn:aStream. |
|
346 |
height := Integer readFrom:aStream. |
|
347 |
height > 0 ifFalse: [ |
|
506 | 348 |
'PBMREADER: Invalid height' errorPrintNL. |
349 |
^ nil |
|
200 | 350 |
]. |
351 |
||
352 |
self skipPBMJunkOn:aStream. |
|
353 |
maxval := Integer readFrom:aStream. |
|
354 |
maxval >= 256 ifTrue: [ |
|
506 | 355 |
'PBMREADER: format error' errorPrintNL. |
356 |
^ nil |
|
200 | 357 |
]. |
358 |
||
359 |
aStream skipThrough: Character cr. |
|
360 |
||
523 | 361 |
"/ the rest is the binary image data ... |
362 |
aStream binary. |
|
363 |
data := ByteArray uninitializedNew:(width*height*3). |
|
364 |
aStream nextBytes:(data size) into:data. |
|
365 |
||
200 | 366 |
photometric := #rgb. |
367 |
samplesPerPixel := 3. |
|
368 |
bitsPerSample := #(8 8 8). |
|
506 | 369 |
|
523 | 370 |
"Modified: 11.4.1997 / 16:36:51 / cg" |
200 | 371 |
! |
372 |
||
373 |
readDepth8PGMStream:aStream |
|
506 | 374 |
"import portable gray map (PGM, P5 format); P5 is already read" |
200 | 375 |
|
376 |
|maxval| |
|
377 |
||
378 |
self skipPBMJunkOn:aStream. |
|
379 |
width := Integer readFrom:aStream. |
|
380 |
width > 0 ifFalse:[ |
|
506 | 381 |
'PBMREADER: Invalid width' errorPrintNL. |
382 |
^ nil |
|
200 | 383 |
]. |
384 |
self skipPBMJunkOn:aStream. |
|
385 |
height := Integer readFrom:aStream. |
|
386 |
height > 0 ifFalse:[ |
|
506 | 387 |
'PBMREADER: Invalid height' errorPrintNL. |
388 |
^ nil |
|
200 | 389 |
]. |
390 |
self skipPBMJunkOn:aStream. |
|
391 |
maxval := Integer readFrom:aStream. |
|
392 |
maxval >= 256 ifTrue:[ |
|
506 | 393 |
'PBMREADER: Invalid format' errorPrintNL. |
394 |
^ nil |
|
200 | 395 |
]. |
396 |
aStream skipThrough: Character cr. |
|
523 | 397 |
|
398 |
"/ the rest is the binary image data ... |
|
200 | 399 |
aStream binary. |
523 | 400 |
data := ByteArray uninitializedNew:(width*height). |
401 |
aStream nextBytes:(data size) into:data. |
|
200 | 402 |
|
403 |
photometric := #blackIs0. |
|
404 |
samplesPerPixel := 1. |
|
405 |
bitsPerSample := #(8). |
|
506 | 406 |
|
523 | 407 |
"Modified: 11.4.1997 / 16:47:13 / cg" |
200 | 408 |
! ! |
409 |
||
51 | 410 |
!PBMReader methodsFor:'testing '! |
411 |
||
412 |
canRepresent:anImage |
|
413 |
"return true, if anImage can be represented in my file format. |
|
414 |
Currently only B&W and Depth8 images are supported." |
|
415 |
||
416 |
|depth| |
|
417 |
||
418 |
anImage photometric == #rgb ifTrue:[ |
|
419 |
^ false "/ not yet implemented |
|
420 |
]. |
|
421 |
(depth := anImage depth) == 1 ifTrue:[^ true]. |
|
422 |
depth == 8 ifTrue:[^ true]. |
|
423 |
^ false |
|
424 |
! ! |
|
425 |
||
2 | 426 |
!PBMReader methodsFor:'writing to file'! |
427 |
||
428 |
save:image onFile:aFileName |
|
429 |
"save image as PBM/PGM/PNM file on aFileName" |
|
430 |
||
431 |
outStream := FileStream newFileNamed:aFileName. |
|
432 |
outStream isNil ifTrue:[ |
|
461
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
433 |
'PBMReader [error]: file create error' errorPrintNL. |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
434 |
^ Image fileCreationErrorSignal |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
435 |
raiseWith:image |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
436 |
errorString:('file creation error: ' , aFileName asString). |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
437 |
]. |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
438 |
|
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
439 |
image mask notNil ifTrue:[ |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
440 |
Image informationLostQuerySignal |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
441 |
raiseWith:image |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
442 |
errorString:('PBM format does not support an imageMask'). |
2 | 443 |
]. |
444 |
||
445 |
width := image width. |
|
446 |
height := image height. |
|
447 |
photometric := image photometric. |
|
448 |
samplesPerPixel := image samplesPerPixel. |
|
449 |
bitsPerSample := image bitsPerSample. |
|
450 |
colorMap := image colorMap. |
|
46 | 451 |
data := image bits. |
2 | 452 |
|
453 |
photometric == #rgb ifTrue:[ |
|
461
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
454 |
^ self writePNMFileOn:outStream |
2 | 455 |
]. |
456 |
samplesPerPixel == 1 ifTrue:[ |
|
461
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
457 |
((bitsPerSample at:1) == 1) ifTrue:[ |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
458 |
^ self writePBMFileOn:outStream |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
459 |
]. |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
460 |
((bitsPerSample at:1) == 8) ifTrue:[ |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
461 |
^ self writePGMFileOn:outStream |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
462 |
]. |
2 | 463 |
]. |
461
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
464 |
^ Image cannotRepresentImageSignal |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
465 |
raiseWith:image |
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
466 |
errorString:('PBMReader cannot represent this image'). |
46 | 467 |
|
468 |
" |
|
469 |
|img| |
|
470 |
||
471 |
img := Image fromFile:'bitmaps/SBrowser.xbm'. |
|
472 |
img inspect. |
|
473 |
PBMReader save:img onFile:'test.pbm'. |
|
474 |
img := Image fromFile:'test.pbm'. |
|
475 |
img inspect. |
|
476 |
||
477 |
||
478 |
|img mono| |
|
479 |
||
480 |
img := Image fromFile:'bitmaps/garfield.gif'. |
|
481 |
img inspect. |
|
482 |
mono := img asMonochromeFormOn:Display. |
|
483 |
img := mono asImage. |
|
484 |
img inspect. |
|
485 |
PBMReader save:img onFile:'test.pbm'. |
|
486 |
img := Image fromFile:'test.pbm'. |
|
487 |
img inspect. |
|
488 |
" |
|
461
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
489 |
|
bacef118f54a
more signals to be raised if anything happens during
Claus Gittinger <cg@exept.de>
parents:
398
diff
changeset
|
490 |
"Modified: 27.2.1997 / 12:45:42 / cg" |
21 | 491 |
! |
492 |
||
46 | 493 |
writePBMFileOn:aStream |
494 |
"Saves the receivers image on the file fileName in Portable Bitmap format. |
|
495 |
See the class method pbmSyntax for details of the format." |
|
496 |
||
497 |
aStream nextPutAll:'P4'; cr. |
|
498 |
aStream nextPutAll:'# Converted from Smalltalk Form on '. |
|
499 |
aStream nextPutAll:Date today printString. |
|
500 |
aStream nextPutAll:' at ', Time now printString. |
|
501 |
aStream cr. |
|
502 |
aStream nextPutAll:width printString. |
|
503 |
aStream space. |
|
504 |
aStream nextPutAll:height printString. |
|
505 |
aStream cr. |
|
506 |
||
507 |
aStream binary. |
|
508 |
photometric == #blackIs0 ifTrue:[ |
|
509 |
aStream nextPutAll:data. |
|
510 |
] ifFalse:[ |
|
511 |
data invert. |
|
512 |
aStream nextPutAll:data. |
|
513 |
data invert. |
|
514 |
]. |
|
515 |
aStream close. |
|
21 | 516 |
! |
517 |
||
46 | 518 |
writePGMFileOn:outStream |
200 | 519 |
"raise an error - this is not yet implemented" |
520 |
||
521 |
self error:'not yet implemented' |
|
522 |
! |
|
523 |
||
524 |
writePNMFileOn:outStream |
|
525 |
"raise an error - this is not yet implemented" |
|
526 |
||
21 | 527 |
self error:'not yet implemented' |
2 | 528 |
! ! |
529 |
||
200 | 530 |
!PBMReader class methodsFor:'documentation'! |
2 | 531 |
|
200 | 532 |
version |
523 | 533 |
^ '$Header: /cvs/stx/stx/libview2/PBMReader.st,v 1.25 1997-04-11 14:49:54 cg Exp $' |
2 | 534 |
! ! |
200 | 535 |
PBMReader initialize! |