[Pharo-project] Issue 3661 in pharo: fixed the calculation of base in PNGReadWriter>>copyPixelsGray: (floor vs ceil)

pharo at googlecode.com pharo at googlecode.com
Sun Feb 6 09:54:12 CET 2011


Status: FixedWaitingToBePharoed
Owner: stephane... at gmail.com
Labels: Milestone-1.3 Type-Squeak

New issue 3661 by stephane... at gmail.com: fixed the calculation of base in  
PNGReadWriter>>copyPixelsGray: (floor vs ceil)
http://code.google.com/p/pharo/issues/detail?id=3661


Name: Graphics-ul.177
Author: ul
Time: 5 February 2011, 4:53:19.27 am
UUID: dfac9cf3-85a4-3c4b-9256-1c8214f36fe6
Ancestors: Graphics-nice.176

- fixed the calculation of base in PNGReadWriter>>copyPixelsGray: (floor vs  
ceil)

=============== Diff against Graphics-nice.176 ===============

Item was changed:
  ----- Method: PNGReadWriter>>copyPixelsGray: (in category 'pixel copies')  
-----
  copyPixelsGray: y
        "Handle non-interlaced grayscale color mode (colorType = 0)"

        | base bits bytesLeft word |
        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 Smalltalk version might be easier to understand than the  
others below."
+       base := y * (form width * bitsPerChannel + 31 // 32) + 1.
-       base := y * form width * bitsPerChannel // 32 + 1.
        bits := form bits.
        0 to: thisScanline size // 4 - 1 do: [ :i |
                | ii |
                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 ].
        (bytesLeft := thisScanline size bitAnd: 3) = 0 ifFalse: [
                word := 0.
                thisScanline size - bytesLeft + 1 to: thisScanline size do:  
[ :ii |
                        word := word * 256 + (thisScanline at: ii) ].
                word := word bitShift: 8 * (4 - bytesLeft).
                bits at: base + (thisScanline size // 4) put: word ].

        "This interesting technique (By Andreas Raab) is faster for very  
large images, but might be slower for small ones"
        "^self copyPixelsGrayWeirdBitBltHack: y ".
        "It uses the following method:
        PNGReadWriter >> copyPixelsGrayWeirdBitBltHack: y
        ""Handle non-interlaced black and white color mode (colorType = 0)
        By Andreas Raab""

        | source dest cmap |
        source := Form extent: 1 @ (thisScanline size // 4) depth: 32 bits:  
thisScanline.
        dest := Form extent: 1 @ (form bits size) depth: 32 bits: form bits.
        cmap := Smalltalk isLittleEndian
                ifTrue:[ColorMap
                                        shifts: #(-24 -8 8 24)
                                        masks: #(16rFF000000 16r00FF0000  
16r0000FF00 16r000000FF)].
        (BitBlt toForm: dest)
                sourceForm: source;
                destX: 0 destY: (y * form width*bitsPerChannel//32) width: 1  
height: (form width+31*bitsPerChannel//32);
                colorMap: cmap;
                combinationRule: 3;
                copyBits."

        "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)".
        "It uses the following method:
        BitMap >> copyFromByteArray2: byteArray to: i
        ""This method should work with either byte orderings""

        | myHack byteHack |
        myHack := Form new hackBits: self.
        byteHack := Form new hackBits: byteArray.
        Smalltalk  isLittleEndian ifTrue: [byteHack swapEndianness].
        byteHack displayOn: myHack at:  0 at i"!






More information about the Pharo-project mailing list