81 " |
84 " |
82 ! ! |
85 ! ! |
83 |
86 |
84 !PICTReader class methodsFor:'initialization'! |
87 !PICTReader class methodsFor:'initialization'! |
85 |
88 |
|
89 defineOpcodes00 |
|
90 Opcodes at: 16r0000 put: ('NOP' -> 0). |
|
91 Opcodes at: 16r0001 put: ('Clip' -> 'Region size'). |
|
92 Opcodes at: 16r0002 put: ('BkPat' -> 8). |
|
93 Opcodes at: 16r0003 put: ('TxFont' -> 2). |
|
94 Opcodes at: 16r0004 put: ('TxFace' -> 1). |
|
95 Opcodes at: 16r0005 put: ('TxMode' -> 2). |
|
96 Opcodes at: 16r0006 put: ('SpExtra' -> 4). |
|
97 Opcodes at: 16r0007 put: ('PnSize' -> 4). |
|
98 Opcodes at: 16r0008 put: ('PnMode' -> 2). |
|
99 Opcodes at: 16r0009 put: ('PnPat' -> 8). |
|
100 Opcodes at: 16r000A put: ('FillPat' -> 8). |
|
101 Opcodes at: 16r000B put: ('OvSize' -> 4). |
|
102 Opcodes at: 16r000C put: ('Origin' -> 4). |
|
103 Opcodes at: 16r000D put: ('TxSize' -> 2). |
|
104 Opcodes at: 16r000E put: ('FgColor' -> 4). |
|
105 Opcodes at: 16r000F put: ('BkColor' -> 4). |
|
106 ! |
|
107 |
|
108 defineOpcodes01 |
|
109 Opcodes at: 16r0010 put: ('TxRatio' -> 8). |
|
110 Opcodes at: 16r0011 put: ('VersionOp' -> 1). |
|
111 Opcodes at: 16r0012 put: ('BkPixPat' -> 'Variable'). |
|
112 Opcodes at: 16r0013 put: ('PnPixPat' -> 'Variable'). |
|
113 Opcodes at: 16r0014 put: ('FillPixPat' -> 'Variable'). |
|
114 Opcodes at: 16r0015 put: ('PnLocHFrac' -> 2). |
|
115 Opcodes at: 16r0016 put: ('ChExtra' -> 2). |
|
116 Opcodes at: 16r0017 put: ('Apple0017' -> 'Not determined'). |
|
117 Opcodes at: 16r0018 put: ('Apple0018' -> 'Not determined'). |
|
118 Opcodes at: 16r0019 put: ('Apple0019' -> 'Not determined'). |
|
119 Opcodes at: 16r001A put: ('RGBFgCol' -> 6). |
|
120 Opcodes at: 16r001B put: ('RGBBkCol' -> 6). |
|
121 Opcodes at: 16r001C put: ('HiliteMode' -> 0). |
|
122 Opcodes at: 16r001D put: ('HiliteColor' -> 6). |
|
123 Opcodes at: 16r001E put: ('DefHilite' -> 0). |
|
124 Opcodes at: 16r001F put: ('OpColor' -> 6). |
|
125 ! |
|
126 |
|
127 defineOpcodes02 |
|
128 Opcodes at: 16r0020 put: ('Line' -> 8). |
|
129 Opcodes at: 16r0021 put: ('LineFrom' -> 4). |
|
130 Opcodes at: 16r0022 put: ('ShortLine' -> 6). |
|
131 Opcodes at: 16r0023 put: ('ShortLineFrom' -> 2). |
|
132 Opcodes at: 16r0024 put: ('Apple0024' -> '2 + data length'). |
|
133 Opcodes at: 16r0025 put: ('Apple0025' -> '2 + data length'). |
|
134 Opcodes at: 16r0026 put: ('Apple0026' -> '2 + data length'). |
|
135 Opcodes at: 16r0027 put: ('Apple0027' -> '2 + data length'). |
|
136 Opcodes at: 16r0028 put: ('LongText' -> '5 + text'). |
|
137 Opcodes at: 16r0029 put: ('DHText' -> '2 + text'). |
|
138 Opcodes at: 16r002A put: ('DVText' -> '2 + text'). |
|
139 Opcodes at: 16r002B put: ('DHDVText' -> '3 + text'). |
|
140 Opcodes at: 16r002C put: ('fontName' -> '5 + name length'). |
|
141 Opcodes at: 16r002D put: ('lineJustify' -> 10). |
|
142 Opcodes at: 16r002E put: ('glyphState' -> 8). |
|
143 Opcodes at: 16r002F put: ('Apple002F' -> '2 + data length'). |
|
144 ! |
|
145 |
|
146 defineOpcodes03 |
|
147 Opcodes at: 16r0030 put: ('frameRect' -> 8). |
|
148 Opcodes at: 16r0031 put: ('paintRect' -> 8). |
|
149 Opcodes at: 16r0032 put: ('eraseRect' -> 8). |
|
150 Opcodes at: 16r0033 put: ('invertRect' -> 8). |
|
151 Opcodes at: 16r0034 put: ('fillRect' -> 8). |
|
152 Opcodes at: 16r0035 put: ('Apple0035' -> 8). |
|
153 Opcodes at: 16r0036 put: ('Apple0036' -> 8). |
|
154 Opcodes at: 16r0037 put: ('Apple0037' -> 8). |
|
155 Opcodes at: 16r0038 put: ('frameSameRect' -> 0). |
|
156 Opcodes at: 16r0039 put: ('paintSameRect' -> 0). |
|
157 Opcodes at: 16r003A put: ('eraseSameRect' -> 0). |
|
158 Opcodes at: 16r003B put: ('invertSameRect' -> 0). |
|
159 Opcodes at: 16r003C put: ('fillSameRect' -> 0). |
|
160 Opcodes at: 16r003D put: ('Apple003D' -> 0). |
|
161 Opcodes at: 16r003E put: ('Apple003E' -> 0). |
|
162 Opcodes at: 16r003F put: ('Apple003F' -> 0). |
|
163 ! |
|
164 |
|
165 defineOpcodes04 |
|
166 Opcodes at: 16r0040 put: ('frameRRect' -> 8). |
|
167 Opcodes at: 16r0041 put: ('paintRRect' -> 8). |
|
168 Opcodes at: 16r0042 put: ('eraseRRect' -> 8). |
|
169 Opcodes at: 16r0043 put: ('invertRRect' -> 8). |
|
170 Opcodes at: 16r0044 put: ('fillRect' -> 8). |
|
171 Opcodes at: 16r0045 put: ('Apple0045' -> 8). |
|
172 Opcodes at: 16r0046 put: ('Apple0046' -> 8). |
|
173 Opcodes at: 16r0047 put: ('Apple0047' -> 8). |
|
174 Opcodes at: 16r0048 put: ('frameSameRRect' -> 0). |
|
175 Opcodes at: 16r0049 put: ('paintSameRRect' -> 0). |
|
176 Opcodes at: 16r004A put: ('eraseSameRRect' -> 0). |
|
177 Opcodes at: 16r004B put: ('invertSameRRect' -> 0). |
|
178 Opcodes at: 16r004C put: ('fillSameRRect' -> 0). |
|
179 Opcodes at: 16r004D put: ('Apple004D' -> 0). |
|
180 Opcodes at: 16r004E put: ('Apple004E' -> 0). |
|
181 Opcodes at: 16r004F put: ('Apple004F' -> 0). |
|
182 ! |
|
183 |
|
184 defineOpcodes05 |
|
185 Opcodes at: 16r0050 put: ('frameOval' -> 8). |
|
186 Opcodes at: 16r0051 put: ('paintOval' -> 8). |
|
187 Opcodes at: 16r0052 put: ('eraseOval' -> 8). |
|
188 Opcodes at: 16r0053 put: ('invertOval' -> 8). |
|
189 Opcodes at: 16r0054 put: ('fillRect' -> 8). |
|
190 Opcodes at: 16r0055 put: ('Apple0055' -> 8). |
|
191 Opcodes at: 16r0056 put: ('Apple0056' -> 8). |
|
192 Opcodes at: 16r0057 put: ('Apple0057' -> 8). |
|
193 Opcodes at: 16r0058 put: ('frameSameOval' -> 0). |
|
194 Opcodes at: 16r0059 put: ('paintSameOval' -> 0). |
|
195 Opcodes at: 16r005A put: ('eraseSameOval' -> 0). |
|
196 Opcodes at: 16r005B put: ('invertSameOval' -> 0). |
|
197 Opcodes at: 16r005C put: ('fillSameOval' -> 0). |
|
198 Opcodes at: 16r005D put: ('Apple005D' -> 0). |
|
199 Opcodes at: 16r005E put: ('Apple005E' -> 0). |
|
200 Opcodes at: 16r005F put: ('Apple005F' -> 0). |
|
201 ! |
|
202 |
|
203 defineOpcodes06 |
|
204 Opcodes at: 16r0060 put: ('frameArc' -> 12). |
|
205 Opcodes at: 16r0061 put: ('paintArc' -> 12). |
|
206 Opcodes at: 16r0062 put: ('eraseArc' -> 12). |
|
207 Opcodes at: 16r0063 put: ('invertArc' -> 12). |
|
208 Opcodes at: 16r0064 put: ('fillRect' -> 12). |
|
209 Opcodes at: 16r0065 put: ('Apple0065' -> 12). |
|
210 Opcodes at: 16r0066 put: ('Apple0066' -> 12). |
|
211 Opcodes at: 16r0067 put: ('Apple0067' -> 12). |
|
212 Opcodes at: 16r0068 put: ('frameSameArc' -> 4). |
|
213 Opcodes at: 16r0069 put: ('paintSameArc' -> 4). |
|
214 Opcodes at: 16r006A put: ('eraseSameArc' -> 4). |
|
215 Opcodes at: 16r006B put: ('invertSameArc' -> 4). |
|
216 Opcodes at: 16r006C put: ('fillSameArc' -> 4). |
|
217 Opcodes at: 16r006D put: ('Apple006D' -> 4). |
|
218 Opcodes at: 16r006E put: ('Apple006E' -> 4). |
|
219 Opcodes at: 16r006F put: ('Apple006F' -> 4). |
|
220 ! |
|
221 |
|
222 defineOpcodes07 |
|
223 Opcodes at: 16r0070 put: ('framePoly' -> 'Polygon size'). |
|
224 Opcodes at: 16r0071 put: ('paintPoly' -> 'Polygon size'). |
|
225 Opcodes at: 16r0072 put: ('erasePoly' -> 'Polygon size'). |
|
226 Opcodes at: 16r0073 put: ('invertPoly' -> 'Polygon size'). |
|
227 Opcodes at: 16r0074 put: ('fillRect' -> 'Polygon size'). |
|
228 Opcodes at: 16r0075 put: ('Apple0075' -> 'Polygon size'). |
|
229 Opcodes at: 16r0076 put: ('Apple0076' -> 'Polygon size'). |
|
230 Opcodes at: 16r0077 put: ('Apple0077' -> 'Polygon size'). |
|
231 Opcodes at: 16r0078 put: ('frameSamePoly' -> 0). |
|
232 Opcodes at: 16r0079 put: ('paintSamePoly' -> 0). |
|
233 Opcodes at: 16r007A put: ('eraseSamePoly' -> 0). |
|
234 Opcodes at: 16r007B put: ('invertSamePoly' -> 0). |
|
235 Opcodes at: 16r007C put: ('fillSamePoly' -> 0). |
|
236 Opcodes at: 16r007D put: ('Apple007D' -> 0). |
|
237 Opcodes at: 16r007E put: ('Apple007E' -> 0). |
|
238 Opcodes at: 16r007F put: ('Apple007F' -> 0). |
|
239 ! |
|
240 |
|
241 defineOpcodes08 |
|
242 Opcodes at: 16r0080 put: ('frameRgn' -> 'Region size'). |
|
243 Opcodes at: 16r0081 put: ('paintRgn' -> 'Region size'). |
|
244 Opcodes at: 16r0082 put: ('eraseRgn' -> 'Region size'). |
|
245 Opcodes at: 16r0083 put: ('invertRgn' -> 'Region size'). |
|
246 Opcodes at: 16r0084 put: ('fillRect' -> 'Region size'). |
|
247 Opcodes at: 16r0085 put: ('Apple0085' -> 'Region size'). |
|
248 Opcodes at: 16r0086 put: ('Apple0086' -> 'Region size'). |
|
249 Opcodes at: 16r0087 put: ('Apple0087' -> 'Region size'). |
|
250 Opcodes at: 16r0088 put: ('frameSameRgn' -> 0). |
|
251 Opcodes at: 16r0089 put: ('paintSameRgn' -> 0). |
|
252 Opcodes at: 16r008A put: ('eraseSameRgn' -> 0). |
|
253 Opcodes at: 16r008B put: ('invertSameRgn' -> 0). |
|
254 Opcodes at: 16r008C put: ('fillSameRgn' -> 0). |
|
255 Opcodes at: 16r008D put: ('Apple008D' -> 0). |
|
256 Opcodes at: 16r008E put: ('Apple008E' -> 0). |
|
257 Opcodes at: 16r008F put: ('Apple008F' -> 0). |
|
258 ! |
|
259 |
|
260 defineOpcodes09 |
|
261 Opcodes at: 16r0090 put: ('BitsRect' -> 'Variable'). |
|
262 Opcodes at: 16r0091 put: ('BitsRgn' -> 'Variable'). |
|
263 Opcodes at: 16r0092 put: ('Apple0092' -> '2 + data length'). |
|
264 Opcodes at: 16r0093 put: ('Apple0093' -> '2 + data length'). |
|
265 Opcodes at: 16r0094 put: ('Apple0094' -> '2 + data length'). |
|
266 Opcodes at: 16r0095 put: ('Apple0095' -> '2 + data length'). |
|
267 Opcodes at: 16r0096 put: ('Apple0096' -> '2 + data length'). |
|
268 Opcodes at: 16r0097 put: ('Apple0097' -> '2 + data length'). |
|
269 Opcodes at: 16r0098 put: ('PackBitsRect' -> 'Variable'). |
|
270 Opcodes at: 16r0099 put: ('PackBitsRgn' -> 'Variable'). |
|
271 Opcodes at: 16r009A put: ('DirectBitsRect' -> 'Variable'). |
|
272 Opcodes at: 16r009B put: ('DirectBitsRegn' -> 'Variable'). |
|
273 Opcodes at: 16r009C put: ('Apple009C' -> '2 + data length'). |
|
274 Opcodes at: 16r009D put: ('Apple009D' -> '2 + data length'). |
|
275 Opcodes at: 16r009E put: ('Apple009E' -> '2 + data length'). |
|
276 Opcodes at: 16r009F put: ('Apple009F' -> '2 + data length'). |
|
277 ! |
|
278 |
|
279 defineOpcodes10 |
|
280 Opcodes at: 16r00A0 put: ('ShortComment' -> 2). |
|
281 Opcodes at: 16r00A1 put: ('LongComment' -> '4 + data'). |
|
282 Opcodes at: 16r00A2 put: ('Apple00A2' -> '2 + data length'). |
|
283 Opcodes at: 16r00A3 put: ('Apple00A3' -> '2 + data length'). |
|
284 Opcodes at: 16r00A4 put: ('Apple00A4' -> '2 + data length'). |
|
285 Opcodes at: 16r00A5 put: ('Apple00A5' -> '2 + data length'). |
|
286 Opcodes at: 16r00A6 put: ('Apple00A6' -> '2 + data length'). |
|
287 Opcodes at: 16r00A7 put: ('Apple00A7' -> '2 + data length'). |
|
288 Opcodes at: 16r00A8 put: ('Apple00A8' -> '2 + data length'). |
|
289 Opcodes at: 16r00A9 put: ('Apple00A9' -> '2 + data length'). |
|
290 Opcodes at: 16r00AA put: ('Apple00AA' -> '2 + data length'). |
|
291 Opcodes at: 16r00AB put: ('Apple00AB' -> '2 + data length'). |
|
292 Opcodes at: 16r00AC put: ('Apple00AC' -> '2 + data length'). |
|
293 Opcodes at: 16r00AD put: ('Apple00AD' -> '2 + data length'). |
|
294 Opcodes at: 16r00AE put: ('Apple00AE' -> '2 + data length'). |
|
295 Opcodes at: 16r00AF put: ('Apple00AF' -> '2 + data length'). |
|
296 ! |
|
297 |
|
298 defineOpcodes99 |
|
299 Opcodes at: 16r00FF put: ('OpEndPic' -> 0). |
|
300 Opcodes at: 16r02FF put: ('Version' -> 2). |
|
301 Opcodes at: 16r0C00 put: ('HeaderOp' -> 24). |
|
302 Opcodes at: 16r8200 put: ('CompressedQuickTime' -> '4 + data length'). |
|
303 Opcodes at: 16r8201 put: ('UncompressedQuickTime' -> '4 + data length'). |
|
304 ! |
|
305 |
86 initialize |
306 initialize |
87 "install myself in the Image classes fileFormat table |
307 "install myself in the Image classes fileFormat table |
88 for the `.icon' and '.im8' extensions." |
308 for the `.pic' and '.pict' extensions." |
89 |
309 |
90 MIMETypes defineImageType:nil suffix:'icon' reader:self. |
310 MIMETypes defineImageType:nil suffix:'pict' reader:self. |
91 MIMETypes defineImageType:nil suffix:'im8' reader:self. |
311 MIMETypes defineImageType:nil suffix:'pic' reader:self. |
92 |
312 |
93 "Modified: 1.2.1997 / 15:08:40 / cg" |
313 "PictReader initialize." |
|
314 ! |
|
315 |
|
316 initializeOpcodes |
|
317 "PictImageStream initializeOpcodes." |
|
318 |
|
319 Opcodes := IdentityDictionary new: 100. |
|
320 self defineOpcodes00. |
|
321 self defineOpcodes01. |
|
322 self defineOpcodes02. |
|
323 self defineOpcodes03. |
|
324 self defineOpcodes04. |
|
325 self defineOpcodes05. |
|
326 self defineOpcodes06. |
|
327 self defineOpcodes07. |
|
328 self defineOpcodes08. |
|
329 self defineOpcodes09. |
|
330 self defineOpcodes10. |
|
331 self defineOpcodes99. |
|
332 ^Opcodes |
94 ! ! |
333 ! ! |
95 |
334 |
96 !PICTReader class methodsFor:'testing'! |
335 !PICTReader class methodsFor:'testing'! |
97 |
336 |
98 isValidImageFile:aFileName |
337 isValidImageFile:aFileName |
146 |
385 |
147 inStream close. |
386 inStream close. |
148 ^ true |
387 ^ true |
149 ! ! |
388 ! ! |
150 |
389 |
151 !PICTReader methodsFor:'reading from file'! |
390 !PICTReader methodsFor:'commands'! |
|
391 |
|
392 xBitsRect |
|
393 ^self xPackBitsRect |
|
394 ! |
|
395 |
|
396 xBitsRgn |
|
397 ^self xPackBitsRgn |
|
398 ! |
|
399 |
|
400 xDHDVText |
|
401 | dh dv count string | |
|
402 dh := self next. |
|
403 dv := self next. |
|
404 count := self next. |
|
405 string := (self next: count) asString. |
|
406 self |
|
407 debug: |
|
408 [Transcript space; show: dh printString. |
|
409 Transcript space; show: dv printString. |
|
410 Transcript space; show: count printString. |
|
411 Transcript space; show: string printString]. |
|
412 ^Array |
|
413 with: dh |
|
414 with: dv |
|
415 with: count |
|
416 with: string |
|
417 ! |
|
418 |
|
419 xDHText |
|
420 | dh count string | |
|
421 dh := self next. |
|
422 count := self next. |
|
423 string := (self next: count) asString. |
|
424 self |
|
425 debug: |
|
426 [Transcript space; show: dh printString. |
|
427 Transcript space; show: count printString. |
|
428 Transcript space; show: string printString]. |
|
429 ^Array |
|
430 with: dh |
|
431 with: count |
|
432 with: string |
|
433 ! |
|
434 |
|
435 xDVText |
|
436 | dv count string | |
|
437 dv := self next. |
|
438 count := self next. |
|
439 string := (self next: count) asString. |
|
440 self |
|
441 debug: |
|
442 [Transcript space; show: dv printString. |
|
443 Transcript space; show: count printString. |
|
444 Transcript space; show: string printString]. |
|
445 ^Array |
|
446 with: dv |
|
447 with: count |
|
448 with: string |
|
449 ! |
|
450 |
|
451 xDirectBitsRect |
|
452 | record | |
|
453 record := self readDirectPixMap: false. |
|
454 self debug: [Transcript space; show: record printString]. |
|
455 imageSequence add: record. |
|
456 ^record |
|
457 ! |
|
458 |
|
459 xDirectBitsRgn |
|
460 ^self readDirectPixMap: true |
|
461 ! |
|
462 |
|
463 xFontName |
|
464 | dataLength fontId nameLength fontName | |
|
465 dataLength := self nextWord. |
|
466 fontId := self nextWord. |
|
467 nameLength := self next. |
|
468 fontName := (self next: nameLength) asString. |
|
469 self |
|
470 debug: |
|
471 [Transcript space; show: dataLength printString. |
|
472 Transcript space; show: fontId printString. |
|
473 Transcript space; show: nameLength printString. |
|
474 Transcript space; show: fontName printString]. |
|
475 ^Array |
|
476 with: dataLength |
|
477 with: fontId |
|
478 with: nameLength |
|
479 with: fontName |
|
480 ! |
|
481 |
|
482 xLongComment |
|
483 | kind size bytes aStream char | |
|
484 kind := self nextWord. |
|
485 size := self nextWord. |
|
486 bytes := self next: size. |
|
487 aStream := WriteStream on: (String new: bytes size). |
|
488 bytes |
|
489 do: |
|
490 [:byte | |
|
491 char := Character value: byte. |
|
492 ((33 <= byte and: [byte <= 126]) |
|
493 or: [char = Character tab or: [char = Character space or: [char = Character cr]]]) |
|
494 ifTrue: [aStream nextPut: char] |
|
495 ifFalse: [aStream nextPut: Character space]]. |
|
496 self |
|
497 debug: |
|
498 [Transcript space; show: kind printString. |
|
499 Transcript space; show: size printString. |
|
500 Transcript space; show: aStream contents printString]. |
|
501 ^Array |
|
502 with: kind |
|
503 with: size |
|
504 with: bytes |
|
505 ! |
|
506 |
|
507 xLongText |
|
508 | point count string | |
|
509 point := self readPoint. |
|
510 count := self next. |
|
511 string := (self next: count) asString. |
|
512 self |
|
513 debug: |
|
514 [Transcript space; show: point printString. |
|
515 Transcript space; show: count printString. |
|
516 Transcript space; show: string printString]. |
|
517 ^Array |
|
518 with: point |
|
519 with: count |
|
520 with: string |
|
521 ! |
|
522 |
|
523 xPackBitsRect |
|
524 | position word record | |
|
525 position := self position. |
|
526 word := self nextWord. |
|
527 self position: position. |
|
528 (word bitShift: -15) |
|
529 = 1 |
|
530 ifTrue: [record := self readPixMap: false] |
|
531 ifFalse: [record := self readBitMap: false]. |
|
532 self debug: [Transcript space; show: record printString]. |
|
533 imageSequence add: record. |
|
534 ^record |
|
535 ! |
|
536 |
|
537 xPackBitsRgn |
|
538 | position word record | |
|
539 position := self position. |
|
540 word := self nextWord. |
|
541 self position: position. |
|
542 (word bitShift: -15) |
|
543 = 1 |
|
544 ifTrue: [record := self readPixMap: true] |
|
545 ifFalse: [record := self readBitMap: true]. |
|
546 self debug: [Transcript space; show: record printString]. |
|
547 imageSequence add: record. |
|
548 ^record |
|
549 ! ! |
|
550 |
|
551 !PICTReader methodsFor:'decoding'! |
|
552 |
|
553 readBitData |
|
554 | bitData | |
|
555 bitData := ByteArray new: rowBytes * bounds height. |
|
556 self progress: 0. |
|
557 1 to: bounds height |
|
558 do: |
|
559 [:column | |
|
560 | start stop replacement | |
|
561 start := column - 1 * rowBytes + 1. |
|
562 stop := column * rowBytes. |
|
563 replacement := self readBitRowData. |
|
564 bitData |
|
565 replaceBytesFrom: start |
|
566 to: stop |
|
567 with: replacement |
|
568 startingAt: 1. |
|
569 self progress: column / bounds height]. |
|
570 ^bitData |
|
571 ! |
|
572 |
|
573 readBitMap: isMaskRgn |
|
574 | bitData anImage pad anArray maskRgn | |
|
575 rowBytes := self nextWord. |
|
576 bounds := self readRect. |
|
577 srcRect := self readRect. |
|
578 dstRect := self readRect. |
|
579 mode := self nextWord. |
|
580 bitData := self readBitData. |
|
581 isMaskRgn = true ifTrue: [maskRgn := self readRegion]. |
|
582 pad := rowBytes * 8 - bounds width. |
|
583 pad >= 8 |
|
584 ifTrue: [pad >= 16 |
|
585 ifTrue: [pad := 32] |
|
586 ifFalse: [pad := 16]] |
|
587 ifFalse: [pad := 8]. |
|
588 |
|
589 anImage := Image |
|
590 extent: bounds width @ bounds height |
|
591 depth: 1 |
|
592 palette: MappedPalette monochromeDefault |
|
593 bits: bitData |
|
594 pad: pad. |
|
595 |
|
596 " self debug: [anImage displayOn: ScheduledControllers activeController view graphicsContext]. " |
|
597 anArray := Array |
|
598 with: anImage |
|
599 with: srcRect |
|
600 with: dstRect |
|
601 with: mode. |
|
602 isMaskRgn = true ifTrue: [anArray := anArray , (Array with: maskRgn)]. |
|
603 ^anArray |
|
604 ! |
|
605 |
|
606 readBitRowData |
|
607 | rawData byteCount | |
|
608 rowBytes < 8 |
|
609 ifTrue: [rawData := self next: rowBytes] |
|
610 ifFalse: |
|
611 [rowBytes > 250 |
|
612 ifTrue: [byteCount := self nextWord] |
|
613 ifFalse: [byteCount := self next]. |
|
614 rawData := self unPackBits: (self next: byteCount)]. |
|
615 ^rawData |
|
616 ! |
|
617 |
|
618 readColorTable |
|
619 ctSeed := self nextLong. |
|
620 ctFlags := self nextWord. |
|
621 ctSize := self nextWord. |
|
622 ctTable := Array new: ctSize + 1. |
|
623 1 to: ctTable size |
|
624 do: |
|
625 [:i | |
|
626 | value rgb | |
|
627 value := self nextWord. |
|
628 value yourself. |
|
629 rgb := self nextWord bitShift: 32. |
|
630 rgb := rgb + (self nextWord bitShift: 16). |
|
631 rgb := rgb + self nextWord. |
|
632 ctTable at: i put: rgb] |
|
633 ! |
|
634 |
|
635 readDataLength2 |
|
636 | length bytes | |
|
637 length := self nextWord. |
|
638 bytes := self next: length. |
|
639 " self debug: [Transcript space; show: bytes printString]. " |
|
640 ^Array with: length with: bytes |
|
641 ! |
|
642 |
|
643 readDataLength4 |
|
644 | length bytes | |
|
645 length := self nextLong. |
|
646 bytes := self next: length. |
|
647 " self debug: [Transcript space; show: bytes printString]. " |
|
648 ^Array with: length with: bytes |
|
649 ! |
|
650 |
|
651 readDirectPixData |
|
652 packType = 0 ifTrue: [^self errorSorryNotSupported]. |
|
653 packType = 1 ifTrue: [^self errorSorryNotSupported]. |
|
654 packType = 2 ifTrue: [^self errorSorryNotSupported]. |
|
655 packType = 3 ifTrue: [^self errorSorryNotSupported]. |
|
656 packType = 4 ifTrue: [^self readDirectPixData4]. |
|
657 ^self errorUnexpectedPakingType |
|
658 ! |
|
659 |
|
660 readDirectPixData4 |
|
661 | palette image row scalingValue color index r g b | |
|
662 palette := FixedPalette |
|
663 redShift: 16 |
|
664 redMask: 255 |
|
665 greenShift: 8 |
|
666 greenMask: 255 |
|
667 blueShift: 0 |
|
668 blueMask: 255. |
|
669 image := Image |
|
670 extent: bounds width @ bounds height |
|
671 depth: 24 |
|
672 palette: palette. |
|
673 self progress: 0. |
|
674 0 to: bounds height - 1 |
|
675 do: |
|
676 [:y | |
|
677 | x | |
|
678 x := 0. |
|
679 row := self readDirectPixRowData. |
|
680 r := row size // 3 * 0 + 1. |
|
681 g := row size // 3 * 1 + 1. |
|
682 b := row size // 3 * 2 + 1. |
|
683 row size // 3 |
|
684 timesRepeat: |
|
685 [scalingValue := ColorValue scalingValue. |
|
686 color := ColorValue |
|
687 scaledRed: (self |
|
688 convertValue: ((row at: r) |
|
689 bitAnd: 255) |
|
690 from: 255 |
|
691 to: scalingValue) |
|
692 scaledGreen: (self |
|
693 convertValue: ((row at: g) |
|
694 bitAnd: 255) |
|
695 from: 255 |
|
696 to: scalingValue) |
|
697 scaledBlue: (self |
|
698 convertValue: (row at: b) |
|
699 from: 255 |
|
700 to: scalingValue). |
|
701 index := palette indexOfPaintNearest: color. |
|
702 image |
|
703 atX: x |
|
704 y: y |
|
705 put: index. |
|
706 r := r + 1. |
|
707 g := g + 1. |
|
708 b := b + 1. |
|
709 x := x + 1]. |
|
710 self progress: y / (bounds height - 1)]. |
|
711 ^image |
|
712 ! |
|
713 |
|
714 readDirectPixMap: isMaskRgn |
|
715 | anImage maskRgn anArray | |
|
716 |
|
717 baseAddr := self nextLong. |
|
718 rowBytes := self nextWord bitAnd: '16r3FFF' asNumber. |
|
719 bounds := self readRect. |
|
720 pmVersion := self nextWord. |
|
721 packType := self nextWord. |
|
722 packSize := self nextLong. |
|
723 hRes := self nextLong. |
|
724 vRes := self nextLong. |
|
725 pixelType := self nextWord. |
|
726 pixelSize := self nextWord. |
|
727 cmpCount := self nextWord. |
|
728 cmpSize := self nextWord. |
|
729 planeBytes := self nextLong. |
|
730 pmTable := self nextLong. |
|
731 pmReserved := self nextLong. |
|
732 srcRect := self readRect. |
|
733 dstRect := self readRect. |
|
734 mode := self nextWord. |
|
735 isMaskRgn = true ifTrue: [maskRgn := self readRegion]. |
|
736 anImage := self readDirectPixData. |
|
737 " self debug: [anImage displayOn: ScheduledControllers activeController view graphicsContext]. " |
|
738 anArray := Array |
|
739 with: anImage |
|
740 with: srcRect |
|
741 with: dstRect |
|
742 with: mode. |
|
743 isMaskRgn = true ifTrue: [anArray := anArray , (Array with: maskRgn)]. |
|
744 ^anArray |
|
745 ! |
|
746 |
|
747 readDirectPixRowData |
|
748 | rawData byteCount | |
|
749 (packType = 1 or: [rowBytes < 8]) |
|
750 ifTrue: [rawData := self next: rowBytes] |
|
751 ifFalse: [packType = 2 |
|
752 ifTrue: [rawData := self next: (rowBytes * (3 / 4)) asInteger] |
|
753 ifFalse: [packType > 2 |
|
754 ifTrue: |
|
755 [rowBytes > 250 |
|
756 ifTrue: [byteCount := self nextWord] |
|
757 ifFalse: [byteCount := self next]. |
|
758 rawData := self unPackBits: (self next: byteCount)]]]. |
|
759 ^rawData |
|
760 ! |
|
761 |
|
762 readHeader |
|
763 | position byte | |
|
764 picSize := self nextWord. |
|
765 picFrame := self readRect. |
|
766 position := self position. |
|
767 byte := self next. |
|
768 byte = '16r11' asNumber |
|
769 ifTrue: [picVersion := self next] |
|
770 ifFalse: |
|
771 [byte := self next. |
|
772 byte = '16r11' asNumber |
|
773 ifTrue: |
|
774 [picVersion := self next. |
|
775 self next] |
|
776 ifFalse: [^self errorCanNotRead]]. |
|
777 self position: position |
|
778 ! |
|
779 |
|
780 readPixData |
|
781 | pixData | |
|
782 pixData := ByteArray new: rowBytes * bounds height. |
|
783 self progress: 0. |
|
784 1 to: bounds height |
|
785 do: |
|
786 [:column | |
|
787 | start stop replacement | |
|
788 start := column - 1 * rowBytes + 1. |
|
789 stop := column * rowBytes. |
|
790 replacement := self readPixRowData. |
|
791 pixData |
|
792 replaceBytesFrom: start |
|
793 to: stop |
|
794 with: replacement |
|
795 startingAt: 1. |
|
796 self progress: column / bounds height]. |
|
797 ^pixData |
|
798 ! |
|
799 |
|
800 readPixMap: isMaskRgn |
|
801 | pixData aPalette anImage pad maskRgn anArray | |
|
802 rowBytes := self nextWord bitAnd: '16r3FFF' asNumber. |
|
803 bounds := self readRect. |
|
804 pmVersion := self nextWord. |
|
805 packType := self nextWord. |
|
806 packSize := self nextLong. |
|
807 hRes := self nextLong. |
|
808 vRes := self nextLong. |
|
809 pixelType := self nextWord. |
|
810 pixelSize := self nextWord. |
|
811 cmpCount := self nextWord. |
|
812 cmpSize := self nextWord. |
|
813 planeBytes := self nextLong. |
|
814 pmTable := self nextLong. |
|
815 pmReserved := self nextLong. |
|
816 self readColorTable. |
|
817 srcRect := self readRect. |
|
818 dstRect := self readRect. |
|
819 mode := self nextWord. |
|
820 isMaskRgn = true ifTrue: [maskRgn := self readRegion]. |
|
821 pixData := self readPixData. |
|
822 aPalette := MappedPalette withColors: (ctTable collect: [:rgb | self colorValueFrom: rgb]). |
|
823 pad := rowBytes * 8 - (bounds width * pixelSize). |
|
824 pad >= 8 |
|
825 ifTrue: [pad >= 16 |
|
826 ifTrue: [pad := 32] |
|
827 ifFalse: [pad := 16]] |
|
828 ifFalse: [pad := 8]. |
|
829 anImage := Image |
|
830 extent: bounds width @ bounds height |
|
831 depth: pixelSize |
|
832 palette: aPalette |
|
833 bits: pixData |
|
834 pad: pad. |
|
835 " self debug: [anImage displayOn: ScheduledControllers activeController view graphicsContext]. " |
|
836 anArray := Array |
|
837 with: anImage |
|
838 with: srcRect |
|
839 with: dstRect |
|
840 with: mode. |
|
841 isMaskRgn = true ifTrue: [anArray := anArray , (Array with: maskRgn)]. |
|
842 ^anArray |
|
843 ! |
|
844 |
|
845 readPixRowData |
|
846 packType = 0 ifTrue: [^self readBitRowData]. |
|
847 packType = 1 ifTrue: [^self readBitRowData]. |
|
848 ^self errorCanNotRead |
|
849 ! |
|
850 |
|
851 readPoint |
|
852 | x y point | |
|
853 x := self nextWord. |
|
854 y := self nextWord. |
|
855 point := x @ y. |
|
856 ^point |
|
857 ! |
|
858 |
|
859 readPolygon |
|
860 | length bytes | |
|
861 length := self nextWord. |
|
862 bytes := self next: length - 2. |
|
863 self |
|
864 debug: |
|
865 [Transcript space; show: length printString. |
|
866 Transcript space; show: bytes printString]. |
|
867 ^Array with: length with: bytes |
|
868 ! |
|
869 |
|
870 readRect |
|
871 | top left bottom right rect | |
|
872 top := self nextWord. |
|
873 left := self nextWord. |
|
874 bottom := self nextWord. |
|
875 right := self nextWord. |
|
876 rect := left @ top corner: right @ bottom. |
|
877 ^rect |
|
878 ! |
|
879 |
|
880 readRegion |
|
881 | length bytes | |
|
882 length := self nextWord. |
|
883 bytes := self next: length - 2. |
|
884 self |
|
885 debug: |
|
886 [Transcript space; show: length printString. |
|
887 Transcript space; show: bytes printString]. |
|
888 ^Array with: length with: bytes |
|
889 ! ! |
|
890 |
|
891 !PICTReader methodsFor:'encoding'! |
|
892 |
|
893 bitData: bitData |
|
894 | imageRowBytes packStream | |
|
895 imageRowBytes := bounds width * pixelSize + 31 // 32 * 4. |
|
896 packStream := WriteStream on: (ByteArray new: bitData size). |
|
897 self progress: 0. |
|
898 1 to: bounds height |
|
899 do: |
|
900 [:h | |
|
901 | rowBits packedBits | |
|
902 rowBits := bitData copyFrom: h - 1 * imageRowBytes + 1 to: h - 1 * imageRowBytes + rowBytes. |
|
903 rowBytes < 8 |
|
904 ifTrue: [packStream nextPutAll: rowBits] |
|
905 ifFalse: |
|
906 [packedBits := self packBits: rowBits. |
|
907 rowBytes > 250 |
|
908 ifTrue: |
|
909 [packStream nextPut: ((packedBits size bitShift: -8) |
|
910 bitAnd: 255). |
|
911 packStream nextPut: (packedBits size bitAnd: 255)] |
|
912 ifFalse: [packStream nextPut: packedBits size]. |
|
913 packStream nextPutAll: packedBits]. |
|
914 self progress: h / bounds height]. |
|
915 ^packStream contents |
|
916 ! |
|
917 |
|
918 directPixData4: anImage |
|
919 | packStream palette r g b index color scalingValue stream | |
|
920 packStream := WriteStream on: (ByteArray new: anImage bits size). |
|
921 palette := anImage palette. |
|
922 self progress: 0. |
|
923 0 to: bounds height - 1 |
|
924 do: |
|
925 [:y | |
|
926 r := WriteStream on: ByteArray new. |
|
927 g := WriteStream on: ByteArray new. |
|
928 b := WriteStream on: ByteArray new. |
|
929 0 to: bounds width - 1 |
|
930 do: |
|
931 [:x | |
|
932 index := anImage atX: x y: y. |
|
933 (palette includesKey: index) |
|
934 ifTrue: [color := palette at: index] |
|
935 ifFalse: [color := palette at: (index bitAnd: palette maxIndex)]. |
|
936 scalingValue := ColorValue scalingValue. |
|
937 r nextPut: (self |
|
938 convertValue: color scaledRed |
|
939 from: scalingValue |
|
940 to: 255). |
|
941 g nextPut: (self |
|
942 convertValue: color scaledGreen |
|
943 from: scalingValue |
|
944 to: 255). |
|
945 b nextPut: (self |
|
946 convertValue: color scaledBlue |
|
947 from: scalingValue |
|
948 to: 255)]. |
|
949 stream := WriteStream on: ByteArray new. |
|
950 stream nextPutAll: r contents. |
|
951 stream nextPutAll: g contents. |
|
952 stream nextPutAll: b contents. |
|
953 packStream nextPutAll: (self directPixRowData: stream contents). |
|
954 self progress: y / (bounds height - 1)]. |
|
955 ^packStream contents |
|
956 ! |
|
957 |
|
958 directPixRowData: row |
|
959 | aStream rawData byteCount | |
|
960 aStream := WriteStream on: (ByteArray new: row size). |
|
961 rawData := self packBits: row. |
|
962 byteCount := rawData size. |
|
963 rowBytes > 250 |
|
964 ifTrue: |
|
965 [aStream nextPut: ((byteCount bitShift: -8) |
|
966 bitAnd: 255). |
|
967 aStream nextPut: (byteCount bitAnd: 255)] |
|
968 ifFalse: [aStream nextPut: byteCount]. |
|
969 aStream nextPutAll: rawData. |
|
970 ^aStream contents |
|
971 ! |
|
972 |
|
973 nextPutImage24: image |
|
974 | anImage endOpcode | |
|
975 Cursor wait showWhile: [anImage := image "convertToPalette: (FixedPalette |
|
976 redShift: 16 |
|
977 redMask: 255 |
|
978 greenShift: 8 |
|
979 greenMask: 255 |
|
980 blueShift: 0 |
|
981 blueMask: 255) |
|
982 renderedBy: ErrorDiffusion new"]. |
|
983 baseAddr := '16r000000FF' asNumber. |
|
984 rowBytes := anImage width * 32 + 7 // 8. |
|
985 bounds := anImage bounds. |
|
986 pmVersion := 0. |
|
987 packType := 4. |
|
988 packSize := 0. |
|
989 hRes := '16r00480000' asNumber. |
|
990 vRes := '16r00480000' asNumber. |
|
991 pixelType := 16. |
|
992 pixelSize := 32. |
|
993 cmpCount := 3. |
|
994 cmpSize := 8. |
|
995 planeBytes := 0. |
|
996 pmTable := 0. |
|
997 pmReserved := 0. |
|
998 srcRect := anImage bounds. |
|
999 dstRect := anImage bounds. |
|
1000 mode := 64. |
|
1001 endOpcode := '16r00FF' asNumber. |
|
1002 self writeImage24: anImage. |
|
1003 self writeOpcode: endOpcode. |
|
1004 ^anImage |
|
1005 ! |
|
1006 |
|
1007 sortPalette: image |
|
1008 | max array color | |
|
1009 max := 1 bitShift: pixelSize. |
|
1010 array := Array new: image palette maxIndex + 1. |
|
1011 1 to: array size |
|
1012 do: |
|
1013 [:i | |
|
1014 color := image palette at: i - 1 ifAbsent: [ColorValue white]. |
|
1015 array at: i put: (self rgbIntegerFrom: color)]. |
|
1016 array size > max |
|
1017 ifTrue: [array := array copyFrom: 1 to: max] |
|
1018 ifFalse: [array size < max ifTrue: [array := array , (Array new: max - array size withAll: 0)]]. |
|
1019 array := array asSortedCollection reverse collect: [:rgb | self colorValueFrom: rgb]. |
|
1020 ^image convertToPalette: (MappedPalette withColors: array) |
|
1021 ! |
|
1022 |
|
1023 writeBits24: bits |
|
1024 | currentOpecode | |
|
1025 currentOpecode := '16r009A' asNumber. |
|
1026 self writeOpcode: currentOpecode. |
|
1027 self nextLongPut: baseAddr. |
|
1028 self nextWordPut: rowBytes + (1 bitShift: 15). |
|
1029 self writeRect: bounds. |
|
1030 self nextWordPut: pmVersion. |
|
1031 self nextWordPut: packType. |
|
1032 self nextLongPut: packSize. |
|
1033 self nextLongPut: hRes. |
|
1034 self nextLongPut: vRes. |
|
1035 self nextWordPut: pixelType. |
|
1036 self nextWordPut: pixelSize. |
|
1037 self nextWordPut: cmpCount. |
|
1038 self nextWordPut: cmpSize. |
|
1039 self nextLongPut: planeBytes. |
|
1040 self nextLongPut: pmTable. |
|
1041 self nextLongPut: pmReserved. |
|
1042 self writeRect: srcRect. |
|
1043 self writeRect: dstRect. |
|
1044 self nextWordPut: mode. |
|
1045 self nextPutAll: bits |
|
1046 ! |
|
1047 |
|
1048 writeBits: bits palette: palette |
|
1049 rowBytes < 8 |
|
1050 ifTrue: [currentOpcode := '16r90' asNumber] |
|
1051 ifFalse: [currentOpcode := '16r0098' asNumber]. |
|
1052 picVersion = 1 |
|
1053 ifTrue: |
|
1054 [self writeOpcode: currentOpcode. |
|
1055 self nextWordPut: rowBytes. |
|
1056 self writeRect: bounds. |
|
1057 self writeRect: srcRect. |
|
1058 self writeRect: dstRect. |
|
1059 self nextWordPut: mode. |
|
1060 self nextPutAll: bits] |
|
1061 ifFalse: |
|
1062 [self writeOpcode: currentOpcode. |
|
1063 self nextWordPut: rowBytes + (1 bitShift: 15). |
|
1064 self writeRect: bounds. |
|
1065 self nextWordPut: pmVersion. |
|
1066 self nextWordPut: packType. |
|
1067 self nextLongPut: packSize. |
|
1068 self nextLongPut: hRes. |
|
1069 self nextLongPut: vRes. |
|
1070 self nextWordPut: pixelType. |
|
1071 self nextWordPut: pixelSize. |
|
1072 self nextWordPut: cmpCount. |
|
1073 self nextWordPut: cmpSize. |
|
1074 self nextLongPut: planeBytes. |
|
1075 self nextLongPut: pmTable. |
|
1076 self nextLongPut: pmReserved. |
|
1077 self nextLongPut: ctSeed. |
|
1078 self nextWordPut: ctFlags. |
|
1079 self nextWordPut: ctSize. |
|
1080 ctTable := Array new: palette maxIndex + 1. |
|
1081 1 to: ctTable size |
|
1082 do: |
|
1083 [:i | |
|
1084 | color value rgb | |
|
1085 color := palette at: i - 1 ifAbsent: [ColorValue white]. |
|
1086 value := 0. |
|
1087 rgb := self rgbIntegerFrom: color. |
|
1088 ctTable at: i put: rgb. |
|
1089 self nextWordPut: value. |
|
1090 self nextWordPut: ((rgb bitShift: -32) |
|
1091 bitAnd: 65535). |
|
1092 self nextWordPut: ((rgb bitShift: -16) |
|
1093 bitAnd: 65535). |
|
1094 self nextWordPut: (rgb bitAnd: 65535)]. |
|
1095 self writeRect: srcRect. |
|
1096 self writeRect: dstRect. |
|
1097 self nextWordPut: mode. |
|
1098 self nextPutAll: bits] |
|
1099 ! |
|
1100 |
|
1101 writeClip: aRectangle |
|
1102 picVersion = 1 |
|
1103 ifTrue: [self writeOpcode: '16r01' asNumber] |
|
1104 ifFalse: [self writeOpcode: '16r0001' asNumber]. |
|
1105 self nextWordPut: 10. |
|
1106 self writeRect: aRectangle |
|
1107 ! |
|
1108 |
|
1109 writeHeader24: bits |
|
1110 | pictCodeSize | |
|
1111 pictCodeSize := 2. |
|
1112 picSize := 40. |
|
1113 picSize := picSize + pictCodeSize. |
|
1114 picSize := picSize + pictCodeSize + 10. |
|
1115 picSize := picSize + pictCodeSize + 68 + bits size. |
|
1116 bits size odd ifTrue: [picSize := picSize + 1]. |
|
1117 picSize := picSize + pictCodeSize. |
|
1118 self nextWordPut: picSize \\ 65535. |
|
1119 self writeRect: picFrame. |
|
1120 self nextWordPut: 17. |
|
1121 self nextWordPut: 767. |
|
1122 self nextWordPut: 3072. |
|
1123 1 to: 2 do: [:i | self nextWordPut: 65535]. |
|
1124 1 to: 4 do: [:i | self nextWordPut: 0]. |
|
1125 self nextWordPut: picFrame width. |
|
1126 1 to: 1 do: [:i | self nextWordPut: 0]. |
|
1127 self nextWordPut: picFrame height. |
|
1128 1 to: 3 do: [:i | self nextWordPut: 0] |
|
1129 ! |
|
1130 |
|
1131 writeHeader: bits palette: palette |
|
1132 | pictCodeSize | |
|
1133 picVersion = 1 |
|
1134 ifTrue: |
|
1135 [pictCodeSize := 1. |
|
1136 picSize := 12. |
|
1137 picSize := picSize + pictCodeSize + 10. |
|
1138 picSize := picSize + pictCodeSize + 10 + 8 + 8 + 2 + bits size. |
|
1139 picSize := picSize + pictCodeSize] |
|
1140 ifFalse: |
|
1141 [pictCodeSize := 2. |
|
1142 picSize := 40. |
|
1143 picSize := picSize + pictCodeSize. |
|
1144 picSize := picSize + pictCodeSize + 10. |
|
1145 picSize := picSize + pictCodeSize + 46 + 8 + (palette maxIndex + 1 * 8) + 8 + 8 + 2 + bits size. |
|
1146 bits size odd ifTrue: [picSize := picSize + 1]. |
|
1147 picSize := picSize + pictCodeSize]. |
|
1148 self nextWordPut: picSize \\ 65535. |
|
1149 self writeRect: picFrame. |
|
1150 picVersion = 1 |
|
1151 ifTrue: |
|
1152 [self nextPut: 17. |
|
1153 self nextPut: 1] |
|
1154 ifFalse: |
|
1155 [self nextWordPut: 17. |
|
1156 self nextWordPut: 767. |
|
1157 self nextWordPut: 3072. |
|
1158 1 to: 2 do: [:i | self nextWordPut: 65535]. |
|
1159 1 to: 4 do: [:i | self nextWordPut: 0]. |
|
1160 self nextWordPut: picFrame width. |
|
1161 1 to: 1 do: [:i | self nextWordPut: 0]. |
|
1162 self nextWordPut: picFrame height. |
|
1163 1 to: 3 do: [:i | self nextWordPut: 0]] |
|
1164 ! |
|
1165 |
|
1166 writeImage24: anImage |
|
1167 | bits | |
|
1168 bits := self directPixData4: anImage. |
|
1169 self writeHeader24: ByteArray new. |
|
1170 self writeClip: bounds. |
|
1171 self writeBits24: bits. |
|
1172 ^anImage |
|
1173 ! |
|
1174 |
|
1175 writeImage: anImage |
|
1176 | image bits | |
|
1177 image := self sortPalette: anImage. |
|
1178 bits := self bitData: image bits. |
|
1179 self writeHeader: bits palette: image palette. |
|
1180 self writeClip: bounds. |
|
1181 self writeBits: bits palette: image palette. |
|
1182 ^anImage |
|
1183 ! |
|
1184 |
|
1185 writeOpcode: opcode |
|
1186 picVersion = 1 |
|
1187 ifTrue: [self nextPut: opcode] |
|
1188 ifFalse: |
|
1189 [self position odd ifTrue: [self nextPut: 0]. |
|
1190 self nextWordPut: opcode] |
|
1191 ! |
|
1192 |
|
1193 writeRect: aRectangle |
|
1194 self nextWordPut: aRectangle top. |
|
1195 self nextWordPut: aRectangle left. |
|
1196 self nextWordPut: aRectangle bottom. |
|
1197 self nextWordPut: aRectangle right |
|
1198 ! ! |
|
1199 |
|
1200 !PICTReader methodsFor:'interpreting'! |
|
1201 |
|
1202 fixedOpcode: opcodeName additionalData: additionalData |
|
1203 | bytes | |
|
1204 self debug: [Transcript space; show: opcodeName]. |
|
1205 bytes := self next: additionalData. |
|
1206 self debug: [Transcript space; show: bytes printString] |
|
1207 ! |
|
1208 |
|
1209 interpretOpcode: association |
|
1210 | opcodeName additionalData | |
|
1211 opcodeName := association key. |
|
1212 additionalData := association value. |
|
1213 additionalData isString |
|
1214 ifTrue: [self variableOpcode: opcodeName additionalData: additionalData] |
|
1215 ifFalse: [self fixedOpcode: opcodeName additionalData: additionalData] |
|
1216 ! |
|
1217 |
|
1218 nextOpcode |
|
1219 | association | |
|
1220 self |
|
1221 debug: |
|
1222 [Transcript cr. |
|
1223 Transcript show: (self hexString4: self position). |
|
1224 Transcript show: ':']. |
|
1225 picVersion = 1 |
|
1226 ifTrue: [currentOpcode := self next] |
|
1227 ifFalse: |
|
1228 [self position odd ifTrue: [self next]. |
|
1229 currentOpcode := self nextWord]. |
|
1230 association := self class opcodeAt: currentOpcode. |
|
1231 association isNil ifTrue: [^self errorUnexpectedOpcode]. |
|
1232 self interpretOpcode: association. |
|
1233 ^association |
|
1234 ! |
|
1235 |
|
1236 variableOpcode: opcodeName additionalData: additionalData |
|
1237 | aSymbol | |
|
1238 self debug: [Transcript space; show: opcodeName]. |
|
1239 additionalData = 'Polygon size' ifTrue: [^self readPolygon]. |
|
1240 additionalData = 'Region size' ifTrue: [^self readRegion]. |
|
1241 additionalData = '2 + data length' ifTrue: [^self readDataLength2]. |
|
1242 additionalData = '4 + data length' ifTrue: [^self readDataLength4]. |
|
1243 (opcodeName copyFrom: 1 to: ('Apple' size min: opcodeName size)) |
|
1244 = 'Apple' ifTrue: [^self errorUnexpectedOpcode]. |
|
1245 aSymbol := ((String with: $x with: opcodeName first asUppercase) |
|
1246 , (opcodeName copyFrom: 2 to: opcodeName size)) asSymbol. |
|
1247 (self respondsTo: aSymbol) |
|
1248 ifTrue: [^self perform: aSymbol]. |
|
1249 ^self errorUnexpectedOpcode |
|
1250 ! ! |
|
1251 |
|
1252 !PICTReader methodsFor:'printing'! |
|
1253 |
|
1254 hexString2: aNumber |
|
1255 | aString aStream | |
|
1256 aString := aNumber printStringRadix: 16. |
|
1257 aStream := WriteStream on: (String new: 12). |
|
1258 aStream nextPutAll: '16r'. |
|
1259 2 - aString size timesRepeat: [aStream nextPutAll: '0']. |
|
1260 aStream nextPutAll: aString. |
|
1261 ^aStream contents |
|
1262 ! |
|
1263 |
|
1264 hexString4: aNumber |
|
1265 | aString aStream | |
|
1266 aString := aNumber printStringRadix: 16. |
|
1267 aStream := WriteStream on: (String new: 12). |
|
1268 aStream nextPutAll: '16r'. |
|
1269 4 - aString size timesRepeat: [aStream nextPutAll: '0']. |
|
1270 aStream nextPutAll: aString. |
|
1271 ^aStream contents |
|
1272 ! |
|
1273 |
|
1274 hexString8: aNumber |
|
1275 | aString aStream | |
|
1276 aString := aNumber printStringRadix: 16. |
|
1277 aStream := WriteStream on: (String new: 12). |
|
1278 aStream nextPutAll: '16r'. |
|
1279 8 - aString size timesRepeat: [aStream nextPutAll: '0']. |
|
1280 aStream nextPutAll: aString. |
|
1281 ^aStream contents |
|
1282 ! ! |
|
1283 |
|
1284 !PICTReader methodsFor:'private'! |
|
1285 |
|
1286 colorValueFrom: rgbInteger |
|
1287 | scalingValue | |
|
1288 scalingValue := ColorValue scalingValue. |
|
1289 ^ColorValue |
|
1290 scaledRed: (self |
|
1291 convertValue: ((rgbInteger bitShift: -32) |
|
1292 bitAnd: 65535) |
|
1293 from: 65535 |
|
1294 to: scalingValue) |
|
1295 scaledGreen: (self |
|
1296 convertValue: ((rgbInteger bitShift: -16) |
|
1297 bitAnd: 65535) |
|
1298 from: 65535 |
|
1299 to: scalingValue) |
|
1300 scaledBlue: (self |
|
1301 convertValue: (rgbInteger bitAnd: 65535) |
|
1302 from: 65535 |
|
1303 to: scalingValue) |
|
1304 ! |
|
1305 |
|
1306 errorSorryNotSupported |
|
1307 self error: 'sorry, not supported'. |
|
1308 ^nil |
|
1309 ! |
|
1310 |
|
1311 errorUnexpectedOpcode |
|
1312 | string | |
|
1313 picVersion = 1 |
|
1314 ifTrue: [string := self hexString2: currentOpcode] |
|
1315 ifFalse: [string := self hexString4: currentOpcode]. |
|
1316 string := (self hexString8: self position) |
|
1317 , ': ' , string. |
|
1318 self error: 'unexpected opcode: ' , string. |
|
1319 ^nil |
|
1320 ! |
|
1321 |
|
1322 errorUnexpectedPakingType |
|
1323 self error: 'unexpected packing type: ' , packType printString. |
|
1324 ^nil |
|
1325 ! |
|
1326 |
|
1327 mergeImages |
|
1328 | aRectangle aDepth aPalette anImage aPattern indexValue | |
|
1329 aRectangle := nil. |
|
1330 aDepth := nil. |
|
1331 aPalette := nil. |
|
1332 imageSequence |
|
1333 do: |
|
1334 [:array | |
|
1335 aRectangle isNil |
|
1336 ifTrue: [aRectangle := array at: 3] |
|
1337 ifFalse: [aRectangle := aRectangle merge: (array at: 3)]. |
|
1338 aDepth isNil |
|
1339 ifTrue: |
|
1340 [aDepth := (array at: 1) depth. |
|
1341 aPalette := (array at: 1) palette] |
|
1342 ifFalse: [aDepth < (array at: 1) depth |
|
1343 ifTrue: |
|
1344 [aDepth := (array at: 1) depth. |
|
1345 aPalette := (array at: 1) palette]]]. |
|
1346 anImage := Image |
|
1347 extent: aRectangle extent |
|
1348 depth: aDepth |
|
1349 palette: aPalette. |
|
1350 aPattern := Image |
|
1351 extent: 16 @ 16 |
|
1352 depth: anImage depth |
|
1353 palette: anImage palette. |
|
1354 indexValue := aPattern palette indexOfPaintNearest: ColorValue white. |
|
1355 0 to: aPattern width - 1 do: [:x | 0 to: aPattern height - 1 do: [:y | aPattern atPoint: x @ y put: indexValue]]. |
|
1356 anImage |
|
1357 tile: aRectangle |
|
1358 from: Point zero |
|
1359 in: aPattern |
|
1360 rule: RasterOp over. |
|
1361 imageSequence |
|
1362 do: |
|
1363 [:array | |
|
1364 | srcImage srcR dstR | |
|
1365 srcImage := array at: 1. |
|
1366 srcR := array at: 2. |
|
1367 dstR := array at: 3. |
|
1368 srcImage palette = aPalette ifFalse: [srcImage := srcImage convertToPalette: aPalette renderedBy: ErrorDiffusion new]. |
|
1369 dstR := dstR translatedBy: Point zero - aRectangle origin. |
|
1370 anImage |
|
1371 copy: dstR |
|
1372 from: srcR origin |
|
1373 in: srcImage |
|
1374 rule: RasterOp over]. |
|
1375 ^anImage |
|
1376 ! |
|
1377 |
|
1378 packBits: bits |
|
1379 | packStream prev writeBlock bitSize bitPos start code replicateSize literalSize | |
|
1380 packStream := WriteStream on: (ByteArray new: bits size). |
|
1381 prev := nil. |
|
1382 writeBlock := [:asc | asc key < 0 |
|
1383 ifTrue: |
|
1384 ["replicate" |
|
1385 packStream nextPut: asc key negated. |
|
1386 packStream nextPut: asc value] |
|
1387 ifFalse: |
|
1388 ["literal" |
|
1389 | litStart litStop | |
|
1390 litStart := asc value first. |
|
1391 litStop := asc value last. |
|
1392 asc key = (litStop - litStart) ifFalse: [self error: 'can''t happen']. |
|
1393 [litStop - litStart + 1 > 128] |
|
1394 whileTrue: |
|
1395 [packStream nextPut: 127. |
|
1396 litStart to: litStart + 127 do: [:litIndex | packStream nextPut: (bits at: litIndex)]. |
|
1397 litStart := litStart + 128]. |
|
1398 litStart <= litStop |
|
1399 ifTrue: |
|
1400 [packStream nextPut: litStop - litStart + 1 - 1. |
|
1401 litStart to: litStop do: [:litIndex | packStream nextPut: (bits at: litIndex)]]]]. |
|
1402 bitSize := bits size. |
|
1403 bitPos := 1. |
|
1404 [bitPos <= bitSize] |
|
1405 whileTrue: |
|
1406 [start := bitPos. |
|
1407 code := bits at: start. |
|
1408 [(bitPos := bitPos + 1) <= bitSize and: [(bits at: bitPos) |
|
1409 = code]] |
|
1410 whileTrue: []. |
|
1411 replicateSize := bitPos - start. |
|
1412 replicateSize > 128 |
|
1413 ifTrue: |
|
1414 [prev == nil |
|
1415 ifFalse: |
|
1416 [writeBlock value: prev. |
|
1417 prev := nil]. |
|
1418 [replicateSize > 128] |
|
1419 whileTrue: |
|
1420 [writeBlock value: -129 -> code. |
|
1421 start := start + 128. |
|
1422 replicateSize := replicateSize - 128]]. |
|
1423 replicateSize = 2 |
|
1424 ifTrue: |
|
1425 ["treat as literal" |
|
1426 literalSize := 2. |
|
1427 prev ~~ nil ifTrue: [prev key >= 0 |
|
1428 ifTrue: |
|
1429 ["prev is literal" |
|
1430 literalSize := literalSize + prev value size. |
|
1431 start := prev value first] |
|
1432 ifFalse: |
|
1433 [writeBlock value: prev. |
|
1434 prev := nil]]. |
|
1435 prev := literalSize - 1 -> (start to: start + literalSize - 1)] |
|
1436 ifFalse: [replicateSize > 2 |
|
1437 ifTrue: |
|
1438 [prev == nil |
|
1439 ifFalse: |
|
1440 [writeBlock value: prev. |
|
1441 prev := nil]. |
|
1442 prev := (256 - (replicateSize - 1)) negated -> code] |
|
1443 ifFalse: ["replicateSize < 2" |
|
1444 bitPos := bitPos - 1]]. |
|
1445 (start := bitPos) <= bitSize |
|
1446 ifTrue: |
|
1447 [code := bits at: start. |
|
1448 [(bitPos := bitPos + 1) <= bitSize and: [(bits at: bitPos) |
|
1449 ~= code]] |
|
1450 whileTrue: [code := bits at: bitPos]. |
|
1451 bitPos <= bitSize ifTrue: [bitPos := bitPos - 1]. |
|
1452 literalSize := bitPos - start. |
|
1453 literalSize > 0 |
|
1454 ifTrue: |
|
1455 [prev ~~ nil ifTrue: [prev key >= 0 |
|
1456 ifTrue: |
|
1457 ["prev is literal" |
|
1458 literalSize := literalSize + prev value size. |
|
1459 start := prev value first] |
|
1460 ifFalse: |
|
1461 [writeBlock value: prev. |
|
1462 prev := nil]]. |
|
1463 prev := literalSize - 1 -> (start to: start + literalSize - 1)]]]. |
|
1464 prev == nil |
|
1465 ifFalse: |
|
1466 [writeBlock value: prev. |
|
1467 prev := nil]. |
|
1468 ^packStream contents |
|
1469 ! |
|
1470 |
|
1471 rgbIntegerFrom: aColorValue |
|
1472 | scalingValue | |
|
1473 scalingValue := ColorValue scalingValue. |
|
1474 ^((self |
|
1475 convertValue: aColorValue scaledRed |
|
1476 from: scalingValue |
|
1477 to: 65535) |
|
1478 bitShift: 32) |
|
1479 + ((self |
|
1480 convertValue: aColorValue scaledGreen |
|
1481 from: scalingValue |
|
1482 to: 65535) |
|
1483 bitShift: 16) + (self |
|
1484 convertValue: aColorValue scaledBlue |
|
1485 from: scalingValue |
|
1486 to: 65535) |
|
1487 ! |
|
1488 |
|
1489 unPackBits: bits |
|
1490 | unpackStream bitSize bitPos code | |
|
1491 unpackStream := WriteStream on: (ByteArray new: bits size). |
|
1492 bitSize := bits size. |
|
1493 bitPos := 0. |
|
1494 [(bitPos := bitPos + 1) <= bitSize] |
|
1495 whileTrue: |
|
1496 [code := bits at: bitPos. |
|
1497 code < 128 |
|
1498 ifTrue: [1 to: code + 1 do: [:i | unpackStream nextPut: (bits at: (bitPos := bitPos + 1))]] |
|
1499 ifFalse: [code > 128 |
|
1500 ifTrue: |
|
1501 [bitPos := bitPos + 1. |
|
1502 1 to: 256 - code + 1 do: [:i | unpackStream nextPut: (bits at: bitPos)]]]]. |
|
1503 ^unpackStream contents |
|
1504 ! ! |
|
1505 |
|
1506 !PICTReader methodsFor:'reading'! |
152 |
1507 |
153 fromStream: aStream |
1508 fromStream: aStream |
154 "read an image in my format from aStream. |
1509 "read an image in my format from aStream. |
155 Dtermine if its a raster or icon file." |
1510 Dtermine if its a raster or icon file." |
156 |
1511 |
157 | rasterType mapType mapBytes imageWords form depth |
1512 |endOpcode| |
158 rMap gMap bMap mapLen |
|
159 a b c index pos| |
|
160 |
1513 |
161 inStream := aStream. |
1514 inStream := aStream. |
162 |
|
163 aStream binary. |
1515 aStream binary. |
164 |
1516 |
165 pos := aStream position. |
1517 inStream skip:512. "apples file header" |
166 ((aStream nextWord == 16r59A6) |
1518 |
167 and:[aStream nextWord == 16r6A95]) ifFalse: [ |
1519 currentOpcode := nil. |
168 "/ 'SUNReader: not a SunRaster file' errorPrintNL. |
1520 imageSequence := OrderedCollection new. |
169 aStream position:pos. |
1521 self readHeader. |
170 ^ self fromSunIconStream:aStream |
1522 endOpcode := 16r00FF. |
171 ]. |
1523 [currentOpcode = endOpcode] |
172 |
1524 whileFalse: [self nextOpcode]. |
173 width := aStream nextLong. |
1525 imageSequence isEmpty ifTrue: [^nil]. |
174 height := aStream nextLong. |
1526 imageSequence size = 1 ifTrue: [^ imageSequence first first]. |
175 |
1527 ^ self mergeImages |
176 depth := aStream nextLong. |
|
177 aStream nextLong. "Ignore the image length since I can't rely on it anyway." |
|
178 rasterType := aStream nextLong. |
|
179 mapType := aStream nextLong. "Ignore the raster maptype." |
|
180 mapBytes := aStream nextLong. |
|
181 |
|
182 depth = 8 ifTrue: [ |
|
183 mapLen := (mapBytes // 3). |
|
184 rMap := aStream nextBytes:mapLen. |
|
185 gMap := aStream nextBytes:mapLen. |
|
186 bMap := aStream nextBytes:mapLen. |
|
187 colorMap := MappedPalette redVector:rMap greenVector:gMap blueVector:bMap. |
|
188 |
|
189 data := ByteArray uninitializedNew:(width * height). |
|
190 aStream nextBytes:(width * height) into:data. |
|
191 |
|
192 photometric := #palette. |
|
193 samplesPerPixel := 1. |
|
194 bitsPerSample := #(8). |
|
195 |
|
196 ^ self |
|
197 ]. |
|
198 depth ~~ 1 ifTrue: [ |
|
199 ^ self fileFormatError:'only depth 1 and 8 supported'. |
|
200 ]. |
|
201 |
|
202 form := nil. |
|
203 |
|
204 aStream skip: mapBytes. "Skip the color map." |
|
205 imageWords := (width / 16) ceiling * height. |
|
206 data := ByteArray uninitializedNew:(imageWords * 2). |
|
207 |
|
208 (rasterType between: 0 and: 2) ifFalse: [ |
|
209 ^ self fileFormatError:'Unknown raster file rasterType'. |
|
210 ]. |
|
211 |
|
212 (rasterType = 2) ifFalse: [ |
|
213 "no compression of bytes" |
|
214 aStream nextBytes:(imageWords * 2) into:data |
|
215 ] ifTrue: [ |
|
216 "run length compression of bytes" |
|
217 |
|
218 index := 1. |
|
219 a := aStream next. |
|
220 [a notNil] whileTrue: [ |
|
221 (a = 128) ifFalse: [ |
|
222 data at:index put: a. |
|
223 index := index + 1 |
|
224 ] ifTrue: [ |
|
225 b := aStream next. |
|
226 b = 0 ifTrue: [ |
|
227 data at:index put:128 . |
|
228 index := index + 1 |
|
229 ] ifFalse: [ |
|
230 c := aStream next. |
|
231 1 to:(b+1) do:[:i | |
|
232 data at:index put:c. |
|
233 index := index + 1 |
|
234 ] |
|
235 ] |
|
236 ]. |
|
237 a := aStream next |
|
238 ]. |
|
239 ]. |
|
240 photometric := #whiteIs0. |
|
241 samplesPerPixel := 1. |
|
242 bitsPerSample := #(1). |
|
243 |
1528 |
244 " |
1529 " |
245 Image fromFile:'bitmaps/founders.im8' |
1530 Image fromFile:'bitmaps/founders.im8' |
246 Image fromFile:'bitmaps/bf.im8' |
1531 Image fromFile:'bitmaps/bf.im8' |
247 SunRasterReader fromStream:'bitmaps/founders.im8' asFilename readStream |
1532 PictReader fromStream:'bitmaps/founders.im8' asFilename readStream |
248 SunRasterReader fromStream:'bitmaps/bf.im8' asFilename readStream |
|
249 " |
1533 " |
250 |
|
251 "Modified: / 3.2.1998 / 18:00:35 / cg" |
|
252 ! ! |
1534 ! ! |
253 |
1535 |
|
1536 !PICTReader methodsFor:'writing'! |
|
1537 |
|
1538 nextPutImage: anImage |
|
1539 | endOpcode | |
|
1540 "/ (anImage isKindOf: Image) not ifTrue: [^self errorCanNotWrite]. |
|
1541 "/ ((imageStream isKindOf: ExternalStream) |
|
1542 "/ or: [(imageStream respondsTo: #stream) |
|
1543 "/ and: [imageStream stream isKindOf: ExternalStream]]) |
|
1544 "/ ifTrue: [self nextPutAll: (ByteArray new: 512)]. |
|
1545 "/ picSize := 0. |
|
1546 "/ picFrame := 0 @ 0 extent: anImage extent. |
|
1547 "/ anImage bitsPerPixel = 1 |
|
1548 "/ ifTrue: [picVersion := 1] |
|
1549 "/ ifFalse: [picVersion := 2]. |
|
1550 "/ anImage bitsPerPixel > 8 ifTrue: [^self nextPutImage24: anImage]. |
|
1551 "/ rowBytes := anImage width * anImage bitsPerPixel + 7 // 8. |
|
1552 "/ bounds := anImage bounds. |
|
1553 "/ pmVersion := 0. |
|
1554 "/ packType := 0. |
|
1555 "/ packSize := 0. |
|
1556 "/ hRes := '16r00480000' asNumber. |
|
1557 "/ vRes := '16r00480000' asNumber. |
|
1558 "/ pixelType := 0. |
|
1559 "/ pixelSize := anImage bitsPerPixel. |
|
1560 "/ cmpCount := 1. |
|
1561 "/ cmpSize := anImage bitsPerPixel. |
|
1562 "/ planeBytes := 0. |
|
1563 "/ pmTable := 0. |
|
1564 "/ pmReserved := 0. |
|
1565 "/ ctSeed := 0. |
|
1566 "/ ctFlags := '16r8000' asNumber. |
|
1567 "/ ctSize := anImage palette maxIndex. |
|
1568 "/ ctTable := nil. |
|
1569 "/ srcRect := anImage bounds. |
|
1570 "/ dstRect := anImage bounds. |
|
1571 "/ mode := 0. |
|
1572 "/ endOpcode := '16r00FF' asNumber. |
|
1573 "/ self writeImage: anImage. |
|
1574 "/ self writeOpcode: endOpcode. |
|
1575 "/ ^anImage |
|
1576 ! ! |
|
1577 |
254 !PICTReader class methodsFor:'documentation'! |
1578 !PICTReader class methodsFor:'documentation'! |
255 |
1579 |
256 version |
1580 version |
257 ^ '$Header: /cvs/stx/stx/libview2/PICTReader.st,v 1.1 2003-09-01 09:52:06 cg Exp $' |
1581 ^ '$Header: /cvs/stx/stx/libview2/PICTReader.st,v 1.2 2003-09-01 15:07:43 cg Exp $' |
258 ! ! |
1582 ! ! |
259 |
1583 |
260 PICTReader initialize! |
1584 PICTReader initialize! |