QL Graphics

Anything QL Software or Programming Related.
User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: QL Graphics

Post by pjw »

To put some meat on the bone, here is an example of a POC "thumbnail" viewer.
Its quite rudimentary and uses my old sprite viewing program to display the
results. The conversion of the various pictures; jpg, img (Atari), pic, etc to
100x100 pix sprites went quite quickly. In practice, one would retain the
thumbnails til next visiting the same directory (updating and deleting), in which
case loading them is very fast indeed.
Attachments
Screendump.jpg


Per
dont be happy. worry
- ?
User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: QL Graphics

Post by pjw »

This is how far I got with trying to determine the mode of a QL screen dump:

Code: Select all

100 REMark Try to determine the mode
110 REMark of a QL screen dump by testing
120 REMark for the (absence of) flash bits
130 REMark Based on an idea from Martyn Hill
140 REMark V0.00, pjw, January 24th 2018
150 :
160 REMark G3 F3 G2 F2 G1 F1 G0 F0
170 :
180 RESTORE
190 DATA 'dos3_snaps_ql_scn4_scr'
200 DATA 'dos3_snaps_ql_dump_scr'
210 DATA 'dos3_snaps_ql_mode8_scr'
220 DATA 'dos3_snaps_ql_scn8_scr'
230 DATA 'dos3_snaps_ql_scn0_scr'
240 DATA 'dos3_snaps_ql_Worm_scr'
250 :
260 CLS
270 REPeat
280  IF EOF: EXIT
290  READ fnm$
300  PRINT fnm$, GetScrMode(fnm$), c
310 END REPeat
320 :
330 DEFine FuNction GetScrMode(fnm$)
340 LOCal ch, pos, b%
350 ch = FOP_IN(fnm$): IF ch < 0: RETurn ch
370 IF FLEN(#ch) <> 32768: CLOSE#ch: RETurn -12
380 c = 0
390 FOR pos = 258 TO 32764 STEP 64
400  c = c + 1
410  BGET#ch\ (pos), b%
420  IF b% = 170: EXIT pos
430 END FOR pos
440 CLOSE#ch
450 RETurn ((b% = 170) + 1) * 4
460 END DEFine GetScrMode
470 :
It correctly detects all the mode 8 files in my list (3 of the above) Obviously, this is only a
simple test, and on a very limited sample, particularly in the mode 8 department (I tested
about six more mode 4 files with no false positives showing up).
On upping the step size to 128, it missed one of the mode 8 files.
The counter (c) is merely for diagnostic purposes.

Id like to know how accurate it is on real-life samples!
Id like to know how fast this is on some other platforms than my own!
Id like ideas on how to speed up the routine.
Fewer, well-chosen but random, samples from the file?
A way of eliminating mode 4 files earlier in the process?


Per
dont be happy. worry
- ?
User avatar
mk79
QL Wafer Drive
Posts: 1349
Joined: Sun Feb 02, 2014 10:54 am
Location: Esslingen/Germany
Contact:

Re: QL Graphics

Post by mk79 »

pjw wrote:The sprite format is a very nice and versatile image format that also sports compression. The best thing about it is that it is supported by the OS. However, it is not designed as a picture format, although it can be manipulated to serve, if required.
Actually I have specifically improved it to a point where it could and should be considered the de-facto picture standard. The last missing piece was that sprites have a mask, which is additional data not needed in pictures. That has been removed, you can just use a null-pointer for the mask and then the sprite is a solid picture. What would be the advantage of yet another picture format?

Cheers, Marcel


User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: QL Graphics

Post by pjw »

mk79 wrote:
pjw wrote:The sprite format is a very nice and versatile image format that also sports compression. The best thing about it is that it is supported by the OS. However, it is not designed as a picture format, although it can be manipulated to serve, if required.
Actually I have specifically improved it to a point where it could and should be considered the de-facto picture standard. The last missing piece was that sprites have a mask, which is additional data not needed in pictures. That has been removed, you can just use a null-pointer for the mask and then the sprite is a solid picture. What would be the advantage of yet another picture format?

Cheers, Marcel
The sprite standard is brilliant! But dont you find that universality often
comes at the expence of efficiency? The excellent PHGTK toolkit uses the
PIC file format extensively. But that standard has some limitations, which
I thought could be addressed by taking a leaf out of your sprite format.

This is what I came up with:

Code: Select all

New Picture format (sketch)

00      dc.w $4AFC      flag
02      dc.w xsize
04      dc.w ysize
06      dc.w llen
08      dc.b mode       (2, 4, 8, 16, 31?, 32, 33, 64) + 128 => New format
09      dc.b ctrl       #0..5=div image formats?, #6, #7 compression

if mode bit#7 not set then remainder is image data, as before, otherwise:

0A      dc.l next-*     relative pointer to next image definition or 0
        dc.l alph-*     relative pointer to alpha channel or 0
        dc.l 0          spare, or whatever

alph
        dc.b 'RLEx'     compression method, eg RLE, PKB, LZW,.. | optio
        dc.l usize      uncompressed size                       | -nal
        dc.w data..

next
        dc.w $4AFC      flag
        dc.w xsize
        dc.w ysize
        dc.w llen
        dc.b mode       (2, 4, 8, 16, 31?, 32, 33, 64) + 128 => New format
        dc.b ctrl       #0..5=div image formats?, #6, #7 compression
        ...

Different formats could specify additional fields, eg below 'spare',
provided scanners could still read the basic header information.

Multiple images could be to

1) Find correct size for screen - only correct image loaded, or
2) Different mode versions or image formats..? or
3) GIF-type image with timed delay between frames, or
4) First image could be standard _pic.

Some OS support required to encourage uptake of standard, eg displaying file
in native format. (RLE decompression, conversion between formats, etc is
already in there and "only" needs being hooked into.) Later, Wman could use
this format..

SBASIC keywords:

BGIMAGE, LOADIMG, SAVEIMG - basic capability. Advanced stuff left to
external graphics programs..

File extension: _pic, _img

External programs, eg PHGTK, will convert scr, pic, png, gif, jpg, tiff,
etc to img format.
You may consider this re-inventing the wheel, but everything in here is
already available; its just a slightly different arrangement. It may be
good to have separate formats for image files and sprites, so sprite files
can be for speed and compactness, while image files could be for the kind
of versatility required for image manipulation. I dont know. Just an idea..


Per
dont be happy. worry
- ?
martyn_hill
Aurora
Posts: 909
Joined: Sat Oct 25, 2014 9:53 am

Re: QL Graphics

Post by martyn_hill »

Hi Per

Nice first stab at the problem. Taking some of your questions:

"Fewer, well-chosen but random, samples from the file?"

I was thinking about this last night.

I don't think that randomising which sub-set of pixels to test would enhance the accuracy over pre-selecting a fixed sub-set of pixels. It would also be difficult to determine if randomising would reduce the time (on average) to find a positive test, though any number-theorists out there may know different :-)

The question is then how to define a fixed-set of pixels to test. Some - conflicting - criteria ('positive test' here means we are most sure its MODE 4):
a) to test as much of the typically used screen-area as possible (to reduce possibility of missing a positive test.)
b) to start from the most likely points to find a positive match (to reduce the average time.)
c) to test as few pixels as possible overall (obviously, to reduce the maximum time to run.)

I'm wondering if a spiral pattern, starting from the centre and stretching outward might meet the above criteria. This assumes a random-access approach to reading the dump-file, which for speed of access on older media such as microdrives would point to using LBYTES and PEEK in place of channel/character-access.

If memory is not short, then allocating the 32k for the LBYTES of the dump-file and pre-calculating the test-pixel co-ords * to test and storing in an array (or loaded from a pre-saved file) shouldn't be problematic.

* Once the test-pixel co-ords are calculated for a given shape-vector, you'd want to convert these to equivalent byte-offsets within the 32k dump-file one-time and save for later use.

"A way of eliminating mode 4 files earlier in the process?"

This should be the aim anyway, as we are testing to see if _any_ FLASH-bit is set (from our chosen test-set of pixels) - if it is, then we meet our ninety-something % criteria that this is really a GREEN, MODE 4 bit, and return accordingly.

BTW - in your code extract below, you were testing for 170 - i.e. _all_ 4x GREEN bits set in a contiguous row - rather than testing for _any_ of 4x FLASH bits being set, which would need bit-wise AND'ing against 85 (= %01010101).

Partial code idea:
----------------------

REMark *** the below approach - using X,Y co-ords would ideally be pre-converted to byte-offsets one-time, but this example sticks with co-ords
DIM testPointX%(numberOfTestPoints%-1), testPointY%(numberOfTestPoints%-1)
populateTestPointArray testPointX%,testPointY%
:
_scr_llen%=128
flashMask%=21760 : REMark *** 21760 = %01010101 00000000 -or- 85 * 256
POSSIBLE%=1 : UNLIKELY%=0
:
screenBuffer=ALCHP(32*1024) : IF screenBuffer < 0 THEN STOP : REMark *** Ooops...
:
PRINT GetScrMode("MyTestFile_scr")
:
RECHP screenBuffer
:
DEFine FuNction GetScrMode(fnm$)
LBYTES fnm$, screenBuffer
couldBeMode8%=POSSIBLE%
:
FOR testPoint%=0 TO (numberOfTestPoints% - 1)
testX% = testPointX%(testPoint%) : testY%=testPointY%(testPoint%)
pixelWordOffset% = testY% * _scr_llen% + ( (testX% DIV 4) * 2 ) : REMark *** (testX% DIV 4): gives byte offset, * 2: shifts to word-alignment (I think...)
pixelWord%=PEEK_W( screenBuffer + pixelWordOffset% )
IF pixelWord% && flashMask% THEN couldBeMode8%=UNLIKELY% : EXIT testPoint%
END FOR testPoint%
:
RETurn (couldBeMode8% * 4) + 4 : REMark *** RETurns either 4 or 8
:
END DEFine GetScrMode
:


User avatar
pjw
QL Wafer Drive
Posts: 1286
Joined: Fri Jul 11, 2014 8:44 am
Location: Norway
Contact:

Re: QL Graphics

Post by pjw »

martyn_hill wrote:"Fewer, well-chosen but random, samples from the file?"

I was thinking about this last night.

I don't think that randomising which sub-set of pixels to test would enhance the accuracy
over pre-selecting a fixed sub-set of pixels. It would also be difficult to determine if randomising
would reduce the time (on average) to find a positive test, though any number-theorists out
there may know different :-)
This was just sloppy language on my part. I meant what you mean: Pre-selected points in some
sort of pattern that improve the chances of finding significant data. But after thinking about it:
Its a complete lottery; no point is more likely than any other to be significant. So Im left with a
statistical approach: Sampling a proportion of the whole file in the hope that the sample is
representative of the whole. This may or may not be the case in any give instance.
<>
If memory is not short, then allocating the 32k for the LBYTES of the dump-file and
pre-calculating the test-pixel co-ords * to test and storing in an array (or loaded from a pre-saved
file) shouldn't be problematic.
The thing I want to use this for precludes the use of microdrives - and probably floppies too, so
taking up to about 32 consecutive (but not contiguous) samples (my hope: one sample per 8 scan
lines) shouldnt take more time than LBYTESing the whole caboodle and would avoid any memory
challenges..
"A way of eliminating mode 4 files earlier in the process?"

This should be the aim anyway, as we are testing to see if _any_ FLASH-bit is set (from our chosen
test-set of pixels) - if it is, then we meet our ninety-something % criteria that this is really a
GREEN, MODE 4 bit, and return accordingly.
My new - empirically derived - "algorithm" does this with considderable improvement compared to
my previous attempt:

Code: Select all

330 DEFine FuNction GetScrMode(fnm$)
340 LOCal ch, fl, pos, b%, m%
350 ch = FOP_IN(fnm$): IF ch < 0: RETurn ch
360 fl = FLEN(#ch)
370 IF fl <> 32768: CLOSE#ch: RETurn -12
380 c = 0: m% = -1: REMark -1 => dont know
390 FOR pos = 258 TO 32700 STEP 64
400  c = c + 1: m% = -1: REMark -1 => Dont know
410  BGET#ch\ pos + 0, b%
420  IF b% = 170 THEN
430   m% = 8: EXIT pos
440  ELSE
450   IF b% && 85: m% = 4: EXIT pos
460  END IF
470 END FOR pos
480 CLOSE#ch
490 RETurn m%
500 END DEFine GetScrMode
510 :
For my limited samples of "typical" screen dumps this worked surprisingly well. However, this
scheme breaks down completely if the dump contains few or no pixels coloured 4..7. I think I
need to revise my understanding of how colours work in the QL modes 4 and 8!
BTW - in your code extract below, you were testing for 170 - i.e. _all_ 4x GREEN bits
set in a contiguous row - rather than testing for _any_ of 4x FLASH bits being set, which would
need bit-wise AND'ing against 85 (= %01010101).
I know! I tried it initially, but got the wrong results. Hence, see code above
Partial code idea:
----------------------
Thanks for your suggestion :) I have taken it on board


Per
dont be happy. worry
- ?
User avatar
tofro
Font of All Knowledge
Posts: 2685
Joined: Sun Feb 13, 2011 10:53 pm
Location: SW Germany

Re: QL Graphics

Post by tofro »

Per,

you seem to be assuming that flash bits don't mean anything in MODE4 - They do, they're just not flashing the screen, but instead are Green bits on even pixel coordinates.

Code: Select all

High byte (A0=0)                   Low Byte (A0=1)             Mode
D7 D6 D5 D4 D3 D2 D1 D0      D7 D6 D5 D4 D3 D2 D1 D0
G7 G6 G5 G4 G3 G2 G1 G0      R7 R6 R5 R4 R3 R2 R1 R0         512 pixel
G3 F3 G2 F2 G1 F1 G0 F0      R3 B3 R2 B2 R1 B1 R0 B0         256-pixel
That means, a flash bit in MODE 8 translates into a green bit in mode 4 in even bytes. If you have a MODE 4 picture that is mainly green (or white), and interpret that as MODE 8, you might see a lot of "FLASH" (which isn't)

One significant difference between flash and green bits is: Flash bits normally come in pairs, because flash needs to be switched off. Otherwise, FLASH will be switched off at the scanline end. Green bits in MODE 4 have no pairs. So an odd number of FLASH bits per scanline is a strong hint to a MODE 4 picture, an even number hints to MODE 8. You could also Try and interpret the average number of Green bits per scanline (G3-G0, MODE8) and compare that tho the average number of Green bits from even bit positions (which can be flash bits). If the latter is significantly lower, this is also a strong hint to a MODE 8 picture.

Tobias


ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
User avatar
BSJR
Trump Card
Posts: 182
Joined: Sun Oct 18, 2015 12:53 pm
Location: Amsterdam
Contact:

Re: QL Graphics

Post by BSJR »

mk79 wrote:
pjw wrote:The sprite format is a very nice and versatile image format that also sports compression. The best thing about it is that it is supported by the OS. However, it is not designed as a picture format, although it can be manipulated to serve, if required.
Actually I have specifically improved it to a point where it could and should be considered the de-facto picture standard. The last missing piece was that sprites have a mask, which is additional data not needed in pictures. That has been removed, you can just use a null-pointer for the mask and then the sprite is a solid picture. What would be the advantage of yet another picture format?
To fully use sprites as image format we need some of the functionality of WSARS (EP4) or PREST (QPTR) that allows you to show sections of a PIC, making it fit a window with pan & scroll options. The current SPRW (EP4) and WSPRT (QPTR) don't allow a partial viewing of big sprites.

Bob


martyn_hill
Aurora
Posts: 909
Joined: Sat Oct 25, 2014 9:53 am

Re: QL Graphics

Post by martyn_hill »

Hi again Per

Coming back to your explicit check for '170' in the high-byte of the pixel-word:

420 IF b% = 170 THEN
430 m% = 8: EXIT pos

What makes you sure that 4-consecutive pixels with GREEN component set but no FLASH (if Mode 8) or alternatively, 8 pixels with alternate GREEN bits set (Mode 4) should be treated as a MODE 8 image?

I think your accuracy will suffer for the sake of speed - which could be increased by choosing less than 500-odd test-points in a more selective 'shape.'

I humbly challenge your algorythm :-)

Tobias - we are taking as a starting point that almost zero images will be saved with FLASH set anywhere. Its not a 100% valid assumption, but meets Per's original (>51%) likelyhood of being one or the other mode. Very clever thinking, though - especially the 'FLASH must be in pairs' observation. :-)


User avatar
Pr0f
QL Wafer Drive
Posts: 1298
Joined: Thu Oct 12, 2017 9:54 am

Re: QL Graphics

Post by Pr0f »

Flash must be in pairs - is that always true ?

What if an entire line was to be set for flash, and somebody made use of the fact that flash would be reset at the end of the scanline - then you'd only have one flash bit set at the start of a line and no corresponding toggle off. In my opinion that could be classed as 'lazy programming' but hey, it's supported ;-)

Sorry to be a devils spanner polisher...


Post Reply