[squeak-dev] Re: quick handling of graphics files

Levente Uzonyi leves at elte.hu
Thu Apr 15 17:42:20 UTC 2010


On Thu, 15 Apr 2010, Juan Vuletich wrote:

> This is an updated version. It includes Levente's suggestion, and Yoshiki's 
> and Andreas' alternatives as well, although disabled. All three options now 
> work for gray level images with other bit depths besides 1 (I only tested 1 
> and 8). I also fixed transparent pixels for gray level images (it was 
> completely broken).

Nice, I ran the following benchmark with all three (+1) versions:

Smalltalk garbageCollect.
(1 to: 5) collect: [ :runs |
 	[ ImageReadWriter formFromFileNamed: 'test.png' ] timeToRun ].

test.png is Ross' test image which is pretty large.
The results:

#Andreas -> #(37 35 36 37 36).
#Juan -> #(100 99 103 100 101).
#Juan2 -> #(75 74 75 75 76).
#Yoshiki -> #(38 38 39 38 38).

#Juan used the original method from your changeset, the others used the 
attached version. It includes three enhancements:
- doesn't create a blitter when it's not necessary, this affects all 
benchmarks
- holds the bitmap in a variable instead of accessing via #bits
- uses #bitShift: instead of #<<


Levente


>
> Cheers,
> Juan Vuletich
>
-------------- next part --------------
'From Squeak4.1beta of 15 April 2010 [latest update: #9972] on 15 April 2010 at 6:23:23 pm'!

!PNGReadWriter methodsFor: 'pixel copies' stamp: 'ul 4/15/2010 18:19'!
copyPixelsGray: y 
	"Handle non-interlaced grayscale color mode (colorType = 0)"

	| base bits |
	bitsPerChannel = 16 ifTrue: [
		"Warning: This is extremely slow. Besides we are downsampling to 8 bits!!"
		| blitter |
		blitter := BitBlt current bitPokerToForm: form.
		0 to: width - 1 do: [ :x |
			blitter pixelAt: x @ y put: 255 - (thisScanline at: x * 2 + 1) ].
			^self ].

	"Just copy the bits"
	"This interesting technique (By Andreas Raab) is faster for very large images, but might be slower for small ones"
	"^self copyPixelsGrayWeirdBitBltHack: y ".

	"This interesting technique  (By Yoshiki Ohshima) is faster for very large images, but might be slower for small ones"
	"form bits copyFromByteArray2: thisScanline to: y * (form width* bitsPerChannel // 32)".

	"This Smalltalk version might be easier to understand"
	base := y * form width * bitsPerChannel // 32 + 1.
	bits := form bits.
	0 to: thisScanline size - 1 // 4 do: [ :i |
		| ii word |
		ii := i * 4.
		"This somewhat weird mixture of (#* and #+) with (#bitShift: and #bitOr:) 
		is to make use of faster arithmetic bytecodes, but not of slow largeintegers."
		word :=
			(((thisScanline at: ii + 1) * 256 + 
			(thisScanline at: ii + 2) * 256 + 
			(thisScanline at: ii + 3)) bitShift: 8) bitOr: 
			(thisScanline at: ii + 4).
		bits at: base + i put: word ].! !


More information about the Squeak-dev mailing list