9 Inset, /* move border in or out uniformly */
10 Insetxy, /* move border in or out; different parameters for x and y */
11 Set, /* set rectangle to absolute values */
12 Blank, /* cut off blank region according to color value */
13 /* Blank is not actually set as a mode; it can be combined with others */
19 fprint(2, "usage: crop [-b rgb] [-c rgb] [-i ±inset | -r R | -x ±inset | -y ±inset] [-t tx ty] [imagefile]\n");
20 fprint(2, "\twhere R is a rectangle: minx miny maxx maxy\n");
21 fprint(2, "\twhere rgb is a color: red green blue\n");
30 return strtol(s, 0, 0);
34 crop(Memimage *m, ulong c)
38 int left, right, top, bottom;
46 if(m->chan != RGBA32){
47 /* convert type for simplicity */
48 n = allocmemimage(m->r, RGBA32);
50 sysfatal("can't allocate temporary image: %r");
51 memimagedraw(n, n->r, m, m->r.min, nil, ZP, S);
54 wpl = wordsperline(m->r, m->depth);
55 bpl = wpl*sizeof(ulong);
58 sysfatal("can't allocate buffer: %r");
60 for(y=m->r.min.y; y<m->r.max.y; y++){
61 x = unloadmemimage(m, Rect(m->r.min.x, y, m->r.max.x, y+1), (uchar*)buf, bpl);
63 sysfatal("unloadmemimage");
78 return Rect(left, top, right+1, bottom+1);
82 main(int argc, char *argv[])
84 int fd, mode, red, green, blue;
97 memset(&rparam, 0, sizeof rparam);
103 red = getint(ARGF())&0xFF;
104 green = getint(ARGF())&0xFF;
105 blue = getint(ARGF())&0xFF;
106 bg = (red<<24)|(green<<16)|(blue<<8)|0xFF;
111 red = getint(ARGF())&0xFF;
112 green = getint(ARGF())&0xFF;
113 blue = getint(ARGF())&0xFF;
114 cropval = (red<<24)|(green<<16)|(blue<<8)|0xFF;
120 rparam.min.x = getint(ARGF());
123 if(mode != None && mode != Insetxy)
126 rparam.min.x = getint(ARGF());
129 if(mode != None && mode != Insetxy)
132 rparam.min.y = getint(ARGF());
138 rparam.min.x = getint(ARGF());
139 rparam.min.y = getint(ARGF());
140 rparam.max.x = getint(ARGF());
141 rparam.max.y = getint(ARGF());
144 t.x = getint(ARGF());
145 t.y = getint(ARGF());
151 if(mode == None && cropval == 0 && eqpt(ZP, t))
160 fd = open(file, OREAD);
162 sysfatal("can't open %s: %r", file);
165 m = readmemimage(fd);
167 sysfatal("can't read %s: %r", file);
171 r = crop(m, cropval);
179 r = insetrect(r, rparam.min.x);
182 r.min.x += rparam.min.x;
183 r.max.x -= rparam.min.x;
184 r.min.y += rparam.min.y;
185 r.max.y -= rparam.min.y;
192 new = allocmemimage(r, m->chan);
194 sysfatal("can't allocate new image: %r");
196 memfillcolor(new, bg);
198 memfillcolor(new, 0x000000FF);
200 memimagedraw(new, m->clipr, m, m->clipr.min, nil, ZP, S);
201 dw = byteaddr(new, ZP) - byteaddr(new, t);
202 new->r = rectaddpt(new->r, t);
204 if(writememimage(1, new) < 0)
205 sysfatal("write error on output: %r");