]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/jpg/totif.c
merge
[plan9front.git] / sys / src / cmd / jpg / totif.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <draw.h>
5 #include <memdraw.h>
6 #include "imagefile.h"
7
8 static Memimage *memtochan(Memimage *, ulong);
9
10 void
11 usage(void)
12 {
13         fprint(2, "usage: %s [-c 'comment'] "
14                 "[-3bgGhklLptvyY] [file]\n", argv0);
15         exits("usage");
16 }
17
18 void
19 main(int argc, char *argv[])
20 {
21         Biobuf bout;
22         Memimage *i, *ni;
23         int fd, chanflag, comp, opt;
24         char *err, *file, *c;
25         ulong chan;
26
27         chan = BGR24;
28         chanflag = opt = 0;
29         comp = 1;
30         c = nil;
31         ARGBEGIN {
32         case '3': /* force RGB */
33                 chan = BGR24;
34                 chanflag = 1;
35                 break;
36         case 'b':
37                 chan = GREY1;
38                 chanflag = 1;
39                 break;
40         case 'c':
41                 c = EARGF(usage());
42                 break;
43         case 'g': /* t4 */
44                 comp = 3;
45                 opt = 0;
46                 break;
47         case 'G': /* t4 two-dimensional */
48                 comp = 3;
49                 opt = 1;
50                 break;
51         case 'h': /* huffman */
52                 comp = 2;
53                 break;
54         case 'k':
55                 chan = GREY8;
56                 chanflag = 1;
57                 break;
58         case 'l': /* lzw */
59                 comp = 5;
60                 opt = 0;
61                 break;
62         case 'L': /* lzw, horizontal differencing */
63                 comp = 5;
64                 opt = 1;
65                 break;
66         case 'p': /* packbits */
67                 comp = 0x8005;
68                 break;
69         case 't': /* t6 */
70                 comp = 4;
71                 break;
72         case 'v': /* RGBV */
73                 chan = CMAP8;
74                 chanflag = 1;
75                 break;
76         case 'y':
77                 chan = GREY2;
78                 chanflag = 1;
79                 break;
80         case 'Y':
81                 chan = GREY4;
82                 chanflag = 1;
83                 break;
84         default:
85                 usage();
86         } ARGEND
87         if(argc > 1)
88                 usage();
89         if(argc == 0) {
90                 file = "<stdin>";
91                 fd = 0;
92         } else {
93                 file = argv[0];
94                 if((fd = open(file, OREAD)) < 0)
95                         sysfatal("open %s: %r", file);
96         }
97         if(Binit(&bout, 1, OWRITE) < 0)
98                 sysfatal("Binit: %r");
99         memimageinit();
100         if((i = readmemimage(fd)) == nil)
101                 sysfatal("readmemimage %s: %r", file);
102         close(fd);
103         if(comp >= 2 && comp <= 4) {
104                 chan = GREY1;
105                 chanflag = 1;
106         } else if(chan == GREY2) {
107                 if((ni = memtochan(i, chan)) == nil)
108                         sysfatal("memtochan: %r");
109                 if(i != ni) {
110                         freememimage(i);
111                         i = ni;
112                 }
113                 chan = GREY4;
114         }
115         if(!chanflag) {
116                 switch(i->chan) {
117                 case GREY1:
118                 case GREY4:
119                 case GREY8:
120                 case CMAP8:
121                 case BGR24:
122                         break;
123                 case GREY2:
124                         chan = GREY4;
125                         chanflag = 1;
126                         break;
127                 default:
128                         chanflag = 1;
129                         break;
130                 }
131         }
132         if(chanflag) {
133                 if((ni = memtochan(i, chan)) == nil)
134                         sysfatal("memtochan: %r");
135                 if(i != ni) {
136                         freememimage(i);
137                         i = ni;
138                 }
139         }
140         if((err = memwritetif(&bout, i, c, comp, opt)) != nil)
141                 fprint(2, "%s: %s\n", argv0, err);
142         freememimage(i);
143         exits(err);
144 }
145
146 static Memimage *
147 memtochan(Memimage *i, ulong chan)
148 {
149         Memimage *ni;
150
151         if(i->chan == chan)
152                 return i;
153         if((ni = allocmemimage(i->r, chan)) == nil)
154                 return nil;
155         memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S);
156         return ni;
157 }