]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/jpg/tga.c
cwfs: back to previous version
[plan9front.git] / sys / src / cmd / jpg / tga.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <draw.h>
5 #include <event.h>
6 #include "imagefile.h"
7
8 int             cflag = 0;
9 int             dflag = 0;
10 int             eflag = 0;
11 int             nineflag = 0;
12 int             threeflag = 0;
13 int             output = 0;
14 ulong           outchan = CMAP8;
15 int             defaultcolor = 1;
16 Image   *image;
17
18 enum{
19         Border  = 2,
20         Edge            = 5
21 };
22
23 char    *show(int, char*);
24
25 Rawimage** readtga(int fd);
26
27 void
28 eresized(int new)
29 {
30         Rectangle r;
31
32         if(new && getwindow(display, Refnone) < 0){
33                 fprint(2, "tga: can't reattach to window\n");
34                 exits("resize");
35         }
36         if(image == nil)
37                 return;
38         r = insetrect(screen->clipr, Edge+Border);
39         r.max.x = r.min.x+Dx(image->r);
40         r.max.y = r.min.y+Dy(image->r);
41         border(screen, r, -Border, nil, ZP);
42         drawop(screen, r, image, nil, image->r.min, S);
43         flushimage(display, 1);
44 }
45
46 void
47 main(int argc, char *argv[])
48 {
49         int fd, i;
50         char *err;
51
52         ARGBEGIN{
53         case '3':               /* produce encoded, compressed, three-color bitmap file; no display by default */
54                 threeflag++;
55                 /* fall through */
56         case 't':               /* produce encoded, compressed, true-color bitmap file; no display by default */
57                 cflag++;
58                 dflag++;
59                 output++;
60                 defaultcolor = 0;
61                 outchan = RGB24;
62                 break;
63         case 'c':               /* produce encoded, compressed, bitmap file; no display by default */
64                 cflag++;
65                 dflag++;
66                 output++;
67                 if(defaultcolor)
68                         outchan = CMAP8;
69                 break;
70         case 'd':               /* suppress display of image */
71                 dflag++;
72                 break;
73         case 'e':               /* disable floyd-steinberg error diffusion */
74                 eflag++;
75                 break;
76         case 'k':               /* force black and white */
77                 defaultcolor = 0;
78                 outchan = GREY8;
79                 break;
80         case 'v':               /* force RGBV */
81                 defaultcolor = 0;
82                 outchan = CMAP8;
83                 break;
84         case '9':               /* produce plan 9, uncompressed, bitmap file; no display by default */
85                 nineflag++;
86                 dflag++;
87                 output++;
88                 if(defaultcolor)
89                         outchan = CMAP8;
90                 break;
91         default:
92                 fprint(2, "usage: tga -39cdektv  [file ...]\n");
93                 exits("usage");
94         }ARGEND;
95
96         err = nil;
97         if(argc == 0)
98                 err = show(0, "<stdin>");
99         else{
100                 for(i=0; i<argc; i++){
101                         fd = open(argv[i], OREAD);
102                         if(fd < 0){
103                                 fprint(2, "tga: can't open %s: %r\n", argv[i]);
104                                 err = "open";
105                         }else{
106                                 err = show(fd, argv[i]);
107                                 close(fd);
108                         }
109                         if((nineflag || cflag) && argc>1 && err==nil){
110                                 fprint(2, "tga: exiting after one file\n");
111                                 break;
112                         }
113                 }
114         }
115         exits(err);
116 }
117
118 int
119 init(void)
120 {
121         static int inited;
122
123         if(inited == 0){
124                 if(initdraw(0, 0, 0) < 0){
125                         fprint(2, "tga: initdraw failed: %r");
126                         return -1;
127                 }
128                 einit(Ekeyboard|Emouse);
129                 inited++;
130         }
131         return 1;
132 }
133
134 char*
135 show(int fd, char *name)
136 {
137         Rawimage **array, *r, *c;
138         Image *i;
139         int j, ch;
140         char buf[32];
141
142         array = readtga(fd);
143         if(array == nil || array[0]==nil){
144                 fprint(2, "tga: decode %s failed: %r\n", name);
145                 return "decode";
146         }
147         if(!dflag){
148                 if(init() < 0)
149                         return "initdraw";
150                 if(defaultcolor && screen->depth>8)
151                         outchan = RGB24;
152         }
153         r = array[0];
154         if(outchan == CMAP8)
155                 c = torgbv(r, !eflag);
156         else{
157                 if(outchan==GREY8 || (r->chandesc==CY && threeflag==0))
158                         c = totruecolor(r, CY);
159                 else
160                         c = totruecolor(r, CRGB24);
161         }
162         if(c == nil){
163                 fprint(2, "tga: converting %s to local format failed: %r\n", name);
164                 return "torgbv";
165         }
166         if(!dflag){
167                 if(r->chandesc == CY)
168                         i = allocimage(display, c->r, GREY8, 0, 0);
169                 else
170                         i = allocimage(display, c->r, outchan, 0, 0);
171
172                 if(i == nil){
173                         fprint(2, "tga: allocimage %s failed: %r\n", name);
174                         return "allocimage";
175                 }
176
177                 if(loadimage(i, i->r, c->chans[0], c->chanlen) < 0){
178                         fprint(2, "tga: loadimage %s failed: %r\n", name);
179                         return "loadimage";
180                 }
181                 image = i;
182                 eresized(0);
183                 if((ch=ekbd())=='q' || ch==0x7F || ch==0x04)
184                         exits(nil);
185                 draw(screen, screen->clipr, display->white, nil, ZP);
186                 image = nil;
187                 freeimage(i);
188         }
189         if(nineflag){
190                 chantostr(buf, outchan);
191                 print("%11s %11d %11d %11d %11d ", buf,
192                         c->r.min.x, c->r.min.y, c->r.max.x, c->r.max.y);
193                 if(write(1, c->chans[0], c->chanlen) != c->chanlen){
194                         fprint(2, "tga: %s: write error %r\n", name);
195                         return "write";
196                 }
197         }else if(cflag){
198                 if(writerawimage(1, c) < 0){
199                         fprint(2, "tga: %s: write error: %r\n", name);
200                         return "write";
201                 }
202         }
203         for(j=0; j<r->nchans; j++)
204                 free(r->chans[j]);
205         free(r->cmap);
206         free(r);
207         free(array);
208         if(c){
209                 free(c->chans[0]);
210                 free(c);
211         }
212         return nil;
213 }