[BUG][FIX] PNGReadWriter tweaks
Duane Maxwell
dmaxwell at entrypoint.com
Thu Apr 27 20:32:12 UTC 2000
Change Set: PNGTweaks
Date: 27 April 2000
Author: Duane Maxwell/EntryPoint
This is a changeset to Squeak 2.8a #2040.
It deals with a couple of bugs in the PNGReadWriter class.
1) fixes bug with unusual-depth odd-sized non-interlaced indexed images
2) fixes bug with extremely small interlaced images (even Netscape has a
bug here)
With this changeset, all of the non-corrupt images at:
http://www.cdrom.com/pub/png/pngsuite.html
should be correctly rendered to the degree we support PNG's esoterica.
Note that this page contains three intentionally corrupt images which may
cause walkbalks.
-------------- next part --------------
'From Squeak2.8alpha of 26 April 2000 [latest update: #2040] on 27 April
2000 at 1:14:44 pm'!
"Change Set: PNGTweaks
Date: 27 April 2000
Author: Duane Maxwell/EntryPoint
This is a changeset to Squeak 2.8a #2040.
It deals with a couple of bugs in the PNGImageReadWriter class.
1) fixes bug with unusual-depth odd-sized non-interlaced indexed images
2) fixes bug with extremely small interlaced images
With this changeset, all of the non-corrupt images at:
http://www.cdrom.com/pub/png/pngsuite.html
should be correctly rendered.
"!
!PNGReadWriter methodsFor: 'chunks' stamp: 'DSM 4/27/2000 13:10'!
processInterlaced
| z filter bytesPerPass startingCol colIncrement rowIncrement
startingRow cx sc |
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 ).
z _ ZLibReadStream
on: chunk
from: 1
to: chunk size.
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.
(startingRow at: pass)
to: height - 1
by: (rowIncrement at: pass)
do:
[:y |
filter _ z next.
(filter isNil or: [(filter
between: 0 and: 4) not])
ifTrue: [^ self].
thisScanline _ z next:
bytesPerPass.
self filterScanline: filter
count: bytesPerPass.
self
copyPixels: y
at: sc
by: cx.
prevScanline
replaceFrom: 1
to: bytesPerPass
with: thisScanline
startingAt: 1]]]! !
!PNGReadWriter methodsFor: 'pixel copies' stamp: 'DSM 4/27/2000 12:34'!
copyPixelsGray: y
"Handle non-interlaced grayscale color mode (colorType = 0)"
| blitter pixPerByte mask shifts pixelNumber rawByte pixel |
blitter _ BitBlt bitPokerToForm: form.
bitsPerChannel = 16
ifTrue:
[0 to: width - 1 do: [:x | blitter pixelAt: x @ y
put: 255 - (thisScanline at: x << 1 + 1)].
^ self]
ifFalse:
[bitsPerChannel = 8
ifTrue:
[1 to: width do: [:x | blitter
pixelAt: x - 1 @ y put: (thisScanline at: x)].
^ self].
bitsPerChannel = 1
ifTrue:
[pixPerByte _ 8.
mask _ 1.
shifts _ #(7 6 5 4 3 2 1 0 )].
bitsPerChannel = 2
ifTrue:
[pixPerByte _ 4.
mask _ 3.
shifts _ #(6 4 2 0 )].
bitsPerChannel = 4
ifTrue:
[pixPerByte _ 2.
mask _ 15.
shifts _ #(4 0 )].
pixelNumber _ 0.
0 to: width - 1 do:
[:x |
rawByte _ thisScanline at: pixelNumber //
pixPerByte + 1.
pixel _ rawByte >> (shifts at: pixelNumber
\\ pixPerByte + 1) bitAnd: mask.
blitter pixelAt: x @ y put: pixel.
pixelNumber _ pixelNumber + 1]]! !
!PNGReadWriter methodsFor: 'pixel copies' stamp: 'DSM 4/27/2000 12:35'!
copyPixelsIndexed: y
"Handle non-interlaced indexed color mode (colorType = 3)"
| blitter pixPerByte mask shifts pixelNumber rawByte pixel |
blitter _ BitBlt bitPokerToForm: form.
bitsPerChannel = 8
ifTrue:
[1 to: width do: [:x | blitter pixelAt: x - 1 @ y
put: (thisScanline at: x)].
^ self].
bitsPerChannel = 1
ifTrue:
[pixPerByte _ 8.
mask _ 1.
shifts _ #(7 6 5 4 3 2 1 0 )].
bitsPerChannel = 2
ifTrue:
[pixPerByte _ 4.
mask _ 3.
shifts _ #(6 4 2 0 )].
bitsPerChannel = 4
ifTrue:
[pixPerByte _ 2.
mask _ 15.
shifts _ #(4 0 )].
pixelNumber _ 0.
0 to: width - 1 do:
[:x |
rawByte _ thisScanline at: pixelNumber // pixPerByte + 1.
pixel _ rawByte >> (shifts at: pixelNumber \\ pixPerByte +
1) bitAnd: mask.
blitter pixelAt: x @ y put: pixel.
pixelNumber _ pixelNumber + 1]! !
!PNGReadWriter methodsFor: 'miscellaneous' stamp: 'DSM 4/27/2000 13:09'!
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 ].
! !
More information about the Squeak-dev
mailing list
|