Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Detecting color depth-16 color, 256 color, or 32 bit color
#11
(08-16-2024, 06:48 PM)bplus Wrote:
(08-16-2024, 05:52 PM)dano Wrote: Thank you.  Does this also mean that there is an easy way to read the current foreground and background colors regardless of the SCREEN setting or 16/256/32bit color?

_DefaultColor and _BackgroundColor

Slow.   Slow.  Big Grin
Reply
#12
(08-16-2024, 06:49 PM)SMcNeill Wrote:
(08-16-2024, 06:48 PM)bplus Wrote:
(08-16-2024, 05:52 PM)dano Wrote: Thank you.  Does this also mean that there is an easy way to read the current foreground and background colors regardless of the SCREEN setting or 16/256/32bit color?

_DefaultColor and _BackgroundColor

Slow.   Slow.  Big Grin

I had to lookup _DefaultColor, I keep wanting to call it _ForegroundColor.
b = b + ...
Reply
#13
I turned Steve's code into a useful function that I just added to my goodies library:

Code: (Select All)
DIM a(4)
a(1) = _NEWIMAGE(640, 480, 32) '  32 bit color
a(2) = _NEWIMAGE(640, 480, 256) ' 256 color
a(3) = _NEWIMAGE(640, 480, 12) '  16 color
a(4) = _NEWIMAGE(80, 25, 0) '    text (16 color)

PRINT IMG_ColorDepth(a(1)) ' 32 bit color return
PRINT IMG_ColorDepth(a(2)) ' 256 color return
PRINT IMG_ColorDepth(a(3)) ' 16 color return
PRINT IMG_ColorDepth(a(4)) ' text color return

'PRINT IMG_ColorDepth(-30) ' this line will cause the error described in the function's documentation


FUNCTION IMG_ColorDepth% (i AS LONG)

    '+------------------------------------------------+
    '| Returns the color depth of an image passed in. |
    '|                                                |
    '| i - the image handle                          |
    '|                                                |
    '| Returns:  0 : not an image                    |
    '|          32 : 32 bit color image              |
    '|          256 : 256 color image                |
    '|          16 : 16 color image (or text only)  |
    '|                                                |
    '| Note: this function will fail if an image      |
    '|      handle value passed in is less than -1  |
    '|      but does not belong to an actual image.  |
    '+------------------------------------------------+

    DIM c AS INTEGER ' color counter
    DIM p AS INTEGER ' palette counter

    IF i > -2 THEN EXIT FUNCTION '                                not an image, return 0
    IF _PIXELSIZE(i) = 4 THEN '                                  4 bytes per pixel?
        IMG_ColorDepth% = 32 '                                    yes, 32 bit color image
    ELSE '                                                        no, 1 byte per pixel
        p = 0 '                                                  reset palette counter
        c = 0 '                                                  reset color counter
        DO '                                                      begin palette search
            IF _PALETTECOLOR(p, i) <> &HFF000000 THEN c = c + 1 ' increment color counter if color found
            p = p + 1 '                                          increment palette counter
        LOOP UNTIL p = 256 '                                      leave when entire palette searched

        IF c <= 16 THEN '                                        16 colors or less?
            IMG_ColorDepth% = 16 '                                yes, 16 color image
        ELSE '                                                    no, greater than 16
            IMG_ColorDepth% = 256 '                              256 color image
        END IF
    END IF

END FUNCTION
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#14
Set a flag.  That checks for 16 NON-BLACK colors.

If theres a black in those first palette entries, and then 16 other colors, that's NOT a 16-color palette.

For example:

Black
Red
Blue
Green
White
Black * 250

The above would count as 4 non-black colors, but there's a valid Black in the 5-color palette.  I wouldn't call that a 4-color image.

The <= 16 check is for:
  standard 16 color palette (black + 15 others)
OR
  non-black palette (someone swapped black for midnight blue.)

But it's going to glitch with:
  Black + 16 other colors, which is actually a 17-color palette and probably a 256 color image.



Subtle glitch, but one that a library function should account for.  You never know who or where a library ends up being exposed to.  Wink
Reply
#15
(08-16-2024, 09:26 PM)SMcNeill Wrote: Set a flag.  That checks for 16 NON-BLACK colors.

If theres a black in those first palette entries, and then 16 other colors, that's NOT a 16-color palette.

For example:

Black
Red
Blue
Green
White
Black * 250

The above would count as 4 non-black colors, but there's a valid Black in the 5-color palette.  I wouldn't call that a 4-color image.

The <= 16 check is for:
  standard 16 color palette (black + 15 others)
OR
  non-black palette (someone swapped black for midnight blue.)

But it's going to glitch with:
  Black + 16 other colors, which is actually a 17-color palette and probably a 256 color image.



Subtle glitch, but one that a library function should account for.  You never know who or where a library ends up being exposed to.  Wink
I think I'm getting dense in my old age. I've re-read this a few times and can't wrap my head around what you are getting at. Isn't the variable c already counting the valid colors?

Could you modify the function I created that shows the code you are referring to that needs to be added?
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#16
On another thread we were discussing the use of ON ERROR to capture when a non image negative value was sent. There's now an associated .BI file that needs to go along with the function.

Here is some example code (ColorDepthTest.BAS):

Code: (Select All)
'$INCLUDE:'lib_img_colordepth.bi'  IMG_ColorDepth function

Image& = _NEWIMAGE(640, 480, 32) ' valid image
PRINT IMG_ColorDepth(Image&) '    valid image
PRINT IMG_ColorDepth(-30) '        invalid image

'$INCLUDE:'lib_img_colordepth.bm'  IMG_ColorDepth function

Here is LIB_IMG_ColorDepth.BI:

Code: (Select All)

'LIB_IMG_ColorDepth.BI

DIM SHARED ColorDepthError AS INTEGER
COLORDEPTH_BIFILE:
IF ERR THEN
    ColorDepthError = ERR
    RESUME NEXT
END IF

And here is LIB_IMG_ColorDepth.BM:

Code: (Select All)

'LIB_IMG_ColorDepth.BM

FUNCTION IMG_ColorDepth% (i AS LONG)

    '+----------------------------------------------------------------------------+
    '| Returns the color depth of an image passed in.                            |
    '|                                                                            |
    '| i - the image handle                                                      |
    '|                                                                            |
    '| Returns:  0 : not an image                                                |
    '|          32 : 32 bit color image                                          |
    '|          256 : 256 color image                                            |
    '|          16 : 16 color image (or text only)                              |
    '|                                                                            |
    '| Note: this function was created from example code provided by SMcNeill at: |
    '|      https://qb64phoenix.com/forum/showthread.php?tid=2950                |
    '+----------------------------------------------------------------------------+

    DIM c AS INTEGER ' color counter
    DIM p AS INTEGER ' palette counter

    IF i > -2 THEN EXIT FUNCTION '                                not an image, return 0
    ON ERROR GOTO COLORDEPTH_BIFILE '                            use error handler in .BI file
    IF _PIXELSIZE(i) = 4 THEN '                                  4 bytes per pixel?
        IF ColorDepthError THEN '                                did _PIXELSIZE generate an error?
            ColorDepthError = 0 '                                yes, reset error flag
            IMG_ColorDepth% = 0 '                                return 0 (not an image)
            ON ERROR GOTO 0 '                                    remove ON ERROR redirection
            EXIT FUNCTION '                                      leave function
        END IF
        IMG_ColorDepth% = 32 '                                    yes, 32 bit color image
    ELSE '                                                        no, 1 byte per pixel
        p = 0 '                                                  reset palette counter
        c = 0 '                                                  reset color counter
        DO '                                                      begin palette search
            IF _PALETTECOLOR(p, i) <> &HFF000000 THEN c = c + 1 ' increment color counter if color found
            p = p + 1 '                                          increment palette counter
        LOOP UNTIL p = 256 '                                      leave when entire palette searched
        IF c <= 16 THEN '                                        16 colors or less?
            IMG_ColorDepth% = 16 '                                yes, 16 color image
        ELSE '                                                    no, greater than 16
            IMG_ColorDepth% = 256 '                              256 color image
        END IF
    END IF
    ON ERROR GOTO 0 '                                            remove ON ERROR redirection

END FUNCTION
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#17
(08-16-2024, 09:38 PM)TerryRitchie Wrote:
(08-16-2024, 09:26 PM)SMcNeill Wrote: Set a flag.  That checks for 16 NON-BLACK colors.

If theres a black in those first palette entries, and then 16 other colors, that's NOT a 16-color palette.

For example:

Black
Red
Blue
Green
White
Black * 250

The above would count as 4 non-black colors, but there's a valid Black in the 5-color palette.  I wouldn't call that a 4-color image.

The <= 16 check is for:
  standard 16 color palette (black + 15 others)
OR
  non-black palette (someone swapped black for midnight blue.)

But it's going to glitch with:
  Black + 16 other colors, which is actually a 17-color palette and probably a 256 color image.



Subtle glitch, but one that a library function should account for.  You never know who or where a library ends up being exposed to.  Wink
I think I'm getting dense in my old age. I've re-read this a few times and can't wrap my head around what you are getting at. Isn't the variable c already counting the valid colors?

Could you modify the function I created that shows the code you are referring to that needs to be added?

It's counting NON-BLACK colors:

IF _PALETTECOLOR(p, i) <> &HFF000000     <--- This line right here.   &HFF000000 is full alpha black.  If the palette we're using isn't a black color then... we count a color.   But, what if the color IS black?   it never gets counted.   

Try this example with the glitch.  I'll zap up a fix in a bit, but this highlights the issue for you, I think.  Wink

Code: (Select All)
Dim a(5)
a(1) = _NewImage(640, 480, 32) '  32 bit color
a(2) = _NewImage(640, 480, 256) ' 256 color
a(3) = _NewImage(640, 480, 12) '  16 color
a(4) = _NewImage(80, 25, 0) '    text (16 color)
a(5) = _NewImage(640, 480, 256) '256 colors, but with a very weird palette
For i = 17 To 255 'colors 17 to 255 are black
    _PaletteColor i, &HFF000000&&, a(5)
Next




Print IMG_ColorDepth(a(1)) ' 32 bit color return
Print IMG_ColorDepth(a(2)) ' 256 color return
Print IMG_ColorDepth(a(3)) ' 16 color return
Print IMG_ColorDepth(a(4)) ' text color return
Print IMG_ColorDepth(a(5)); " <--- Note here" ' 256 weird palette color return


'PRINT IMG_ColorDepth(-30) ' this line will cause the error described in the function's documentation
Function IMG_ColorDepth% (i As Long)
    '+------------------------------------------------+
    '| Returns the color depth of an image passed in. |
    '|                                                |
    '| i - the image handle                          |
    '|                                                |
    '| Returns:  0 : not an image                    |
    '|          32 : 32 bit color image              |
    '|          256 : 256 color image                |
    '|          16 : 16 color image (or text only)  |
    '|                                                |
    '| Note: this function will fail if an image      |
    '|      handle value passed in is less than -1  |
    '|      but does not belong to an actual image.  |
    '+------------------------------------------------+
    Dim c As Integer ' color counter
    Dim p As Integer ' palette counter
    If i > -2 Then Exit Function '                                not an image, return 0
    If _PixelSize(i) = 4 Then '                                  4 bytes per pixel?
        IMG_ColorDepth% = 32 '                                    yes, 32 bit color image
    Else '                                                        no, 1 byte per pixel
        p = 0 '                                                  reset palette counter
        c = 0 '                                                  reset color counter
        Do '                                                      begin palette search
            If _PaletteColor(p, i) <> &HFF000000 Then c = c + 1 ' increment color counter if color found
            p = p + 1 '                                          increment palette counter
        Loop Until p = 256 '                                      leave when entire palette searched
        If c <= 16 Then '                                        16 colors or less?
            IMG_ColorDepth% = 16 '                                yes, 16 color image
        Else '                                                    no, greater than 16
            IMG_ColorDepth% = 256 '                              256 color image
        End If
    End If
End Function
Reply
#18
@TerryRitchie  See if this helps showcase this one weird setup, that gives false positives that we can account for:

Code: (Select All)
Dim a(5)
a(1) = _NewImage(640, 480, 32) '  32 bit color
a(2) = _NewImage(640, 480, 256) ' 256 color
a(3) = _NewImage(640, 480, 12) '  16 color
a(4) = _NewImage(80, 25, 0) '    text (16 color)
a(5) = _NewImage(640, 480, 256) '256 colors, but with a very weird palette
For i = 18 To 255 'colors 18 to 255 are black
    _PaletteColor i, &HFF000000&&, a(5)
Next
'with the above, 0 is black .... it's not counted
'1 to 17 are colors.... that's 16 colors
'but we need to count that initial black to push it to being counted as a 17-color palette and not a false-16.



Print IMG_ColorDepth(a(1)) ' 32 bit color return
Print IMG_ColorDepth(a(2)) ' 256 color return
Print IMG_ColorDepth(a(3)) ' 16 color return
Print IMG_ColorDepth(a(4)) ' text color return
Print IMG_ColorDepth(a(5)); " <--- Note here" ' 256 weird palette color return


'PRINT IMG_ColorDepth(-30) ' this line will cause the error described in the function's documentation
Function IMG_ColorDepth% (i As Long)
    '+------------------------------------------------+
    '| Returns the color depth of an image passed in. |
    '|                                                |
    '| i - the image handle                          |
    '|                                                |
    '| Returns:  0 : not an image                    |
    '|          32 : 32 bit color image              |
    '|          256 : 256 color image                |
    '|          16 : 16 color image (or text only)  |
    '|                                                |
    '| Note: this function will fail if an image      |
    '|      handle value passed in is less than -1  |
    '|      but does not belong to an actual image.  |
    '+------------------------------------------------+
    Dim c As Integer ' color counter
    Dim p As Integer ' palette counter
    If i > -2 Then Exit Function '                                not an image, return 0
    If _PixelSize(i) = 4 Then '                                  4 bytes per pixel?
        IMG_ColorDepth% = 32 '                                    yes, 32 bit color image
    Else '                                                        no, 1 byte per pixel
        p = 0 '                                                  reset palette counter
        c = 0 '                                                  reset color counter
        Do '                                                      begin palette search
            If _PaletteColor(p, i) <> &HFF000000 Then
                c = c + 1 ' increment color counter if color found
            Else
                If black = 0 Then black = p 'first instance of a black color
            End If
            p = p + 1 '                                          increment palette counter
        Loop Until p = 256 '                                      leave when entire palette searched
        If c < 16 Then '                                        16 colors or less?
            IMG_ColorDepth% = 16 '                                yes, 16 color image
        ElseIf c = 16 Then 'we need to test for 16 with no-black, or 16 + black
            If black <= 16 Then 'it's an early black and part of the palette.  We have 17 color palette
                IMG_ColorDepth% = 256
            Else 'that first black is beyond the initial 16 colors, it's not part of the palette
                IMG_ColorDepth% = 16
            End If
        Else '                                                    no, greater than 16
            IMG_ColorDepth% = 256 '                              256 color image
        End If
    End If
End Function
Reply
#19
Ok, I now see what you were getting at. I incorporated the changes and here are the final results.

ColorDepthTest.BAS

Code: (Select All)
'$INCLUDE:'lib_img_colordepth.bi'  IMG_ColorDepth function

Image1& = _NEWIMAGE(640, 480, 32) '  valid 32 bit color image
Image2& = _NEWIMAGE(640, 480, 256) ' valid 256 color image with altered palette
Image3& = _NEWIMAGE(640, 480, 256) ' valid 256 color image with unaltered palette
Image4& = _NEWIMAGE(640, 480, 12) '  valid 16 color image (Qbasic SCREEN 12)

' Alter Image2&'s palette

FOR i = 18 TO 255 '                        colors 18 to 255 are black
    _PALETTECOLOR i, &HFF000000&&, Image2&
NEXT

PRINT IMG_ColorDepth(Image1&) '  valid 32 bit image image
PRINT IMG_ColorDepth(Image2&) '  valid 256 color image with altered palette
PRINT IMG_ColorDepth(Image3&) '  valid 256 color image with unaltered palette
PRINT IMG_ColorDepth(Image4&) '  valid 16 color image (Qbasic SCREEN 12)
PRINT IMG_ColorDepth(-30) '      invalid image

'$INCLUDE:'lib_img_colordepth.bm'  IMG_ColorDepth function

LIB_IMG_ColorDepth.BI

Code: (Select All)

'LIB_IMG_ColorDepth.BI

DIM SHARED ColorDepthError AS INTEGER
COLORDEPTH_BIFILE:
IF ERR THEN
    ColorDepthError = ERR
    RESUME NEXT
END IF

LIB_IMG_ColorDepth.BM

Code: (Select All)

'LIB_IMG_ColorDepth.BM

FUNCTION IMG_ColorDepth% (i AS LONG)

    '+----------------------------------------------------------------------------+
    '| Returns the color depth of an image passed in.                            |
    '|                                                                            |
    '| i - the image handle                                                      |
    '|                                                                            |
    '| Returns:  0 : not an image                                                |
    '|          32 : 32 bit color image                                          |
    '|          256 : 256 color image                                            |
    '|          16 : 16 color image (or text only)                              |
    '|                                                                            |
    '| Note: this function was created from example code provided by SMcNeill at: |
    '|      https://qb64phoenix.com/forum/showthread.php?tid=2950                |
    '+----------------------------------------------------------------------------+

    DIM c AS INTEGER '  color counter
    DIM p AS INTEGER '  palette counter
    DIM fb AS INTEGER ' first black seen

    IF i > -2 THEN EXIT FUNCTION '                                not an image, return 0
    ON ERROR GOTO COLORDEPTH_BIFILE '                            use error handler in .BI file
    IF _PIXELSIZE(i) = 4 THEN '                                  4 bytes per pixel?
        IF ColorDepthError THEN '                                did _PIXELSIZE generate an error?
            ColorDepthError = 0 '                                yes, reset error flag
            IMG_ColorDepth% = 0 '                                return 0 (not an image)
            ON ERROR GOTO 0 '                                    remove ON ERROR redirection
            EXIT FUNCTION '                                      leave function
        END IF

        ' ----------------------------------------
        '| 4 bytes per pixel means a 32 bit image |
        ' ----------------------------------------

        IMG_ColorDepth% = 32 '                                    this is a 32 bit color image
    ELSE '                                                        no, 1 byte per pixel
        p = 0 '                                                  reset palette counter
        c = 0 '                                                  reset color counter
        fb = 0 '                                                  reset first black seen
        DO '                                                      begin palette search
            IF _PALETTECOLOR(p, i) <> &HFF000000 THEN '          color here?
                c = c + 1 '                                      yes, increment color counter
            ELSE '                                                no, black found
                IF fb = 0 THEN fb = p '                          record first instance of black seen
            END IF
            p = p + 1 '                                          increment palette counter
        LOOP UNTIL p = 256 '                                      leave when entire palette searched
        IF c < 16 THEN '                                          less than 16 colors?

            ' ---------------------------
            '| Less than 16 colors found |
            ' ---------------------------

            IMG_ColorDepth% = 16 '                                yes, 16 color image
        ELSEIF c = 16 THEN '                                      16 colors found?

            ' -------------------------
            '| Exactly 16 colors found |
            ' -------------------------

            IF fb <= 16 THEN '                                    yes, is black within this range?

                ' ----------------------------------
                '| With black in the 16 color range |
                ' ----------------------------------

                IMG_ColorDepth% = 256 '                          yes, then at least 17 colors exist
            ELSE '                                                no, black is beyond the initial 16 colors

                ' ------------------------------------------
                '| With black outside of the 16 color range |
                ' ------------------------------------------

                IMG_ColorDepth% = 16 '                            this is a 16 color image
            END IF
        ELSE '                                                    no, greater than 16

            ' ------------------------------
            '| Greater than 16 colors found |
            ' ------------------------------

            IMG_ColorDepth% = 256 '                              this is a 256 color image
        END IF
    END IF
    ON ERROR GOTO 0 '                                            remove ON ERROR redirection

END FUNCTION
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#20
Terry,

Since you are error trapping, isn't this line redundant?

IF i > -2 THEN EXIT FUNCTION

Pete
Fake News + Phony Politicians = Real Problems

Reply




Users browsing this thread: 1 Guest(s)