kopia lustrzana https://github.com/Wren6991/PicoDVI
Encode symbols for palette rather than relying on hardcoded values. Allows 24-bit colour values.
rodzic
1203673e5c
commit
8e5f53625c
|
@ -569,7 +569,7 @@ decl_func_y tmds_fullres_encode_loop_16bpp_leftshift_y
|
|||
b 2f
|
||||
.align 2
|
||||
1:
|
||||
.rept 8
|
||||
.rept 10
|
||||
ldmia r0!, {r3, r5}
|
||||
lsrs r4, r3, #14
|
||||
lsls r3, #2
|
||||
|
|
|
@ -19,10 +19,6 @@ const uint32_t __scratch_y("tmds_table_fullres_y") tmds_table_fullres_y[] = {
|
|||
#include "tmds_table_fullres.h"
|
||||
};
|
||||
|
||||
const uint32_t tmds_table_fullres_noncritical[] = {
|
||||
#include "tmds_table_fullres.h"
|
||||
};
|
||||
|
||||
// Configure an interpolator to extract a single colour channel from each of a pair
|
||||
// of pixels, with the first pixel's lsb at pixel_lsb, and the pixels being
|
||||
// pixel_width wide. Produce a LUT address for the first pixel's colour data on
|
||||
|
@ -171,6 +167,46 @@ void __not_in_flash_func(tmds_encode_data_channel_fullres_16bpp)(const uint32_t
|
|||
#endif
|
||||
}
|
||||
|
||||
static const int8_t imbalance_lookup[16] = { -4, -2, -2, 0, -2, 0, 0, 2, -2, 0, 0, 2, 0, 2, 2, 4 };
|
||||
|
||||
static inline int byte_imbalance(uint32_t x)
|
||||
{
|
||||
return imbalance_lookup[x >> 4] + imbalance_lookup[x & 0xF];
|
||||
}
|
||||
|
||||
static void tmds_encode_symbols(uint8_t pixel, uint32_t* negative_balance_sym, uint32_t* positive_balance_sym)
|
||||
{
|
||||
int pixel_imbalance = byte_imbalance(pixel);
|
||||
uint32_t sym = pixel & 1;
|
||||
if (pixel_imbalance > 0 || (pixel_imbalance == 0 && sym == 0)) {
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
sym |= (~((sym >> i) ^ (pixel >> (i + 1))) & 1) << (i + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
sym |= ( ((sym >> i) ^ (pixel >> (i + 1))) & 1) << (i + 1);
|
||||
}
|
||||
sym |= 0x100;
|
||||
}
|
||||
|
||||
int imbalance = byte_imbalance(sym & 0xFF);
|
||||
if (imbalance == 0) {
|
||||
if ((sym & 0x100) == 0) sym ^= 0x2ff;
|
||||
*positive_balance_sym = sym;
|
||||
*negative_balance_sym = sym;
|
||||
return;
|
||||
}
|
||||
else if (imbalance > 0) {
|
||||
*negative_balance_sym = (sym ^ 0x2ff) | (((-imbalance + imbalance_lookup[2 ^ (sym >> 8)] + 2) & 0x3F) << 26);
|
||||
*positive_balance_sym = sym | ((imbalance + imbalance_lookup[sym >> 8] + 2) << 26);
|
||||
}
|
||||
else {
|
||||
*negative_balance_sym = sym | (((imbalance + imbalance_lookup[sym >> 8] + 2) & 0x3F) << 26);
|
||||
*positive_balance_sym = (sym ^ 0x2ff) | ((-imbalance + imbalance_lookup[2 ^ (sym >> 8)] + 2) << 26);
|
||||
}
|
||||
}
|
||||
|
||||
// This takes a 16-bit (RGB 565) colour palette and makes palettes of TMDS symbols suitable
|
||||
// for performing fullres encode.
|
||||
// The TMDS palette buffer should be 6 * n_palette words long.
|
||||
|
@ -180,15 +216,30 @@ void tmds_setup_palette_symbols(const uint16_t *palette, uint32_t *tmds_palette,
|
|||
uint32_t* tmds_palette_green = tmds_palette + 2 * n_palette;
|
||||
uint32_t* tmds_palette_red = tmds_palette + 4 * n_palette;
|
||||
for (int i = 0; i < n_palette; ++i) {
|
||||
uint16_t blue = (palette[i] << 1) & 0x3e;
|
||||
uint16_t green = (palette[i] >> 5) & 0x3f;
|
||||
uint16_t red = (palette[i] >> 10) & 0x3e;
|
||||
tmds_palette_blue[i] = tmds_table_fullres_noncritical[blue];
|
||||
tmds_palette_blue[i + n_palette] = tmds_table_fullres_noncritical[64 + blue];
|
||||
tmds_palette_green[i] = tmds_table_fullres_noncritical[green];
|
||||
tmds_palette_green[i + n_palette] = tmds_table_fullres_noncritical[64 + green];
|
||||
tmds_palette_red[i] = tmds_table_fullres_noncritical[red];
|
||||
tmds_palette_red[i + n_palette] = tmds_table_fullres_noncritical[64 + red];
|
||||
uint16_t blue = (palette[i] << 3) & 0xf8;
|
||||
uint16_t green = (palette[i] >> 3) & 0xfc;
|
||||
uint16_t red = (palette[i] >> 8) & 0xf8;
|
||||
tmds_encode_symbols(blue, &tmds_palette_blue[i], &tmds_palette_blue[i + n_palette]);
|
||||
tmds_encode_symbols(green, &tmds_palette_green[i], &tmds_palette_green[i + n_palette]);
|
||||
tmds_encode_symbols(red, &tmds_palette_red[i], &tmds_palette_red[i + n_palette]);
|
||||
}
|
||||
}
|
||||
|
||||
// This takes a 24-bit (RGB 888) colour palette and makes palettes of TMDS symbols suitable
|
||||
// for performing fullres encode.
|
||||
// The TMDS palette buffer should be 6 * n_palette words long.
|
||||
// n_palette must be a power of 2 <= 256.
|
||||
void tmds_setup_palette24_symbols(const uint32_t *palette, uint32_t *tmds_palette, size_t n_palette) {
|
||||
uint32_t* tmds_palette_blue = tmds_palette;
|
||||
uint32_t* tmds_palette_green = tmds_palette + 2 * n_palette;
|
||||
uint32_t* tmds_palette_red = tmds_palette + 4 * n_palette;
|
||||
for (int i = 0; i < n_palette; ++i) {
|
||||
uint16_t blue = palette[i] & 0xff;
|
||||
uint16_t green = (palette[i] >> 8) & 0xff;
|
||||
uint16_t red = (palette[i] >> 16) & 0xff;
|
||||
tmds_encode_symbols(blue, &tmds_palette_blue[i], &tmds_palette_blue[i + n_palette]);
|
||||
tmds_encode_symbols(green, &tmds_palette_green[i], &tmds_palette_green[i + n_palette]);
|
||||
tmds_encode_symbols(red, &tmds_palette_red[i], &tmds_palette_red[i + n_palette]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ void tmds_encode_data_channel_16bpp(const uint32_t *pixbuf, uint32_t *symbuf, si
|
|||
void tmds_encode_data_channel_8bpp(const uint32_t *pixbuf, uint32_t *symbuf, size_t n_pix, uint channel_msb, uint channel_lsb);
|
||||
void tmds_encode_data_channel_fullres_16bpp(const uint32_t *pixbuf, uint32_t *symbuf, size_t n_pix, uint channel_msb, uint channel_lsb);
|
||||
void tmds_setup_palette_symbols(const uint16_t *palette, uint32_t *symbuf, size_t n_palette);
|
||||
void tmds_setup_palette24_symbols(const uint32_t *palette, uint32_t *symbuf, size_t n_palette);
|
||||
void tmds_encode_palette_data(const uint32_t *pixbuf, const uint32_t *tmds_palette, uint32_t *symbuf, size_t n_pix, uint32_t palette_bits);
|
||||
|
||||
// Functions from tmds_encode.S
|
||||
|
|
Ładowanie…
Reference in New Issue