Jump to content
  • 0
desertfish

cx16 image file format ideas

Question

While delving into routines to load and show various image file formats (koala, pcx, png, iff, bmp) it occurred to me that none of them particularly suits the Cx16.

  • Koala images are very specifically tied to the way the Vic-II in the C64 does graphics, and require a lot of conversion logic
  • Bmp contains a lot of Windows clutter and is always large and uncompressed
  • Pcx is always compressed and requires cpu power to decode (although that looks to be simple and the file format has little other overhead)
  • Png is a complex beast and requires a zlib deflate uncompressor
  • IFF is almost universally tied to the Amiga's bit-plane graphics and requires bit fiddling logic to decode

So I thought why not create a new image file format that is optimized for images that are meant to be displayed on the Cx16?

Currently I'm leaning towards the almost universal approach of having one file consisting of a header with meta data about the image, then the palette data, followed by the actual bitmap data. This looks to be convenient and with the appropriate fields in the header can be quite flexible as well to allow for various sizes, color depths and such.

However there are a few issues with this approach:
it does require the file to be loaded sequentially byte-by-byte, and this process is relatively slow compared to reading whole files at once using the LOAD kernel routine or the VLOAD basic command. Also unfortunately, reading the file sequentially only seems to work in the emulator when the file is on an sdcard image, which is a bit inconvenient compared to just reading it from a directory.

So I was thinking:
you could either VLOAD the file but taking into account that the bitmap data is preceded by several hundred bytes of header and pallette, and so use an adjusted load adress (but potentially overwriting other memory with that data).   
Or perhaps split the file in three parts: metadata, palette, bitmap.   Each can then be loaded as desired with just a regular LOAD/VLOAD call.

 

Any thoughts about the above ideas?
Could the  difference in loading times perhaps be explained by the fact that I am using the emulator with its tweaked load routines?
VLOAD of an image is only possible when the image is exactly the width of the screen I think?  If it is smaller or larger it will be displayed scrambled I suspect

 

PS.  I'm currently only investigating pure bit map images. I have zero knowledge about the VERA's tile based display capabilities but would very much like to include them into this format if at all possible.

 

Edited by desertfish
  • Like 1

Share this post


Link to post
Share on other sites

14 answers to this question

Recommended Posts

  • 0

If you want to create a drawing program for the CX16, then fine, go ahead and also create a proprietary image format for that drawing program. Otherwise I don't see any reason to create a new image format that no other programs know about. What would be the benefit?

In my opinion, it will usually be easier to work with images on a standard computer and when the image is done, convert it to binary, save the palette and then ensure that what ever program, you need the image for, is able to load the binary data and palette separately. 

Share this post


Link to post
Share on other sites
  • 0

I agree it is mostly out of interest and for me to learn how to display images in various formats on the cx16.

Maybe I shouldn't put too much energy into "my own" format (although it's a fun exercise) and instead try to make a decoder for one or more of those existing formats. It could be useful if you want to avoid a manual conversion step and just want to display images you've downloaded on the Cx64 for instance 🙂

I have 1 finished decoder, for the C64's Koala format.  A demo of that is in the download section!

Edited by desertfish

Share this post


Link to post
Share on other sites
  • 0

Oh, Targa, it has been a VERY long time since I last heard about that format!  Thanks for reminding me.    At a glance it looks simple enough.     Maybe I'll add it to the list of decoders that I'm trying out .

  • Like 2

Share this post


Link to post
Share on other sites
  • 0

I didn't think PNG was that much of a pain... ah Wikipedia agrees that it uses DEFLATE. 

So the X16 has LZSA2 decompression.  Is there an image format that uses that?

There of course is also PNM.  https://en.wikipedia.org/wiki/Netpbm#File_formats.  So then, how about LZSA2-compressed PPM or PAM files?

 

Edited by rje

Share this post


Link to post
Share on other sites
  • 0

I never heard of LZSA before reading about it in the Cx16's documentation. I was thinking of using LZSA compression for my own image format, but I'm not gonna pursue that any time soon. I'll look at the existing image formats unchanged first.

Those netpbm files look horribly inefficient

Share this post


Link to post
Share on other sites
  • 0
3 hours ago, desertfish said:

I never heard of LZSA before reading about it in the Cx16's documentation. I was thinking of using LZSA compression for my own image format, but I'm not gonna pursue that any time soon. I'll look at the existing image formats unchanged first.

Those netpbm files look horribly inefficient

LOL they probably are.  My naive assumption was that compression takes care of encoding inefficiency.  But maybe not enough?

 

Share this post


Link to post
Share on other sites
  • 0
On 12/11/2020 at 6:13 AM, desertfish said:

Oh, Targa, it has been a VERY long time since I last heard about that format!  Thanks for reminding me.    At a glance it looks simple enough.     Maybe I'll add it to the list of decoders that I'm trying out .

I used to write graphic conversion stuff in DOS back in the day. TGA is pretty straight forward.

Share this post


Link to post
Share on other sites
  • 0

Yeah, TGA is quite programmer-friendly, but many (most?) TGA files are written bottom to top, which means you'll probably have to reload VERA's address register for every line of the bitmap.

I remember playing around with Turbo Pascal back in the 90's, writing a TGA image viewer for files created by POV-Ray and being quite surprised when the image finally showed up, only upside-down. Of course, I only had a faint idea what that thing they call the Internet was and you can imagine it was quite difficult obtaining file format specifications. Ahhhh, happy days 🙂

  • Like 1

Share this post


Link to post
Share on other sites
  • 0

I've got a PCX format viewer up and running now!  The RLE decompression was quite simple it turned out.
Amiga IFF viewer also working, again, the RLE decompression is pretty simple.
BMP viewer also working.

If I can get that 6502 DEFLATE routine someone linked to me working, PNG will close the list, however that source code is in a weird assembler format and the various filter processing routines in the PNG standard make it quite complex and slow I think.... Also the decompressed image data has to fit in memory all at once which make it rather problematic to actually show any image of interesting size.... I think I'm going to skip PNG for now.

They're all separate programs at the moment, I'll integrate them all into one generic image viewer that supports all  formats (except PNG for now)

Edited by desertfish
no PNG for now
  • Like 2

Share this post


Link to post
Share on other sites
  • 0

Right, I'm pretty much done with the image viewer program. It can load iff, pcx, bmp and koala.   I'm not going to pursue PNG or my own format.

Many image files are too large to be loaded into memory at once. So the program loads them progressively via the kernal's CHRIN routine instead.  This only seems to work when the files are on an sd-card image though (in the emulator).  I may just upload a compressed sdcard image to the demo section rather than a handful of separate files? 

Here's a demo of the viewer in action!

 

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
On 12/10/2020 at 12:29 PM, desertfish said:

Any thoughts about the above ideas?
Could the  difference in loading times perhaps be explained by the fact that I am using the emulator with its tweaked load routines?
VLOAD of an image is only possible when the image is exactly the width of the screen I think?  If it is smaller or larger it will be displayed scrambled I suspect

I proposed a file format a while back that would act as a universal data/binary container, with load addresses and block sizes in it. Maybe this is the time to resurrect this format. The idea is pretty simple: the file consists of blocks of data, and each block has a header that describes the block's start address, size, and has room for a short text description. This is useful for graphics files, as well, since loading into VERA is part of the specification. 

Ideally, you'd simply load the register block as part of a block, so the loader would just load that in and populate the VERA configuration registers, but as VERA evolves, it might not be the best way to go. So instead, a "Data" block with configuration information (metadata) does sound like a smart idea. 

The simplest implementation would look like this:

  • FF16 - 2 bytes Little Endian, denotes an "Advanced PRG" file. Since the Commander can't actually load a file in the $FF page, this would trigger the system to load the file using the advanced loader. The "16" means this is a Commander X16 binary.
  • M,B,V,A,P,D - Main memory, Banked memory, VERA, ASCII, PETSCII, Data (application specific). 
  • nn 1 byte, Bank number, ignored for data loaded into main memory
  • nnnn - 2 bytes, LE, absolute load address
  • nnnn - 2 bytes LE, block length
  • data - block length bytes of data. 

So a program loading graphic data into VERA would contain 3 blocks:

  1. Bitmap data, which would likely start at V $00 $0000 
  2. Color data, which would start at V $0F $1000 (or wherever the palette currently lives)
  3. Data block with the metadata. This would be loaded to a specific place in RAM, where your program will decode and use it. The simplest format would probably be:
    1. 1 byte: mode (Tile, Bitmap)
    2. 2 bytes: Columns
    3. 2 bytes: Rows
    4. 1 byte: Bit depth
    5. Start address of layer 1
    6. Start address of layer 2
    7. Start address of tile data 1
    8. Start address of tile data 2

Ideally, I'd love to see the KERNAL adopt this format, so you could simply use the LOAD command, and it would automatically populate the blocks in memory. But since the team has their hands full just fixing BASIC bugs and the like, I may just write and release a reference loader in BASIC and ASM formats.

Here's my current specification. 

https://docs.google.com/document/d/1q4IhDcdZ12B9EqySmHs5tHblFYIzGlzmPuHl3QkiUL0/edit?usp=sharing

Edited by TomXP411
clarify image metadata

Share this post


Link to post
Share on other sites
  • 0

@TomXP411 interesting. I was writing down something similar but meant for just images. Also I'm not very familiar with the VERA's display modes yet so it only has raw bitmap data for now like most other image files do. Here's my take on it for now

 

; offset      value
; -----------------
; HEADER (12 bytes):
; 0-1    'CI' in petscii , from "CommanderX16 Image".
; 2      Size of the header data following this byte (always 9, could become more if format changes)
; 3-4    Width in pixels  (must be multiple of 8)
; 5-6    Height in pixels
; 7      Bits-per-pixel  (1, 2, 4 or 8)  (= 2, 4, 16 or 256 colors)
;          this also determines the number of palette entries following later.
; 8      Settings bits.
;          bit 0 and 1 = compression.  00 = uncompressed
;                                      01 = RLE        [TODO not yet implemented]
;                                      10 = LZSA       [TODO not yet implemented]
;                                      11 = Exomizer   [TODO not yet implemented]
;          bit 2 = palette format.  0 = 4 bits/channel  (2 bytes per color, $0R $GB)
;                                   1 = 8 bits/channel  (3 bytes per color, $RR $GG $BB)
;                  4 bits per channel is what the Vera in the Cx16 supports.
;          bit 3 = bitmap format.   0 = raw bitmap pixels
;                                   1 = tile-based image   [TODO not yet implemented]
;          bit 4 = hscale (horizontal display resolution) 0 = 320 pixels, 1 = 640 pixels
;          bit 5 = vscale (vertical display resolution) 0 = 240 pixels, 1 = 480 pixels
;          bit 6,7: reserved, set to 0
; 9-11   Size of the bitmap data following the palette data.
;          This is a 24-bits number, can be 0 ("unknown", in which case just read until the end).
;
; PALETTE (always present but size varies):
; 12-... Color palette. Number of entries = 2 ^ bits-per-pixel.  Number of bytes per
;          entry is 2 or 3, depending on the chosen palette format in the setting bits.
;
; BITMAPDATA (size varies):
; After this, the actual image data follows.
Edited by desertfish

Share this post


Link to post
Share on other sites
  • 0
20 minutes ago, desertfish said:

Here's my take on it for now

That certainly could drop into my format as block type $11 (image metadata). since the file format doesn't actually care about the contents of the block data, you could put your file header in as the first block, extending your "CI" out to something like "CXIMAGE 1.0" in the 16 byte descriptor. Then we could simply re-define block $11 based on your file header. 

Although... I'm not a fan of bit packed fields in data files. I get why you'd pack the data like that (RAM is limited, after all), but for a universal file format, you'd want to keep the specification as simple as possible, with each data field being byte-aligned. 

 

Edited by TomXP411

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Please review our Terms of Use