From: Laurent Mazet Date: Sun, 6 Oct 2024 21:57:27 +0000 (+0200) Subject: expand and shrink image X-Git-Tag: v2.0~9 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=3511a4172ee6d85587e40e63f4d8fbdbeda2ab3f;p=display.git expand and shrink image --- diff --git a/image.c b/image.c index 7234084..45d1aec 100644 --- a/image.c +++ b/image.c @@ -40,4 +40,56 @@ float correction (float value, float factor) return powf (value, 1. / factor); } +image_t *expandimage (image_t *image, int scale) +{ + image_t *nimage = newimage (image->width * scale, image->height * scale, image->maxvalue); + + int i, j; + for (i = 0; i < nimage->width; i++) { + for (j = 0; j < nimage->height; j++) { + int pos = i / scale + (j / scale) * image->width; + int Pos = i + j * nimage->width; + nimage->red[Pos] = image->red[pos]; + nimage->green[Pos] = image->green[pos]; + nimage->blue[Pos] = image->blue[pos]; + } + } + + return nimage; +} + +image_t *shrinkimage (image_t *image, int scale) +{ + image_t *nimage = newimage ((image->width + scale - 1) / scale, (image->height + scale - 1) / scale, image->maxvalue); + + int i, j; + for (i = 0; i < nimage->width; i++) { + for (j = 0; j < nimage->height; j++) { + float red = 0; + float green = 0; + float blue = 0; + int k, l, n = 0; + for (k = 0; k < scale; k++) { + for (l = 0; l < scale; l++) { + int I = i * scale + k; + int J = j * scale + l; + if ((I < image->width) && (J < image->height)) { + int Pos = I + J * image->width; + red += image->red[Pos]; + green += image->green[Pos]; + blue += image->blue[Pos]; + n++; + } + } + } + int pos = i + j * nimage->width; + nimage->red[pos] = red / n; + nimage->green[pos] = green / n; + nimage->blue[pos] = blue / n; + } + } + + return nimage; +} + /* vim: set ts=4 sw=4 et: */ diff --git a/image.h b/image.h index 155bab5..01f67f5 100644 --- a/image.h +++ b/image.h @@ -20,4 +20,8 @@ int contain (char *str, char c); float correction (float value, float factor); +image_t *expandimage (image_t *image, int scale); + +image_t *shrinkimage (image_t *image, int scale); + #endif /* __IMAGE_H__ */ diff --git a/ndisplay.c b/ndisplay.c index 97a099a..5b84610 100644 --- a/ndisplay.c +++ b/ndisplay.c @@ -14,6 +14,7 @@ #include "pnm.h" #define min(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) +#define max(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; }) #define KEY_ESC 0x1b @@ -24,6 +25,8 @@ char *version = "0.1"; int colormap = 2; float gf[3] = { 1.0f, 1.0f, 1.0f }; int mode = 1; +int scale = 1; +#define MAXSCALE 4 char *help = " Move up\n" @@ -51,6 +54,7 @@ int usage (int ret) int main (int argc, char *argv[]) { char *filename = NULL; + int i; /* get basename */ char *pt = progname = argv[0]; @@ -125,7 +129,12 @@ int main (int argc, char *argv[]) } /* main process */ - image_t *image = readpnm (filename); + image_t *images[MAXSCALE + 1] = {0}; + images[1] = readpnm (filename); + for (i = 2; i <= MAXSCALE; i++) { + images[i] = shrinkimage (images[1], i); + } + images[0] = expandimage (images[1], 2); /* init curses window */ initscr (); @@ -149,18 +158,33 @@ int main (int argc, char *argv[]) /* event loop */ int stop = 0; while (!stop) { + int x, y; + + /* clear screen */ + clear (); + + /* check cursor location */ + if (images[scale]->width - xcursor < COLS / mode) { + xcursor = max (0, images[scale]->width - COLS / mode); + } + if (images[scale]->height - ycursor < LINES) { + ycursor = max (0, images[scale]->height - LINES); + } - int width = min (image->width - xcursor, COLS / mode); - int height = min (image->height - ycursor, LINES); + /* display current image view */ + int width = min (images[scale]->width - xcursor, COLS / mode); + int height = min (images[scale]->height - ycursor, LINES); VERBOSE (DEBUG, FILE *fd = fopen ("my.log", "a"); fprintf (fd, "(%d, %d)\n", width, height); fclose (fd)); - int x, y; for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { - int ind = (x + xcursor) + image->width * (y + ycursor); - color_t *color = findcolor (correction (image->red[ind], gf[0]), - correction (image->green[ind], gf[1]), - correction (image->blue[ind], gf[2]), colormap); + int ind = x + xcursor + images[scale]->width * (y + ycursor); + if (ind >= images[scale]->width * images[scale]->height) { + continue; + } + color_t *color = findcolor (correction (images[scale]->red[ind], gf[0]), + correction (images[scale]->green[ind], gf[1]), + correction (images[scale]->blue[ind], gf[2]), colormap); attron (COLOR_PAIR (color->code)); move (y, x * mode); @@ -193,26 +217,54 @@ int main (int argc, char *argv[]) break; case KEY_DOWN: case 'k': - if (image->height - ycursor > LINES) { + if (images[scale]->height - ycursor >= LINES) { ycursor++; } break; case KEY_RIGHT: case 'l': - if (image->width - xcursor > COLS / mode) { + if (images[scale]->width - xcursor >= COLS / mode) { xcursor++; } break; + case KEY_END: + case 'o': + if (scale < MAXSCALE) { + scale++; + if (scale > 1) { + xcursor = (xcursor * (scale - 1)) / scale; + ycursor = (ycursor * (scale - 1)) / scale; + } else { + xcursor /= 2; + ycursor /= 2; + } + } + break; case KEY_ESC: case 'q': stop = 1; break; + case KEY_HOME: + case 'u': + if (scale > 0) { + scale--; + if (scale > 0) { + xcursor = (xcursor * (scale + 1)) / scale; + ycursor = (ycursor * (scale + 1)) / scale; + } else { /* scale 0 is *2 */ + xcursor *= 2; + ycursor *= 2; + } + } + break; } } /* cleaning before quiting */ endwin (); - freeimage (image); + for (i = 0; i <= scale; i++) { + freeimage (images[i]); + } return 0; }