7 inclusion of the above copyright notice. This software may not |
7 inclusion of the above copyright notice. This software may not |
8 be provided or otherwise made available to, or used by, any |
8 be provided or otherwise made available to, or used by, any |
9 other person. No title to or ownership of the software is |
9 other person. No title to or ownership of the software is |
10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 |
|
13 |
|
14 |
|
15 "{ Package: 'stx:libview2' }" |
12 "{ Package: 'stx:libview2' }" |
16 |
13 |
17 ImageReader subclass:#PNGReader |
14 ImageReader subclass:#PNGReader |
18 instanceVariableNames:'colorType depth compressionMethod filterMethod interlaceMode |
15 instanceVariableNames:'colorType depth compressionMethod filterMethod interlaceMode |
19 redBytes greenBytes blueBytes' |
16 redBytes greenBytes blueBytes bytesPerScanline globalDataChunk' |
20 classVariableNames:'' |
17 classVariableNames:'' |
21 poolDictionaries:'' |
18 poolDictionaries:'' |
22 category:'Graphics-Images-Readers' |
19 category:'Graphics-Images-Readers' |
23 ! |
20 ! |
24 |
21 |
164 |
162 |
165 "Created: 21.6.1996 / 21:15:49 / cg" |
163 "Created: 21.6.1996 / 21:15:49 / cg" |
166 ! |
164 ! |
167 |
165 |
168 processChunk:type len:len |
166 processChunk:type len:len |
|
167 |chunk| |
|
168 |
|
169 type = 'IDAT' ifTrue:[ |
|
170 "---since the compressed data can span multiple |
|
171 chunks, stitch them all together first. later, |
|
172 if memory is an issue, we need to figure out how |
|
173 to do this on the fly---" |
|
174 chunk := inStream next:len. |
|
175 globalDataChunk := globalDataChunk isNil |
|
176 ifTrue: [chunk] |
|
177 ifFalse:[globalDataChunk,chunk]. |
|
178 ^ true |
|
179 "/ ^ self processIDATChunkLen:len |
|
180 ]. |
|
181 |
169 type = 'gAMA' ifTrue:[^ self processGAMAChunkLen:len]. |
182 type = 'gAMA' ifTrue:[^ self processGAMAChunkLen:len]. |
170 type = 'sBIT' ifTrue:[^ self processSBITChunkLen:len]. |
183 type = 'sBIT' ifTrue:[^ self processSBITChunkLen:len]. |
171 type = 'tEXt' ifTrue:[^ self processTEXTChunkLen:len]. |
184 type = 'tEXt' ifTrue:[^ self processTEXTChunkLen:len]. |
172 type = 'IDAT' ifTrue:[^ self processIDATChunkLen:len]. |
|
173 type = 'tIME' ifTrue:[^ self processTIMEChunkLen:len]. |
185 type = 'tIME' ifTrue:[^ self processTIMEChunkLen:len]. |
174 type = 'bKGD' ifTrue:[^ self processBKGDChunkLen:len]. |
186 type = 'bKGD' ifTrue:[^ self processBKGDChunkLen:len]. |
175 type = 'zTXt' ifTrue:[^ self processZTXTChunkLen:len]. |
187 type = 'zTXt' ifTrue:[^ self processZTXTChunkLen:len]. |
176 type = 'PLTE' ifTrue:[^ self processPLTEChunkLen:len]. |
188 type = 'PLTE' ifTrue:[^ self processPLTEChunkLen:len]. |
177 |
189 |
191 processGAMAChunkLen:len |
203 processGAMAChunkLen:len |
192 inStream skip:len. |
204 inStream skip:len. |
193 ^ true |
205 ^ true |
194 |
206 |
195 "Created: 21.6.1996 / 21:10:52 / cg" |
207 "Created: 21.6.1996 / 21:10:52 / cg" |
|
208 ! |
|
209 |
|
210 processGlobalIDATChunk |
|
211 interlaceMode == 0 ifTrue: [ |
|
212 ^ self processNonInterlacedGlobalDATA |
|
213 ]. |
|
214 ^ self processInterlacedGlobalDATA |
196 ! |
215 ! |
197 |
216 |
198 processIDATChunkLen:len |
217 processIDATChunkLen:len |
199 interlaceMode == 0 ifTrue: [ |
218 interlaceMode == 0 ifTrue: [ |
200 ^ self processNonInterlacedDATA:len |
219 ^ self processNonInterlacedDATA:len |
203 ! |
222 ! |
204 |
223 |
205 processIHDRChunkLen:len |
224 processIHDRChunkLen:len |
206 "header chunk - currently unhandled" |
225 "header chunk - currently unhandled" |
207 |
226 |
208 |width height bitsPerChannel interlaceMethod palette image bitsPerPixel bytesPerScanline rowSize| |
227 |bitsPerChannel interlaceMethod palette image bitsPerPixel rowSize| |
209 |
228 |
210 self halt. |
229 self halt. |
211 width := inStream nextLongMSB:true. "/ 1..4 |
230 width := inStream nextLongMSB:true. "/ 1..4 |
212 height := inStream nextLongMSB:true. "/ 5..8 |
231 height := inStream nextLongMSB:true. "/ 5..8 |
213 bitsPerChannel := inStream nextByte. "/ 9 |
232 bitsPerChannel := inStream nextByte. "/ 9 |
239 ! |
258 ! |
240 |
259 |
241 processNonInterlacedDATA:len |
260 processNonInterlacedDATA:len |
242 | zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen| |
261 | zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen| |
243 |
262 |
244 zlibReader := ZLibReadStream on:inStream from: 1 to:len. |
263 zlibReader := ZipStream readOpenAsZipStreamOn:inStream. |
|
264 "/ zlibReader := ZLibReadStream on:inStream from: 1 to:len. |
|
265 |
|
266 prevScanline := ByteArray new: self bytesPerRow. |
|
267 thisScanline := ByteArray new: self bytesPerRow. |
|
268 0 to: height - 1 do: |
|
269 [:index | |
|
270 filter := (zlibReader next: 1) first. |
|
271 filtersSeen add: filter. |
|
272 (filter isNil or: [(filter between: 0 and: 4) not]) ifTrue: [^self]. |
|
273 thisScanline := zlibReader next: bytesPerScanline into: thisScanline startingAt: 1. |
|
274 self filterScanline: filter count: bytesPerScanline. |
|
275 self copyPixels: index. |
|
276 temp := prevScanline. |
|
277 prevScanline := thisScanline. |
|
278 thisScanline := temp] |
|
279 ! |
|
280 |
|
281 processNonInterlacedGlobalDATA |
|
282 | zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen| |
|
283 |
|
284 zlibReader := ZipStream readOpenAsZipStreamOn:(globalDataChunk readStream). |
|
285 bytesPerScanline := self bytesPerRow. |
|
286 |
245 prevScanline := ByteArray new: bytesPerScanline. |
287 prevScanline := ByteArray new: bytesPerScanline. |
246 thisScanline := ByteArray new: bytesPerScanline. |
288 thisScanline := ByteArray new: bytesPerScanline. |
247 0 to: height - 1 do: |
289 0 to: height - 1 do: |
248 [:index | |
290 [:index | |
249 filter := (zlibReader next: 1) first. |
291 filter := (zlibReader next: 1) first. |