--- a/PNGReader.st Fri Jul 31 14:14:55 2009 +0200
+++ b/PNGReader.st Fri Jul 31 15:06:56 2009 +0200
@@ -12,9 +12,9 @@
"{ Package: 'stx:libview2' }"
ImageReader subclass:#PNGReader
- instanceVariableNames:'colorType depth compressionMethod filterMethod interlaceMode
- redBytes greenBytes blueBytes bytesPerScanline globalDataChunk
- thisScanline prevScanline'
+ instanceVariableNames:'colorType bitsPerChannel depth compressionMethod filterMethod
+ interlaceMode redBytes greenBytes blueBytes bytesPerScanline
+ globalDataChunk thisScanline prevScanline'
classVariableNames:''
poolDictionaries:''
category:'Graphics-Images-Readers'
@@ -62,7 +62,7 @@
PNGReader fromFile:'C:\Users\cg\Desktop\croquet\cobalt-base-current-build-20090210\cobalt-base-current-build-20090210\content\models\textures\checkerboard.png'
PNGReader fromFile:'C:\Dokumente und Einstellungen\cg\Desktop\misc\PNGs\Delete.png'
-
+ PNGReader fromFile:'\\exeptn\unsaved\pd_stuff\PNGs\Delete.png'
"
! !
@@ -175,7 +175,7 @@
processIHDRChunkLen:len
"header chunk - currently unhandled"
- |bitsPerChannel interlaceMethod palette image bitsPerPixel rowSize|
+ |interlaceMethod palette image bitsPerPixel rowSize|
self halt.
width := inStream nextLongMSB:true. "/ 1..4
@@ -198,7 +198,7 @@
palette: (colorType = 0
ifTrue: [self grayColorsFor: depth]
ifFalse: [palette := self class defaultPalette])].
- bitsPerPixel := (BPP at: colorType + 1) at: bitsPerChannel highBit.
+ "/ bitsPerPixel := (BPP at: colorType + 1) at: bitsPerChannel highBit.
bytesPerScanline := (width * bitsPerPixel + 7) // 8.
rowSize := image width * image depth + 31 >> 5
!
@@ -335,15 +335,71 @@
]
!
+filterPaeth: count
+ "Select one of (the pixel to the left, the pixel above and the pixel to above left) to
+ predict the value of this pixel"
+
+ | delta |
+
+ delta _ self bitsPerPixel // 8 max: 1.
+ 1 to: delta do: [ :i |
+ thisScanline at: i put:
+ (((thisScanline at: i) + (prevScanline at: i)) bitAnd: 255)].
+ delta+1 to: count do: [ :i |
+ thisScanline
+ at: i
+ put: (((thisScanline at: i) + (self
+ paethPredictLeft: (thisScanline at: i-delta)
+ above: (prevScanline at: i)
+ aboveLeft: (prevScanline at: i-delta)))
+ bitAnd: 255)]
+!
+
filterScanline:filterType count:count
self
perform:(#(filterNone: filterHorizontal: filterVertical: filterAverage: filterPaeth:)
at:filterType+1)
with:count
+!
+
+filterVertical: count
+ "Use the pixel above as a predictor"
+
+ 1 to: count do: [ :i |
+ thisScanline at: i put: (((thisScanline at: i) +
+ (prevScanline at: i)) bitAnd: 255)
+ ]
+!
+
+paethPredictLeft: a above: b aboveLeft: c
+ "Predicts the value of a pixel based on nearby pixels, based on Paeth (GG II, 1991)"
+
+ | pa pb pc |
+
+ pa := b > c ifTrue: [b - c] ifFalse: [c - b].
+ pb := a > c ifTrue: [a - c] ifFalse: [c - a].
+ pc := a + b - c - c.
+ pc < 0 ifTrue: [
+ pc := pc * -1
+ ].
+ ((pa <= pb) and: [pa <= pc]) ifTrue: [^ a].
+ (pb <= pc) ifTrue: [^ b].
+ ^ c
! !
!PNGReader methodsFor:'private-reading'!
+copyPixelsRGBA: y
+ "Handle non-interlaced RGBA color modes (colorType = 6)"
+
+ |bpr i|
+
+ bpr := self bytesPerRow.
+ i := y * bpr.
+
+ data replaceFrom:1+i to:(i+bpr-1) with:thisScanline startingAt:1.
+!
+
getChunk
|len type crc|
@@ -501,6 +557,8 @@
[self getChunk] whileTrue.
+ data := ByteArray new:(self bytesPerRow * height).
+
globalDataChunk notNil ifTrue:[
self processGlobalIDATChunk
].
@@ -603,7 +661,7 @@
!PNGReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.14 2009-07-31 12:14:55 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.15 2009-07-31 13:06:56 cg Exp $'
! !
PNGReader initialize!