--- a/PNGReader.st Fri Jul 31 12:58:11 2009 +0200
+++ b/PNGReader.st Fri Jul 31 14:14:55 2009 +0200
@@ -13,7 +13,8 @@
ImageReader subclass:#PNGReader
instanceVariableNames:'colorType depth compressionMethod filterMethod interlaceMode
- redBytes greenBytes blueBytes bytesPerScanline globalDataChunk'
+ redBytes greenBytes blueBytes bytesPerScanline globalDataChunk
+ thisScanline prevScanline'
classVariableNames:''
poolDictionaries:''
category:'Graphics-Images-Readers'
@@ -104,7 +105,7 @@
"Modified: 21.6.1996 / 20:38:46 / cg"
! !
-!PNGReader methodsFor:'private'!
+!PNGReader methodsFor:'private-chunks'!
processBKGDChunkLen:len
inStream skip:len.
@@ -229,24 +230,30 @@
!
processNonInterlacedGlobalDATA
- | data n zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen|
+ | "data n" zlibReader filter temp bytesPerScanline "filtersSeen" copyMethod|
+
+ "/ filtersSeen := Set new.
"/ data := ByteArray new:(self bytesPerRow * height)+1000.
"/ n := ZipStream uncompress: globalDataChunk into: data.
"/ self halt.
- zlibReader := ZipStream readOpenAsZipStreamOn:(globalDataChunk readStream).
+ zlibReader := ZipStream readOpenAsZipStreamOn:(globalDataChunk readStream).
+ zlibReader binary.
bytesPerScanline := self bytesPerRow.
+ copyMethod := #(copyPixelsGray: nil copyPixelsRGB: copyPixelsIndexed:
+ copyPixelsGrayAlpha: nil copyPixelsRGBA:) at:colorType+1.
+
prevScanline := ByteArray new: bytesPerScanline.
thisScanline := ByteArray new: bytesPerScanline.
0 to: height - 1 do:[:index |
filter := (zlibReader next: 1) first.
- filtersSeen add: filter.
+ "/ 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.
+ zlibReader next: bytesPerScanline into: thisScanline startingAt: 1.
+ filter ~~ 0 ifTrue:[ self filterScanline: filter count: bytesPerScanline ].
+ self perform:copyMethod with: index.
temp := prevScanline.
prevScanline := thisScanline.
thisScanline := temp
@@ -315,6 +322,26 @@
"Created: 21.6.1996 / 21:15:58 / cg"
! !
+!PNGReader methodsFor:'private-filtering'!
+
+filterHorizontal:count
+ "use the pixel to the left as a predictor"
+
+ |delta|
+
+ delta := self bitsPerPixel // 8 max:1.
+ delta+1 to:count do:[:i|
+ thisScanline at:i put:(((thisScanline at:i)+ (thisScanline at:i-delta)) bitAnd:255)
+ ]
+!
+
+filterScanline:filterType count:count
+ self
+ perform:(#(filterNone: filterHorizontal: filterVertical: filterAverage: filterPaeth:)
+ at:filterType+1)
+ with:count
+! !
+
!PNGReader methodsFor:'private-reading'!
getChunk
@@ -576,7 +603,7 @@
!PNGReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.13 2009-07-31 10:58:11 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.14 2009-07-31 12:14:55 cg Exp $'
! !
PNGReader initialize!