Shop OBEX P1 Docs P2 Docs Learn Events
PASM - Averaging Bytes within Longs — Parallax Forums

PASM - Averaging Bytes within Longs

lanternfishlanternfish Posts: 366
edited 2010-12-08 18:30 in Propeller 1
What I need to do is average the same byte within two longs e.g. (byte 0 (bits 0 - 7) of long 1 + byte 0 (bits 0 - 7) of long 2)/2

Attached is some code that works so my question is Can it be done more efficiently?
{{Average Bytes within 2 Longs}}
{
 Data Format:           Long1   %00000000_00rrrrrr_00gggggg_00bbbbbb
                        Long2   %00000000_00rrrrrr_00gggggg_00bbbbbb
                        
                      Answer1   %00000000_00rrrrrr_00gggggg_00bbbbbb
                                  Byte 3   Byte 2   Byte 1   Byte 0
 }
PUB Main
 {Launch COG}

  coginit(0, @AverageRGB, 0) 'Launch COG 0

CON

 _clkmode = xtal1 + pll16x
 _xinfreq = 5_000_000

DAT
                        org 0

AverageRGB
                        mov     Answer1, #0                           'Clear Answer Long
                        mov     RGB1, PseudoIna                       '1st RGB Value              
                        mov     RGB2, PseudoInb                       '2nd RGB Value
                        add     Answer1, RGB1                         'Add RGB Values
                        add     Answer1, RGB2

                        mov     RedValue, Answer1                     'To get Red level (byte 2),
                        and     RedValue, RedMask                     'Mask of bytes 3,1,0
                        shr     RedValue, #17                         'To average Red value shift into lowest byte of long
                        shl     RedValue, #16                         'plus one more bit. And then shift back to byte 2 
                        
                        mov     GreenValue, Answer1                   'To get Green level (byte 1), 
                        and     GreenValue, GreenMask                 'Mask of bytes 3,2,0 
                        shr     GreenValue, #9                        'To average Green value shift right lowest byte of long
                        shl     GreenValue, #8                        'plus one more bit. And then shift back to byte 1
                        
                        mov     BlueValue, Answer1                    'To get Blue level (byte 0),
                        and     BlueValue, BlueMask                   'Mask of bytes 3,2,1 
                        shr     BlueValue, #1                         'To average Blue value shift right one bit
 

                        mov     Answer1, #0                           'Clear Answer Long
                        add     Answer1, RedValue                     'Add Red, Green & Blue Values
                        add     Answer1, BlueValue                    'to get 
                        add     Answer1, GreenValue
                      
ForeverLoop            jmp     #ForeverLoop

{Variables}

RGB1                    long 0
RGB2                    long 0
Answer1                 long 0
RedValue                long 0
GreenValue              long 0
BlueValue               long 0


{Constants}

PseudoIna               long %00000000_00000000_00001111_00111111     
PseudoInb               long %00000000_00111111_00110000_00000000
RedMask                 long $00_FF_00_00
GreenMask               long $00_00_FF_00
BlueMask                long $00_00_00_FF
        

My maths brain is missing a few neurons at the moment so any pointer in a better direction will be most appreciated.

Comments

  • mparkmpark Posts: 1,305
    edited 2010-12-08 18:08
    If you know each byte won't exceed 63 (as your comment implies), then yes: add long1 and long2, shift the result right by 1, then and with $7f7f7f7f.
  • kuronekokuroneko Posts: 3,623
    edited 2010-12-08 18:09
    What's wrong with this (as you used to do previously although without masking)?
    DAT
                    mov     temp, RGB1              ' keep RGB1 
                    add     temp, RGB2              ' RGB1 + RGB2
                    shr     temp, #1                ' (RGB1 + RGB2)/2
                    and     temp, mask              ' clean up
    
    mask            long    %00000000_00111111_00111111_00111111
    

    Edit: One reason (for me) to delete a post (now being redundant). And you can't **** do it any more.
  • lanternfishlanternfish Posts: 366
    edited 2010-12-08 18:30
    @ mpark and @ kuroneko

    Thanks so much for that. I knew I was making it more difficult than it needed to be - the obvious was staring me in the face.
Sign In or Register to comment.