--- a/PNGReader.st Fri Jul 31 19:56:56 2009 +0200
+++ b/PNGReader.st Mon Aug 03 14:28:19 2009 +0200
@@ -63,19 +63,16 @@
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'
+ PNGReader fromFile:'\\exeptn\unsaved\pd_stuff\PNGs\Down.png'
"
! !
!PNGReader class methodsFor:'initialization'!
initialize
- "install myself in the Image classes fileFormat table
- for the `.png' extension."
+ "install myself in the Image classes fileFormat table for the `.png' extension."
- "/ not yet finished - do not add
- "/ MIMETypes defineImageType:'image/x-png' suffix:'png' reader:self.
-
- "Modified: 1.2.1997 / 15:02:47 / cg"
+ MIMETypes defineImageType:'image/x-png' suffix:'png' reader:self.
! !
!PNGReader class methodsFor:'testing'!
@@ -107,6 +104,22 @@
!PNGReader methodsFor:'private-chunks'!
+doPass: pass
+ "Certain interlace passes are skipped with certain small image dimensions"
+
+ pass = 1 ifTrue: [ ^ true ].
+ ((width = 1) and: [height = 1]) ifTrue: [ ^ false ].
+ pass = 2 ifTrue: [ ^ width >= 5 ].
+ pass = 3 ifTrue: [ ^ height >= 5 ].
+ pass = 4 ifTrue: [ ^ (width >=3 ) or: [height >= 5] ].
+ pass = 5 ifTrue: [ ^ height >=3 ].
+ pass = 6 ifTrue: [ ^ width >=2 ].
+ pass = 7 ifTrue: [ ^ height >=2 ].
+
+ self error:'invalid argument'.
+ ^ true
+!
+
processBKGDChunkLen:len
inStream skip:len.
^ true
@@ -208,6 +221,51 @@
^ true
!
+processInterlacedGlobalDATA
+ | zlibReader filter bytesPerPass startingCol colIncrement rowIncrement
+ startingRow cx sc temp "filtersSeen" bitsPerPixel copyMethod|
+
+self error:'interlaced pictures not yet supported'.
+
+ "/ filtersSeen := Set new.
+
+ startingCol := #(0 4 0 2 0 1 0 ).
+ colIncrement := #(8 8 4 4 2 2 1 ).
+ rowIncrement := #(8 8 8 4 4 2 2 ).
+ startingRow := #(0 0 4 0 2 0 1 ).
+
+ zlibReader := ZipStream readOpenAsZipStreamOn:(globalDataChunk readStream).
+ zlibReader binary.
+ bytesPerScanline := self bytesPerRow.
+ bitsPerPixel := self bitsPerPixel.
+
+ copyMethod := #(copyPixelsGray: nil copyPixelsRGB: copyPixelsIndexed:
+ copyPixelsGrayAlpha: nil copyPixelsRGBA:) at:colorType+1.
+
+ 1 to: 7 do: [:pass |
+ (self doPass: pass) ifTrue:[
+ cx := colIncrement at: pass.
+ sc := startingCol at: pass.
+ bytesPerPass := width - sc + cx - 1 // cx * bitsPerPixel + 7 // 8.
+ prevScanline := ByteArray new: bytesPerPass.
+ thisScanline := ByteArray new: bytesPerScanline.
+ (startingRow at: pass) to: height - 1 by: (rowIncrement at: pass) do: [:y |
+ filter := zlibReader next.
+ "/ filtersSeen add: filter.
+ (filter isNil or: [(filter between: 0 and: 4) not])
+ ifTrue: [^ self].
+ zlibReader next: bytesPerPass into: thisScanline startingAt: 1.
+ filter ~~ 0 ifTrue:[ self filterScanline: filter count: bytesPerPass ].
+ self copyPixels:y at:sc by:cx.
+ temp := prevScanline.
+ prevScanline := thisScanline.
+ thisScanline := temp.
+ ]
+ ]
+ ].
+ zlibReader atEnd ifFalse:[self error:'Unexpected data'].
+!
+
processNonInterlacedDATA:len
| zlibReader filter temp prevScanline thisScanline bytesPerScanline filtersSeen|
@@ -324,6 +382,20 @@
!PNGReader methodsFor:'private-filtering'!
+filterAverage: count
+ "Use the average of the pixel to the left and the pixel above as a predictor"
+
+ | delta |
+ delta := self bitsPerPixel // 8 max: 1.
+ 1 to: delta do: [:i |
+ thisScanline at: i put: ((thisScanline at: i) + ((prevScanline at: i) // 2) bitAnd: 255)].
+ delta + 1 to: count do: [:i |
+ thisScanline at: i put:
+ ((thisScanline at: i)
+ + ((prevScanline at: i)
+ + (thisScanline at: i - delta) // 2) bitAnd: 255)]
+!
+
filterHorizontal:count
"use the pixel to the left as a predictor"
@@ -335,6 +407,9 @@
]
!
+filterNone: count
+!
+
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"
@@ -387,7 +462,50 @@
^ c
! !
-!PNGReader methodsFor:'private-reading'!
+!PNGReader methodsFor:'private-pixel copy'!
+
+copyPixels: y at: startX by: incX
+ "Handle interlaced pixels of supported colorTypes"
+
+ | s |
+
+ s := #(copyPixelsGray:at:by: nil copyPixelsRGB:at:by: copyPixelsIndexed:at:by:
+ copyPixelsGrayAlpha:at:by: nil copyPixelsRGBA:at:by:) at: colorType+1.
+ self perform: s asSymbol with: y with: startX with: incX
+!
+
+copyPixelsGray: y
+ "Handle non-interlaced Gray color modes (colorType = 0)"
+
+ |bpr i|
+
+ bpr := self bytesPerRow.
+ i := y * bpr.
+
+ data replaceFrom:1+i to:(i+bpr-1) with:thisScanline startingAt:1.
+!
+
+copyPixelsIndexed:y
+ "Handle non-interlaced palette color modes (colorType = 3)"
+
+ |bpr i|
+
+ bpr := self bytesPerRow.
+ i := y * bpr.
+
+ data replaceFrom:1+i to:(i+bpr-1) with:thisScanline startingAt:1.
+!
+
+copyPixelsRGB: y
+ "Handle non-interlaced RGB color modes (colorType = 2)"
+
+ |bpr i|
+
+ bpr := self bytesPerRow.
+ i := y * bpr.
+
+ data replaceFrom:1+i to:(i+bpr-1) with:thisScanline startingAt:1.
+!
copyPixelsRGBA: y
"Handle non-interlaced RGBA color modes (colorType = 6)"
@@ -398,7 +516,9 @@
i := y * bpr.
data replaceFrom:1+i to:(i+bpr-1) with:thisScanline startingAt:1.
-!
+! !
+
+!PNGReader methodsFor:'private-reading'!
getChunk
|len type crc|
@@ -657,7 +777,7 @@
!PNGReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.16 2009-07-31 17:56:56 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/PNGReader.st,v 1.17 2009-08-03 12:28:19 cg Exp $'
! !
PNGReader initialize!