Photochrome

From MultimediaWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
  • Extensions: .pcs

Photochrome is an image format that uses palette switching and alternating two screens to display more colors on the originally limitted graphics hardware of the Atari ST.

16-bit words are stored in big-endian order.

File layout

typedef struct {
 uint16_t width;                   /* always 0x140 (320) */
 uint16_t height;                  /* always 0xc8 (200) */
 uint8_t screen_mode;              /* 0 = single screen mode, bit 0 = xor screen data, bit 1 = xor palette data */
 uint8_t frequency;                /* 0 = 60Hz, 1 = 50Hz */
 uint8_t screen_data1[];           /* compressed screen data */
 uint8_t palettes1[];              /* compressed palettes */
 uint8_t screen_data2[];           /* when screen_mode != 0 */
 uint8_t palettes2[];              /* idem */
} photochrome_file;

Image data

The image data are stored as four separate bitplanes and compressed with yet another RLE variant.

uint16_t number_of_control_bytes;

uint8_t x;

    x  < 0 : -x literal bytes follow
    x == 0 : uint16_t y times uint8_t z
    x == 1 : uint16_t y literal bytes
    x  > 1 : x times uint8_t y

Palettes compression

The palette compression algorithm is similar to that of the image data but works solely on 16-bit words.

uint16_t number_of_control_bytes;

uint8_t x;

    x  < 0 : -x literal 16-bit words follow
    x == 0 : uint16_t y times uint16_t z
    x == 1 : uint16_t y literal 16-bit words
    x  > 1 : x times uint16_t y

Each palette contains 16 colors. 200 scanlines and 3 palettes per scanline plus one final palette makes 9616 total palette entries.

Palette selection

Given an x-coordinate and a color index, returns the corresponding Photochrome palette index.

/*  Based on code by Hans Wessels, Public Domain 2008
 */
int find_pcs_index(int x, int c) {
    int x1 = 4 * c, index = c;

    if (x >= x1)                index += 16;
    if (x >= x1+64+12 &&  c<14) index += 16;
    if (x >= 132+16   && c==14) index += 16;
    if (x >= 132+20   && c==15) index += 16;

    x1 = 10 * c - (c&1) * 6;

    if (x >= 176+x1   &&  c<14) index += 16;

    return index;
}