Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Backports:SLE-15-SP1
mgp
mgp-bilinear-zoom.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File mgp-bilinear-zoom.diff of Package mgp
--- image/zoom.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- mgp.c | 9 ++- mgp.man | 2 3 files changed, 168 insertions(+), 2 deletions(-) --- a/image/zoom.c +++ b/image/zoom.c @@ -11,6 +11,8 @@ #include "copyright.h" #include "image.h" +int smooth_scaling = 1; + static unsigned int *buildIndex(width, zoom, rwidth) unsigned int width; float zoom; @@ -36,6 +38,144 @@ static unsigned int *buildIndex(width, z return(index); } +static Pixel rgb8_to_true(r, g, b) + byte r; + byte g; + byte b; +{ + return (Pixel)r << 16 | (Pixel)g << 8 | (Pixel)b; +} + +/* simple bilinear resampling */ +static void resize_image(oimage, image) + Image *oimage; + Image *image; +{ + double cx, cy, xoff, yoff; + double xstep, ystep; + int maxx, maxy; + int x1, x2, y1, y2; + int i, j; + byte *line1, *line2; + byte *destptr; + unsigned int srclinelen; + unsigned int pixlen; + Pixel v[4]; + unsigned int r, g, b; + + maxx = oimage->width - 1; + maxy = oimage->height - 1; + pixlen= oimage->pixlen; + srclinelen= oimage->width * pixlen; + destptr = image->data; + cy = 0; + xstep = (double)oimage->width / (double)image->width; + ystep = (double)oimage->height / (double)image->height; + for (j = image->height; j > 0; j--) { + y1 = cy; + if (y1 >= maxy) { + y1 = y2 = maxy; + yoff = 0; + } else { + y2 = y1 + 1; + yoff = cy - y1; + } + line1 = oimage->data + srclinelen * y1; + line2 = oimage->data + srclinelen * y2; + cx = 0; + for (i = image->width; i > 0; i--) { + x1 = cx; + if (x1 >= maxx) { + x1 = x2 = maxx; + xoff = 0; + } else { + x2 = x1 + 1; + xoff = cx - x1; + } + v[0] = memToVal(line1 + pixlen * x1, pixlen); + v[1] = memToVal(line1 + pixlen * x2, pixlen); + v[2] = memToVal(line2 + pixlen * x1, pixlen); + v[3] = memToVal(line2 + pixlen * x2, pixlen); + r = (TRUE_RED(v[0]) * (1 - xoff) + + TRUE_RED(v[1]) * xoff) * (1 - yoff) + + (TRUE_RED(v[2]) * (1 - xoff) + + TRUE_RED(v[3]) * xoff) * yoff; + g = (TRUE_GREEN(v[0]) * (1 - xoff) + + TRUE_GREEN(v[1]) * xoff) * (1 - yoff) + + (TRUE_GREEN(v[2]) * (1 - xoff) + + TRUE_GREEN(v[3]) * xoff) * yoff; + b = (TRUE_BLUE(v[0]) * (1 - xoff) + + TRUE_BLUE(v[1]) * xoff) * (1 - yoff) + + (TRUE_BLUE(v[2]) * (1 - xoff) + + TRUE_BLUE(v[3]) * xoff) * yoff; + v[0] = rgb8_to_true(r, g, b); + valToMem(v[0], destptr, pixlen); + destptr += pixlen; + cx += xstep; + } + cy += ystep; + } +} + +/* reduce the given image in integer factor */ +static Image *reduced_image(oimage, width, height) + Image *oimage; + unsigned int width; + unsigned int height; +{ + Image *dest; + byte *destptr; + unsigned int srclinelen; + unsigned int i, j; + unsigned int factorx = oimage->width / width; + unsigned int factory = oimage->height / height; + unsigned int pixlen= oimage->pixlen; + + if (factorx < 1) + factorx = 1; + if (factory < 1) + factory = 1; + + width = oimage->width / factorx; + if (oimage->width % factorx) + width++; + height = oimage->height / factory; + if (oimage->height % factory) + height++; + + dest = newTrueImage(width, height); + destptr = dest->data; + + srclinelen = oimage->width * oimage->pixlen; + + for (j = 0; j < oimage->height; j += factory) { + for (i = 0; i < oimage->width; i += factorx) { + unsigned int r, g, b, div, x, y; + Pixel v; + + r = g = b= 0; + div = 0; + for (y = 0; y < factory && j + y < oimage->height; y++) { + byte *src = oimage->data + srclinelen * (j + y); + for (x = 0; x < factorx && i + x < oimage->width; x++) { + v = memToVal(src + pixlen * (i + x), pixlen); + r += TRUE_RED(v); + g += TRUE_GREEN(v); + b += TRUE_BLUE(v); + div++; + } + } + r /= div; + g /= div; + b /= div; + v = rgb8_to_true(r, g, b); + valToMem(v, destptr, pixlen); + destptr += pixlen; + } + } + return dest; +} + Image *zoom(oimage, xzoom, yzoom, verbose) Image *oimage; float xzoom, yzoom; @@ -145,8 +285,25 @@ Image *zoom(oimage, xzoom, yzoom, verbos /* FALLTHRU */ case ITRUE: - if (!RGBP(oimage)) + if (!RGBP(oimage)) { + Image *tmpimage = NULL; + if (smooth_scaling && oimage->transparent == -1 && + (oimage->width / xwidth > 1 || oimage->height / ywidth > 1)) { + tmpimage = reduced_image(oimage, xwidth, ywidth); + if (tmpimage->width == xwidth && tmpimage->height == ywidth) { + image = tmpimage; + break; + } + } image= newTrueImage(xwidth, ywidth); + if (smooth_scaling && oimage->transparent == -1) { + resize_image(tmpimage ? tmpimage : oimage, image); + if (tmpimage) + freeImage(tmpimage); + break; + } + } + pixlen= oimage->pixlen; destptr= image->data; srcline= oimage->data; --- a/mgp.c +++ b/mgp.c @@ -113,6 +113,8 @@ static int wantreload __P((void)); /*image*/ extern char *expandPath __P((char *)); +extern int smooth_scaling; /* in image/zoom.c */ + #ifdef TTY_KEYINPUT static void susp(int sig) @@ -261,7 +263,7 @@ main(argc, argv) argv=tmp_argv; argc=tmp_argc; -#define ACCEPTOPTS "Bd:vVob:c:eg:f:hlGp:qt:Q:PSUT:D:CORw:X:x:nF:E:" +#define ACCEPTOPTS "Bd:vVob:c:eg:f:hlGp:qt:Q:PsSUT:D:CORw:X:x:nF:E:" while ((opt = getopt(argc, argv, ACCEPTOPTS)) != -1) { #undef ACCEPTOPTS switch (opt) { @@ -342,6 +344,10 @@ main(argc, argv) parse_debug++; break; + case 's': + smooth_scaling = !smooth_scaling; + break; + case 'S': mgp_flag |= FL_NOFORK; break; @@ -750,6 +756,7 @@ mgp_usage(name) fprintf(stderr, "\t-U: Do process directives that forks process\n\t or allow to use non-ASCII filenames (unsecure mode)\n"); fprintf(stderr, "\t-T <timestampfile>: Update timestampfile on page refresh\n"); fprintf(stderr, "\t-P: print stderr from image conversion tools (by default it's discarded)\n"); + fprintf(stderr, "\t-s: Toggle smooth image scaling\n"); fprintf(stderr, "\t-V: Be verbose\n"); fprintf(stderr, "\t-X <gsdevice>: ghostscript device to use\n"); fprintf(stderr, "\t--title <title>: Set window title\n"); --- a/mgp.man +++ b/mgp.man @@ -259,6 +259,8 @@ every time it updates the presentation w This option is useful for external process to understand when .Nm modifies the window. +.It Fl s +Toggle the smooth image rendering by bilinear interpolation. .It Fl V Be verbose. Generate debugging output to standard output.
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor