Blame


1 228bb71d 2004-12-28 devnull #include <u.h>
2 228bb71d 2004-12-28 devnull #include <libc.h>
3 228bb71d 2004-12-28 devnull #include <draw.h>
4 228bb71d 2004-12-28 devnull #include <memdraw.h>
5 228bb71d 2004-12-28 devnull
6 228bb71d 2004-12-28 devnull enum
7 228bb71d 2004-12-28 devnull {
8 228bb71d 2004-12-28 devnull None,
9 228bb71d 2004-12-28 devnull Inset, /* move border in or out uniformly */
10 228bb71d 2004-12-28 devnull Insetxy, /* move border in or out; different parameters for x and y */
11 228bb71d 2004-12-28 devnull Set, /* set rectangle to absolute values */
12 228bb71d 2004-12-28 devnull Blank, /* cut off blank region according to color value */
13 228bb71d 2004-12-28 devnull /* Blank is not actually set as a mode; it can be combined with others */
14 228bb71d 2004-12-28 devnull };
15 228bb71d 2004-12-28 devnull
16 228bb71d 2004-12-28 devnull void
17 228bb71d 2004-12-28 devnull usage(void)
18 228bb71d 2004-12-28 devnull {
19 228bb71d 2004-12-28 devnull fprint(2, "usage: crop [-c rgb] [-i ±inset | -r R | -x ±inset | -y ±inset] [-t tx ty] [-b rgb ] [imagefile]\n");
20 228bb71d 2004-12-28 devnull fprint(2, "\twhere R is a rectangle minx miny maxx maxy\n");
21 228bb71d 2004-12-28 devnull fprint(2, "\twhere rgb is a color red green blue\n");
22 228bb71d 2004-12-28 devnull exits("usage");
23 228bb71d 2004-12-28 devnull }
24 228bb71d 2004-12-28 devnull
25 228bb71d 2004-12-28 devnull int
26 228bb71d 2004-12-28 devnull getint(char *s)
27 228bb71d 2004-12-28 devnull {
28 228bb71d 2004-12-28 devnull if(s == nil)
29 228bb71d 2004-12-28 devnull usage();
30 228bb71d 2004-12-28 devnull if(*s == '+')
31 228bb71d 2004-12-28 devnull return atoi(s+1);
32 228bb71d 2004-12-28 devnull if(*s == '-')
33 228bb71d 2004-12-28 devnull return -atoi(s+1);
34 228bb71d 2004-12-28 devnull return atoi(s);
35 228bb71d 2004-12-28 devnull }
36 228bb71d 2004-12-28 devnull
37 228bb71d 2004-12-28 devnull Rectangle
38 228bb71d 2004-12-28 devnull crop(Memimage *m, ulong c)
39 228bb71d 2004-12-28 devnull {
40 228bb71d 2004-12-28 devnull Memimage *n;
41 228bb71d 2004-12-28 devnull int x, y, bpl, wpl;
42 228bb71d 2004-12-28 devnull int left, right, top, bottom;
43 228bb71d 2004-12-28 devnull ulong *buf;
44 228bb71d 2004-12-28 devnull
45 228bb71d 2004-12-28 devnull left = m->r.max.x;
46 228bb71d 2004-12-28 devnull right = m->r.min.x;
47 228bb71d 2004-12-28 devnull top = m->r.max.y;
48 228bb71d 2004-12-28 devnull bottom = m->r.min.y;
49 228bb71d 2004-12-28 devnull n = nil;
50 228bb71d 2004-12-28 devnull if(m->chan != RGBA32){
51 228bb71d 2004-12-28 devnull /* convert type for simplicity */
52 228bb71d 2004-12-28 devnull n = allocmemimage(m->r, RGBA32);
53 228bb71d 2004-12-28 devnull if(n == nil)
54 228bb71d 2004-12-28 devnull sysfatal("can't allocate temporary image: %r");
55 228bb71d 2004-12-28 devnull memimagedraw(n, n->r, m, m->r.min, nil, ZP, S);
56 228bb71d 2004-12-28 devnull m = n;
57 228bb71d 2004-12-28 devnull }
58 228bb71d 2004-12-28 devnull wpl = wordsperline(m->r, m->depth);
59 228bb71d 2004-12-28 devnull bpl = wpl*sizeof(ulong);
60 228bb71d 2004-12-28 devnull buf = malloc(bpl);
61 228bb71d 2004-12-28 devnull if(buf == nil)
62 228bb71d 2004-12-28 devnull sysfatal("can't allocate buffer: %r");
63 228bb71d 2004-12-28 devnull
64 228bb71d 2004-12-28 devnull for(y=m->r.min.y; y<m->r.max.y; y++){
65 228bb71d 2004-12-28 devnull x = unloadmemimage(m, Rect(m->r.min.x, y, m->r.max.x, y+1), (uchar*)buf, bpl);
66 228bb71d 2004-12-28 devnull if(x != bpl)
67 228bb71d 2004-12-28 devnull sysfatal("unloadmemimage");
68 228bb71d 2004-12-28 devnull for(x=0; x<wpl; x++)
69 228bb71d 2004-12-28 devnull if(buf[x] != c){
70 228bb71d 2004-12-28 devnull if(x < left)
71 228bb71d 2004-12-28 devnull left = x;
72 228bb71d 2004-12-28 devnull if(x > right)
73 228bb71d 2004-12-28 devnull right = x;
74 228bb71d 2004-12-28 devnull if(y < top)
75 228bb71d 2004-12-28 devnull top = y;
76 228bb71d 2004-12-28 devnull bottom = y;
77 228bb71d 2004-12-28 devnull }
78 228bb71d 2004-12-28 devnull }
79 228bb71d 2004-12-28 devnull
80 228bb71d 2004-12-28 devnull if(n != nil)
81 228bb71d 2004-12-28 devnull freememimage(n);
82 228bb71d 2004-12-28 devnull return Rect(left, top, right+1, bottom+1);
83 228bb71d 2004-12-28 devnull }
84 228bb71d 2004-12-28 devnull
85 228bb71d 2004-12-28 devnull void
86 228bb71d 2004-12-28 devnull main(int argc, char *argv[])
87 228bb71d 2004-12-28 devnull {
88 228bb71d 2004-12-28 devnull int fd, mode, red, green, blue;
89 228bb71d 2004-12-28 devnull Rectangle r, rparam;
90 228bb71d 2004-12-28 devnull Point t;
91 228bb71d 2004-12-28 devnull Memimage *m, *new;
92 228bb71d 2004-12-28 devnull char *file;
93 228bb71d 2004-12-28 devnull ulong bg, cropval;
94 228bb71d 2004-12-28 devnull long dw;
95 228bb71d 2004-12-28 devnull
96 228bb71d 2004-12-28 devnull memimageinit();
97 228bb71d 2004-12-28 devnull mode = None;
98 228bb71d 2004-12-28 devnull bg = 0;
99 228bb71d 2004-12-28 devnull cropval = 0;
100 228bb71d 2004-12-28 devnull t = ZP;
101 228bb71d 2004-12-28 devnull memset(&rparam, 0, sizeof rparam);
102 228bb71d 2004-12-28 devnull
103 228bb71d 2004-12-28 devnull ARGBEGIN{
104 228bb71d 2004-12-28 devnull case 'b':
105 228bb71d 2004-12-28 devnull if(bg != 0)
106 228bb71d 2004-12-28 devnull usage();
107 228bb71d 2004-12-28 devnull red = getint(ARGF())&0xFF;
108 228bb71d 2004-12-28 devnull green = getint(ARGF())&0xFF;
109 228bb71d 2004-12-28 devnull blue = getint(ARGF())&0xFF;
110 228bb71d 2004-12-28 devnull bg = (red<<24)|(green<<16)|(blue<<8)|0xFF;
111 228bb71d 2004-12-28 devnull break;
112 228bb71d 2004-12-28 devnull case 'c':
113 228bb71d 2004-12-28 devnull if(cropval != 0)
114 228bb71d 2004-12-28 devnull usage();
115 228bb71d 2004-12-28 devnull red = getint(ARGF())&0xFF;
116 228bb71d 2004-12-28 devnull green = getint(ARGF())&0xFF;
117 228bb71d 2004-12-28 devnull blue = getint(ARGF())&0xFF;
118 228bb71d 2004-12-28 devnull cropval = (red<<24)|(green<<16)|(blue<<8)|0xFF;
119 228bb71d 2004-12-28 devnull break;
120 228bb71d 2004-12-28 devnull case 'i':
121 228bb71d 2004-12-28 devnull if(mode != None)
122 228bb71d 2004-12-28 devnull usage();
123 228bb71d 2004-12-28 devnull mode = Inset;
124 228bb71d 2004-12-28 devnull rparam.min.x = getint(ARGF());
125 228bb71d 2004-12-28 devnull break;
126 228bb71d 2004-12-28 devnull case 'x':
127 228bb71d 2004-12-28 devnull if(mode != None && mode != Insetxy)
128 228bb71d 2004-12-28 devnull usage();
129 228bb71d 2004-12-28 devnull mode = Insetxy;
130 228bb71d 2004-12-28 devnull rparam.min.x = getint(ARGF());
131 228bb71d 2004-12-28 devnull break;
132 228bb71d 2004-12-28 devnull case 'y':
133 228bb71d 2004-12-28 devnull if(mode != None && mode != Insetxy)
134 228bb71d 2004-12-28 devnull usage();
135 228bb71d 2004-12-28 devnull mode = Insetxy;
136 228bb71d 2004-12-28 devnull rparam.min.y = getint(ARGF());
137 228bb71d 2004-12-28 devnull break;
138 228bb71d 2004-12-28 devnull case 'r':
139 228bb71d 2004-12-28 devnull if(mode != None)
140 228bb71d 2004-12-28 devnull usage();
141 228bb71d 2004-12-28 devnull mode = Set;
142 228bb71d 2004-12-28 devnull rparam.min.x = getint(ARGF());
143 228bb71d 2004-12-28 devnull rparam.min.y = getint(ARGF());
144 228bb71d 2004-12-28 devnull rparam.max.x = getint(ARGF());
145 228bb71d 2004-12-28 devnull rparam.max.y = getint(ARGF());
146 228bb71d 2004-12-28 devnull break;
147 228bb71d 2004-12-28 devnull case 't':
148 228bb71d 2004-12-28 devnull t.x = getint(ARGF());
149 228bb71d 2004-12-28 devnull t.y = getint(ARGF());
150 228bb71d 2004-12-28 devnull break;
151 228bb71d 2004-12-28 devnull default:
152 228bb71d 2004-12-28 devnull usage();
153 228bb71d 2004-12-28 devnull }ARGEND
154 228bb71d 2004-12-28 devnull
155 228bb71d 2004-12-28 devnull if(mode == None && cropval == 0 && eqpt(ZP, t))
156 228bb71d 2004-12-28 devnull usage();
157 228bb71d 2004-12-28 devnull
158 228bb71d 2004-12-28 devnull file = "<stdin>";
159 228bb71d 2004-12-28 devnull fd = 0;
160 228bb71d 2004-12-28 devnull if(argc > 1)
161 228bb71d 2004-12-28 devnull usage();
162 228bb71d 2004-12-28 devnull else if(argc == 1){
163 228bb71d 2004-12-28 devnull file = argv[0];
164 228bb71d 2004-12-28 devnull fd = open(file, OREAD);
165 228bb71d 2004-12-28 devnull if(fd < 0)
166 228bb71d 2004-12-28 devnull sysfatal("can't open %s: %r", file);
167 228bb71d 2004-12-28 devnull }
168 228bb71d 2004-12-28 devnull
169 228bb71d 2004-12-28 devnull m = readmemimage(fd);
170 228bb71d 2004-12-28 devnull if(m == nil)
171 228bb71d 2004-12-28 devnull sysfatal("can't read %s: %r", file);
172 228bb71d 2004-12-28 devnull
173 228bb71d 2004-12-28 devnull r = m->r;
174 228bb71d 2004-12-28 devnull if(cropval != 0){
175 228bb71d 2004-12-28 devnull r = crop(m, cropval);
176 228bb71d 2004-12-28 devnull m->clipr = r;
177 228bb71d 2004-12-28 devnull }
178 228bb71d 2004-12-28 devnull
179 228bb71d 2004-12-28 devnull switch(mode){
180 228bb71d 2004-12-28 devnull case None:
181 228bb71d 2004-12-28 devnull break;
182 228bb71d 2004-12-28 devnull case Inset:
183 228bb71d 2004-12-28 devnull r = insetrect(r, rparam.min.x);
184 228bb71d 2004-12-28 devnull break;
185 228bb71d 2004-12-28 devnull case Insetxy:
186 228bb71d 2004-12-28 devnull r.min.x += rparam.min.x;
187 228bb71d 2004-12-28 devnull r.max.x -= rparam.min.x;
188 228bb71d 2004-12-28 devnull r.min.y += rparam.min.y;
189 228bb71d 2004-12-28 devnull r.max.y -= rparam.min.y;
190 228bb71d 2004-12-28 devnull break;
191 228bb71d 2004-12-28 devnull case Set:
192 228bb71d 2004-12-28 devnull r = rparam;
193 228bb71d 2004-12-28 devnull break;
194 228bb71d 2004-12-28 devnull }
195 228bb71d 2004-12-28 devnull
196 228bb71d 2004-12-28 devnull new = allocmemimage(r, m->chan);
197 228bb71d 2004-12-28 devnull if(new == nil)
198 228bb71d 2004-12-28 devnull sysfatal("can't allocate new image: %r");
199 228bb71d 2004-12-28 devnull if(bg != 0)
200 228bb71d 2004-12-28 devnull memfillcolor(new, bg);
201 228bb71d 2004-12-28 devnull else
202 228bb71d 2004-12-28 devnull memfillcolor(new, 0x000000FF);
203 228bb71d 2004-12-28 devnull
204 228bb71d 2004-12-28 devnull memimagedraw(new, m->clipr, m, m->clipr.min, nil, ZP, S);
205 228bb71d 2004-12-28 devnull dw = byteaddr(new, ZP) - byteaddr(new, t);
206 228bb71d 2004-12-28 devnull new->r = rectaddpt(new->r, t);
207 228bb71d 2004-12-28 devnull new->zero += dw;
208 228bb71d 2004-12-28 devnull if(writememimage(1, new) < 0)
209 228bb71d 2004-12-28 devnull sysfatal("write error on output: %r");
210 228bb71d 2004-12-28 devnull exits(nil);
211 228bb71d 2004-12-28 devnull }