Photochrome

From MultimediaWiki
Jump to: navigation, search
  • 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;
}