]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/resize.c
/sys/src/cmd/ndb/dns.h:
[plan9front.git] / sys / src / cmd / resize.c
index a66cd90c7f38ea4f55259e150a342ef6f13b5eff..eb0235a4f31124192edd9e3f9d3adceff1c4f59f 100644 (file)
@@ -3,6 +3,8 @@
 #include <draw.h>
 #include <memdraw.h>
 
+int nflag;
+
 static void
 resample(Memimage *dst, Rectangle r, Memimage *src, Rectangle sr)
 {
@@ -29,6 +31,8 @@ resample(Memimage *dst, Rectangle r, Memimage *src, Rectangle sr)
        for(dp.y=0; dp.y<=dsize.y; dp.y++){
                sp.y = _sp.y>>12;
                ty = _sp.y&0xFFF;
+               if(nflag)
+                       ty = ty << 1 & 0x1000;
                pdst = pdst0;
                sp.x = sr.min.x;
                psrc0 = byteaddr(src, sp);
@@ -36,6 +40,8 @@ resample(Memimage *dst, Rectangle r, Memimage *src, Rectangle sr)
                for(dp.x=0; dp.x<=dsize.x; dp.x++){
                        sp.x = _sp.x>>12;
                        tx = _sp.x&0xFFF;
+                       if(nflag)
+                               tx = tx << 1 & 0x1000;
                        psrc = psrc0 + sp.x*bpp;
                        s00 = (0x1000-tx)*(0x1000-ty);
                        s01 = tx*(0x1000-ty);
@@ -70,10 +76,25 @@ resample(Memimage *dst, Rectangle r, Memimage *src, Rectangle sr)
        }
 }
 
+enum {
+       PERCENT = 0x80000000,
+};
+
+static int
+getsize(char *s)
+{
+       int v;
+
+       v = strtol(s, &s, 10) & ~PERCENT;
+       if(*s == '%')
+               v |= PERCENT;
+       return v;
+}
+
 void
 usage(void)
 {
-       sysfatal("Usage: %s [ -x width ] [ -y height ] [image]\n", argv0);
+       sysfatal("Usage: %s [ -x width ] [ -y height ] [ file ]\n", argv0);
 }
 
 void
@@ -82,15 +103,20 @@ main(int argc, char **argv)
        int fd, xsize, ysize;
        Memimage *im, *nim;
        ulong ochan, tchan;
-       char buf[12];
 
        xsize = ysize = 0;
        ARGBEGIN{
+       case 'a':
+               xsize = ysize = getsize(EARGF(usage()));
+               break;
        case 'x':
-               xsize = atoi(EARGF(usage()));
+               xsize = getsize(EARGF(usage()));
                break;
        case 'y':
-               ysize = atoi(EARGF(usage()));
+               ysize = getsize(EARGF(usage()));
+               break;
+       case 'n':
+               nflag++;
                break;
        default:
                usage();
@@ -104,6 +130,10 @@ main(int argc, char **argv)
        memimageinit();
        if((im = readmemimage(fd)) == nil)
                sysfatal("readmemimage: %r");
+       if(xsize & PERCENT)
+               xsize = ((xsize & ~PERCENT) * Dx(im->r)) / 100;
+       if(ysize & PERCENT)
+               ysize = ((ysize & ~PERCENT) * Dy(im->r)) / 100;
        if(xsize || ysize){
                if(ysize == 0)
                        ysize = (xsize * Dy(im->r)) / Dx(im->r);
@@ -112,7 +142,14 @@ main(int argc, char **argv)
                ochan = im->chan;
                switch(ochan){
                default:
-                       sysfatal("can't handle channel type %s", chantostr(buf, ochan));
+                       for(tchan = ochan; tchan; tchan >>= 8)
+                               if(TYPE(tchan) == CAlpha){
+                                       tchan = RGBA32;
+                                       break;
+                               }
+                       if(tchan == 0)
+                               tchan = RGB24;
+                       break;
                case GREY8:
                case RGB24:
                case RGBA32:
@@ -120,11 +157,6 @@ main(int argc, char **argv)
                case XRGB32:
                        tchan = ochan;
                        break;
-               case CMAP8:
-               case RGB16:
-               case RGB15:
-                       tchan = RGB24;
-                       break;
                case GREY1:
                case GREY2:
                case GREY4:
@@ -138,8 +170,10 @@ main(int argc, char **argv)
                        freememimage(im);
                        im = nim;
                }
-               if((nim = allocmemimage(Rect(im->r.min.x, im->r.min.y, xsize, ysize), tchan)) == nil)
-                       sysfatal("addocmemimage: %r");
+               if((nim = allocmemimage(
+                       Rect(im->r.min.x, im->r.min.y, im->r.min.x+xsize, im->r.min.y+ysize), 
+                       tchan)) == nil)
+                       sysfatal("allocmemimage: %r");
                resample(nim, nim->r, im, im->r);
                freememimage(im);
                im = nim;