source: trunk/JPGPROC/source/gbmsrc/gbmtif.c@ 2

Last change on this file since 2 was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 37.9 KB
Line 
1/*
2
3gbmtif.c - Microsoft/Aldus Tagged Image File Format support
4
5Reads and writes 1,4,8 and 24 bit colour files.
6Supports uncompressed, Packbits and LZW compressed files only.
7Input option: index=N (default is 0)
8Output options: artist=,software=,make=,model=,host=,documentname=,pagename=,
9 imagedescription=,pal1bpp
10
11Added support to allow SamplePerPixel>=3 for RGB data (TIFF 6.0 new feature).
12Added rejection test of FillOrder!=1.
13Added rejection test of PlanarConfiguration!=1.
14Added support for CMYK images.
15Changed write of 1bpp data to Baseline black and white write.
16Added pal1bpp output option meaning don't force Baseline write of 1bpp data.
17Improved error messages substantially.
18Fixed Packbits compression.
19Added support for PlanarConfiguration==2 for RGB images only.
20Added Predictor==2 support for bps==8, spp=1 case.
21Added Predictor==2 support for bps==8, spp>=3 case.
22Removed Too Many Strips limitation.
23Faster LZW code.
24Fixes to LZW compressor (and #ifdef DEBUG debug code).
25
26*/
27
28/*...sincludes:0:*/
29#include <stdio.h>
30#include <ctype.h>
31#include <stddef.h>
32#include <stdlib.h>
33#include <string.h>
34#include "gbm.h"
35#include "gbmhelp.h"
36#include "gbmtifh.h"
37
38/*...vgbm\46\h:0:*/
39/*...vgbmhelp\46\h:0:*/
40/*...vgbmtifh\46\h:0:*/
41
42#ifndef min
43#define min(a,b) (((a)<(b))?(a):(b))
44#endif
45/*...e*/
46
47/* #define DEBUG */
48
49static GBMFT tif_gbmft =
50 {
51 "TIFF",
52 "Tagged Image File Format support (almost TIFF 6.0 Baseline)",
53 "TIF TIFF",
54 GBM_FT_R1|GBM_FT_R4|GBM_FT_R8|GBM_FT_R24|
55 GBM_FT_W1|GBM_FT_W4|GBM_FT_W8|GBM_FT_W24,
56 };
57
58/*...serror codes:0:*/
59#define GBM_ERR_TIF_VERSION ((GBM_ERR) 800)
60#define GBM_ERR_TIF_N_TAGS ((GBM_ERR) 801)
61#define GBM_ERR_TIF_TAG_TYPE ((GBM_ERR) 802)
62#define GBM_ERR_TIF_HEADER ((GBM_ERR) 803)
63#define GBM_ERR_TIF_MISSING_TAG ((GBM_ERR) 804)
64#define GBM_ERR_TIF_SPP_BIT ((GBM_ERR) 805)
65#define GBM_ERR_TIF_BPS_BIT ((GBM_ERR) 806)
66#define GBM_ERR_TIF_SPP_RGB ((GBM_ERR) 807)
67#define GBM_ERR_TIF_BPS_RGB ((GBM_ERR) 808)
68#define GBM_ERR_TIF_SPP_PAL ((GBM_ERR) 809)
69#define GBM_ERR_TIF_BPS_PAL ((GBM_ERR) 810)
70#define GBM_ERR_TIF_SPP_CMYK ((GBM_ERR) 811)
71#define GBM_ERR_TIF_BPS_CMYK ((GBM_ERR) 812)
72#define GBM_ERR_TIF_COMP_1D_MH ((GBM_ERR) 813)
73#define GBM_ERR_TIF_COMP_T4 ((GBM_ERR) 814)
74#define GBM_ERR_TIF_COMP_T6 ((GBM_ERR) 815)
75#define GBM_ERR_TIF_COMP ((GBM_ERR) 816)
76#define GBM_ERR_TIF_COLORMAP ((GBM_ERR) 817)
77#define GBM_ERR_TIF_CORRUPT ((GBM_ERR) 818)
78#define GBM_ERR_TIF_PREDICTOR ((GBM_ERR) 819)
79#define GBM_ERR_TIF_PHOTO_TRANS ((GBM_ERR) 821)
80#define GBM_ERR_TIF_PHOTO_Y_Cb_Cr ((GBM_ERR) 822)
81#define GBM_ERR_TIF_PHOTO ((GBM_ERR) 823)
82#define GBM_ERR_TIF_FILLORDER ((GBM_ERR) 824)
83#define GBM_ERR_TIF_PLANARCONFIG_1 ((GBM_ERR) 825)
84#define GBM_ERR_TIF_PLANARCONFIG_12 ((GBM_ERR) 826)
85#define GBM_ERR_TIF_INKSET ((GBM_ERR) 827)
86#define GBM_ERR_TIF_ORIENT ((GBM_ERR) 828)
87#define GBM_ERR_TIF_INDEX ((GBM_ERR) 829)
88/*...e*/
89
90/*...sdefns:0:*/
91/*
92#define MAX_STRIPS 200
93*/
94#define MAX_STRIPS ((PRIV_SIZE-9*sizeof(int)-0x100*sizeof(GBMRGB))/sizeof(long))
95
96typedef struct
97 {
98 GBMRGB gbmrgb[0x100];
99 int rps, spp, bps, comp, photo, orient, planar, predictor, inx;
100 long so[MAX_STRIPS];
101 } TIF_PRIV;
102
103#define ENC_NONE ((int) 1)
104#define ENC_G3_1D_MH ((int) 2)
105#define ENC_T4 ((int) 3)
106#define ENC_T6 ((int) 4)
107#define ENC_LZW ((int) 5)
108#define ENC_PACKBITS ((int) 32773)
109
110#define PHOTO_BIT0 0
111#define PHOTO_BIT1 1
112#define PHOTO_RGB 2
113#define PHOTO_PAL 3
114#define PHOTO_TRANS 4
115#define PHOTO_CMYK 5
116#define PHOTO_Y_Cb_Cr 6
117
118/* TIFF LZW definitions */
119
120#define INIT_CODE_SIZE 9
121#define CLEAR_CODE 0x100
122#define EOI_CODE 0x101
123#define FIRST_FREE_CODE 0x102
124/*...e*/
125
126/*...srgb_bgr:0:*/
127static void rgb_bgr(const byte *p, byte *q, int n)
128 {
129 while ( n-- )
130 {
131 byte r = *p++;
132 byte g = *p++;
133 byte b = *p++;
134
135 *q++ = b;
136 *q++ = g;
137 *q++ = r;
138 }
139 }
140/*...e*/
141
142typedef unsigned int cword;
143
144#ifdef DEBUG
145#define LOG(args) printf args
146#else
147#define LOG(args)
148#endif
149
150/*...stif_qft:0:*/
151GBM_ERR tif_qft(GBMFT *gbmft)
152 {
153 *gbmft = tif_gbmft;
154 return GBM_ERR_OK;
155 }
156/*...e*/
157/*...stif_rhdr:0:*/
158/*...svalue_of_tag_def:0:*/
159static long value_of_tag_def(IFD *ifd, short type, long def)
160 {
161 TAG *tag;
162
163 if ( (tag = locate_tag(ifd, type)) != NULL )
164 return value_of_tag(tag);
165 else
166 return def;
167 }
168/*...e*/
169
170GBM_ERR tif_rhdr(const char *fn, int fd, GBM *gbm, const char *opt)
171 {
172 TIF_PRIV *tif_priv = (TIF_PRIV *) gbm->priv;
173 TAG *tag_w, *tag_h, *tag_so;
174 GBM_ERR rc;
175 IFH *ifh;
176 IFD *ifd;
177 int inx = 0, strip, n_strips, fillorder;
178 const char *index;
179
180 if ( (index = gbm_find_word_prefix(opt, "index=")) != NULL )
181 sscanf(index + 6, "%d", &inx);
182 tif_priv->inx = inx;
183
184 fn=fn; /* Suppress 'unref arg' compiler warnings */
185
186 switch ( read_ifh_and_ifd(fd, inx, &ifh) )
187 {
188 case TE_OK: rc = GBM_ERR_OK; break;
189 case TE_MEM: rc = GBM_ERR_MEM; break;
190 case TE_VERSION: rc = GBM_ERR_TIF_VERSION; break;
191 case TE_N_TAGS: rc = GBM_ERR_TIF_N_TAGS; break;
192 case TE_TAG_TYPE: rc = GBM_ERR_TIF_TAG_TYPE; break;
193 case TE_N_IFD: rc = GBM_ERR_TIF_INDEX; break;
194 default: rc = GBM_ERR_TIF_HEADER; break;
195 }
196
197 if ( rc != GBM_ERR_OK )
198 return rc;
199
200 ifd = ifh->ifd;
201
202 if ( (tag_w = locate_tag(ifd, T_IMAGEWIDTH )) == NULL ||
203 (tag_h = locate_tag(ifd, T_IMAGELENGTH )) == NULL ||
204 (tag_so = locate_tag(ifd, T_STRIPOFFSETS)) == NULL )
205 {
206 free_ifh(ifh);
207 return GBM_ERR_TIF_MISSING_TAG;
208 }
209
210 gbm->w = (int) value_of_tag(tag_w);
211 gbm->h = (int) value_of_tag(tag_h);
212 tif_priv->photo = (int) value_of_tag_def(ifd, T_PHOTOMETRIC , 1L);
213 tif_priv->rps = (int) value_of_tag_def(ifd, T_ROWSPERSTRIP , (long) gbm->h);
214 tif_priv->spp = (int) value_of_tag_def(ifd, T_SAMPLESPERPIXEL, 1L);
215 tif_priv->bps = (int) value_of_tag_def(ifd, T_BITSPERSAMPLE , 1L);
216 tif_priv->comp = (int) value_of_tag_def(ifd, T_COMPRESSION , 1L);
217 tif_priv->orient = (int) value_of_tag_def(ifd, T_ORIENTATION , 1L);
218 tif_priv->planar = (int) value_of_tag_def(ifd, T_PLANARCONFIG , 1L);
219
220 rc = GBM_ERR_OK;
221 switch ( tif_priv->photo )
222 {
223/*...sPHOTO_BITx \45\ bitmap or greyscale:16:*/
224case PHOTO_BIT0:
225case PHOTO_BIT1:
226 if ( tif_priv->spp != 1 )
227 rc = GBM_ERR_TIF_SPP_BIT;
228 else if ( tif_priv->bps != 1 && tif_priv->bps != 4 && tif_priv->bps != 8 )
229 rc = GBM_ERR_TIF_BPS_BIT;
230 else
231 {
232 int i, n_pal;
233
234 n_pal = ( 1 << tif_priv->bps );
235 for ( i = 0; i < n_pal; i++ )
236 {
237 tif_priv->gbmrgb[i].r =
238 tif_priv->gbmrgb[i].g =
239 tif_priv->gbmrgb[i].b = (byte) ((0xff * i) / (n_pal - 1));
240 }
241 if ( tif_priv->photo == PHOTO_BIT0 )
242 for ( i = 0; i < n_pal; i++ )
243 {
244 tif_priv->gbmrgb[i].r ^= 0xff;
245 tif_priv->gbmrgb[i].g ^= 0xff;
246 tif_priv->gbmrgb[i].b ^= 0xff;
247 }
248 }
249 gbm->bpp = tif_priv->bps;
250 break;
251/*...e*/
252/*...sPHOTO_RGB \45\ 24 bit data:16:*/
253/* It is possible for sample per pixel to be greater than 3.
254 This implies there are extra samples (which we will ignore).
255 This is a new TIFF 6.0 feature. */
256
257case PHOTO_RGB:
258 if ( tif_priv->spp < 3 )
259 rc = GBM_ERR_TIF_SPP_RGB;
260 else if ( tif_priv->bps != 8 )
261 rc = GBM_ERR_TIF_BPS_RGB;
262 gbm->bpp = 24;
263 break;
264/*...e*/
265/*...sPHOTO_PAL \45\ palettised:16:*/
266/*
267There are 2 known bugs in commonly available TIFF files today.
268UBU will only write a ColorMap tag with a length field of 256 (not 256 * 3).
269This bug is fixed inside my TIFF library itself!
270OS/2 Image Support will write all palette entrys as bytes!
271*/
272
273case PHOTO_PAL:
274 if ( tif_priv->spp != 1 )
275 rc = GBM_ERR_TIF_SPP_PAL;
276 else if ( tif_priv->bps != 1 && tif_priv->bps != 4 && tif_priv->bps != 8 )
277 rc = GBM_ERR_TIF_BPS_PAL;
278 else
279 {
280 int i, n_pal;
281 TAG *tag_cm;
282
283 n_pal = (1 << tif_priv->bps);
284 if ( (tag_cm = locate_tag(ifd, T_COLORMAP)) != NULL )
285 {
286 GBMRGB *gbmrgb;
287
288 for ( i = 0, gbmrgb = tif_priv->gbmrgb; i < n_pal; i++, gbmrgb++ )
289 {
290 gbmrgb->r = (byte) ((unsigned)value_of_tag_n(tag_cm, i) >> 8);
291 gbmrgb->g = (byte) ((unsigned)value_of_tag_n(tag_cm, n_pal + i) >> 8);
292 gbmrgb->b = (byte) ((unsigned)value_of_tag_n(tag_cm, 2 * n_pal + i) >> 8);
293 }
294/*...sfix for OS\47\2 Image Support \40\and others\41\:40:*/
295{
296byte bugfix = 0;
297
298for ( i = 0, gbmrgb = tif_priv->gbmrgb; i < n_pal; i++, gbmrgb++ )
299 bugfix |= (gbmrgb->r | gbmrgb->g | gbmrgb->b);
300
301if ( bugfix == 0 )
302 for ( i = 0, gbmrgb = tif_priv->gbmrgb; i < n_pal; i++, gbmrgb++ )
303 {
304 gbmrgb->r = (byte) value_of_tag_n(tag_cm, i);
305 gbmrgb->g = (byte) value_of_tag_n(tag_cm, n_pal + i);
306 gbmrgb->b = (byte) value_of_tag_n(tag_cm, 2 * n_pal + i);
307 }
308}
309/*...e*/
310 }
311 else
312 rc = GBM_ERR_TIF_COLORMAP;
313 }
314 gbm->bpp = tif_priv->bps;
315 break;
316/*...e*/
317/*...sPHOTO_TRANS \45\ transparency mask:16:*/
318case PHOTO_TRANS:
319 rc = GBM_ERR_TIF_PHOTO_TRANS;
320 break;
321/*...e*/
322/*...sPHOTO_CMYK \45\ CMYK or other seperated image:16:*/
323/* This is a colour seperated image.
324 Typically expect 4 seperations, for CMYK.
325 Can be other numbers, and possibly 4 with non standard ink colours.
326 Ignore all but 4 seperations which are CMYK.
327 Consider this a 24 bit RGB, mapping will occur from CMYK to RGB. */
328
329case PHOTO_CMYK:
330 if ( tif_priv->spp != 4 )
331 rc = GBM_ERR_TIF_SPP_CMYK;
332 else if ( tif_priv->bps != 8 )
333 rc = GBM_ERR_TIF_BPS_CMYK;
334 else if ( value_of_tag_def(ifd, T_INKSET, 1L) != 1 )
335 rc = GBM_ERR_TIF_INKSET;
336 else
337 gbm->bpp = 24;
338 break;
339/*...e*/
340/*...sPHOTO_Y_Cb_Cr \45\ Y\45\Cb\45\Cr colour space:16:*/
341case PHOTO_Y_Cb_Cr:
342 rc = GBM_ERR_TIF_PHOTO_Y_Cb_Cr;
343 break;
344/*...e*/
345/*...sdefault \45\ wierd PhotometricInterpretation:16:*/
346default:
347 rc = GBM_ERR_TIF_PHOTO;
348 break;
349/*...e*/
350 }
351
352 if ( rc != GBM_ERR_OK )
353 { free_ifh(ifh); return rc; }
354
355 /* Remember where strips are, and how big they are */
356
357 n_strips = (gbm->h + (tif_priv->rps - 1)) / tif_priv->rps;
358 if ( tif_priv->photo == PHOTO_RGB && tif_priv->planar == 2 )
359 n_strips *= 3;
360
361 if ( n_strips <= MAX_STRIPS )
362 for ( strip = 0; strip < n_strips; strip++ )
363 tif_priv->so[strip] = value_of_tag_n(tag_so, strip);
364
365 if ( tif_priv->comp != ENC_NONE &&
366 tif_priv->comp != ENC_PACKBITS &&
367 tif_priv->comp != ENC_LZW )
368/*...sreject compression type:16:*/
369{
370free_ifh(ifh);
371switch ( tif_priv->comp )
372 {
373 case ENC_G3_1D_MH: return GBM_ERR_TIF_COMP_1D_MH;
374 case ENC_T4: return GBM_ERR_TIF_COMP_T4 ;
375 case ENC_T6: return GBM_ERR_TIF_COMP_T6 ;
376 default: return GBM_ERR_TIF_COMP ;
377 }
378}
379/*...e*/
380
381 if ( tif_priv->orient != 1 && tif_priv->orient != 4 )
382 { free_ifh(ifh); return GBM_ERR_TIF_ORIENT; }
383
384 fillorder = (int) value_of_tag_def(ifd, T_FILLORDER, 1L);
385 if ( fillorder != 1 )
386 { free_ifh(ifh); return GBM_ERR_TIF_FILLORDER; }
387
388 if ( tif_priv->photo == PHOTO_RGB )
389 /* Allow photo of 1 or 2 */
390 {
391 if ( tif_priv->planar != 1 && tif_priv->planar != 2 )
392 { free_ifh(ifh); return GBM_ERR_TIF_PLANARCONFIG_12; }
393 }
394 else
395 /* Allow photo of 1 only */
396 {
397 if ( tif_priv->planar != 1 )
398 { free_ifh(ifh); return GBM_ERR_TIF_PLANARCONFIG_1; }
399 }
400
401 tif_priv->predictor = (int) value_of_tag_def(ifd, T_PREDICTOR, 1L);
402
403 /* Only allow predictor of 1, unless a special case we handle */
404 if ( tif_priv->predictor != 1 &&
405 !(tif_priv->comp == ENC_LZW &&
406 tif_priv->bps == 8 &&
407 (tif_priv->spp == 1 || tif_priv->spp >= 3)) )
408 { free_ifh(ifh); return GBM_ERR_TIF_PREDICTOR; }
409
410 free_ifh(ifh);
411
412 return GBM_ERR_OK;
413 }
414/*...e*/
415/*...stif_rpal:0:*/
416GBM_ERR tif_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
417 {
418 TIF_PRIV *tif_priv = (TIF_PRIV *) gbm->priv;
419
420 fd=fd; /* Suppress 'unref arg' compiler warning */
421
422 if ( gbm->bpp != 24 )
423 memcpy(gbmrgb, tif_priv->gbmrgb, (1 << gbm->bpp) * sizeof(GBMRGB));
424
425 return GBM_ERR_OK;
426 }
427/*...e*/
428/*...stif_rdata:0:*/
429/*
430TIFF data is usually stored top-left-origin based.
431ie: We ignore the private "Orientation" tag.
432Our data format in memory has bigger padding than TIFF.
433It has 'istride' bytes per line, GBM uses/requires 'stride' bytes per line.
434Therefore we read it to the part of the strip area and then expand downwards.
435*/
436
437/*...sget_strip_packbits \45\ get bytes with packbits decompression:0:*/
438static GBM_ERR get_strip_packbits(int fd, byte *dest, long n_bytes)
439 {
440 AHEAD *ahead;
441
442 if ( (ahead = gbm_create_ahead(fd)) == NULL )
443 return GBM_ERR_MEM;
444
445 while ( n_bytes > 0 )
446 {
447 byte b = (byte) gbm_read_ahead(ahead);
448
449 if ( b < 0x80 )
450 {
451 unsigned int count = b + 1;
452
453 do
454 *dest++ = (byte) gbm_read_ahead(ahead);
455 while ( --count > 0 );
456 n_bytes -= (b + 1);
457 }
458 else if ( b > 0x80 )
459 {
460 unsigned int count = 0x101 - (unsigned int) b;
461 byte c = (byte) gbm_read_ahead(ahead);
462
463 memset(dest, c, count);
464 dest += count;
465 n_bytes -= count;
466 }
467 }
468
469 gbm_destroy_ahead(ahead);
470 return GBM_ERR_OK;
471 }
472/*...e*/
473/*...sget_strip_lzw \45\ get bytes with TIFF style LZW decompression:0:*/
474/*
475This code runs on output of FotoTouch and some sample TIFFs from an afs
476directory on the IBM IP-network.
477*/
478
479/*...sread context:0:*/
480typedef struct
481 {
482 int fd; /* File descriptor to read */
483 int inx, size; /* Index and size in bits */
484 byte buf[255+3]; /* Buffer holding bits */
485 int code_size; /* Number of bits to return at once */
486 cword read_mask; /* 2^code_size-1 */
487 } READ_CONTEXT;
488
489static cword read_code(READ_CONTEXT *c)
490 {
491 dword raw_code; int byte_inx;
492
493 while ( c->inx + c->code_size > c->size )
494/*...snot enough bits in buffer\44\ refill it:16:*/
495/* Not very efficient, but infrequently called */
496
497{
498int bytes_to_lose = ((unsigned)c->inx >> 3);
499int bytes;
500
501/* Note biggest code size is 12 bits */
502/* And this can at worst span 3 bytes */
503memcpy(c->buf, c->buf + bytes_to_lose, 3);
504(c->inx) &= 7;
505(c->size) -= (bytes_to_lose << 3);
506bytes = 255 - ( (unsigned)c->size >> 3 );
507if ( (bytes = gbm_file_read(c->fd, c->buf + ((unsigned)c->size >> 3), bytes)) <= 0 )
508 return 0xffff;
509(c->size) += (bytes << 3);
510}
511/*...e*/
512
513 byte_inx = ((unsigned)c->inx >> 3);
514 raw_code = ((c->buf[byte_inx ]) << 16) +
515 ((c->buf[byte_inx + 1]) << 8) +
516 ( c->buf[byte_inx + 2] ) ;
517 raw_code <<= ((c->inx) & 7);
518 (c->inx) += (byte) (c->code_size);
519 raw_code >>= ( 24 - c->code_size );
520 return (cword) raw_code & c->read_mask;
521 }
522/*...e*/
523
524static GBM_ERR get_strip_lzw(int fd, byte *dest, long n_bytes)
525 {
526 cword max_code; /* 1 << code_size */
527 cword free_code; /* Next available free code slot */
528 int i, out_count = 0;
529 cword code, cur_code, old_code, in_code, fin_char;
530 cword *prefix, *suffix, *outcode;
531 READ_CONTEXT c;
532 BOOLEAN table_full = FALSE;
533 byte *limit = dest+n_bytes;
534
535 if ( (prefix = (cword *) malloc((size_t) (4096 * sizeof(cword)))) == NULL )
536 return GBM_ERR_MEM;
537 if ( (suffix = (cword *) malloc((size_t) (4096 * sizeof(cword)))) == NULL )
538 {
539 free(prefix);
540 return GBM_ERR_MEM;
541 }
542 if ( (outcode = (cword *) malloc((size_t) (4097 * sizeof(cword)))) == NULL )
543 {
544 free(suffix);
545 free(prefix);
546 return GBM_ERR_MEM;
547 }
548
549 /* Initial read context */
550
551 c.inx = 0;
552 c.size = 0;
553 c.fd = fd;
554 c.code_size = INIT_CODE_SIZE;
555 c.read_mask = (cword) ( (1 << INIT_CODE_SIZE) - 1 );
556
557 /* 2^min_code size accounts for all colours in file */
558
559 free_code = FIRST_FREE_CODE;
560 max_code = (cword) ( 1 << INIT_CODE_SIZE );
561
562 LOG(("STRIP\n"));
563 while ( dest < limit && (code = read_code(&c)) != EOI_CODE && code != 0xffff )
564 {
565 if ( code == CLEAR_CODE )
566 {
567 LOG(("CLEARED\n"));
568 c.code_size = INIT_CODE_SIZE;
569 c.read_mask = (cword) ( (1 << INIT_CODE_SIZE) - 1);
570 max_code = (cword) ( 1 << INIT_CODE_SIZE );
571 free_code = FIRST_FREE_CODE;
572 cur_code = old_code = code = read_code(&c);
573 if ( code == EOI_CODE || code == 0xffff )
574 break;
575 fin_char = cur_code;
576 if ( cur_code >= 0x100 )
577 {
578 free(outcode);
579 free(suffix);
580 free(prefix);
581 LOG(("CORRUPT1\n"));
582 return GBM_ERR_TIF_CORRUPT;
583 }
584 *dest++ = (byte) fin_char;
585 LOG(("%02x ", (byte) fin_char));
586 LOG(("%03x:%u\n", code, c.code_size));
587 table_full = FALSE;
588 }
589 else
590 {
591 cur_code = in_code = code;
592 if ( cur_code >= free_code )
593 {
594 cur_code = old_code;
595 outcode[out_count++] = fin_char;
596 }
597 while ( cur_code > 0xff )
598 {
599 if ( out_count > 4096 )
600 {
601 free(outcode);
602 free(suffix);
603 free(prefix);
604 LOG(("CORRUPT2\n"));
605 return GBM_ERR_TIF_CORRUPT;
606 }
607 outcode[out_count++] = suffix[cur_code];
608 cur_code = prefix[cur_code];
609 }
610 fin_char = cur_code;
611 outcode[out_count++] = fin_char;
612 for ( i = out_count - 1; i >= 0; i-- )
613 {
614 *dest++ = (byte) outcode[i];
615 LOG(("%02x ", (byte) outcode[i]));
616 }
617 LOG(("%03x:%u\n", code, c.code_size));
618 out_count = 0;
619
620 /* Update dictionary */
621
622 if ( !table_full )
623 {
624 prefix[free_code] = old_code;
625 suffix[free_code] = fin_char;
626
627 /* Advance to next free slot */
628
629 if ( ++free_code >= max_code - 1 )
630 {
631 if ( c.code_size < 12 )
632 {
633 c.code_size++;
634 max_code <<= 1;
635 c.read_mask = (cword) (( 1 << c.code_size ) - 1);
636 }
637 else
638 {
639 table_full = TRUE;
640 LOG(("FULL\n"));
641 }
642 }
643 }
644 old_code = in_code;
645 }
646 }
647
648 free(outcode);
649 free(suffix);
650 free(prefix);
651
652 if ( dest < limit && code == 0xffff )
653 return GBM_ERR_READ;
654
655 return GBM_ERR_OK;
656 }
657/*...e*/
658/*...sget_strip_lzw_pred \45\ get_strip_lzw with non 1 predictor fixup:0:*/
659static GBM_ERR get_strip_lzw_pred(
660 int fd,
661 byte *dest,
662 long n_bytes,
663 TIF_PRIV *tif_priv,
664 int w, int h
665 )
666 {
667 GBM_ERR rc;
668
669 if ( (rc = get_strip_lzw(fd, dest, n_bytes)) != GBM_ERR_OK )
670 return rc;
671
672 if ( tif_priv->predictor == 2 )
673 /* Note: This is only allowed if bps==8 */
674 {
675 int x, y, spp = tif_priv->spp;
676 for ( y = 0; y < h; y++, dest += w * spp )
677 for ( x = spp; x < w * spp; x++ )
678 dest[x] += dest[x - spp];
679 }
680
681 return GBM_ERR_OK;
682 }
683/*...e*/
684/*...sget_strip_comp \45\ get strip\44\ dealing with any compression:0:*/
685/* n_bytes is passed in as istride * n_lines */
686
687static GBM_ERR get_strip_comp(
688 int fd,
689 byte *dest,
690 long so, long n_bytes,
691 TIF_PRIV *tif_priv,
692 int w, int h
693 )
694 {
695 gbm_file_lseek(fd, so, SEEK_SET);
696 switch ( tif_priv->comp )
697 {
698/*...sENC_NONE \45\ no compression:16:*/
699case ENC_NONE:
700 return ( (int) n_bytes == gbm_file_read(fd, dest, (int) n_bytes) ) ?
701 GBM_ERR_OK : GBM_ERR_READ;
702/*...e*/
703/*...sENC_PACKBITS \45\ packbits:16:*/
704case ENC_PACKBITS:
705 return get_strip_packbits(fd, dest, n_bytes);
706/*...e*/
707/*...sENC_LZW \45\ lzw:16:*/
708case ENC_LZW:
709 return get_strip_lzw_pred(fd, dest, n_bytes, tif_priv, w, h);
710/*...e*/
711 }
712 return GBM_ERR_NOT_SUPP;
713 }
714/*...e*/
715/*...sget_strip \45\ get strip\44\ discarding extra samples\44\ and CMYK mapping:0:*/
716/*
717If there are too many samples per pixel, this code can ignore the extra ones.
718Also, if CMYK data is being read, it will read the CMYK, and convert.
719This requires a temporary buffer, to read the original data in.
720The original data is then 'converted'.
721*/
722
723static GBM_ERR get_strip(
724 int fd,
725 byte *dest,
726 long so, long n_bytes,
727 TIF_PRIV *tif_priv,
728 int w, int h
729 )
730 {
731 byte *buf = dest;
732 GBM_ERR rc;
733
734 if ( tif_priv->photo == PHOTO_CMYK )
735/*...sallocate space for CMYK image:16:*/
736{
737n_bytes = (long) w * 4L * (long) h;
738if ( (buf = malloc((size_t) n_bytes)) == NULL )
739 return GBM_ERR_MEM;
740}
741/*...e*/
742 else if ( tif_priv->photo == PHOTO_RGB && tif_priv->spp > 3 )
743/*...sallocate space for image \43\ extra samples:16:*/
744{
745n_bytes = (long) w * tif_priv->spp * (long) h;
746if ( (buf = malloc((size_t) n_bytes)) == NULL )
747 return GBM_ERR_MEM;
748}
749/*...e*/
750
751 if ( (rc = get_strip_comp(fd, buf, so, n_bytes, tif_priv, w, h)) != GBM_ERR_OK )
752 {
753 if ( buf != dest )
754 free(buf);
755 return rc;
756 }
757
758 if ( tif_priv->photo == PHOTO_CMYK )
759/*...sconvert from CMYK to RGB:16:*/
760{
761int x, yy;
762byte *buf_p = buf, *dest_p = dest;
763for ( yy = 0; yy < h; yy++ )
764 for ( x = 0; x < w; x++ )
765 {
766 word c = *buf_p++;
767 word m = *buf_p++;
768 word y = *buf_p++;
769 word k = *buf_p++;
770
771 /* Exploit 8 bit modulo arithmetic by biasing by + 0x100 */
772
773 word r = 0x1ff - (c + k);
774 word g = 0x1ff - (m + k);
775 word b = 0x1ff - (y + k);
776
777 if ( r < 0x100 ) r = 0x100;
778 if ( g < 0x100 ) g = 0x100;
779 if ( b < 0x100 ) b = 0x100;
780
781 *dest_p++ = (byte) r;
782 *dest_p++ = (byte) g;
783 *dest_p++ = (byte) b;
784 }
785
786free(buf);
787}
788/*...e*/
789 else if ( tif_priv->photo == PHOTO_RGB && tif_priv->spp > 3 )
790/*...sextract\44\ ignoring extra\45\samples:16:*/
791{
792int x, y, skip = tif_priv->spp - 2;
793byte *buf_p = buf, *dest_p = dest;
794for ( y = 0; y < h; y++ )
795 for ( x = 0; x < w; x++ )
796 {
797 *dest_p++ = *buf_p++;
798 *dest_p++ = *buf_p++;
799 *dest_p++ = *buf_p ;
800 buf_p += skip;
801 }
802
803free(buf);
804}
805/*...e*/
806
807 return GBM_ERR_OK;
808 }
809/*...e*/
810/*...sget_image \45\ get all strips\44\ result is whole image:0:*/
811/*
812This routine calls get_strip() to get strips data one after another until it
813has read the entire images worth of data. Of course, scan lines are aligned on
814byte boundaries, and the data is usually considered to be image top to bottom.
815*/
816
817static GBM_ERR get_image(
818 int fd,
819 byte *dest,
820 TIF_PRIV *tif_priv,
821 long *so,
822 GBM *gbm,
823 int *strip
824 )
825 {
826 GBM_ERR rc;
827 int y, istride = ((gbm->w * gbm->bpp + 7) / 8);
828
829 for ( y = 0; y < gbm->h; y += tif_priv->rps, (*strip)++ )
830 {
831 int n_lines = min(tif_priv->rps, gbm->h - y);
832 if ( (rc = get_strip(fd, dest + y * istride,
833 so[*strip],
834 (long) n_lines * (long) istride,
835 tif_priv,
836 gbm->w, n_lines)) != GBM_ERR_OK )
837 return rc;
838 }
839
840 return GBM_ERR_OK;
841 }
842/*...e*/
843/*...sget_image_planar \45\ get all strips\44\ allowing for PlanarConfiguration:0:*/
844/*
845get_image() will assume the data is in PlanarConfiguration==1, ie: chunky
846pixel mode. This is TRUE most of the time. But sometimes we will actually
847allow PlanarConfiguration==2. In this case, use get_image() and then fix-up
848the results.
849*/
850
851static GBM_ERR get_image_planar(
852 int fd,
853 byte *dest,
854 TIF_PRIV *tif_priv,
855 long *so,
856 GBM *gbm
857 )
858 {
859 int strip = 0;
860
861 if ( tif_priv->photo == PHOTO_RGB &&
862 tif_priv->planar == 2 )
863/*...sread 3 seperate planes\44\ and combine them:16:*/
864/*
865If PhotometricInterpretation==RGB and
866 SamplesPerPixel>=3 and
867 BitsPerSample==8 then
868 we allow PlanarConfiguration==2
869
870I have successfully read in a PlanarConfiguration==2 RGB TIFF file by using
871the "read 3 images" logic below. This image had RowsPerStrip==1, and so
872technically either fold below would have worked. I think the read 3 images
873logic is a better interpretation of the TIFF 6.0 spec., but until I find
874some other images I can handle, I will keep the alternative peice of code.
875*/
876
877{
878GBM_ERR rc;
879GBM gbm_planar;
880int saved_spp = tif_priv->spp;
881int n_bytes = gbm->w * gbm->h;
882int x, y;
883byte *buf, *p[3];
884
885if ( (buf = malloc((size_t) (n_bytes * 3))) == NULL )
886 return GBM_ERR_MEM;
887p[0] = buf;
888p[1] = p[0] + n_bytes;
889p[2] = p[1] + n_bytes;
890
891tif_priv->spp = 1;
892/*...sread 3 images:16:*/
893{
894int i;
895
896gbm_planar.w = gbm->w;
897gbm_planar.h = gbm->h;
898gbm_planar.bpp = 8;
899for ( i = 0; i < 3; i++ )
900 if ( (rc = get_image(fd, p[i], tif_priv, so, &gbm_planar, &strip)) != GBM_ERR_OK )
901 {
902 tif_priv->spp = saved_spp;
903 free(buf);
904 return rc;
905 }
906}
907/*...e*/
908#ifdef NEVER
909/*...sread single image 3x too high:16:*/
910gbm_planar.w = gbm->w;
911gbm_planar.h = gbm->h * 3;
912gbm_planar.bpp = 8;
913if ( (rc = get_image(fd, buf, tif_priv, so, &gbm_planar, &strip)) != GBM_ERR_OK )
914 {
915 tif_priv->spp = saved_spp;
916 free(buf);
917 return rc;
918 }
919/*...e*/
920#endif
921tif_priv->spp = saved_spp;
922
923for ( y = 0; y < gbm->h; y++ )
924 for ( x = 0; x < gbm->w; x++ )
925 {
926 *dest++ = *(p[0])++;
927 *dest++ = *(p[1])++;
928 *dest++ = *(p[2])++;
929 }
930free(buf);
931return GBM_ERR_OK;
932}
933/*...e*/
934 else
935 return get_image(fd, dest, tif_priv, so, gbm, &strip);
936 }
937/*...e*/
938/*...sget_image_orient \45\ get all strips\44\ correctly orientated:0:*/
939static GBM_ERR get_image_orient(
940 int fd,
941 byte *dest,
942 TIF_PRIV *tif_priv,
943 long *so,
944 GBM *gbm
945 )
946 {
947 switch ( tif_priv->orient )
948 {
949/*...s1 \45\ usual Baseline required case:16:*/
950/*
951File has array[scanlines_down] of array[pixels_across] of pixel.
952GBMs bitmap data is array[scanlines_up] of array[pixels_across] of pixel.
953So call get_image_planar(), and vertically reflect resulting data.
954*/
955
956case 1:
957 {
958 int istride = ((gbm->bpp * gbm->w + 7) / 8);
959 byte *p0, *p1, *p2;
960 GBM_ERR rc;
961 if ( (rc = get_image_planar(fd, dest, tif_priv, so, gbm)) != GBM_ERR_OK )
962 return rc;
963 if ( (p0 = malloc((size_t) istride)) == NULL )
964 return GBM_ERR_MEM;
965 for ( p1 = dest, p2 = p1 + (gbm->h - 1) * istride;
966 p1 < p2;
967 p1 += istride, p2 -= istride )
968 {
969 memcpy(p0, p1, istride);
970 memcpy(p1, p2, istride);
971 memcpy(p2, p0, istride);
972 }
973 free(p0);
974 return GBM_ERR_OK;
975 }
976/*...e*/
977/*...s4 \45\ vertically swapped case we can easily handle:16:*/
978/*
979File has array[scanlines_up] of array[pixels_across] of pixel.
980Exactly matches GBMs layout of a bitmap.
981So simply call get_image() and be done with.
982*/
983
984case 4:
985 return get_image_planar(fd, dest, tif_priv, so, gbm);
986/*...e*/
987 }
988 return GBM_ERR_NOT_SUPP; /* Shouldn't get here */
989 }
990/*...e*/
991/*...sget_image_strippy \45\ get all strips\44\ when there are loads of them:0:*/
992static GBM_ERR get_image_strippy(
993 int fd,
994 byte *dest,
995 TIF_PRIV *tif_priv,
996 GBM *gbm
997 )
998 {
999 int n_strips = (gbm->h + (tif_priv->rps - 1)) / tif_priv->rps;
1000 long *so = tif_priv->so;
1001
1002 if ( n_strips > MAX_STRIPS )
1003/*...sre\45\read TIFF file header:16:*/
1004{
1005GBM_ERR rc;
1006int strip;
1007IFH *ifh;
1008IFD *ifd;
1009TAG *tag_so;
1010
1011if ( (so = malloc((size_t) (n_strips * sizeof(long)))) == NULL )
1012 return GBM_ERR_MEM;
1013
1014gbm_file_lseek(fd, 0L, SEEK_SET);
1015if ( read_ifh_and_ifd(fd, tif_priv->inx, &ifh) != TE_OK )
1016 {
1017 free(so);
1018 return GBM_ERR_MEM;
1019 }
1020ifd = ifh->ifd;
1021tag_so = locate_tag(ifd, T_STRIPOFFSETS);
1022for ( strip = 0; strip < n_strips; strip++ )
1023 so[strip] = value_of_tag_n(tag_so, strip);
1024free_ifh(ifh);
1025
1026rc = get_image_orient(fd, dest, tif_priv, so, gbm);
1027
1028free(so);
1029return rc;
1030}
1031/*...e*/
1032 else
1033 return get_image_orient(fd, dest, tif_priv, so, gbm);
1034 }
1035/*...e*/
1036
1037GBM_ERR tif_rdata(int fd, GBM *gbm, byte *data)
1038 {
1039 TIF_PRIV *tif_priv = (TIF_PRIV *) gbm->priv;
1040 int stride = ((gbm->bpp * gbm->w + 31) / 32) * 4;
1041 int istride = ((gbm->bpp * gbm->w + 7) / 8);
1042 int bias = gbm->h * (stride - istride);
1043 GBM_ERR rc;
1044
1045 /* Read in data, packed close, and upside down */
1046
1047 if ( (rc = get_image_strippy(fd, data + bias, tif_priv, gbm)) != GBM_ERR_OK )
1048 return rc;
1049
1050/*...snow expand out from byte padding to dword padding:8:*/
1051if ( bias )
1052 {
1053 int y;
1054 byte *dest = data, *src = data + bias;
1055
1056 for ( y = 0; y < gbm->h; y++, dest += stride, src += istride )
1057 memcpy(dest, src, istride);
1058 }
1059/*...e*/
1060/*...snow RGB\45\\62\BGR if 24 bit data returned:8:*/
1061if ( gbm->bpp == 24 )
1062 {
1063 int y;
1064 byte *p = data;
1065
1066 for ( y = 0; y < gbm->h; y++, p += stride )
1067 rgb_bgr(p, p, gbm->w);
1068 }
1069/*...e*/
1070
1071 return GBM_ERR_OK;
1072 }
1073/*...e*/
1074/*...stif_w:0:*/
1075/*
1076Write out data in a single large strip for now.
1077Note that the palette entrys are written as ((r << 8) | r).
1078This means they are 257/256 too big (insignificant).
1079Most programs only look at the top 8 bits (ie: no error).
1080A few (incorrectly) look at the bottom 8 bits.
1081Therefore we cater for all programs, with minimal fuss.
1082*/
1083
1084/*...suser_tag:0:*/
1085static BOOLEAN user_tag(IFD *ifd, char *name, short type, const char *opt, char *def)
1086 {
1087 char buf[200+1];
1088 const char *s;
1089
1090 if ( (s = gbm_find_word_prefix(opt, name)) != NULL )
1091 sscanf(s + strlen(name), "%s", buf);
1092 else
1093 strcpy(buf, def);
1094
1095 if ( *buf == '\0' )
1096 return TRUE;
1097
1098 return add_ascii_tag(ifd, type, buf);
1099 }
1100/*...e*/
1101/*...swrite_strip:0:*/
1102static GBM_ERR write_strip(int fd, int w, int h, int bpp, const byte *data)
1103 {
1104 int stride = ((bpp * w + 31) / 32) * 4;
1105 int ostride = ((bpp * w + 7) / 8);
1106 int y;
1107 data += ((h - 1) * stride);
1108 if ( bpp == 24 )
1109/*...sreverse rgb\47\bgr ordering and write:16:*/
1110{
1111byte *line;
1112
1113if ( (line = malloc((size_t) ostride)) == NULL )
1114 return GBM_ERR_MEM;
1115for ( y = 0; y < h; y++, data -= stride )
1116 {
1117 rgb_bgr(data, line, w);
1118 if ( gbm_file_write(fd, line, ostride) != ostride )
1119 {
1120 free(line);
1121 return GBM_ERR_WRITE;
1122 }
1123 }
1124free(line);
1125}
1126/*...e*/
1127 else
1128/*...swrite:16:*/
1129for ( y = 0; y < h; y++, data -= stride )
1130 if ( gbm_file_write(fd, data, ostride) != ostride )
1131 return GBM_ERR_WRITE;
1132/*...e*/
1133 return GBM_ERR_OK;
1134 }
1135/*...e*/
1136/*...swrite_strip_lzw \45\ new fast tail\43\col lookup version:0:*/
1137/*
1138This is a tricky bit of code to get right.
1139This code blantantly copied and hacked from that in gbmgif.c!
1140hashvalue is calculated from a string of pixels cumulatively.
1141hashtable is searched starting at index hashvalue for to find the entry.
1142hashtable is big enough so that MAX_HASH > 4*MAX_DICT.
1143*/
1144
1145/*...swrite context:0:*/
1146#define L_BUF 1024
1147
1148typedef struct
1149 {
1150 int fd; /* Open file descriptor to write to */
1151 int inx; /* Bit index into buf */
1152 int code_size; /* Code size in bits */
1153 byte buf[L_BUF+2]; /* Biggest block + overflow space */
1154 } WRITE_CONTEXT;
1155
1156static BOOLEAN write_code(cword code, WRITE_CONTEXT *w)
1157 {
1158 byte *buf = w->buf + ((unsigned)w->inx >> 3);
1159
1160 LOG(("%03x:%u\n", code, w->code_size));
1161 code <<= (24-w->code_size);
1162 code >>= (w->inx&7U);
1163 *buf++ |= (byte) (code >> 16);
1164 *buf++ = (byte) (code >> 8);
1165 *buf = (byte) code ;
1166
1167 (w->inx) += (w->code_size);
1168 if ( w->inx >= L_BUF * 8 )
1169 /* Flush out full buffer */
1170 {
1171 if ( gbm_file_write(w->fd, w->buf, L_BUF) != L_BUF )
1172 return FALSE;
1173 memcpy(w->buf, w->buf + L_BUF, 2);
1174 memset(w->buf + 2, 0, L_BUF);
1175 (w->inx) -= (L_BUF * 8);
1176 }
1177
1178 return TRUE;
1179 }
1180
1181static BOOLEAN flush_code(WRITE_CONTEXT *w)
1182 {
1183 int bytes = (((unsigned)w->inx + 7) >> 3);
1184
1185 if ( bytes )
1186 {
1187 if ( gbm_file_write(w->fd, w->buf, bytes) != bytes )
1188 return FALSE;
1189 }
1190
1191 return TRUE;
1192 }
1193/*...e*/
1194
1195#define MAX_HASH 17777 /* Probably prime, and > 4096 */
1196#define MAX_DICT 4096 /* Dictionary size */
1197#define INIT_HASH(p) (((p)+3)*301) /* Initial hash value */
1198
1199typedef struct { cword tail; byte col; } DICT;
1200
1201static GBM_ERR write_strip_lzw(int fd, int w, int h, int bpp, const byte *data)
1202 {
1203 int stride = ((bpp * w + 31) / 32) * 4;
1204 int ostride = ((bpp * w + 7) / 8);
1205 WRITE_CONTEXT wc;
1206 cword last_code, max_code, tail;
1207 int x, y;
1208 unsigned int hashvalue, lenstring, j;
1209 DICT *dict, **hashtable;
1210
1211 if ( (dict = (DICT *) malloc((size_t) (MAX_DICT * sizeof(DICT)))) == NULL )
1212 return GBM_ERR_MEM;
1213
1214 if ( (hashtable = (DICT **) malloc((size_t) (MAX_HASH * sizeof(DICT *)))) == NULL )
1215 {
1216 free(dict);
1217 return GBM_ERR_MEM;
1218 }
1219
1220 /* Setup write context */
1221
1222 wc.fd = fd;
1223 wc.inx = 0;
1224 wc.code_size = INIT_CODE_SIZE;
1225 memset(wc.buf, 0, sizeof(wc.buf));
1226
1227 if ( !write_code(CLEAR_CODE, &wc) )
1228 {
1229 free(hashtable);
1230 free(dict);
1231 return GBM_ERR_WRITE;
1232 }
1233
1234 last_code = EOI_CODE;
1235 max_code = ( 1 << INIT_CODE_SIZE );
1236 lenstring = 0;
1237
1238 for ( j = 0; j < MAX_HASH; j++ )
1239 hashtable[j] = NULL;
1240
1241 data += ( (h - 1) * stride );
1242 for ( y = h - 1; y >= 0; y--, data -= stride )
1243 {
1244 int inx1 = 0, inx2 = 2;
1245 for ( x = 0; x < ostride; x++ )
1246 {
1247 byte col;
1248/*...sget byte to write to col:24:*/
1249if ( bpp == 24 )
1250 /* Have to handle rgb/bgr reverse as we go along */
1251 {
1252 col = data[inx1+inx2];
1253 if ( --inx2 < 0 )
1254 {
1255 inx1 += 3; inx2 = 2;
1256 }
1257 }
1258else
1259 col = data[x];
1260/*...e*/
1261/*...sLZW encode:24:*/
1262if ( ++lenstring == 1 )
1263 {
1264 tail = col;
1265 hashvalue = INIT_HASH(col);
1266 }
1267else
1268 {
1269 hashvalue *= ( col + lenstring + 4 );
1270 j = ( hashvalue %= MAX_HASH );
1271 while ( hashtable[j] != NULL &&
1272 ( hashtable[j]->tail != tail ||
1273 hashtable[j]->col != col ) )
1274 if ( ++j >= MAX_HASH )
1275 j = 0;
1276 if ( hashtable[j] != NULL )
1277 /* Found in the strings table */
1278 {
1279 tail = (hashtable[j]-dict);
1280 LOG(("%02x ", col));
1281 }
1282 else
1283 /* Not found */
1284 {
1285 if ( !write_code(tail, &wc) )
1286 {
1287 free(hashtable);
1288 free(dict);
1289 return GBM_ERR_WRITE;
1290 }
1291 hashtable[j] = dict + ++last_code;
1292 hashtable[j]->tail = tail;
1293 hashtable[j]->col = col;
1294 LOG(("%02x ", col));
1295 tail = col;
1296 hashvalue = INIT_HASH(col);
1297 lenstring = 1;
1298
1299/* Note: Things change 1 earlier than in the GIF LZW case, hence -1. */
1300 if ( last_code >= max_code -1 )
1301 /* Next code will be written longer */
1302 {
1303 max_code <<= 1;
1304 wc.code_size++;
1305 }
1306 else if ( last_code >= MAX_DICT-2 )
1307 /* Reset tables */
1308 {
1309 if ( !write_code(tail , &wc) ||
1310 !write_code(CLEAR_CODE, &wc) )
1311 {
1312 free(hashtable);
1313 free(dict);
1314 return GBM_ERR_WRITE;
1315 }
1316 lenstring = 0;
1317 last_code = EOI_CODE;
1318 wc.code_size = INIT_CODE_SIZE;
1319 max_code = ( 1 << INIT_CODE_SIZE );
1320 for ( j = 0; j < MAX_HASH; j++ )
1321 hashtable[j] = NULL;
1322 }
1323 }
1324 }
1325/*...e*/
1326 }
1327 }
1328
1329 free(hashtable);
1330 free(dict);
1331
1332 if ( lenstring != 0 )
1333 /* Only write tail if no code written for some input */
1334 {
1335 if ( !write_code(tail, &wc) )
1336 return GBM_ERR_WRITE;
1337 if ( ++last_code >= max_code -1 )
1338 /* Next code will be written longer */
1339 wc.code_size++;
1340 }
1341
1342 if ( !write_code(EOI_CODE, &wc) ||
1343 !flush_code( &wc) )
1344 return GBM_ERR_WRITE;
1345
1346 return GBM_ERR_OK;
1347 }
1348/*...e*/
1349
1350GBM_ERR tif_w(const char *fn, int fd, const GBM *gbm, const GBMRGB *gbmrgb, const byte *data, const char *opt)
1351 {
1352 BOOLEAN baseline = ( gbm_find_word(opt, "pal1bpp") == NULL );
1353 BOOLEAN lzw = ( gbm_find_word(opt, "lzw" ) != NULL );
1354 IFH *ifh;
1355 IFD *ifd;
1356 long w = gbm->w;
1357 long h = gbm->h;
1358 long stripoffset, stripbytecount;
1359 short samplesperpixel, bitspersample[3], photo, comp;
1360 short colormap[0x100+0x100+0x100];
1361 BOOLEAN ok;
1362 GBM_ERR rc;
1363
1364 fn=fn; /* Suppress 'unref arg' compiler warning */
1365
1366 if ( (ifh = make_ifh()) == NULL )
1367 return GBM_ERR_MEM;
1368
1369 ifd = ifh->ifd;
1370
1371 if ( gbm->bpp == 1 && baseline )
1372 {
1373 word k0 = (word) gbmrgb[0].r + (word) gbmrgb[0].g + (word) gbmrgb[0].b;
1374 word k1 = (word) gbmrgb[1].r + (word) gbmrgb[1].g + (word) gbmrgb[1].b;
1375 samplesperpixel = 1;
1376 bitspersample[0] = 1;
1377 photo = ( k0 < k1 ) ? PHOTO_BIT1 : PHOTO_BIT0; /* Black is zero : White is zero */
1378 }
1379 else if ( gbm->bpp == 24 )
1380 {
1381 samplesperpixel = 3;
1382 bitspersample[0] =
1383 bitspersample[1] =
1384 bitspersample[2] = 8;
1385 photo = PHOTO_RGB;
1386 }
1387 else
1388 {
1389 samplesperpixel = 1;
1390 bitspersample[0] = (short) gbm->bpp;
1391 photo = PHOTO_PAL;
1392 }
1393
1394 comp = ( lzw ) ? ENC_LZW : ENC_NONE;
1395
1396 ok = add_long_tag(ifd, T_IMAGEWIDTH, &w, 1) &&
1397 add_long_tag(ifd, T_IMAGELENGTH, &h, 1) &&
1398 add_long_tag(ifd, T_STRIPOFFSETS, &stripoffset, 1) &&
1399 add_long_tag(ifd, T_STRIPBYTECOUNTS, &stripbytecount, 1) &&
1400 add_short_tag(ifd, T_SAMPLESPERPIXEL, &samplesperpixel, 1) &&
1401 add_short_tag(ifd, T_BITSPERSAMPLE, bitspersample, samplesperpixel) &&
1402 add_short_tag(ifd, T_PHOTOMETRIC, &photo, 1) &&
1403 add_short_tag(ifd, T_COMPRESSION, &comp, 1) &&
1404 user_tag(ifd, "artist=", T_ARTIST, opt, "") &&
1405 user_tag(ifd, "software=", T_MAKE, opt, "") &&
1406 user_tag(ifd, "make=", T_MAKE, opt, "") &&
1407 user_tag(ifd, "model=", T_MODEL, opt, "") &&
1408 user_tag(ifd, "hostcomputer=", T_HOSTCOMPUTER, opt, "") &&
1409 user_tag(ifd, "documentname=", T_DOCNAME, opt, "") &&
1410 user_tag(ifd, "pagename=", T_PAGENAME, opt, "") &&
1411 user_tag(ifd, "imagedescription=", T_DESCRIPTION, opt, "");
1412
1413 if ( gbm->bpp != 24 )
1414 {
1415 int i, n_cols = (1 << gbm->bpp);
1416
1417 for ( i = 0; i < n_cols; i++ )
1418 {
1419 short r = (short) gbmrgb[i].r;
1420 short g = (short) gbmrgb[i].g;
1421 short b = (short) gbmrgb[i].b;
1422
1423 colormap[ i] = ((r << 8) | r);
1424 colormap[ n_cols + i] = ((g << 8) | g);
1425 colormap[2 * n_cols + i] = ((b << 8) | b);
1426 }
1427 if ( gbm->bpp != 1 || !baseline )
1428 ok &= add_short_tag(ifd, T_COLORMAP, colormap, n_cols * 3);
1429 }
1430
1431 if ( !ok )
1432 {
1433 free_ifh(ifh);
1434 return GBM_ERR_MEM;
1435 }
1436
1437 if ( !write_ifh_and_ifd(ifh, fd) )
1438 {
1439 free_ifh(ifh);
1440 return GBM_ERR_WRITE;
1441 }
1442
1443 stripoffset = gbm_file_lseek(fd, 0L, SEEK_CUR);
1444
1445 if ( lzw )
1446 rc = write_strip_lzw(fd, gbm->w, gbm->h, gbm->bpp, data);
1447 else
1448 rc = write_strip(fd, gbm->w, gbm->h, gbm->bpp, data);
1449
1450 if ( rc != GBM_ERR_OK )
1451 {
1452 free_ifh(ifh);
1453 return rc;
1454 }
1455
1456 stripbytecount = gbm_file_lseek(fd, 0L, SEEK_CUR) - stripoffset;
1457
1458 update_long_tag(ifd, T_STRIPOFFSETS, &stripoffset);
1459 update_long_tag(ifd, T_STRIPBYTECOUNTS, &stripbytecount);
1460
1461 if ( !update_ifd(ifd, fd) )
1462 {
1463 free_ifh(ifh);
1464 return GBM_ERR_WRITE;
1465 }
1466
1467 free_ifh(ifh);
1468
1469 return GBM_ERR_OK;
1470 }
1471/*...e*/
1472/*...stif_err:0:*/
1473const char *tif_err(GBM_ERR rc)
1474 {
1475 switch ( (int) rc )
1476 {
1477 case GBM_ERR_TIF_VERSION:
1478 return "version number not 42";
1479 case GBM_ERR_TIF_N_TAGS:
1480 return "too many tags in file";
1481 case GBM_ERR_TIF_TAG_TYPE:
1482 return "bad tag type";
1483 case GBM_ERR_TIF_HEADER:
1484 return "corrupt header";
1485 case GBM_ERR_TIF_MISSING_TAG:
1486 return "ImageWidth, ImageLength or StripOffsets tag missing";
1487 case GBM_ERR_TIF_SPP_BIT:
1488 return "SamplesPerPixel tag must be 1 for bitmap or greyscale file";
1489 case GBM_ERR_TIF_BPS_BIT:
1490 return "BitsPerSample tag must be 1,4 or 8 for bitmap or greyscale file";
1491 case GBM_ERR_TIF_SPP_RGB:
1492 return "SamplesPerPixel tag must be 3 or more for RGB file";
1493 case GBM_ERR_TIF_BPS_RGB:
1494 return "BitsPerSample tag must be 8 for RGB file";
1495 case GBM_ERR_TIF_SPP_PAL:
1496 return "SamplesPerPixel tag must be 1 for palettised file";
1497 case GBM_ERR_TIF_BPS_PAL:
1498 return "BitsPerSample tag must be 1,4 or 8 for palettised file";
1499 case GBM_ERR_TIF_SPP_CMYK:
1500 return "SamplesPerPixel tag must be 4 for CMYK file";
1501 case GBM_ERR_TIF_BPS_CMYK:
1502 return "BitsPerSample tag must be 8 for CMYK file";
1503 case GBM_ERR_TIF_COMP_1D_MH:
1504 return "Compression tag is CCITT 1D Modified Huffman, not supported";
1505 case GBM_ERR_TIF_COMP_T4:
1506 return "Compression tag is CCITT T.4 G3 Facsimile, not supported";
1507 case GBM_ERR_TIF_COMP_T6:
1508 return "Compression tag is CCITT T.6 G4 Facsimile, not supported";
1509 case GBM_ERR_TIF_COMP:
1510 return "Compression tag not uncompressed, PackBits or LZW, not supported";
1511 case GBM_ERR_TIF_COLORMAP:
1512 return "ColorMap tag missing";
1513 case GBM_ERR_TIF_CORRUPT:
1514 return "encoded data is corrupt";
1515 case GBM_ERR_TIF_PREDICTOR:
1516 return "Predictor tag bad";
1517 case GBM_ERR_TIF_PHOTO_TRANS:
1518 return "PhotometricInterpretation tag is transparency mask, not supported";
1519 case GBM_ERR_TIF_PHOTO_Y_Cb_Cr:
1520 return "PhotometricInterpreation tag is Y-Cb-Cr colour space, not supported";
1521 case GBM_ERR_TIF_PHOTO:
1522 return "PhotometricInterpretation tag unsupported/bad";
1523 case GBM_ERR_TIF_FILLORDER:
1524 return "FillOrder tag must be 1";
1525 case GBM_ERR_TIF_PLANARCONFIG_1:
1526 return "PlanarConfiguration tag must be 1 for non RGB files";
1527 case GBM_ERR_TIF_PLANARCONFIG_12:
1528 return "PlanarConfiguration tag must be 1 or 2 for RGB files";
1529 case GBM_ERR_TIF_INKSET:
1530 return "InkSet tag indicates non-CMYK colour seperations";
1531 case GBM_ERR_TIF_ORIENT:
1532 return "Orientation tag must be 1 or 4";
1533 case GBM_ERR_TIF_INDEX:
1534 return "less bitmaps in file than index requested";
1535 }
1536 return NULL;
1537 }
1538/*...e*/
Note: See TracBrowser for help on using the repository browser.