]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/rotate.c
ip/ipconfig: format ipmask with %M instead of %I
[plan9front.git] / sys / src / cmd / rotate.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <memdraw.h>
5
6 Memimage*
7 rot90(Memimage *m)
8 {
9         int line, bpp, x, y, dx, dy;
10         ulong chan;
11         uchar *s, *d;
12         Memimage *w;
13
14         bpp = (m->depth+7)/8;
15         chan = m->chan;
16         switch(chan){
17         case GREY1:
18         case GREY2:
19         case GREY4:
20                 if((w = allocmemimage(m->r, GREY8)) == nil)
21                         sysfatal("allocmemimage: %r");
22                 memimagedraw(w, w->r, m, m->r.min, nil, ZP, S);
23                 freememimage(m);
24                 m = w;
25                 break;
26         }
27
28         dx = Dx(m->r);
29         dy = Dy(m->r);
30         if((w = allocmemimage(Rect(m->r.min.x, m->r.min.y, 
31                 m->r.min.x+dy, m->r.min.y+dx), m->chan)) == nil)
32                 sysfatal("allocmemimage: %r");
33         line = w->width*sizeof(ulong);
34         for(y=0; y<dy; y++){
35                 s = byteaddr(m, addpt(m->r.min, Pt(0, y)));
36                 d = byteaddr(w, addpt(w->r.min, Pt(dy-y-1, 0)));
37                 for(x=0; x<dx; x++){
38                         switch(bpp){
39                         case 4:
40                                 d[3] = s[3];
41                         case 3:
42                                 d[2] = s[2];
43                         case 2:
44                                 d[1] = s[1];
45                         case 1:
46                                 d[0] = s[0];
47                         }
48                         s += bpp;
49                         d += line;
50                 }
51         }
52         freememimage(m);
53         if(w->chan != chan){
54                 if((m = allocmemimage(w->r, chan)) == nil)
55                         sysfatal("allocmemimage: %r");
56                 memimagedraw(m, m->r, w, w->r.min, nil, ZP, S);
57                 freememimage(w);
58                 w = m;
59         }
60         return w;
61 }
62
63 Memimage*
64 upsidedown(Memimage *m)
65 {
66         uchar *s, *d, *t;
67         int w, y, dy;
68
69         dy = Dy(m->r);
70         w = m->width * sizeof(ulong);
71         if((t = malloc(w)) == nil)
72                 sysfatal("malloc: %r");
73         for(y=0; y<dy/2; y++){
74                 s = byteaddr(m, addpt(m->r.min, Pt(0, y)));
75                 d = byteaddr(m, addpt(m->r.min, Pt(0, dy-y-1)));
76                 memmove(t, d, w);
77                 memmove(d, s, w);
78                 memmove(s, t, w);
79         }
80         free(t);
81         return m;
82 }
83
84 void
85 usage(void)
86 {
87         fprint(2, "usage: %s [ -r degree ] [ -u | -l ] [ file ]\n", argv0);
88         exits("usage");
89 }
90
91 void
92 main(int argc, char *argv[])
93 {
94         Memimage *m;
95         int fd, r;
96         char f;
97
98         f = 0;
99         r = 0;
100         fd = 0;
101         ARGBEGIN {
102         case 'u':
103                 f = 'u';
104                 break;
105         case 'l':
106                 f = 'l';
107                 break;
108         case 'r':
109                 r = atoi(EARGF(usage()));
110                 break;
111         default:
112                 usage();
113         } ARGEND;
114         if(*argv){
115                 fd = open(*argv, OREAD);
116                 if(fd < 0)
117                         sysfatal("open: %r");
118         }
119         memimageinit();
120         if((m = readmemimage(fd)) == nil)
121                 sysfatal("readmemimage: %r");
122         if(f == 'u' || f == 'l'){
123                 m = upsidedown(m);
124                 if(f == 'l')
125                         r = 180;
126         }
127         switch(r % 360){
128         case 270:
129                 m = rot90(m);
130         case 180:
131                 m = rot90(m);
132         case 90:
133                 m = rot90(m);
134                 break;
135         }
136         if(writememimage(1, m) < 0)
137                 sysfatal("writememimage: %r");
138         exits(0);
139 }
140