]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/resize.c
python: update python build configuration to new ape capabilities like getaddrinfo...
[plan9front.git] / sys / src / cmd / resize.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <memdraw.h>
5
6 static void
7 resample(Memimage *dst, Rectangle r, Memimage *src, Rectangle sr)
8 {
9         Point sp, dp;
10         Point _sp, qp;
11         Point ssize, dsize;
12         uchar *pdst0, *pdst, *psrc0, *psrc;
13         ulong s00, s01, s10, s11;
14         int tx, ty, bpp, bpl;
15
16         ssize = subpt(subpt(sr.max, sr.min), Pt(1,1));
17         dsize = subpt(subpt(r.max, r.min), Pt(1,1));
18         pdst0 = byteaddr(dst, r.min);
19         bpp = src->depth/8;
20         bpl = src->width*sizeof(int);
21
22         qp = Pt(0, 0);
23         if(dsize.x > 0)
24                 qp.x = (ssize.x<<12)/dsize.x;
25         if(dsize.y > 0)
26                 qp.y = (ssize.y<<12)/dsize.y;
27
28         _sp.y = sr.min.y<<12;
29         for(dp.y=0; dp.y<=dsize.y; dp.y++){
30                 sp.y = _sp.y>>12;
31                 ty = _sp.y&0xFFF;
32                 pdst = pdst0;
33                 sp.x = sr.min.x;
34                 psrc0 = byteaddr(src, sp);
35                 _sp.x = 0;
36                 for(dp.x=0; dp.x<=dsize.x; dp.x++){
37                         sp.x = _sp.x>>12;
38                         tx = _sp.x&0xFFF;
39                         psrc = psrc0 + sp.x*bpp;
40                         s00 = (0x1000-tx)*(0x1000-ty);
41                         s01 = tx*(0x1000-ty);
42                         s10 = (0x1000-tx)*ty;
43                         s11 = tx*ty;
44                         switch(bpp){
45                         case 4:
46                                 pdst[3] = (s11*psrc[bpl+bpp+3] + 
47                                            s10*psrc[bpl+3] + 
48                                            s01*psrc[bpp+3] +
49                                            s00*psrc[3]) >>24;
50                         case 3:
51                                 pdst[2] = (s11*psrc[bpl+bpp+2] + 
52                                            s10*psrc[bpl+2] + 
53                                            s01*psrc[bpp+2] +
54                                            s00*psrc[2]) >>24;
55                                 pdst[1] = (s11*psrc[bpl+bpp+1] + 
56                                            s10*psrc[bpl+1] + 
57                                            s01*psrc[bpp+1] +
58                                            s00*psrc[1]) >>24;
59                         case 1:
60                                 pdst[0] = (s11*psrc[bpl+bpp] + 
61                                            s10*psrc[bpl] + 
62                                            s01*psrc[bpp] +
63                                            s00*psrc[0]) >>24;
64                         }
65                         pdst += bpp;
66                         _sp.x += qp.x;
67                 }
68                 pdst0 += dst->width*sizeof(int);
69                 _sp.y += qp.y;
70         }
71 }
72
73 enum {
74         PERCENT = 0x80000000,
75 };
76
77 static int
78 getsize(char *s)
79 {
80         int v;
81
82         v = strtol(s, &s, 10) & ~PERCENT;
83         if(*s == '%')
84                 v |= PERCENT;
85         return v;
86 }
87
88 void
89 usage(void)
90 {
91         sysfatal("Usage: %s [ -x width ] [ -y height ] [ file ]\n", argv0);
92 }
93
94 void
95 main(int argc, char **argv)
96 {
97         int fd, xsize, ysize;
98         Memimage *im, *nim;
99         ulong ochan, tchan;
100
101         xsize = ysize = 0;
102         ARGBEGIN{
103         case 'a':
104                 xsize = ysize = getsize(EARGF(usage()));
105                 break;
106         case 'x':
107                 xsize = getsize(EARGF(usage()));
108                 break;
109         case 'y':
110                 ysize = getsize(EARGF(usage()));
111                 break;
112         default:
113                 usage();
114         }ARGEND
115         fd = 0;
116         if(*argv){
117                 fd = open(*argv, OREAD);
118                 if(fd < 0)
119                         sysfatal("open: %r");
120         }
121         memimageinit();
122         if((im = readmemimage(fd)) == nil)
123                 sysfatal("readmemimage: %r");
124         if(xsize & PERCENT)
125                 xsize = ((xsize & ~PERCENT) * Dx(im->r)) / 100;
126         if(ysize & PERCENT)
127                 ysize = ((ysize & ~PERCENT) * Dy(im->r)) / 100;
128         if(xsize || ysize){
129                 if(ysize == 0)
130                         ysize = (xsize * Dy(im->r)) / Dx(im->r);
131                 if(xsize == 0)
132                         xsize = (ysize * Dx(im->r)) / Dy(im->r);
133                 ochan = im->chan;
134                 switch(ochan){
135                 default:
136                         for(tchan = ochan; tchan; tchan >>= 8)
137                                 if(TYPE(tchan) == CAlpha){
138                                         tchan = RGBA32;
139                                         break;
140                                 }
141                         if(tchan == 0)
142                                 tchan = RGB24;
143                         break;
144                 case GREY8:
145                 case RGB24:
146                 case RGBA32:
147                 case ARGB32:
148                 case XRGB32:
149                         tchan = ochan;
150                         break;
151                 case GREY1:
152                 case GREY2:
153                 case GREY4:
154                         tchan = GREY8;
155                         break;
156                 }
157                 if(tchan != ochan){
158                         if((nim = allocmemimage(im->r, tchan)) == nil)
159                                 sysfatal("allocimage: %r");
160                         memimagedraw(nim, nim->r, im, im->r.min, nil, ZP, S);
161                         freememimage(im);
162                         im = nim;
163                 }
164                 if((nim = allocmemimage(
165                         Rect(im->r.min.x, im->r.min.y, im->r.min.x+xsize, im->r.min.y+ysize), 
166                         tchan)) == nil)
167                         sysfatal("addocmemimage: %r");
168                 resample(nim, nim->r, im, im->r);
169                 freememimage(im);
170                 im = nim;
171                 if(tchan != ochan){
172                         if((im = allocmemimage(nim->r, ochan)) == nil)
173                                 sysfatal("allocimage: %r");
174                         memimagedraw(im, im->r, nim, nim->r.min, nil, ZP, S);
175                         freememimage(nim);
176                 }
177         }
178         if(writememimage(1, im) < 0)
179                 sysfatal("writememimage: %r");
180         exits(0);
181 }