]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/jpg/writetif.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / jpg / writetif.c
1 /*
2 * code/documentation:
3 * http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
4 * http://www.fileformat.info/format/tiff/egff.htm
5 * http://www.fileformat.info/mirror/egff/ch09_05.htm
6 * http://www.itu.int/rec/T-REC-T.4-199904-S/en
7 * http://www.itu.int/rec/T-REC-T.6-198811-I/en
8 *
9 * many thanks to paul bourke for a simple description of tiff:
10 * http://paulbourke.net/dataformats/tiff/
11 *
12 * copy-pasted fax codes and copy-pasted lzw encoding
13 * hash table implementation:
14 * http://www.remotesensing.org/libtiff/
15 */
16 #include <u.h>
17 #include <libc.h>
18 #include <bio.h>
19 #include <draw.h>
20 #include <memdraw.h>
21 #include "imagefile.h"
22
23 enum {
24         Tbyte = 0x0001,
25         Tascii = 0x0002,
26         Tshort = 0x0003,
27         Tlong = 0x0004,
28         Trational = 0x0005,
29         Tnocomp = 0x0001,
30         Thuffman = 0x0002,
31         Tt4enc = 0x0003,
32         Tt6enc = 0x0004,
33         Tlzw = 0x0005,
34         Tpackbits = 0x8005
35 };
36
37 enum {
38         Twidth,
39         Tlength,
40         Tbits,
41         Tcomp,
42         Tphoto,
43         Tfill,
44         Tdesc,
45         Tstrips,
46         Tsamples,
47         Trows,
48         Tcounts,
49         Txres,
50         Tyres,
51         T4opt,
52         Tresunit,
53         Tpredictor,
54         Tcolor
55 };
56
57 enum {
58         Kpar = 2,
59         Nfaxtab = 105
60 };
61
62 enum {
63         Clrcode = 256,
64         Eoicode = 257,
65         Tabsz = 1<<12,
66         Hshift = 13 - 8,
67         Hsize = 9001L
68 };
69
70 typedef struct Tab Tab;
71 typedef struct Fax Fax;
72 typedef struct Hash Hash;
73 typedef struct Lzw Lzw;
74 typedef struct Pkb Pkb;
75 typedef struct Fld Fld;
76 typedef struct Tif Tif;
77
78 struct Tab {
79         int len;
80         int code;
81         int run;
82 };
83
84 struct Fax {
85         int st;
86         Tab *tab[2];
87         int byte;
88         int nbyte;
89         ulong *l1;
90         ulong *l2;
91         uchar *data;
92         ulong ndata;
93         ulong n;
94 };
95
96 struct Hash {
97         long hash;
98         u16int code;
99 };
100
101 struct Lzw {
102         Hash hash[Hsize];
103         int ntab;
104         int len;
105         int byte;
106         int nbyte;
107         uchar *data;
108         ulong ndata;
109         ulong n;
110 };
111
112 struct Pkb {
113         uchar *data;
114         ulong ndata;
115         ulong n;
116 };
117
118 struct Fld {
119         ushort tag;
120         ushort typ;
121 };
122
123 struct Tif {
124         ulong dx;
125         ulong dy;
126         ushort depth[3];
127         ushort comp;
128         ulong opt;
129         char *(*compress)(Tif *);
130         ushort photo;
131         char *desc;
132         ulong *strips;
133         ulong nstrips;
134         ushort samples;
135         ulong rows;
136         ulong *counts;
137         ushort *color;
138         ulong ncolor;
139         uchar *data;
140         ulong ndata;
141         ushort nfld;
142         int bpl;
143 };
144
145 static Fld flds[] = {
146         [Twidth] {0x0100, Tlong},
147         [Tlength] {0x0101, Tlong},
148         [Tbits] {0x0102, Tshort},
149         [Tcomp] {0x0103, Tshort},
150         [Tphoto] {0x0106, Tshort},
151         [Tfill] {0x010a, Tshort},
152         [Tdesc] {0x010e, Tascii},
153         [Tstrips] {0x0111, Tlong},
154         [Tsamples] {0x0115, Tshort},
155         [Trows] {0x0116, Tlong},
156         [Tcounts] {0x0117, Tlong},
157         [Txres] {0x011a, Trational},
158         [Tyres] {0x011b, Trational},
159         [T4opt] {0x0124, Tlong},
160         [Tresunit] {0x0128, Tshort},
161         [Tpredictor] {0x013d, Tshort},
162         [Tcolor] {0x0140, Tshort}
163 };
164
165 /*
166 * imported from libdraw/arith.c to permit
167 * extern log2 function
168 */
169 static int log2[] = {
170         -1, 0, 1, -1, 2, -1, -1, -1, 3,
171         -1, -1, -1, -1, -1, -1, -1, 4,
172         -1, -1, -1, -1, -1, -1, -1, 4 /* BUG */,
173         -1, -1, -1, -1, -1, -1, -1, 5
174 };
175
176 static Tab faxwhite[Nfaxtab] = {
177         {8, 0x35, 0}, /* 0011 0101 */
178         {6, 0x7, 1}, /* 0001 11 */
179         {4, 0x7, 2}, /* 0111 */
180         {4, 0x8, 3}, /* 1000 */
181         {4, 0xb, 4}, /* 1011 */
182         {4, 0xc, 5}, /* 1100 */
183         {4, 0xe, 6}, /* 1110 */
184         {4, 0xf, 7}, /* 1111 */
185         {5, 0x13, 8}, /* 1001 1 */
186         {5, 0x14, 9}, /* 1010 0 */
187         {5, 0x7, 10}, /* 0011 1 */
188         {5, 0x8, 11}, /* 0100 0 */
189         {6, 0x8, 12}, /* 0010 00 */
190         {6, 0x3, 13}, /* 0000 11 */
191         {6, 0x34, 14}, /* 1101 00 */
192         {6, 0x35, 15}, /* 1101 01 */
193         {6, 0x2a, 16}, /* 1010 10 */
194         {6, 0x2b, 17}, /* 1010 11 */
195         {7, 0x27, 18}, /* 0100 111 */
196         {7, 0xc, 19}, /* 0001 100 */
197         {7, 0x8, 20}, /* 0001 000 */
198         {7, 0x17, 21}, /* 0010 111 */
199         {7, 0x3, 22}, /* 0000 011 */
200         {7, 0x4, 23}, /* 0000 100 */
201         {7, 0x28, 24}, /* 0101 000 */
202         {7, 0x2b, 25}, /* 0101 011 */
203         {7, 0x13, 26}, /* 0010 011 */
204         {7, 0x24, 27}, /* 0100 100 */
205         {7, 0x18, 28}, /* 0011 000 */
206         {8, 0x2, 29}, /* 0000 0010 */
207         {8, 0x3, 30}, /* 0000 0011 */
208         {8, 0x1a, 31}, /* 0001 1010 */
209         {8, 0x1b, 32}, /* 0001 1011 */
210         {8, 0x12, 33}, /* 0001 0010 */
211         {8, 0x13, 34}, /* 0001 0011 */
212         {8, 0x14, 35}, /* 0001 0100 */
213         {8, 0x15, 36}, /* 0001 0101 */
214         {8, 0x16, 37}, /* 0001 0110 */
215         {8, 0x17, 38}, /* 0001 0111 */
216         {8, 0x28, 39}, /* 0010 1000 */
217         {8, 0x29, 40}, /* 0010 1001 */
218         {8, 0x2a, 41}, /* 0010 1010 */
219         {8, 0x2b, 42}, /* 0010 1011 */
220         {8, 0x2c, 43}, /* 0010 1100 */
221         {8, 0x2d, 44}, /* 0010 1101 */
222         {8, 0x4, 45}, /* 0000 0100 */
223         {8, 0x5, 46}, /* 0000 0101 */
224         {8, 0xa, 47}, /* 0000 1010 */
225         {8, 0xb, 48}, /* 0000 1011 */
226         {8, 0x52, 49}, /* 0101 0010 */
227         {8, 0x53, 50}, /* 0101 0011 */
228         {8, 0x54, 51}, /* 0101 0100 */
229         {8, 0x55, 52}, /* 0101 0101 */
230         {8, 0x24, 53}, /* 0010 0100 */
231         {8, 0x25, 54}, /* 0010 0101 */
232         {8, 0x58, 55}, /* 0101 1000 */
233         {8, 0x59, 56}, /* 0101 1001 */
234         {8, 0x5a, 57}, /* 0101 1010 */
235         {8, 0x5b, 58}, /* 0101 1011 */
236         {8, 0x4a, 59}, /* 0100 1010 */
237         {8, 0x4b, 60}, /* 0100 1011 */
238         {8, 0x32, 61}, /* 0011 0010 */
239         {8, 0x33, 62}, /* 0011 0011 */
240         {8, 0x34, 63}, /* 0011 0100 */
241         {5, 0x1b, 64}, /* 1101 1 */
242         {5, 0x12, 128}, /* 1001 0 */
243         {6, 0x17, 192}, /* 0101 11 */
244         {7, 0x37, 256}, /* 0110 111 */
245         {8, 0x36, 320}, /* 0011 0110 */
246         {8, 0x37, 384}, /* 0011 0111 */
247         {8, 0x64, 448}, /* 0110 0100 */
248         {8, 0x65, 512}, /* 0110 0101 */
249         {8, 0x68, 576}, /* 0110 1000 */
250         {8, 0x67, 640}, /* 0110 0111 */
251         {9, 0xcc, 704}, /* 0110 0110 0 */
252         {9, 0xcd, 768}, /* 0110 0110 1 */
253         {9, 0xd2, 832}, /* 0110 1001 0 */
254         {9, 0xd3, 896}, /* 0110 1001 1 */
255         {9, 0xd4, 960}, /* 0110 1010 0 */
256         {9, 0xd5, 1024}, /* 0110 1010 1 */
257         {9, 0xd6, 1088}, /* 0110 1011 0 */
258         {9, 0xd7, 1152}, /* 0110 1011 1 */
259         {9, 0xd8, 1216}, /* 0110 1100 0 */
260         {9, 0xd9, 1280}, /* 0110 1100 1 */
261         {9, 0xda, 1344}, /* 0110 1101 0 */
262         {9, 0xdb, 1408}, /* 0110 1101 1 */
263         {9, 0x98, 1472}, /* 0100 1100 0 */
264         {9, 0x99, 1536}, /* 0100 1100 1 */
265         {9, 0x9a, 1600}, /* 0100 1101 0 */
266         {6, 0x18, 1664}, /* 0110 00 */
267         {9, 0x9b, 1728}, /* 0100 1101 1 */
268         {11, 0x8, 1792}, /* 0000 0001 000 */
269         {11, 0xc, 1856}, /* 0000 0001 100 */
270         {11, 0xd, 1920}, /* 0000 0001 101 */
271         {12, 0x12, 1984}, /* 0000 0001 0010 */
272         {12, 0x13, 2048}, /* 0000 0001 0011 */
273         {12, 0x14, 2112}, /* 0000 0001 0100 */
274         {12, 0x15, 2176}, /* 0000 0001 0101 */
275         {12, 0x16, 2240}, /* 0000 0001 0110 */
276         {12, 0x17, 2304}, /* 0000 0001 0111 */
277         {12, 0x1c, 2368}, /* 0000 0001 1100 */
278         {12, 0x1d, 2432}, /* 0000 0001 1101 */
279         {12, 0x1e, 2496}, /* 0000 0001 1110 */
280         {12, 0x1f, 2560}, /* 0000 0001 1111 */
281         {12, 0x1, -1} /* 0000 0000 0001 */
282 };
283
284 static Tab faxblack[Nfaxtab] = {
285         {10, 0x37, 0}, /* 0000 1101 11 */
286         {3, 0x2, 1}, /* 010 */
287         {2, 0x3, 2}, /* 11 */
288         {2, 0x2, 3}, /* 10 */
289         {3, 0x3, 4}, /* 011 */
290         {4, 0x3, 5}, /* 0011 */
291         {4, 0x2, 6}, /* 0010 */
292         {5, 0x3, 7}, /* 0001 1 */
293         {6, 0x5, 8}, /* 0001 01 */
294         {6, 0x4, 9}, /* 0001 00 */
295         {7, 0x4, 10}, /* 0000 100 */
296         {7, 0x5, 11}, /* 0000 101 */
297         {7, 0x7, 12}, /* 0000 111 */
298         {8, 0x4, 13}, /* 0000 0100 */
299         {8, 0x7, 14}, /* 0000 0111 */
300         {9, 0x18, 15}, /* 0000 1100 0 */
301         {10, 0x17, 16}, /* 0000 0101 11 */
302         {10, 0x18, 17}, /* 0000 0110 00 */
303         {10, 0x8, 18}, /* 0000 0010 00 */
304         {11, 0x67, 19}, /* 0000 1100 111 */
305         {11, 0x68, 20}, /* 0000 1101 000 */
306         {11, 0x6c, 21}, /* 0000 1101 100 */
307         {11, 0x37, 22}, /* 0000 0110 111 */
308         {11, 0x28, 23}, /* 0000 0101 000 */
309         {11, 0x17, 24}, /* 0000 0010 111 */
310         {11, 0x18, 25}, /* 0000 0011 000 */
311         {12, 0xca, 26}, /* 0000 1100 1010 */
312         {12, 0xcb, 27}, /* 0000 1100 1011 */
313         {12, 0xcc, 28}, /* 0000 1100 1100 */
314         {12, 0xcd, 29}, /* 0000 1100 1101 */
315         {12, 0x68, 30}, /* 0000 0110 1000 */
316         {12, 0x69, 31}, /* 0000 0110 1001 */
317         {12, 0x6a, 32}, /* 0000 0110 1010 */
318         {12, 0x6b, 33}, /* 0000 0110 1011 */
319         {12, 0xd2, 34}, /* 0000 1101 0010 */
320         {12, 0xd3, 35}, /* 0000 1101 0011 */
321         {12, 0xd4, 36}, /* 0000 1101 0100 */
322         {12, 0xd5, 37}, /* 0000 1101 0101 */
323         {12, 0xd6, 38}, /* 0000 1101 0110 */
324         {12, 0xd7, 39}, /* 0000 1101 0111 */
325         {12, 0x6c, 40}, /* 0000 0110 1100 */
326         {12, 0x6d, 41}, /* 0000 0110 1101 */
327         {12, 0xda, 42}, /* 0000 1101 1010 */
328         {12, 0xdb, 43}, /* 0000 1101 1011 */
329         {12, 0x54, 44}, /* 0000 0101 0100 */
330         {12, 0x55, 45}, /* 0000 0101 0101 */
331         {12, 0x56, 46}, /* 0000 0101 0110 */
332         {12, 0x57, 47}, /* 0000 0101 0111 */
333         {12, 0x64, 48}, /* 0000 0110 0100 */
334         {12, 0x65, 49}, /* 0000 0110 0101 */
335         {12, 0x52, 50}, /* 0000 0101 0010 */
336         {12, 0x53, 51}, /* 0000 0101 0011 */
337         {12, 0x24, 52}, /* 0000 0010 0100 */
338         {12, 0x37, 53}, /* 0000 0011 0111 */
339         {12, 0x38, 54}, /* 0000 0011 1000 */
340         {12, 0x27, 55}, /* 0000 0010 0111 */
341         {12, 0x28, 56}, /* 0000 0010 1000 */
342         {12, 0x58, 57}, /* 0000 0101 1000 */
343         {12, 0x59, 58}, /* 0000 0101 1001 */
344         {12, 0x2b, 59}, /* 0000 0010 1011 */
345         {12, 0x2c, 60}, /* 0000 0010 1100 */
346         {12, 0x5a, 61}, /* 0000 0101 1010 */
347         {12, 0x66, 62}, /* 0000 0110 0110 */
348         {12, 0x67, 63}, /* 0000 0110 0111 */
349         {10, 0xf, 64}, /* 0000 0011 11 */
350         {12, 0xc8, 128}, /* 0000 1100 1000 */
351         {12, 0xc9, 192}, /* 0000 1100 1001 */
352         {12, 0x5b, 256}, /* 0000 0101 1011 */
353         {12, 0x33, 320}, /* 0000 0011 0011 */
354         {12, 0x34, 384}, /* 0000 0011 0100 */
355         {12, 0x35, 448}, /* 0000 0011 0101 */
356         {13, 0x6c, 512}, /* 0000 0011 0110 0 */
357         {13, 0x6d, 576}, /* 0000 0011 0110 1 */
358         {13, 0x4a, 640}, /* 0000 0010 0101 0 */
359         {13, 0x4b, 704}, /* 0000 0010 0101 1 */
360         {13, 0x4c, 768}, /* 0000 0010 0110 0 */
361         {13, 0x4d, 832}, /* 0000 0010 0110 1 */
362         {13, 0x72, 896}, /* 0000 0011 1001 0 */
363         {13, 0x73, 960}, /* 0000 0011 1001 1 */
364         {13, 0x74, 1024}, /* 0000 0011 1010 0 */
365         {13, 0x75, 1088}, /* 0000 0011 1010 1 */
366         {13, 0x76, 1152}, /* 0000 0011 1011 0 */
367         {13, 0x77, 1216}, /* 0000 0011 1011 1 */
368         {13, 0x52, 1280}, /* 0000 0010 1001 0 */
369         {13, 0x53, 1344}, /* 0000 0010 1001 1 */
370         {13, 0x54, 1408}, /* 0000 0010 1010 0 */
371         {13, 0x55, 1472}, /* 0000 0010 1010 1 */
372         {13, 0x5a, 1536}, /* 0000 0010 1101 0 */
373         {13, 0x5b, 1600}, /* 0000 0010 1101 1 */
374         {13, 0x64, 1664}, /* 0000 0011 0010 0 */
375         {13, 0x65, 1728}, /* 0000 0011 0010 1 */
376         {11, 0x8, 1792}, /* 0000 0001 000 */
377         {11, 0xc, 1856}, /* 0000 0001 100 */
378         {11, 0xd, 1920}, /* 0000 0001 101 */
379         {12, 0x12, 1984}, /* 0000 0001 0010 */
380         {12, 0x13, 2048}, /* 0000 0001 0011 */
381         {12, 0x14, 2112}, /* 0000 0001 0100 */
382         {12, 0x15, 2176}, /* 0000 0001 0101 */
383         {12, 0x16, 2240}, /* 0000 0001 0110 */
384         {12, 0x17, 2304}, /* 0000 0001 0111 */
385         {12, 0x1c, 2368}, /* 0000 0001 1100 */
386         {12, 0x1d, 2432}, /* 0000 0001 1101 */
387         {12, 0x1e, 2496}, /* 0000 0001 1110 */
388         {12, 0x1f, 2560}, /* 0000 0001 1111 */
389         {12, 0x1, -1} /* 0000 0000 0001 */
390 };
391
392 static Tab faxcodes[] = {
393         {4, 0x1, 0}, /* 0001 */
394         {3, 0x1, 0}, /* 001 */
395         {1, 0x1, 0}, /* 1 */
396         {3, 0x2, 0}, /* 010 */
397         {6, 0x2, 0}, /* 0000 10 */
398         {7, 0x2, 0}, /* 0000 010 */
399         {3, 0x3, 0}, /* 011 */
400         {6, 0x3, 0}, /* 0000 11 */
401         {7, 0x3, 0} /* 0000 011 */
402 };
403
404 static int typesizes[] = {0, 1, 1, 2, 4, 8};
405 static char memerr[] = "WriteTIF: malloc failed";
406
407 static int
408 put1(Biobuf *b, uchar c)
409 {
410         return Bputc(b, c);
411 }
412
413 static int
414 put2(Biobuf *b, uint s)
415 {
416         if(put1(b, s>>8) < 0)
417                 return -1;
418         return put1(b, s);
419 }
420
421 static int
422 put4(Biobuf *b, ulong l)
423 {
424         if(put2(b, l>>16) < 0)
425                 return -1;
426         return put2(b, l);
427 }
428
429 static char *
430 nocomp(Tif *)
431 {
432         return nil;
433 }
434
435 static char *
436 faxputbyte(Fax *f)
437 {
438         if(f->n >= f->ndata) {
439                 f->ndata *= 2;
440                 f->data = realloc(f->data,
441                         f->ndata*sizeof *f->data);
442                 if(f->data == nil)
443                         return memerr;
444         }
445         f->data[f->n++] = f->byte;
446         f->byte = f->nbyte = 0;
447         return nil;
448 }
449
450 static char *
451 faxputbit(Fax *f, int bit)
452 {
453         f->byte = (f->byte << 1) | bit;
454         f->nbyte++;
455         return f->nbyte >= 8? faxputbyte(f): nil;
456 }
457
458 static char *
459 faxbytealign(Fax *f)
460 {
461         char *err;
462
463         err = nil;
464         if(f->nbyte != 0) {
465                 f->byte <<= 8 - f->nbyte;
466                 err = faxputbyte(f);
467         }
468         return err;
469 }
470
471 static char *
472 faxputcode(Fax *f, Tab *tab)
473 {
474         int i, bit;
475         char *err;
476
477         for(i = tab->len-1; i >= 0; i--) {
478                 bit = (tab->code >> i) & 0x1;
479                 if((err = faxputbit(f, bit)) != nil)
480                         return err;
481         }
482         return nil;
483 }
484
485 static int
486 faxgettab(int run)
487 {
488         if(run >= 0) {
489                 if(run <= 64)
490                         return run;
491                 if(run <= 2560)
492                         return 64 + run/64 - 1;
493         }
494         return Nfaxtab - 1;
495 }
496
497 static char *
498 faxputrun(Fax *f, long run)
499 {
500         char *err;
501         Tab *tab, *p;
502
503         tab = f->tab[f->st];
504         p = &tab[faxgettab(2560)];
505         while(run >= 2624) {
506                 if((err = faxputcode(f, p)) != nil)
507                         return err;
508                 run -= 2560;
509         }
510         if(run >= 64) {
511                 p = &tab[faxgettab(run)];
512                 if((err = faxputcode(f, p)) != nil)
513                         return err;
514                 run -= p->run;
515         }
516         p = &tab[faxgettab(run)];
517         err = faxputcode(f, p);
518         f->st ^= 1;
519         return err;
520 }
521
522 static char *
523 faxputeol(Fax *f)
524 {
525         return faxputcode(f, &f->tab[0][faxgettab(-1)]);
526 }
527
528 static char *
529 fax1d(Fax *f, ulong dx)
530 {
531         ulong i;
532         long run;
533         char *err;
534
535         f->st = 0;
536         run = f->l2[0];
537         for(i = 0;;) {
538                 if((err = faxputrun(f, run)) != nil)
539                         return err;
540                 if(f->l2[i++] >= dx)
541                         break;
542                 run = f->l2[i] - f->l2[i-1];
543         }
544         memmove(f->l1, f->l2, i*sizeof *f->l1);
545         return nil;
546 }
547
548 static char *
549 fax2d(Fax *f, ulong dx)
550 {
551         int j, v;
552         ulong i;
553         long a0, a1, a2, b1, b2;
554         char *err;
555         Tab *tab, *p;
556
557         f->st = 0;
558         a0 = a1 = -1;
559         tab = faxcodes;
560         for(i = 0, err = nil; err == nil;) {
561                 while(a1 <= a0)
562                         a1 = f->l2[i++];
563                 for(j = 0;; j++) {
564                         b1 = f->l1[j];
565                         if(b1 > a0 && f->st == j%2)
566                                 break;
567                         if(b1 >= dx)
568                                 break;
569                 }
570                 if((b2 = b1) < dx)
571                         b2 = f->l1[j+1];
572                 if(b2 < a1) {
573                         /* pass */
574                         p = &tab[0];
575                         err = faxputcode(f, p);
576                         a0 = b2;
577                 } else if(abs(v = a1-b1) < 3) {
578                         /* vertical */
579                         p = &tab[2+(v>0?3:0)+abs(v)];
580                         err = faxputcode(f, p);
581                         f->st ^= 1;
582                         a0 = a1;
583                 } else {
584                         /* horizontal */
585                         if(a0 < 0)
586                                 a0 = 0;
587                         p = &tab[1];
588                         if((err = faxputcode(f, p)) != nil)
589                                 return err;
590                         a2 = a1 < dx? f->l2[i++]: a1;
591                         if((err = faxputrun(f, a1-a0)) != nil)
592                                 return err;
593                         err = faxputrun(f, a2-a1);
594                         a0 = a2;
595                 }
596                 if(a0 >= dx)
597                         break;
598         }
599         memmove(f->l1, f->l2, i*sizeof *f->l1);
600         return err;
601 }
602
603 static char *
604 faxstrip(Tif *t, Fax *f, uchar *data, ulong n, ulong dx)
605 {
606         int k, s, d1, two;
607         ulong i, j, x;
608         char *err;
609
610         d1 = t->comp != Tt6enc;
611         two = 0;
612         if(t->comp == Tt4enc) {
613                 if((err = faxputeol(f)) != nil)
614                         return err;
615                 if(t->opt && (err = faxputbit(f, 1)) != nil)
616                         return err;
617         }
618         for(i = j = x = 0; i < n;) {
619                 s = 7 - x++%8;
620                 k = ((data[i] >> s) & 0x1) ^ 0x1;
621                 if(s == 0)
622                         i++;
623                 if(k != f->st) {
624                         f->l2[j++] = x - 1;
625                         f->st ^= 1;
626                 }
627                 if(x == dx) {
628                         f->l2[j] = dx;
629                         if(d1) {
630                                 err = fax1d(f, dx);
631                                 if(t->comp == Tt4enc &&
632                                         t->opt) {
633                                         two = Kpar - 1;
634                                         d1 = 0;
635                                 }
636                         } else {
637                                 err = fax2d(f, dx);
638                                 if(two > 0 && --two <= 0)
639                                         d1 = 1;
640                         }
641                         if(err != nil)
642                                 return err;
643                         if(t->comp == Thuffman)
644                                 err = faxbytealign(f);
645                         else if(t->comp == Tt4enc &&
646                                 t->opt) {
647                                 if((err = faxputeol(f)) != nil)
648                                         return err;
649                                 err = faxputbit(f, d1);
650                         } else if(t->comp == Tt4enc)
651                                 err = faxputeol(f);
652                         if(err != nil)
653                                 return err;
654                         f->st = 0;
655                         if(s != 0)
656                                 i++;
657                         x = 0;
658                         j = 0;
659                 }
660         }
661         if(t->comp == Tt4enc || t->comp == Tt6enc) {
662                 i = t->comp == Tt4enc? 5: 2;
663                 for(; i > 0; i--) {
664                         if((err = faxputeol(f)) != nil)
665                                 return err;
666                         if(t->comp == Tt4enc && t->opt) {
667                                 err = faxputbit(f, 1);
668                                 if(err != nil)
669                                         return err;
670                         }
671                 }
672         }
673         return faxbytealign(f);
674 }
675
676 static char *
677 fax(Tif *t)
678 {
679         ulong i, m, n;
680         char *err;
681         uchar *data;
682         Fax f;
683
684         f.ndata = t->ndata;
685         if((f.data = malloc(f.ndata*sizeof *f.data)) == nil)
686                 return memerr;
687         f.l1 = mallocz((t->dx+1)*sizeof *f.l1, 1);
688         f.l2 = mallocz((t->dx+1)*sizeof *f.l2, 1);
689         if(f.l1 == nil || f.l2 == nil) {
690                 free(f.data);
691                 if(f.l1 != nil)
692                         free(f.l1);
693                 if(f.l2 != nil)
694                         free(f.l2);
695                 return memerr;
696         }
697         f.tab[0] = faxwhite;
698         f.tab[1] = faxblack;
699         f.n = f.byte = f.nbyte = 0;
700         for(i = n = 0, data = t->data; i < t->nstrips; i++) {
701                 f.st = 0;
702                 f.l1[0] = t->dx;
703                 m = t->counts[i];
704                 if((err = faxstrip(t, &f, data, m, t->dx)) != nil) {
705                         if(f.data != nil)
706                                 free(f.data);
707                         return err;
708                 }
709                 data += m;
710                 t->counts[i] = f.n - n;
711                 n = f.n;
712         }
713         free(t->data);
714         free(f.l1);
715         free(f.l2);
716         t->data = f.data;
717         t->ndata = f.n;
718         return nil;
719 }
720
721 static void
722 lzwtabinit(Lzw *l)
723 {
724         long i;
725         Hash *hp;
726
727         l->ntab = Eoicode + 1;
728         l->len = 9;
729         hp = &l->hash[Hsize-1];
730         i = Hsize - 8;
731         do {
732                 i -= 8;
733                 hp[-7].hash = -1;
734                 hp[-6].hash = -1;
735                 hp[-5].hash = -1;
736                 hp[-4].hash = -1;
737                 hp[-3].hash = -1;
738                 hp[-2].hash = -1;
739                 hp[-1].hash = -1;
740                 hp[0].hash = -1;
741                 hp -= 8;
742         } while(i >= 0);
743         for(i += 8; i > 0; i--, hp--)
744                 hp->hash = -1;
745 }
746
747 static char *
748 lzwputbyte(Lzw *l)
749 {
750         if(l->n >= l->ndata) {
751                 l->ndata *= 2;
752                 l->data = realloc(l->data,
753                         l->ndata*sizeof *l->data);
754                 if(l->data == nil)
755                         return memerr;
756         }
757         l->data[l->n++] = l->byte;
758         l->byte = l->nbyte = 0;
759         return nil;
760 }
761
762 static char *
763 lzwbytealign(Lzw *l)
764 {
765         char *err;
766
767         err = nil;
768         if(l->nbyte != 0) {
769                 l->byte <<= 8 - l->nbyte;
770                 err = lzwputbyte(l);
771         }
772         return err;
773 }
774
775 static char *
776 lzwputcode(Lzw *l, int code)
777 {
778         int i, c;
779         char *err;
780
781         for(i = l->len-1; i >= 0; i--) {
782                 c = (code >> i) & 0x1;
783                 l->byte = (l->byte << 1) | c;
784                 l->nbyte++;
785                 if(l->nbyte >= 8) {
786                         if((err = lzwputbyte(l)) != nil)
787                                 return err;
788                 }
789         }
790         return nil;
791 }
792
793 static void
794 predict1(Tif *t)
795 {
796         int pix, b[8], d, m, n, j;
797         ulong x, y;
798         uchar *data, *p;
799
800         p = t->data;
801         d = *t->depth;
802         m = (1 << d) - 1;
803         n = 8 / d;
804         for(y = 0; y < t->dy; y++) {
805                 data = p += t->bpl;
806                 for(x = t->bpl; x > 0; x--) {
807                         pix = *--data;
808                         for(j = 0; j < n; j++) {
809                                 b[j] = (pix >> d*j) & m;
810                                 if(j > 0)
811                                         b[j-1] -= b[j];
812                         }
813                         if(x > 1)
814                                 b[n-1] -= *(data-1) & m;
815                         for(j = pix = 0; j < n; j++)
816                                 pix |= (b[j] & m) << d*j;
817                         *data = pix;
818                 }
819         }
820 }
821
822 static void
823 predict8(Tif *t)
824 {
825         ulong j, s, x, y;
826         uchar *data, *p;
827
828         p = t->data;
829         s = t->samples;
830         for(y = 0; y < t->dy; y++) {
831                 data = p += t->dx * s;
832                 for(x = t->dx; x > 1; x--) {
833                         for(j = 0; j < s; j++) {
834                                 data--;
835                                 *data -= *(data-s);
836                         }
837                 }
838         }
839 }
840
841 static char *
842 lzwstrip(Lzw *l, uchar *data, ulong n)
843 {
844         int k, h;
845         long fcode, disp;
846         ulong i;
847         char *err;
848         Hash *hp;
849         u16int ent;
850
851         if((err = lzwputcode(l, Clrcode)) != nil)
852                 return err;
853         i = 0;
854         ent = data[i++];
855         for(; i < n; i++) {
856                 k = data[i];
857                 fcode = ((long)k << 12) + ent;
858                 h = (k << Hshift) ^ ent;
859                 hp = &l->hash[h];
860                 if(hp->hash == fcode) {
861 hit:
862                         ent = hp->code;
863                         continue;
864                 }
865                 if(hp->hash >= 0) {
866                         disp = h == 0? 1: Hsize - h;
867                         do {
868                                 if((h -= disp) < 0)
869                                         h += Hsize;
870                                 hp = &l->hash[h];
871                                 if(hp->hash == fcode)
872                                         goto hit;
873                         } while(hp->hash >= 0);
874                 }
875                 if((err = lzwputcode(l, ent)) != nil)
876                         return err;
877                 ent = k;
878                 hp->hash = fcode;
879                 switch(hp->code = l->ntab) {
880                 case 511:
881                 case 1023:
882                 case 2047:
883                         l->len++;
884                         break;
885                 default:
886                         break;
887                 }
888                 if(l->ntab++ >= Tabsz-2) {
889                         err = lzwputcode(l, Clrcode);
890                         if(err != nil)
891                                 return err;
892                         lzwtabinit(l);
893                 }
894         }
895         if((err = lzwputcode(l, ent)) != nil)
896                 return err;
897         if((err = lzwputcode(l, Eoicode)) != nil)
898                 return err;
899         return lzwbytealign(l);
900 }
901
902 static char *
903 lzw(Tif *t)
904 {
905         ulong i, m, n;
906         char *err;
907         uchar *data;
908         Lzw l;
909
910         if(t->opt)
911                 *t->depth < 8? predict1(t): predict8(t);
912         l.ndata = t->ndata;
913         if((l.data = malloc(l.ndata*sizeof *l.data)) == nil)
914                 return memerr;
915         l.n = l.byte = l.nbyte = 0;
916         err = nil;
917         for(i = n = 0, data = t->data; i < t->nstrips; i++) {
918                 lzwtabinit(&l);
919                 m = t->counts[i];
920                 if((err = lzwstrip(&l, data, m)) != nil)
921                         break;
922                 data += m;
923                 t->counts[i] = l.n - n;
924                 n = l.n;
925         }
926         if(err != nil) {
927                 if(l.data != nil)
928                         free(l.data);
929                 return err;
930         }
931         free(t->data);
932         t->data = l.data;
933         t->ndata = l.n;
934         return nil;
935 }
936
937 static char *
938 pkbrow(Pkb *p, uchar *data, int ndata, long *buf)
939 {
940         int b, repl;
941         long i, j, k, n;
942         ulong m;
943
944         i = n = 0;
945         buf[n++] = i;
946         b = data[i++];
947         if(i < ndata)
948                 repl = b == data[i]? 1: 0;
949         else
950                 repl = 0;
951         for(; i < ndata; i++) {
952                 k = data[i];
953                 j = labs(buf[n-1]);
954                 if(repl) {
955                         if(b != k) {
956                                 repl ^= 1;
957                                 buf[n++] = -i;
958                         }
959                 } else {
960                         if(b == k) {
961                                 repl ^= 1;
962                                 if(i-j > 1)
963                                         buf[n++] = i - 1;
964                         }
965                 }
966                 b = k;
967         }
968         buf[n++] = repl? -i: i;
969         for(i = 1; i < n;) {
970                 k = buf[i];
971                 j = labs(buf[i-1]);
972                 if(i < n-2 && k > 0 && buf[i+1] < 0 &&
973                         buf[i+2] > 0 && -buf[i+1]-k <= 2) {
974                         buf[i] = buf[i+1] = buf[i+2];
975                         continue;
976                 }
977                 if((b = labs(k) - j) > 128) {
978                         b = 128;
979                         buf[i-1] += buf[i-1] < 0? -b: b;
980                 } else
981                         i++;
982                 if(b == 0)
983                         continue;
984                 m = 1 + (k < 0? 1: b);
985                 if(p->n+m > p->ndata) {
986                         p->ndata = (p->n + m) * 2;
987                         p->data = realloc(p->data,
988                                 p->ndata*sizeof *p->data);
989                         if(p->data == nil)
990                                 return memerr;
991                 }
992                 if(k < 0) {
993                         p->data[p->n++] = 1 - b;
994                         p->data[p->n++] = data[j];
995                 } else {
996                         p->data[p->n++] = b - 1;
997                         memmove(p->data+p->n, data+j, b);
998                         p->n += b;
999                 }
1000         }
1001         return nil;
1002 }
1003
1004 static char *
1005 packbits(Tif *t)
1006 {
1007         ulong i, j, n;
1008         char *err;
1009         uchar *data;
1010         long *buf;
1011         Pkb p;
1012
1013         p.ndata = t->ndata;
1014         if((p.data = malloc(p.ndata*sizeof *p.data)) == nil)
1015                 return memerr;
1016         if((buf = malloc((t->bpl+1)*sizeof *buf)) == nil) {
1017                 free(p.data);
1018                 return memerr;
1019         }
1020         p.n = 0;
1021         data = t->data;
1022         for(i = j = n = 0, err = nil; i < t->dy; i++) {
1023                 if((err = pkbrow(&p, data, t->bpl, buf)) != nil)
1024                         break;
1025                 data += t->bpl;
1026                 if(i%t->rows == t->rows-1) {
1027                         t->counts[j++] = p.n - n;
1028                         n = p.n;
1029                 }
1030         }
1031         free(buf);
1032         if(err != nil) {
1033                 if(p.data != nil)
1034                         free(p.data);
1035                 return err;
1036         }
1037         if(j < t->nstrips)
1038                 t->counts[j] = p.n - n;
1039         free(t->data);
1040         t->data = p.data;
1041         t->ndata = p.n;
1042         return nil;
1043 }
1044
1045 static char *
1046 alloctif(Tif *t)
1047 {
1048         int rgb;
1049         ulong i, count, n;
1050
1051         count = t->ndata < 0x2000? t->ndata: 0x2000;
1052         t->rows = (count + t->bpl - 1) / t->bpl;
1053         if(t->comp == Tt4enc && t->opt) {
1054                 if((n = t->rows%Kpar) != 0)
1055                         t->rows += Kpar - n;
1056         }
1057         t->nstrips = (t->dy + t->rows - 1) / t->rows;
1058         t->strips = malloc(t->nstrips*sizeof *t->strips);
1059         if(t->strips == nil)
1060                 return memerr;
1061         t->counts = malloc(t->nstrips*sizeof *t->counts);
1062         if(t->counts == nil) {
1063                 free(t->strips);
1064                 return memerr;
1065         }
1066         if(t->ncolor > 0) {
1067                 t->color = malloc(t->ncolor*sizeof *t->color);
1068                 if(t->color == nil) {
1069                         free(t->strips);
1070                         free(t->counts);
1071                         return memerr;
1072                 }
1073                 for(i = 0; i < 256; i++) {
1074                         rgb = cmap2rgb(i);
1075                         t->color[i] = (rgb >> 16) & 0xff;
1076                         t->color[i+256] = (rgb >> 8) & 0xff;
1077                         t->color[i+256*2] = rgb & 0xff;
1078                 }
1079         }
1080         count = t->rows * t->bpl;
1081         for(i = 0, n = t->ndata; i < t->nstrips-1; i++) {
1082                 t->counts[i] = count;
1083                 n -= count;
1084         }
1085         t->counts[i] = n;
1086         return nil;
1087 }
1088
1089 static void
1090 freetif(Tif *t)
1091 {
1092         free(t->strips);
1093         free(t->counts);
1094         if(t->color != nil)
1095                 free(t->color);
1096         free(t->data);
1097 }
1098
1099 static int
1100 typesize(int fld)
1101 {
1102         return typesizes[flds[fld].typ];
1103 }
1104
1105 static void
1106 writefld(Biobuf *fd, int fld, ulong cnt, ulong val)
1107 {
1108         put2(fd, flds[fld].tag);
1109         put2(fd, flds[fld].typ);
1110         put4(fd, cnt);
1111         put4(fd, val);
1112 }
1113
1114 static void
1115 writeflds(Biobuf *fd, Tif *t)
1116 {
1117         int n;
1118         ulong i, off, slen, s, offs[7];
1119
1120         slen = t->desc == nil? 0: strlen(t->desc) + 1;
1121         put2(fd, 0x4d4d);
1122         put2(fd, 0x002a);
1123         off = 0x00000008;
1124         memset(offs, 0, sizeof offs);
1125         n = 0;
1126         offs[n++] = off;
1127         if(t->samples > 1) {
1128                 off += t->samples * typesize(Tbits);
1129                 offs[n++] = off;
1130         }
1131         if(slen > 4) {
1132                 off += slen * typesize(Tdesc);
1133                 offs[n++] = off;
1134         }
1135         if(t->nstrips > 1) {
1136                 off += t->nstrips * typesize(Tstrips);
1137                 offs[n++] = off;
1138                 off += t->nstrips * typesize(Tcounts);
1139                 offs[n++] = off;
1140         }
1141         off += typesize(Txres);
1142         offs[n++] = off;
1143         off += typesize(Tyres);
1144         offs[n] = off;
1145         if(t->color != nil)
1146                 off += t->ncolor * typesize(Tcolor);
1147         for(i = 0; i < t->nstrips-1; i++) {
1148                 t->strips[i] = off;
1149                 off += t->counts[i];
1150         }
1151         t->strips[i] = off;
1152         off += t->counts[i];
1153         put4(fd, off);
1154         if(t->samples > 1) {
1155                 for(i = 0; i < t->samples; i++)
1156                         put2(fd, t->depth[i]);
1157         }
1158         if(slen > 4) {
1159                 Bwrite(fd, t->desc, slen-1);
1160                 put1(fd, 0x00);
1161         }
1162         if(t->nstrips > 1) {
1163                 for(i = 0; i < t->nstrips; i++)
1164                         put4(fd, t->strips[i]);
1165                 for(i = 0; i < t->nstrips; i++)
1166                         put4(fd, t->counts[i]);
1167         }
1168         put4(fd, t->dx);
1169         put4(fd, 0x00000004);
1170         put4(fd, t->dy);
1171         put4(fd, 0x00000004);
1172         if(t->color != nil) {
1173                 for(i = 0; i < t->ncolor; i++)
1174                         put2(fd, t->color[i]);
1175         }
1176         Bwrite(fd, t->data, t->ndata);
1177         n = 0;
1178         put2(fd, t->nfld);
1179         writefld(fd, Twidth, 1, t->dx);
1180         writefld(fd, Tlength, 1, t->dy);
1181         if(t->samples > 1)
1182                 writefld(fd, Tbits, t->samples, offs[n++]);
1183         else
1184                 writefld(fd, Tbits, t->samples, *t->depth<<16);
1185         writefld(fd, Tcomp, 1, t->comp<<16);
1186         writefld(fd, Tphoto, 1, t->photo<<16);
1187         if(t->comp >= 2 && t->comp <= 4)
1188                 writefld(fd, Tfill, 1, 1<<16);
1189         if(slen > 1) {
1190                 if(slen <= 4) {
1191                         for(i = s = 0; i < slen-1; i++)
1192                                 s = (s << 8) | t->desc[i];
1193                         s <<= 8;
1194                         writefld(fd, Tdesc, slen, s);
1195                 } else
1196                         writefld(fd, Tdesc, slen, offs[n++]);
1197         }
1198         if(t->nstrips > 1)
1199                 writefld(fd, Tstrips, t->nstrips, offs[n++]);
1200         else
1201                 writefld(fd, Tstrips, t->nstrips, *t->strips);
1202         if(t->samples > 1)
1203                 writefld(fd, Tsamples, 1, t->samples<<16);
1204         writefld(fd, Trows, 1, t->rows);
1205         if(t->nstrips > 1)
1206                 writefld(fd, Tcounts, t->nstrips, offs[n++]);
1207         else
1208                 writefld(fd, Tcounts, t->nstrips, *t->counts);
1209         writefld(fd, Txres, 1, offs[n++]);
1210         writefld(fd, Tyres, 1, offs[n++]);
1211         if(t->comp == Tt4enc && t->opt)
1212                 writefld(fd, T4opt, 1, 1);
1213         writefld(fd, Tresunit, 1, 2<<16);
1214         if(t->comp == Tlzw && t->opt)
1215                 writefld(fd, Tpredictor, 1, 2<<16);
1216         if(t->color != nil)
1217                 writefld(fd, Tcolor, t->ncolor, offs[n]);
1218         put4(fd, 0x00000000);
1219 }
1220
1221 static char *
1222 writedata(Biobuf *fd, Image *i, Memimage *m, Tif *t)
1223 {
1224         char *err;
1225         uchar *data;
1226         int j, ndata, depth;
1227         Rectangle r;
1228
1229         if(m != nil) {
1230                 r = m->r;
1231                 depth = m->depth;
1232         } else {
1233                 r = i->r;
1234                 depth = i->depth;
1235         }
1236         t->dx = Dx(r);
1237         t->dy = Dy(r);
1238         for(j = 0; j < t->samples; j++)
1239                 t->depth[j] = depth / t->samples;
1240         /*
1241         * potentially one extra byte on each
1242         * end of each scan line
1243         */
1244         ndata = t->dy * (2 + t->dx*depth/8);
1245         if((data = malloc(ndata)) == nil)
1246                 return memerr;
1247         if(m != nil)
1248                 ndata = unloadmemimage(m, r, data, ndata);
1249         else
1250                 ndata = unloadimage(i, r, data, ndata);
1251         if(ndata < 0) {
1252                 free(data);
1253                 if((err = malloc(ERRMAX*sizeof *err)) == nil)
1254                         return memerr;
1255                 snprint(err, ERRMAX, "WriteTIF: %r");
1256         } else {
1257                 t->data = data;
1258                 t->ndata = ndata;
1259                 t->bpl = bytesperline(r, depth);
1260                 err = alloctif(t);
1261                 if(err != nil) {
1262                         freetif(t);
1263                         return err;
1264                 }
1265                 if((err = (*t->compress)(t)) == nil)
1266                         writeflds(fd, t);
1267                 freetif(t);
1268         }
1269         return err;
1270 }
1271
1272 static char *
1273 writetif0(Biobuf *fd, Image *image, Memimage *memimage,
1274         ulong chan, char *s, int comp, int opt)
1275 {
1276         Tif t;
1277
1278         t.nfld = 11;
1279         t.color = nil;
1280         if((t.desc = s) != nil)
1281                 t.nfld++;
1282         t.opt = opt;
1283         t.comp = comp;
1284         switch(chan) {
1285         case GREY1:
1286         case GREY4:
1287         case GREY8:
1288                 t.photo = 1;
1289                 t.samples = 1;
1290                 t.ncolor = 0;
1291                 break;
1292         case CMAP8:
1293                 t.photo = 3;
1294                 t.samples = 1;
1295                 t.ncolor = 3 * 256;
1296                 t.nfld++;
1297                 break;
1298         case BGR24:
1299                 t.photo = 2;
1300                 t.samples = 3;
1301                 t.ncolor = 0;
1302                 t.nfld++;
1303                 break;
1304         default:
1305                 return "WriteTIF: can't handle channel type";
1306         }
1307         switch(t.comp) {
1308         case Tnocomp:
1309                 t.compress = nocomp;
1310                 break;
1311         case Thuffman:
1312         case Tt4enc:
1313         case Tt6enc:
1314                 t.photo = 0;
1315                 t.nfld++;
1316                 if(t.comp == Tt4enc && t.opt)
1317                         t.nfld++;
1318                 t.compress = fax;
1319                 break;
1320         case Tlzw:
1321                 t.compress = lzw;
1322                 if(t.opt)
1323                         t.nfld++;
1324                 break;
1325         case Tpackbits:
1326                 t.compress = packbits;
1327                 break;
1328         default:
1329                 return "WriteTIF: unknown compression";
1330         }
1331         return writedata(fd, image, memimage, &t);
1332 }
1333
1334 char *
1335 writetif(Biobuf *fd, Image *i, char *s, int comp, int opt)
1336 {
1337         return writetif0(fd, i, nil, i->chan, s, comp, opt);
1338 }
1339
1340 char *
1341 memwritetif(Biobuf *fd, Memimage *m, char *s, int comp, int opt)
1342 {
1343         return writetif0(fd, nil, m, m->chan, s, comp, opt);
1344 }