B4J Question Map Bug?

Discussion in 'B4J Questions' started by techknight, Aug 3, 2019.

  1. techknight

    techknight Well-Known Member Licensed User

    So encountered an issue that I cant figure out how to work around.

    So I am building an RGB palette index table. Easiest way is a Map, the RGB in hexstring as the Key, and the "index" as the value. so if I pass in the RGB, I can get the correct index back.

    Anyways, Here is my code:
    Code:
    'Load Radar Palette
        Dim PaletteString As String = File.ReadString(File.DirAssets, "Radar.pal")
        
    Dim RadarPalette() As String = Regex.Split("#", PaletteString.ToUpperCase)
        
    'Dim RGBVal As String
        RadarImagePalette.Initialize
        
    For I = 0 To RadarPalette.Length-1
            RadarImagePalette.Put(RadarPalette(I), I)
        
    Next
     
        
    For Each k As String In RadarImagePalette.Keys
            
    Log(k)
            
    Log(RadarImagePalette.Get(k))
        
    Next

        
    Dim k As String = "000000" 'This is one of the values stored as a Key.
        Log(RadarImagePalette.Get(k)) 'Returns Null
    Problem is, if I try to to a GET of anything, all I retrieve is null. No matter what RGB I try, that the routine above puts into the table. I did a Log in the loop to know that the key is there. But its not there...

    I attached my palette text file.

    any ideas?
     

    Attached Files:

  2. emexes

    emexes Well-Known Member Licensed User

    My first guess is that the key values are not 6 characters long. Pull on that thread ;-)
     
  3. Roycefer

    Roycefer Well-Known Member Licensed User

    Your text file has each item on its own line. That means each item is separated by a # and a CRLF. You are only splitting on # which means you are getting a CRLF at the end of each RadarPalette array item. Try this instead:
    Code:
    RadarImagePalette.Put(RadarPalette(I).Trim, I) 'this will remove the CRLF before adding it to your Map.
    In a broader context, consider storing your Maps with File.WriteMap and reading them with File.ReadMap instead of trying to split on Strings.
     
    Jorge M A likes this.
  4. emexes

    emexes Well-Known Member Licensed User

    Roycefer beat me to it, but try this anyway - effectively does the .Trim by filtering for hex digits/numbers only:
    Code:
    'Load Radar Palette
    Dim PaletteString As String = File.ReadString(File.DirAssets, "Radar.pal")

    Dim HexMatcher As Matcher = Regex.Matcher("[0-9a-fA-F]+", PaletteString)

    RadarImagePalette.Initialize
    Dim IndexNumber As Int = 0
    Do While HexMatcher.Find
        RadarImagePalette.Put(HexMatcher.Match.ToUpperCase, IndexNumber)
        IndexNumber = IndexNumber + 
    1
    Loop

    For Each k As String In RadarImagePalette.Keys
        
    Log(k)
        
    Log(RadarImagePalette.Get(k))
    Next

    Dim k As String = "000000" 'This is one of the values stored as a Key.
    Log(RadarImagePalette.Get(k)) 'Returns Null - YE OF LITTLE FAITH ;-)
     
    Last edited: Aug 4, 2019
  5. emexes

    emexes Well-Known Member Licensed User

    Or change the hex-number separator to be anything-but-hex:
    Code:
    Dim RadarPalette() As String = Regex.Split("[^0-9a-fA-F]+", PaletteString.ToUpperCase)
    edit: in fact, since the input string is obviously uppercase, you could even just:
    Code:
    Dim RadarPalette() As String = Regex.Split("[^0-9A-F]+", PaletteString.ToUpperCase)
     
  6. techknight

    techknight Well-Known Member Licensed User

    Thanks for the ideas and programming efficiency thoughts. Ultimately, the CrLF was the problem.

    It took me a complete re-write to get away from Maps and indexes to a plain Array just to figure that one out. LOL..... anyways, live and learn.

    BTW the txt/pal file was generated by the Palette Export in GIMP, so thats how it puts out the files natively.
     
    emexes likes this.
  7. Roycefer

    Roycefer Well-Known Member Licensed User

    In that case, you should use File.ReadList. It will give you a list of lines.
     
  8. techknight

    techknight Well-Known Member Licensed User

    But the # needs to go as well, thats why I was doing the split.
     
  9. emexes

    emexes Well-Known Member Licensed User

    While we're doing another lap on this topic, I'd like to present a revised one-line-change solution:
    Code:
    Dim RadarPalette() As String = Regex.Split("[^0-9A-F]+""#" & PaletteString.ToUpperCase & "#")
    since the previous suggestion would return empty strings in the first and/or last elements of RadarPalette if there was a leading and/or trailing separator.

    By adding a separator character front and back, we have made the situation more constant: the first and last elements are now *always* empty, and thus the actual palette is in elements 1..RadarPalette.Length-2 rather than the more usual/expected 0..RadarPalette.Length-1

    edit: then I realised this is actually a three-line-change solution, because we need to update the For..Next loop and the Map Key, eg:
    Code:
    For I = 1 To RadarPalette.Length - 2    'skip first and last elements since always empty
        RadarImagePalette.Put(RadarPalette(I - 1), I - 1)    'array and palette both zero-based, hence "- 1" for each
    Next
    Spewin!

    But I'm not feeling too guilty, because the same problem would have been occurring with the original Regex.Split too :-/
     
    Last edited: Aug 5, 2019
  10. techknight

    techknight Well-Known Member Licensed User

    Well at least now I know there are multiple ways to skin a cat!

    Anyways, the utility that does this takes an indexed GIF image and converts it into binary pixel array of index values. and the palette itself is extracted.

    This gets sent to an older index color-based genlock graphics card run by a microcontroller.
     
    emexes likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice