Posts: 2,696
Threads: 327
Joined: Apr 2022
Reputation:
217
(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.
Posts: 3,974
Threads: 177
Joined: Apr 2022
Reputation:
219
08-16-2024, 06:57 PM
(This post was last modified: 08-16-2024, 06:57 PM by bplus.)
(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.
I had to lookup _DefaultColor, I keep wanting to call it _ForegroundColor.
b = b + ...
Posts: 1,272
Threads: 119
Joined: Apr 2022
Reputation:
100
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
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 2,696
Threads: 327
Joined: Apr 2022
Reputation:
217
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.
Posts: 1,272
Threads: 119
Joined: Apr 2022
Reputation:
100
(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. 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?
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 1,272
Threads: 119
Joined: Apr 2022
Reputation:
100
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
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 2,696
Threads: 327
Joined: Apr 2022
Reputation:
217
(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. 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.
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
Posts: 2,696
Threads: 327
Joined: Apr 2022
Reputation:
217
@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
Posts: 1,272
Threads: 119
Joined: Apr 2022
Reputation:
100
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
New to QB64pe? Visit the QB64 tutorial to get started.
QB64 Tutorial
Posts: 2,171
Threads: 222
Joined: Apr 2022
Reputation:
103
Terry,
Since you are error trapping, isn't this line redundant?
IF i > -2 THEN EXIT FUNCTION
Pete
Shoot first and shoot people who ask questions, later.
|