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