3 * http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
4 * http://paulbourke.net/dataformats/tiff/
5 * http://www.fileformat.info/format/tiff/egff.htm
6 * http://www.fileformat.info/mirror/egff/ch09_05.htm
7 * http://www.itu.int/rec/T-REC-T.4-199904-S/en
8 * http://www.itu.int/rec/T-REC-T.6-198811-I/en
10 * copy-pasted fax codes and copy-pasted lzw encoding
11 * hash table implementation:
12 * http://www.remotesensing.org/libtiff/
19 #include "imagefile.h"
68 typedef struct Tab Tab;
69 typedef struct Fax Fax;
70 typedef struct Hash Hash;
71 typedef struct Lzw Lzw;
72 typedef struct Pkb Pkb;
73 typedef struct Fld Fld;
74 typedef struct Tif Tif;
127 char *(*compress)(Tif *);
143 static Fld flds[] = {
144 [Twidth] {0x0100, Tlong},
145 [Tlength] {0x0101, Tlong},
146 [Tbits] {0x0102, Tshort},
147 [Tcomp] {0x0103, Tshort},
148 [Tphoto] {0x0106, Tshort},
149 [Tfill] {0x010a, Tshort},
150 [Tdesc] {0x010e, Tascii},
151 [Tstrips] {0x0111, Tlong},
152 [Tsamples] {0x0115, Tshort},
153 [Trows] {0x0116, Tlong},
154 [Tcounts] {0x0117, Tlong},
155 [Txres] {0x011a, Trational},
156 [Tyres] {0x011b, Trational},
157 [T4opt] {0x0124, Tlong},
158 [Tresunit] {0x0128, Tshort},
159 [Tpredictor] {0x013d, Tshort},
160 [Tcolor] {0x0140, Tshort}
164 * imported from libdraw/arith.c to permit
165 * extern log2 function
167 static int log2[] = {
168 -1, 0, 1, -1, 2, -1, -1, -1, 3,
169 -1, -1, -1, -1, -1, -1, -1, 4,
170 -1, -1, -1, -1, -1, -1, -1, 4 /* BUG */,
171 -1, -1, -1, -1, -1, -1, -1, 5
174 static Tab faxwhite[Nfaxtab] = {
175 {8, 0x35, 0}, /* 0011 0101 */
176 {6, 0x7, 1}, /* 0001 11 */
177 {4, 0x7, 2}, /* 0111 */
178 {4, 0x8, 3}, /* 1000 */
179 {4, 0xb, 4}, /* 1011 */
180 {4, 0xc, 5}, /* 1100 */
181 {4, 0xe, 6}, /* 1110 */
182 {4, 0xf, 7}, /* 1111 */
183 {5, 0x13, 8}, /* 1001 1 */
184 {5, 0x14, 9}, /* 1010 0 */
185 {5, 0x7, 10}, /* 0011 1 */
186 {5, 0x8, 11}, /* 0100 0 */
187 {6, 0x8, 12}, /* 0010 00 */
188 {6, 0x3, 13}, /* 0000 11 */
189 {6, 0x34, 14}, /* 1101 00 */
190 {6, 0x35, 15}, /* 1101 01 */
191 {6, 0x2a, 16}, /* 1010 10 */
192 {6, 0x2b, 17}, /* 1010 11 */
193 {7, 0x27, 18}, /* 0100 111 */
194 {7, 0xc, 19}, /* 0001 100 */
195 {7, 0x8, 20}, /* 0001 000 */
196 {7, 0x17, 21}, /* 0010 111 */
197 {7, 0x3, 22}, /* 0000 011 */
198 {7, 0x4, 23}, /* 0000 100 */
199 {7, 0x28, 24}, /* 0101 000 */
200 {7, 0x2b, 25}, /* 0101 011 */
201 {7, 0x13, 26}, /* 0010 011 */
202 {7, 0x24, 27}, /* 0100 100 */
203 {7, 0x18, 28}, /* 0011 000 */
204 {8, 0x2, 29}, /* 0000 0010 */
205 {8, 0x3, 30}, /* 0000 0011 */
206 {8, 0x1a, 31}, /* 0001 1010 */
207 {8, 0x1b, 32}, /* 0001 1011 */
208 {8, 0x12, 33}, /* 0001 0010 */
209 {8, 0x13, 34}, /* 0001 0011 */
210 {8, 0x14, 35}, /* 0001 0100 */
211 {8, 0x15, 36}, /* 0001 0101 */
212 {8, 0x16, 37}, /* 0001 0110 */
213 {8, 0x17, 38}, /* 0001 0111 */
214 {8, 0x28, 39}, /* 0010 1000 */
215 {8, 0x29, 40}, /* 0010 1001 */
216 {8, 0x2a, 41}, /* 0010 1010 */
217 {8, 0x2b, 42}, /* 0010 1011 */
218 {8, 0x2c, 43}, /* 0010 1100 */
219 {8, 0x2d, 44}, /* 0010 1101 */
220 {8, 0x4, 45}, /* 0000 0100 */
221 {8, 0x5, 46}, /* 0000 0101 */
222 {8, 0xa, 47}, /* 0000 1010 */
223 {8, 0xb, 48}, /* 0000 1011 */
224 {8, 0x52, 49}, /* 0101 0010 */
225 {8, 0x53, 50}, /* 0101 0011 */
226 {8, 0x54, 51}, /* 0101 0100 */
227 {8, 0x55, 52}, /* 0101 0101 */
228 {8, 0x24, 53}, /* 0010 0100 */
229 {8, 0x25, 54}, /* 0010 0101 */
230 {8, 0x58, 55}, /* 0101 1000 */
231 {8, 0x59, 56}, /* 0101 1001 */
232 {8, 0x5a, 57}, /* 0101 1010 */
233 {8, 0x5b, 58}, /* 0101 1011 */
234 {8, 0x4a, 59}, /* 0100 1010 */
235 {8, 0x4b, 60}, /* 0100 1011 */
236 {8, 0x32, 61}, /* 0011 0010 */
237 {8, 0x33, 62}, /* 0011 0011 */
238 {8, 0x34, 63}, /* 0011 0100 */
239 {5, 0x1b, 64}, /* 1101 1 */
240 {5, 0x12, 128}, /* 1001 0 */
241 {6, 0x17, 192}, /* 0101 11 */
242 {7, 0x37, 256}, /* 0110 111 */
243 {8, 0x36, 320}, /* 0011 0110 */
244 {8, 0x37, 384}, /* 0011 0111 */
245 {8, 0x64, 448}, /* 0110 0100 */
246 {8, 0x65, 512}, /* 0110 0101 */
247 {8, 0x68, 576}, /* 0110 1000 */
248 {8, 0x67, 640}, /* 0110 0111 */
249 {9, 0xcc, 704}, /* 0110 0110 0 */
250 {9, 0xcd, 768}, /* 0110 0110 1 */
251 {9, 0xd2, 832}, /* 0110 1001 0 */
252 {9, 0xd3, 896}, /* 0110 1001 1 */
253 {9, 0xd4, 960}, /* 0110 1010 0 */
254 {9, 0xd5, 1024}, /* 0110 1010 1 */
255 {9, 0xd6, 1088}, /* 0110 1011 0 */
256 {9, 0xd7, 1152}, /* 0110 1011 1 */
257 {9, 0xd8, 1216}, /* 0110 1100 0 */
258 {9, 0xd9, 1280}, /* 0110 1100 1 */
259 {9, 0xda, 1344}, /* 0110 1101 0 */
260 {9, 0xdb, 1408}, /* 0110 1101 1 */
261 {9, 0x98, 1472}, /* 0100 1100 0 */
262 {9, 0x99, 1536}, /* 0100 1100 1 */
263 {9, 0x9a, 1600}, /* 0100 1101 0 */
264 {6, 0x18, 1664}, /* 0110 00 */
265 {9, 0x9b, 1728}, /* 0100 1101 1 */
266 {11, 0x8, 1792}, /* 0000 0001 000 */
267 {11, 0xc, 1856}, /* 0000 0001 100 */
268 {11, 0xd, 1920}, /* 0000 0001 101 */
269 {12, 0x12, 1984}, /* 0000 0001 0010 */
270 {12, 0x13, 2048}, /* 0000 0001 0011 */
271 {12, 0x14, 2112}, /* 0000 0001 0100 */
272 {12, 0x15, 2176}, /* 0000 0001 0101 */
273 {12, 0x16, 2240}, /* 0000 0001 0110 */
274 {12, 0x17, 2304}, /* 0000 0001 0111 */
275 {12, 0x1c, 2368}, /* 0000 0001 1100 */
276 {12, 0x1d, 2432}, /* 0000 0001 1101 */
277 {12, 0x1e, 2496}, /* 0000 0001 1110 */
278 {12, 0x1f, 2560}, /* 0000 0001 1111 */
279 {12, 0x1, -1} /* 0000 0000 0001 */
282 static Tab faxblack[Nfaxtab] = {
283 {10, 0x37, 0}, /* 0000 1101 11 */
284 {3, 0x2, 1}, /* 010 */
285 {2, 0x3, 2}, /* 11 */
286 {2, 0x2, 3}, /* 10 */
287 {3, 0x3, 4}, /* 011 */
288 {4, 0x3, 5}, /* 0011 */
289 {4, 0x2, 6}, /* 0010 */
290 {5, 0x3, 7}, /* 0001 1 */
291 {6, 0x5, 8}, /* 0001 01 */
292 {6, 0x4, 9}, /* 0001 00 */
293 {7, 0x4, 10}, /* 0000 100 */
294 {7, 0x5, 11}, /* 0000 101 */
295 {7, 0x7, 12}, /* 0000 111 */
296 {8, 0x4, 13}, /* 0000 0100 */
297 {8, 0x7, 14}, /* 0000 0111 */
298 {9, 0x18, 15}, /* 0000 1100 0 */
299 {10, 0x17, 16}, /* 0000 0101 11 */
300 {10, 0x18, 17}, /* 0000 0110 00 */
301 {10, 0x8, 18}, /* 0000 0010 00 */
302 {11, 0x67, 19}, /* 0000 1100 111 */
303 {11, 0x68, 20}, /* 0000 1101 000 */
304 {11, 0x6c, 21}, /* 0000 1101 100 */
305 {11, 0x37, 22}, /* 0000 0110 111 */
306 {11, 0x28, 23}, /* 0000 0101 000 */
307 {11, 0x17, 24}, /* 0000 0010 111 */
308 {11, 0x18, 25}, /* 0000 0011 000 */
309 {12, 0xca, 26}, /* 0000 1100 1010 */
310 {12, 0xcb, 27}, /* 0000 1100 1011 */
311 {12, 0xcc, 28}, /* 0000 1100 1100 */
312 {12, 0xcd, 29}, /* 0000 1100 1101 */
313 {12, 0x68, 30}, /* 0000 0110 1000 */
314 {12, 0x69, 31}, /* 0000 0110 1001 */
315 {12, 0x6a, 32}, /* 0000 0110 1010 */
316 {12, 0x6b, 33}, /* 0000 0110 1011 */
317 {12, 0xd2, 34}, /* 0000 1101 0010 */
318 {12, 0xd3, 35}, /* 0000 1101 0011 */
319 {12, 0xd4, 36}, /* 0000 1101 0100 */
320 {12, 0xd5, 37}, /* 0000 1101 0101 */
321 {12, 0xd6, 38}, /* 0000 1101 0110 */
322 {12, 0xd7, 39}, /* 0000 1101 0111 */
323 {12, 0x6c, 40}, /* 0000 0110 1100 */
324 {12, 0x6d, 41}, /* 0000 0110 1101 */
325 {12, 0xda, 42}, /* 0000 1101 1010 */
326 {12, 0xdb, 43}, /* 0000 1101 1011 */
327 {12, 0x54, 44}, /* 0000 0101 0100 */
328 {12, 0x55, 45}, /* 0000 0101 0101 */
329 {12, 0x56, 46}, /* 0000 0101 0110 */
330 {12, 0x57, 47}, /* 0000 0101 0111 */
331 {12, 0x64, 48}, /* 0000 0110 0100 */
332 {12, 0x65, 49}, /* 0000 0110 0101 */
333 {12, 0x52, 50}, /* 0000 0101 0010 */
334 {12, 0x53, 51}, /* 0000 0101 0011 */
335 {12, 0x24, 52}, /* 0000 0010 0100 */
336 {12, 0x37, 53}, /* 0000 0011 0111 */
337 {12, 0x38, 54}, /* 0000 0011 1000 */
338 {12, 0x27, 55}, /* 0000 0010 0111 */
339 {12, 0x28, 56}, /* 0000 0010 1000 */
340 {12, 0x58, 57}, /* 0000 0101 1000 */
341 {12, 0x59, 58}, /* 0000 0101 1001 */
342 {12, 0x2b, 59}, /* 0000 0010 1011 */
343 {12, 0x2c, 60}, /* 0000 0010 1100 */
344 {12, 0x5a, 61}, /* 0000 0101 1010 */
345 {12, 0x66, 62}, /* 0000 0110 0110 */
346 {12, 0x67, 63}, /* 0000 0110 0111 */
347 {10, 0xf, 64}, /* 0000 0011 11 */
348 {12, 0xc8, 128}, /* 0000 1100 1000 */
349 {12, 0xc9, 192}, /* 0000 1100 1001 */
350 {12, 0x5b, 256}, /* 0000 0101 1011 */
351 {12, 0x33, 320}, /* 0000 0011 0011 */
352 {12, 0x34, 384}, /* 0000 0011 0100 */
353 {12, 0x35, 448}, /* 0000 0011 0101 */
354 {13, 0x6c, 512}, /* 0000 0011 0110 0 */
355 {13, 0x6d, 576}, /* 0000 0011 0110 1 */
356 {13, 0x4a, 640}, /* 0000 0010 0101 0 */
357 {13, 0x4b, 704}, /* 0000 0010 0101 1 */
358 {13, 0x4c, 768}, /* 0000 0010 0110 0 */
359 {13, 0x4d, 832}, /* 0000 0010 0110 1 */
360 {13, 0x72, 896}, /* 0000 0011 1001 0 */
361 {13, 0x73, 960}, /* 0000 0011 1001 1 */
362 {13, 0x74, 1024}, /* 0000 0011 1010 0 */
363 {13, 0x75, 1088}, /* 0000 0011 1010 1 */
364 {13, 0x76, 1152}, /* 0000 0011 1011 0 */
365 {13, 0x77, 1216}, /* 0000 0011 1011 1 */
366 {13, 0x52, 1280}, /* 0000 0010 1001 0 */
367 {13, 0x53, 1344}, /* 0000 0010 1001 1 */
368 {13, 0x54, 1408}, /* 0000 0010 1010 0 */
369 {13, 0x55, 1472}, /* 0000 0010 1010 1 */
370 {13, 0x5a, 1536}, /* 0000 0010 1101 0 */
371 {13, 0x5b, 1600}, /* 0000 0010 1101 1 */
372 {13, 0x64, 1664}, /* 0000 0011 0010 0 */
373 {13, 0x65, 1728}, /* 0000 0011 0010 1 */
374 {11, 0x8, 1792}, /* 0000 0001 000 */
375 {11, 0xc, 1856}, /* 0000 0001 100 */
376 {11, 0xd, 1920}, /* 0000 0001 101 */
377 {12, 0x12, 1984}, /* 0000 0001 0010 */
378 {12, 0x13, 2048}, /* 0000 0001 0011 */
379 {12, 0x14, 2112}, /* 0000 0001 0100 */
380 {12, 0x15, 2176}, /* 0000 0001 0101 */
381 {12, 0x16, 2240}, /* 0000 0001 0110 */
382 {12, 0x17, 2304}, /* 0000 0001 0111 */
383 {12, 0x1c, 2368}, /* 0000 0001 1100 */
384 {12, 0x1d, 2432}, /* 0000 0001 1101 */
385 {12, 0x1e, 2496}, /* 0000 0001 1110 */
386 {12, 0x1f, 2560}, /* 0000 0001 1111 */
387 {12, 0x1, -1} /* 0000 0000 0001 */
390 static Tab faxcodes[] = {
391 {4, 0x1, 0}, /* 0001 */
392 {3, 0x1, 0}, /* 001 */
394 {3, 0x2, 0}, /* 010 */
395 {6, 0x2, 0}, /* 0000 10 */
396 {7, 0x2, 0}, /* 0000 010 */
397 {3, 0x3, 0}, /* 011 */
398 {6, 0x3, 0}, /* 0000 11 */
399 {7, 0x3, 0} /* 0000 011 */
402 static int typesizes[] = {0, 1, 1, 2, 4, 8};
403 static char memerr[] = "WriteTIF: malloc failed";
406 put1(Biobuf *b, uchar c)
412 put2(Biobuf *b, uint s)
414 if(put1(b, s>>8) < 0)
420 put4(Biobuf *b, ulong l)
422 if(put2(b, l>>16) < 0)
436 if(f->n >= f->ndata) {
438 f->data = realloc(f->data,
439 f->ndata*sizeof *f->data);
443 f->data[f->n++] = f->byte;
444 f->byte = f->nbyte = 0;
449 faxputbit(Fax *f, int bit)
451 f->byte = (f->byte << 1) | bit;
453 return f->nbyte >= 8? faxputbyte(f): nil;
463 f->byte <<= 8 - f->nbyte;
470 faxputcode(Fax *f, Tab *tab)
475 for(i = tab->len-1; i >= 0; i--) {
476 bit = (tab->code >> i) & 0x1;
477 if((err = faxputbit(f, bit)) != nil)
490 return 64 + run/64 - 1;
496 faxputrun(Fax *f, long run)
502 p = &tab[faxgettab(2560)];
504 if((err = faxputcode(f, p)) != nil)
509 p = &tab[faxgettab(run)];
510 if((err = faxputcode(f, p)) != nil)
514 p = &tab[faxgettab(run)];
515 err = faxputcode(f, p);
523 return faxputcode(f, &f->tab[0][faxgettab(-1)]);
527 fax1d(Fax *f, ulong dx)
536 if((err = faxputrun(f, run)) != nil)
540 run = f->l2[i] - f->l2[i-1];
542 memmove(f->l1, f->l2, i*sizeof *f->l1);
547 fax2d(Fax *f, ulong dx)
551 long a0, a1, a2, b1, b2;
558 for(i = 0, err = nil; err == nil;) {
563 if(b1 > a0 && f->st == j%2)
573 err = faxputcode(f, p);
575 } else if(abs(v = a1-b1) < 3) {
577 p = &tab[2+(v>0?3:0)+abs(v)];
578 err = faxputcode(f, p);
586 if((err = faxputcode(f, p)) != nil)
588 a2 = a1 < dx? f->l2[i++]: a1;
589 if((err = faxputrun(f, a1-a0)) != nil)
591 err = faxputrun(f, a2-a1);
597 memmove(f->l1, f->l2, i*sizeof *f->l1);
602 faxstrip(Tif *t, Fax *f, uchar *data, ulong n, ulong dx)
608 d1 = t->comp != Tt6enc;
610 if(t->comp == Tt4enc) {
611 if((err = faxputeol(f)) != nil)
613 if(t->opt && (err = faxputbit(f, 1)) != nil)
616 for(i = j = x = 0; i < n;) {
618 k = ((data[i] >> s) & 0x1) ^ 0x1;
629 if(t->comp == Tt4enc &&
636 if(two > 0 && --two <= 0)
641 if(t->comp == Thuffman)
642 err = faxbytealign(f);
643 else if(t->comp == Tt4enc &&
645 if((err = faxputeol(f)) != nil)
647 err = faxputbit(f, d1);
648 } else if(t->comp == Tt4enc)
659 if(t->comp == Tt4enc || t->comp == Tt6enc) {
660 i = t->comp == Tt4enc? 5: 2;
662 if((err = faxputeol(f)) != nil)
664 if(t->comp == Tt4enc && t->opt) {
665 err = faxputbit(f, 1);
671 return faxbytealign(f);
683 if((f.data = malloc(f.ndata*sizeof *f.data)) == nil)
685 f.l1 = mallocz((t->dx+1)*sizeof *f.l1, 1);
686 f.l2 = mallocz((t->dx+1)*sizeof *f.l2, 1);
687 if(f.l1 == nil || f.l2 == nil) {
697 f.n = f.byte = f.nbyte = 0;
698 for(i = n = 0, data = t->data; i < t->nstrips; i++) {
702 if((err = faxstrip(t, &f, data, m, t->dx)) != nil) {
708 t->counts[i] = f.n - n;
725 l->ntab = Eoicode + 1;
727 hp = &l->hash[Hsize-1];
741 for(i += 8; i > 0; i--, hp--)
748 if(l->n >= l->ndata) {
750 l->data = realloc(l->data,
751 l->ndata*sizeof *l->data);
755 l->data[l->n++] = l->byte;
756 l->byte = l->nbyte = 0;
767 l->byte <<= 8 - l->nbyte;
774 lzwputcode(Lzw *l, int code)
779 for(i = l->len-1; i >= 0; i--) {
780 c = (code >> i) & 0x1;
781 l->byte = (l->byte << 1) | c;
784 if((err = lzwputbyte(l)) != nil)
794 int pix, b[8], d, m, n, j;
800 for(y = 0; y < t->dy; y++) {
801 for(x = t->bpl-1;; x--) {
804 for(j = 0; j < n; j++) {
805 b[j] = (pix >> d*j) & m;
810 b[n-1] -= t->data[i-1] & m;
811 for(j = pix = 0; j < n; j++)
812 pix |= (b[j] & m) << d*j;
826 for(y = 0; y < t->dy; y++) {
827 for(x = t->dx-1; x >= 1; x--) {
828 i = (y*t->dx + x) * s;
829 for(j = 0; j < s; i++, j++)
830 t->data[i] -= t->data[i-s];
836 lzwstrip(Lzw *l, uchar *data, ulong n)
845 if((err = lzwputcode(l, Clrcode)) != nil)
851 fcode = ((long)k << 12) + ent;
852 h = (k << Hshift) ^ ent;
854 if(hp->hash == fcode) {
860 disp = h == 0? 1: Hsize - h;
865 if(hp->hash == fcode)
867 } while(hp->hash >= 0);
869 if((err = lzwputcode(l, ent)) != nil)
873 switch(hp->code = l->ntab) {
882 if(l->ntab++ >= Tabsz-2) {
883 err = lzwputcode(l, Clrcode);
889 if((err = lzwputcode(l, ent)) != nil)
891 if((err = lzwputcode(l, Eoicode)) != nil)
893 return lzwbytealign(l);
905 *t->depth < 8? predict1(t): predict8(t);
907 if((l.data = malloc(l.ndata*sizeof *l.data)) == nil)
909 l.n = l.byte = l.nbyte = 0;
911 for(i = n = 0, data = t->data; i < t->nstrips; i++) {
914 if((err = lzwstrip(&l, data, m)) != nil)
917 t->counts[i] = l.n - n;
932 pkbrow(Pkb *p, uchar *data, int ndata, long *buf)
942 repl = b == data[i]? 1: 0;
945 for(; i < ndata; i++) {
962 buf[n++] = repl? -i: i;
966 if(i < n-2 && k > 0 && buf[i+1] < 0 &&
967 buf[i+2] > 0 && -buf[i+1]-k <= 2) {
968 buf[i] = buf[i+1] = buf[i+2];
971 if((b = labs(k) - j) > 128) {
973 buf[i-1] += buf[i-1] < 0? -b: b;
978 m = 1 + (k < 0? 1: b);
979 if(p->n+m > p->ndata) {
980 p->ndata = (p->n + m) * 2;
981 p->data = realloc(p->data,
982 p->ndata*sizeof *p->data);
987 p->data[p->n++] = 1 - b;
988 p->data[p->n++] = data[j];
990 p->data[p->n++] = b - 1;
991 memmove(p->data+p->n, data+j, b);
1008 if((p.data = malloc(p.ndata*sizeof *p.data)) == nil)
1010 if((buf = malloc((t->bpl+1)*sizeof *buf)) == nil) {
1016 for(i = j = n = 0, err = nil; i < t->dy; i++) {
1017 if((err = pkbrow(&p, data, t->bpl, buf)) != nil)
1020 if(i%t->rows == t->rows-1) {
1021 t->counts[j++] = p.n - n;
1032 t->counts[j] = p.n - n;
1045 count = t->ndata < 0x2000? t->ndata: 0x2000;
1046 t->rows = (count + t->bpl - 1) / t->bpl;
1047 if(t->comp == Tt4enc && t->opt) {
1048 if((n = t->rows%Kpar) != 0)
1049 t->rows += Kpar - n;
1051 t->nstrips = (t->dy + t->rows - 1) / t->rows;
1052 t->strips = malloc(t->nstrips*sizeof *t->strips);
1053 if(t->strips == nil)
1055 t->counts = malloc(t->nstrips*sizeof *t->counts);
1056 if(t->counts == nil) {
1061 t->color = malloc(t->ncolor*sizeof *t->color);
1062 if(t->color == nil) {
1067 for(i = 0; i < 256; i++) {
1069 t->color[i] = (rgb >> 16) & 0xff;
1070 t->color[i+256] = (rgb >> 8) & 0xff;
1071 t->color[i+256*2] = rgb & 0xff;
1074 count = t->rows * t->bpl;
1075 for(i = 0, n = t->ndata; i < t->nstrips-1; i++) {
1076 t->counts[i] = count;
1096 return typesizes[flds[fld].typ];
1100 writefld(Biobuf *fd, int fld, ulong cnt, ulong val)
1102 put2(fd, flds[fld].tag);
1103 put2(fd, flds[fld].typ);
1109 writeflds(Biobuf *fd, Tif *t)
1112 ulong i, off, slen, s, offs[7];
1114 slen = t->desc == nil? 0: strlen(t->desc) + 1;
1118 memset(offs, 0, sizeof offs);
1121 if(t->samples > 1) {
1122 off += t->samples * typesize(Tbits);
1126 off += slen * typesize(Tdesc);
1129 if(t->nstrips > 1) {
1130 off += t->nstrips * typesize(Tstrips);
1132 off += t->nstrips * typesize(Tcounts);
1135 off += typesize(Txres);
1137 off += typesize(Tyres);
1140 off += t->ncolor * typesize(Tcolor);
1141 for(i = 0; i < t->nstrips-1; i++) {
1143 off += t->counts[i];
1146 off += t->counts[i];
1148 if(t->samples > 1) {
1149 for(i = 0; i < t->samples; i++)
1150 put2(fd, t->depth[i]);
1153 Bwrite(fd, t->desc, slen-1);
1156 if(t->nstrips > 1) {
1157 for(i = 0; i < t->nstrips; i++)
1158 put4(fd, t->strips[i]);
1159 for(i = 0; i < t->nstrips; i++)
1160 put4(fd, t->counts[i]);
1163 put4(fd, 0x00000004);
1165 put4(fd, 0x00000004);
1166 if(t->color != nil) {
1167 for(i = 0; i < t->ncolor; i++)
1168 put2(fd, t->color[i]);
1170 Bwrite(fd, t->data, t->ndata);
1173 writefld(fd, Twidth, 1, t->dx);
1174 writefld(fd, Tlength, 1, t->dy);
1176 writefld(fd, Tbits, t->samples, offs[n++]);
1178 writefld(fd, Tbits, t->samples, *t->depth<<16);
1179 writefld(fd, Tcomp, 1, t->comp<<16);
1180 writefld(fd, Tphoto, 1, t->photo<<16);
1181 if(t->comp >= 2 && t->comp <= 4)
1182 writefld(fd, Tfill, 1, 1<<16);
1185 for(i = s = 0; i < slen-1; i++)
1186 s = (s << 8) | t->desc[i];
1188 writefld(fd, Tdesc, slen, s);
1190 writefld(fd, Tdesc, slen, offs[n++]);
1193 writefld(fd, Tstrips, t->nstrips, offs[n++]);
1195 writefld(fd, Tstrips, t->nstrips, *t->strips);
1197 writefld(fd, Tsamples, 1, t->samples<<16);
1198 writefld(fd, Trows, 1, t->rows);
1200 writefld(fd, Tcounts, t->nstrips, offs[n++]);
1202 writefld(fd, Tcounts, t->nstrips, *t->counts);
1203 writefld(fd, Txres, 1, offs[n++]);
1204 writefld(fd, Tyres, 1, offs[n++]);
1205 if(t->comp == Tt4enc && t->opt)
1206 writefld(fd, T4opt, 1, 1);
1207 writefld(fd, Tresunit, 1, 2<<16);
1208 if(t->comp == Tlzw && t->opt)
1209 writefld(fd, Tpredictor, 1, 2<<16);
1211 writefld(fd, Tcolor, t->ncolor, offs[n]);
1212 put4(fd, 0x00000000);
1216 writedata(Biobuf *fd, Image *i, Memimage *m, Tif *t)
1220 int j, ndata, depth;
1232 for(j = 0; j < t->samples; j++)
1233 t->depth[j] = depth / t->samples;
1235 * potentially one extra byte on each
1236 * end of each scan line
1238 ndata = t->dy * (2 + t->dx*depth/8);
1239 if((data = malloc(ndata)) == nil)
1242 ndata = unloadmemimage(m, r, data, ndata);
1244 ndata = unloadimage(i, r, data, ndata);
1247 if((err = malloc(ERRMAX*sizeof *err)) == nil)
1249 snprint(err, ERRMAX, "WriteTIF: %r");
1253 t->bpl = bytesperline(r, depth);
1259 if((err = (*t->compress)(t)) == nil)
1267 writetif0(Biobuf *fd, Image *image, Memimage *memimage,
1268 ulong chan, char *s, int comp, int opt)
1274 if((t.desc = s) != nil)
1299 return "WriteTIF: can't handle channel type";
1303 t.compress = nocomp;
1310 if(t.comp == Tt4enc && t.opt)
1320 t.compress = packbits;
1323 return "WriteTIF: unknown compression";
1325 return writedata(fd, image, memimage, &t);
1329 writetif(Biobuf *fd, Image *i, char *s, int comp, int opt)
1331 return writetif0(fd, i, nil, i->chan, s, comp, opt);
1335 memwritetif(Biobuf *fd, Memimage *m, char *s, int comp, int opt)
1337 return writetif0(fd, nil, m, m->chan, s, comp, opt);