--- a/PNGReader.st Sat Jun 28 14:24:40 2008 +0200
+++ b/PNGReader.st Mon Jun 30 11:36:58 2008 +0200
@@ -9,14 +9,11 @@
other person. No title to or ownership of the software is
hereby transferred.
"
-
-
-
"{ Package: 'stx:libview2' }"
ImageReader subclass:#PNGReader
instanceVariableNames:'colorType depth compressionMethod filterMethod interlaceMode
- redBytes greenBytes blueBytes'
+ redBytes greenBytes blueBytes bytesPerScanline globalDataChunk'
classVariableNames:''
poolDictionaries:''
category:'Graphics-Images-Readers'
@@ -60,6 +57,7 @@
examples
"
PNGReader fromFile:'/home/cg/AudioExplorer_51_files/use_small.png'
+ PNGReader fromFile:'\\Exeptn\tmp\images\expeccoScreenshot4020_5526507.png'
"
! !
@@ -166,10 +164,24 @@
!
processChunk:type len:len
+ |chunk|
+
+ type = 'IDAT' ifTrue:[
+ "---since the compressed data can span multiple
+ chunks, stitch them all together first. later,
+ if memory is an issue, we need to figure out how
+ to do this on the fly---"
+ chunk := inStream next:len.
+ globalDataChunk := globalDataChunk isNil
+ ifTrue: [chunk]
+ ifFalse:[globalDataChunk,chunk].
+ ^ true
+"/ ^ self processIDATChunkLen:len
+ ].
+
type = 'gAMA' ifTrue:[^ self processGAMAChunkLen:len].
type = 'sBIT' ifTrue:[^ self processSBITChunkLen:len].
type = 'tEXt' ifTrue:[^ self processTEXTChunkLen:len].
- type = 'IDAT' ifTrue:[^ self processIDATChunkLen:len].
type = 'tIME' ifTrue:[^ self processTIMEChunkLen:len].
type = 'bKGD' ifTrue:[^ self processBKGDChunkLen:len].
type = 'zTXt' ifTrue:[^ self processZTXTChunkLen:len].
@@ -195,6 +207,13 @@
"Created: 21.6.1996 / 21:10:52 / cg"
!
+processGlobalIDATChunk
+ interlaceMode == 0 ifTrue: [
+ ^ self processNonInterlacedGlobalDATA
+ ].
+ ^ self processInterlacedGlobalDATA
+!
+
processIDATChunkLen:len
interlaceMode == 0 ifTrue: [
^ self processNonInterlacedDATA:len
@@ -205,7 +224,7 @@
processIHDRChunkLen:len
"header chunk - currently unhandled"
- |width height bitsPerChannel interlaceMethod palette image bitsPerPixel bytesPerScanline rowSize|
+ |bitsPerChannel interlaceMethod palette image bitsPerPixel rowSize|
self halt.
width := inStream nextLongMSB:true. "/ 1..4
@@ -241,7 +260,30 @@
processNonInterlacedDATA:len
| zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen|
- zlibReader := ZLibReadStream on:inStream from: 1 to:len.
+ zlibReader := ZipStream readOpenAsZipStreamOn:inStream.
+ "/ zlibReader := ZLibReadStream on:inStream from: 1 to:len.
+
+ prevScanline := ByteArray new: self bytesPerRow.
+ thisScanline := ByteArray new: self bytesPerRow.
+ 0 to: height - 1 do:
+ [:index |
+ filter := (zlibReader next: 1) first.
+ filtersSeen add: filter.
+ (filter isNil or: [(filter between: 0 and: 4) not]) ifTrue: [^self].
+ thisScanline := zlibReader next: bytesPerScanline into: thisScanline startingAt: 1.
+ self filterScanline: filter count: bytesPerScanline.
+ self copyPixels: index.
+ temp := prevScanline.
+ prevScanline := thisScanline.
+ thisScanline := temp]
+!
+
+processNonInterlacedGlobalDATA
+ | zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen|
+
+ zlibReader := ZipStream readOpenAsZipStreamOn:(globalDataChunk readStream).
+ bytesPerScanline := self bytesPerRow.
+
prevScanline := ByteArray new: bytesPerScanline.
thisScanline := ByteArray new: bytesPerScanline.
0 to: height - 1 do:
@@ -421,6 +463,10 @@
[self getChunk] whileTrue.
+ globalDataChunk notNil ifTrue:[
+ self processGlobalIDATChunk
+ ].
+
photometric == #palette ifTrue:[
redBytes isNil ifTrue:[
'PNGReader: missing palette chunk.' infoPrintCR.
@@ -444,7 +490,7 @@
!PNGReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.10 2003-11-19 15:38:33 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.11 2008-06-30 09:36:58 cg Exp $'
! !
PNGReader initialize!