Continuing issue using pointers etc...

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

Continuing issue using pointers etc...

Postby leopardpm » Jun 12, 2017 0:00

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: 3078
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Continuing issue using pointers etc...

Postby MrSwiss » Jun 12, 2017 0:45

@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: 1238
Joined: Jun 04, 2005 9:51

Re: Continuing issue using pointers etc...

Postby dafhi » Jun 12, 2017 1:28

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

Re: Continuing issue using pointers etc...

Postby leopardpm » Jun 12, 2017 2:54

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: 1764
Joined: Jan 02, 2017 0:34
Location: UK

Re: Continuing issue using pointers etc...

Postby deltarho[1859] » Jun 12, 2017 8:33

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

Postby Aethelstan » Jun 12, 2017 8:34

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: 3078
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Continuing issue using pointers etc...

Postby MrSwiss » Jun 12, 2017 11:52

@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: 1791
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Postby leopardpm » Jun 12, 2017 12:57

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: 1791
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Postby leopardpm » Jun 12, 2017 13:05

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: 1791
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Postby leopardpm » Jun 12, 2017 13:14

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: 1764
Joined: Jan 02, 2017 0:34
Location: UK

Re: Continuing issue using pointers etc...

Postby deltarho[1859] » Jun 12, 2017 13:21

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: 3078
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Continuing issue using pointers etc...

Postby MrSwiss » Jun 12, 2017 13:26

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: 1791
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Postby leopardpm » Jun 12, 2017 13:27

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: 3078
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Continuing issue using pointers etc...

Postby MrSwiss » Jun 12, 2017 13:34

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: 1791
Joined: Feb 28, 2009 20:58

Re: Continuing issue using pointers etc...

Postby leopardpm » Jun 12, 2017 13:36

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!

Return to “General”

Who is online

Users browsing this forum: No registered users and 3 guests