[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