[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
|