Continuing issue using pointers etc...

General FreeBASIC programming questions.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Continuing issue using pointers etc...

Post by leopardpm »

I have continual issues trying to work with pointers, can't seem to get a handle on using them correctly. Here is my routines goal:

Iterate through a RGBA image, ignoring any fully transparent pixels, and counting up each of the 'strips' of non-transparent pixels. It is supposed to encode the image into an allocated block of memory (32 bit RGBA elements).

The data in the encoded block of memory would be organized like this:
Every 'strip' would begin with a 'fake' RGBA element which would have:
... 'R' = x location
... 'G' = y location
... 'B' = length of strip (number of pixels)
... 'A' = 00 (fully transparent)
the R & G (x & y locations) are offsets to 'where' this strip is located in the image

so, in this example 'image', I am using letters to denote RGBA elements (lets say 'T' = fully transparent, 'Q' = some color, 'Z' = some color):
TTTTTTTTTT <--- 10 pixels of transparent
TQQZQQTTTT <--- 10 pixels, first pixel transparent, last 4 pixels transparent
QZZZZZQQQT <--- 10 pixels, only last one Transparent
TQZTTTQTTZ <--- 10 pixels, some Trans, some not...

This example image would be encoded like this into the buffer (each 'fake' RGBA pixel will be a red number in this example, with a key at the end):
buffer = 1QQZQQ2QZZZZZQQQ3QZ4Q5Z6
Fake RGBA pixels (1-6) look like this:
1: R=1,G=1,B=5,A=0 meaning 'next strip starts at 1,1 and has 5 pixels'
2: R=0,G=2,B=9,A=0 meaning 'next strip starts at 0,2 and has 9 pixels'
3: R=1,G=3,B=2,A=0 meaning 'next strip starts at 1,3 and has 2 pixels'
4: R=6,G=3,B=1,A=0 meaning 'next strip starts at 6,3 and has 1 pixel'
5: R=9,G=3,B=1,A=0 meaning 'next strip starts at 9,3 and has 1 pixel'
6: R=255,G=255,B=255,A=0 meaning 'end of image'

there is ONE special case though: when a row 'ends' with a non-trans pixel and the next row begins with a non-trans pixel, then make sure to break this up into 2 strips, not one continuous one. This special case can occur because of the way I am iterating through the image and would not be an issue if I used a different method.

here is my code, forgive me:

Code: Select all

    Dim SS1_buffer As ulongPtr = CAllocate(ImageWidth*ImageHeight,4)
    
'-------------------------------------------------------------------------------
sub EncodeSpeedSprite_Ver1(img as any ptr, buffer as any ptr)
    ' This version just iterates through the image, copying over the RGBA values to the buffer,
    ' EXCEPT if the value has an Alpha of '0' (totally transparent) in which case it finds the
    ' next non-transparent pixel and saves this location in the R & G (x & y respectively) of
    ' the copied over transparent pixel... basically RLE's only the transparent pixels...
    '
    ' MUST CAllocate enough space into buffer before calling!
    '
    dim as ulong buf_index = 0, tranny = 0, reggy = 0, last_tranny = 0
    dim as ulong TempColor
    
    For y As ulong = 0 To ImageHeight - 1
        Dim row As ulong Ptr = ImageAddress + y * ImagePitch
        For x As ulong = 0 To ImageWidth - 1
            TempColor = row[x]
            if RGBA_A(TempColor) = 0 then
                ' if transparent then...count it
                tranny += 1
                if tranny = 1 then ' .. if first tranny then stop counting reggy and save it!
                    ' --- hopefully it is grabbing 4 bytes (32 bit) value here...???
                    TempColor = buffer[last_tranny]
                    ' this next line assumes that reggy is less than 255 - all the pixels on same line...
                    buffer[last_tranny] = rgba(RGB_R(TempColor),RGB_G(TempColor),reggy,0)
                    reggy = 0
                end if
                
            else
                ' if NOT transparent, then....
                if tranny > 0 then ' if currently counting transparent pixels...
                    ' then ran into a regular pixel... so make the Transparent coded pixel...
                    buf_index += 1
                    last_tranny = buf_index
                    buffer[buf_index] = rgba(x,y,0,0)
                    tranny = 0
                end if
                ' just a regular pixel color, so save it into buffer
                buf_index += 1
                reggy += 1
                buffer[buf_index] = TempColor
            end if
        next x
        if reggy > 0 then 'was still accumulating regular pixels when hit end of line.
            ' so make the last trans pixel say only reggy amount of pixels and make new trans pix for next line...
            TempColor = buffer[last_tranny] '--- hopefully it is grabbing 4 bytes (32 bit) value here...???
            ' this next line assumes that reggy is less than 255 - all the pixels on same line...
            buffer[last_tranny] = rgba(RGB_R(TempColor),RGB_G(TempColor),reggy,0)
            reggy = 0
            dim as ulong hold_y = y+1
            if hold_y < ImageHeight then
                buf_index += 1
                buffer[buf_index] = rgba(0,y+1,0,0) ' new trans pixel pointing to beginning of next line
                last_tranny = buf_index
            end if
        end if
    next y
    ' put in 'end of sprite' delimiter...
    buf_index += 1
    buffer[buf_index] = rgba(255,255,255,0) ' no other color in buffer will be transparent white...
end sub
the errors I get are LOTS of 'incomplete type' errors, everywhere I am trying to refer to an element in the buffer, like in this line:

Code: Select all

TempColor = buffer[last_tranny]
the error I get for this line is "error 70: Incomplete type in 'TempColor = buffer' "
Last edited by leopardpm on Jun 12, 2017 3:05, edited 2 times in total.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Continuing issue using pointers etc...

Post by MrSwiss »

@leopardpm,

do yourself a favour, and give this "stone-age" Manual (Help-File), a kick in the butt.
latest freebasic_manual.chm here ... 2017-06-05 (today's check)
FreeBASIC-Manual (current-online) wrote:ULONG
Standard data type: 32-bit unsigned integer.
Equivalent to Unsigned Long.

Syntax:
dim variable as Ulong

Description:
32-bit unsigned whole-number data type. Can hold values from 0 to 4294967295. Corresponds to an unsigned DWORD.
That's just for starters ...

array access is usually: arr_name(element)
where element is the index of the array-element

pointer access is usually: pointer[index] (if pointer points to array, only "typed" pointers, not Any Ptr)
or pointer->member (if pointer points to a Type)
...
Last edited by MrSwiss on Jun 12, 2017 1:30, edited 1 time in total.
dafhi
Posts: 1641
Joined: Jun 04, 2005 9:51

Re: Continuing issue using pointers etc...

Post by dafhi »

the integer type is 8 bytes with 64 bit compiler. ulongint = 8 and ulong = 4 bytes
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Post by leopardpm »

dafhi wrote:the integer type is 8 bytes with 64 bit compiler. ulongint = 8 and ulong = 4 bytes
that is part of what gets me confused... I prefer using integers for RGBA values, so i try to use ulongint.. but is 8 bytes... something about ulong being floating point disturbs me, even though there is probably no real issue..wait, according to Mr Swiss's manual, it isnt floating point, is integer...dang it, ok...I will chane all my uintegers to ulongs and update the code, but that won't fix the issue i fear...
do yourself a favour, and give this "stone-age" Manual (Help-File), a kick in the butt.
latest freebasic_manual.chm here ... 2017-06-05 (today's check)
I agree, but it is so dang conveinent to use the included help, just hit F1 and boom, whatever command the cursor is on shows up in help... I have been trying to use the FBwiki manual (http://www.freebasic.net/wiki/wikka.php?wakka=FBWiki) but isn't as easy... lazy me pays for it with time lost debugging wrong command descriptions...

oops, forgot to show my CAllocate statement in the above code... fixed now... but same errors

Code: Select all

    Dim SS1_buffer As uinteger Ptr = CAllocate(ImageWidth*ImageHeight,4)
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Continuing issue using pointers etc...

Post by deltarho[1859] »

just hit F1 and boom, whatever command the cursor is on shows up in help
I didn't know that - thank you.

At the bottom of the manual's 'Table of Contents' page is a compilation date. The chm which came with my FBIde reads 'This document last compiled : 2011-08-07 01:15:09'. The one that I am currently using reads 'This document last compiled : 2017.05.28 03:49:53'.

If you get the latest version just point FBIde at it in the 'View > Settings > FreeBASIC' tab. Mine points to 'F:\Downloads\FB-manual-1.05.0-chm\freebasic_manual.chm'.

Added: Mine now reads 'This document last compiled : 2017.06.05 03:52:00' <smile>
Last edited by deltarho[1859] on Jun 12, 2017 8:38, edited 1 time in total.
Aethelstan
Posts: 19
Joined: Feb 22, 2017 18:34

Re: Continuing issue using pointers etc...

Post by Aethelstan »

leopardpm wrote:
dafhi wrote:the integer type is 8 bytes with 64 bit compiler. ulongint = 8 and ulong = 4 bytes
that is part of what gets me confused...
Using ULong is just a safe way of telling a compiler: "give me a 4 byte unsigned integer, no matter what is your processor architecture". This should make it less confusing, I think :)

About your errors: have you tried this method of sending parameters to procedure: (?)

Code: Select all

sub EncodeSpeedSprite_Ver1(img as ULong ptr, buffer as ULong ptr)
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Continuing issue using pointers etc...

Post by MrSwiss »

@leopardpm,

just a reminder, color = 32bit = ULong (always, max. size), you can only go lower: 8, 16 etc.

Code: Select all

Dim SS1_buffer As uinteger Ptr = CAllocate(ImageWidth*ImageHeight,4)  ' clearly a case of "wrong variable"
/' OK '/    Dim SS1_buffer As ULong Ptr = CAllocate(ImageWidth * ImageHeight, SizeOf(ULong))
Careful here because,
this buffer can only be used for "raw" image-data, without header etc. otherwise, use ImageCreate ...

Second remark:
If you want to be able, to access the single color-channels (without pointer casting), you might want
to use a Union:

Code: Select all

Union Colour  ' BE = OK
    As ULong clr
    Type
        As UByte b
        As UByte g
        As UByte r
        AS UByte a
    End Type
End Union
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Post by leopardpm »

Aethelstan wrote:About your errors: have you tried this method of sending parameters to procedure: (?)

Code: Select all

sub EncodeSpeedSprite_Ver1(img as ULong ptr, buffer as ULong ptr)
it works now... img has to be an 'any ptr' because it points to an FB image format, but changing buffer to a ulong ptr i think made it work! And even more importantly, my code runs correctly on the first try - no logic errors, YAY!

Thanks all!
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Post by leopardpm »

deltarho[1859] wrote:
just hit F1 and boom, whatever command the cursor is on shows up in help
I didn't know that - thank you.

At the bottom of the manual's 'Table of Contents' page is a compilation date. The chm which came with my FBIde reads 'This document last compiled : 2011-08-07 01:15:09'. The one that I am currently using reads 'This document last compiled : 2017.05.28 03:49:53'.

If you get the latest version just point FBIde at it in the 'View > Settings > FreeBASIC' tab. Mine points to 'F:\Downloads\FB-manual-1.05.0-chm\freebasic_manual.chm'.

Added: Mine now reads 'This document last compiled : 2017.06.05 03:52:00' <smile>
tricky! I downloaded freebasic_manual.chm, then pointed fbide to it, and it loads it.. but doesn't show info.... maybe if i restart fbide? will try that where did you get the "freebasic_manual.chm"? I downloaded from the site that Mr. Swiss referenced above... perhaps is wrong place?
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Post by leopardpm »

Second pointer question:
here is the simple code-

Code: Select all

sub BasicBlit(img as any ptr, dx as ulong, dy as ulong)
' BasicBlit is just a pset
    dim as ulong sy = 0, sy_end = ImageHeight * ImagePitch, sdy = dy * SCR_pitch, numBytes = ImageWidth * 4
    dim as any ptr drowy = SCR_address + dx * 4
    do
        srow = ImageAddress + sy
        drow = drowy + sdy
            memcpy (drow, srow, numBytes) ' = ImageWidth pixels x 4 bytes each
        sy += ImagePitch
        sdy += SCR_pitch
    loop until sy > sy_end
end sub
for the life of me I cannot figure out how to get the pointer statements (srow = imageaddress +sy, drow = drowy +sdy) to combine with my increment statements (sy += ImagePitch, sdy += SCR_pitch)... I should be able to get rid of one addition per statement by combining these, that would be two less additions per loop which could be a significant speed increase... but every time I try to make a combo statement it gives me an error because I just do not know pointers 'intuitively' ...YET!

for instance, here is my 'attempt':

Code: Select all

sub BasicBlit(img as any ptr, dx as ulong, dy as ulong)
' BasicBlit is just a pset
    dim as ulong sy = 0, sy_end = ImageHeight * ImagePitch, sdy = dy * SCR_pitch, numBytes = ImageWidth * 4
    dim as any ptr drowy = SCR_address + dx * 4
    dim as ulong ptr image_end
    dim as ulong ptr srow, drow

    srow = ImageAddress
    drow = SCR_address + (dx * 4)
    image_end = ImageAddress + (ImageHeight * ImagePitch)
    do
'        srow = ImageAddress + sy
'        drow = drowy + sdy
        memcpy (drow, srow, numBytes) ' = ImageWidth pixels x 4 bytes each
'        sy += ImagePitch
'        sdy += SCR_pitch
        srow += ImagePitch
        drow += SCR_pitch
    loop until srow > sy_end
end sub
Last edited by leopardpm on Jun 12, 2017 13:28, edited 1 time in total.
deltarho[1859]
Posts: 4292
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Continuing issue using pointers etc...

Post by deltarho[1859] »

where did you get the "freebasic_manual.chm"?
At MrSwiss' link opening page, third line from the bottom.
but doesn't show info
What does show?
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Continuing issue using pointers etc...

Post by MrSwiss »

Mr. Swiss referenced above... perhaps is wrong place?
No, it is the "only"place! <lol>
It's the <german> FreeBASIC - Webpages, St_W's build Server (also there: "nightly" Compiler builds).
These occur, when there is a change in the source, detected (trigger mechanism).
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Post by leopardpm »

deltarho[1859] wrote:
where did you get the "freebasic_manual.chm"?
At MrSwiss' link opening page, third line from the bottom.
ok, that is the one I downloaded...good
but doesn't show info
What does show?
it shows the index and all that stuff correctly on the left... but when I click anything, or type a command, the big 'info box' on the right is always blank... no info
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Continuing issue using pointers etc...

Post by MrSwiss »

You might have to "unlock" the file first:
right click it,
choose properties,
look for: small check box (lower right corner)
uncheck
press apply button
Another, rather sensless "M$ security" issue ...
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Post by leopardpm »

MrSwiss wrote:@leopardpm,

just a reminder, color = 32bit = ULong (always, max. size), you can only go lower: 8, 16 etc.

Code: Select all

Dim SS1_buffer As uinteger Ptr = CAllocate(ImageWidth*ImageHeight,4)  ' clearly a case of "wrong variable"
/' OK '/    Dim SS1_buffer As ULong Ptr = CAllocate(ImageWidth * ImageHeight, SizeOf(ULong))
Careful here because,
this buffer can only be used for "raw" image-data, without header etc. otherwise, use ImageCreate ...
yes, I understand this. I am using the buffer as just raw data, not an image for FB to use, I will make the blit routine.
Second remark:
If you want to be able, to access the single color-channels (without pointer casting), you might want
to use a Union:

Code: Select all

Union Colour  ' BE = OK
    As ULong clr
    Type
        As UByte b
        As UByte g
        As UByte r
        AS UByte a
    End Type
End Union
I ALWAYS forget about this 'union' trick - it is genius - thanks for reminding me, Mr Swiss!
Post Reply