90 nColors := header at: 20. |
90 nColors := header at: 20. |
91 |
91 |
92 colorMap := Array new:colormapSize. |
92 colorMap := Array new:colormapSize. |
93 |
93 |
94 1 to:nColors do:[:i | |
94 1 to:nColors do:[:i | |
95 |clr| |
95 |clr r g b| |
96 |
96 |
97 aStream nextLong. |
97 aStream nextLong. |
98 clr := ColorValue scaledRed: ((aStream nextUnsignedShortMSB:true) bitShift: -3) |
98 r := aStream nextUnsignedShortMSB:true. |
99 scaledGreen: ((aStream nextUnsignedShortMSB:true) bitShift: -3) |
99 g := aStream nextUnsignedShortMSB:true. |
100 scaledBlue: ((aStream nextUnsignedShortMSB:true) bitShift: -3). |
100 b := aStream nextUnsignedShortMSB:true. |
|
101 clr := ColorValue scaledRed: (r bitShift: -3) |
|
102 scaledGreen: (g bitShift: -3) |
|
103 scaledBlue: (b bitShift: -3). |
101 colorMap at:i put:clr. |
104 colorMap at:i put:clr. |
102 aStream nextWord. |
105 aStream nextWord. |
103 ]. |
106 ]. |
104 |
107 |
105 nColors+1 to:colormapSize do: [:i | colorMap at:i put:Color black]. |
108 nColors+1 to:colormapSize do: [:i | colorMap at:i put:Color black]. |
122 ]. |
125 ]. |
123 ] |
126 ] |
124 " |
127 " |
125 XWDReader fromFile:'testfile.xwd' |
128 XWDReader fromFile:'testfile.xwd' |
126 " |
129 " |
|
130 " |
|
131 XWDReader save:(Image fromUser) onFile: '/tmp/st.xwd' |
|
132 (Image fromFile: '/tmp/st.xwd') inspect |
|
133 " |
127 ! ! |
134 ! ! |
128 |
135 |
|
136 !XWDReader methodsFor:'image writing'! |
|
137 |
|
138 save:image onFile:fileName |
|
139 "Save as a version 7 color X11 window dump file (xwd) to the file fileName. |
|
140 This produces a mapped color table with 16 bit color. The xwd file can be |
|
141 viewed by the xwud program and printed with xpr. There is no compression |
|
142 encoding performed on the scanlines. |
|
143 |
|
144 See the file ...include/X11/XWDFile.h for a definition of the format. |
|
145 |
|
146 Notice: |
|
147 this method was adapted from a goody in the uiuc archive |
|
148 (Prime time freeware). |
|
149 The original files header is: |
|
150 NAME imageToXWD |
|
151 AUTHOR Brad Schoening <brad@boole.com> |
|
152 FUNCTION Writes a Smalltalk image to an X11 xwd file |
|
153 ST-VERSION PPST 4.0 or 4.1 |
|
154 DISTRIBUTION world |
|
155 VERSION 1.0 |
|
156 DATE July 1993 |
|
157 " |
|
158 |
|
159 | aStream rgbColor paletteColors ncolors cindex dumpName headerSize | |
|
160 |
|
161 image bitsPerPixel ~~ 8 ifTrue:[ |
|
162 self error:'XWD format only supports 8bit images'. |
|
163 ^ nil |
|
164 ]. |
|
165 image photometric ~~ #palette ifTrue:[ |
|
166 self error:'XWD format only supports palette images'. |
|
167 ^ nil |
|
168 ]. |
|
169 |
|
170 dumpName := 'stdin'. |
|
171 headerSize := 4 * (25 + (dumpName size / 4) ceiling). |
|
172 paletteColors := image palette "colors". |
|
173 ncolors := paletteColors size. |
|
174 |
|
175 "create the header (each item is 32 bits long)" |
|
176 aStream := fileName asFilename writeStream. |
|
177 aStream binary. |
|
178 aStream nextLongPut: headerSize. "total header size in bytes" |
|
179 aStream nextLongPut: 7. "XWD file version" |
|
180 aStream nextLongPut: 2. "pixmap format : ZPixmap" |
|
181 aStream nextLongPut: 8. "pixmap depth" |
|
182 aStream nextLongPut: image width. "pixmap cols" |
|
183 aStream nextLongPut: image height. "pixmap rows" |
|
184 aStream nextLongPut: 0. "bitmap x offset" |
|
185 aStream nextLongPut: 1. "byte order: MSBFirst" |
|
186 aStream nextLongPut: 8. "bitmap unit" |
|
187 aStream nextLongPut: 1. "bitmap bit order: MSBFirst" |
|
188 aStream nextLongPut: 8. "bitmap scanline pad" |
|
189 aStream nextLongPut: 8. "bits per pixel" |
|
190 aStream nextLongPut: image width. "bytes per scanline" |
|
191 aStream nextLongPut: 3. "colormap class : PseudoColor" |
|
192 aStream nextLongPut: 0. "Z red mask" |
|
193 aStream nextLongPut: 0. "Z green mask" |
|
194 aStream nextLongPut: 0. "Z blue mask" |
|
195 aStream nextLongPut: 8. "bits per rgb" |
|
196 aStream nextLongPut: 256. "number of color map entries" |
|
197 aStream nextLongPut: ncolors. "number of color structures" |
|
198 aStream nextLongPut: image width. "window width" |
|
199 aStream nextLongPut: image height. "window height" |
|
200 aStream nextLongPut: 0. "window upper left x coordinate" |
|
201 aStream nextLongPut: 0. "window upper left y coordinate" |
|
202 aStream nextLongPut: 0. "window border width" |
|
203 aStream nextPutAll: dumpName asByteArray. "name of dump" |
|
204 "Pad the string to the next 32-bit boundary" |
|
205 aStream nextPut: 0. "/ 6 |
|
206 aStream nextPut: 0. "/ 7 |
|
207 aStream nextPut: 0. "/ 8 |
|
208 |
|
209 "/ [(aStream position rem: 4) == 0] whileFalse: [ aStream nextPut: 0 ]. |
|
210 |
|
211 "Write out the color table. Each color table entry is 12 bytes long composed of: |
|
212 an index (4 bytes) |
|
213 red color value (2 bytes) |
|
214 green color value (2 bytes) |
|
215 blue color value (2 bytes) |
|
216 flag values (1 byte) |
|
217 pad (1 byte) |
|
218 " |
|
219 0 to: ncolors-1 do: [ :index | |
|
220 |r g b| |
|
221 |
|
222 aStream nextLongPut: index. |
|
223 rgbColor := paletteColors at: (1+index). |
|
224 (rgbColor isNil) ifTrue: [ rgbColor := ColorValue white ]. |
|
225 r := (rgbColor red / 100.0 * 65535) rounded. |
|
226 g := (rgbColor green / 100.0 * 65535) rounded. |
|
227 b := (rgbColor blue / 100.0 * 65535) rounded. |
|
228 |
|
229 aStream nextWordPut:r. |
|
230 aStream nextWordPut:g. |
|
231 aStream nextWordPut:b. |
|
232 aStream nextPut: 7. "flags" |
|
233 aStream nextPut: 0. "pad" |
|
234 ]. |
|
235 |
|
236 "Write out the pixels as index color values" |
|
237 "/ Cursor write showWhile: [ |
|
238 "/ 1 to: (image height) do: [ :row | |
|
239 "/ 1 to: (image width) do: [ :col | |
|
240 "/ cindex := image atPoint: (col-1)@(row-1). |
|
241 "/ aStream nextPut: cindex.]] |
|
242 "/ ]. |
|
243 aStream nextPutAll:image bits. |
|
244 |
|
245 aStream close |
|
246 |
|
247 " |
|
248 XWDReader save:(Image fromUser) onFile: '/tmp/st.xwd' |
|
249 (Image fromFile: '/tmp/st.xwd') inspect |
|
250 " |
|
251 ! ! |
|
252 |