Improve screencap scaling aspect ratios

pull/128/head
IanSB 2020-01-09 15:10:30 +00:00
rodzic b7b9353279
commit ccd4463640
2 zmienionych plików z 54 dodań i 86 usunięć

Wyświetl plik

@ -52,100 +52,61 @@ static int generate_png(capture_info_t *capinfo, uint8_t **png, unsigned int *pn
int hscale = get_hscale();
int vscale = get_vscale();
log_info("Scaling is %d/2 x %d/2 x=%d y=%d", hscale, vscale, capinfo->width, capinfo->height );
int hdouble = (hscale & 0x80000000) ? 1 : 0;
int vdouble = (vscale & 0x80000000) ? 1 : 0;
uint8_t png_buffer[((width * hscale) >> 1) * ((height * vscale) >> 1)];
hscale &= 0xff;
vscale &= 0xff;
int png_width = (width >> hdouble) * hscale;
int png_height = (height >> vdouble) * vscale;
log_info("Scaling is %d/2 x %d/2 x=%d y=%d px=%d py=%d", hscale, vscale, width, height, png_width, png_height);
uint8_t png_buffer[png_width * png_height];
uint8_t *pp = png_buffer;
if (capinfo->bpp == 8) {
for (int y = 0; y < capinfo->height; y++) {
for (int sy = 0; sy < (vscale >> 1); sy++) {
for (int y = 0; y < capinfo->height; y += (vdouble + 1)) {
for (int sy = 0; sy < vscale; sy++) {
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
for (int x = 0; x < capinfo->width; x++) {
for (int x = 0; x < capinfo->width; x += (hdouble + 1)) {
uint8_t single_pixel = *fp++;
for (int sx = 0; sx < (hscale >> 1); sx++) {
if (hdouble) fp++;
for (int sx = 0; sx < hscale; sx++) {
*pp++ = single_pixel;
}
if ((hscale & 1) == 1 && (x & 1) == 1) {
*pp++ = single_pixel;
}
}
}
if ((vscale & 1) == 1 && (y & 1) == 1) {
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
for (int x = 0; x < capinfo->width; x++) {
uint8_t single_pixel = *fp++;
for (int sx = 0; sx < (hscale >> 1); sx++) {
*pp++ = single_pixel;
}
if ((hscale & 1) == 1 && (x & 1) == 1) {
*pp++ = single_pixel;
}
}
}
}
} else {
for (int y = 0; y < capinfo->height; y++) {
for (int sy = 0; sy < (vscale >> 1); sy++) {
for (int y = 0; y < capinfo->height; y += (vdouble + 1)) {
for (int sy = 0; sy < vscale; sy++) {
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
uint8_t single_pixel = 0;
for (int x = 0; x < capinfo->width; x++) {
if ((x & 1) == 0) {
single_pixel= *fp++;
for (int sx = 0; sx < (hscale >> 1); sx++) {
for (int x = 0; x < capinfo->width; x += (hdouble + 1)) {
if (hdouble) {
single_pixel = *fp++;
for (int sx = 0; sx < hscale; sx++) {
*pp++ = single_pixel >> 4;
}
} else {
for (int sx = 0; sx < (hscale >> 1); sx++) {
*pp++ = single_pixel & 0x0f;
}
if ((hscale & 1) == 1) {
*pp++ = single_pixel & 0x0f;
if ((x & 1) == 0) {
single_pixel = *fp++;
for (int sx = 0; sx < hscale; sx++) {
*pp++ = single_pixel >> 4;
}
} else {
for (int sx = 0; sx < hscale; sx++) {
*pp++ = single_pixel & 0x0f;
}
}
}
}
}
if ((vscale & 1) == 1 && (y & 1) == 1) {
uint8_t *fp = capinfo->fb + capinfo->pitch * y;
uint8_t single_pixel = 0;
for (int x = 0; x < capinfo->width; x++) {
if ((x & 1) == 0) {
single_pixel= *fp++;
for (int sx = 0; sx < (hscale >> 1); sx++) {
*pp++ = single_pixel >> 4;
}
} else {
for (int sx = 0; sx < (hscale >> 1); sx++) {
*pp++ = single_pixel & 0x0f;
}
if ((hscale & 1) == 1) {
*pp++ = single_pixel & 0x0f;
}
}
}
}
}
}
unsigned int result = lodepng_encode(png, png_len, png_buffer, (width * hscale) >> 1, (height * vscale) >> 1, &state);
unsigned int result = lodepng_encode(png, png_len, png_buffer, png_width, png_height, &state);
if (result) {
log_warn("lodepng_encode32 failed (result = %d)", result);
return 1;

Wyświetl plik

@ -522,17 +522,16 @@ void geometry_get_fb_params(capture_info_t *capinfo) {
//log_info("scaling h = %d, %d, %f, %d, %d, %d, %d",h_size, h_size43, hscalef, hscale, hborder, hborder43, newhborder43);
//log_info("scaling v = %d, %d, %f, %d, %d, %d, %d",v_size, v_size43, vscalef, vscale, vborder, vborder43, newvborder43);
caphscale = h_aspect << 1;
capvscale = v_aspect << 1;
if (double_width) {
caphscale = h_aspect;
capvscale = v_aspect;
while ((caphscale & 1) == 0 && (capvscale & 1) == 0) {
caphscale >>= 1;
}
if (double_height) {
capvscale >>= 1;
}
if (caphscale >= 4 && capvscale >= 4) {
caphscale >>= 1;
capvscale >>= 1;
if (caphscale == 1 && capvscale == 1 && h_aspect == v_aspect) {
caphscale = 2;
capvscale = 2;
}
switch (scaling) {
@ -563,8 +562,8 @@ void geometry_get_fb_params(capture_info_t *capinfo) {
}
if (capscale != 0) {
caphscale = (h_size << 1) / capinfo->width;
capvscale = (v_size << 1) / capinfo->height;
caphscale = ((h_size << double_width) / capinfo->width);
capvscale = ((v_size << double_height) / capinfo->height);
}
}
break;
@ -584,11 +583,6 @@ void geometry_get_fb_params(capture_info_t *capinfo) {
break;
};
if (caphscale == 1 && capvscale == 1) {
caphscale = 2;
capvscale = 2;
}
if (capinfo->chars_per_line > (capinfo->width >> 3)) {
capinfo->chars_per_line = (capinfo->width >> 3);
}
@ -602,6 +596,18 @@ void geometry_get_fb_params(capture_info_t *capinfo) {
//log_info("Clipping capture height to %d", capinfo->nlines);
}
if (mode7) {
caphscale = 3;
capvscale = 2;
} else {
if (double_width) {
caphscale |= 0x80000000;
}
if (double_height) {
capvscale |= 0x80000000;
}
}
//log_info("size= %d, %d, %d, %d, %d, %d, %d",capinfo->chars_per_line, capinfo->nlines, geometry_min_h_width, geometry_min_v_height,capinfo->width, capinfo->height, capinfo->sizex2);
}
@ -612,6 +618,7 @@ int get_vscale() {
return capvscale;
}
void geometry_get_clk_params(clk_info_t *clkinfo) {
clkinfo->clock = geometry->clock;
clkinfo->line_len = geometry->line_len;