Пример #1
0
/*
    Calculate a RGB palette out of VIC/VIC-II/TED colors (in ycbcr format),
    apply saturation, brightness, contrast, tint and gamma settings.

    this palette will be used for screenshots and by renderers if CRT emulation
    is disabled.
*/
static palette_t *video_calc_palette(struct video_canvas_s *canvas, const video_ycbcr_palette_t *p)
{
    palette_t *prgb;
    unsigned int i;
    float sat, bri, con, gam, tin;
    video_resources_t *video_resources = &(canvas->videoconfig->video_resources);

    DBG(("video_calc_palette"));

    sat = ((float)(video_resources->color_saturation)) / 1000.0f;
    bri = ((float)(video_resources->color_brightness - 1000)) * (128.0f / 1000.0f);
    con = ((float)(video_resources->color_contrast)) / 1000.0f;
    gam = video_get_gamma(video_resources);
    tin = (((float)(video_resources->color_tint)) / (2000.0f / 50.0f)) - 25.0f;

    /* create RGB palette with the base colors of the video chip */
    prgb = palette_create(p->num_entries, NULL);
    if (prgb == NULL) {
        return NULL;
    }

    for (i = 0; i < p->num_entries; i++) {
        video_convert_ycbcr_to_rgb(&p->entries[i], sat, bri, con, gam, tin,
                                   &prgb->entries[i]);
    }

    return prgb;
}
Пример #2
0
/*
    Calculate a RGB palette out of VIC/VIC-II/TED colors (in ycbcr format),
    apply saturation, brightness, contrast, tint and gamma settings.

    this palette will be used for screenshots and by renderers if CRT emulation
    is disabled.
*/
static palette_t *video_calc_palette(struct video_canvas_s *canvas, const video_ycbcr_palette_t *p, int video)
{
    palette_t *prgb;
    unsigned int i;
    float sat, bri, con, gam, tin;
    video_resources_t *video_resources = &(canvas->videoconfig->video_resources);

    DBG(("video_calc_palette"));

    sat = ((float)(video_resources->color_saturation)) / 1000.0f;
    bri = ((float)(video_resources->color_brightness - 1000)) * (128.0f / 1000.0f);
    con = ((float)(video_resources->color_contrast)) / 1000.0f;
    gam = video_get_gamma(video_resources, video);
    tin = (((float)(video_resources->color_tint)) / (2000.0f / 50.0f)) - 25.0f;

    /* create RGB palette with the base colors of the video chip */
    prgb = palette_create(p->num_entries, NULL);
    if (prgb == NULL) {
        return NULL;
    }

    DBG((" sat:%d bri:%d con:%d gam:%d tin:%d", (int)sat, (int)bri, (int)con, (int)gam, (int)tin));

    for (i = 0; i < p->num_entries; i++) {
        video_convert_renderer_to_rgb_gamma(&p->entries[i], sat, bri, con, gam, tin, &prgb->entries[i], video);
        DBG((" %2d: Y:%4d Cb:%4d Cr:%4d  R:%3d G:%3d B:%3d", i,
            (int)p->entries[i].y, (int)p->entries[i].cb, (int)p->entries[i].cr,
            (int)prgb->entries[i].red, (int)prgb->entries[i].green, (int)prgb->entries[i].blue));
    }

    return prgb;
}
Пример #3
0
/* gammatable calculation */
static void video_calc_gammatable(video_resources_t *video_resources)
{
    int i;
    float bri, con, gam, scn, v;
    double factor;
    DWORD vi;

    bri = ((float)(video_resources->color_brightness - 1000))
          * (128.0f / 1000.0f);
    con = ((float)(video_resources->color_contrast   )) / 1000.0f;
    gam = video_get_gamma(video_resources);
    scn = ((float)(video_resources->pal_scanlineshade)) / 1000.0f;

    factor = pow(255.0f, 1.0f - gam);
    for (i = 0; i < (256 * 3); i++) {
        v = video_gamma((float)(i - 256), factor, gam, bri, con);

        vi = (DWORD)v;
        if (vi > 255) {
            vi = 255;
        }
        gamma_red[i] = color_red[vi];
        gamma_grn[i] = color_grn[vi];
        gamma_blu[i] = color_blu[vi];

        vi = (DWORD)(v * scn);
        if (vi > 255) {
            vi = 255;
        }
        gamma_red_fac[i * 2] = color_red[vi];
        gamma_grn_fac[i * 2] = color_grn[vi];
        gamma_blu_fac[i * 2] = color_blu[vi];
        v = video_gamma((float)(i - 256) + 0.5f, factor, gam, bri, con);
        vi = (DWORD)(v * scn);
        if (vi > 255) {
            vi = 255;
        }
        gamma_red_fac[i * 2 + 1] = color_red[vi];
        gamma_grn_fac[i * 2 + 1] = color_grn[vi];
        gamma_blu_fac[i * 2 + 1] = color_blu[vi];
    }
}
Пример #4
0
static void video_calc_ycbcrtable(video_resources_t *video_resources,
                                  const video_ycbcr_palette_t *p, video_render_color_tables_t *color_tab)
{
    video_ycbcr_color_t *primary;
    unsigned int i, lf, hf;
    float sat, tin, bri, con, gam;
    float yf, uf, vf;
    int y, u, v;
    double factor, len;

    lf = 64 * video_resources->pal_blur / 1000;
    hf = 255 - (lf << 1);
    sat = ((float)(video_resources->color_saturation)) * (256.0f / 1000.0f);
    tin = (((float)(video_resources->color_tint)) * (50.0f / 2000.0f)) - 25.0f;
    bri = ((float)(video_resources->color_brightness - 1000)) * (112.0f / 1000.0f);
    con = ((float)(video_resources->color_contrast   )) / 1000.0f;
    gam = video_get_gamma(video_resources);

    factor = pow(256.0f, 1.0f - gam);
    for (i = 0; i < p->num_entries; i++) {
        SDWORD val;

        /* create primary table */
        primary = &p->entries[i];
        val = (SDWORD)(primary->y * 256.0f);
        color_tab->ytablel[i] = val * lf;
        color_tab->ytableh[i] = val * hf;
        color_tab->cbtable[i] = (SDWORD)((primary->cb) * sat);
        color_tab->cutable[i] = (SDWORD)(0.493111 * primary->cb * 256.0);
        /* tint, add to cr in odd lines */
        val = (SDWORD)(tin);
        color_tab->crtable[i] = (SDWORD)((primary->cr + val) * sat);
        color_tab->cvtable[i] = (SDWORD)(0.877283 * (primary->cr + val) * 256.0);

        yf = (float)(video_gamma(primary->y, factor, gam, bri, con) * 224.0 / 256.0 + 16.5);
        uf = (float)(0.493111 * primary->cb * sat * con * 224.0 / 256.0 / 256.0 + 128.5);
        vf = (float)(0.877283 * (primary->cr + tin) * sat * con * 224.0 / 256.0 / 256.0 + 128.5);
        y = (int)yf;
        u = (int)uf;
        v = (int)vf;

        /* sanity check: cbtable and crtable must be kept in 16 bit range or we 
                         might get overflows in eg the CRT renderer */
        len = sqrt(((double)color_tab->cbtable[i] * (double)color_tab->cbtable[i]) +
                   ((double)color_tab->crtable[i] * (double)color_tab->crtable[i]));
        if (len >= (double)0x10000) {
            log_error(LOG_DEFAULT, 
                "video_calc_ycbcrtable: color %d cbcr vector too long, use lower base saturation.", i);
        }

        if (y < 16) {
            y = 16;
        } else if (y > 240) {
            y = 240;
        }
        if (u < 16) {
            u = 16;
        } else if (u > 240) {
            u = 240;
        }
        if (v < 16) {
            v = 16;
        } else if (v > 240) {
            v = 240;
        }
        /* YCbCr to YUV, scale [0, 256] to [0, 255] */
        color_tab->yuv_table[i] = (y << 16) | (u << 8) | v;
    }
    color_tab->yuv_updated = 0;
}
Пример #5
0
/* called by video_color_update_palette, internal and external palette */
static void video_calc_ycbcrtable(video_resources_t *video_resources,
                                  const video_ycbcr_palette_t *p, video_render_color_tables_t *color_tab, int video)
{
    video_ycbcr_color_t *primary;
    unsigned int i, lf, hf;
    float sat, tin, bri, con, gam;
    float yf, uf, vf;
    int y, u, v;
    double factor, len;
#ifdef DEBUG_VIDEO
    palette_entry_t temp;
#endif

    DBG(("video_calc_ycbcrtable"));

    lf = 64 * video_resources->pal_blur / 1000;
    hf = 255 - (lf << 1);
    sat = ((float)(video_resources->color_saturation)) * (256.0f / 1000.0f);
    tin = (((float)(video_resources->color_tint)) * (50.0f / 2000.0f)) - 25.0f;
    bri = ((float)(video_resources->color_brightness - 1000)) * (112.0f / 1000.0f);
    con = ((float)(video_resources->color_contrast   )) / 1000.0f;
    gam = video_get_gamma(video_resources, video);

    factor = pow(256.0f, 1.0f - gam);

    DBG((" sat:%d bri:%d con:%d gam:%d tin:%d", (int)sat, (int)bri, (int)con, (int)gam, (int)tin));

    for (i = 0; i < p->num_entries; i++) {
        SDWORD val;

        /* create primary table */
        primary = &p->entries[i];
        if (video) {
            val = (SDWORD)(primary->y * 256.0f);
            color_tab->ytablel[i] = val * lf;
            color_tab->ytableh[i] = val * hf;
            /* tint, add to cr in odd lines */
            val = (SDWORD)(tin);
            color_tab->cbtable[i] = (SDWORD)((primary->cb) * sat);
            color_tab->crtable[i] = (SDWORD)((primary->cr + val) * sat);
            color_tab->cutable[i] = (SDWORD)(0.493111f * primary->cb * 256.0); /* convert Cb to U */
            color_tab->cvtable[i] = (SDWORD)(0.877283f * (primary->cr + val) * 256.0); /* convert Cr to V */
        } else {
            /* for NTSC use one bit less for the fraction in the tables to avoid
               integer overflows in the CRT renderer */
            val = (SDWORD)(primary->y * 128.0f);
            color_tab->ytablel[i] = (val * lf);
            color_tab->ytableh[i] = (val * hf);
            /* FIXME: tint for NTSC */
            val = (SDWORD)(tin);
            color_tab->cbtable[i] = (SDWORD)((primary->cb) * sat) >> 1;
            color_tab->crtable[i] = (SDWORD)((primary->cr + val) * sat) >> 1;
            /* FIXME: convert IQ to UV (used by YUV renderers) */
            color_tab->cutable[i] = (SDWORD)(primary->cb * 256.0);
            color_tab->cvtable[i] = (SDWORD)((primary->cr + val) * 256.0);
        }

#ifdef DEBUG_VIDEO
        video_convert_renderer_to_rgb(primary, &temp, video);
        DBG((" %2d  'Cb':%4d 'Cr':%4d     'Cr':%6d 'Cb':%6d     R:%4d G:%4d B:%4d", i,
            (int)primary->cb, (int)primary->cr,
            (int)color_tab->cbtable[i], (int)color_tab->crtable[i],
            temp.red, temp.green, temp.blue
        ));
#endif

        yf = (float)(video_gamma(primary->y, factor, gam, bri, con) * 224.0 / 256.0 + 16.5);
        if (video) {
            /* PAL: convert CbCr to UV */
            uf = (float)(0.493111f * primary->cb * sat * con * 224.0 / 256.0 / 256.0 + 128.5);
            vf = (float)(0.877283f * (primary->cr + tin) * sat * con * 224.0 / 256.0 / 256.0 + 128.5);
        } else {
            /* FIXME: convert IQ to UV (used by YUV renderers) */
            uf = (float)(0.493111f * primary->cb * sat * con * 224.0 / 256.0 / 256.0 + 128.5);
            vf = (float)(0.877283f * (primary->cr + tin) * sat * con * 224.0 / 256.0 / 256.0 + 128.5);
        }

        /* sanity check: cbtable and crtable must be kept in 16 bit range or we 
                         might get overflows in eg the CRT renderer */
        /* FIXME: we need to check more and clamp the values accordingly - it is
                  still possible to "overdrive" the renderer in NTSC mode */
        len = sqrt(((double)color_tab->cbtable[i] * (double)color_tab->cbtable[i]) +
                   ((double)color_tab->crtable[i] * (double)color_tab->crtable[i]));
        if (len >= (double)0x10000) {
            log_error(LOG_DEFAULT, 
                "video_calc_ycbcrtable: color %d cbcr vector too long, use lower base saturation.", i);
        }

        y = (int)RMINMAX(yf, 16, 240);
        u = (int)RMINMAX(uf, 16, 240);
        v = (int)RMINMAX(vf, 16, 240);

        /* YCbCr to YUV, scale [0, 256] to [0, 255] (used by YUV renderers) */
        color_tab->yuv_table[i] = (y << 16) | (u << 8) | v;
    }
    color_tab->yuv_updated = 0;
}